; 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 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 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 ld de, ShuffleDeckSetup ld a, e ld [hl+], a ld a, d ld [hl+], a ld hl, SCENE_UPDATE ld de, ShuffleDeckUpdate ld a, e ld [hl+], a ld a, d ld [hl+], a ld hl, SCENE_DRAW ld de, ShuffleDeckDraw ld a, e ld [hl+], a ld a, d ld [hl+], a ld hl, SCENE_TEARDOWN 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 ld b, 144 call AwaitLine call SCENE_SETUP - 1 Loop: di ; 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 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 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 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" INCLUDE "ShuffleDeckScreen.inc" Instructions: call Instructions + 2 ret