;------------------------------- ; Passport ; a 4am hack ; (c) 2016-2022 by 4am ; ; Permission is hereby granted, free of charge, to any ; person obtaining a copy of this software and associated ; documentation files (the "Software"), to deal in the ; Software without restriction, including without limitation ; the rights to use, copy, modify, merge, publish, ; distribute, sublicense, and/or sell copies of the ; furnished to do so, subject to the following conditions: ; ; The above copyright notice and this permission notice ; shall be included in all copies or substantial portions of ; the Software. ; ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY ; KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ; WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR ; PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS ; OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ; OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; ;------------------------------- !cpu 6502 !ifdef RELBASE { *=RELBASE } else { *=$2000 } !ifndef VERBOSE { VERBOSE = $00 ; set to $01 to display API label addresses } !to "../build/passport.tmp",plain !ct "lcase.ct" Relocatable !bin "../build/t00only.pak" NonRelocatable !source "apidefs.a" !source "strings/en.a" !source "id/dos33.a" !source "id/dos32.a" !source "id/dos32lo.a" !source "id/prodos.a" !source "id/pascal.a" !source "id/rdos16.a" !source "id/jsr8b3.a" !source "id/mecc.a" !source "id/datasoft.a" !source "id/tsr.a" !source "id/protecteddos.a" !source "id/encode44.a" !source "id/encode53.a" !source "id/ea.a" !source "id/milliken.a" !source "id/daviddos.a" !source "id/quickdos.a" !source "id/diversidos.a" !source "id/prontodos.a" !source "id/laureate.a" !source "id/micrograms.a" !source "id/volumename.a" !source "id/dinkeydos.a" !source "id/advent.a" !source "id/baudville.a" !source "id/enlightenment.a" !source "id/panglosdos.a" !source "id/davidson.a" !source "id/holle.a" !source "id/phoenix.a" !source "id/jmp600.a" !source "id/555.a" !source "id/trace32.a" !source "id/trace8b3.a" !source "id/trace33p.a" !source "id/trace.a" ; \__ execution falls through !source "universalstyle.a" ; / !source "id/trace33.a" ; \__ execution falls through !source "adstyle.a" ; / !source "crackme.a" ; / !source "id/inspect0.a" !source "print.a" !source "compare.a" !source "modify.a" !source "sectormap.a" !source "write.a" !source "mli.a" !source "ramdisk.a" !source "harddisk.a" ; \__ execution falls through !source "memory.a" ; / !source "slots.a" !source "prefs.a" !source "prefs.save.a" !source "keys.a" !source "cffa.a" !source "progress.a" !source "rwts.a" ; \__ execution falls through !source "memory.clear.a" ; / !source "standarddelivery.a" MainMenu jsr Cleanup ; RAM/HD files might be left open after Ctrl-Reset jsr ClearScreen jsr MoveT00PakLow @refreshMainMenu jsr PrintByID !byte s_header jsr PrintByID !byte s_mainmenu bit gTargetType bmi @usingHardDisk bvs @usingCFFA lda #s_targetdisk !byte $2C @usingCFFA lda #s_targetcffa !byte $2C @usingHardDisk lda #s_targetfile sta + jsr PrintByID + !byte $FD ; SMC @getkey jsr WaitForKey cmp #$80 bne + jsr EnterCFFAIfAvailable bcc MainMenu bcs @getkey + cmp #$9B ; Esc quits beq @jumpToExit cmp #$91 ; Ctrl-Q quits beq @jumpToExit cmp #k_quit bne + @jumpToExit jmp CleanExit + cmp #k_slot bne + jsr NextSlot lda #0 sta HPOS sta VPOS jsr $FBC1 lda #TRUE sta gChangedPrefs beq @refreshMainMenu ; always branches + cmp #k_verify bne + lda #%00000000 beq Action ; always branches + cmp #k_crack bne @getkey lda #%11000000 ; /!\ execution falls through here Action sta gMode jsr InitSectorMap Reaction lda #FALSE sta gTriedUniv sta gSaidWriting sta gIsProtDOS sta gIsInfocom18 sta gIs13Sector sta gIsRW18 lda #$00 sta gTrack sta gSector sta gPatchCount sta jCallRWTS+1 sta CacheDst+1 lda #$08 sta gAddress+1 lda #$D4 sta CacheDst+2 jsr ShowInitialProgressScreen lda gMode bpl @printReading ; don't create RAM disk or hard disk file in verify mode jsr LookupUnitNumberOfSelectedHardDisk beq @notHardDrive jsr CreateFileOnHardDisk bcc @printReading jmp FatalWriteError ; failed to create target file on hard disk ; this is fatal @idBootloader jmp IDBootloader ; /src/id/inspect0 @notHardDrive +MaybeCreateFileOnRAMDisk @printReading jsr PrintByID !byte s_reading lda #$B2 ldx #$00 ldy #$06 jsr ClearMemory jsr CopyUniversal jsr IgnoreAddressChecksum jsr ReadSector bcc @idBootloader jsr IDBootFailure ; /src/id/bootfailure bcc @idBootloader jsr PrintByID !byte s_fatal0000 ; /!\ execution falls through here TheEnd jsr Cleanup jsr PrintByID !byte s_done jsr WaitForKey cmp #$9B beq CleanExit cmp #k_redo beq HandleRedo cmp #k_redo_with_ignore beq HandleRedoWithIgnore jsr CheckLogKeys jmp MainMenu HandleRedoWithIgnore jsr InitSectorMapWithIgnore jmp Reaction HandleRedo jsr ShowInitialProgressScreen jsr PrintByID !byte s_reading ; /!\ execution falls through here ;------------------------------- ; RestartScan ; Print 'Restarting scan...' then do exactly that. ; Used by several patchers that find evidence of a protection ; then activate an expensive search the second time around. ; Can be called from anywhere. ; Resets stack, never returns. ; Exits via ReadWithRWTS ;------------------------------- RestartScan jsr PrintByID !byte s_restart jsr RestartProgress jsr IncProgress jmp ReadWithRWTS ;------------------------------- ; Cleanup ; ; Cleans up open files (if any) ; Also turns off slot 6 drive motor ; ; in: ProDOS is NOT in memory ; out: ProDOS is NOT in memory ; all registers and flags clobbered ;------------------------------- Cleanup lda $C0E8 lda gHardDiskRef ora gRAMDiskRef bne + rts + jsr SwapProDOS ; ProDOS out -> in jsr DeleteFileOnRAMDisk +CloseFileOnHardDisk jmp SwapProDOS ; ProDOS in -> out ;------------------------------- ; CleanExit ; ; Cleans up open files, saves preferences (if modified), ; and quits via ProDOS MLI ; ; in: ProDOS is NOT in memory ; out: does not return ;------------------------------- CleanExit jsr Cleanup +SavePrefs jsr PRODOSMLI ; does not return !byte $65 !word + + !byte $04 ;------------------------------- ; AnalyzeTrack routine ; Looks at buffer in memory to detect known ; copy protections and disable/revert/modify them ; to work on standard disks. ; Prints through COUT ; Makes modifications in memory only. ; in: @BASEPAGE contains one track worth of data ($1000 bytes) ; gTrack contains track number ; out: everything clobbered ;------------------------------- AnalyzeTrack lda gTrack bne @applyToAll ; Track 0 patchers are stored compressed in memory ; then decompressed into $2000 when needed bit gMode bpl @applyToAll ; only run track 0 modules in crack mode lda T00PakPtr+1 sta _byte_hi lda T00PakPtr sta _byte_lo jsr decrunch jsr $2000 ; /!\ execution falls through here @applyToAll ; run these modules in verify and crack mode !source "patchers/t11diskvol.a" ; T11 only !source "patchers/t02volumename.a" ; T02 && gIsBoot0 only bit gMode bmi + rts + ; only run these modules in crack mode !source "patchers/universale7.a" !source "patchers/c9ff.a" !source "patchers/d5d5f7.a" ; gIsPascal || gIsBoot0 only !source "patchers/rwtsswapmecc.a" ; gMECCFastloadType || gPossibleMECCSwapper only !source "patchers/meccdqc.a" ; gMECCFastloadType==1 && gT07 only !source "patchers/rwtsswappenguin.a" ; T01 only !source "patchers/protecteddos.a" ; gIsProtDOS only !source "patchers/fbff.a" !source "patchers/corrupter.a" ; T13 only !source "patchers/ea.a" ; gIsEA || gIsBoot0 only !source "patchers/gamco.a" ; gPossibleGamco only !source "patchers/optimum.a" ; gIsOptimum only !source "patchers/bootcounter.a" ; T01 only !source "patchers/jmp2012.a" ; T02 only !source "patchers/advint.a" ; gAdventureInternational only !source "patchers/jmpb4bb.a" ; T02 only !source "patchers/dos32muse.a" ; T01 && gIsDOS32 only !source "patchers/sra.a" ; gIsDOS32 || gIsBoot0 only !source "patchers/sierra13.a" ; gIsDOS32 only !source "patchers/ssprot.a" ; gIsF7F6 only !source "patchers/f7f6.a" ; gIsF7F6 only !source "patchers/trillium.a" ; gIsTrillium only !source "patchers/trillium2.a" ; T17 only !source "patchers/advent.a" ; gIsAdvent only !source "patchers/davidsonforth.a" ; gIsDavidson only !source "patchers/davidsonasm.a" ; gIsDavidson only !source "patchers/ssi.a" ; gIsRDOS13 only !source "patchers/rdosfmt.a" ; gIsRDOS13 only !source "patchers/aacount.a" !source "patchers/holle.a" ; gIsHolle only !source "patchers/zoomgrafix.a" ; gIsPhoenix only !source "patchers/e7everywhere.a" ; gIsBoot0 || gIsProDOS only !source "patchers/tsr.a" ; T04 && gIsTSR only !source "patchers/woodbury.a" ; gPossibleWoodbury only !source "patchers/b4bbbasic.a" ; gPossibleB4BBBasic only !source "patchers/sigcheck.a" ; gPossibleSigCheck only !source "patchers/errord51.a" ; gIsLowDOS only !source "patchers/enlightenment.a" ; gIsEnlightenment && T02 only ; ; DOS 3.3-specific patchers ; lda gIsBoot0 beq + jmp _endDOS33Patchers + !source "patchers/hallabs.a" ; gIsBoot0 && T01 only !source "patchers/harvey.a" ; gIsBoot0 && T01 only !source "patchers/microlearn.a" ; gIsBoot0 && T01 only !source "patchers/jmpb400.a" ; gIsBoot0 && T02 only !source "patchers/jmpb412.a" ; gIsBoot0 && T02 only !source "patchers/mak.a" ; gIsBoot0 && T02 only !source "patchers/jsr8635.a" ; gIsBoot0 only !source "patchers/sierra.a" ; gIsBoot0 only !source "patchers/probs5.a" ; gIsBoot0 only !source "patchers/didatech.a" ; gIsBoot0 && gIsDidatech only _endDOS33Patchers ; ; Diversi-DOS-specific patchers ; lda gIsDiversi bne _endDiversiPatchers !source "patchers/pdi.a" ; gIsDiversi only _endDiversiPatchers ; ; ProDOS-specific patchers ; lda gIsProDOS beq + jmp _endProDOSPatchers + !source "patchers/bbf9.a" ; gIsProDOS only !source "patchers/fbffencrypted.a" ; gIsProDOS only !source "patchers/e7everywhere.encrypted.a" ; gIsProDOS only !source "patchers/pfs.prodos.a" ; gIsProDOS && T05 only !source "patchers/leisure.a" ; gIsProDOS && T22 only !source "patchers/memory.config.a" ; gIsProDOS only !source "patchers/origin.a" ; gIsProDOS only !source "patchers/polarware.a" ; gIsProDOS only !source "patchers/prodos6a.a" ; gIsProDOS only !source "patchers/prodosmecc.a" ; gIsProDOS only !source "patchers/prodosrwts.a" ; gIsProDOS only _endProDOSPatchers ; ; Pascal-specific patchers ; lda gIsPascal beq + jmp _endPascalPatchers + !source "patchers/a5count.a" ; gIsPascal only !source "patchers/a6bc95.a" ; gIsPascal only !source "patchers/fbffpascal.a" ; gIsPascal only !source "patchers/pfs.pascal.a" ; gIsPascal only _endPascalPatchers ; /!\ execution falls through here because why not ; utility functions used by several patchers inx0F inx inx0E inx inx0D inx inx0C inx inx0B inx inx0A inx inx9 inx inx8 inx inx7 inx inx6 inx inx5 inx inx4 inx inx inx inx rts ; ; Patchers that are called manually ; !source "patchers/choplifter.a" !source "patchers/555.a" universalrwts !bin "../build/universalrwts.pak" !source "exodecrunch.s" get_crunched_byte: _byte_lo = * + 1 _byte_hi = * + 2 lda $1234 ; needs to be set correctly before ; decrunch_file is called. inc _byte_lo bne _byte_skip_hi inc _byte_hi _byte_skip_hi: rts !source "id/bootfailure.a" nop nop !source "wholetrack.a" !source "apicode.a" ; /!\ must be last !if RELBASE = $2000 { !ifdef PASS2 { } else { ;PASS2 !set PASS2=1 !warn "RELBASE = ", HIGHPOINT - (* - Relocatable) } } else { !if (HIGHPOINT - (* - NonRelocatable)) < LOWPOINT { ; code before NonRelocatable is moved and tracked, so it can be below LOWPOINT !serious "My spoon is too big (", HIGHPOINT - (* - NonRelocatable), ") is below minimum (", LOWPOINT, ")!" } else { !warn "LowPoint=", NonRelocatable } !warn "ThisSlot=",ThisSlot !warn "PrintByID=",PrintByID !warn "WaitForKey=",WaitForKey !warn "CleanExit=",CleanExit !warn "OpenFile=",OpenFile !warn "ReadFile=",ReadFile !warn "CloseFile=",CloseFile !warn "GetVolumeName=",GetVolumeName !warn "GetVolumeInfo=",GetVolumeInfo !warn "PREFSVER=",PREFSVER !warn "PREFSFILE=",PREFSFILE !warn "SLOT=",SLOT !warn "DRIVE=",DRIVE !warn "MainMenu=",MainMenu !warn "CheckCache=",CheckCache }