Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;hl=source offset
- ;de=target offset
- ;bc=length
- SECTION "Mem copy during HBLANK", ROM0[$1c39]
- ;this subroutine can copy to VRAM safely at any time
- mem_copy_safe:
- ldh a, [rLCDC]
- and LCDCF_ON
- jr nz, .mem_copy_safe_start
- jp mem_copy ;if LCD is off we can copy at any time, call the basic mem_copy
- ;check how many bytes we are trying to copy
- .mem_copy_safe_start:
- ld a, b
- or a
- jr nz, .start_copying_three_bytes ;there are at least 256 bytes to copy, start copying three bytes
- ld a,c
- cp 3
- jr c, .check_if_2_or_1_bytes_remaining ;if c<3, there are only 2 or 1 bytes
- .start_copying_three_bytes:
- call copy_three_bytes_during_hblank
- jr z, .copy_finished ;if bc%3==0, then there are no more bytes to copy, return (this could be replaced by ret z???)
- .check_if_2_or_1_bytes_remaining:
- ld a, c
- cp 2
- jr nz, .start_copying_last_byte ;there is only a byte to copy
- call copy_two_bytes_during_hblank
- jr .copy_finished ;the last 2 bytes were copied (this could be replaced by ret???)
- .start_copying_last_byte:
- call copy_last_byte_during_hblank
- .copy_finished:
- ret
- copy_three_bytes_during_hblank:
- ld a,b
- or a
- jr nz, _1c66 ;there are at least 256 bytes to copy, start copying
- ld a, c
- cp a, $03
- ret c ;there are less than 3 bytes to copy, return
- _1c66:
- push bc
- ld c, [hl]
- inc hl
- ld b, [hl]
- inc hl
- ld a, [hli]
- push hl
- ld l, e
- ld h, d
- ld d, a
- ;c, b and d=three bytes to copy
- .wait_for_non_vblank:
- ldh a, [rLY]
- cp a, 142
- jr nc, .wait_for_non_vblank
- di
- .wait_for_hblank1:
- ld a,[rSTAT]
- and STATF_LCD
- jr z, .wait_for_hblank1 ;do not continue if we are halfway hblank (as there wouldn't be enough time for 3 bytes)
- .wait_for_hblank2:
- ldh a,[rSTAT]
- and STATF_LCD
- jr nz, .wait_for_hblank2 ;do not continue if we aren't in hblank yet
- ld [hl],c
- inc hl
- ld [hl],b
- inc hl
- ld [hl],d
- ei
- inc hl
- ld e,l
- ld d,h
- pop hl
- pop bc
- dec bc
- dec bc
- dec bc
- ld a,b
- or c
- jr nz, copy_three_bytes_during_hblank
- ret
- copy_two_bytes_during_hblank:
- ld a,b
- or a
- jr nz, _1c9e ;there are at least 256 bytes to copy, start copying (however, it shouldn't never get here at this point, so might not be needed?)
- ld a,c
- cp a,$02
- ret c ;there are less than 2 bytes to copy, return
- _1c9e:
- push bc
- ld c,[hl]
- inc hl
- ld b,[hl]
- inc hl
- push hl
- ld l,e
- ld h,d
- ;c and b=two bytes to copy
- .wait_for_non_vblank:
- ldh a, [rLY]
- cp a, 142
- jr nc, .wait_for_non_vblank
- di
- .wait_for_hblank1:
- ld a,[rSTAT]
- and STATF_LCD
- jr z, .wait_for_hblank1 ;do not continue if either OAM or VRAM (vblank) are not in use
- .wait_for_hblank2:
- ldh a,[rSTAT]
- and STATF_LCD
- jr nz, .wait_for_hblank2 ;do not continue if we aren't in hblank yet
- ld [hl], c
- inc hl
- ld [hl], b
- ei
- inc hl
- ld e,l
- ld d,h
- pop hl
- pop bc
- dec bc
- dec bc
- ld a,b
- or c
- jr nz,copy_two_bytes_during_hblank
- ret
- copy_last_byte_during_hblank:
- ld a,b
- or a
- jr nz,_1cd1 ;there are at least 256 bytes to copy, start copying (however, it shouldn't never get here at this point, so might not be needed?)
- ld a,c
- cp a,$01
- ret c ;there are no bytes to copy, return
- _1cd1:
- push bc
- ld c,[hl]
- inc hl
- push hl
- ld l,e
- ld h,d
- ;c=single byte to copy
- .wait_for_non_vblank:
- ldh a, [rLY]
- cp a, 142
- jr nc, .wait_for_non_vblank
- di
- .wait_for_hblank1:
- ld a,[rSTAT]
- and STATF_LCD
- jr z, .wait_for_hblank1 ;do not continue if either OAM or VRAM (vblank) are not in use
- .wait_for_hblank2:
- ldh a,[rSTAT]
- and STATF_LCD
- jr nz, .wait_for_hblank2 ;do not continue if we aren't in hblank yet
- ld [hl],c
- ei
- inc hl
- ld e,l
- ld d,h
- pop hl
- pop bc
- dec bc
- ld a,b
- or c
- jr nz, copy_last_byte_during_hblank
- ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement