Add the Super GameBoy code (bank 3C)

This commit is contained in:
Pierre de La Morinerie 2019-09-30 16:48:51 +00:00
parent 577e8bca6a
commit 290219b813
5 changed files with 1629 additions and 5 deletions

View File

@ -62,5 +62,5 @@
- 39: Graphics: photo elements
- 3A: Graphics: photo elements
- 3B: Graphics: photo elements, photo pictures
- 3C: Graphics and code
- 3C: Super GameBoy graphics and code
- 3D: Code

View File

@ -34,10 +34,8 @@ Init::
call LCDOff ; Turn off screen
ld sp, $DFFF ; Init stack pointer
; Call 003C:6A22
ld a, $3C
ld [MBC3SelectBank], a
call $6A22
; Super GameBoy detection and initialization
callsb SuperGameBoyInit
; Clear registers
xor a

271
src/code/super_gameboy.asm Normal file
View File

@ -0,0 +1,271 @@
; Super Game Boy code
;
; TODO:
; - Understand what are the commands sent to the SGB
; - Split out the data in tiles, tilemap and palette
; During initialization, detect the Super Game Boy
; and upload the colored frame data if needed.
SuperGameBoyInit::
; If running on GBC, return immediately
ldh a, [hIsGBC] ; $6A22: $F0 $FE
and a ; $6A24: $A7
ret nz ; $6A25: $C0
; Wait for 30 frames
ld bc, $001E ; $6A26: $01 $1E $00
call WaitForBCFrames ; $6A29: $CD $92 $6B
ld hl, $6A12 ; $6A2C: $21 $12 $6A
call SendUploadCommand ; $6A2F: $CD $51 $6B
call WaitFor3Frames ; $6A32: $CD $86 $6B
; Try to detect the Super GameBoy by reading from the joypad
ld a, [rP1] ; $6A35: $F0 $00
and J_RIGHT | J_LEFT ; $6A37: $E6 $03
cp J_RIGHT | J_LEFT ; $6A39: $FE $03
jr nz, .else_6A76_3C ; $6A3B: $20 $39
ld a, J_B ; $6A3D: $3E $20
ld [rP1], a ; $6A3F: $E0 $00
ld a, [rP1] ; $6A41: $F0 $00
ld a, [rP1] ; $6A43: $F0 $00
ld a, J_A | J_B ; $6A45: $3E $30
ld [rP1], a ; $6A47: $E0 $00
ld a, J_A ; $6A49: $3E $10
ld [rP1], a ; $6A4B: $E0 $00
ld a, [rP1] ; $6A4D: $F0 $00
ld a, [rP1] ; $6A4F: $F0 $00
ld a, [rP1] ; $6A51: $F0 $00
ld a, [rP1] ; $6A53: $F0 $00
ld a, [rP1] ; $6A55: $F0 $00
ld a, [rP1] ; $6A57: $F0 $00
ld a, J_A | J_B ; $6A59: $3E $30
ld [rP1], a ; $6A5B: $E0 $00
ld a, [rP1] ; $6A5D: $F0 $00
ld a, [rP1] ; $6A5F: $F0 $00
ld a, [rP1] ; $6A61: $F0 $00
ld a, [rP1] ; $6A63: $F0 $00
and J_RIGHT | J_LEFT ; $6A65: $E6 $03
cp J_RIGHT | J_LEFT ; $6A67: $FE $03
jr nz, .else_6A76_3C ; $6A69: $20 $0B
ld hl, $6A02 ; $6A6B: $21 $02 $6A
call SendUploadCommand ; $6A6E: $CD $51 $6B
call WaitFor3Frames ; $6A71: $CD $86 $6B
sub a ; $6A74: $97
ret ; $6A75: $C9
.else_6A76_3C:
ld hl, $6A02 ; $6A76: $21 $02 $6A
call SendUploadCommand ; $6A79: $CD $51 $6B
call WaitFor3Frames ; $6A7C: $CD $86 $6B
ld hl, $6860 ; $6A7F: $21 $60 $68
call SendUploadCommand ; $6A82: $CD $51 $6B
ld bc, $0006 ; $6A85: $01 $06 $00
call WaitForBCFrames ; $6A88: $CD $92 $6B
ld hl, $6960 ; $6A8B: $21 $60 $69
call SendUploadCommand ; $6A8E: $CD $51 $6B
ld bc, $0006 ; $6A91: $01 $06 $00
call WaitForBCFrames ; $6A94: $CD $92 $6B
ld hl, $6880 ; $6A97: $21 $80 $68
call SendUploadCommand ; $6A9A: $CD $51 $6B
ld bc, $0006 ; $6A9D: $01 $06 $00
call WaitForBCFrames ; $6AA0: $CD $92 $6B
ld hl, $6890 ; $6AA3: $21 $90 $68
call SendUploadCommand ; $6AA6: $CD $51 $6B
ld bc, $0006 ; $6AA9: $01 $06 $00
call WaitForBCFrames ; $6AAC: $CD $92 $6B
ld hl, $68A0 ; $6AAF: $21 $A0 $68
call SendUploadCommand ; $6AB2: $CD $51 $6B
ld bc, $0006 ; $6AB5: $01 $06 $00
call WaitForBCFrames ; $6AB8: $CD $92 $6B
ld hl, $68B0 ; $6ABB: $21 $B0 $68
call SendUploadCommand ; $6ABE: $CD $51 $6B
ld bc, $0006 ; $6AC1: $01 $06 $00
call WaitForBCFrames ; $6AC4: $CD $92 $6B
ld hl, $68C0 ; $6AC7: $21 $C0 $68
call SendUploadCommand ; $6ACA: $CD $51 $6B
ld bc, $0006 ; $6ACD: $01 $06 $00
call WaitForBCFrames ; $6AD0: $CD $92 $6B
ld hl, $68D0 ; $6AD3: $21 $D0 $68
call SendUploadCommand ; $6AD6: $CD $51 $6B
ld bc, $0006 ; $6AD9: $01 $06 $00
call WaitForBCFrames ; $6ADC: $CD $92 $6B
ld hl, $68E0 ; $6ADF: $21 $E0 $68
call SendUploadCommand ; $6AE2: $CD $51 $6B
ld bc, $0006 ; $6AE5: $01 $06 $00
call WaitForBCFrames ; $6AE8: $CD $92 $6B
ld hl, $68F0 ; $6AEB: $21 $F0 $68
call SendUploadCommand ; $6AEE: $CD $51 $6B
ld bc, $0006 ; $6AF1: $01 $06 $00
call WaitForBCFrames ; $6AF4: $CD $92 $6B
ld hl, $6900 ; $6AF7: $21 $00 $69
call SendUploadCommand ; $6AFA: $CD $51 $6B
ld bc, $0006 ; $6AFD: $01 $06 $00
call WaitForBCFrames ; $6B00: $CD $92 $6B
ld hl, $6910 ; $6B03: $21 $10 $69
call SendUploadCommand ; $6B06: $CD $51 $6B
ld bc, $0006 ; $6B09: $01 $06 $00
call WaitForBCFrames ; $6B0C: $CD $92 $6B
ld hl, $4000 ; $6B0F: $21 $00 $40
ld de, $6930 ; $6B12: $11 $30 $69
call Func_03C_6BA3 ; $6B15: $CD $A3 $6B
ld hl, $5000 ; $6B18: $21 $00 $50
ld de, $6940 ; $6B1B: $11 $40 $69
call Func_03C_6BA3 ; $6B1E: $CD $A3 $6B
ld hl, $6000 ; $6B21: $21 $00 $60
ld de, $6950 ; $6B24: $11 $50 $69
call Func_03C_6BA3 ; $6B27: $CD $A3 $6B
ld hl, vTiles0 ; $6B2A: $21 $00 $80
ld bc, $2000 ; $6B2D: $01 $00 $20
.loop_6B30_3C:
xor a ; $6B30: $AF
ldi [hl], a ; $6B31: $22
dec bc ; $6B32: $0B
ld a, c ; $6B33: $79
or b ; $6B34: $B0
jr nz, .loop_6B30_3C ; $6B35: $20 $F9
ld a, $81 ; $6B37: $3E $81
ld [rLCDC], a ; $6B39: $E0 $40
ld bc, $0006 ; $6B3B: $01 $06 $00
call WaitForBCFrames ; $6B3E: $CD $92 $6B
ld hl, $6870 ; $6B41: $21 $70 $68
call SendUploadCommand ; $6B44: $CD $51 $6B
ld bc, $0006 ; $6B47: $01 $06 $00
call WaitForBCFrames ; $6B4A: $CD $92 $6B
xor a ; $6B4D: $AF
ld [rLCDC], a ; $6B4E: $E0 $40
ret ; $6B50: $C9
SendUploadCommand::
ld a, [hl] ; $6B51: $7E
and %00000111 ; $6B52: $E6 $07
ret z ; $6B54: $C8
ld b, a ; $6B55: $47
ld c, $00 ; $6B56: $0E $00
.Func_03C_6B58::
push bc ; $6B58: $C5
xor a ; $6B59: $AF
ld [$ff00+c], a ; $6B5A: $E2
ld a, $30 ; $6B5B: $3E $30
ld [$ff00+c], a ; $6B5D: $E2
ld b, $10 ; $6B5E: $06 $10
.loop_6B60_3C:
ld e, $08 ; $6B60: $1E $08
ldi a, [hl] ; $6B62: $2A
ld d, a ; $6B63: $57
.loop_6B64_3C:
bit 0, d ; $6B64: $CB $42
ld a, $10 ; $6B66: $3E $10
jr nz, .else_6B6C_3C ; $6B68: $20 $02
ld a, $20 ; $6B6A: $3E $20
.else_6B6C_3C:
ld [$ff00+c], a ; $6B6C: $E2
ld a, $30 ; $6B6D: $3E $30
ld [$ff00+c], a ; $6B6F: $E2
rr d ; $6B70: $CB $1A
dec e ; $6B72: $1D
jr nz, .loop_6B64_3C ; $6B73: $20 $EF
dec b ; $6B75: $05
jr nz, .loop_6B60_3C ; $6B76: $20 $E8
ld a, $20 ; $6B78: $3E $20
ld [$ff00+c], a ; $6B7A: $E2
ld a, $30 ; $6B7B: $3E $30
ld [$ff00+c], a ; $6B7D: $E2
pop bc ; $6B7E: $C1
dec b ; $6B7F: $05
ret z ; $6B80: $C8
call WaitFor3Frames ; $6B81: $CD $86 $6B
jr .Func_03C_6B58 ; $6B84: $18 $D2
WaitFor3Frames::
ld de, $1B58 ; $6B86: $11 $58 $1B
.loop_6B89_3C:
nop ; $6B89: $00
nop ; $6B8A: $00
nop ; $6B8B: $00
dec de ; $6B8C: $1B
ld a, d ; $6B8D: $7A
or e ; $6B8E: $B3
jr nz, .loop_6B89_3C ; $6B8F: $20 $F8
ret ; $6B91: $C9
; Busy-loop the duration required for the number of
; frames in BC.
;
; Inputs:
; - bc: the number of frames to wait for
WaitForBCFrames::
; Inner loop: wait for one frame.
;
; As the LCD screen is off, we can't use VBlank for timing.
; Instead, as we know the number of cycles per frame is 69905,
; let's way for approximately this number of cycles.
ld de, $06D6 ; $6B92: $11 $D6 $06
; Loop while (de-- != 0)
.whileDE
; (the instructions in this loop take 36 clock cycles)
nop ; $6B95: $00
nop ; $6B96: $00
nop ; $6B97: $00
dec de ; $6B98: $1B
ld a, d ; $6B99: $7A
or e ; $6B9A: $B3
jr nz, .whileDE ; $6B9B: $20 $F8
; Repeat the inner loop while the number of frames is > 0
dec bc ; $6B9D: $0B
ld a, b ; $6B9E: $78
or c ; $6B9F: $B1
jr nz, WaitForBCFrames ; $6BA0: $20 $F0
ret ; $6BA2: $C9
Func_03C_6BA3::
push de ; $6BA3: $D5
ld a, $E4 ; $6BA4: $3E $E4
ld [rBGP], a ; $6BA6: $E0 $47
ld de, $8800 ; $6BA8: $11 $00 $88
ld bc, $1000 ; $6BAB: $01 $00 $10
call CopyData ; $6BAE: $CD $14 $29
ld hl, vBGMap0 ; $6BB1: $21 $00 $98
ld de, $000C ; $6BB4: $11 $0C $00
ld a, $80 ; $6BB7: $3E $80
ld c, $0D ; $6BB9: $0E $0D
.loop_6BBB_3C:
ld b, $14 ; $6BBB: $06 $14
.loop_6BBD_3C:
ldi [hl], a ; $6BBD: $22
inc a ; $6BBE: $3C
dec b ; $6BBF: $05
jr nz, .loop_6BBD_3C ; $6BC0: $20 $FB
add hl, de ; $6BC2: $19
dec c ; $6BC3: $0D
jr nz, .loop_6BBB_3C ; $6BC4: $20 $F5
ld a, $81 ; $6BC6: $3E $81
ld [rLCDC], a ; $6BC8: $E0 $40
ld bc, $0005 ; $6BCA: $01 $05 $00
call WaitForBCFrames ; $6BCD: $CD $92 $6B
pop hl ; $6BD0: $E1
call SendUploadCommand ; $6BD1: $CD $51 $6B
ld bc, $0006 ; $6BD4: $01 $06 $00
call WaitForBCFrames ; $6BD7: $CD $92 $6B
xor a ; $6BDA: $AF
ld [rLCDC], a ; $6BDB: $E0 $40
ret ; $6BDD: $C9

1351
src/data/super_gameboy.asm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -316,6 +316,10 @@ section "bank3B",romx[$4000],bank[$3B]
incbin "gfx/photos/photo_elements_3.2bpp"
incbin "gfx/photos/photo_dizzy_link.2bpp"
section "bank3C",romx[$4000],bank[$3C]
include "data/super_gameboy.asm"
include "code/super_gameboy.asm"
; Unused banks; make blank sections so they are filled with $00 instead of $ff to match
; the rom
section "bank3E",romx[$4000],bank[$3E]