gb-tarot/main.asm

196 lines
4.5 KiB
NASM
Raw Normal View History

; FF80 CALL
; FF81 LOW
; FF82 HIGH
; FF83 RET
; pattern repeats for the first 16 bytes so we can have some call vectors for the scene system
DEF SCENE_SETUP EQU $FF81
DEF SCENE_UPDATE EQU SCENE_SETUP + 4 ; call then ret is 3+1 bytes
DEF SCENE_DRAW EQU SCENE_UPDATE + 4
DEF SCENE_TEARDOWN EQU SCENE_DRAW + 4
DEF INTERRUPT_LCD EQU $FF91
DEF rMYBTN EQU $FFA8
DEF rMYBTNP EQU rMYBTN + 1
2025-01-09 15:39:07 -05:00
DEF rDELTAT EQU rMYBTNP + 1
DEF VARIABLES_START EQU rDELTAT+1
INCLUDE "hardware.inc"
SECTION "Interrupts", ROM0[$0]
ds $48 - @, 0
call INTERRUPT_LCD - 1
ret
SECTION "Header", ROM0[$100]
jp EntryPoint
ds $150 - @, 0 ; Make room for the header
EntryPoint:
; Shut down audio circuitry
ld a, 0
2025-01-09 15:39:07 -05:00
ld [rNR52], a ; shut down audio
ldh [rDIV], a ; reset timer just in case??
ld a, [Instructions] ; get the value of a call instruction so we can shove it into our handles
ld hl, SCENE_SETUP - 1
ld [hl], a
ld hl, SCENE_UPDATE - 1
ld [hl], a
ld hl, SCENE_DRAW - 1
ld [hl], a
ld hl, SCENE_TEARDOWN - 1
ld [hl], a
ld hl, INTERRUPT_LCD - 1
ld [hl], a
ld a, [Instructions + 3] ; get the value of a ret instruction
ld hl, SCENE_SETUP + 2
ld [hl], a
ld hl, SCENE_UPDATE + 2
ld [hl], a
ld hl, SCENE_DRAW + 2
ld [hl], a
ld hl, SCENE_TEARDOWN + 2
ld [hl], a
ld hl, INTERRUPT_LCD + 2
ld [hl], a
; set up our scene vectors
ld hl, SCENE_SETUP
2025-01-09 15:39:07 -05:00
ld de, ShuffleDeckSetup
ld a, e
ld [hl+], a
ld a, d
ld [hl+], a
ld hl, SCENE_UPDATE
2025-01-09 15:39:07 -05:00
ld de, ShuffleDeckUpdate
ld a, e
ld [hl+], a
ld a, d
ld [hl+], a
ld hl, SCENE_DRAW
2025-01-09 15:39:07 -05:00
ld de, ShuffleDeckDraw
ld a, e
ld [hl+], a
ld a, d
ld [hl+], a
ld hl, SCENE_TEARDOWN
2025-01-09 15:39:07 -05:00
ld de, ShuffleDeckTeardown
ld a, e
ld [hl+], a
ld a, d
ld [hl+], a
; set up the interrupt vector to just be ret.
ld hl, INTERRUPT_LCD
ld de, INTERRUPT_LCD + 2
ld a, e
ld [hl+], a
ld a, d
ld [hl+], a
2025-01-09 15:39:07 -05:00
ld b, 144
call AwaitLine
call SCENE_SETUP - 1
Loop:
di
2025-01-09 15:39:07 -05:00
; okay this is kinda sketchy. we want a delta time variable.
; we've got two eight-bit counters, one at 4096hz and one at 16384hz
; we can definitely reset the faster counter.
; but! that's gonna overflow every frame.
; however! it should always overflow the same amount
; because we're basically running once per frame (AwaitLine call later)
; if we assume it overflows once per frame, then the total value should be
; 256 + [rDIV]. so if we divide by two (or more!) the total value will be
; 256/2 + [rDIV]/2. so we just have to right shift and add 128.
; or right shift twice and add 64. this loses us precision but we didn't need
; it anyway.
ldh a, [rDIV]
ldh [rDIV], a ; this will reset the timer
sra a
sra a
add a, 64
ldh [rDELTAT], a
xor a, a ; zero a out in one cycle
; store dpad and btn state in the rMYBTN register
ld hl, rP1
ld [hl], P1F_GET_DPAD
ld a, [hl]
ld a, [hl]
ld a, [hl]
ld a, [hl]
cpl
and a, %00001111
ld b, a
ld [hl], P1F_GET_BTN
ld a, [hl]
ld a, [hl]
ld a, [hl]
ld a, [hl]
cpl
and a, %00001111
swap a
or a, b
2025-01-09 15:39:07 -05:00
ld b, a ; put new input state in b
ldh a, [rMYBTN] ; previous input state in a
cpl ; a holds buttons which weren't pressed last frame
and a, b ; select buttons which were pressed this frame, but not last frame
ldh [rMYBTNP], a ; save that as btnp state
ld a, b ; select buttons which were pressed this frame
ldh [rMYBTN], a ; save that as btn state
call SCENE_UPDATE - 1 ; hope this takes not too many scanlines!
ld b, 144
call AwaitLine
2025-01-09 15:39:07 -05:00
call SCENE_DRAW - 1 ; hope this takes fewer than 9 scanlines!
; either way it's going to eat into the update timing
jp Loop
AwaitLine: ; put the line you want to reach in b
ld a, [rLY]
cp b
jp nz, AwaitLine
ret
2025-01-09 15:39:07 -05:00
ArrayClampLooping: ; loops a to be in the array, assuming hl points to the length
cp a, [hl] ; if a == length...
jp nz, :+
ld a, 0 ; set it to 0
:
cp a, $FF ; otherwise if a == $FF...
jp nz, :+
ld a, [hl]
dec a ; then set it to length-1
:
ret ; a is return value
PrintString: ; write ascii string which has been prefixed by its length.
ld b, [hl]
inc hl
PrintBChars: ;write ascii characters. will not respect newlines or anything like that
; hl should be the source of ascii text
; de should be the location in the tile map to start writing at
; b should be the length
ld a, [hli]
or a, %10000000
ld [de], a
inc de
dec b
jp nz, PrintBChars
ret
INCLUDE "CardReadScreen.inc"
2025-01-09 15:39:07 -05:00
INCLUDE "ShuffleDeckScreen.inc"
Instructions:
call Instructions + 2
ret