diff options
Diffstat (limited to 'src/home/sgb.asm')
-rw-r--r-- | src/home/sgb.asm | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/src/home/sgb.asm b/src/home/sgb.asm new file mode 100644 index 0000000..6df9095 --- /dev/null +++ b/src/home/sgb.asm @@ -0,0 +1,272 @@ +; setup SNES memory $810-$867 and palette +InitSGB: + ld hl, MaskEnPacket_Freeze + call SendSGB + ld hl, DataSndPacket1 + call SendSGB + ld hl, DataSndPacket2 + call SendSGB + ld hl, DataSndPacket3 + call SendSGB + ld hl, DataSndPacket4 + call SendSGB + ld hl, DataSndPacket5 + call SendSGB + ld hl, DataSndPacket6 + call SendSGB + ld hl, DataSndPacket7 + call SendSGB + ld hl, DataSndPacket8 + call SendSGB + ld hl, Pal01Packet_InitSGB + call SendSGB + ld hl, MaskEnPacket_Cancel + call SendSGB + ret + +DataSndPacket1: + sgb DATA_SND, 1 ; sgb_command, length + dwb $085d, $00 ; destination address, bank + db $0b ; number of bytes to write + db $8c, $d0, $f4, $60, $00, $00, $00, $00, $00, $00, $00 ; data bytes + +DataSndPacket2: + sgb DATA_SND, 1 ; sgb_command, length + dwb $0852, $00 ; destination address, bank + db $0b ; number of bytes to write + db $a9, $e7, $9f, $01, $c0, $7e, $e8, $e8, $e8, $e8, $e0 ; data bytes + +DataSndPacket3: + sgb DATA_SND, 1 ; sgb_command, length + dwb $0847, $00 ; destination address, bank + db $0b ; number of bytes to write + db $c4, $d0, $16, $a5, $cb, $c9, $05, $d0, $10, $a2, $28 ; data bytes + +DataSndPacket4: + sgb DATA_SND, 1 ; sgb_command, length + dwb $083c, $00 ; destination address, bank + db $0b ; number of bytes to write + db $f0, $12, $a5, $c9, $c9, $c8, $d0, $1c, $a5, $ca, $c9 ; data bytes + +DataSndPacket5: + sgb DATA_SND, 1 ; sgb_command, length + dwb $0831, $00 ; destination address, bank + db $0b ; number of bytes to write + db $0c, $a5, $ca, $c9, $7e, $d0, $06, $a5, $cb, $c9, $7e ; data bytes + +DataSndPacket6: + sgb DATA_SND, 1 ; sgb_command, length + dwb $0826, $00 ; destination address, bank + db $0b ; number of bytes to write + db $39, $cd, $48, $0c, $d0, $34, $a5, $c9, $c9, $80, $d0 ; data bytes + +DataSndPacket7: + sgb DATA_SND, 1 ; sgb_command, length + dwb $081b, $00 ; destination address, bank + db $0b ; number of bytes to write + db $ea, $ea, $ea, $ea, $ea, $a9, $01, $cd, $4f, $0c, $d0 ; data bytes + +DataSndPacket8: + sgb DATA_SND, 1 ; sgb_command, length + dwb $0810, $00 ; destination address, bank + db $0b ; number of bytes to write + db $4c, $20, $08, $ea, $ea, $ea, $ea, $ea, $60, $ea, $ea ; data bytes + +MaskEnPacket_Freeze: + sgb MASK_EN, 1 ; sgb_command, length + db MASK_EN_FREEZE_SCREEN + ds $0e + +MaskEnPacket_Cancel: + sgb MASK_EN, 1 ; sgb_command, length + db MASK_EN_CANCEL_MASK + ds $0e + +Pal01Packet_InitSGB: + sgb PAL01, 1 ; sgb_command, length + rgb 28, 28, 24 + rgb 20, 20, 16 + rgb 8, 8, 8 + rgb 0, 0, 0 + rgb 31, 0, 0 + rgb 15, 0, 0 + rgb 7, 0, 0 + db $00 + +Pal23Packet_0b00: + sgb PAL23, 1 ; sgb_command, length + rgb 0, 31, 0 + rgb 0, 15, 0 + rgb 0, 7, 0 + rgb 0, 0, 0 + rgb 0, 0, 31 + rgb 0, 0, 15 + rgb 0, 0, 7 + db $00 + +AttrBlkPacket_0b10: + sgb ATTR_BLK, 1 ; sgb_command, length + db 1 ; number of data sets + ; Control Code, Color Palette Designation, X1, Y1, X2, Y2 + db ATTR_BLK_CTRL_INSIDE + ATTR_BLK_CTRL_LINE, 1 << 0 + 2 << 2, 5, 5, 10, 10 ; data set 1 + ds 6 ; data set 2 + ds 2 ; data set 3 + +; send SGB packet at hl (or packets, if length > 1) +SendSGB: + ld a, [hl] + and $7 + ret z ; return if packet length is 0 + ld b, a ; length (1-7) + ld c, LOW(rJOYP) +.send_packets_loop + push bc + ld a, $0 + ld [$ff00+c], a + ld a, P15 | P14 + ld [$ff00+c], a + ld b, SGB_PACKET_SIZE +.send_packet_loop + ld e, $8 + ld a, [hli] + ld d, a +.read_byte_loop + bit 0, d + ld a, P14 ; '1' bit + jr nz, .transfer_bit + ld a, P15 ; '0' bit +.transfer_bit + ld [$ff00+c], a + ld a, P15 | P14 + ld [$ff00+c], a + rr d + dec e + jr nz, .read_byte_loop + dec b + jr nz, .send_packet_loop + ld a, P15 ; stop bit + ld [$ff00+c], a + ld a, P15 | P14 + ld [$ff00+c], a + pop bc + dec b + jr nz, .send_packets_loop + ld bc, 4 + call Wait + ret + +; SGB hardware detection +; return carry if SGB detected and disable multi-controller mode before returning +DetectSGB: + ld bc, 60 + call Wait + ld hl, MltReq2Packet + call SendSGB + ldh a, [rJOYP] + and %11 + cp SNES_JOYPAD1 + jr nz, .sgb + ld a, P15 + ldh [rJOYP], a + ldh a, [rJOYP] + ldh a, [rJOYP] + ld a, P15 | P14 + ldh [rJOYP], a + ld a, P14 + ldh [rJOYP], a + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + ld a, P15 | P14 + ldh [rJOYP], a + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + and %11 + cp SNES_JOYPAD1 + jr nz, .sgb + ld hl, MltReq1Packet + call SendSGB + or a + ret +.sgb + ld hl, MltReq1Packet + call SendSGB + scf + ret + +MltReq1Packet: + sgb MLT_REQ, 1 ; sgb_command, length + db MLT_REQ_1_PLAYER + ds $0e + +MltReq2Packet: + sgb MLT_REQ, 1 ; sgb_command, length + db MLT_REQ_2_PLAYERS + ds $0e + +; fill v*Tiles1 and v*Tiles2 with data at hl +; write $0d sequences of $80,$81,$82,...,$94 separated each by $0c bytes to v*BGMap0 +; send the SGB packet at de +Func_0bcb: + di + push de +.wait_vblank + ldh a, [rLY] + cp LY_VBLANK + 3 + jr nz, .wait_vblank + ld a, LCDC_BGON | LCDC_OBJON | LCDC_WIN9C00 + ldh [rLCDC], a + ld a, %11100100 + ldh [rBGP], a + ld de, v0Tiles1 + ld bc, v0BGMap0 - v0Tiles1 +.tiles_loop + ld a, [hli] + ld [de], a + inc de + dec bc + ld a, b + or c + jr nz, .tiles_loop + ld hl, v0BGMap0 + ld de, $000c + ld a, $80 + ld c, $0d +.bgmap_outer_loop + ld b, $14 +.bgmap_inner_loop + ld [hli], a + inc a + dec b + jr nz, .bgmap_inner_loop + add hl, de + dec c + jr nz, .bgmap_outer_loop + ld a, LCDC_BGON | LCDC_OBJON | LCDC_WIN9C00 | LCDC_ON + ldh [rLCDC], a + pop hl + call SendSGB + ei + ret + +; loops 63000 * bc cycles (~15 * bc ms) +Wait: + ld de, 1750 +.loop + nop + nop + nop + dec de + ld a, d + or e + jr nz, .loop + dec bc + ld a, b + or c + jr nz, Wait + ret |