;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 ", * } 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 lda ROM_MACHINEID ; requires ROM read cmp #$06 bne @NotGS sec 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 ; now bit 4 = 1 if VidHD ; bit 5 = 1 if IIgs ; bit 6 = 1 if 128K ; bit 7 = 1 if joystick ; and all other bits are 0 (we'll set bit 3 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 ; Since we know we are on IIgs, let's also force Mono Mode off lda NEWVIDEO and #$DF sta NEWVIDEO ; Bit 5=1 for B/W double hi-res lda #$00 sta MONOCOLOR ; bit 7=1 disables color + ; 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 #19 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_VIDHD then CR & print 'VidHD' lda zpMachineStatus and #HAS_VIDHD beq + +LDADDR LoadingVidHD 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 $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 ; requires RAM1 write jsr BuildVBLFunction ; requires ROM read, RAM1 write txa beq @done_with_mb and #HAS_STEREO beq @mb_mono +LDADDR LoadingMockingboardStereo bne @mb_print @mb_mono +LDADDR LoadingMockingboardStereo @mb_print jsr LoadingPrint ; requires ROM read ; if Mockingboard AND HAS_SPEECH then print CR & '...and it talks!' txa 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.memcheck.a" !source "src/hw.joystick.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" LoadingVidHD +PSTRING "\rVidHD" 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 ; A = #$08 or #$00 ora MachineStatus ; requires RAM1 read sta MachineStatus ; set bit 3 of MachineStatus ; requires RAM1 write rol rol rol rol and #%00000110 tax ; X in (0,2,4,6) ldy kGameCounts, x sty GameCount ; store total game count based on based on (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) lda kSearchIndexLo, x sta @searchIndexSrc+1 ; set up search index record based on (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-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 kSearchIndexRecord00 !byte >kSearchIndexRecord01 !byte >kSearchIndexRecord10 !byte >kSearchIndexRecord11 kSearchCacheLo !byte kSearchCacheRecord00 !byte >kSearchCacheRecord01 !byte >kSearchCacheRecord10 !byte >kSearchCacheRecord11 kSearchIndexRecord00 !source "src/index/search00.idx.a" kSearchIndexRecord01 !source "src/index/search01.idx.a" kSearchIndexRecord10 !source "src/index/search10.idx.a" kSearchIndexRecord11 !source "src/index/search11.idx.a" kSearchCacheRecord00 !source "src/index/cache00.idx.a" kSearchCacheRecord01 !source "src/index/cache01.idx.a" kSearchCacheRecord10 !source "src/index/cache10.idx.a" kSearchCacheRecord11 !source "src/index/cache11.idx.a" kGameCounts !source "src/index/count00.a" !source "src/index/count01.a" !source "src/index/count10.a" !source "src/index/count11.a"