131 lines
3.1 KiB
NASM
131 lines
3.1 KiB
NASM
|
|
SECTION "SGB routines", ROM0
|
|
|
|
; Sends SGB packets to the SGB, assuming we're running on one.
|
|
; @param hl Pointer to the packet data to be sent (can send any number of packets btw)
|
|
; @return hl Points to the end of the packet data
|
|
; @return de Zero
|
|
; @return bc Zero
|
|
; @return a Zero
|
|
SendPackets::
|
|
ld a, [hl] ; Length
|
|
and %111
|
|
ret z
|
|
ld c, a
|
|
|
|
.sendPacket
|
|
call SendPacketNoDelay
|
|
call SGBDelay ; Let the ICD chip rest a bit
|
|
dec c
|
|
jr nz, .sendPacket
|
|
ret
|
|
|
|
|
|
; Sends a SGB packet to the SGB to freeze the screen, assuming we're running on one.
|
|
; Does not perform any delay after sending the packet.
|
|
; Use only if you're not going to send another SGB packet in the next few frames.
|
|
; You're likely to perform some decompression or smth after this
|
|
; @param hl Pointer to the packet data to be sent.
|
|
; @return hl Points to the end of the packet data
|
|
; @return b Zero
|
|
; @return d Zero
|
|
; @return a $30
|
|
; @destroy e
|
|
FreezeSGBScreen::
|
|
ld hl, FreezeScreenPacket
|
|
; Sends a SGB packet to the SGB, assuming it's running on one.
|
|
; Does not perform any delay after sending the packet.
|
|
; Unsuitable to send multi-packet packets.
|
|
; Use only if you're not going to send another SGB packet in the next four frames.
|
|
; Assumes the joypad won't be polled by interrupts during this time, but since the VBlank handler doesn't poll except when waited for, this is fine.
|
|
; @param hl Pointer to the packet data to be sent.
|
|
; @return hl Points to the end of the packet data
|
|
; @return b Zero
|
|
; @return d Zero
|
|
; @return a $30
|
|
; @destroy e
|
|
SendPacketNoDelay::
|
|
; Packet transmission begins by sending $00 then $30
|
|
xor a
|
|
ldh [rP1], a
|
|
ld a, $30
|
|
ldh [rP1], a
|
|
|
|
ld b, SGB_PACKET_SIZE
|
|
.sendByte
|
|
ld d, 8 ; 8 bits in a byte
|
|
ld a, [hli] ; Read byte to send
|
|
ld e, a
|
|
|
|
.sendBit
|
|
ld a, $10 ; 1 bits are sent with $10
|
|
rr e ; Rotate d and get its lower bit, two birds in one stone!
|
|
jr c, .bitSet
|
|
add a, a ; 0 bits are sent with $20
|
|
.bitSet
|
|
ldh [rP1], a
|
|
ld a, $30 ; Terminate pulse
|
|
ldh [rP1], a
|
|
dec d
|
|
jr nz, .sendBit
|
|
|
|
dec b
|
|
jr nz, .sendByte
|
|
|
|
; Packets are terminated by a "STOP" 0 bit
|
|
ld a, $20
|
|
ldh [rP1], a
|
|
ld a, $30
|
|
ldh [rP1], a
|
|
ret
|
|
|
|
SGBDelay::
|
|
ld de, 7000 ; Magic value, apparently
|
|
.loop
|
|
nop
|
|
nop
|
|
nop
|
|
dec de
|
|
ld a, d
|
|
or e
|
|
jr nz, .loop
|
|
ret
|
|
|
|
FreezeScreenPacket:
|
|
sgb_packet MASK_EN, 1, 1
|
|
|
|
|
|
; Fill the $9C00 tilemap with a pattern suitable for SGB _TRN
|
|
; Also sets up the rendering parameters for the transfer
|
|
; Finally, assumes the LCD is **off**
|
|
; @return hl
|
|
FillScreenWithSGBMap::
|
|
xor a
|
|
ldh [hSCY], a
|
|
ldh [hSCX], a
|
|
ld b, a ; ld b, 0
|
|
ld hl, $9C00
|
|
.writeRow
|
|
ld c, SCRN_X_B
|
|
.writeTile
|
|
ld a, b
|
|
ld [hli], a
|
|
inc b
|
|
jr z, .done
|
|
dec c
|
|
jr nz, .writeTile
|
|
ld a, l
|
|
add a, SCRN_VX_B - SCRN_X_B
|
|
ld l, a
|
|
jr nc, .writeRow
|
|
inc h
|
|
jr .writeRow
|
|
.done
|
|
ld a, %11100100
|
|
ldh [hBGP], a
|
|
SetupSGBLCDC::
|
|
ld a, LCDCF_ON | LCDCF_WINOFF | LCDCF_BG8000 | LCDCF_BG9C00 | LCDCF_OBJOFF | LCDCF_BGON
|
|
ldh [rLCDC], a
|
|
ldh [hLCDC], a
|
|
ret
|