2019-09-10 04:04:16 +00:00
|
|
|
;License:MIT
|
2019-06-26 02:44:39 +00:00
|
|
|
;(c) 2018-9 by 4am
|
|
|
|
;
|
|
|
|
; common UI functions
|
|
|
|
;
|
|
|
|
; Public functions
|
2019-07-04 02:27:46 +00:00
|
|
|
; - WaitForKeyFor30Seconds
|
2019-07-03 22:31:50 +00:00
|
|
|
; - GetOffscreenAddress
|
2019-07-04 02:27:46 +00:00
|
|
|
; - LoadTitleOffscreen
|
|
|
|
; - LoadCoverOffscreen
|
2019-09-21 21:35:49 +00:00
|
|
|
; - LoadGameTitleOffscreen
|
|
|
|
; - DrawBrowseUI
|
|
|
|
; - DrawSearchUI
|
2019-07-03 22:31:50 +00:00
|
|
|
; - ShowOtherPage
|
|
|
|
; - ToggleOffscreenPage
|
2019-07-04 02:27:46 +00:00
|
|
|
; - CoverFade
|
2019-06-26 02:44:39 +00:00
|
|
|
; - SoftBell
|
|
|
|
; - Home
|
|
|
|
; - BlankHGR
|
|
|
|
; - BlankDHGR
|
2019-09-10 04:04:16 +00:00
|
|
|
; - ClearOffscreen
|
|
|
|
; - ExecuteTransitionAndWait
|
2019-09-06 19:21:38 +00:00
|
|
|
; - IsSearchKey
|
2019-07-03 22:31:50 +00:00
|
|
|
|
|
|
|
; Public variables
|
|
|
|
; - OffscreenPage
|
|
|
|
; - VisibleGameCount (set during init)
|
2019-06-26 02:44:39 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
!zone {
|
2019-07-04 02:27:46 +00:00
|
|
|
|
2019-07-03 22:31:50 +00:00
|
|
|
OffscreenPage
|
|
|
|
!byte 1 ; 0 = currently showing HGR page 2
|
|
|
|
; (so offscreen is page 1 @ $2000)
|
|
|
|
; 1 = currently showing HGR page 1
|
|
|
|
; (so offscreen is page 2 @ $4000)
|
|
|
|
|
2019-07-08 18:10:11 +00:00
|
|
|
Instructions
|
|
|
|
!text "[Type to search, "
|
|
|
|
!byte $0B
|
|
|
|
!text " to browse] "
|
2019-07-03 22:31:50 +00:00
|
|
|
VisibleGameCount
|
2019-07-08 18:10:11 +00:00
|
|
|
!text "000 games"
|
|
|
|
ReturnToPlay
|
|
|
|
!byte $0D
|
|
|
|
!text " to play"
|
2019-07-03 22:31:50 +00:00
|
|
|
|
2019-09-21 17:41:36 +00:00
|
|
|
kCheatsEnabled = 3 ; index of 'cheats enabled' string in following table
|
|
|
|
kCheatDescriptionLo
|
|
|
|
!byte <sNoCheats
|
|
|
|
!byte <sInfiniteLives
|
|
|
|
!byte <sInfiniteLivesAndWeapons
|
|
|
|
!byte <sCheatsEnabled
|
|
|
|
kCheatDescriptionHi
|
|
|
|
!byte >sNoCheats
|
|
|
|
!byte >sInfiniteLives
|
|
|
|
!byte >sInfiniteLivesAndWeapons
|
|
|
|
!byte >sCheatsEnabled
|
|
|
|
sNoCheats
|
|
|
|
!byte 8
|
|
|
|
!text "no cheat"
|
|
|
|
sInfiniteLives
|
|
|
|
!byte 18
|
|
|
|
!byte $16 ; bolt
|
|
|
|
!text " "
|
|
|
|
!text "infinite lives"
|
|
|
|
!text " "
|
|
|
|
!byte $16 ; bolt
|
|
|
|
sInfiniteLivesAndWeapons
|
|
|
|
!byte 28
|
|
|
|
!byte $16 ; bolt
|
|
|
|
!text " "
|
|
|
|
!text "infinite lives & weapons"
|
|
|
|
!text " "
|
|
|
|
!byte $16 ; bolt
|
|
|
|
sCheatsEnabled
|
|
|
|
!byte 18
|
|
|
|
!byte $16 ; bolt
|
|
|
|
!text " "
|
|
|
|
!text "cheats enabled"
|
|
|
|
!text " "
|
|
|
|
!byte $16 ; bolt
|
|
|
|
sCheatDescriptionPrefix
|
|
|
|
!byte 2
|
|
|
|
!byte $03 ; vertical line
|
|
|
|
!text " "
|
|
|
|
sCheatDescriptionSuffix
|
|
|
|
!byte 2
|
|
|
|
!text " "
|
|
|
|
!byte $03 ; vertical line
|
|
|
|
|
2019-09-10 04:19:07 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; GetOffscreenAddress
|
|
|
|
; get high byte of HGR page that is currently not showing
|
|
|
|
;
|
2019-07-03 22:31:50 +00:00
|
|
|
; in: none
|
|
|
|
; out: A = high byte of offscreen HGR page (#$20 or #$40)
|
|
|
|
; preserves X/Y
|
2019-09-10 04:19:07 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
GetOffscreenAddress
|
2019-07-03 22:31:50 +00:00
|
|
|
lda OffscreenPage
|
|
|
|
beq +
|
|
|
|
lda #$40
|
|
|
|
rts
|
|
|
|
+ lda #$20
|
|
|
|
rts
|
|
|
|
|
2019-09-10 04:19:07 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; LoadTitleOffscreen
|
|
|
|
; load title screen in the HGR page that is currently not showing
|
|
|
|
;
|
|
|
|
; in: none
|
|
|
|
; out: all flags and registers clobbered
|
|
|
|
;------------------------------------------------------------------------------
|
2019-07-04 02:27:46 +00:00
|
|
|
LoadTitleOffscreen
|
|
|
|
+LDADDR .TitleFile
|
|
|
|
bne + ; Always branches, because Y is loaded
|
|
|
|
; last with the high byte of the address,
|
|
|
|
; which is never 0. I miss my 65c02.
|
2019-09-10 04:19:07 +00:00
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; LoadCoverOffscreen
|
|
|
|
; load cover screen in the HGR page that is currently not showing
|
|
|
|
;
|
|
|
|
; in: none
|
|
|
|
; out: all flags and registers clobbered
|
|
|
|
;------------------------------------------------------------------------------
|
2019-07-04 02:27:46 +00:00
|
|
|
LoadCoverOffscreen
|
|
|
|
; clobbers all
|
|
|
|
+LDADDR .CoverFile
|
|
|
|
+
|
2019-09-10 02:38:17 +00:00
|
|
|
+STAY @fname
|
2019-07-04 02:27:46 +00:00
|
|
|
jsr GetOffscreenAddress
|
|
|
|
sta +
|
2019-09-10 02:38:17 +00:00
|
|
|
jsr LoadFile
|
|
|
|
!word kRootDirectory
|
|
|
|
@fname !word $FDFD ; SMC
|
2019-07-04 02:27:46 +00:00
|
|
|
!byte $00
|
|
|
|
+ !byte $FD ; SMC
|
|
|
|
rts
|
|
|
|
.TitleFile
|
|
|
|
!byte 5
|
|
|
|
!text "TITLE"
|
|
|
|
.CoverFile
|
|
|
|
!byte 5
|
|
|
|
!text "COVER"
|
|
|
|
|
2019-09-21 21:35:49 +00:00
|
|
|
LoadGameTitleOffscreen
|
|
|
|
; in: X = game index
|
|
|
|
+LDADDR gGamesListStore
|
|
|
|
jsr okvs_nth
|
|
|
|
+STAY @fname
|
|
|
|
jsr GetOffscreenAddress
|
|
|
|
sta +
|
|
|
|
jsr LoadFile
|
|
|
|
!word kHGRTitleDirectory
|
|
|
|
@fname !word $FDFD ; SMC
|
|
|
|
!byte $00
|
|
|
|
+ !byte $FD ; SMC
|
|
|
|
rts
|
|
|
|
|
2019-09-10 04:19:07 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; CoverFade
|
|
|
|
; load cover screen and animate per-character fade
|
|
|
|
;
|
|
|
|
; in: none
|
|
|
|
; out: all flags and registers clobbered
|
|
|
|
;------------------------------------------------------------------------------
|
2019-07-04 02:27:46 +00:00
|
|
|
CoverFade
|
|
|
|
jsr LoadCoverOffscreen
|
|
|
|
jsr ShowOtherPage
|
|
|
|
lda OffscreenPage
|
|
|
|
bne +
|
|
|
|
jsr LoadCoverOffscreen
|
|
|
|
jsr ShowOtherPage
|
|
|
|
+
|
2019-09-10 02:38:17 +00:00
|
|
|
jsr LoadFile ; load transition effect code at $6000
|
|
|
|
!word kFXDirectory
|
|
|
|
!word @CoverFadeFile
|
|
|
|
!word $6000
|
2019-07-04 02:27:46 +00:00
|
|
|
jmp $6000 ; exit via loaded code
|
|
|
|
@CoverFadeFile
|
|
|
|
!byte 9
|
|
|
|
!text "COVERFADE"
|
|
|
|
|
2019-09-10 04:19:07 +00:00
|
|
|
;------------------------------------------------------------------------------
|
2019-09-21 21:35:49 +00:00
|
|
|
; DrawUIWithoutDots/DrawUI
|
|
|
|
; draw 2- or 4-line UI on the HGR page that is not currently showing, then
|
|
|
|
; show that HGR page
|
2019-09-10 04:19:07 +00:00
|
|
|
;
|
2019-09-21 16:59:56 +00:00
|
|
|
; in: gGameToLaunch = game index, or #$FF if no game is selected
|
2019-09-10 04:19:07 +00:00
|
|
|
; out: all flags and registers clobbered
|
|
|
|
;------------------------------------------------------------------------------
|
2019-09-21 21:35:49 +00:00
|
|
|
DrawUIWithoutDots
|
2019-09-21 17:41:36 +00:00
|
|
|
lda #" "
|
2019-09-21 21:35:49 +00:00
|
|
|
clc
|
|
|
|
bcc +
|
|
|
|
DrawUI
|
|
|
|
lda #$7F
|
|
|
|
sec
|
|
|
|
+ sta @printCursor+1 ; set up cursor printing based on entry point
|
|
|
|
php
|
2019-09-21 17:41:36 +00:00
|
|
|
|
|
|
|
ldy #39
|
|
|
|
- lda #$00 ; horizontal bar character
|
|
|
|
sta UILine1,y ; reset UI line 1 to solid bar
|
|
|
|
sta gPathname,y ; reset cheat UI line 1 to solid bar
|
|
|
|
lda Instructions,y
|
|
|
|
sta UILine2,y ; copy instructions to UI line 2
|
|
|
|
dey
|
|
|
|
bpl -
|
|
|
|
|
|
|
|
ldx gGameToLaunch
|
|
|
|
cpx #$FF ; if no game, nothing more to do on UI line 2
|
|
|
|
beq @doneWithLine2
|
|
|
|
|
|
|
|
+LDADDR gGamesListStore
|
|
|
|
jsr okvs_nth
|
|
|
|
+STAY + ; (A/Y) -> game filename
|
|
|
|
|
|
|
|
jsr okvs_get
|
|
|
|
!word gGamesListStore
|
|
|
|
+ !word $FDFD
|
|
|
|
+STAY SRC ; (SRC) -> game title
|
2019-09-21 16:59:56 +00:00
|
|
|
|
2019-09-21 17:41:36 +00:00
|
|
|
ldy #0 ; copy game title into UI line 2
|
|
|
|
lda (SRC),y
|
|
|
|
sta SAVE ; title length
|
|
|
|
inc SAVE
|
|
|
|
- iny
|
|
|
|
cpy SAVE
|
|
|
|
bcc @printTitleChar
|
|
|
|
beq @printCursor
|
|
|
|
lda #" "
|
|
|
|
+HIDE_NEXT_2_BYTES
|
|
|
|
@printCursor
|
|
|
|
lda #$FD ; SMC
|
|
|
|
+HIDE_NEXT_2_BYTES
|
|
|
|
@printTitleChar
|
|
|
|
lda (SRC),y
|
|
|
|
sta UILine2,y
|
|
|
|
cpy #MaxInputLength+1
|
|
|
|
bcc -
|
|
|
|
|
|
|
|
ldx #8 ; replace games count with 'to play' label
|
|
|
|
- lda ReturnToPlay,x
|
|
|
|
sta UI_ToPlay,x
|
|
|
|
dex
|
|
|
|
bpl -
|
|
|
|
|
|
|
|
@doneWithLine2
|
|
|
|
bit gCheatsEnabled
|
|
|
|
bpl @maybeDrawDots ; if cheat mode is disabled, we don't need
|
|
|
|
; any curves or spaces on UI line 1
|
|
|
|
ldx gGameToLaunch
|
|
|
|
ldy gCheatsAvailable,x
|
|
|
|
cpx #$FF
|
|
|
|
bne +
|
|
|
|
ldy #kCheatsEnabled
|
|
|
|
+
|
|
|
|
lda kCheatDescriptionLo,y
|
|
|
|
sta SAVE
|
|
|
|
lda kCheatDescriptionHi,y
|
|
|
|
sta SAVE+1
|
|
|
|
; (SAVE) -> length-prefixed string
|
|
|
|
; (game-specific description or 'cheats enabled' message)
|
|
|
|
ldy #0
|
|
|
|
lda (SAVE),y ; A = string length
|
|
|
|
clc
|
|
|
|
adc #4 ; extra padding (2 on each side)
|
|
|
|
sta @len
|
|
|
|
lda #40
|
|
|
|
sec
|
|
|
|
sbc @len
|
|
|
|
lsr
|
|
|
|
tax
|
|
|
|
lda #$09 ; rounded bottom-right character
|
|
|
|
sta UILine1,x
|
|
|
|
ldy #1 ; fill the proper width with spaces
|
|
|
|
lda #$20 ; space character
|
|
|
|
- inx
|
|
|
|
sta UILine1,x
|
|
|
|
iny
|
|
|
|
@len=*+1
|
|
|
|
cpy #$FD ; SMC
|
|
|
|
bne -
|
|
|
|
lda #$08 ; rounded bottom-left character
|
|
|
|
sta UILine1,x
|
|
|
|
|
|
|
|
@maybeDrawDots
|
|
|
|
plp
|
|
|
|
bcc @doneHighlight ; if caller asked for no dots, then we're done building UI line 1
|
|
|
|
|
|
|
|
ldx #0
|
|
|
|
ldy #0
|
|
|
|
@dotloop
|
|
|
|
iny
|
|
|
|
lda (SRC),y ; (SRC) still points to game title
|
|
|
|
+LOW_ASCII_TO_LOWER
|
|
|
|
cmp InputBuffer,x
|
|
|
|
bne +
|
|
|
|
lda #$11 ; dot character
|
|
|
|
sta UILine1,y
|
|
|
|
inx
|
|
|
|
cpx InputLength ; if input buffer is exhausted, we're done drawing dots
|
|
|
|
beq @doneHighlight
|
|
|
|
+ inc HTAB
|
|
|
|
cpy SAVE ; if game name is exhausted, we're done drawing dots
|
|
|
|
bne @dotloop
|
|
|
|
@doneHighlight
|
|
|
|
|
|
|
|
lda #22
|
2019-07-03 22:31:50 +00:00
|
|
|
sta VTAB
|
|
|
|
lda OffscreenPage
|
2019-09-21 17:41:36 +00:00
|
|
|
ror
|
|
|
|
php
|
2019-07-03 22:31:50 +00:00
|
|
|
+LDADDR UILine1
|
2019-09-21 17:41:36 +00:00
|
|
|
jsr Draw40Chars ; draw UI line 1 on offscreen page
|
|
|
|
plp
|
2019-07-03 22:31:50 +00:00
|
|
|
+LDADDR UILine2
|
2019-09-21 17:41:36 +00:00
|
|
|
jsr Draw40Chars ; draw UI line 2 on offscreen page
|
2019-09-15 21:55:16 +00:00
|
|
|
|
2019-09-21 17:41:36 +00:00
|
|
|
bit gCheatsEnabled ; if cheats are disabled, then we're done drawing UI
|
2019-09-21 21:35:49 +00:00
|
|
|
bpl @uidone
|
2019-09-21 17:41:36 +00:00
|
|
|
; (SAVE) still points to length-prefixed cheat description
|
|
|
|
ldy #0
|
|
|
|
lda (SAVE),y ; A = length of cheat description
|
|
|
|
clc
|
|
|
|
adc #4 ; extra padding (2 on each side)
|
|
|
|
sta gPathname ; gPathname = length
|
|
|
|
tax
|
|
|
|
lda #$07 ; gPathname+length = top-right rounded corner character
|
|
|
|
sta gPathname,x
|
|
|
|
lda #$06 ; gPathname+1 = top-left rounded corner character
|
|
|
|
sta gPathname+1
|
2019-09-15 21:55:16 +00:00
|
|
|
lda #20
|
|
|
|
sta VTAB
|
|
|
|
lda OffscreenPage
|
|
|
|
ror
|
2019-09-21 17:41:36 +00:00
|
|
|
php
|
2019-09-15 21:55:16 +00:00
|
|
|
+LDADDR gPathname
|
2019-09-21 17:41:36 +00:00
|
|
|
jsr DrawCenteredString ; draw cheat UI line 1
|
2019-09-15 21:55:16 +00:00
|
|
|
|
2019-09-21 17:41:36 +00:00
|
|
|
ldx gGameToLaunch
|
|
|
|
ldy gCheatsAvailable,x
|
|
|
|
cpx #$FF
|
|
|
|
bne +
|
|
|
|
ldy #kCheatsEnabled
|
|
|
|
+ lda kCheatDescriptionLo,y
|
|
|
|
sta SAVE
|
|
|
|
lda kCheatDescriptionHi,y
|
|
|
|
sta SAVE+1
|
|
|
|
; (SAVE) -> length-prefixed cheat description
|
|
|
|
+LDADDR sCheatDescriptionPrefix
|
|
|
|
jsr SetPath
|
|
|
|
+LDAY SAVE
|
|
|
|
jsr AddToPath
|
|
|
|
+LDADDR sCheatDescriptionSuffix
|
|
|
|
jsr AddToPath
|
2019-09-15 21:55:16 +00:00
|
|
|
inc VTAB
|
2019-09-21 17:41:36 +00:00
|
|
|
plp
|
2019-09-15 21:55:16 +00:00
|
|
|
+LDADDR gPathname
|
2019-09-21 21:35:49 +00:00
|
|
|
jsr DrawCenteredString ; draw cheat UI line 2
|
|
|
|
|
|
|
|
@uidone jmp ShowOtherPage
|
2019-07-03 22:31:50 +00:00
|
|
|
|
2019-09-10 04:04:16 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; ClearOffscreen
|
|
|
|
; clear $2000..$3FFF or $4000..$5FFF, depending on which HGR page is not
|
|
|
|
; visible right now
|
|
|
|
; does not change HGR mode
|
|
|
|
;
|
|
|
|
; in: none
|
|
|
|
; out: $2000..$3FFF or $4000..$5FFF cleared
|
|
|
|
; A = 0
|
|
|
|
; X = 0
|
|
|
|
; Y = 0
|
|
|
|
; Z = 1
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
ClearOffscreen
|
|
|
|
jsr GetOffscreenAddress
|
|
|
|
+HIDE_NEXT_2_BYTES
|
|
|
|
.ClearHGR1
|
|
|
|
lda #$20
|
|
|
|
sta @a+2
|
|
|
|
ldx #$20
|
|
|
|
lda #$80
|
|
|
|
ldy #0
|
|
|
|
@a sta $2000,y
|
|
|
|
iny
|
|
|
|
bne @a
|
|
|
|
inc @a+2
|
|
|
|
dex
|
|
|
|
bne @a
|
|
|
|
rts
|
|
|
|
|
2019-09-10 04:19:07 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; ShowOtherPage
|
|
|
|
; switch to the HGR page that is not currently showing
|
|
|
|
;
|
2019-07-03 22:31:50 +00:00
|
|
|
; in: none
|
|
|
|
; out: A = new value of OffscreenPage
|
|
|
|
; preserves X/Y
|
2019-09-10 04:19:07 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
ShowOtherPage
|
2019-07-03 22:31:50 +00:00
|
|
|
jsr ToggleOffscreenPage
|
|
|
|
bne +
|
|
|
|
bit PAGE2 ; show page 2
|
|
|
|
rts
|
|
|
|
+ bit PAGE1 ; show page 1
|
|
|
|
rts
|
|
|
|
|
2019-09-10 04:19:07 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; ToggleOffscreenPage
|
|
|
|
; switch the internal variable that tracks which HGR page is showing
|
|
|
|
; (does not affect screen)
|
|
|
|
;
|
2019-07-03 22:31:50 +00:00
|
|
|
; in: none
|
|
|
|
; out: A = new value of OffscreenPage
|
|
|
|
; preserves X/Y
|
2019-09-10 04:19:07 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
ToggleOffscreenPage
|
2019-07-03 22:31:50 +00:00
|
|
|
lda OffscreenPage
|
|
|
|
eor #$01
|
|
|
|
sta OffscreenPage
|
|
|
|
rts
|
|
|
|
|
2019-06-26 02:44:39 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; SoftBell
|
|
|
|
; yell at the user, but, like, gently
|
|
|
|
;
|
|
|
|
; in: none
|
2019-09-07 18:15:53 +00:00
|
|
|
; out: C clear
|
|
|
|
; Y preserved
|
|
|
|
; A=0
|
|
|
|
; X=0
|
|
|
|
; all flags preserved
|
2019-06-26 02:44:39 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
SoftBell
|
|
|
|
ldx #32
|
|
|
|
- lda #2
|
|
|
|
jsr @wait
|
2019-06-27 14:55:07 +00:00
|
|
|
bit SPEAKER
|
2019-06-26 02:44:39 +00:00
|
|
|
lda #33
|
|
|
|
jsr @wait
|
2019-06-27 14:55:07 +00:00
|
|
|
bit SPEAKER
|
2019-06-26 02:44:39 +00:00
|
|
|
dex
|
|
|
|
bne -
|
2019-09-07 18:15:53 +00:00
|
|
|
clc
|
2019-06-26 02:44:39 +00:00
|
|
|
rts
|
|
|
|
@wait ; identical to $FCA8 ROM routine, but ROM is switched out when we need it
|
|
|
|
sec
|
|
|
|
-- pha
|
|
|
|
- sbc #1
|
|
|
|
bne -
|
|
|
|
pla
|
|
|
|
sbc #1
|
|
|
|
bne --
|
|
|
|
rts
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; Home
|
|
|
|
; clear and display text screen (HARDER THAN IT SOUNDS)
|
|
|
|
;
|
|
|
|
; in: none
|
|
|
|
; out: $0106..$011F clobbered
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
Home
|
2019-09-11 04:26:00 +00:00
|
|
|
MachineStatus = *+1
|
|
|
|
lda #$D1 ; SMC
|
2019-06-26 02:44:39 +00:00
|
|
|
and #SUPPORTS_SHR
|
|
|
|
beq @noSHR
|
2019-06-27 14:55:07 +00:00
|
|
|
lda NEWVIDEO
|
2019-06-30 17:59:06 +00:00
|
|
|
and #$3F
|
|
|
|
sta NEWVIDEO ; get out of SHR mode and linear mode
|
2019-06-28 03:42:01 +00:00
|
|
|
lda #$F0
|
|
|
|
sta TBCOLOR ; white text on black background
|
|
|
|
lda #$00
|
|
|
|
sta CLOCKCTL ; black border
|
2019-06-28 03:50:25 +00:00
|
|
|
sta CLOCKCTL ; set twice for VidHD
|
2019-06-26 02:44:39 +00:00
|
|
|
@noSHR
|
|
|
|
ldx #(@end-@start-1)
|
|
|
|
- lda @start,x
|
|
|
|
sta $106,x
|
|
|
|
dex
|
|
|
|
bpl -
|
|
|
|
jmp $106
|
|
|
|
@start
|
|
|
|
; this will be run from main memory
|
|
|
|
+READ_ROM_NO_WRITE
|
2019-06-27 14:55:07 +00:00
|
|
|
sta CLR80VID ; get out of DHGR mode
|
|
|
|
sta DHIRESOFF ; get out of DHGR mode
|
|
|
|
jsr ROM_TEXT ; TEXT
|
|
|
|
jsr ROM_HOME ; HOME
|
2019-06-26 02:44:39 +00:00
|
|
|
+READ_RAM1_WRITE_RAM1
|
|
|
|
rts
|
|
|
|
@end
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; BlankDHGR
|
|
|
|
; clear and show DHGR page 1 without flickering
|
|
|
|
;
|
|
|
|
; in: none
|
|
|
|
; out: text page clobbered (but screen holes preserved)
|
|
|
|
; $2000..$3FFF/main and /aux cleared
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
BlankDHGR
|
|
|
|
jsr Home
|
|
|
|
jsr .ClearHGR1 ; clear hi-res screen 1
|
2019-06-27 14:55:07 +00:00
|
|
|
sta WRITEAUXMEM
|
2019-06-26 02:44:39 +00:00
|
|
|
jsr .ClearHGR1 ; clear hi-res screen 1 in auxmem
|
2019-06-27 14:55:07 +00:00
|
|
|
sta WRITEMAINMEM
|
|
|
|
sta SET80VID
|
|
|
|
sta DHIRESON
|
2019-09-10 04:04:16 +00:00
|
|
|
bit PAGE1
|
|
|
|
jmp HGRMode
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
2019-09-10 04:24:54 +00:00
|
|
|
; BlankHGR
|
|
|
|
; clear and show HGR page 1 without flickering
|
|
|
|
;
|
|
|
|
; in: none
|
|
|
|
; out: text page clobbered (but screen holes preserved)
|
|
|
|
; $2000..$3FFF cleared
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
BlankHGR
|
|
|
|
jsr Home
|
|
|
|
jsr .ClearHGR1 ; clear hi-res screen 1
|
|
|
|
bit PAGE1 ; show hi-res screen 1 (now blank)
|
|
|
|
; execution falls through here
|
|
|
|
;------------------------------------------------------------------------------
|
2019-09-10 04:04:16 +00:00
|
|
|
; HGRMode
|
|
|
|
; twiddles softswitches to set HGR mode (does not set page 1 or 2)
|
|
|
|
;
|
|
|
|
; in: none
|
|
|
|
; out: all registers preserved
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
HGRMode
|
|
|
|
bit $C057
|
|
|
|
bit $C052
|
|
|
|
bit $C050
|
2019-06-26 02:44:39 +00:00
|
|
|
rts
|
|
|
|
|
2019-09-10 04:04:16 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; ExecuteTransitionAndWait
|
|
|
|
; call transition effect code (address passed in) and wait a period of time
|
|
|
|
; or until the user presses a key
|
|
|
|
;
|
|
|
|
; in: A/Y = address of transition effect code
|
|
|
|
; out: all flags and registers clobbered
|
|
|
|
;------------------------------------------------------------------------------
|
2019-06-26 02:44:39 +00:00
|
|
|
ExecuteTransitionAndWait
|
|
|
|
+STAY @j+1
|
|
|
|
@j jsr $FDFD ; SMC call transition effect code
|
|
|
|
ldx #$20 ; picture is showing so now we wait
|
|
|
|
- lda #0
|
|
|
|
jsr WaitForKeyWithTimeout
|
|
|
|
bmi +
|
|
|
|
dex
|
|
|
|
bpl -
|
2019-09-10 03:04:17 +00:00
|
|
|
+ lda KBD
|
|
|
|
cmp #$95
|
|
|
|
bne +
|
|
|
|
bit CLEARKBD
|
2019-06-26 02:44:39 +00:00
|
|
|
+ rts
|
|
|
|
|
2019-09-06 19:21:38 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; IsSearchKey
|
|
|
|
; test whether accumulator contains a key that might trigger a new textrank
|
|
|
|
; search
|
|
|
|
;
|
|
|
|
; in: A = key
|
|
|
|
; out: A &= 0x7F
|
|
|
|
; Y preserved
|
|
|
|
; X clobbered
|
|
|
|
; Z = 1 if this is a search key
|
|
|
|
; Z = 0 if this is not a search key
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
IsSearchKey
|
|
|
|
and #$7F ; strip high bit for search characters
|
|
|
|
cmp #$30 ; control keys and punctuation ignored
|
|
|
|
bcc @badkey
|
|
|
|
cmp #$3A ; numbers are good input
|
|
|
|
bcc @goodkey
|
|
|
|
cmp #$41 ; more punctuation (also ignored)
|
|
|
|
bcc @badkey
|
|
|
|
cmp #$5B ; uppercase letters are good input
|
|
|
|
bcs +
|
|
|
|
ora #$20 ; convert uppercase letters to lowercase
|
|
|
|
bne @goodkey ; always branches
|
|
|
|
|
|
|
|
+ cmp #$61 ; more punctuation (also ignored)
|
|
|
|
bcc @badkey
|
|
|
|
cmp #$7B ; lowercase letters are good input
|
|
|
|
bcc @goodkey
|
|
|
|
@badkey
|
|
|
|
ldx #1
|
|
|
|
rts
|
|
|
|
@goodkey
|
|
|
|
ldx #0
|
2019-09-10 04:22:28 +00:00
|
|
|
ConvenientlyPlacedRTS
|
2019-09-06 19:21:38 +00:00
|
|
|
rts
|
|
|
|
|
2019-09-10 04:19:07 +00:00
|
|
|
; /!\ keep this last in the file to ensure it doesn't cross a page boundary /!\
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; WaitForKeyFor30Seconds
|
|
|
|
; does what it says on the tin
|
|
|
|
;
|
|
|
|
; in: none
|
|
|
|
; out: if user presses a key before the timer runs out, exits with A = key
|
|
|
|
; otherwise exits via MegaAttractMode
|
|
|
|
; X/Y preserved
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
WaitForKeyFor30Seconds
|
|
|
|
lda #$16 ; initialize timeout counters
|
|
|
|
sta Timeout
|
|
|
|
sta Timeout+1
|
|
|
|
sta Timeout+2
|
|
|
|
@loop
|
|
|
|
lda KBD
|
2019-09-10 04:22:28 +00:00
|
|
|
bmi ConvenientlyPlacedRTS
|
2019-09-10 04:19:07 +00:00
|
|
|
|
|
|
|
inc RNDSEED+1 ; these are only ever incremented, never
|
|
|
|
bne + ; reset (may be used as a pseudorandom
|
|
|
|
inc RNDSEED ; seed)
|
|
|
|
+
|
|
|
|
dec Timeout ; these are a 3-byte timeout counter
|
|
|
|
bne @loop ; that counts down from a number set
|
|
|
|
dec Timeout+1 ; in .ResetInputTimeout and reset
|
|
|
|
bne @loop ; on every keypress (whether or not
|
|
|
|
dec Timeout+2 ; the key leads to an action)
|
|
|
|
bne @loop
|
|
|
|
jsr CoverFade ; no input for ~30 seconds, switch to
|
|
|
|
jmp MegaAttractMode ; mega-attract mode
|
|
|
|
|
2019-06-26 02:44:39 +00:00
|
|
|
}
|