os-z80/kernel/pmem.z80
2023-02-03 09:24:28 -06:00

234 lines
3.0 KiB
Z80 Assembly

.global set_frame
.global get_free_frame
.global pmem_init
RAM_TYPE equ 2
SHARED_DATA_PAGE equ 2
BMAP_PAGE_512K equ 3
RAM_SIZE_LOW_PORT equ 0xFD
RAM_SIZE_HIGH_PORT equ 0xFE
BANKING_PAGE equ 0xE
ram_nums equ BANKING_PAGE << 12
first_ram_card: .db 0
; Get the pointer to the specified RAM card's bitmap.
; Also maps the right frame in
; A contains the RAM card to use
; HL returns the pointer to the bitmap
; The values in A, BC, DE, and IX are destroyed.
get_ram_bmap:
ex af, af'
ld a, (first_ram_card)
ld b, a
ld c, BANKING_PAGE
ld d, 0
ld e, SHARED_DATA_PAGE
call set_frame
ex af, af'
ld b, a
ld c, 0xFD
in l, (c)
inc c
in h, (c)
ex af, af'
ld a, h
cp 0
jp nz, grb_large_card
ld a, l
cp 128
jp nz, grb_large_card
; grb_512k_card
ld l, a
ld a, (first_ram_card)
ld b, a
ld c, BANKING_PAGE
ld d, 0
ld e, BMAP_PAGE_512K
call set_frame
ex af, af'
ld h, 0
ld l, a
add hl, hl
add hl, hl
add hl, hl
add hl, hl
ld a, h
or 0xE0
ld h, a
ret
grb_large_card:
ex af, af'
ld b, a
ld c, 0xF
ld d, 0
ld e, d
call set_frame
ld hl, 0xE000
ret
; Get a free frame of RAM
; On return, C contains the card that the frame is in, and
; HL contains the frame number
; The values in A, B, D, E, IX, and IY are destroyed.
get_free_frame:
push bc
ld a, (first_ram_card)
ld b, a
ld c, BANKING_PAGE
ld d, 0
ld e, SHARED_DATA_PAGE
call set_frame
pop bc
gff_loop:
ld ix, ram_nums
ld a, (ix+0)
cp 0
jp z, gff_done
push af
push ix
call get_ram_bmap
pop ix
push hl
pop iy
pop af
push iy
ld b, a
ld c, 0xFD
in l, (c)
inc c
in h, (c)
srl h
rr l
srl h
rr l
srl h
rr l
ld b, h
ld c, l
byte_loop:
push bc
ld b, 8
ld c, a
bit_loop:
ld a, b
sub 1
sla a
sla a
sla a
or 0x47
ld (bit_ins+1), a
or 0x80
ld (gff_set_ins+1), a
ld a, (iy+0)
bit_ins: bit 0, a
jp nz, used_frame
pop de
pop de
push iy
pop hl
ld a, (hl)
gff_set_ins: set 0, a
ld (hl), a
scf
ccf
sbc hl, de
add hl, hl
add hl, hl
add hl, hl
ld a, b
sub 1
add a, l
ld l, a
ret
used_frame:
djnz bit_loop
ld d, c
pop bc
dec bc
inc iy
ld a,b
or c
ld a, d
jp nz,byte_loop
inc ix
pop iy
jp gff_loop
gff_done:
exx
ld c, 0
ld hl, 0
ret
pmem_init:
ld b, RAM_TYPE
call find_first_card
ld a, l
ld (first_ram_card), a
ex af, af'
ld c, BANKING_PAGE
ld b, l
ld d, 0
ld e, SHARED_DATA_PAGE
call set_frame
ld ix, ram_nums
ld b, 16
ld c, RAM_TYPE
call get_all_cards
ld ix, ram_nums
init_loop:
ld a, (ix+0)
inc ix
cp 0
jp z, init_done
ld b, a
ld c, RAM_SIZE_LOW_PORT
in l, (c)
ld c, RAM_SIZE_HIGH_PORT
in h, (c)
push hl
pop iy
ld d, a
push af
ld a, d
call get_ram_bmap
pmem_init_grb_done:
pop af
push hl
push iy
pop bc
ld d, h
ld e, l
ld (hl), 0 ; Zero out the first byte ( Acts as a 'seed' for the zeroing )
ldir
pop hl
ld b, a
push iy
pop de
ld a, d
cp 0
jp nz, init_if1
ld a, e
cp 128
jp nz, init_if1
jp init_if1_end
init_if1:
ld (hl), 0x1
init_if1_end:
/* ld a, (first_ram_card) */
/* ld c, a */
/* ld a, b */
/* cp c */
jp nz, init_if2_end
ld (hl), 0xFF
init_if2_end:
ld a, (first_ram_card)
ld b, a
ld c, BANKING_PAGE
ld d, 0
ld e, SHARED_DATA_PAGE
call set_frame
jp init_loop
init_done:
ret