307 lines
3.7 KiB
Z80 Assembly
307 lines
3.7 KiB
Z80 Assembly
.global mb_send
|
|
; Sends a message to the MB whose ID is in HL,
|
|
; with the message pointer in C:DE:IX
|
|
; Returns 0 in B if it sent the mesage, of 1 if the box was full
|
|
mb_send:
|
|
push de
|
|
push bc
|
|
push ix
|
|
ld a, l
|
|
cp 0
|
|
jp nz, not_init
|
|
; halt
|
|
not_init:
|
|
call get_mb_ptr
|
|
pop ix
|
|
pop bc
|
|
pop de
|
|
push ix
|
|
push hl
|
|
pop ix
|
|
pop hl
|
|
ld ixl, 0xFC
|
|
ld a, (ix+0)
|
|
inc a
|
|
cp 42
|
|
jp nz, no_wrap
|
|
ld a, 0
|
|
no_wrap:
|
|
ld b, (ix+1)
|
|
cp b
|
|
jp nz, mb_not_full
|
|
ld b, 1
|
|
ret
|
|
mb_not_full:
|
|
ld a, (ix+0)
|
|
ld ixl, 0
|
|
ld b, a
|
|
sla a
|
|
sla a
|
|
sla b
|
|
add a, b
|
|
ld ixl, a
|
|
ld (ix+0), c
|
|
ld (ix+1), e
|
|
ld (ix+2), d
|
|
ld (ix+3), l
|
|
ld (ix+4), h
|
|
ld ixl, 0xFC
|
|
ld a, (ix+0)
|
|
inc a
|
|
cp 42
|
|
jp nz, mbs_no_wrap
|
|
ld a, 0
|
|
mbs_no_wrap:
|
|
ld (ix+0), a
|
|
ld b, 0
|
|
ret
|
|
|
|
.global mb_read
|
|
;Reads a message from the MB specified in HL,
|
|
; and returns the pointer in C:DE:HL.
|
|
; Returns 0 in B if the mailbox had a message, and 1 if it was full
|
|
mb_read:
|
|
call get_mb_ptr
|
|
mb_read_gmbp_done:
|
|
push hl
|
|
pop ix
|
|
ld ixl, 0xFC
|
|
ld a, (ix+1)
|
|
ld b, (ix+0)
|
|
ld ixl, 0x0
|
|
cp b
|
|
jp nz, mb_not_empty
|
|
ld b, 1
|
|
ret
|
|
mb_not_empty:
|
|
ld b, a
|
|
sla a
|
|
sla a
|
|
sla b
|
|
add a, b
|
|
ld ixl, a
|
|
ld c, (ix+0)
|
|
ld e, (ix+1)
|
|
ld d, (ix+2)
|
|
ld l, (ix+3)
|
|
ld h, (ix+4)
|
|
ld ixl, 0xFC
|
|
ld a, (ix+1)
|
|
inc a
|
|
cp 42
|
|
jp nz, mbr_no_wrap
|
|
ld a, 0
|
|
mbr_no_wrap:
|
|
ld (ix+1), a
|
|
ld b, 0
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
.global get_free_mailbox
|
|
; Gets a free mailbox
|
|
; ID is returned in HL
|
|
get_free_mailbox:
|
|
ld a, (mb_free_list)
|
|
cp 0
|
|
jp nz, gfm_list_not_empty
|
|
ld a, (mb_free_list+1)
|
|
cp 0
|
|
jp nz, gfm_list_not_empty
|
|
gfm_list_empty:
|
|
ld hl, (mb_next_frame_num)
|
|
add hl, hl
|
|
add hl, hl
|
|
add hl, hl
|
|
add hl, hl
|
|
push hl
|
|
ld bc, (mb_next_frame_num)
|
|
inc bc
|
|
ld (mb_next_frame_num), bc
|
|
call get_mb_ptr
|
|
push hl
|
|
pop ix
|
|
pop hl
|
|
push hl
|
|
inc hl
|
|
/* push hl */
|
|
/* pop iy */
|
|
link_loop:
|
|
ld (ix + 0), l
|
|
ld (ix + 1), h
|
|
inc hl
|
|
inc ixh
|
|
ld a, ixh
|
|
cp 0xef
|
|
jp nz, link_loop
|
|
link_loop_done:
|
|
ld (ix + 0), 0
|
|
ld (ix + 1), 0
|
|
pop hl
|
|
ld (mb_free_list), hl
|
|
ld bc, (mb_free_list)
|
|
inc bc
|
|
ld (mb_free_list), bc
|
|
ret
|
|
gfm_list_not_empty:
|
|
ld a, (mb_free_list)
|
|
ld (temp), a
|
|
ld a, (mb_free_list + 1)
|
|
ld (temp + 1), a
|
|
ld hl, (mb_free_list)
|
|
call get_mb_ptr
|
|
push hl
|
|
pop ix
|
|
ld a, (ix + 0)
|
|
ld (mb_free_list), a
|
|
ld a, (ix + 1)
|
|
ld (mb_free_list + 1), a
|
|
ld hl, (temp)
|
|
xor a
|
|
ld (temp), a
|
|
ld (temp + 1), a
|
|
ret
|
|
|
|
; Clobbers A, BC, DE, and IX
|
|
get_mb_ptr:
|
|
ld a, h
|
|
srl a
|
|
srl a
|
|
srl a
|
|
srl a
|
|
srl a
|
|
srl a
|
|
ld b, a
|
|
sla a
|
|
add a, b
|
|
ld ix, mb_frame_list_frames
|
|
ld b, 0
|
|
ld c, a
|
|
add ix, bc
|
|
ld b, (ix + 0)
|
|
ld a, b
|
|
cp 0
|
|
jp z, gmbp_no_frame_list_frame
|
|
ld b, (ix + 0)
|
|
ld e, (ix + 1)
|
|
ld d, (ix + 2)
|
|
ld c, 0xE
|
|
push ix
|
|
call set_frame
|
|
pop ix
|
|
gmbp_has_frame_list_frame:
|
|
push hl
|
|
ld a, h
|
|
and 0x3F
|
|
ld h, a
|
|
srl h
|
|
rr l
|
|
srl h
|
|
rr l
|
|
ld a, l
|
|
and 0xFC
|
|
ld l, a
|
|
ld a, h
|
|
or 0xE0
|
|
ld h, a
|
|
ld b, (hl)
|
|
ld a, b
|
|
cp 0
|
|
jp z, gmbp_no_frame
|
|
inc hl
|
|
ld e, (hl)
|
|
inc hl
|
|
ld d, (hl)
|
|
ld c, 0xE
|
|
call set_frame
|
|
gmbp_has_frame:
|
|
pop hl
|
|
ld a, l
|
|
and 0xF
|
|
or 0xE0
|
|
ld h, a
|
|
ld l, 0x0
|
|
gmbp_done:
|
|
ret
|
|
gmbp_no_frame_list_frame:
|
|
push hl
|
|
push ix
|
|
call get_free_frame
|
|
pop ix
|
|
push hl
|
|
pop de
|
|
ld (ix + 0), c
|
|
ld (ix + 1), e
|
|
ld (ix + 2), d
|
|
pop hl
|
|
ld b, c
|
|
ld c, 0xE
|
|
push ix
|
|
call set_frame
|
|
pop ix
|
|
push bc
|
|
push de
|
|
push hl
|
|
ld bc, 0x1000
|
|
ld de, 0xE000
|
|
ld h, d
|
|
ld l, e
|
|
ld (hl), 0 ; Zero out the first byte in the segment ( Acts as a 'seed' for the zeroing )
|
|
ldir
|
|
gbmp_no_flf_zeroed:
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
jp gmbp_has_frame_list_frame
|
|
gmbp_no_frame:
|
|
push hl
|
|
push ix
|
|
call get_free_frame
|
|
pop ix
|
|
push hl
|
|
pop de
|
|
pop hl
|
|
push bc
|
|
push de
|
|
ld b, (ix + 0)
|
|
ld e, (ix + 1)
|
|
ld d, (ix + 2)
|
|
ld c, 0xE
|
|
call set_frame
|
|
pop de
|
|
pop bc
|
|
ld (hl), c
|
|
inc hl
|
|
ld (hl), e
|
|
inc hl
|
|
ld (hl), d
|
|
dec hl
|
|
dec hl
|
|
ld b, c
|
|
ld c, 0xE
|
|
push ix
|
|
call set_frame
|
|
pop ix
|
|
push bc
|
|
push de
|
|
push hl
|
|
ld bc, 0x1000
|
|
ld de, 0xE000
|
|
ld h, d
|
|
ld l, e
|
|
ld (hl), 0 ; Zero out the first byte in the segment ( Acts as a 'seed' for the zeroing )
|
|
ldir
|
|
gbmp_no_f_zeroed:
|
|
pop hl
|
|
pop de
|
|
pop bc
|
|
jp gmbp_has_frame
|
|
|
|
temp: .ds.b 5
|
|
mb_free_list: .ds.b 2
|
|
|
|
mb_frame_list_frames: .ds.b 3*4
|
|
mb_next_frame_num: .ds.b 2
|