.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 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