Files
4cade/src/4cade.init.a
T

623 lines
19 KiB
Plaintext
Executable File

;license:MIT
;(c) 2018-2023 by 4am
;
; first-run initialization code
;
; This file is included directly and is run from $2000/main as soon as the
; .SYSTEM file is loaded
;
!src "src/4cade.init.machine.a" ; exits with ROM read, no write
!src "src/4cade.init.screen.a"
; print text title in same place as graphical title will appear
jsr PrintBranding
; proboothd duplicates the above code and jumps here,
; so if you make any changes before this comment, you
; MUST adjust the final JMP in src/proboothd/proboothd.a
!if (* != ProBootEntry) {
!serious "ProBootEntry is wrong, should be ", *
}
BIT $FACA
BIT $FACA
BIT $FAFE
BIT $F82C
BIT $F851 ; work around a ROMx+BOOTi on II+ issue
jsr Has64K ; check for 64K (required)
; exits with ROM read, no write
bcc @enough_mem
ldy #@no64Klen
- lda @s_no64K,y
sta $6B6,y
dey
bpl -
@hang bmi @hang
@s_no64K !scrxor $80,"REQUIRES 64K"
@no64Klen=(*-@s_no64K)-1
@enough_mem
lda #0
sta zpMachineStatus
sta SETC3ROM
jsr HasVidHDCard ; check for VidHD card (allows super hi-res artwork even on non-IIgs machines)
; does not rely on ROM
sta CLRC3ROM
ror zpMachineStatus
bmi @foundVidHD
jsr HasAppletiniCard ; check for Appletini card (allows super hi-res artwork even on non-IIgs machines)
; does not rely on ROM
ror zpMachineStatus
@foundVidHD
pha
lda ROM_MACHINEID ; requires ROM read
cmp #$06
php ; carry set on match
bne @NotGS
jsr $FE1F ; check for IIgs (allows super hi-res artwork)
; requires ROM read
bcs @NotGS
sec
+HIDE_NEXT_BYTE
@NotGS clc
ror zpMachineStatus
jsr Has128K ; check for 128K (allows DHGR slideshows and 128K games)
; exits with ROM read, no write
ror zpMachineStatus
jsr HasJoystick ; check for joystick (absence is OK but we filter out some games that require a joystick)
; requires ROM read
ror zpMachineStatus
plp
bne @NotIIc
lda ROM_MACHINE2C
bne @NotIIc
clc
lda zpMachineStatus
bmi @NoMouse ; if IIc with joystick connected, then skip mouse check (it's either/or)
@NotIIc jsr HasMouse ; check for mouse (also affects filtering)
@NoMouse ror zpMachineStatus
; now bit 3 = 1 if SHR card (VidHD or Appletini)
; bit 4 = 1 if IIgs
; bit 5 = 1 if 128K
; bit 6 = 1 if joystick
; bit 7 = 1 if mouse
; and all other bits are 0 (we'll set bit 2 after copying it to LC RAM)
; IIgs fix for Alternate Display Mode (clear shadow page 2)
lda zpMachineStatus
and #IS_IIGS
beq +
ldx #0
txa
!cpu 65816
- sta $E00800,x ; when Alternate Display Mode is turned off, the "2"s
sta $E00900,x ; displayed on the screen live at $E00800
sta $E00A00,x ; (page "2"/$0800 of IIgs bank $E0)
sta $E00B00,x ; They are initialized by the IIgs boot ROM
inx
bne -
!cpu 6502
+
; accommodate uppercase-only machines (64K ][ and ][+ are supported)
lda ROM_MACHINEID ; requires ROM read
cmp #$A0
beq + ; Spectrum ED
cmp #$06
beq +
lda #$DF
+HIDE_NEXT_2_BYTES
+ lda #$FF
sta zpCharMask
; increase text window width so we can print to the edge of the screen without scrolling
inc $21
; print version or build number in lower right corner
ldx #28
ldy #23
jsr SetCursorPosition ; requires ROM read
+LDADDR LoadingVersion
jsr LoadingPrint ; requires ROM read
!ifndef RELEASE {
lda LoadingBuild
ldx LoadingBuild+1
ldy #0
jsr PrintAsDecimal ; requires ROM read
}
; set up text window so it only covers lower left corner
lda #28
sta $21
lda #18
sta $22
; print machine configuration in lower left corner
ldx #0
ldy #23
jsr SetCursorPosition ; requires ROM read
; if zpMachineStatus AND IS_IIGS then print 'IIgs'
; else if zpMachineStatus AND HAS_128K then print '128K'
; else print '64K'
lda zpMachineStatus
and #IS_IIGS
beq +
+LDADDR LoadingIIgs
bne @printMem
+ lda zpMachineStatus
and #HAS_128K
beq +
+LDADDR Loading128K
bne @printMem
+
+LDADDR Loading64K
@printMem
jsr LoadingPrint ; requires ROM read
; if zpMachineStatus AND HAS_JOYSTICK then CR & print 'joystick'
lda zpMachineStatus
and #HAS_JOYSTICK
beq +
+LDADDR LoadingJoystick
jsr LoadingPrint ; requires ROM read
+
; if (zpMachineStatus AND HAS_MOUSE) but (not IIgs) then CR & print 'mouse'
lda zpMachineStatus
and #IS_IIGS
bne +
lda zpMachineStatus
and #HAS_MOUSE
beq +
+LDADDR LoadingMouse
jsr LoadingPrint ; requires ROM read
+
; if zpMachineStatus AND HAS_SHRCARD then CR & print 'VidHD' or 'Appletini' as appropriate
pla
tay
lda zpMachineStatus
and #HAS_SHRCARD
beq +
cpy #ID_VIDHD
bne @notVidHD
+LDADDR LoadingVidHD
bne @printSHR
@notVidHD
;;cpy ID_APPLETINI
+LDADDR LoadingAppletini
@printSHR
jsr LoadingPrint ; requires ROM read
+
@Relocate
; if zpMachineStatus AND IS_IIGS then check for CFFA
; before performing any further disk access
lda zpMachineStatus
and #IS_IIGS
beq +
jsr HackThaCFFA
+
; initialize and relocate ProRWTS2 to $D400 in LC RAM bank 2
+READ_ROM_WRITE_RAM2
jsr init ; requires RAM2 write
; overwrite ProDOS IRQ handler
sei
lda #<NOIRQ
sta $3FE
lda #>NOIRQ
sta $3FF
cli
; relocate pseudo-ProDOS to LC RAM bank 2
ldx #$00
ldy #>(255 + EvenLasterMover - LastMover)
@LM lda COPYSRC, x
sta COPYDST, x ; requires RAM2 write
inx
bne @LM
inc @LM+2
inc @LM+5
dey
bne @LM
jsr BuildAcceleratorFunction ; requires ROM read
+ST16 @accelSrc
dex
-
@accelSrc=*+1
lda $FDFD,x ; copy (de)acceleration functions to LC RAM bank 2
sta DisableAccelerator,x ; requires RAM2 write
dex
bpl -
; X=FF
; relocate program code to LC RAM bank 1
; since we end at $0000 now, we adjust low offset to avoid destroying zpage
+READ_ROM_WRITE_RAM1
inx
;X=0
@FM lda FirstMover - (RELBASE & $FF), x
sta RELBASE & $FF00, x ; requires RAM1 write
inx
bne @FM
inc @FM+2
inc @FM+5
bne @FM
;X=0
; relocate font data to LC RAM bank 1
ldy #4
@ELM lda FONTSRC, x
sta FONTDST, x ; requires RAM1 write
inx
bne @ELM
inc @ELM+2
inc @ELM+5
dey
bne @ELM
+DISABLE_ACCEL ; cycle counting in Mockingboard detection requires 1MHz
; /!\ macro exits with ROM read, no write
+LDADDR FoundMockingboardCallback
jsr GetMockingboardStuff ; requires ROM read
; /!\ exits with ROM read, no write
+READ_ROM_WRITE_RAM1
stx MockingboardStuff ; save mockingboard slot and type
txa ; requires RAM1 write
php
bmi @mb_speech
asl
bpl @no_speech
lsr
@mb_speech
and #7
ora #$C0
sta SilenceIsGolden + 2
@no_speech
jsr BuildVBLFunction ; requires ROM read, RAM1 write
plp
beq @done_with_mb
+READ_RAM1_NO_WRITE
lda MockingboardStuff ; requires RAM1 read
+READ_ROM_NO_WRITE
and #HAS_STEREO
beq @mb_mono
+LDADDR LoadingMockingboardStereo
bne @mb_print ; always branches
@mb_mono
+LDADDR LoadingMockingboardMono
@mb_print
jsr LoadingPrint ; requires ROM read
; if Mockingboard AND HAS_SPEECH then print CR & '...and it talks!'
+READ_RAM1_NO_WRITE
lda MockingboardStuff ; requires RAM1 read
+READ_ROM_NO_WRITE
and #HAS_SPEECH
beq @done_with_mb
+LDADDR LoadingMockingboardSpeech
jsr LoadingPrint ; requires ROM read
@done_with_mb
+READ_RAM2_NO_WRITE
jsr EnableAccelerator ; requires RAM2 read
jmp OneTimeSetup
; ProRWTS2 has its own function to relocate itself
!source "src/prorwts2.a"
ProRWTSBuffer
; these routines will only be called once, from main memory, before relocating to language card
!source "src/hw.vidhd.a"
!source "src/hw.appletini.a"
!source "src/hw.memcheck.a"
!source "src/hw.joystick.a"
!source "src/hw.mouse.a"
!source "src/hw.mockingboard.a"
SetCursorPosition
stx HTAB
sty VTAB
jmp $FC22
LoadingPrint
+ST16 PTR
ldy #0
lda (PTR),y
sta @max
sty i
- inc i
ldy i
lda (PTR),y
ora #$80
+FORCE_UPPERCASE_IF_REQUIRED
jsr ROM_COUT
ldy i
@max=*+1
cpy #$FD ; SMC
bne -
rts
FoundMockingboardCallback
; in: zp$81 contains slot number in form $Cx
+LDADDR LoadingMockingboard
jsr LoadingPrint
lda $81
and #$0F
ora #$B0
jmp ROM_COUT
NOIRQ rti
!src "src/4cade.branding.a"
!src "src/4cade.version.a"
Loading64K
+PSTRING "64K"
Loading128K
+PSTRING "128K"
LoadingIIgs
+PSTRING "IIgs"
LoadingJoystick
+PSTRING "\rjoystick"
LoadingMouse
+PSTRING "\rmouse"
LoadingVidHD
+PSTRING "\rVidHD"
LoadingAppletini
+PSTRING "\rAppletini"
LoadingMockingboard
+PSTRING "\rMockingboard in slot "
LoadingMockingboardStereo
+PSTRING "\rStereo"
LoadingMockingboardMono
+PSTRING "\rMono"
LoadingMockingboardSpeech
+PSTRING "...and it talks!"
!ifndef RELEASE {
PrintAsDecimal
jsr $FF4A
lda $FDE2
cmp #$EA
bne +
dec @addr+1 ; fix for Laser
+
-- lda #$00
clv
ldx #$18
- cmp #$05
bcc +
sbc #$85
sec
+ rol $45
rol $46
rol $47
rol
dex
bne -
pha
lda #$FD
pha
@addr lda #$E1
pha
bvs --
rts
}
!source "src/hw.accel.a"
!source "src/hw.vbl.init.a"
!source "src/parse.common.a"
OneTimeSetup
+READ_ROM_WRITE_RAM1
lda zpMachineStatus
sta MachineStatus ; save machine status
; requires RAM1 write
and #IS_IIGS
beq @NotGSOS
!cpu 65816
lda $E100BD ; Make sure GS/OS was the boot OS
!cpu 6502
beq @NotGSOS
jsr PrepareGSOS
@NotGSOS
; initialize ProDOS shim
+READ_RAM2_WRITE_RAM2
ldy #$0b
- lda $BF13, y
sta promote + $13, y ; requires RAM2 write
dey
bpl -
; save unit in LC bank 2 while overriding !pseudopc
lda $BF30
sta promote + ProDOS_unit - $bf00 ; requires RAM2 write
; save current directory as 'root'
lda hddopendir+1 ; requires RAM2 read
ldy hddopendir+3 ; requires RAM2 read
sta gRootDirectory+1 ; requires RAM2 write
sty gRootDirectory+3 ; requires RAM2 write
; load raw preferences file into $8000
+READ_RAM1_WRITE_RAM1
jsr LoadFile ; requires RAM1 read
; exits with RAM1 read/write
!word kRootDirectory
!word kGlobalPrefsFilename
- !word $8000
; parse raw preferences file into OKVS data structure
jsr ParseKeyValueList ; requires RAM1 write because that's where gGlobalPrefsStore is
!word gGlobalPrefsStore
!word -
!byte 16
; see if cheats are enabled by default
jsr pref_get ; requires RAM1 read
; sets PTR -> cheat pref value as length-prefixed string '1' or '0'
!word kCheat
!word 0
ldy #1
lda (PTR),y ; A = #$B1 or #$B0
and #1 ; A = #$01 or #$00
asl
asl
asl
asl ; A = #$04 or #$00
ora MachineStatus ; requires RAM1 read
sta MachineStatus ; set bit 2 of MachineStatus
; requires RAM1 write
and #(HAS_MOUSE+HAS_JOYSTICK+HAS_128K)
lsr
lsr
lsr
lsr
tax ; X in (0,2,4,6,8,$A,$C,$E)
ldy kGameCounts, x
sty GameCount ; store total game count based on based on (has-mouse) X (has-joystick) X (has-128K)
; requires RAM1 write
sty SAVE
ldy kGameCounts+1, x
sty GameCount+1 ; requires RAM1 write
sty SAVE+1
lsr
tax ; X in (0,1,2,3,4,5,6,7)
lda kSearchIndexLo, x
sta @searchIndexSrc+1 ; set up search index record based on (has-mouse) X (has-joystick) X (has-128K)
lda kSearchIndexHi, x
sta @searchIndexSrc+2
lda kSearchCacheLo, x
sta @searchCacheSrc+1 ; set up search cache record based on (has-mouse) X (has-joystick) X (has-128K)
lda kSearchCacheHi, x
sta @searchCacheSrc+2
ldy #5
@searchIndexSrc
lda $FDFD, y ; SMC
sta kSearchIndexRecord, y ; requires RAM1 write
@searchCacheSrc
lda $FDFD, y
sta kSearchCacheRecord, y ; requires RAM1 write
dey
bpl @searchIndexSrc
; convert GameCount (word) to VisibleGameCount (3-digit decimal number as ASCII string)
iny ; Y = 0
@outer
lda #0
pha
@inner
lda SAVE
sec
sbc @kPowersOfTen,y
sta SAVE
lda SAVE+1
sbc #0
bcc @digitDone
sta SAVE+1
pla
adc #0
pha
jmp @inner
@digitDone
lda SAVE
adc @kPowersOfTen,y
sta SAVE
pla
ora #$30
sta VisibleGameCount,y ; requires RAM1 write
iny
cpy #$03
bcc @outer
bit CLEARKBD
jmp Reenter ; requires RAM1 or RAM2 read
@kPowersOfTen
!byte 100
!byte 10
!byte 1
kSearchIndexLo
!byte <kSearchIndexRecord000
!byte <kSearchIndexRecord001
!byte <kSearchIndexRecord010
!byte <kSearchIndexRecord011
!byte <kSearchIndexRecord100
!byte <kSearchIndexRecord101
!byte <kSearchIndexRecord110
!byte <kSearchIndexRecord111
kSearchIndexHi
!byte >kSearchIndexRecord000
!byte >kSearchIndexRecord001
!byte >kSearchIndexRecord010
!byte >kSearchIndexRecord011
!byte >kSearchIndexRecord100
!byte >kSearchIndexRecord101
!byte >kSearchIndexRecord110
!byte >kSearchIndexRecord111
kSearchCacheLo
!byte <kSearchCacheRecord000
!byte <kSearchCacheRecord001
!byte <kSearchCacheRecord010
!byte <kSearchCacheRecord011
!byte <kSearchCacheRecord100
!byte <kSearchCacheRecord101
!byte <kSearchCacheRecord110
!byte <kSearchCacheRecord111
kSearchCacheHi
!byte >kSearchCacheRecord000
!byte >kSearchCacheRecord001
!byte >kSearchCacheRecord010
!byte >kSearchCacheRecord011
!byte >kSearchCacheRecord100
!byte >kSearchCacheRecord101
!byte >kSearchCacheRecord110
!byte >kSearchCacheRecord111
kSearchIndexRecord000
!source "build/index/search000.idx.a"
kSearchIndexRecord001
!source "build/index/search001.idx.a"
kSearchIndexRecord010
!source "build/index/search010.idx.a"
kSearchIndexRecord011
!source "build/index/search011.idx.a"
kSearchIndexRecord100
!source "build/index/search100.idx.a"
kSearchIndexRecord101
!source "build/index/search101.idx.a"
kSearchIndexRecord110
!source "build/index/search110.idx.a"
kSearchIndexRecord111
!source "build/index/search111.idx.a"
kSearchCacheRecord000
!source "build/index/cache000.idx.a"
kSearchCacheRecord001
!source "build/index/cache001.idx.a"
kSearchCacheRecord010
!source "build/index/cache010.idx.a"
kSearchCacheRecord011
!source "build/index/cache011.idx.a"
kSearchCacheRecord100
!source "build/index/cache100.idx.a"
kSearchCacheRecord101
!source "build/index/cache101.idx.a"
kSearchCacheRecord110
!source "build/index/cache110.idx.a"
kSearchCacheRecord111
!source "build/index/cache111.idx.a"
kGameCounts
!source "build/index/count000.a"
!source "build/index/count001.a"
!source "build/index/count010.a"
!source "build/index/count011.a"
!source "build/index/count100.a"
!source "build/index/count101.a"
!source "build/index/count110.a"
!source "build/index/count111.a"