os-z80/kernel/vmem.z80

155 lines
2.5 KiB
Z80 Assembly
Raw Normal View History

2023-01-29 11:03:53 -06:00
.global set_frame
.global get_frame
.global clear_frame
.global vmem_init
.global vmem_mapping_card
.global vmem_mapping_bank_low
.global vmem_mapping_bank_high
.global pmap_set
.global pmap_load
; map a RAM frame into memory
; C contains the page to map
; B contains the card # to use
; DE contains the bank # in the card
; The contents of A, IX and C are destroyed
set_frame:
push bc
push de
call clear_frame
pop de
pop bc
2023-01-29 11:03:53 -06:00
ld a, c
ld (card_set+2), a
ld (low_set+2), a
ld (high_set+2), a
ld ix, vmem_mapping_card
card_set: ld (ix+0), b
ld ix, vmem_mapping_bank_low
low_set: ld (ix+0), e
ld ix, vmem_mapping_bank_high
high_set: ld (ix+0), d
ld a, e
out (c), a
ld a, c
or 0x20
ld c, a
ld a, d
or 0x80
out (c), a
ret
; Get the RAM frame a page is mapped to
; C contains the page to get
; B will contain the card #
; DE will contain the bank # in the card
; The contents of A, IX are destroyed
; If the page is unmapped, C will be 0 and DE will contain garbage
get_frame:
ld a, c
ld (vgf_card_get+2), a
ld (vgf_low_get+2), a
ld (vgf_high_get+2), a
ld ix, vmem_mapping_card
vgf_card_get: ld b, (ix+0)
ld ix, vmem_mapping_bank_low
vgf_low_get: ld e, (ix+0)
ld ix, vmem_mapping_bank_high
vgf_high_get: ld d, (ix+0)
ret
; Unmaps a memory page
; C contains the page to unmap
; The contents of A, BC, DE, and IX are destroyed
clear_frame:
call get_frame
ld a, c
ld (vcf_card_set+2), a
ld ix, vmem_mapping_card
vcf_card_set: ld (ix+0), 0
xor a
out (c), a
ld a, c
or 0x20
ld c, a
xor a
out (c), a
ret
; Loads a pagemap pointed to by IX
; The contents of A, BC, DE, and IX are destroyed
pmap_load:
ld c, 0
pmap_load_loop:
push bc
push ix
call clear_frame
pop ix
pop bc
ld b, (ix+0)
ld e, (ix+1)
ld d, (ix+2)
push bc
push ix
call set_frame
pop ix
pop bc
inc ix
inc ix
inc ix
inc c
ld a, c
cp 12
jp nz, pmap_load_loop
ret
; Stores the pagemap in the memory pointed to by IX
; The contents of A, BC, DE, and IX are destroyed
pmap_set:
ld c, 0
pmap_set_loop:
push ix
call get_frame
pop ix
ld (ix+0), b
ld (ix+1), e
ld (ix+2), d
inc ix
inc ix
inc ix
inc c
ld a, c
cp 12
jp nz, pmap_set_loop
ret
RAM_TYPE equ 2
; Initializes the virtual memory manager
vmem_init:
ld b, RAM_TYPE
call find_first_card
ld a, l
ld c, 15
ld b, 0
ld de, vmem_mapping_card
ld h, d
ld l, e
inc de
ld (hl), a
ldir
ld ix, vmem_mapping_bank_low+15
ld b, 15
vmem_init_loop:
ld (ix+0), b
dec ix
djnz vmem_init_loop
ret
vmem_mapping_card: .ds.b 16, 0
vmem_mapping_bank_low: .ds.b 16, 0
vmem_mapping_bank_high: .ds.b 16, 0