async subsystem :)
This commit is contained in:
parent
1226ee7345
commit
97432b1c2b
@ -14,6 +14,7 @@ TheFool:
|
|||||||
dw FoolMap
|
dw FoolMap
|
||||||
dw FoolTilesEnd - FoolTiles
|
dw FoolTilesEnd - FoolTiles
|
||||||
dw FoolTiles
|
dw FoolTiles
|
||||||
|
|
||||||
FoolTiles:
|
FoolTiles:
|
||||||
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||||
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$00,$01,$00,$02
|
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$00,$01,$00,$02
|
||||||
|
260
Async.inc
Normal file
260
Async.inc
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
def vAsyncAF equ $ff80
|
||||||
|
def vAsyncHL EQU $ff82
|
||||||
|
def vAsyncDE EQU $ff84
|
||||||
|
def vAsyncBC equ $ff86
|
||||||
|
def vAsyncPC equ $ff88
|
||||||
|
def vAsyncNext equ $ff8a
|
||||||
|
def vAsyncAfter equ $ff8c
|
||||||
|
|
||||||
|
def SAFE_ASYNC_START EQU 144
|
||||||
|
def SAFE_ASYNC_END EQU 151
|
||||||
|
|
||||||
|
DoInAsyncVBlank:
|
||||||
|
di
|
||||||
|
push af
|
||||||
|
|
||||||
|
ld a, l
|
||||||
|
ldh [vAsyncHL], a
|
||||||
|
ld a, h
|
||||||
|
ldh [vAsyncHL+1], a
|
||||||
|
ld a, e
|
||||||
|
ldh [vAsyncDE], a
|
||||||
|
ld a, d
|
||||||
|
ldh [vAsyncDE+1], a
|
||||||
|
ld a, c
|
||||||
|
ldh [vAsyncBC], a
|
||||||
|
ld a, b
|
||||||
|
ldh [vAsyncBC+1], a
|
||||||
|
|
||||||
|
pop hl
|
||||||
|
ld a, l
|
||||||
|
ldh [vAsyncAF], a
|
||||||
|
ld a, h
|
||||||
|
ldh [vAsyncAF+1], a
|
||||||
|
|
||||||
|
; set pu the next call!
|
||||||
|
ldh a, [vAsyncNext]
|
||||||
|
ldh [vAsyncPC], a
|
||||||
|
ldh a, [vAsyncNext+1]
|
||||||
|
ldh [vAsyncPC+1], a ; put next into pc
|
||||||
|
ldh a, [vAsyncAfter]
|
||||||
|
ldh [vAsyncNext], a
|
||||||
|
ldh a, [vAsyncAfter+1]
|
||||||
|
ldh [vAsyncNext+1], a ; puut after into next
|
||||||
|
ld a, 0
|
||||||
|
ldh [vAsyncAfter], a ; unless this gets overwritten later, end execution after that
|
||||||
|
ldh [vAsyncAfter+1], a
|
||||||
|
|
||||||
|
ld a, LOW(DoInAsyncVBlank_EnterThread)
|
||||||
|
ld [INTERRUPT_LCD], a
|
||||||
|
ld a, HIGH(DoInAsyncVBlank_EnterThread)
|
||||||
|
ld [INTERRUPT_LCD + 1], a; set interrupt handler to "ENTER THREAD"
|
||||||
|
ld a, SAFE_ASYNC_START ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
|
ld [rLYC], a ; set LYC
|
||||||
|
ld hl, rIE
|
||||||
|
set 1, [hl] ; enable vblank
|
||||||
|
ld hl, rSTAT
|
||||||
|
set 6, [hl] ; set the stat interrupt to LYC mode
|
||||||
|
ld hl, rIF
|
||||||
|
res 1, [hl] ; clear the interrupt so we don't immediately fire it
|
||||||
|
ei
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
DoInAsyncVBlank_EnterThread:
|
||||||
|
;stack looks like:
|
||||||
|
;c113 (SMC int @ LYC 90 pc), 004b (hw int @ LYC 90 pc), outer context pc
|
||||||
|
|
||||||
|
push hl
|
||||||
|
push bc
|
||||||
|
push de
|
||||||
|
push af
|
||||||
|
|
||||||
|
;af, de, bc, hl, c113 (SMC interrupt pc), 004b (hardwired interrput pc), outer context pc
|
||||||
|
|
||||||
|
; check if there's anything queued up for next execution
|
||||||
|
ldh a, [vAsyncPC]
|
||||||
|
ld l, a
|
||||||
|
ldh a, [vAsyncPC+1]
|
||||||
|
ld h, a
|
||||||
|
or a, l
|
||||||
|
jp z, DoInAsyncVBlank_EndThread ; if nothing is queued up, jump to cleanup
|
||||||
|
|
||||||
|
ld a, LOW(DoInAsyncVBlank_ExitThread)
|
||||||
|
ld [INTERRUPT_LCD], a
|
||||||
|
ld a, HIGH(DoInAsyncVBlank_ExitThread)
|
||||||
|
ld [INTERRUPT_LCD+1], a
|
||||||
|
ld a, SAFE_ASYNC_END ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
|
ld [rLYC], a ; set lcd interrupt handler to EXIT SAFE MODE on line 153
|
||||||
|
|
||||||
|
; what if our async thread calls return?
|
||||||
|
; we need to have a PC to return to. if that happens, we will want to
|
||||||
|
; reti.
|
||||||
|
ld hl, DoInAsyncVBlank_EarlyReturn
|
||||||
|
push hl ; address for if the thread retrns
|
||||||
|
|
||||||
|
ldh a, [vAsyncPC]
|
||||||
|
ld l, a
|
||||||
|
ldh a, [vAsyncPC+1]
|
||||||
|
ld h, a
|
||||||
|
push hl ; put vAsyncPC on the stack! for jumping to it!
|
||||||
|
; stack looks like: vasyncpc, early return, af, de, bc, hll, SMC interrput pc, hardwired interrupt pc, outer context pc
|
||||||
|
|
||||||
|
ldh a, [vAsyncAF]
|
||||||
|
ld l, a
|
||||||
|
ldh a, [vAsyncAF+1]
|
||||||
|
ld h, a
|
||||||
|
push hl
|
||||||
|
|
||||||
|
ldh a, [vAsyncHL]
|
||||||
|
ld l, a
|
||||||
|
ldh a, [vAsyncHL+1]
|
||||||
|
ld h, a
|
||||||
|
ldh a, [vAsyncDE]
|
||||||
|
ld e, a
|
||||||
|
ldh a, [vAsyncDE+1]
|
||||||
|
ld d, a
|
||||||
|
ldh a, [vAsyncBC]
|
||||||
|
ld c, a
|
||||||
|
ldh a, [vAsyncBC+1]
|
||||||
|
ld b, a
|
||||||
|
|
||||||
|
pop af; putting vAsyncAF into af requires this hoop-jumping
|
||||||
|
|
||||||
|
ei
|
||||||
|
ret ; "return" to the vAsyncPC wee put on the stack previously.
|
||||||
|
; this is more or less a jump, not a return.
|
||||||
|
; is that the source of our problems?
|
||||||
|
; after this instruction executes, stack looks like:
|
||||||
|
; early return, af, de, bc, hl, PC (smc int), PC (hardwired int), PC (outer context)
|
||||||
|
; and we'll be in the async thread, executing
|
||||||
|
|
||||||
|
DoInAsyncVBlank_EarlyReturn:
|
||||||
|
; stack:
|
||||||
|
; af, de, bc, hl, PC (smc int @ LYC90), PC (hw int @ LYC 90), PC (outer context)
|
||||||
|
PRINTln "early return handle is ", DoInAsyncVBlank_EarlyReturn
|
||||||
|
; save state of registers
|
||||||
|
di
|
||||||
|
push af
|
||||||
|
|
||||||
|
ld a, l
|
||||||
|
ldh [vAsyncHL], a
|
||||||
|
ld a, h
|
||||||
|
ldh [vAsyncHL+1], a
|
||||||
|
ld a, e
|
||||||
|
ldh [vAsyncDE], a
|
||||||
|
ld a, d
|
||||||
|
ldh [vAsyncDE+1], a
|
||||||
|
ld a, c
|
||||||
|
ldh [vAsyncBC], a
|
||||||
|
ld a, b
|
||||||
|
ldh [vAsyncBC+1], a
|
||||||
|
|
||||||
|
pop hl
|
||||||
|
ld a, l
|
||||||
|
ldh [vAsyncAF], a
|
||||||
|
ld a, h
|
||||||
|
ldh [vAsyncAF+1], a
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; set pu the next call!
|
||||||
|
ldh a, [vAsyncNext]
|
||||||
|
ldh [vAsyncPC], a
|
||||||
|
ldh a, [vAsyncNext+1]
|
||||||
|
ldh [vAsyncPC+1], a ; put next into pc
|
||||||
|
ldh a, [vAsyncAfter]
|
||||||
|
ldh [vAsyncNext], a
|
||||||
|
ldh a, [vAsyncAfter+1]
|
||||||
|
ldh [vAsyncNext+1], a ; puut after into next
|
||||||
|
ld a, 0
|
||||||
|
ldh [vAsyncAfter], a ; unless this gets overwritten later, end execution after that
|
||||||
|
ldh [vAsyncAfter+1], a
|
||||||
|
|
||||||
|
ld a, LOW(DoInAsyncVBlank_EnterThread) ; set up next call
|
||||||
|
ld [INTERRUPT_LCD], a
|
||||||
|
ld a, HIGH(DoInAsyncVBlank_EnterThread)
|
||||||
|
ld [INTERRUPT_LCD+1], a
|
||||||
|
ld a, SAFE_ASYNC_START
|
||||||
|
ld [rLYC], a
|
||||||
|
|
||||||
|
; restore the pre-interrupt registers, return and enable interrupts
|
||||||
|
pop af
|
||||||
|
pop de
|
||||||
|
pop bc
|
||||||
|
pop hl
|
||||||
|
reti
|
||||||
|
|
||||||
|
DoInAsyncVBlank_EndThread:
|
||||||
|
; end execution of the thread by disabling the interrupt
|
||||||
|
; and restore the state for the outer thread
|
||||||
|
ld hl, rIE
|
||||||
|
res 1, [hl] ; disable STAT/vblank interrupt
|
||||||
|
pop af
|
||||||
|
pop de
|
||||||
|
pop bc
|
||||||
|
pop hl
|
||||||
|
reti
|
||||||
|
|
||||||
|
DoInAsyncVBlank_ExitThread:
|
||||||
|
; at this point, it's an interrpt being called from inside the interrupt
|
||||||
|
; our stack probably looks like this:
|
||||||
|
; PC (smc int), PC (hardwired int), PC (inside thread), early return, af, de, bc, hl, PC (smc int), PC (hardwired int), PC (outer context)
|
||||||
|
; first, save the interrpt thread registers.
|
||||||
|
push af
|
||||||
|
|
||||||
|
ld a, l
|
||||||
|
ldh [vAsyncHL], a
|
||||||
|
ld a, h
|
||||||
|
ldh [vAsyncHL+1], a
|
||||||
|
ld a, e
|
||||||
|
ldh [vAsyncDE], a
|
||||||
|
ld a, d
|
||||||
|
ldh [vAsyncDE+1], a
|
||||||
|
ld a, c
|
||||||
|
ldh [vAsyncBC], a
|
||||||
|
ld a, b
|
||||||
|
ldh [vAsyncBC+1], a
|
||||||
|
|
||||||
|
pop hl
|
||||||
|
ld a, l
|
||||||
|
ldh [vAsyncAF], a
|
||||||
|
ld a, h
|
||||||
|
ldh [vAsyncAF+1], a
|
||||||
|
|
||||||
|
;god i'm such a genius
|
||||||
|
; this was called as an interrupt inside the interrupt
|
||||||
|
;so our stack looks like this:
|
||||||
|
; PC (smc int), PC (hardwired int), PC (inside thread), early return, af, de, bc, hl, PC (smc int), PC (hardwired int), PC (outer context)
|
||||||
|
; we've got the two PCs from the inner interrupt call stack.
|
||||||
|
; get rid of them! we're running without handrails! i know what i'm doing! I hope!
|
||||||
|
pop hl
|
||||||
|
pop hl
|
||||||
|
; now, save the interrupt thread's pc., which is on the stack from this
|
||||||
|
; interrupt being called.
|
||||||
|
pop hl
|
||||||
|
ld a, l
|
||||||
|
ldh [vAsyncPC], a
|
||||||
|
ld a, h
|
||||||
|
ldh [vAsyncPC+1], a
|
||||||
|
; now we are done with this entire execution of thread. now we need to set up
|
||||||
|
; the next execution of this thread.
|
||||||
|
ld a, LOW(DoInAsyncVBlank_EnterThread)
|
||||||
|
ld [INTERRUPT_LCD], a
|
||||||
|
ld a, HIGH(DoInAsyncVBlank_EnterThread)
|
||||||
|
ld [INTERRUPT_LCD+1], a
|
||||||
|
ld a, SAFE_ASYNC_START ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
|
ld [rLYC], a ; set lcd interrupt handler to EXIT SAFE MODE on line 153
|
||||||
|
|
||||||
|
;at present the stack looks like:
|
||||||
|
; early return, af, de, bc, hl, pc (smc int @ LYC 90), pc (hardwired int at LYC 90), PC (outer context)
|
||||||
|
; pop the early return and discard it.
|
||||||
|
pop hl
|
||||||
|
; and finally, we can restore the state of the registers to what they were
|
||||||
|
; before this whole handler got called.
|
||||||
|
pop af
|
||||||
|
pop de
|
||||||
|
pop bc
|
||||||
|
pop hl
|
||||||
|
reti ; this is a proper return
|
||||||
|
|
@ -1,17 +1,31 @@
|
|||||||
SECTION "Card Data", ROM0
|
SECTION "Card Data", ROM0
|
||||||
|
|
||||||
Spreads:
|
Spreads:
|
||||||
|
db 5 ; length
|
||||||
.nospread
|
.nospread
|
||||||
db 0
|
db 0
|
||||||
|
db 20, " Nothing "
|
||||||
|
db 20, " This is no spread. "
|
||||||
|
.onecard
|
||||||
|
db 1, $21
|
||||||
|
db 20, " One Card Spread "
|
||||||
|
db 20, " Draw a single card."
|
||||||
.tencard
|
.tencard
|
||||||
db 10, $00, $10, $20, $30, $40, $02, $12, $22, $32, $42
|
db 10, $00, $10, $20, $30, $40, $02, $12, $22, $32, $42
|
||||||
|
db 20, " Ten Card Spread "
|
||||||
|
db 20, "Throw more cards on."
|
||||||
.fivecard
|
.fivecard
|
||||||
db 5, $11, $20, $22, $31, $41
|
db 5, $11, $20, $22, $31, $41
|
||||||
|
db 20, " Horizontal Cross "
|
||||||
|
db 20, " A little spicy. "
|
||||||
.threecard
|
.threecard
|
||||||
db 3, $11, $21, $31
|
db 3, $01, $21, $41
|
||||||
|
db 20, " Three Card Spread "
|
||||||
|
db 20, " Old reliable. "
|
||||||
|
.end
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
db 5
|
db 5 ; length
|
||||||
dw TheFool
|
dw TheFool
|
||||||
dw TheMagician
|
dw TheMagician
|
||||||
dw TheHighPriestess
|
dw TheHighPriestess
|
||||||
|
@ -9,6 +9,8 @@ DEF vSafeCopySTAT EQU vSafeCopyLYC + 1 ; stashes $FF41, the STAT register
|
|||||||
DEF vSafeCopyInterrupt EQU vSafeCopySTAT + 1 ; stashes the previous LCD interrupt
|
DEF vSafeCopyInterrupt EQU vSafeCopySTAT + 1 ; stashes the previous LCD interrupt
|
||||||
DEF vSafeCopyInterruptEnable EQU vSafeCopyInterrupt + 2 ; stashes $FFFF, which interrupts are enabled
|
DEF vSafeCopyInterruptEnable EQU vSafeCopyInterrupt + 2 ; stashes $FFFF, which interrupts are enabled
|
||||||
|
|
||||||
|
DEF SAFE_TRANSFER_START EQU 145
|
||||||
|
DEF SAFE_TRANSFER_END EQU 153
|
||||||
|
|
||||||
CopyRangeSafe:
|
CopyRangeSafe:
|
||||||
; hl is source
|
; hl is source
|
||||||
@ -56,7 +58,7 @@ CopyRangeSafe:
|
|||||||
ld [INTERRUPT_LCD], a
|
ld [INTERRUPT_LCD], a
|
||||||
ld a, h
|
ld a, h
|
||||||
ld [INTERRUPT_LCD + 1], a; set interrupt handler to "ENTER SAFE MODE"
|
ld [INTERRUPT_LCD + 1], a; set interrupt handler to "ENTER SAFE MODE"
|
||||||
ld a, 143 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
ld a, SAFE_TRANSFER_START ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
ld [$ff45], a
|
ld [$ff45], a
|
||||||
ld hl, $ffff
|
ld hl, $ffff
|
||||||
set 1, [hl]
|
set 1, [hl]
|
||||||
@ -88,7 +90,7 @@ CopyRangeSafe_EnterSafeMode:
|
|||||||
ld [INTERRUPT_LCD], a
|
ld [INTERRUPT_LCD], a
|
||||||
ld a, h
|
ld a, h
|
||||||
ld [INTERRUPT_LCD+1], a
|
ld [INTERRUPT_LCD+1], a
|
||||||
ld a, 153 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
ld a, SAFE_TRANSFER_END ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
ld [$ff45], a ; set lcd interrupt handler to EXIT SAFE MODE on line 153
|
ld [$ff45], a ; set lcd interrupt handler to EXIT SAFE MODE on line 153
|
||||||
ldh a, [vSafeCopySource]
|
ldh a, [vSafeCopySource]
|
||||||
ld l, a
|
ld l, a
|
||||||
@ -145,7 +147,7 @@ CopyRangeSafe_CleanUp:
|
|||||||
ld [INTERRUPT_LCD], a
|
ld [INTERRUPT_LCD], a
|
||||||
ld a, h
|
ld a, h
|
||||||
ld [INTERRUPT_LCD+1], a
|
ld [INTERRUPT_LCD+1], a
|
||||||
ld a, 143 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
ld a, SAFE_TRANSFER_START ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
|
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
|
||||||
pop af
|
pop af
|
||||||
pop de
|
pop de
|
||||||
@ -174,7 +176,7 @@ CopyRangeSafe_Done: ; called when the complete transfer is finished,
|
|||||||
ld [INTERRUPT_LCD], a
|
ld [INTERRUPT_LCD], a
|
||||||
ld a, h
|
ld a, h
|
||||||
ld [INTERRUPT_LCD+1], a
|
ld [INTERRUPT_LCD+1], a
|
||||||
ld a, 143 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
ld a, SAFE_TRANSFER_START ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
|
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
|
||||||
pop af
|
pop af
|
||||||
pop de
|
pop de
|
||||||
@ -205,7 +207,7 @@ CopyRangeSafe_Done: ; called when the complete transfer is finished,
|
|||||||
CopyRangeSafe_Return:
|
CopyRangeSafe_Return:
|
||||||
reti
|
reti
|
||||||
|
|
||||||
CopyRangeUnsafe:
|
CopyRangeUnsafe: ; this is threadsafe but not vblank safe
|
||||||
; hl is source
|
; hl is source
|
||||||
; de is destination
|
; de is destination
|
||||||
; bc is length to copy
|
; bc is length to copy
|
||||||
|
@ -40,7 +40,7 @@ CopyTilesSafe:
|
|||||||
ld [INTERRUPT_LCD], a
|
ld [INTERRUPT_LCD], a
|
||||||
ld a, h
|
ld a, h
|
||||||
ld [INTERRUPT_LCD + 1], a; set interrupt handler to "ENTER SAFE MODE"
|
ld [INTERRUPT_LCD + 1], a; set interrupt handler to "ENTER SAFE MODE"
|
||||||
ld a, 148 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
ld a, SAFE_TRANSFER_START ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
ld [$ff45], a
|
ld [$ff45], a
|
||||||
ld hl, $ffff
|
ld hl, $ffff
|
||||||
set 1, [hl]
|
set 1, [hl]
|
||||||
@ -65,7 +65,7 @@ CopyTilesSafe_EnterSafeMode:
|
|||||||
ld [INTERRUPT_LCD], a
|
ld [INTERRUPT_LCD], a
|
||||||
ld a, h
|
ld a, h
|
||||||
ld [INTERRUPT_LCD+1], a
|
ld [INTERRUPT_LCD+1], a
|
||||||
ld a, 153 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
ld a, SAFE_TRANSFER_END ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
ld [$ff45], a ; set lcd interrupt handler to EXIT SAFE MODE on line 153
|
ld [$ff45], a ; set lcd interrupt handler to EXIT SAFE MODE on line 153
|
||||||
ldh a, [vSafeCopySource]
|
ldh a, [vSafeCopySource]
|
||||||
ld l, a
|
ld l, a
|
||||||
@ -120,7 +120,6 @@ CopyTilesSafe_DoneWithLine:
|
|||||||
|
|
||||||
dec b
|
dec b
|
||||||
ld a, b
|
ld a, b
|
||||||
cp a, 0
|
|
||||||
|
|
||||||
ldh [vSafeCopyOriginalCount+1], a ; store the decremented line count
|
ldh [vSafeCopyOriginalCount+1], a ; store the decremented line count
|
||||||
jp nz, CopyTilesSafe_TransferLoop
|
jp nz, CopyTilesSafe_TransferLoop
|
||||||
@ -151,7 +150,7 @@ CopyTilesSafe_CleanUp:
|
|||||||
ld [INTERRUPT_LCD], a
|
ld [INTERRUPT_LCD], a
|
||||||
ld a, h
|
ld a, h
|
||||||
ld [INTERRUPT_LCD+1], a
|
ld [INTERRUPT_LCD+1], a
|
||||||
ld a, 148 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
ld a, SAFE_TRANSFER_START ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
|
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
|
||||||
pop af
|
pop af
|
||||||
pop de
|
pop de
|
||||||
@ -180,7 +179,7 @@ CopyTilesSafe_Done: ; called when the complete transfer is finished,
|
|||||||
ld [INTERRUPT_LCD], a
|
ld [INTERRUPT_LCD], a
|
||||||
ld a, h
|
ld a, h
|
||||||
ld [INTERRUPT_LCD+1], a
|
ld [INTERRUPT_LCD+1], a
|
||||||
ld a, 148 ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
ld a, SAFE_TRANSFER_START ; CHANGE ME TO ADJUST SAFE TRANSFER TIMING
|
||||||
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
|
ld [$ff45], a ; set lcd interrupt handler to ENTER SAFE MODE on line 148
|
||||||
pop af
|
pop af
|
||||||
pop de
|
pop de
|
||||||
@ -213,11 +212,11 @@ CopyTilesSafe_Return:
|
|||||||
|
|
||||||
|
|
||||||
CopyTilesToMapUnsafe:
|
CopyTilesToMapUnsafe:
|
||||||
; copy tiles from where they are linearly packed at an origin (de)
|
; copy tiles from where they are linearly packed at an origin (hl)
|
||||||
; to a rectangle in the tilemap in vram (hl)
|
; to a rectangle in the tilemap in vram (de)
|
||||||
; assuming it has height in b and width in c.
|
; assuming it has height in b and width in c.
|
||||||
push bc
|
push bc
|
||||||
CopyTile:
|
.copyTile
|
||||||
ld a, [hl] ; load from the tile map into a
|
ld a, [hl] ; load from the tile map into a
|
||||||
ld [de], a ; load from a into the destination
|
ld [de], a ; load from a into the destination
|
||||||
inc hl ; this is slower than using hli but i'm trying to work with this here
|
inc hl ; this is slower than using hli but i'm trying to work with this here
|
||||||
@ -226,8 +225,8 @@ CopyTile:
|
|||||||
; check if we've completed a line?
|
; check if we've completed a line?
|
||||||
ld a, 0
|
ld a, 0
|
||||||
or a, c ; check if c is zero, if it's not zero go back and copy more bytes
|
or a, c ; check if c is zero, if it's not zero go back and copy more bytes
|
||||||
jp nz, CopyTile
|
jp nz, .copyTile
|
||||||
DoneWithLine:
|
.doneWithLine
|
||||||
pop bc
|
pop bc
|
||||||
|
|
||||||
ld a, e
|
ld a, e
|
||||||
@ -248,3 +247,44 @@ DoneWithLine:
|
|||||||
cp a, 0
|
cp a, 0
|
||||||
jp nz, CopyTilesToMapUnsafe
|
jp nz, CopyTilesToMapUnsafe
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
CopyTilesToMapThreadsafe:
|
||||||
|
; copy tiles from where they are linearly packed at an origin (hl)
|
||||||
|
; to a rectangle in the tilemap in vram (de)
|
||||||
|
; assuming it has height in b and width in c.
|
||||||
|
di
|
||||||
|
ei
|
||||||
|
nop
|
||||||
|
di
|
||||||
|
push bc
|
||||||
|
.copyTile
|
||||||
|
ld a, [hl] ; load from the tile map into a
|
||||||
|
ld [de], a ; load from a into the destination
|
||||||
|
inc hl ; this is slower than using hli but i'm trying to work with this here
|
||||||
|
inc de
|
||||||
|
dec c
|
||||||
|
; check if we've completed a line?
|
||||||
|
ld a, 0
|
||||||
|
or a, c ; check if c is zero, if it's not zero go back and copy more bytes
|
||||||
|
jp nz, .copyTile
|
||||||
|
.doneWithLine
|
||||||
|
pop bc
|
||||||
|
|
||||||
|
ld a, e
|
||||||
|
add a, 32
|
||||||
|
ld e, a
|
||||||
|
ld a, d
|
||||||
|
adc a, 0
|
||||||
|
ld d, a
|
||||||
|
ld a, e
|
||||||
|
sub a, c
|
||||||
|
ld e, a
|
||||||
|
ld a, d
|
||||||
|
sbc a, 0
|
||||||
|
ld d, a
|
||||||
|
|
||||||
|
dec b
|
||||||
|
ld a, b
|
||||||
|
cp a, 0
|
||||||
|
jp nz, CopyTilesToMapThreadsafe
|
||||||
|
ret
|
@ -9,7 +9,6 @@ ScreenCardRead:
|
|||||||
dw CardReadDraw
|
dw CardReadDraw
|
||||||
dw CardReadTeardown
|
dw CardReadTeardown
|
||||||
|
|
||||||
;; CARD READ PAGE STARTS HERE
|
|
||||||
CardReadSetup:
|
CardReadSetup:
|
||||||
; Turn the LCD off
|
; Turn the LCD off
|
||||||
ld hl, rLCDC
|
ld hl, rLCDC
|
||||||
@ -37,18 +36,8 @@ CardReadSetup:
|
|||||||
ld c, 10 ; width
|
ld c, 10 ; width
|
||||||
call CopyTilesToMapUnsafe
|
call CopyTilesToMapUnsafe
|
||||||
|
|
||||||
ld a, 0
|
|
||||||
ld hl, $c000
|
|
||||||
ld bc, 18*10
|
|
||||||
.buildZeros
|
|
||||||
ld a, 0
|
|
||||||
ld [hl+], a
|
|
||||||
ld a, b
|
|
||||||
or a, c
|
|
||||||
dec bc
|
|
||||||
jp nz, .buildZeros
|
|
||||||
|
|
||||||
ld hl, $c000
|
ld hl, ZEROES
|
||||||
ld de, $9800 + 10
|
ld de, $9800 + 10
|
||||||
ld b, 18
|
ld b, 18
|
||||||
ld c, 10
|
ld c, 10
|
||||||
@ -75,37 +64,25 @@ CardReadSetup:
|
|||||||
|
|
||||||
CardReadUpdate:
|
CardReadUpdate:
|
||||||
ld hl, rMYBTNP
|
ld hl, rMYBTNP
|
||||||
bit 5, [hl]
|
bit 4, [hl]
|
||||||
jp z, .doneWithB
|
jp z, .doneWithB
|
||||||
ld hl, ScreenMainMenu
|
ld hl, ScreenMainMenu
|
||||||
call ChangeScene
|
call ChangeScene
|
||||||
ret
|
ret
|
||||||
.doneWithB
|
.doneWithB
|
||||||
|
ldh a, [vSelectedCardIndex]
|
||||||
|
|
||||||
bit 3, [hl] ; select the down key
|
bit 3, [hl] ; select the down key
|
||||||
jp z, :+ ; skip the following code if down is not pressed
|
jp z, :+ ; skip the following code if down is not pressed
|
||||||
ldh a, [vSelectedCardIndex]
|
|
||||||
inc a ; increment when they press down because the deck has card 0 at the top
|
inc a ; increment when they press down because the deck has card 0 at the top
|
||||||
ldh [vSelectedCardIndex], a
|
|
||||||
:
|
:
|
||||||
bit 2, [hl] ; select up key %0000_0100
|
bit 2, [hl] ; select up key %0000_0100
|
||||||
jp z, :+ ; skip the following code if up is not pressed
|
jp z, :+ ; skip the following code if up is not pressed
|
||||||
ldh a, [vSelectedCardIndex]
|
|
||||||
dec a ; decrement when they press up because the deck has card 0 at the top
|
dec a ; decrement when they press up because the deck has card 0 at the top
|
||||||
ldh [vSelectedCardIndex], a
|
|
||||||
:
|
|
||||||
ldh a, [vSelectedCardIndex] ; load current selected tile index
|
|
||||||
ld hl, Cards ; deck length
|
|
||||||
cp a, [hl] ; ddoes the index equal the deck length?
|
|
||||||
jp nz, :+
|
|
||||||
ld a, 0 ; if the index equals the deck length replace it with zero
|
|
||||||
ldh [vSelectedCardIndex], a
|
|
||||||
:
|
|
||||||
cp a, $FF ; if the tile index is $FF (underflowed from dec)
|
|
||||||
jp nz, :+
|
|
||||||
ld a, [hl]
|
|
||||||
dec a ;replace with deck length - 1
|
|
||||||
ldh [vSelectedCardIndex], a
|
|
||||||
:
|
:
|
||||||
|
ld hl, Cards
|
||||||
|
call ArrayClampLooping
|
||||||
|
ldh [vSelectedCardIndex], a ; load current selected tile index
|
||||||
|
|
||||||
ld hl, rMYBTNP
|
ld hl, rMYBTNP
|
||||||
bit 1, [hl]
|
bit 1, [hl]
|
||||||
@ -140,90 +117,13 @@ CardReadUpdate:
|
|||||||
|
|
||||||
CardReadDraw:
|
CardReadDraw:
|
||||||
; first, we draw the spread minimap
|
; first, we draw the spread minimap
|
||||||
.drawSpread
|
|
||||||
ldh a, [vCurrentSpread]
|
ldh a, [vCurrentSpread]
|
||||||
ld c, a
|
ld c, a
|
||||||
ldh a, [vCurrentSpread+1]
|
ldh a, [vCurrentSpread+1]
|
||||||
ld b, a
|
ld b, a
|
||||||
ld a, [bc]
|
|
||||||
ld e, a
|
|
||||||
ld d, 0
|
|
||||||
|
|
||||||
.foundSpread
|
|
||||||
push de ; length of the spread in e!
|
|
||||||
.drawCard
|
|
||||||
ld a, e
|
|
||||||
cp a, 0
|
|
||||||
jp z, .doneWithSpread
|
|
||||||
inc bc ; first card of spread is after the length of the spread
|
|
||||||
|
|
||||||
ld hl, $9800 + (32*12)+11
|
ld hl, $9800 + (32*12)+11
|
||||||
|
|
||||||
ld a, [bc]
|
|
||||||
swap a
|
|
||||||
and a, %0000_1111
|
|
||||||
ld d, 0
|
|
||||||
ld e, a ; add a to hl
|
|
||||||
add hl, de
|
|
||||||
.doneWithWalkRight
|
|
||||||
ld a, [bc]
|
|
||||||
and a, %0000_1111
|
|
||||||
ld d, 0
|
|
||||||
ld e, 32
|
|
||||||
jp z, .doneWithWalkDown
|
|
||||||
.walkDown
|
|
||||||
dec a
|
|
||||||
add hl, de
|
|
||||||
cp a, 0
|
|
||||||
jp nz, .walkDown
|
|
||||||
.doneWithWalkDown
|
|
||||||
.drawMiniCard
|
|
||||||
ld [hl], $83
|
|
||||||
add hl, de
|
|
||||||
ld [hl], $84
|
|
||||||
.doneDrawingCard
|
|
||||||
pop de
|
|
||||||
dec de
|
|
||||||
ld a, e
|
|
||||||
cp a, 0
|
|
||||||
jp nz, .foundSpread
|
|
||||||
|
|
||||||
.doneWithSpread
|
|
||||||
; highlight the selected card
|
|
||||||
ldh a, [vCurrentSpread]
|
|
||||||
ld l, a
|
|
||||||
ldh a, [vCurrentSpread+1]
|
|
||||||
ld h, a
|
|
||||||
|
|
||||||
ldh a, [vSelectedCardInSpread]
|
ldh a, [vSelectedCardInSpread]
|
||||||
ld d, 0
|
call DrawSpreadMinimap
|
||||||
ld e, a ; index of selected card in spread
|
|
||||||
inc e ; skip length
|
|
||||||
|
|
||||||
add hl, de
|
|
||||||
ld b, h
|
|
||||||
ld c, l ; move location of selected card to bc
|
|
||||||
|
|
||||||
ld hl, $9800 + (32*12)+11
|
|
||||||
ld a, [bc] ; a has card location
|
|
||||||
swap a
|
|
||||||
and a, %0000_1111
|
|
||||||
ld e, a
|
|
||||||
add hl, de ; step right
|
|
||||||
ld e, 32
|
|
||||||
ld a, [bc]
|
|
||||||
and a, %0000_1111
|
|
||||||
jp z, CardReadDraw_DrawSelectedCard
|
|
||||||
:
|
|
||||||
dec a
|
|
||||||
add hl, de ; step down
|
|
||||||
cp a, 0
|
|
||||||
jp nz, :-
|
|
||||||
CardReadDraw_DrawSelectedCard:
|
|
||||||
ld [hl], $85
|
|
||||||
add hl, de
|
|
||||||
ld [hl], $86
|
|
||||||
|
|
||||||
|
|
||||||
; okay now we draw the deck minimap
|
; okay now we draw the deck minimap
|
||||||
ld a, [Cards]
|
ld a, [Cards]
|
||||||
@ -384,8 +284,6 @@ INCLUDE "CopyRangeSafe.inc"
|
|||||||
|
|
||||||
INCLUDE "CopyTilesSafe.inc"
|
INCLUDE "CopyTilesSafe.inc"
|
||||||
|
|
||||||
INCLUDE "CardLibrary.inc"
|
|
||||||
|
|
||||||
SECTION "Tile data", ROM0
|
SECTION "Tile data", ROM0
|
||||||
|
|
||||||
UITiles:
|
UITiles:
|
||||||
|
@ -182,7 +182,11 @@ MainMenuUpdate:
|
|||||||
jp z, .option3
|
jp z, .option3
|
||||||
jp .doneWithMenuSelect
|
jp .doneWithMenuSelect
|
||||||
.option1
|
.option1
|
||||||
jp .doneWithMenuSelect
|
ld a, 0
|
||||||
|
ld [vSelectedSpreadIndex], a
|
||||||
|
ld hl, ScreenSpreadSelect
|
||||||
|
call ChangeScene
|
||||||
|
ret
|
||||||
.option2
|
.option2
|
||||||
jp .doneWithMenuSelect
|
jp .doneWithMenuSelect
|
||||||
.option3
|
.option3
|
||||||
@ -193,7 +197,6 @@ MainMenuUpdate:
|
|||||||
ld hl, ScreenCardRead
|
ld hl, ScreenCardRead
|
||||||
call ChangeScene
|
call ChangeScene
|
||||||
ret
|
ret
|
||||||
jp .doneWithMenuSelect
|
|
||||||
.doneWithMenuSelect
|
.doneWithMenuSelect
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,447 @@
|
|||||||
|
DEF vSelectedSpreadIndex EQU VARIABLES_START
|
||||||
|
DEF vPreviousSpreadIndex EQU vSelectedSpreadIndex + 1
|
||||||
|
def vSelectedSpreadCard equ vPreviousSpreadIndex + 1
|
||||||
|
|
||||||
|
ScreenSpreadSelect:
|
||||||
|
dw SpreadSelectSetup
|
||||||
|
dw SpreadSelectUpdate
|
||||||
|
dw SpreadSelectDraw
|
||||||
|
dw SpreadSelectTeardown
|
||||||
|
|
||||||
|
SpreadSelectSetup:
|
||||||
|
ld a, 0
|
||||||
|
ldh [vSelectedCardInSpread], a
|
||||||
|
ldh [vPreviousSpreadIndex], a
|
||||||
|
ldh [vSelectedSpreadIndex], a
|
||||||
|
|
||||||
|
ld hl, ZEROES
|
||||||
|
ld de, $9800
|
||||||
|
ld b, 18
|
||||||
|
ld c, 20
|
||||||
|
|
||||||
|
ld a, LOW(CopyTilesToMapThreadsafe)
|
||||||
|
ld [vAsyncNext], a
|
||||||
|
ld a, HIGH(CopyTilesToMapThreadsafe)
|
||||||
|
ld [vAsyncNext+1], a
|
||||||
|
ld a, LOW(.loadUITiles)
|
||||||
|
ld [vAsyncAfter], a
|
||||||
|
ld a, HIGH(.loadUITiles)
|
||||||
|
ld [vAsyncAfter+1], a
|
||||||
|
call DoInAsyncVBlank
|
||||||
|
|
||||||
|
ld a, HIGH(ZEROES)
|
||||||
|
ld de, $ffc0
|
||||||
|
call RunDMA
|
||||||
|
ret
|
||||||
|
|
||||||
|
.loadUITiles
|
||||||
|
ld hl, UITiles ; source
|
||||||
|
ld de, $8000 + $80*16; destination of copy
|
||||||
|
ld bc, UITilesEnd - UITiles ; length to copy
|
||||||
|
|
||||||
|
ld a, LOW(CopyRangeUnsafe)
|
||||||
|
ld [vAsyncNext], a
|
||||||
|
ld a, HIGH(CopyRangeUnsafe)
|
||||||
|
ld [vAsyncNext+1], a
|
||||||
|
ld a, LOW(DrawSpreadAsync)
|
||||||
|
ld [vAsyncAfter], a
|
||||||
|
ld a, HIGH(DrawSpreadAsync)
|
||||||
|
ld [vAsyncAfter+1], a
|
||||||
|
ret
|
||||||
|
|
||||||
|
SpreadSelectUpdate:
|
||||||
|
ld hl, rMYBTNP
|
||||||
|
bit 4, [hl]
|
||||||
|
jp z, .doneB
|
||||||
|
ld hl, ScreenMainMenu
|
||||||
|
call ChangeScene
|
||||||
|
ret
|
||||||
|
.doneB
|
||||||
|
ld a, [vSelectedSpreadIndex]
|
||||||
|
|
||||||
|
bit 3, [hl] ; select the down key
|
||||||
|
jp z, .doneDown ; skip the following code if down is not pressed
|
||||||
|
dec a ; increment when they press down because the deck has card 0 at the top
|
||||||
|
.doneDown
|
||||||
|
bit 2, [hl] ; select up key
|
||||||
|
jp z, .doneUp ; skip the following code if up is not pressed
|
||||||
|
inc a ; decrement when they press up because the deck has card 0 at the top
|
||||||
|
.doneUp
|
||||||
|
ld hl, Spreads
|
||||||
|
call ArrayClampLooping
|
||||||
|
ldh [vSelectedSpreadIndex], a ; load current selected tile index
|
||||||
|
|
||||||
|
ld hl, vPreviousSpreadIndex
|
||||||
|
cp a, [hl]
|
||||||
|
ret z ; we're done if previous index is same as new index
|
||||||
|
|
||||||
|
; execute an async call to DrawSpreadAsync.
|
||||||
|
ld a, LOW(DrawSpreadAsync)
|
||||||
|
ld [vAsyncNext], a
|
||||||
|
ld a, HIGH(DrawSpreadAsync)
|
||||||
|
ld [vAsyncNext+1], a
|
||||||
|
|
||||||
|
call DoInAsyncVBlank
|
||||||
|
ret ; return from main thread. go back to looping.
|
||||||
|
|
||||||
|
DrawSpreadAsync:
|
||||||
|
ldh a, [vSelectedSpreadIndex]
|
||||||
|
ldh [vPreviousSpreadIndex], a
|
||||||
|
|
||||||
|
; find the correct spread address
|
||||||
|
ld hl, Spreads
|
||||||
|
inc hl ; skip length of spreads
|
||||||
|
ld a, [vSelectedSpreadIndex]
|
||||||
|
inc a ; we're decing at the start so we inc first to prepare...
|
||||||
|
ld d, 0
|
||||||
|
.findSpread
|
||||||
|
dec a
|
||||||
|
jp z, .spreadFound
|
||||||
|
|
||||||
|
ld e, [hl] ; skip cards in spread
|
||||||
|
inc hl
|
||||||
|
add hl, de
|
||||||
|
|
||||||
|
ld e, [hl] ; skip title of spread
|
||||||
|
inc hl
|
||||||
|
add hl, de
|
||||||
|
|
||||||
|
ld e, [hl] ; skip description
|
||||||
|
inc hl
|
||||||
|
add hl, de
|
||||||
|
|
||||||
|
jp .findSpread
|
||||||
|
.spreadFound
|
||||||
|
ld a, l
|
||||||
|
ld [vCurrentSpread], a
|
||||||
|
ld a, h
|
||||||
|
ld [vCurrentSpread+1], a ; save the current spread (hl) into vcurrentspread.
|
||||||
|
|
||||||
|
ld de, $9800 + 32*4 + 3
|
||||||
|
ld hl, ZEROES
|
||||||
|
ld b, 8
|
||||||
|
ld c, 10
|
||||||
|
|
||||||
|
ld a, LOW(CopyTilesToMapThreadsafe)
|
||||||
|
ld [vAsyncNext], a
|
||||||
|
ld a, HIGH(CopyTilesToMapThreadsafe)
|
||||||
|
ld [vAsyncNext+1], a
|
||||||
|
ld a, LOW(.afterClear)
|
||||||
|
ld [vAsyncAfter], a
|
||||||
|
ld a, HIGH(.afterClear)
|
||||||
|
ld [vAsyncAfter+1], a
|
||||||
|
ret ; return from async execution now that we've registered desire
|
||||||
|
; to call copytilestomapthreadsafe
|
||||||
|
; and then drawspread
|
||||||
|
|
||||||
|
.afterClear
|
||||||
|
ld a, [vCurrentSpread]
|
||||||
|
ld l, a
|
||||||
|
ld a, [vCurrentSpread+1]
|
||||||
|
ld h, a
|
||||||
|
ld d, 0
|
||||||
|
ld e, [hl]
|
||||||
|
inc e
|
||||||
|
add hl, de
|
||||||
|
ld de, $9800 + 32
|
||||||
|
ld a, LOW(PrintString)
|
||||||
|
ld [vAsyncNext], a
|
||||||
|
ld a, HIGH(PrintString)
|
||||||
|
ld [vAsyncNext+1], a
|
||||||
|
ld a, LOW(.afterTitle)
|
||||||
|
ld [vAsyncAfter], a
|
||||||
|
ld a, HIGH(.afterTitle)
|
||||||
|
ld [vAsyncAfter+1], a
|
||||||
|
ret
|
||||||
|
|
||||||
|
.afterTitle
|
||||||
|
ld de, $9800 + (32*2)
|
||||||
|
ld a, LOW(PrintString)
|
||||||
|
ld [vAsyncNext], a
|
||||||
|
ld a, HIGH(PrintString)
|
||||||
|
ld [vAsyncNext+1], a
|
||||||
|
ld a, LOW(.afterDescription)
|
||||||
|
ld [vAsyncAfter], a
|
||||||
|
ld a, HIGH(.afterDescription)
|
||||||
|
ld [vAsyncAfter+1], a
|
||||||
|
ret
|
||||||
|
|
||||||
|
.afterDescription
|
||||||
|
|
||||||
|
ld hl, $9800 + 32*4 + 3
|
||||||
|
ldh a, [vSelectedSpreadCard]
|
||||||
|
ld e, a ; e contains the selected index
|
||||||
|
|
||||||
|
ld a, LOW(DrawSpreadBigAndThreadsafe)
|
||||||
|
ld [vAsyncNext], a
|
||||||
|
ld a, HIGH(DrawSpreadBigAndThreadsafe)
|
||||||
|
ld [vAsyncNext+1], a
|
||||||
|
ld a, LOW(.finishAsyncUpdate)
|
||||||
|
ld [vAsyncAfter], a
|
||||||
|
ld a, HIGH(.finishAsyncUpdate)
|
||||||
|
ld [vAsyncAfter+1], a
|
||||||
|
ret
|
||||||
|
|
||||||
|
.finishAsyncUpdate
|
||||||
|
; signal that we're done with execution of the async thread
|
||||||
|
ld a, 0
|
||||||
|
ld [vAsyncNext], a
|
||||||
|
ld [vAsyncNext+1], a
|
||||||
|
ld [vAsyncAfter], a
|
||||||
|
ld [vAsyncAfter+1], a
|
||||||
|
ret
|
||||||
|
|
||||||
|
SpreadSelectDraw:
|
||||||
|
ret
|
||||||
|
SpreadSelectTeardown:
|
||||||
|
ret
|
||||||
|
|
||||||
|
DrawSpreadBigAndThreadsafe:
|
||||||
|
; hl for location on screen
|
||||||
|
; bc for current spread address ; actually holding that in vCurrentSpread
|
||||||
|
; e for index of selected card
|
||||||
|
di
|
||||||
|
ld a, [vCurrentSpread]
|
||||||
|
ld c, a
|
||||||
|
ld a, [vCurrentSpread+1]
|
||||||
|
ld b, a
|
||||||
|
ld a, [bc]
|
||||||
|
cp a, 0 ; length of spread
|
||||||
|
ret z ; return early if the spread is empty
|
||||||
|
ld d, a ; length of spread in d
|
||||||
|
inc d
|
||||||
|
.drawCards
|
||||||
|
ei
|
||||||
|
nop
|
||||||
|
di
|
||||||
|
dec d
|
||||||
|
jp z, .doneWithSpread ; if we're drawing zero remaining cards, stop drawing
|
||||||
|
inc bc ; step forward
|
||||||
|
push hl ; need this bc drawsmallcard changes hl
|
||||||
|
ld a, [bc]
|
||||||
|
call DrawBigCard
|
||||||
|
pop hl
|
||||||
|
jp .drawCards
|
||||||
|
.doneWithSpread
|
||||||
|
; stack has spread address
|
||||||
|
; d is zero
|
||||||
|
; e should have currently selected index
|
||||||
|
ld b, h
|
||||||
|
ld c, l ; stash hl in bc for a mo; this should be a location in vram
|
||||||
|
|
||||||
|
ld a, [vCurrentSpread]
|
||||||
|
ld l, a
|
||||||
|
ld a, [vCurrentSpread+1]
|
||||||
|
ld h, a
|
||||||
|
;spread address in hl
|
||||||
|
|
||||||
|
inc e ; skip the tiles length
|
||||||
|
|
||||||
|
add hl, de
|
||||||
|
ld a, [hl] ; load card descriptor into a
|
||||||
|
|
||||||
|
ld h, b
|
||||||
|
ld l, c; retrieve vram address
|
||||||
|
ei
|
||||||
|
nop
|
||||||
|
di
|
||||||
|
call DrawBigCardSelected
|
||||||
|
|
||||||
|
ei
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DrawSpreadBig:
|
||||||
|
; hl for location on screen
|
||||||
|
; bc for current spread address
|
||||||
|
; e for index of selected card
|
||||||
|
ld a, [bc]
|
||||||
|
cp a, 0 ; length of spread
|
||||||
|
ret z ; return early if the spread is empty
|
||||||
|
push bc
|
||||||
|
ld d, a ; length of spread in d
|
||||||
|
inc d
|
||||||
|
.drawCards
|
||||||
|
dec d
|
||||||
|
jp z, .doneWithSpread ; if we're drawing zero remaining cards, stop drawing
|
||||||
|
inc bc ; step forward
|
||||||
|
push hl ; need this bc drawsmallcard changes hl
|
||||||
|
ld a, [bc]
|
||||||
|
call DrawBigCard
|
||||||
|
pop hl
|
||||||
|
jp .drawCards
|
||||||
|
.doneWithSpread
|
||||||
|
; stack has spread address
|
||||||
|
; d is zero
|
||||||
|
; e should have currently selected index
|
||||||
|
ld b, h
|
||||||
|
ld c, l ; stash hl in bc for a mo; this should be a location in vram
|
||||||
|
pop hl ; put bc from stack into hl, this is the spread address
|
||||||
|
|
||||||
|
inc e ; skip the tiles length
|
||||||
|
|
||||||
|
add hl, de
|
||||||
|
ld a, [hl]
|
||||||
|
|
||||||
|
ld h, b
|
||||||
|
ld l, c; retrieve
|
||||||
|
;call DrawBigCardSelected
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
DrawBigCard: ; starting from screen location hl, draw a card at
|
||||||
|
;the location described in a
|
||||||
|
; saves de and is therefore not threadsafe
|
||||||
|
push de
|
||||||
|
ld d, a
|
||||||
|
swap a
|
||||||
|
and a, %0000_1111
|
||||||
|
sla a
|
||||||
|
ld e, a
|
||||||
|
|
||||||
|
ld a, d
|
||||||
|
and a, %0000_1111
|
||||||
|
|
||||||
|
ld d, 0
|
||||||
|
add hl, de ; step right
|
||||||
|
|
||||||
|
ld e, 64
|
||||||
|
jp z, .drawCard
|
||||||
|
.stepDown
|
||||||
|
add hl, de ; step down
|
||||||
|
dec a
|
||||||
|
jp nz, .stepDown
|
||||||
|
.drawCard
|
||||||
|
ld de, 32
|
||||||
|
ld [hl], $12
|
||||||
|
inc hl
|
||||||
|
ld [hl], $1e
|
||||||
|
add hl, de
|
||||||
|
ld [hl], $1f
|
||||||
|
dec hl
|
||||||
|
ld [hl], $13
|
||||||
|
add hl, de
|
||||||
|
ld [hl], $13
|
||||||
|
inc hl
|
||||||
|
ld [hl], $1f
|
||||||
|
add hl, de
|
||||||
|
ld [hl], $23
|
||||||
|
dec hl
|
||||||
|
ld [hl], $17
|
||||||
|
|
||||||
|
pop de
|
||||||
|
ret
|
||||||
|
|
||||||
|
DrawBigCardSelected: ; starting from screen location hl, draw a card at
|
||||||
|
;the location described in a
|
||||||
|
push de
|
||||||
|
push af
|
||||||
|
swap a
|
||||||
|
ld d, 0
|
||||||
|
and a, %0000_1111
|
||||||
|
sla a
|
||||||
|
ld e, a
|
||||||
|
add hl, de ; step right
|
||||||
|
|
||||||
|
ld e, 64
|
||||||
|
pop af
|
||||||
|
and a, %0000_1111
|
||||||
|
jp z, .drawCard
|
||||||
|
.stepDown
|
||||||
|
add hl, de ; step down
|
||||||
|
dec a
|
||||||
|
jp nz, .stepDown
|
||||||
|
.drawCard
|
||||||
|
ld de, 32
|
||||||
|
ld [hl], $12
|
||||||
|
inc hl
|
||||||
|
ld [hl], $1e
|
||||||
|
add hl, de
|
||||||
|
ld [hl], $1f
|
||||||
|
dec hl
|
||||||
|
ld [hl], $13
|
||||||
|
add hl, de
|
||||||
|
ld [hl], $13
|
||||||
|
inc hl
|
||||||
|
ld [hl], $1f
|
||||||
|
add hl, de
|
||||||
|
ld [hl], $23
|
||||||
|
dec hl
|
||||||
|
ld [hl], $17
|
||||||
|
|
||||||
|
pop de
|
||||||
|
ret
|
||||||
|
|
||||||
|
DrawSpreadMinimap:
|
||||||
|
; hl for location on screen
|
||||||
|
; bc for current spread address
|
||||||
|
; a for index of selected card
|
||||||
|
push af
|
||||||
|
push bc
|
||||||
|
|
||||||
|
ld a, [bc]
|
||||||
|
ld d, 0
|
||||||
|
ld e, a ; length of spread in de
|
||||||
|
.drawCards
|
||||||
|
ld a, e
|
||||||
|
cp a, 0
|
||||||
|
jp z, .doneWithSpread ; if we're drawing zero remaining cards, stop drawing
|
||||||
|
dec e
|
||||||
|
inc bc ; step forward
|
||||||
|
|
||||||
|
push hl ; need this bc drawsmallcard changes hl
|
||||||
|
push bc
|
||||||
|
ld a, [bc]
|
||||||
|
ld bc, $8384
|
||||||
|
call DrawSmallCard
|
||||||
|
pop bc
|
||||||
|
pop hl
|
||||||
|
|
||||||
|
jp .drawCards
|
||||||
|
.doneWithSpread ; stack has hl, bc, af at the time of jumping here
|
||||||
|
pop bc ; stack: af
|
||||||
|
pop af
|
||||||
|
ld d, 0
|
||||||
|
ld e, a ; index of selected card in spread
|
||||||
|
inc e ; skip the length
|
||||||
|
|
||||||
|
push hl ; stack: hl
|
||||||
|
ld h, b
|
||||||
|
ld l, c ; put bc in hl temporarily so we can add to hl
|
||||||
|
|
||||||
|
add hl, de
|
||||||
|
|
||||||
|
ld a, [hl]
|
||||||
|
pop hl ; stack: empty
|
||||||
|
ld bc, $8586
|
||||||
|
call DrawSmallCard
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
DrawSmallCard: ; starting from screen location hl, draw a card at
|
||||||
|
;the location described in a, top and bottom sprite in b and c
|
||||||
|
push de
|
||||||
|
push af
|
||||||
|
swap a
|
||||||
|
ld d, 0
|
||||||
|
and a, %0000_1111
|
||||||
|
ld e, a
|
||||||
|
add hl, de ; step right
|
||||||
|
|
||||||
|
ld e, 32
|
||||||
|
pop af
|
||||||
|
and a, %0000_1111
|
||||||
|
jp z, .drawCard
|
||||||
|
:
|
||||||
|
dec a
|
||||||
|
add hl, de ; step down
|
||||||
|
cp a, 0
|
||||||
|
jp nz, :-
|
||||||
|
.drawCard
|
||||||
|
ld [hl], b
|
||||||
|
add hl, de
|
||||||
|
ld [hl], c
|
||||||
|
|
||||||
|
pop de
|
||||||
|
ret
|
34
main.asm
34
main.asm
@ -10,6 +10,8 @@ DEF SCENE_TEARDOWN EQU SCENE_DRAW + 4
|
|||||||
|
|
||||||
DEF INTERRUPT_LCD EQU $c111
|
DEF INTERRUPT_LCD EQU $c111
|
||||||
|
|
||||||
|
def ZEROES equ $D000
|
||||||
|
|
||||||
DEF rMYBTN EQU $FFA8
|
DEF rMYBTN EQU $FFA8
|
||||||
DEF rMYBTNP EQU rMYBTN + 1
|
DEF rMYBTNP EQU rMYBTN + 1
|
||||||
DEF rDELTAT EQU rMYBTNP + 1
|
DEF rDELTAT EQU rMYBTNP + 1
|
||||||
@ -30,9 +32,21 @@ SECTION "Header", ROM0[$100]
|
|||||||
EntryPoint:
|
EntryPoint:
|
||||||
; Shut down audio circuitry
|
; Shut down audio circuitry
|
||||||
ld a, 0
|
ld a, 0
|
||||||
ld [rNR52], a ; shut down audio
|
ldh [rNR52], a ; shut down audio
|
||||||
ldh [rDIV], a ; reset timer just in case??
|
ldh [rDIV], a ; reset timer just in case??
|
||||||
|
|
||||||
|
ld a, 0
|
||||||
|
ld hl, ZEROES
|
||||||
|
ld bc, $200
|
||||||
|
.buildZeros
|
||||||
|
ld a, 0
|
||||||
|
ld [hl+], a
|
||||||
|
ld a, b
|
||||||
|
or a, c
|
||||||
|
dec bc
|
||||||
|
jp nz, .buildZeros
|
||||||
|
|
||||||
|
|
||||||
; set up the scene and interrupt vectors
|
; set up the scene and interrupt vectors
|
||||||
ld hl, Instructions
|
ld hl, Instructions
|
||||||
|
|
||||||
@ -101,7 +115,6 @@ EntryPoint:
|
|||||||
call ChangeScene
|
call ChangeScene
|
||||||
|
|
||||||
Loop:
|
Loop:
|
||||||
di
|
|
||||||
; okay this is kinda sketchy. we want a delta time variable.
|
; 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've got two eight-bit counters, one at 4096hz and one at 16384hz
|
||||||
; we can definitely reset the faster counter.
|
; we can definitely reset the faster counter.
|
||||||
@ -156,7 +169,13 @@ Loop:
|
|||||||
|
|
||||||
call SCENE_DRAW - 1 ; hope this takes fewer than 9 scanlines!
|
call SCENE_DRAW - 1 ; hope this takes fewer than 9 scanlines!
|
||||||
; either way it's going to eat into the update timing
|
; either way it's going to eat into the update timing
|
||||||
|
; at this point we want to make sure that scanline 153 has passed
|
||||||
|
; we should check if we're past there and skip this await if necessary
|
||||||
|
ld b, 5
|
||||||
|
call AwaitLine
|
||||||
|
|
||||||
jp Loop
|
jp Loop
|
||||||
|
|
||||||
ChangeScene: ; hl should be a pointer to, in sequence, setup update draw teardown
|
ChangeScene: ; hl should be a pointer to, in sequence, setup update draw teardown
|
||||||
call SCENE_TEARDOWN - 1
|
call SCENE_TEARDOWN - 1
|
||||||
|
|
||||||
@ -199,8 +218,11 @@ ArrayClampLooping: ; loops a to be in the array, assuming hl points to the lengt
|
|||||||
:
|
:
|
||||||
ret ; a is return value
|
ret ; a is return value
|
||||||
|
|
||||||
PrintString: ; write ascii string which has been prefixed by its length.
|
PrintString: ; write ascii string which has been prefixed by its length. at hl
|
||||||
ld b, [hl]
|
ld b, [hl]
|
||||||
|
ld a, b
|
||||||
|
cp a, 0
|
||||||
|
ret z
|
||||||
inc hl
|
inc hl
|
||||||
PrintBChars: ;write ascii characters. will not respect newlines or anything like that
|
PrintBChars: ;write ascii characters. will not respect newlines or anything like that
|
||||||
; hl should be the source of ascii text
|
; hl should be the source of ascii text
|
||||||
@ -240,7 +262,9 @@ run_dma_tail: ; This part must be in HRAM.
|
|||||||
Instructions:
|
Instructions:
|
||||||
call SCENE_UPDATE + 2
|
call SCENE_UPDATE + 2
|
||||||
ret
|
ret
|
||||||
|
INCLUDE "Async.inc"
|
||||||
INCLUDE "ScreenMainMenu.inc"
|
INCLUDE "ScreenMainMenu.inc"
|
||||||
INCLUDE "ScreenCardRead.inc"
|
|
||||||
INCLUDE "ScreenSpreadSelect.inc"
|
INCLUDE "ScreenSpreadSelect.inc"
|
||||||
|
INCLUDE "ScreenCardRead.inc"
|
||||||
|
|
||||||
|
INCLUDE "CardLibrary.inc"
|
||||||
|
Loading…
Reference in New Issue
Block a user