diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9955f60 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +/build/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3bc20e1 --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +# +# Passport Makefile +# assembles source code, optionally builds a disk image and mounts it +# +# original by Quinn Dunki on 2014-08-15 +# One Girl, One Laptop Productions +# http://www.quinndunki.com/blondihacks +# +# adapted by 4am on 2017-01-07 +# + +# third-party tools required to build +# https://sourceforge.net/projects/acme-crossass/ +ACME=/usr/local/bin/acme +# https://sourceforge.net/projects/applecommander/ +AC=bin/AppleCommander.jar + +BUILDDISK=build/passport.po + +asm: + mkdir -p build + cd src && $(ACME) passport.a && cd - + cp res/work.po $(BUILDDISK) + java -jar $(AC) -p $(BUILDDISK) "PASSPORT.SYSTEM" sys 0x2000 < build/PASSPORT.SYSTEM + +clean: + rm -rf build/ + +mount: + osascript bin/V2Make.scpt "`pwd`" $(BUILDDISK) + +all: clean asm mount diff --git a/bin/AppleCommander.jar b/bin/AppleCommander.jar new file mode 100644 index 0000000..f74e7cb Binary files /dev/null and b/bin/AppleCommander.jar differ diff --git a/bin/V2Make.scpt b/bin/V2Make.scpt new file mode 100644 index 0000000..2e697cb Binary files /dev/null and b/bin/V2Make.scpt differ diff --git a/res/readme.txt b/res/readme.txt new file mode 100755 index 0000000..7623603 --- /dev/null +++ b/res/readme.txt @@ -0,0 +1 @@ +----------------Passport--------------- A 4am hack 2016-12-30 --------------------------------------- Passport is a cracker's tool that can remove several forms of copy protection from Apple II 5.25-inch floppy disks. Minimum system requirements: - Apple //e, //c, IIgs, or ][+ with 64K - Two 5.25-inch disk drives(*) (*) fully compatible with floppy drive emulators like CFFA3000 and FloppyEMU. Some fun facts about copy protection: 1. Many companies, especially smaller ones, outsourced their copy protection. I have seen byte-for byte identical copy protection on disks from 7 different companies! 2. Even companies that wrote their own copy protection would try to re-use it on multiple disks to get the most "bang for the buck." 3. Not everything has been cracked! Because there was so much piracy in the 1980s, some people assume that everything ever published has been cracked and ultimately preserved in an emulator-friendly format. In reality, there are hundreds of disks that have never been cracked. Thirty years later, these programs are still trapped on physical media, literally rotting away. ~ Using Passport is simple. After running the program, put an original disk in slot 6, drive 1 and a blank formatted disk in any other drive. If necessary, press "S" to cycle through your drives. Then press "C" to start the cracking. If all goes well, Passport will read your original disk and write a copy in a standard format, then remove any protection checks from the copy. The copy will boot and run just as well as the original disk, but it will be copyable with COPYA or any full-disk copy program. If all does not go well, Passport will tell you where it all went wrong. In any case, Passport will NEVER write to or alter your original disk in any way. And neither should you! Don't reduce the number of original disks in the world; they aren't making any more of them. ~ Passport targets common protection schemes that were reused by multiple companies. These types of protection were common on educational software, not blockbuster arcade games. Here is a sampling of companies whose disks Passport may be able to crack: - Apple "Special Delivery" e.g. Ernie's Quiz, Instant Zoo - MECC e.g. Word Munchers, Clock Works - Sunburst Communications e.g. M-ss-ng L-nks, The Incredible Laboratory - The Learning Company e.g. Bumble Games, Gertrude's Secrets - Scholastic e.g. Math Shop, Microzine - Edu-Ware e.g. Decimals, Algebra 2 - Hartley Courseware e.g. Chariots, Cougars, and Kings; Tim and the Cat and the Big Red Hat - Hayden e.g. SAT Score Improvement System (series) - Developmental Learning Materials e.g. Curious George in Outer Space, Alien Addition - DesignWare e.g. Spellicopter, Crypto Cube - Mindscape e.g. The Halley Project, Paperboy - Focus Media e.g. The Time Tunnel (series), Travels with Za-Zoom - MindPlay e.g. Fraction-oids, Dyno-Quest - Spinnaker Software (limited) e.g. Snooper Troops (series), KidWriter - Springboard Software (limited) e.g. Early Games for Young Children, Puzzle Master, Mask Parade - Reader's Digest e.g. Key Lingo, Cogito - McCarthy-McCormack e.g. Vowel Corral, Library Magic - Troll Associates e.g. Dino Dig, Make A Face - Abracadata e.g. Design Your Own Home (series) - Methods & Solutions e.g. Fantasy Land, Behind The Wheel - Mindplay e.g. Math Magic, Ace Detective - Quest Learning Systems e.g. Bingo Bugglebee Presents Home Alone, Outdoor Safety - HRM Software e.g. Gene Machine, Heredity Dog - Pelican Software e.g. Dino Days, Graphics Converter - Unicorn Software e.g. Magical Myths, Ten Little Robots - Grolier Publishing e.g. NoteCard Maker, EduCalc - Random House e.g. Snoopy to the Rescue, Charlie Brown's ABCs - Josten Learning Systems e.g. Building Reading Skills, Explorations in Science - Heartsoft e.g. Electric Chalkboard, Tommy the Time-Telling Turtle - Ellen Nelson Learning Library e.g. Science (series), House-a-fire! - Millennium Group e.g. The Brain Game, Concentration - Media Basics e.g. Return to Reading (series) - Polarware e.g. The Electric Crayon (series), The Spy's Adventures (series) - Queue e.g. Force and Motion, Practical Grammar - Atari e.g. Defender, Gremlins - Epyx (limited) e.g. Summer Games, Deathsword - Data East (limited) e.g. Ikari Warriors, Batman - Sierra On-Line (very limited) e.g. BC's Quest for Tires, Sammy Lightfoot - Broderbund (very limited) e.g. The Playroom, Where in Time Is Carmen Sandiego ~ Passport is open source and is distributed under the MIT license. Passport Copyright (c) 2016 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 Software, and to permit persons to whom the Software is 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. ~ 2016-12-30 - add support for DOS 3.3P e.g. Ernie's Quiz, Instant Zoo - improve support for disks created with MECC Database - faster detection of 4-and-4 encoding and 5-and-3 encoding (neither is supported) - various speed improvements 2016-09-02 - add support for Protected.DOS e.g. Moebius, Math Blaster - add support for "JMP $B660" RWTS e.g. Verb Viper, Master Match - add support for Datasoft encrypted bootloader e.g. Tomahawk, Video Title Shop - fix bug in boot sector detection that erroneously claimed some disks were unreadable - add informational messages about some RWTS variants (LSR $6A, BCS $08) - refactor code in /id/ directory 2016-07-12 - initial release ------------------EOF------------------ \ No newline at end of file diff --git a/res/work.po b/res/work.po new file mode 100644 index 0000000..4a37aad Binary files /dev/null and b/res/work.po differ diff --git a/src/analyze.a b/src/analyze.a new file mode 100755 index 0000000..0177df5 --- /dev/null +++ b/src/analyze.a @@ -0,0 +1,293 @@ +;------------------------------- +; IsF7 +; check for a specific nibble sequence +; ("F7 F6 EF EE AB") that is used by a +; whole-track protection scheme +; +; in slot 6, drive 1 is on track to test +; out C clear if sequence was found +; C set if sequence was not found +;------------------------------- +IsF7 + lda $C0E9 + lda #$00 + jsr WAIT + lda #$20 + sta nibcount + ldy #$00 +- lda $C0EC + bpl - + cmp #$F7 + beq + +restart iny + bne - + dec nibcount + bne - + beq F7fail +- ++ lda $C0EC + bpl - + cmp #$F6 + bne restart +- lda $C0EC + bpl - + cmp #$EF + bne restart +- lda $C0EC + bpl - + cmp #$EE + bne restart +- lda $C0EC + bpl - + cmp #$AB + bne restart + clc + !byte $24 ; hides SEC +F7fail sec + lda $C0E8 + rts + +;------------------------------- +; IsSyncBytes +; check if track is mostly $FF bytes +; +; in slot 6, drive 1 is on track to test +; out C clear if track is mostly just $FF bytes +; C set otherwise +;------------------------------- +IsSyncBytes + lda #$FD + sta nibtableff + jsr IsUnformatted + lda #$3F + sta nibtableff + rts + +;------------------------------- +; IsUnformatted +; check if track is unformatted +; +; in slot 6, drive 1 is on track to test +; out C clear if track is unformatted +; C set if track is formatted +;------------------------------- +IsUnformatted + lda $C0E9 + lda #$00 + sta unform + sta unform+1 + jsr WAIT + lda #$20 + sta nibcount + ldy #$00 +nibloop ldx $C0EC + bpl nibloop + lda nibtable,x + bpl + + inc unform + bne + + inc unform+1 ++ iny + bne nibloop + dec nibcount + bne nibloop + lda $C0E8 + lda #$18 + cmp unform+1 + rts + +;------------------------------- +; xHeredityDog +; check for a protection check at $BB00 +; which implies an unreadable T00,S0A +; +; in: $0800..$08FF contains boot0 +; $B600..$BFFF contains boot1 +; out: C clear if protection code was found +; C set if protection code was not found +;------------------------------- +xHeredityDog + lda $08FE + clc + adc #$04 + pha + ldx #$16 + ldy #$0B + jsr CompareMemory + !byte $F0,05,$A2,$B2,$4C,$F0,$BB,$BD,$8C,$C0,$A9 + pla + bcc analyze_maybe + jmp no1 + +; don't check byte at $BB21 because it can vary + +analyze_maybe + ldx #$22 + ldy #$3E + jsr CompareMemory + !byte $8D,00,02,$BD,$8C,$C0,$10,$FB,$C9,$EB,$D0,$F7,$BD,$8C + !byte $C0,$10,$FB,$C9,$D5,$D0,$EE,$BD,$8C,$C0,$10,$FB,$C9,$AA,$D0,$E5 + !byte $A9,$4C,$A0,00,$99,00,$95,$88,$D0,$FA,$CE,$46,$BB,$AD,$46,$BB + !byte $C9,07,$D0,$EC,$A9,$18,$8D,$42,$B9,$A9,$0A,$8D,$ED,$B7,$D0,05 + bcs no1 +yes1 + lda #$80 + sta T00S0A +no1 + rts + +;------------------------------- +; xSunburst +; check for a Sunburst RWTS +; which implies an unreadable T11,S0F +; +; in: $0800..$08FF contains boot0 +; $B600..$BFFF contains boot1 +; out: C clear if Sunburst RWTS was found +; C set otherwise +;------------------------------- +xSunburst + lda $08FE + clc + adc #$03 + ldx #$69 + ldy #$2C + jsr CompareMemory + !byte $48,$A5,$2A,$4A,$A8,$B9,$29,$BA + !byte $8D,$6A,$B9,$8D,$84,$BC,$B9,$34 + !byte $BA,$8D,$FC,$B8,$8D,$5D,$B8,$C0 + !byte $11,$D0,03,$A9,02,$AC,$A9,$0E + !byte $8D,$C0,$BF,$68,$69,00,$48,$AD + !byte $78,04,$90,$2B + bcs no2 +yes2 + lda #$80 + sta T11S0F +no2 + rts + +;------------------------------- +; xOptimumRes +; check if disk has Optimum Resource bootloader +; which implies an unreadable T01,S0F +; +; in: $0800..$08FF contains boot0 +; $B600..$BFFF contains boot1 +; out: C clear if OptimumRes bootloader was found +; C set otherwise +;------------------------------- +xOptimumRes + lda #$08 + ldx #$5D + ldy #$0C + jsr CompareMemory + !byte $68,$85,$F0,$68,$85,$F1,$A0,01 + !byte $B1,$F0,$85,$54 + bcc yes3 + lda #$08 + ldx #$5D + ldy #$0C + jsr CompareMemory + !byte $68,$85,$A0,$68,$85,$A1,$A0,01 + !byte $B1,$A0,$85,$54 + bcs no3 +yes3 + lda #$80 + sta T01S0F +no3 + rts + +;------------------------------- +; xB4BB +; check if disk changes RWTS in +; late boot after a nibble check +; +; in: $0800..$08FF contains boot0 +; $B600..$BFFF contains boot1 +; out: C clear if RWTS was modified in this routine +; C set otherwise +;------------------------------- +xB4BB + lda gTrack + pha + lda gSector + pha +b4bbcompare + lda #$FF ; modified at runtime (in Inspect1) + ldx #$00 + ldy #$20 + jsr CompareMemory + !byte $D8,$A9,$DF,$48,$A9,$FF,$48,$A9 + !byte 08,$85,$3D,$85,$43,$A9,$BF,$85 + !byte $3F,$A9,00,$85,$3C,$85,$42,$E6 + !byte $42,$A9,$FE,$85,$3E,$A0,00,$AD + bcs _b4bbexit + lda #$00 + sta gTrack + sta gAddress + lda #$0C + sta gSector + lda #$0C + clc + adc #BASEPAGE + sta gAddress+1 + jsr ReadSector + bcs _b4bbexit + lda #$0C + ldx #$84 + ldy #$03 + jsr compare + !byte $4C,$BB,$B4 + bcs _b4bbexit + lda #$02 + sta gTrack + sta gSector + jsr ReadSector + bcs _b4bbexit + lda #$0C + clc + adc #BASEPAGE + sta x0+2 +x0 lda $FFC2 ; modified at runtime (above) +b4bbmodify + sta $FF55 ; modified at runtime (in Inspect1) + lda #$DE +b4bbmodify2 + sta $FF91 ; modified at runtime (in Inspect1) +_b4bbexit + pla + sta gSector + pla + sta gTrack + rts + +;------------------------------- +; xB660 +; Check if RWTS calls an extra routine at $B660 +; after matching the first two data prologue +; nibbles. This routine can hang in an infinite +; loop if it's used to read an unprotected sector, +; so we need to force-switch to the built-in RWTS +; after reading all the protected sectors. +; (T00,S00-S09 are unprotected because they are +; read by the drive firmware.) +; +; in: $0800..$08FF contains boot0 +; out: C clear if $B660 routine was found +; C set otherwise +;------------------------------- +xB660 + lda #$08 + ldx #$60 + ldy #$1A + jsr CompareMemory + !byte $BD,$8C,$C0,$10,$FB,$C9,$AD,$D0 + !byte $F4,$A9,$F8,$3D,$8C,$C0,$D0,02 + !byte $EA,$EA,$EA,$EA,$BD,$8C,$C0,$2A + !byte $30,02 + bcs no4 +yes4 + lda #$FE + sta T00S09 +no4 + rts diff --git a/src/applyglobals.a b/src/applyglobals.a new file mode 100755 index 0000000..903e812 --- /dev/null +++ b/src/applyglobals.a @@ -0,0 +1,128 @@ +; +; initialize some variables that are used by many +; other patchers on track $00 +; +ApplyGlobals + lda #$00 + ldx #$00 + ldy #$4A + jsr compare ; if T00,S00,$00 == + +; This needs to be pretty strict because, if it matches, +; we're going to patch the sector and trace it to capture +; the RWTS. + + !byte 01,$A5,$27,$C9,09,$D0,$18,$A5 + !byte $2B,$4A,$4A,$4A,$4A,09,$C0,$85 + !byte $3F,$A9,$5C,$85,$3E,$18,$AD,$FE + !byte 08,$6D,$FF,08,$8D,$FE,08,$AE + !byte $FF,08,$30,$15,$BD,$4D,08,$85 + !byte $3D,$CE,$FF,08,$AD,$FE,08,$85 + !byte $27,$CE,$FE,08,$A6,$2B,$6C,$3E + !byte 00,$EE,$FE,08,$EE,$FE,08,$20 + !byte $89,$FE,$20,$93,$FE,$20,$2F,$FB + !byte $A6,$2B + ldx #TRUE + bcc boot0 + ldx #FALSE +boot0 + stx gIsBoot0 + + lda #$01 + ldx #$00 + ldy #$38 + jsr compare ; if T00,S01,$00 == + !byte $8E,$E9,$B7,$8E,$F7,$B7,$A9,01 + !byte $8D,$F8,$B7,$8D,$EA,$B7,$AD,$E0 + !byte $B7,$8D,$E1,$B7,$A9,02,$8D,$EC + !byte $B7,$A9,04,$8D,$ED,$B7,$AC,$E7 + !byte $B7,$88,$8C,$F1,$B7,$A9,01,$8D + !byte $F4,$B7,$8A,$4A,$4A,$4A,$4A,$AA + !byte $A9,00,$9D,$F8,04,$9D,$78,04 + ldx #TRUE + bcc boot1 + ldx #FALSE +:boot1 + stx gIsBoot1 + + lda #$01 + ldx #$00 + ldy #$38 + jsr compare ; if T00,S01,$00 == + !byte $8E,$E9,$37,$8E,$F7,$37,$A9,01 + !byte $8D,$F8,$37,$8D,$EA,$37,$AD,$E0 + !byte $37,$8D,$E1,$37,$A9,02,$8D,$EC + !byte $37,$A9,04,$8D,$ED,$37,$AC,$E7 + !byte $37,$88,$8C,$F1,$37,$A9,01,$8D + !byte $F4,$37,$8A,$4A,$4A,$4A,$4A,$AA + !byte $A9,00,$9D,$F8,04,$9D,$78,04 + ldx #TRUE + bcc master + ldx #FALSE +master + stx gIsMaster + + lda #$07 + ldx #$00 + ldy #$40 + jsr compare ; if T00,S07,$00 == + !byte $84,$48,$85,$49,$A0,02,$8C,$F8 + !byte 06,$A0,04,$8C,$F8,04,$A0,01 + !byte $B1,$48,$AA,$A0,$0F,$D1,$48,$F0 + !byte $1B,$8A,$48,$B1,$48,$AA,$68,$48 + !byte $91,$48,$BD,$8E,$C0,$A0,08,$BD + !byte $8C,$C0,$DD,$8C,$C0,$D0,$F6,$88 + !byte $D0,$F8,$68,$AA,$BD,$8E,$C0,$BD + !byte $8C,$C0,$A0,08,$BD,$8C,$C0,$48 + ldx #TRUE + bcc rwts + ldx #FALSE +rwts + stx gIsRWTS + + lda #$00 + ldx #$00 + ldy #$05 + jsr compare ; if T00,S00,$00 == + +; This abbreviated signature matches all ProDOS disks +; I can find, with no false positives. +; Some disks jump to $08FF at $0804 (SOS entry point). +; Others have a modified T00,S00 but eventually load +; ProDOS (e.g. 1-2-3 Sequence Me, Alge-Blaster Plus, +; Dazzle Draw, SuperPrint II) + + !byte 01,$38,$B0,$03,$4C + ldx #TRUE + bcc prodos + ldx #FALSE +prodos + stx gIsProDOS + + lda #$00 + ldx #$00 + ldy #$08 + jsr compare ; if T00,S00,$00 == + +; Apple Pascal signature (version < 1.3) +; The wildcard in 7th position catches alternate jump +; addresses (e.g. Wizardry I, Sundog Frozen Legacy) + + !byte 01,$E0,$60,$F0,03,$4C,$97,$08 + ldx #TRUE + bcc pascal + lda #$00 + ldx #$00 + ldy #$08 + jsr compare ; or if T00,S00,$00 == + +; Pascal 1.3 signature [thanks Marco V.] + + !byte 01,$E0,$07,$B0,04,$E0,$40,$B0 + ldx #TRUE + bcc pascal + ldx #FALSE +pascal + stx gIsPascal + + rts diff --git a/src/compare.a b/src/compare.a new file mode 100755 index 0000000..c85b12c --- /dev/null +++ b/src/compare.a @@ -0,0 +1,202 @@ +WILDCARD = $97 + +;------------------------------- +; SearchTrack subroutine +; written by qkumba +; search for a string occurring anywhere +; in the data buffer for the current track +; #WILDCARD in search string matches any 1 byte +; (like "." character in regular expressions) +; in: Y = string length +; stack = string to find +; out: C clear if string found +; or set if not found +; If C is clear, then +; A = sector where string was found +; X = starting offset where string was found +; all other registers and flags clobbered +;------------------------------- +SearchTrack + pla + sta match_buffer1+1 + sta match_all+1 + pla + sta match_buffer1+2 + sta match_all+2 + tax + sty match_size1+1 + sty match_size2+1 + +; fetch last byte to improve search speed + +match_buffer1 + lda $d1d1,y ; modified at runtime + sta check_byte1+1 + sta check_byte2+1 + +; set low part of initial search position + + tya + dey + sty cont_search+1 + +; set return address + + clc + adc match_buffer1+1 + tay + bcc plus01 + inx +plus01 + txa + pha + tya + pha + +; set match position + + inc match_all+1 + bne plus02 + inc match_all+2 +plus02 + +; set high part of initial search position + + lda #BASEPAGE + sta search+2 + + lda #Inspect1_8b3 + sta $085C + lda #$60 + sta $08CC + lda #$2C + sta $083F + sta $0842 + sta $0845 + pla + plp + jmp $0801 diff --git a/src/id/mecc.a b/src/id/mecc.a new file mode 100755 index 0000000..0e5c5d6 --- /dev/null +++ b/src/id/mecc.a @@ -0,0 +1,230 @@ +;------------------------------- +; IDMECC +; identify MECC custom bootloader +; note: there are several MECC RWTSes that share +; the same bootloader, so further checks will be +; required to distinguish between them +; +; in: track buffer contains T00,S00 +; out: C clear if MECC bootloader was found +; C set if not found +; all other flags clobbered +; all registers clobbered +;------------------------------- +IDMECC + lda #$00 + ldx #$00 + ldy #$17 + jsr compare + !byte 01,$4C,$1A,08,$17,$0F,00,00 + !byte $0D,$0B,09,07,05,03,01,$0E + !byte $0C,$0A,08,06,04,02,$0F + rts + +;------------------------------- +; IDMECCM8 +; identify MECC "M8" bootloader +; +; in: track buffer contains T00,S00 +; out: C clear if MECC "M8" bootloader was found +; C set if not found +; all other flags clobbered +; all registers clobbered +;------------------------------- +IDMECCM8 + lda #$00 + sta gTrack + sta gAddress + lda #$0B + sta gSector + clc + adc #BASEPAGE + sta gAddress+1 + jsr ReadSector + bcc + +mecc_no1 + rts ++ + lda #$0B + ldx #$02 + ldy #$06 + jsr compare ; IF T00,S0B,$02 == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs mecc_no1 + lda #$0B + ldx #$09 + ldy #$09 + jsr compare ; AND T00,S0B,$09 == + !byte $D0,$EF,$EA,$BD,$8C,$C0,$10,$FB + !byte $C9 + bcs mecc_no1 + lda #$0B + ldx #$13 + ldy #$0A + jsr compare ; AND T00,S0B,$13 == + !byte $D0,$E5,$A0,03,$BD,$8C,$C0,$10 + !byte $FB,$C9 + bcs mecc_no1 + lda #$0B + ldx #$89 + ldy #$06 + jsr compare ; AND T00,S0B,$89 == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs mecc_no1 + lda #$0B + ldx #$90 + ldy #$09 + jsr compare ; AND T00,S0B,$90 == + !byte $D0,$F4,$EA,$BD,$8C,$C0,$10,$FB + !byte $C9 + bcs mecc_no1 + lda #$0B + ldx #$9A + ldy #$09 + jsr compare ; AND T00,S0B,$9A == + !byte $D0,$F2,$EA,$BD,$8C,$C0,$10,$FB + !byte $C9 + rts + +foundmeccm8 +; +; We found an "M8" MECC bootloader. Now we create +; an RWTS that can read the rest of the disk. +; Starting with our built-in RWTS, we modify address +; and data prologues based on the parameters of the +; original disk. +; + lda #s_meccb0 + jsr PrintByID + jsr CopyUniversal + lda #$00 + sta modsrc + lda #$0B + clc + adc #BASEPAGE + sta modsrc+1 + ldy #$08 + lda (modsrc),y + lsr + sta $B956 + ldy #$12 + lda (modsrc),y + sta $B966 + ldy #$1D + lda (modsrc),y + sta $B96F + ldy #$8F + lda (modsrc),y + sta $B8E7 + ldy #$99 + lda (modsrc),y + sta $B8F1 + ldy #$A3 + lda (modsrc),y + sta $B8FC + pla + plp + jmp ADStyle + +;------------------------------- +; IDMECCM7 +; identify MECC "M7" bootloader +; +; in: track buffer contains T00,S00 +; out: C clear if MECC "M7" bootloader was found +; C set if not found +; all other flags clobbered +; all registers clobbered +;------------------------------- +IDMECCM7 + lda #$00 + sta gTrack + sta gAddress + lda #$07 + sta gSector + clc + adc #BASEPAGE + sta gAddress+1 + jsr ReadSector + bcc + +mecc_no2 + rts ++ + lda #$07 + ldx #$7D + ldy #$06 + jsr compare ; IF T00,S07,$7D == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs mecc_no2 + lda #$07 + ldx #$84 + ldy #$09 + jsr compare ; AND T00,S07,$84 == + !byte $D0,$F0,$EA,$BD,$8C,$C0,$10,$FB,$C9 + bcs mecc_no2 + lda #$07 + ldx #$8E + ldy #$0A + jsr compare ; and T00,S07,$8E == + !byte $D0,$F2,$A0,03,$BD,$8C,$C0,$10,$FB,$C9 + bcs mecc_no2 + lda #$07 + ldx #$0F + ldy #$06 + jsr compare ; and T00,S07,$0F == + !byte $BD,$8C,$C0,$10,$FB,$49 + bcs mecc_no2 + lda #$07 + ldx #$18 + ldy #$07 + jsr compare ; and T00,S07,$18 == + !byte $EA,$BD,$8C,$C0,$10,$FB,$C9 + bcs mecc_no2 + lda #$07 + ldx #$20 + ldy #$0A + jsr compare ; and T00,S07,$20 == + !byte $D0,$F2,$A0,$56,$BD,$8C,$C0,$10,$FB,$C9 + rts + +foundmeccm7 +; +; We found an "M7" MECC bootloader. Now we create +; an RWTS that can read the rest of the disk. +; Starting with our built-in RWTS, we modify address +; and data prologues based on the parameters of the +; original disk. +; + lda #s_meccm7 + jsr PrintByID + + jsr CopyUniversal + + lda #$00 + sta modsrc + lda #$07 + clc + adc #BASEPAGE + sta modsrc+1 + ldy #$83 + lda (modsrc),y + lsr + sta $B956 + ldy #$8D + lda (modsrc),y + sta $B966 + ldy #$98 + lda (modsrc),y + sta $B96F + ldy #$15 + lda (modsrc),y + sta $B8E7 + ldy #$1F + lda (modsrc),y + sta $B8F1 + ldy #$2A + lda (modsrc),y + sta $B8FC + pla + plp + jmp ADStyle diff --git a/src/id/protecteddos.a b/src/id/protecteddos.a new file mode 100755 index 0000000..ef7cbf3 --- /dev/null +++ b/src/id/protecteddos.a @@ -0,0 +1,54 @@ +;------------------------------- +; ProtectedDOS +; in: $0800..$08FF contains boot0 +; $B600..$BFFF contains boot1 +; out: C clear if "Protected DOS" was found +; C set if "Protected DOS" was not found +; gProtectedDOS is set to TRUE or FALSE +;------------------------------- +ProtectedDOS + lda #$B7 + ldx #$00 + ldy #$1A + jsr CompareMemory + !byte $A0,$1A,$B9,00,$B7,$49,$97,$99 + !byte 00,$B7,$C8,$D0,$F5,$EE,04,$B7 + !byte $EE,09,$B7,$AD,09,$B7,$C9,$C0 + !byte $D0,$E8 + bcs protecteddos_exit + + lda $B706 ; decryption key + sta key+1 + sta gDisplayBytes + lda #s_protdos + jsr PrintByID + +; +; decrypt RWTS in memory +; + lda #$B7 + sta decrypt+2 + sta store+2 + ldy #$1A +decrypt lda $B700,y +key eor #$FF ; set at runtime +store sta $B700,y + iny + bne decrypt + inc decrypt+2 + inc store+2 + lda store+2 + cmp #$C0 + bne decrypt + +; +; this RWTS swaps the A/Y hi/lo parameter table address +; when calling the RWTS entry point, so we need to +; set a flag so we can call it properly later +; (in ReadSector) +; + lda #TRUE + sta gIsProtDOS + clc +protecteddos_exit + rts diff --git a/src/id/specdelivery.a b/src/id/specdelivery.a new file mode 100755 index 0000000..4ef6798 --- /dev/null +++ b/src/id/specdelivery.a @@ -0,0 +1,244 @@ +; "Special Delivery" boot tracer +; for DOS 3.3P disks +; e.g. Ernie's Quiz, Elite +; +;------------------------------- +; IDSpecDel +; returns C clear if "Special Delivery" bootloader +; detected in T00,S00 +;------------------------------- +IDSpecDel + lda #$00 + ldx #$00 + ldy #$58 + jsr compare + !byte 02,$90,$4A,$C6,$27,$BD,$31,09 + !byte $49,$B0,$48,$C6,$3D,$98,$C8,$48 + !byte $CE,00,08,$A9,$20,$C6,$27,$48 + !byte $51,$26,$91,$26,$AA,$A5,$27,$85 + !byte $32,$CE,00,08,$A8,$B5,$33,$84 + !byte $29,$84,$21,$8A,$A2,$17,$86,$31 + !byte $D5,$33,$A6,$2B,$5D,$31,09,$85 + !byte $29,$5D,$32,09,$C6,$3D,$85,$28 + !byte $5D,$33,09,$85,$48,$A0,$2B,$84 + !byte $20,$C6,$40,$30,$3E,$24,$40,$30 + !byte $33,$24,$24,$24,$24,$40,$40,$40 + rts + +;------------------------------- +; TraceSpecDel +; set up boot trace to capture the bootloader and DOS +; of "Special Delivery" disks (stored in non-sector +; format on tracks 0-2) +;------------------------------- +TraceSpecDel + jsr ClearTSBuffer + lda #$00 ; set a marker to see if entire + sta $3FFF ; RWTS loads successfully later + lda #$00 ; save zero page before trace + ldx #$0A + ldy #$01 + jsr CopyMemory + + lda #TraceSpecDel2 + jmp Trace + +TraceSpecDel2 + lda #$4C + sta $0855 + lda #TraceSpecDel3 + sta $0857 + lda #$02 + sec + jmp $0801 + +TraceSpecDel3 + lda $1212 + cmp #$D8 + bne SDfail + lda #$4C + sta $10D5 + lda #TraceSpecDel4 + sta $10D7 + lda #$4C + sta $10F0 + lda #TraceSpecDel4 + sta $10F2 + jmp $1212 + +TraceSpecDel4 + lda $C0E8 ; turn off source drive + lda #$0A ; restore zero page from before trace + ldx #$00 + ldy #$01 + jsr CopyMemory + + lda $3FFF + cmp #$EA + bne SDfail + + lda #$0B + ldx #$00 + ldy #$03 + jsr compare ; if $1B00 == + !byte $4C,$4D,$2A + bcc SDsuccess +SDfail + jmp UseUniversal + +SDsuccess +; +; Restore the original code in memory before writing. +; + lda #$A2 + sta $10D5 + lda #$FF + sta $10D6 + lda #$9A + sta $10D7 + lda #$A5 + sta $10F0 + lda #$2B + sta $10F1 + lda #$4A + sta $10F2 +; +; move $1000-$13FF to $1100-$14FF to align it as we need it +; for writing to disk with the Standard Delivery bootloader +; in T00,S00 +; + lda #$13 + ldx #$14 + ldy #$01 + jsr CopyMemory + lda #$12 + ldx #$13 + ldy #$01 + jsr CopyMemory + lda #$11 + ldx #$12 + ldy #$01 + jsr CopyMemory + lda #$10 + ldx #$11 + ldy #$01 + jsr CopyMemory + +; $1B00-$1FFF is real code and in the right place +; but we should clear the rest of T00 so we're not +; writing garbage to disk on unused sectors + + lda #$10 + ldx #$00 + ldy #$01 + jsr ClearMemory + lda #$15 + ldx #$00 + ldy #$06 + jsr ClearMemory + +; copy Standard Delivery bootloader into place for T00,S00 + + ldy #$7E ; _SDboot0-SDboot0, but set here + ; manually to work around Merlin bug +sdcopy lda SDboot0,y + sta $1000,y + dey + bpl sdcopy + +; now manually write out track 0 with Standard Delivery +; bootloader + + jsr IncProgress + lda #$00 + sta gTrack + jsr WriteTrackNA + +; manually write out track 1 + + jsr IncProgress + inc gTrack + lda #$20 + ldx #$10 + ldy #$10 + jsr CopyMemory + jsr WriteTrackNA + +; manually write out track 2 with a patched RWTS + + jsr IncProgress + inc gTrack + lda #$30 + ldx #$10 + ldy #$10 + jsr CopyMemory + lda #$08 + ldx #$B6 + ldy #$04 + jsr modify + !byte $C9,$AD,$90,$E5 + lda #$18 + ldx #$38 + ldy #$01 + jsr CopyMemory + jsr WriteTrackNA + lda #$C9 + sta $38B6 + lda #$AD + sta $38B7 + lda #$90 + sta $38B8 + lda #$E5 + sta $38B9 + +; mark tracks 0-2 as "skip" in sector map + + ldy #$2F + lda #$00 +skipsectors + sta T00,y + dey + bpl skipsectors + +; set up RWTS entry point + + lda #$D5 + sta callrwts+1 + lda #$36 + sta callrwts+2 + +; read the rest of the disk with the original RWTS + + lda #$03 + sta gLastTrack + jmp ADStyle + +; Standard Delivery bootloader with DOS 3.3P support +; https://github.com/peterferrie/standard-delivery/ +; rev. a5b839d7d0fa21b0ff3a7776d9f6c9750b09ae10 of 2016-11-29 +; +SDboot0 + !byte 01,$a8,$ee,06,08,$ad,$4e,08 + !byte $c9,$c0,$f0,$40,$85,$27,$c8,$c0 + !byte $10,$90,09,$f0,05,$20,$2f,08 + !byte $a8,$2c,$a0,01,$84,$3d,$c8,$a5 + !byte $27,$f0,$df,$8a,$4a,$4a,$4a,$4a + !byte 09,$c0,$48,$a9,$5b,$48,$60,$e6 + !byte $41,06,$40,$20,$37,08,$18,$20 + !byte $3c,08,$e6,$40,$a5,$40,$29,03 + !byte $2a,05,$2b,$a8,$b9,$80,$c0,$a9 + !byte $30,$4c,$a8,$fc,$4c,$b3,$10 + !byte $1E,$1D,$1C,$1B,00,00,00,00 + !byte 00,00,$13,$12,$11,$10,$1F,$20 + !byte $2E,$2D,$2C,$2B,$2A,$29,$28,$27 + !byte $26,$25,$24,$23,$22,$21,$2F,$30 + !byte $3E,$3D,$3C,$3B,$3A,$39,$38,$37 + !byte $36,$35,$34,$33,$32,$31,$3F,$C0 +_SDboot0 diff --git a/src/id/trace.a b/src/id/trace.a new file mode 100755 index 0000000..e3a3e58 --- /dev/null +++ b/src/id/trace.a @@ -0,0 +1,156 @@ +;------------------------------- +; TraceDOS33 +; set up 1st-level boot trace on +; a DOS 3.3-shaped bootloader +;------------------------------- +TraceDOS33 +; +; Before we trace through the drive firmware (which -- +; at least on some machines -- will loop forever looking +; for each sector), we do a pre-check to ensure that all +; the sectors we're about to trace are actually readable. +; + lda #$00 + sta gTrack + lda #$09 + sta gSector +precheck + ldy #gRWTSParams + jsr $BD00 + bcc + + jmp FatalError ++ + dec gSector + bne precheck + +; pre-check passed, do the trace + + lda #TraceDOS33b + jmp Trace + +;------------------------------- +; TraceDOS33b +; set up 2nd boot trace at $084A +;------------------------------- +TraceDOS33b + lda #$4C + sta $084A + lda #TraceDOS33c + sta $084C + lda #$2C ; disable calls to + sta $083F ; TEXt/PR0/IN0 + sta $0842 + sta $0845 + jmp $0801 + +TraceDOS33c + lda $08FE ; 2nd-level trace callback is here + clc + adc #$02 +_Inspect1a + sta x1+1 + sta x2+1 + sta b4bbmodify+2 + sta b4bbmodify2+2 + clc + adc #$06 + sta b4bbcompare+1 + sec + sbc #$02 + sta x3+1 + sta x4+1 + sta callrwts+2 + jsr ProtectedDOS ; check for a specific (encrypted) + ; bootloader called "Protected DOS" + bcs notprotdos + jmp ADStyle +notprotdos + lda callrwts+2 + ldx #$00 ; check for "STY $48;STA $49" + ldy #$04 ; at RWTS entry point + jsr CompareMemory ; (e.g. $BD00 or $3D00) + !byte $84,$48,$85,$49 + bcc x1 + jmp UseUniversal +x1 lda #$FF ; check for "SEC;RTS" at $B942 + ldx #$42 + ldy #$02 + jsr CompareMemory + !byte $38,$60 + bcc x2 + jmp UseUniversal +x2 lda #$FF ; check for "LDA $C08C,X" at $B94F + ldx #$4F + ldy #$03 + jsr CompareMemory + !byte $BD,$8C,$C0 + bcc x3 + jmp UseUniversal +x3 lda #$FF ; check for "JSR $xx00" at $BDB9 + ldx #$B9 + ldy #$02 + jsr CompareMemory + !byte $20,00 + bcc + +; +; Check for RWTS variant that has extra code before +; JSR $B800 e.g. Verb Viper (DLM), Advanced Analogies (Hartley) +; +x4 lda #$FF ; check for "JSR $xx00" at $BDC5 + ldx #$C5 + ldy #$02 + jsr CompareMemory + !byte $20,00 + bcc + + jmp UseUniversal ; give up tracing; this RWTS is unsupported ++ jmp ADStyle ; use this RWTS to read the disk + +; TODO this doesn't belong here +Inspect1_8b3 + jsr WriteTrack + lda $08FE + clc + adc #$01 + jmp _Inspect1a + +;------------------------------- +; Trace +; common code for all boot tracers +; in: A = lo byte of callback +; X = hi byte of callback +; never returns +;------------------------------- +Trace + pha + txa + pha + lda #$C6 + ldx #$B6 + ldy #$01 + jsr CopyMemory + pla + tax + pla + ldy $B6F8 + cpy #$4C + bne maybe_gs + sty $B6F8 ; JMP + sta $B6F9 ; lo byte of callback + stx $B6FA ; hi byte of callback + jmp $B600 +maybe_gs + ldy $B6FB + cpy #$4C + bne unknowndrive + sty $B6FB ; JMP + sta $B6FC ; lo byte of callback + stx $B6FD ; hi byte of callback + jmp $B600 +unknowndrive + lda #s_canttrace + jsr PrintByID + jmp UseUniversal diff --git a/src/keys.a b/src/keys.a new file mode 100755 index 0000000..7c28e12 --- /dev/null +++ b/src/keys.a @@ -0,0 +1,20 @@ +KEY = $C000 +STROBE = $C010 + +WaitForKey + bit STROBE +k lda KEY + bpl k + bit STROBE + cmp #"*" + bne noast + jsr TEXT + lda #s_reset + jsr PrintByID + jmp $FF59 +noast + cmp #$E1 + bcc + + and #$DF ; force uppercase ++ + rts diff --git a/src/lcase.a b/src/lcase.a new file mode 100755 index 0000000..6ba7c0a --- /dev/null +++ b/src/lcase.a @@ -0,0 +1,4 @@ +!to "lcase.ct", plain +*=0 +!for i, 128 {!byte i+127} +!for i, 256-128 {!byte i+127} diff --git a/src/lcase.ct b/src/lcase.ct new file mode 100755 index 0000000..38dee39 --- /dev/null +++ b/src/lcase.ct @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/memory.a b/src/memory.a new file mode 100755 index 0000000..a352e43 --- /dev/null +++ b/src/memory.a @@ -0,0 +1,126 @@ +;------------------------------- +; CopyMemory +; in: A = source address (high) +; X = destination address (high) +; Y = number of pages to copy +; out: all flags and registers clobbered +;------------------------------- +CopyMemory + sta source1+2 + stx dest1+2 + ldx #$00 +source1 lda $FF00,x +dest1 sta $FF00,x + inx + bne source1 + inc source1+2 + inc dest1+2 + dey + bne source1 + rts + +;------------------------------- +; ClearMemory +; in: A = source address (high) +; X = value to set +; Y = number of pages +; out: all flags and registers clobbered +;------------------------------- +ClearMemory + sta dest2+2 + txa + ldx #$00 +dest2 sta $FF00,x + inx + bne dest2 + inc dest2+2 + dey + bne dest2 + rts + +;------------------------------- +; ClearTSBuffer +; clear the $1000 byte memory buffer +; used to store the current track's data +; in: none +; out: all flags and registers clobbered +;------------------------------- +ClearTSBuffer + lda #BASEPAGE + ldx #$00 + ldy #$10 + jmp ClearMemory + +;------------------------------- +; SwapMemory +; in: A = source address (high) +; X = destination address (high) +; Y = number of pages to copy +; out: all flags and registers clobbered +;------------------------------- +SwapMemory + sta source11+2 + sta source22+2 + stx dest11+2 + stx dest22+2 + ldx #$00 +source11 lda $FF00,x + pha +dest11 lda $FF00,x +source22 sta $FF00,x + pla +dest22 sta $FF00,x + inx + bne source11 + inc source11+2 + inc source22+2 + inc dest11+2 + inc dest22+2 + dey + bne source11 + rts + +;------------------------------- +; SaveProDOS +; saves memory pages used by ProDOS +; pages $00, $03, $BF +; in: none +; out: all flags and registers clobbered +;------------------------------- +SaveProDOS + lda #$00 + ldx #$40 + ldy #$01 + jsr CopyMemory + lda #$03 + ldx #$41 + ldy #$01 + jsr CopyMemory + lda #$BF + ldx #$42 + ldy #$01 + jsr CopyMemory +memory_exit + rts + +;------------------------------- +; SwapProDOS +; saves/restores memory pages used by ProDOS +; pages $00, $03, $BF +; in: none +; out: all flags and registers clobbered +;------------------------------- +SwapProDOS + lda #$00 + ldx #$40 + ldy #$01 + jsr SwapMemory + lda #$03 + ldx #$41 + ldy #$01 + jsr SwapMemory + lda #$BF + ldx #$42 + ldy #$01 + jsr SwapMemory + rts diff --git a/src/mli.a b/src/mli.a new file mode 100755 index 0000000..7716939 --- /dev/null +++ b/src/mli.a @@ -0,0 +1,509 @@ +; MLI command codes +CMD_CREATE = $C0 ; create new file +CMD_DESTROY = $C1 ; delete a file +CMD_SETPREFIX = $C6 ; change default pathname prefix +CMD_OPEN = $C8 ; open a file +CMD_NEWLINE = $C9 ; set line-by-line read mode +CMD_READ = $CA ; read an open file +CMD_WRITE = $CB ; write to an open file +CMD_CLOSE = $CC ; close an open file +CMD_SETMARK = $CE ; change position in an open file + +; MLI parameter counts +PC_CREATE = $07 +PC_DESTROY = $01 +PC_SETPREFIX = $01 +PC_OPEN = $03 +PC_NEWLINE = $03 +PC_READ = $04 +PC_WRITE = $04 +PC_CLOSE = $01 +PC_SETMARK = $02 + +PRODOSMLI = $BF00 ; [callable] MLI entry point + +; MLI error codes +ERR_FNF = $46 +ERR_EOF = $4C + +;------------------------------- +; WriteTrackMLI - write the contents of +; BASEPAGE data buffer to disk +; in: @SLOT contains (slot x 16) + $30 +; @DRIVE contains drive + $30 +; @gTrack contains track number +; @BASEPAGE contains data to write ($1000 bytes) +; out: if C set, write failed (A contains MLI error code) +; if C clear, write succeeded (A is clobbered) +; all other flags clobbered +; all registers clobbered +;------------------------------- +WriteTrackMLI + jsr SwapProDOS + jsr ReorderBuffer + lda #$81 ; 'write block' command + sta mlicmd + lda DRIVE ; ProDOS "unit number" is + sec + sbc #$30 + lsr ; DSSS0000, where D is the + asl ; drive number (0=drive 1, + asl ; 1=drive 2) and SSS is + asl ; the slot number (1-7). + asl ; "Beneath Apple ProDOS" + asl ; page 6-19 + asl + asl + sta mliparam+1 + lda SLOT + sec + sbc #$30 + asl + asl + asl + asl + clc + adc mliparam+1 + sta mliparam+1 + lda #$00 + sta mliparam+2 ; lo byte of data buffer + lda #$08 + sta blockcount + lda gTrack + asl + asl + asl + sta mliparam+4 ; lo byte of block number + rol + and #$01 + sta mliparam+5 ; hi byte of block number + lda #BASEPAGE ; hi byte of data buffer + sta mliparam+3 +writeloop + lda mlicmd + ldy #$03 ; parameter count + jsr mli + bcs mli_writeerr + inc mliparam+3 ; 2 pages per block + inc mliparam+3 + inc mliparam+4 + dec blockcount + bne writeloop + clc + bcc writedone +mli_writeerr +writedone + php + pha + jsr ReorderBuffer + jsr SwapProDOS + pla + plp + rts + +blockcount !byte $FF + +;------------------------------- +; ReorderBuffer - convert data +; buffer between ProDOS and +; DOS 3.3 ordering (use after +; read or before write under +; ProDOS) +; in: none +; out: all flags clobbered +; all registers clobbered +; @cmp1, @cmp2 clobbered +;------------------------------- +ReorderBuffer + lda #$00 + sta cmp1 + sta cmp2 + tay + lda #$01 + clc + adc #BASEPAGE + sta cmp1+1 + lda #$0E + clc + adc #BASEPAGE + sta cmp2+1 + ldx #$07 +L lda (cmp1),y + pha + lda (cmp2),y + sta (cmp1),y + pla + sta (cmp2),y + iny + bne L + inc cmp1+1 + dec cmp2+1 + dex + bne L + rts + +;------------------------------- +; SaveFile1Shot +; save a file to disk all at once, +; using ProDOS MLI calls +; +; in: stack contains 11 ($0B) bytes of parameters: +; +1 address of pathname +; +3 [byte] file type +; +4 [word] aux file type +; +6 address of data buffer +; +8 [word] length of data buffer +; +A address of ProDOS file buffer +; out: if C set, save failed and A contains error code +; from open or write +; if C clear, save succeeded +; all other flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------- +SaveFile1Shot + pla + sta $00 + pla + sta $01 + tax + lda #$0B + clc + adc $00 + bcc mli_noinc1 + inx +mli_noinc1 + tay + txa + pha + tya + pha + + ldy #$01 + lda ($00),y ; lo byte of pathname + sta mliparam+1 + iny + lda ($00),y ; hi byte of pathname + sta mliparam+2 + jsr DeleteFile ; don't care if this fails + ldy #$03 + lda ($00),y ; file type + sta mliparam+4 + iny + lda ($00),y ; lo byte of aux file type + sta mliparam+5 + iny + lda ($00),y ; hi byte of aux file type + sta mliparam+6 + jsr CreateFile + bcs savefile1s + + ldy #$0A + lda ($00),y ; lo byte of ProDOS file buffer + sta mliparam+3 + iny + lda ($00),y ; hi byte of ProDOS file buffer + sta mliparam+4 + jsr OpenFile + bcs savefile1s + + pha ; push file reference number + ldy #$06 + lda ($00),y ; lo address of data buffer + sta mliparam+2 + iny + lda ($00),y ; hi address of data buffer + sta mliparam+3 + iny + lda ($00),y ; lo data length + sta mliparam+4 + iny + lda ($00),y ; hi data length + sta mliparam+5 + pla ; pull file reference number + jsr WriteFile + php ; save flags from writefile + pha + jsr CloseFile ; always close whether write worked or not + pla + plp ; restore flags from write + ; (so caller gets codes from write attempt, + ; not close) + +savefile1s + rts + +;------------------------------- +; LoadFile1Shot +; load a file into memory all at once, +; using ProDOS MLI calls +; +; in: stack contains 8 bytes of parameters: +; +1 address of pathname +; +3 address of data buffer (to receive file contents) +; +5 [word] maximum length of data to read +; +7 address of ProDOS file buffer +; out: if C set, load failed and A contains error code +; from open or read +; if C clear, load succeeded and ($02) contains +; data loaded from file +; all other flags clobbered +; all registers clobbered +; stack set to next instruction after parameters +;------------------------------- +LoadFile1Shot + pla + sta $00 + pla + sta $01 + tax + lda #$08 + clc + adc $00 + bcc mli_noinc2 + inx +mli_noinc2 + tay + txa + pha + tya + pha + + ldy #$01 + lda ($00),y ; lo byte of pathname + sta mliparam+1 + iny + lda ($00),y ; hi byte of pathname + sta mliparam+2 + ldy #$07 + lda ($00),y ; lo byte of ProDOS file buffer + sta mliparam+3 + iny + lda ($00),y ; hi byte of ProDOS file buffer + sta mliparam+4 + + jsr OpenFile + bcs loadfile1s ; C set on error + + pha ; push file reference number + ldy #$03 + lda ($00),y ; lo address of data buffer + sta mliparam+2 + iny + lda ($00),y ; hi address of data buffer + sta mliparam+3 + iny + lda ($00),y ; lo data length + sta mliparam+4 + iny + lda ($00),y ; hi data length + sta mliparam+5 + pla ; pull file reference number + jsr ReadFile + php ; save flags from readfile + pha + jsr CloseFile ; always close whether read worked or not + pla + plp ; restore flags from readfile + ; (so caller gets codes from read attempt, + ; not close) +loadfile1s + rts + +;------------------------------- +; open file via ProDOS MLI +; +; in: caller has filled @mliparam with address of +; pathname, address of data buffer, and maximum +; data length +; A = file reference number +; out: if C set, open failed and A contains error code +; if C clear, open succeeded and A contains +; file reference number +;------------------------------- +OpenFile + lda #CMD_OPEN ; MLI command + ldy #PC_OPEN ; number of parameters for 'open' command + jsr mli + bcs openfile + lda refnum ; caller should save file reference number + ; as this memory location may be + ; overwritten by later MLI calls +openfile + rts + +;------------------------------- +; set line-by-line mode via ProDOS MLI +; +; in: A = file reference number +; out: if C set, set failed and A contains error code +; if S clear, set succeeded and A contains the same +; file reference number that was passed in +;------------------------------- +lbl_mask = $7F +lbl_cr = $0D + +SetLineByLine + sta mliparam+1 ; store file reference number + lda #lbl_mask ; accept high bit set or clear + sta mliparam+2 + lda #lbl_cr ; carriage return character + sta mliparam+3 + lda #CMD_NEWLINE ; MLI 'newline' command to set read mode + ldy #PC_NEWLINE ; number of parameters for 'newline' command + jsr mli + bcs setlinebylin + lda mliparam+1 ; if no error, return file reference number +setlinebylin + rts + +;------------------------------- +; read an open file via ProDOS MLI +; +; in: A = file reference number +; caller has filled @mliparam with address of +; data buffer and maximum data length +; out: if C set, read failed and A contains error code +; if C clear, read succeeded and A contains the same +; file reference number that was passed in +;------------------------------- +ReadFile + sta mliparam+1 ; store file reference number + lda #CMD_READ ; MLI read command + ldy #PC_READ ; number of parameters for 'read' command + jsr mli + bcs readfile + lda mliparam+1 ; if no error, return file reference number +readfile + rts + +;------------------------------- +; change file position in an open file via ProDOS MLI +; +; in: A = file reference number +; caller has filled @mliparam+2/+3/+4 with +; new file position +; out: if C set, set_mark call failed and A contains error code +; if C clear, set_mark call succeeded and A contains +; the same file reference number that was passed in +;------------------------------- +SetMark + sta mliparam+1 ; store file reference number + lda #CMD_SETMARK ; MLI set_mark command + ldy #PC_SETMARK ; number of params for 'set_mark' cmd + jsr mli + bcs mli_exit + lda mliparam+1 ; if no error, return file refnum +mli_exit rts + +;------------------------------- +; write to an open file via ProDOS MLI +; +; in: A = file reference number +; caller has filled @mliparam with address of +; data buffer and data length +; out: if C set, write failed and A contains error code +; if C clear, write succeeded and A contains the same +; file reference number that was passed in +;------------------------------- +WriteFile + sta mliparam+1 ; store file reference number + lda #CMD_WRITE ; MLI write command + ldy #PC_WRITE ; number of parameters for 'write' command + jsr mli + bcs writefile + lda mliparam+1 ; if no error, return file reference number +writefile + rts + +;------------------------------- +; close an open file +; in: A = file reference number +; out: if error, C set and A contains error code +; if success, C clear +;------------------------------- +CloseFile + sta mliparam+1 ; store file reference number + lda #CMD_CLOSE ; MLI close command + ldy #PC_CLOSE ; number of parameters for 'close' command + jsr mli + rts + +;------------------------------- +; create a file via ProDOS MLI +; always sets access bits to $C3 (full access) +; always sets creation to 0 (current date/time) +; always sets storage type to 1 (file) +; in: caller has filled @mliparam +; with address of pathname, +; file type, aux file type +; out: if error, C set and A contains error code +; if success, C clear +;------------------------------- +accessbits = $C3 ; full access + +CreateFile + lda #accessbits + sta mliparam+3 ; access bits (full access) + lda #1 + sta mliparam+7 ; storage type (file) + lda #0 + sta mliparam+8 ; creation date (current) + sta mliparam+9 + sta mliparam+10 ; creation time (current) + sta mliparam+11 + lda #CMD_CREATE ; MLI create command + ldy #PC_CREATE ; number of parameters for 'create' command + jsr mli + rts + +;------------------------------- +; delete a file using ProDOS MLI +; in: caller has filled @mliparam +; with address of pathname +; out: if error, C set and A contains error code +; if success, C clear +;------------------------------- +DeleteFile + lda #CMD_DESTROY ; MLI destroy command + ldy #PC_DESTROY ; number of parameters for 'destroy' command + jsr mli + rts + +;------------------------------- +; change current directory (set prefix) +; using ProDOS MLI +; in: caller has filled @mliparam +; with address of pathname +; out: if error, C set and A contains error code +; if success, C clear +;------------------------------- +SetPrefix + lda #CMD_SETPREFIX + ldy #PC_SETPREFIX + jsr mli + rts + +;------------------------------- +; low-level MLI wrapper +; in: A = MLI command code +; Y = number of MLI parameters +; caller has filled @mliparam +; with all relevant parameters +; out: returns immediately after +; calling MLI, so whatever +; state the MLI routine sets, +; the caller will see it +; verbatim +;------------------------------- +mli sta mlicmd ; store command code + sty mliparam ; number of parameters + jsr PRODOSMLI ; call ProDOS +mlicmd !byte 00 ; command number + !word mliparam ; address of parameter table + rts +mliparam !byte $FE,$FE,$FE,$FE,$FE +refnum !byte $FE ; file refnum (set by MLI open) +mlilen !byte $FE,$FE ; file length (set by MLI read) + !byte $FE,$FE,$FE,$FE + ; used by createfile diff --git a/src/modify.a b/src/modify.a new file mode 100755 index 0000000..6d56bd5 --- /dev/null +++ b/src/modify.a @@ -0,0 +1,73 @@ +;------------------------------- +; modify subroutine +; in: A = starting address (high byte) +; X = starting address (low byte) +; Y = string length +; stack = string to set +; out $BASEPAGE buffer changed +; $gPatchCount++ +; $modsrc zero page clobbered +; $moddest zero page clobbered +; stack set to return to +; code after string +; all registers clobbered +; all flags clobbered +;------------------------------- +modify + sta gDisplayBytes + clc + adc #BASEPAGE + sta moddest+1 + stx moddest + stx gDisplayBytes+1 + pla + sta modsrc + pla + sta modsrc+1 + tax + tya + clc + adc modsrc + bcc noinc + inx +noinc + sta tmp + txa + pha + lda tmp + pha + sty modtmp + bit gMode + bpl exitnomod ; verify mode -> no modify + bvc exitnomod ; demuffin mode -> no modify + lda #s_modify + jsr PrintByID + ldy #0 +dest + lda (moddest),y + jsr PrintByte + iny + cpy modtmp + bne dest + lda #s_modifyto + jsr PrintByID + ldy #0 +src + iny + lda (modsrc),y + jsr PrintByte + cpy modtmp + bne src + lda #$8D + jsr PrintA +mod + lda (modsrc),y + dey + bmi modify_exit + sta (moddest),y + clv + bvc mod ; unconditional branch +modify_exit + inc gPatchCount +exitnomod + rts diff --git a/src/passport.a b/src/passport.a new file mode 100755 index 0000000..6fbf7a5 --- /dev/null +++ b/src/passport.a @@ -0,0 +1,767 @@ +!cpu 6502 +*=$2000 + +;------------------------------- +; Passport +; a 4am hack +; (c) 2016-7 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. +; +;------------------------------- + +; Supported languages +; (each has its own localized strings file +; and its own output filename) +ENGLISH = 1 ; src/strings/en, PASSPORT.SYSTEM +FRENCH = 2 ; src/strings/fr, PASSPORT.FR +SPANISH = 3 ; src/strings/es, PASSPORT.ES +ITALIAN = 4 ; src/strings/it, PASSPORT.IT +FINNISH = 5 ; src/strings/fi, PASSPORT.FI + +; Current language for this assembly +LANG = ENGLISH + + !if LANG=ENGLISH { + !to "../build/PASSPORT.SYSTEM",plain + } + !if LANG=FRENCH { + !to "../build/PASSPORT.FR",plain + } + !if LANG=SPANISH { + !to "../build/PASSPORT.SP",plain + } + !if LANG=ITALIAN { + !to "../build/PASSPORT.IT",plain + } + !if LANG=FINNISH { + !to "../build/PASSPORT.FI",plain + } + +;------------------------------- +; Addresses we read/call +TEXTTOP = $22 +VPOS = $25 +MLI = $BF00 +REBOOT = $FAA6 +TEXT = $FB2F +MACHINEID = $FBB3 +HOME = $FC58 +WAIT = $FCA8 +PRBYTE = $FDDA +COUT = $FDED +PR0 = $FE89 +IN0 = $FE93 + +; Zero-page addresses we use for variables +nibsrcindex = $EC ; byte +nibdestindex = $ED ; byte +prbuf = $EE ; word +unform = $F0 ; word +nibcount = $F2 ; byte +modtmp = $F3 ; byte +modsrc = $F4 ; word +moddest = $F6 ; word +cmp1 = $F8 ; word +cmp2 = $FA ; word +counter = $FC ; byte +tmp = $FC ; byte +tmpa = $FC ; byte +tmpx = $FD ; byte +tmpy = $FE ; byte +flag = $FF ; byte + +; Application constants (not zero addresses) +BASEPAGE = $10 ; Special Delivery tracer assumes + ; this is $10, so don't change it! +TRUE = $00 ; Lots of code assumes this is $00 + ; so it can branch with BEQ, so + ; don't change it either! +FALSE = $01 + +FirstMover + ldy #>LastMover-FirstMover + ldx #$00 +FM lda $2000,x + sta $6800,x + inx + bne FM + inc FM+2 + inc FM+5 + dey + cpy #$48 + bne FM + jmp OneTimeSetup + + !pseudopc *+$4800 { + +; use localized strings based on current language + + !if LANG=ENGLISH { + !source "strings/en.a" + } + !if LANG=FRENCH { + !source "strings/fr.a" + } + !if LANG=SPANISH { + !source "strings/es.a" + } + !if LANG=ITALIAN { + !source "strings/it.a" + } + !if LANG=FINNISH { + !source "strings/fi.a" + } + + !source "analyze.a" + !source "id/inspect0.a" + !source "id/trace.a" + !source "id/dos33.a" + !source "id/jsr8b3.a" + !source "id/mecc.a" + !source "id/datasoft.a" + !source "id/protecteddos.a" + !source "id/specdelivery.a" + !source "id/encode44.a" + !source "id/encode53.a" + !source "print.a" + !source "compare.a" + !source "modify.a" + !source "memory.a" + !source "sectormap.a" + !source "mli.a" + !source "slots.a" + !source "prefs.a" + !source "keys.a" + !source "rwts.a" + +OneTimeSetup + lda $C0E8 + jsr SaveProDOS + ldx MACHINEID + cpx #$EA + bne slotscan + lda #$DF + sta kForceLower +slotscan + jsr ScanForDiskII + lda DiskIIArray+5 + bne founds6 + jmp FatalNoSlot6 +founds6 + jsr LoadPrefs ; load preferences (if available) + bcc ResetVector + jsr SavePrefs ; save preferences (if possible) +ResetVector + lda #ResetVector + sta $03F3 + eor #$A5 + sta $03F4 + lda $C0E8 + jsr PR0 + jsr IN0 + sta $C000 + sta $C002 + sta $C004 + sta $C00C + sta $C00E +MainMenu + ldx #$FF + txs + jsr TEXT + jsr ClearScreen + lda #s_header + jsr PrintByID + lda #s_mainmenu + jsr PrintByID +:getkey + jsr WaitForKey + cmp #$9B + beq jmptoexit + cmp #k_quit + bne + +jmptoexit + jmp CleanExit ++ + cmp #k_slot + bne + + jsr NextSlot + lda #TRUE + sta gChangedPrefs + jmp MainMenu ++ + cmp #k_verify + bne + + lda #%00000000 + beq Action ; unconditional branch ++ + cmp #k_demuffin + bne + + lda #%10000000 + bne Action ; unconditional branch ++ + cmp #k_crack + bne getkey + lda #%11000000 + +; note: execution falls through here + +Action + sta gMode + jsr ResetProgress + jsr InitSectorMap + jsr CopyUniversal + lda #FALSE + sta gTriedUniv + sta gSaidWriting + lda #$00 + sta gTrack + sta gSector + sta gPatchCount + sta callrwts+1 + lda #$08 + sta gAddress+1 + jsr ClearScreen + lda #s_header + jsr PrintByID + lda #s_progbar + jsr PrintByID + lda VPOS + sta TEXTTOP + lda #s_reading + jsr PrintByID +; +; For the initial T00,S00 check, we need to wait much longer +; than usual to find the address prologue, because sector 0 +; might literally be the only standard sector on the track. +; This will get overridden as soon as we either trace the +; disk's RWTS or copy the universal RWTS again. (One of these +; is guaranteed to happen before we read the rest of the disk.) +; + lda #$E7 + sta $B945 + ldy #gRWTSParams ; if T00,S00 is readable + jsr $BD00 ; (only care about the return code) + bcs fatalt00s00 + jmp checkt00s00 +:fatalt00s00 + lda #$F0 + sta $B959 + lda #$05 + sta $B95A + ldy #gRWTSParams + jsr $BD00 + bcs reallyfatal +; +; Bad emulator detected (disk controller presents nibbles +; immediately instead of based on cycle count). Patch the +; universal RWTS to compensate. +; + lda #$F0 + sta _B959 + lda #$05 + sta _B95A + bne checkt00s00 ; unconditional branch +reallyfatal + lda #s_fail + jsr PrintByID + lda #s_fatal0000 + jsr PrintByID + jmp TheEnd +checkt00s00 + jmp CheckT00S00 ; /src/id/inspect0 + + + + + + +; +; We are now fairly confident that the RWTS in memory +; is normal enough to call, Advanced Demuffin style. +; +ADStyle + jsr IncProgress + lda #s_diskrwts + jsr PrintByID +; +; Check for protections in early boot that +; might indicate intentional bad sectors +; elsewhere in the disk that we should skip, +; or changes we need to make to the RWTS +; before we start. +; + jsr xHeredityDog + bcs noDog + lda #s_bb00 + jsr PrintByID +noDog + jsr xSunburst + bcs noSun + lda #s_sunburst + jsr PrintByID +noSun + jsr xOptimumRes + bcs noOptimum + lda #s_optimum + jsr PrintByID +noOptimum + jsr xB660 + jsr xB4BB + jmp ReadWithRWTS + +UseUniversal + jsr IncProgress + jsr StartWithUniv + +; note: execution falls through here + +ReadWithRWTS + lda #$22 + jsr ChangeTrackNW + lda #$0F + jsr ChangeSector + lda #T22S0F + sta checksector+2 +read + lda KEY + bpl checksector + jmp Cancel +checksector + lda $FFFF ; current sector in sector map + pha + beq nextsector ; #$00 = skip this sector + cmp #$FE ; #$FE = switch to built-in RWTS + bne + ; to read this sector + lda gTriedUniv + beq + + jsr SwitchToUniv ++ + jsr ReadSector + bcc nextsector + pla + pha +; +; Uh oh, we got a read error. But do we care? +; Maybe we marked this sector as optional based +; on markers in the bootloader. +; + cmp #$80 + beq optional +; +; If we're in the middle of a track, try switching to the +; universal RWTS and see if that helps. (Many disks contain +; an RWTS that can't read the early tracks or sectors that +; contain the RWTS code, since those are loaded by the +; disk controller firmware.) +; + lda gSector + cmp #$0F + bne tryuniversal +; +; We just got to this track, so check for a variety +; of whole-track conditions +; +; 1) unformatted track +; + jsr IsUnformatted + bcs checkf7 + lda #s_unformat + jsr PrintByID + jmp skiptrack +; +; 2) $F7 protection track (F7F6EFEAAB nibble sequence) +; +checkf7 + jsr IsF7 + bcs checksync + lda #s_f7 + jsr PrintByID + jmp skiptrack +; +; 3) nibble count track (mostly $FF sync bytes) +; +:checksync + jsr IsSyncBytes + bcs tryuniversal + lda #s_sync + jsr PrintByID + +; note: execution falls through here + +skiptrack + lda #$00 ; skip rest of track + jsr ChangeSector + lda checksector+1 + sec + sbc #$0F + sta checksector+1 + bcs notrackdec + dec checksector+2 +notrackdec + jmp nextsector + +:tryuniversal + lda gTriedUniv ; have we tried the universal RWTS? + beq fatal ; yes, so read error is fatal + jsr SwitchToUniv ; no, switch it in now + jmp read ; and re-read this sector + +fatal pla ; if we get to here, we've + jmp FatalError ; decided the read error is fatal + +optional + lda #s_optbad ; say we're skipping this + jsr PrintByID ; optional sector + +; note: execution falls through here + +nextsector + pla + dec checksector+1 + lda checksector+1 + cmp #$FF + bne nodec + dec checksector+2 +nodec + lda gSector + sec + sbc #$01 + jsr ChangeSector + lda gSector + bmi prevtrack + jmp read +prevtrack + lda #$0F + jsr ChangeSector + lda gTrack + sec + sbc #$01 + jsr ChangeTrack + jsr IncProgress + lda gTrack + bmi pass + cmp gLastTrack + bcc pass + jmp read +pass + bit gMode + bmi passwrite + lda #s_pass + bne passprint ; always branches +passwrite + bvs ppasscrack + lda #s_passdemuf + bne passprint ; always branches +ppasscrack + lda gPatchCount + beq ppasscrack0 + lda #s_passcrack + !byte $2C ; hide next LDA +ppasscrack0 + lda #s_passcrack0 +passprint + jsr PrintByID + jmp TheEnd + +SwitchToUniv + lda #s_switch + !byte $2C ; hide next LDA +StartWithUniv + lda #s_builtin + jsr PrintByID + lda #TRUE + sta gTriedUniv + lda #FALSE + sta gIsProtDOS + +; note: execution falls through here + +CopyUniversal + lda #>universalrwts + ldx #$B8 + ldy #$08 + jsr CopyMemory + lda #$00 + sta callrwts+1 + lda #$BD + sta callrwts+2 + rts + +Cancel + lda #s_canceled + jsr PrintByID + jmp TheEnd + +FatalError + lda #s_fail + jsr PrintByID + lda gTrack + cmp #$22 + beq failont22 + jmp TheEnd +failont22 + lda gSector + cmp #$0F + beq failont22s0f + jmp TheEnd +failont22s0f + lda #s_fatal220f + jsr PrintByID + +; note: execution falls through here + +TheEnd + lda $C0E8 + lda #s_done + jsr PrintByID + jsr WaitForKey + cmp #$9B + beq CleanExit + jmp MainMenu + +CleanExit + jsr SwapProDOS + lda gChangedPrefs + bne doquit + jsr SavePrefs +doquit + jsr MLI + !byte $65 + !word quitparm +quitparm + !byte 04,00,00,00,00,00,00 + +FatalNoSlot6 + lda #s_noslot6 + jsr PrintByID + jsr WaitForKey + jmp CleanExit + +ResetProgress + lda #$82 ; reset progress indicator + sta progressind+1 + lda #$05 + sta progressind+2 + rts + +IncProgress + lda #$20 ; display minimal progress indicator +progressind + sta $FFFF ; set at runtime + inc progressind+1 + rts + +;------------------------------- +; WriteTrack +;------------------------------- +MLI_IOERR = $27 +MLI_NODEV = $28 +MLI_WRITEPROT = $2B + +WriteTrack + jsr AnalyzeTrack +WriteTrackNA ; entry point used by Special Delivery tracer + ; to write track with "N"o "A"nalysis + bit gMode + bpl pdone ; verify mode -> no write + lda gSaidWriting + beq write + lda #s_writing ; only print "writing to" message once + jsr PrintByID + lda #TRUE + sta gSaidWriting +write + jsr WriteTrackMLI + bcc pdone + sta gDisplayBytes ; for use in error messages, if any + cmp #MLI_IOERR + beq ioerr + cmp #MLI_NODEV + beq nodev + cmp #MLI_WRITEPROT + beq pwriteprot + lda #s_othermli + !byte $2C ; hide next LDA +ioerr + lda #s_writeioerr + !byte $2C ; hide next LDA +nodev + lda #s_writenodev + !byte $2C ; hide next LDA +pwriteprot + lda #s_writeprot + pha + lda #s_writeerr + jsr PrintByID + pla + jsr PrintByID + jmp TheEnd +pdone + rts + +;------------------------------- +; ChangeTrack +; in: A = new track +;------------------------------- +ChangeTrack + pha + jsr WriteTrack + pla + +; note: execution falls through here + +ChangeTrackNW ; "N"o "W"rite + sta gTrack + jsr ClearTSBuffer + rts + +;------------------------------- +; ChangeSector +; in: A = new sector +;------------------------------- +ChangeSector + sta gSector + clc + adc #BASEPAGE + sta gAddress+1 + rts + +;------------------------------- +; 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 as it finds and makes +; modifications in memory only. +; in: $BASEPAGE page contains one track worth of data +; out: if C set, no known protections were found and +; no modifications were made +; if C clear, at least one modification was made +;------------------------------- +AnalyzeTrack + lda gTrack + beq _applyToT00 + jmp _applyToAll +_applyToT00 + jsr ApplyGlobals + !source "patchers/sunburst.a" + !source "patchers/jmpbcf0.a" + !source "patchers/jmpbeb1.a" + !source "patchers/jmpbeca.a" + !source "patchers/jmpbeca2.a" + !source "patchers/jmpb660.a" + !source "patchers/jmpb720.a" + !source "patchers/bademu.a" + !source "patchers/bademu2.a" + !source "patchers/rwts.a" + !source "patchers/meccm8.a" + !source "patchers/meccm7.a" + !source "patchers/rol1e.a" + !source "patchers/jmpb4bb.a" + !source "patchers/jmpb4bbhi.a" + !source "patchers/jmpb400.a" + !source "patchers/thunder.a" + !source "patchers/jsrbb03.a" + !source "patchers/davidbb03.a" + !source "patchers/rwtsswap.a" + !source "patchers/rwtsswap2.a" + !source "patchers/jmpae8e.a" + !source "patchers/jmpbbfe.a" + !source "patchers/datasoft.a" + !source "patchers/nibtable.a" + !source "patchers/diskvol.a" +_applyToAll + !source "patchers/universale7.a" + !source "patchers/runhello.a" + !source "patchers/a6bc95.a" + !source "patchers/d5d5f7.a" + !source "patchers/prodosrwts.a" + !source "patchers/prodosmecc.a" + !source "patchers/rwtsswapmecc.a" + !source "patchers/protecteddos.a" + + lda gPatchCount + beq nopatches + clc + !byte $24 ; hide next SEC +nopatches + sec ; set carry if nothing happened + rts + +; +; Global variables +; +gTriedUniv + !byte FALSE ; 0=true, 1=false + ; reset to #FALSE before each operation +gMode + !byte %00000000 ; bit 7 0=verify, 1=see bit 6 + ; bit 6 0=demuffin, 1=crack + ; set based on main menu choice +gPatchCount + !byte 00 ; int + ; reset before each operation +gSaidWriting + !byte FALSE ; 0=true, 1=false + ; reset before each operation +gChangedPrefs + !byte FALSE ; 0=true, 1=false + ; set to #TRUE when changing slots +gLastTrack + !byte 00 ; int + ; set after reading T00 +gIsBoot0 + !byte FALSE ; 0=true, 1=false + ; set after reading T00 +gIsBoot1 + !byte FALSE ; 0=true, 1=false + ; set after reading T00 +gIsMaster + !byte FALSE ; 0=true, 1=false + ; set after reading T00 +gIsRWTS + !byte FALSE ; 0=true, 1=false + ; set after reading T00 +gIsProDOS + !byte FALSE ; 0=true, 1=false + ; set after reading T00 +gIsPascal + !byte FALSE ; 0=true, 1=false + ; set after reading T00 +gIsDatasoft + !byte FALSE ; 0=true, 1=false + ; set after reading T00 +gIsProtDOS + !byte FALSE ; 0=true, 1=false + ; set after reading T00 + + !source "applyglobals.a" + !source "universalrwts.a" +LastMover + } diff --git a/src/patchers/a6bc95.a b/src/patchers/a6bc95.a new file mode 100755 index 0000000..05edd9b --- /dev/null +++ b/src/patchers/a6bc95.a @@ -0,0 +1,28 @@ +;------------------------------- +; #A6BC95 +; nibble count after "A6 BC 95" prologue +; e.g. The Secrets of Science Island +;------------------------------- +_a6bc95 + lda gIsPascal ; only ever seen this protection + bne a6bc95_exit ; on Pascal disks + + ldy #$33 + jsr SearchTrack + !byte $AE,$F8,01,$A9,$0A,$8D,$FE,01 + !byte $BD,$8E,$C0,$BD,$89,$C0,$A9,$3A + !byte $8D,$DF,01,$A0,$20,$84,02,$88 + !byte $D0,07,$C6,02,$D0,03,$4C,$F8 + !byte 00,$BD,$8C,$C0,$10,$FB,$C9,$A6 + !byte $D0,$ED,$BD,$8C,$C0,$10,$FB,$C9 + !byte $BC,$D0,$E4 + bcs a6bc95_exit + sta gDisplayBytes + pha + lda #s_a6bc95 + jsr PrintByID + pla + ldy #$01 + jsr modify + !byte $60 +a6bc95_exit diff --git a/src/patchers/bademu.a b/src/patchers/bademu.a new file mode 100755 index 0000000..f785972 --- /dev/null +++ b/src/patchers/bademu.a @@ -0,0 +1,27 @@ +;------------------------------- +; #BADEMU +; RWTS checks for timing bit by +; checking if data latch is still +; $D5 after waiting "too long" +; but this confuses legacy emulators +; (AppleWin, older versions of MAME) +; so we patch it for compatibility +; e.g. Dino Dig, Make A Face +;------------------------------- +_bademu + lda gIsRWTS ; if DOS 3.3 RWTS + bne bademu_exit + lda #$03 + ldx #$4F + ldy #$11 + jsr compare ; and T00,S03,$4F == + !byte $BD,$8C,$C0,$10,$FB,$C9,$D5,$D0 + !byte $F0,$EA,$BD,$8C,$C0,$C9,$D5,$F0 + !byte $12 + bcs bademu_exit + lda #$03 + ldx #$58 + ldy #$02 + jsr modify ; and set T00,S03,$58 = + !byte $F0,06 +bademu_exit diff --git a/src/patchers/bademu2.a b/src/patchers/bademu2.a new file mode 100755 index 0000000..8e91092 --- /dev/null +++ b/src/patchers/bademu2.a @@ -0,0 +1,27 @@ +;------------------------------- +; #BADEMU2 +; RWTS checks for timing bit by +; checking if data latch is still +; $D5 after waiting "too long" +; but this confuses legacy emulators +; (AppleWin, older versions of MAME) +; so we patch it for compatibility +; e.g. Dinosaur Days +;------------------------------- +_bademu2 + lda gIsRWTS ; if DOS 3.3 RWTS + bne bademu2_exit + lda #$03 + ldx #$4F + ldy #$11 + jsr compare ; and T00,S03,$4F == + !byte $BD,$8C,$C0,$10,$FB,$4A,$C9,$6A + !byte $D0,$EF,$BD,$8C,$C0,$C9,$D5,$F0 + !byte $12 + bcs bademu2_exit + lda #$03 + ldx #$59 + ldy #$02 + jsr modify ; and set T00,S03,$59 = + !byte $F0,05 +bademu2_exit diff --git a/src/patchers/d5d5f7.a b/src/patchers/d5d5f7.a new file mode 100755 index 0000000..8c7900c --- /dev/null +++ b/src/patchers/d5d5f7.a @@ -0,0 +1,24 @@ +;------------------------------- +; #D5D5F7 +; nibble count with weird bitstream +; involving $D5 and $F7 as delimiters +; e.g. NoteCard Maker, many Mindplay titles +; (Ace Detective, Robomath, Fraction-oids) +;------------------------------- +_d5d5f7 + ldy #$20 + jsr SearchTrack + !byte $BD,$8C,$C0,$10,$FB,$48,$68,$C9 + !byte $D5,$D0,$F5,$A0,00,$8C,$97,$97 + !byte $BD,$8C,$C0,$10,$FB,$C9,$D5,$F0 + !byte $0F,$C9,$F7,$D0,01,$C8,$18,$6D + bcs d5d5f7_exit + sta gDisplayBytes + pha + lda #s_d5d5f7 + jsr PrintByID + pla + ldy #$01 + jsr modify + !byte $60 +d5d5f7_exit diff --git a/src/patchers/datasoft.a b/src/patchers/datasoft.a new file mode 100755 index 0000000..aad72c1 --- /dev/null +++ b/src/patchers/datasoft.a @@ -0,0 +1,22 @@ +;------------------------------- +; #DATASOFT +; nibble count in encrypted bootloader +; e.g. Video Title Shop, Tomahawk //e +;------------------------------- +_datasoft + lda gIsDatasoft ; only ever seen this protection + bne datasoft_exit ; on Datasoft disks (ID'd earlier) + + ldy #$06 + jsr SearchTrack + !byte $5D,$D4,$80,$49,00,$19 + bcs datasoft_exit + sta gDisplayBytes + pha + lda #s_datasoft + jsr PrintByID + pla + ldy #$01 + jsr modify + !byte $C0 +datasoft_exit diff --git a/src/patchers/davidbb03.a b/src/patchers/davidbb03.a new file mode 100755 index 0000000..4a0afb5 --- /dev/null +++ b/src/patchers/davidbb03.a @@ -0,0 +1,49 @@ +;------------------------------- +; #DAVIDBB03 +; David-DOS boot0 calls $BB03 +; for a self-decrypting nibble +; check which continues to $B7A9 +; on success +; e.g. Case of the Great Train +; Robbery, Case of the Missing +; Chick, Mrs. Wigglesworth's Secret +; Mystery of the Witch's Shoes +;------------------------------- +_davidbb03 + lda #$00 + ldx #$00 + ldy #$38 + jsr compare ; and T00,S00,$00 == + !byte 01,$A5,$27,$C9,09,$D0,$17,$A5 + !byte $2B,$4A,$4A,$4A,$4A,$AA,09,$C0 + !byte $85,$3F,$A9,00,$9D,$78,04,$9D + !byte $F8,04,$A9,$5C,$85,$3E,$AE,$FF + !byte 08,$30,$15,$BD,$ED,08,$85,$3D + !byte $CE,$FF,08,$AD,$FE,08,$85,$27 + !byte $CE,$FE,08,$A6,$2B,$6C,$3E,00 + bcs davidbb03_exit + lda #$00 + ldx #$8B + ldy #$03 + jsr compare ; and T00,S00,$8B == + !byte $20,03,$BB + bcs davidbb03_exit + lda #$07 + ldx #$03 + ldy #$25 + jsr compare ; and T00,S07,$03 == + !byte $4E,06,$BB,$71,$6E + !byte $0A,$BB,$40,$27,$6E,$0F,$BB,$DD + !byte $1B,$BB,$6E,$15,$BB,$DC,$1E,$BB + !byte $6E,$25,$BB,$72,00,$BB,$B3,00 + !byte $B8,$99,00,$BB,$C8,$A0,$F4,$B0 + bcs davidbb03_exit + lda #s_jsrbb03 + jsr PrintByID + lda #$07 + ldx #$03 + ldy #$0B + jsr modify ; then set T00,S07,$03 = + !byte $A9,$B5,$48,$A9,$18,$48,$A0,04 + !byte $4C,$A9,$B7 +davidbb03_exit diff --git a/src/patchers/diskvol.a b/src/patchers/diskvol.a new file mode 100755 index 0000000..4b3b1f9 --- /dev/null +++ b/src/patchers/diskvol.a @@ -0,0 +1,46 @@ +;------------------------------- +; #DISKVOL +; non-standard disk volume prevents +; DOS from loading +;------------------------------- +_diskvol + lda gIsRWTS ; if DOS 3.3 RWTS + bne diskvol_exit + lda #$01 + ldx #$EE + ldy #$01 + jsr compare ; and T00,S01,$EE == + !byte $FB + bcs diskvol_exit + lda #$01 + ldx #$FB + ldy #$04 + jsr compare ; and T00,S01,$FB == + !byte 00,01,$EF,$D8 + bcs diskvol_exit + lda #$08 + ldx #$10 + ldy #$05 + jsr compare ; and T00,S08,$10 == + !byte $A0,03,$B1,$48,$48 + bcs diskvol_exit + lda #$01 + ldx #$EB + ldy #$01 + jsr compare ; and T00,S01,$EB != + !byte $FE + bcc diskvol_exit + lda #$01 + ldx #$EB + ldy #$01 + jsr compare ; and T00,S01,$EB != + !byte 00 + bcc diskvol_exit + lda #s_diskvol + jsr PrintByID + lda #$08 + ldx #$12 + ldy #$02 + jsr modify ; then set T00,S08,$12 = + !byte $A9,00 +diskvol_exit diff --git a/src/patchers/fbff.a b/src/patchers/fbff.a new file mode 100755 index 0000000..612e7cc --- /dev/null +++ b/src/patchers/fbff.a @@ -0,0 +1 @@ + ƍ 卪  捠 덠ؠøððİؠưøðؠð°øðؠðİĸưؠøð¸ùؠİĸðؠ ᠺ᫱ᠣ捠čᠣᠺƠ 占頺ᠺ㍠㠺ᠺ㠺㠺᫱ᠺᠺ썺ᠣƠ 卺Ơ 占ؠƠ 占㠺ؠð占ؠĵ \ No newline at end of file diff --git a/src/patchers/jmpae8e.a b/src/patchers/jmpae8e.a new file mode 100755 index 0000000..475f0e5 --- /dev/null +++ b/src/patchers/jmpae8e.a @@ -0,0 +1,25 @@ +;------------------------------- +; #JMPAE8E +; Late stage DOS jumps to $AE8E +; for a nibble check +; e.g. Alien Addition +;------------------------------- +_jmpae8e + lda gIsBoot0 ; if DOS 3.3 boot0 loader + bne jmpae8e_exit + lda gIsBoot1 ; and DOS 3.3 boot1 loader + bne jmpae8e_exit + lda #$0D + ldx #$4D + ldy #$03 + jsr compare ; and T00,S0D,$4D == + !byte $4C,$8E,$AE + bcs jmpae8e_exit + lda #s_jmpae8e + jsr PrintByID + lda #$0D + ldx #$4E + ldy #$02 + jsr modify ; then set T00,S0D,$4E = + !byte $80,$A1 +jmpae8e_exit diff --git a/src/patchers/jmpb400.a b/src/patchers/jmpb400.a new file mode 100755 index 0000000..7a3ab1e --- /dev/null +++ b/src/patchers/jmpb400.a @@ -0,0 +1,26 @@ +;------------------------------- +; #JMPB400 +; boot1 jumps to nibble check at +; $B400 instead of $9D84 +; e.g. Decimal Discovery +;------------------------------- +_jmpb400 + lda gIsBoot0 ; if DOS 3.3 boot0 loader + bne jmpb400_exit + lda gIsBoot1 ; and DOS 3.3 boot1 loader + bne jmpb400_exit + lda #$01 + sta gDisplayBytes + ldx #$47 + ldy #$03 + jsr compare ; and T00,S01,$47 == + !byte $4C,00,$B4 + bcs jmpb400_exit + lda #s_jmpb400 + jsr PrintByID + lda #$01 + ldx #$48 + ldy #$02 + jsr modify ; then set T00,S01,$48 = + !byte $84,$9D +jmpb400_exit diff --git a/src/patchers/jmpb4bb.a b/src/patchers/jmpb4bb.a new file mode 100755 index 0000000..754f691 --- /dev/null +++ b/src/patchers/jmpb4bb.a @@ -0,0 +1,39 @@ +;------------------------------- +; #JMPB4BB +; boot2 jumps to $B4BB for a +; nibble check +; e.g. Troll's Tale +;------------------------------- +_jmpb4bb + lda gIsMaster ; if DOS 3.3 lomem bootloader + bne jmpb4bb_exit + lda #$0C + sta gDisplayBytes + ldx #$84 + ldy #$03 + jsr compare ; and T00,S0C,$84 == + !byte $4C,$BB,$B4 + bcs jmpb4bb_exit + lda #s_jmpb4bb + lda #$0C + ldx #$84 + ldy #$03 + jsr modify ; then set T00,S0C,$84 = + !byte $AD,$E9,$37 +; +; also check a variant that redirects the DOS input +; vector through code that is only loaded by the +; protection check we just bypassed +; + lda #$0D + ldx #$BA + ldy #$03 + jsr compare ; if T00,S0D,$BA == + !byte $4C,$0B,$37 + bcs jmpb4bb_exit + lda #$0D + ldx #$BA + ldy #$03 + jsr modify ; then set T00,S0D,$BA = + !byte $6C,$38,00 +jmpb4bb_exit diff --git a/src/patchers/jmpb4bbhi.a b/src/patchers/jmpb4bbhi.a new file mode 100755 index 0000000..16b4ee3 --- /dev/null +++ b/src/patchers/jmpb4bbhi.a @@ -0,0 +1,24 @@ +;------------------------------- +; #JMPB4BBHI +; boot2 jumps to $B4BB for a +; nibble check +; e.g. Snooper Troops 2 +;------------------------------- +_jmpb4bbhi + lda gIsBoot1 ; if DOS 3.3 bootloader + bne jmpb4bbhi_exit + lda #$0C + sta gDisplayBytes + ldx #$84 + ldy #$03 + jsr compare ; and T00,S0C,$84 == + !byte $4C,$BB,$B4 + bcs jmpb4bbhi_exit + lda #s_jmpb4bb + jsr PrintByID + lda #$0C + ldx #$84 + ldy #$03 + jsr modify ; then set T00,S0C,$84 = + !byte $AD,$E9,$B7 +jmpb4bbhi_exit diff --git a/src/patchers/jmpb660.a b/src/patchers/jmpb660.a new file mode 100755 index 0000000..6e03615 --- /dev/null +++ b/src/patchers/jmpb660.a @@ -0,0 +1,26 @@ +;------------------------------- +; #JMPB660 +; RWTS jumps to $B660 instead of +; checking third data prologue +; e.g. Analogies Tutorial, Verb Viper +;------------------------------- +_jmpb660 + lda gIsRWTS ; if DOS 3.3-shaped RWTS + bne jmpb660_exit + lda #$02 + ldx #$DC + ldy #$1D + jsr compare ; and T00,S02,$DC == + !byte $A0,$20,$88,$F0,$61,$BD,$8C,$C0 + !byte $10,$FB,$49,$97,$D0,$F4,$EA,$BD + !byte $8C,$C0,$10,$FB,$C9,$97,$D0,$F2 + !byte $A0,$56,$4C,$60,$B6 + bcs jmpb660_exit + lda #s_jmpb660 + jsr PrintByID + lda #$02 + ldx #$F6 + ldy #$03 + jsr modify ; then set T00,S02,$F6 = + !byte $BD,$8C,$C0 +jmpb660_exit diff --git a/src/patchers/jmpb720.a b/src/patchers/jmpb720.a new file mode 100755 index 0000000..b182c38 --- /dev/null +++ b/src/patchers/jmpb720.a @@ -0,0 +1,24 @@ +;------------------------------- +; #JMPB720 +; RWTS swapper forcibly reinstalls +; a jump to $B720 instead of writing +; third data prologue +; e.g. Analogies Tutorial, Verb Viper +;------------------------------- +_jmpb720 + lda gIsRWTS ; if DOS 3.3-shaped RWTS + bne jmpb720_exit + lda #$0B + ldx #$08 + ldy #$18 + jsr compare ; and T00,S0B,$08 == + !byte $4C,$20,$B7,$4C,$0E,$A9,$A2,02 + !byte $BD,$0B,$B7,$9D,$5E,$B8,$BD,08 + !byte $B7,$9D,$F6,$B8,$CA,$10,$F1,$60 + bcs jmpb720_exit + lda #$0B + ldx #$08 + ldy #$06 + jsr modify ; then set T00,S0B,$08 = + !byte $BD,$8C,$C0,$20,$B8,$B8 +jmpb720_exit diff --git a/src/patchers/jmpbbfe.a b/src/patchers/jmpbbfe.a new file mode 100755 index 0000000..934e605 --- /dev/null +++ b/src/patchers/jmpbbfe.a @@ -0,0 +1,21 @@ +;------------------------------- +; #JMPBBFE +; boot0 jumps to nibble check at +; ($BBFE) instead of ($08FD) +; e.g. Mind Over Matter +;------------------------------- +_jmpbbfe + lda gIsBoot0 ; if DOS 3.3 boot0 loader + bne jmpbbfe_exit + lda #$00 + ldx #$4A + ldy #$03 + jsr compare ; and T00,S00,$4A == + !byte $6C,$FE,$BB + bcs jmpbbfe_exit + lda #$00 + ldx #$4B + ldy #$02 + jsr modify ; then set T00,S00,$4B = + !byte $FD,08 +jmpbbfe_exit diff --git a/src/patchers/jmpbcf0.a b/src/patchers/jmpbcf0.a new file mode 100755 index 0000000..08a90a8 --- /dev/null +++ b/src/patchers/jmpbcf0.a @@ -0,0 +1,25 @@ +;------------------------------- +; #JMPBCF0 +; $B999 jumps to $BCF0 to count +; timing bits in data epilogue +; e.g. Easy as ABC +; NOTE: must be run before RWTS +; patchers due to overlapping bytes +;------------------------------- +_jmpbcf0 + lda gIsRWTS ; if DOS 3.3 RWTS + bne jmpbcf0_exit + lda #$03 + ldx #$94 + ldy #$08 + jsr compare ; and T00,S03,$94 == + !byte $DD,$8C,$C0,$D0,$A9,$4C,$F0,$BC + bcs jmpbcf0_exit + lda #s_jmpbcf0 + jsr PrintByID + lda #$03 + ldx #$94 + ldy #$08 + jsr modify ; then set T00,S03,$94 = + !byte $EA,$BD,$8C,$C0,$10,$FB,$C9,$AA +jmpbcf0_exit diff --git a/src/patchers/jmpbeb1.a b/src/patchers/jmpbeb1.a new file mode 100755 index 0000000..1b93c5b --- /dev/null +++ b/src/patchers/jmpbeb1.a @@ -0,0 +1,46 @@ +;------------------------------- +; #JMPBEB1 +; RWTS calls $BEB1 after writing +; data prologue +; e.g. Terrapin Logo 1.2, Starting with Phonics +; NOTE: must be run before RWTS +; patchers due to overlapping bytes +;------------------------------- +_jmpbeb1 + lda gIsRWTS ; if DOS 3.3 RWTS + bne jmpbeb1_exit + lda #$02 + ldx #$48 + ldy #$10 + jsr compare ; and T00,S03,$48 == + !byte $A0,03,$48,$68,$20,$B9,$B8,$88 + !byte $D0,$F8,$4C,$B1,$BE,$EA,$EA,$A9 + bcs jmpbeb1_exit + lda #$02 + ldx #$59 + ldy #$04 + jsr compare ; and T00,S02,$59 == + !byte $20,$B8,$B8,$A9 + bcs jmpbeb1_exit + lda #$02 + ldx #$5E + ldy #$03 + jsr compare ; and T00,S04,$5E == + !byte $20,$BB,$B8 + bcs jmpbeb1_exit + lda #$02 + ldx #$49 + ldy #$01 + jsr modify ; then set T00,S02,$49 = + !byte 04 + lda #$02 + ldx #$52 + ldy #$05 + jsr modify ; and set T00,S02,$52 = + !byte $A9,$D5,$20,$B8,$B8 + lda #$02 + ldx #$5F + ldy #$01 + jsr modify ; and set T00,S02,$5F = + !byte $B8 +jmpbeb1_exit diff --git a/src/patchers/jmpbeca.a b/src/patchers/jmpbeca.a new file mode 100755 index 0000000..4e5985d --- /dev/null +++ b/src/patchers/jmpbeca.a @@ -0,0 +1,27 @@ +;------------------------------- +; #JMPBECA +; RWTS calls $BECA after reading +; data prologue to burn cycles +; e.g. Terrapin Logo 1.2, Starting with Phonics +; NOTE: must be run before RWTS +; patchers due to overlapping bytes +;------------------------------- +_jmpbeca + lda gIsRWTS ; if DOS 3.3 RWTS + bne jmpbeca_exit + lda #$02 + ldx #$F4 + ldy #$0D + jsr compare ; and T00,S02,$F4 == + !byte $EA,$BD,$8C,$C0,$10,$FB,$C9,$AD + !byte $D0,$E8,$4C,$CA,$BE + bcs jmpbeca_exit + lda #s_jmpbeca + jsr PrintByID + lda #$02 + ldx #$F4 + ldy #$0D + jsr modify ; and set T00,S02,$F4 = + !byte $A0,$56,$BD,$8C,$C0,$10,$FB,$C9 + !byte $AD,$D0,$E7,$A9,$00 +jmpbeca_exit diff --git a/src/patchers/jmpbeca2.a b/src/patchers/jmpbeca2.a new file mode 100755 index 0000000..7d40cfc --- /dev/null +++ b/src/patchers/jmpbeca2.a @@ -0,0 +1,28 @@ +;------------------------------- +; #JMPBECA2 +; RWTS calls $BECA for funny business +; instead of checking data prologue +; (variation #2) +; e.g. Library Magic +; NOTE: must be run before RWTS +; patchers due to overlapping bytes +;------------------------------- +_jmpbeca2 + lda gIsRWTS ; if DOS 3.3 RWTS + bne jmpbeca2_exit + lda #$02 + ldx #$F4 + ldy #$0D + jsr compare ; and T00,S02,$F4 == + !byte $4C,$CA,$BE,$EA,$BD,$8C,$C0,$10 + !byte $FB,$49,$AD,$D0,$DD + bcs jmpbeca2_exit + lda #s_jmpbeca + jsr PrintByID + lda #$02 + ldx #$F4 + ldy #$0D + jsr modify ; and set T00,S02,$F4 = + !byte $A0,$56,$BD,$8C,$C0,$10,$FB,$C9 + !byte $AD,$D0,$E7,$A9,00 +jmpbeca2_exit diff --git a/src/patchers/jsrbb03.a b/src/patchers/jsrbb03.a new file mode 100755 index 0000000..488f5b9 --- /dev/null +++ b/src/patchers/jsrbb03.a @@ -0,0 +1,37 @@ +;------------------------------- +; #JSRBB03 +; boot1 calls $BB03 for a self- +; decrypting nibble check which +; continues to $B793 on success +; e.g. Classifying Animals with +; Backbones, EduCalc +;------------------------------- +_jsrbb03 + lda gIsBoot0 ; if DOS 3.3 boot0 loader + bne jsrbb03_exit + lda gIsBoot1 ; and DOS 3.3 boot1 loader + bne jsrbb03_exit + lda #$01 + ldx #$38 + ldy #$03 + jsr compare ; and T00,S01,$38 == + !byte $20,03,$BB + bcs jsrbb03_exit + lda #$05 + ldx #$03 + ldy #$25 + jsr compare ; and T00,S05,$03 == + !byte $4E,06,$BB,$71,$6E + !byte $0A,$BB,$40,$27,$6E,$0F,$BB,$DD + !byte $1B,$BB,$6E,$15,$BB,$DC,$1E,$BB + !byte $6E,$25,$BB,$72,00,$BB,$B3,00 + !byte $B8,$99,00,$BB,$C8,$A0,$F4,$B0 + bcs jsrbb03_exit + lda #s_jsrbb03 + jsr PrintByID + lda #$05 + ldx #$03 + ldy #$09 + jsr modify ; then set T00,S05,$03 = + !byte $A9,$B5,$48,$A9,$18,$48,$4C,$93,$B7 +jsrbb03_exit diff --git a/src/patchers/meccm7.a b/src/patchers/meccm7.a new file mode 100755 index 0000000..fd90b6b --- /dev/null +++ b/src/patchers/meccm7.a @@ -0,0 +1,126 @@ +;------------------------------- +; #MECCM7 +; MECC fastloader with custom +; address and data prologues +; e.g. Phonics Prime Time series +;------------------------------- +_meccm7 + lda #$00 + ldx #$00 + ldy #$17 + jsr compare ; if T00,S00,$00 == + !byte 01,$4C,$1A,08,$17,$0F,00,00 + !byte $0D,$0B,09,07,05,03,01,$0E + !byte $0C,$0A,08,06,04,02,$0F + bcs meccm7_exit + lda #$07 + ldx #$7D + ldy #$06 + jsr compare ; and T00,S07,$7D == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs meccm7_exit + lda #$07 + ldx #$84 + ldy #$09 + jsr compare ; and T00,S07,$84 == + !byte $D0,$F0,$EA,$BD,$8C,$C0,$10,$FB,$C9 + bcs meccm7_exit + lda #$07 + ldx #$8E + ldy #$0A + jsr compare ; and T00,S07,$8E == + !byte $D0,$F2,$A0,03,$BD,$8C,$C0,$10,$FB,$C9 + bcs meccm7_exit + lda #$07 + ldx #$0F + ldy #$06 + jsr compare ; and T00,S07,$0F == + !byte $BD,$8C,$C0,$10,$FB,$49 + bcs meccm7_exit + lda #$07 + ldx #$18 + ldy #$07 + jsr compare ; and T00,S07,$18 == + !byte $EA,$BD,$8C,$C0,$10,$FB,$C9 + bcs meccm7_exit + lda #$07 + ldx #$20 + ldy #$0A + jsr compare ; and T00,S07,$20 == + !byte $D0,$F2,$A0,$56,$BD,$8C,$C0,$10,$FB,$C9 + bcc meccm7_allclear +meccm7_exit + jmp meccm7_exit2 +meccm7_allclear + lda #$07 + ldx #$83 + ldy #$01 + jsr compare ; if T00,S07,$83 != + !byte $D5 + bcc meccm7_addr2 + lda #$07 + ldx #$83 + ldy #$01 + jsr modify ; then set T00,S07,$83 = + !byte $D5 +meccm7_addr2 + lda #$07 + ldx #$8D + ldy #$01 + jsr compare ; if T00,S07,$8D != + !byte $AA + bcc meccm7_addr3 + lda #$07 + ldx #$8D + ldy #$01 + jsr modify ; then set T00,S07,$8D = + !byte $AA +meccm7_addr3 + lda #$07 + ldx #$98 + ldy #$01 + jsr compare ; if T00,S07,$98 != + !byte $96 + bcc meccm7_data1 + lda #$07 + ldx #$98 + ldy #$01 + jsr modify ; then set T00,S07,$98 = + !byte $96 +meccm7_data1 + lda #$07 + ldx #$15 + ldy #$01 + jsr compare ; if T00,S07,$15 != + !byte $D5 + bcc meccm7_data2 + lda #$07 + ldx #$15 + ldy #$01 + jsr modify ; then set T00,S07,$15 = + !byte $D5 +meccm7_data2 + lda #$07 + ldx #$1F + ldy #$01 + jsr compare ; if T00,S07,$1F != + !byte $AA + bcc meccm7_data3 + lda #$07 + ldx #$1F + ldy #$01 + jsr modify ; then set T00,S07,$1F = + !byte $AA +meccm7_data3 + lda #$07 + ldx #$2A + ldy #$01 + jsr compare ; if T00,S07,$2A != + !byte $AD + bcc meccm7_exit2 + lda #$07 + ldx #$2A + ldy #$01 + jsr modify ; then set T00,S07,$2A = + !byte $AD +meccm7_exit2 diff --git a/src/patchers/meccm8.a b/src/patchers/meccm8.a new file mode 100755 index 0000000..54d2626 --- /dev/null +++ b/src/patchers/meccm8.a @@ -0,0 +1,130 @@ +;------------------------------- +; #MECCM8 +; MECC fastloader with custom +; address and data prologues +; e.g. Word Munchers +;------------------------------- +_meccm8 + lda #$00 + ldx #$00 + ldy #$17 + jsr compare ; if T00,S00,$00 == + !byte 01,$4C,$1A,08,$17,$0F,00,00 + !byte $0D,$0B,09,07,05,03,01,$0E + !byte $0C,$0A,08,06,04,02,$0F + bcs meccm8_exit + lda #$0B + ldx #$02 + ldy #$06 + jsr compare ; and T00,S0B,$02 == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs meccm8_exit + lda #$0B + ldx #$09 + ldy #$09 + jsr compare ; and T00,S0B,$09 == + !byte $D0,$EF,$EA,$BD,$8C,$C0,$10,$FB + !byte $C9 + bcs meccm8_exit + lda #$0B + ldx #$13 + ldy #$0A + jsr compare ; and T00,S0B,$13 == + !byte $D0,$E5,$A0,$03,$BD,$8C,$C0,$10 + !byte $FB,$C9 + bcs meccm8_exit + lda #$0B + ldx #$89 + ldy #$06 + jsr compare ; and T00,S0B,$89 == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs meccm8_exit + lda #$0B + ldx #$90 + ldy #$09 + jsr compare ; and T00,S0B,$90 == + !byte $D0,$F4,$EA,$BD,$8C,$C0,$10,$FB + !byte $C9 + bcs meccm8_exit + lda #$0B + ldx #$9A + ldy #$09 + jsr compare ; and T00,S0B,$9A == + !byte $D0,$F2,$EA,$BD,$8C,$C0,$10,$FB + !byte $C9 + bcc meccm8_allclear +meccm8_exit + jmp meccm8_exit2 +meccm8_allclear + lda #$0B + ldx #$08 + ldy #$01 + jsr compare ; if T00,S0B,$08 != + !byte $D5 + bcc meccm8_addr2 + lda #$0B + ldx #$08 + ldy #$01 + jsr modify ; then set T00,S0B,$0B = + !byte $D5 +meccm8_addr2 + lda #$0B + ldx #$12 + ldy #$01 + jsr compare ; if T00,S0B,$12 != + !byte $AA + bcc meccm8_addr3 + lda #$0B + ldx #$12 + ldy #$01 + jsr modify ; then set T00,S0B,$12 = + !byte $AA +meccm8_addr3 + lda #$0B + ldx #$1D + ldy #$01 + jsr compare ; if T00,S0B,$1D != + !byte $96 + bcc meccm8_data1 + lda #$0B + ldx #$1D + ldy #$01 + jsr modify ; then set T00,S0B,$1D = + !byte $96 +meccm8_data1 + lda #$0B + ldx #$8F + ldy #$01 + jsr compare ; if T00,S0B,$8F != + !byte $D5 + bcc meccm8_data2 + lda #$0B + ldx #$8F + ldy #$01 + jsr modify ; then set T00,S0B,$8F = + !byte $D5 +meccm8_data2 + lda #$0B + ldx #$99 + ldy #$01 + jsr compare ; if T00,S0B,$99 != + !byte $AA + bcc meccm8_data3 + lda #$0B + ldx #$99 + ldy #$01 + jsr modify ; then set T00,S0B,$99 = + !byte $AA +meccm8_data3 + lda #$0B + ldx #$A3 + ldy #$01 + jsr compare ; if T00,S0B,$A3 != + !byte $AD + bcc meccm8_exit2 + lda #$0B + ldx #$A3 + ldy #$01 + jsr modify ; then set T00,S0B,$A3 = + !byte $AD +meccm8_exit2 diff --git a/src/patchers/nibtable.a b/src/patchers/nibtable.a new file mode 100755 index 0000000..6631123 --- /dev/null +++ b/src/patchers/nibtable.a @@ -0,0 +1,136 @@ +;------------------------------- +; #NIBTABLE +; detect and fix non-standard +; nibble-to-byte translation +; e.g. Travels with Za-Zoom +;------------------------------- +_nibtable + jmp checkread + +readdata + !byte 00,01 + !byte $98,$99,02,03,$9C,04,05,06 + !byte $A0,$A1,$A2,$A3,$A4,$A5,07,08 + !byte $A8,$A9,$AA,09,$0A,$0B,$0C,$0D + !byte $B0,$B1,$0E,$0F,$10,$11,$12,$13 + !byte $B8,$14,$15,$16,$17,$18,$19,$1A + !byte $C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7 + !byte $C8,$C9,$CA,$1B,$CC,$1C,$1D,$1E + !byte $D0,$D1,$D2,$1F,$D4,$D5,$20,$21 + !byte $D8,$22,$23,$24,$25,$26,$27,$28 + !byte $E0,$E1,$E2,$E3,$E4,$29,$2A,$2B + !byte $E8,$2C,$2D,$2E,$2F,$30,$31,$32 + !byte $F0,$F1,$33,$34,$35,$36,$37,$38 + !byte $F8,$39,$3A,$3B,$3C,$3D,$3E,$3F + +writedata + !byte $96,$97,$9A,$9B,$9D,$9E,$9F,$A6 + !byte $A7,$AB,$AC,$AD,$AE,$AF,$B2,$B3 + !byte $B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC + !byte $BD,$BE,$BF,$CB,$CD,$CE,$CF,$D3 + !byte $D6,$D7,$D9,$DA,$DB,$DC,$DD,$DE + !byte $DF,$E5,$E6,$E7,$E9,$EA,$EB,$EC + !byte $ED,$EE,$EF,$F2,$F3,$F4,$F5,$F6 + !byte $F7,$F9,$FA,$FB,$FC,$FD,$FE,$FF + +checkread + lda gIsRWTS ; if DOS 3.3 RWTS + bne nibtable_exit + lda #$02 + ldx #$6D + ldy #$03 + jsr compare ; and T00,S02,$6D == + !byte $BD,$29,$BA + bcs checkwrite + lda #$02 + ldx #$82 + ldy #$03 + jsr compare ; and T00,S02,$82 == + !byte $BD,$29,$BA + bcs checkwrite + lda #$02 + ldx #$95 + ldy #$03 + jsr compare ; and T00,S02,$95 == + !byte $BD,$29,$BA + bcs checkwrite + jsr fixwrite +checkwrite + lda #$03 + ldx #$09 + ldy #$03 + jsr compare ; if T00,S03,$09 == + !byte $59,00,$BA + bcs nibtable_exit + lda #$03 + ldx #$1A + ldy #$03 + jsr compare ; and T00,S03,$1A == + !byte $59,00,$BA + bcs nibtable_exit + lda #$03 + ldx #$2A + ldy #$03 + jsr compare ; and T00,S03,$2A == + !byte $D9,00,$BA + bcs nibtable_exit + jsr fixread +nibtable_exit + jmp nibtable_exit2 + +fixread + lda #$00 + sta nibsrcindex + lda #$96 + sta nibdestindex +nibtable_read + ldx nibsrcindex + lda readdata,x + sta nibcmpr + sta nibmodr + lda #$04 + ldx nibdestindex + ldy #$01 + jsr compare +nibcmpr !byte $FF + bcc nomodr + lda #$04 + ldx nibdestindex + ldy #$01 + jsr modify +nibmodr !byte $FF +nomodr + inc nibsrcindex + inc nibdestindex + bne nibtable_read + rts + +fixwrite + lda #$00 + sta nibsrcindex + lda #$29 + sta nibdestindex +nibtable_write + ldx nibsrcindex + lda writedata,x + sta nibcmpw + sta nibmodw + lda #$04 + ldx nibdestindex + ldy #$01 + jsr compare +nibcmpw !byte $FF + bcc nomodw + lda #$04 + ldx nibdestindex + ldy #$01 + jsr modify +nibmodw !byte $FF +nomodw + inc nibsrcindex + inc nibdestindex + lda nibsrcindex + cmp #$40 + bne nibtable_write + rts +nibtable_exit2 diff --git a/src/patchers/prodosmecc.a b/src/patchers/prodosmecc.a new file mode 100755 index 0000000..e712454 --- /dev/null +++ b/src/patchers/prodosmecc.a @@ -0,0 +1,146 @@ +;------------------------------- +; #PRODOSMECC +; patch MECC-specific bits on +; ProDOS-based MECC disks +; [thanks LoGo] +;------------------------------- +_prodosmecc + lda gIsProDOS + beq + + jmp prodosmecc_exit ++ + ldy #$0E + jsr SearchTrack + !byte $50,$54,$58,$5C,$60,$64,$68,00 + !byte $20,$10,$30,$97,$AA,$EB + bcs + + sta gDisplayBytes + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + ldy #$01 + jsr compare + !byte $DE + bcc + + ldy #$01 + jsr modify + !byte $DE ++ + ldy #$15 + jsr SearchTrack + !byte $AD,$C4,$D1,$CD,$C8,$D4,08,$2C + !byte $81,$C0,$28,$D0,06,$C9,$DE,$F0 + !byte 02,$18,$24,$38,$60 + bcs + + sta gDisplayBytes + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + ldy #$01 + jsr compare + !byte $38 + bcs + + ldy #$01 + jsr modify + !byte $18 ++ + ldy #$18 + jsr SearchTrack + +; variation seen in e.g. A-232 Spelling Press + + !byte $AD,$C4,$D1,$CD,$C8,$D4,08,$2C + !byte $81,$C0,$28,$D0,09,$8D,$97,$97 + !byte $C9,$DE,$F0,02,$18,$24,$38,$60 + bcs + + sta gDisplayBytes + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + ldy #$01 + jsr compare + !byte $38 + bcs + + ldy #$01 + jsr modify + !byte $18 ++ + ldy #$0C + jsr SearchTrack + !byte $30,$A2,$20,00,$BF,$80,$97,$97,$B0,$98,$38,$60 + bcs + + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + ldy #$01 + jsr compare + !byte $38 + bcs + + ldy #$01 + jsr modify + !byte $18 ++ + ldy #$0B + jsr SearchTrack + !byte $30,$91,$38,$60,00,$20,00,03,00,03,00 + bcs prodosmecc_exit + inx + inx + ldy #$01 + jsr compare + !byte $38 + bcs prodosmecc_exit + ldy #$01 + jsr modify + !byte $18 +prodosmecc_exit diff --git a/src/patchers/prodosrwts.a b/src/patchers/prodosrwts.a new file mode 100755 index 0000000..6a25cee --- /dev/null +++ b/src/patchers/prodosrwts.a @@ -0,0 +1,38 @@ +;------------------------------- +; #PRODOSRWTS +; patch ProDOS RWTS +; e.g. ProDOS-based MECC disks +;------------------------------- +_prodosrwts + lda gIsProDOS + bne prodosrwts_exit + ldy #$14 + jsr SearchTrack + !byte $29,$FC,$5D,$97,$97,$D0,$0C,$A6 + !byte $97,$BD,$8C,$C0,$10,$FB,$C9,$97 + !byte $18,$F0,01,$38 + bcs prodosrwts_exit + sta gDisplayBytes + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + inx + ldy #$01 + jsr compare + !byte $DE + bcc prodosrwts_exit + ldy #$01 + jsr modify + !byte $DE +prodosrwts_exit diff --git a/src/patchers/protecteddos.a b/src/patchers/protecteddos.a new file mode 100755 index 0000000..c3d7102 --- /dev/null +++ b/src/patchers/protecteddos.a @@ -0,0 +1,223 @@ +;------------------------------- +; #PROTECTEDDOS +; patcher for "Protected.DOS", +; an insane full-DOS makeover with a self- +; decrypting bootloader, RWTS swappers, +; embedded serial numbers, and more +; e.g. Bingo Bugglebee Presents series +; (Home Alone / Outdoor Safety / Famous People), +; Math Blaster, Moebius +;------------------------------- +_protdos + lda gIsProtDOS + beq + + jmp protdos_exit ++ +; +; Find secondary/tertiary RWTS swappers on any track +; e.g. Moebius +; + ldy #$0C + jsr SearchTrack + !byte $A9,$B5,$85,$4E,$8D,$5D,$BD,$A9 + !byte $D5,$8D,$2C,$BF + bcs specific + sta swapper2+1 + inx + stx swapper1+1 + ldy #$01 + jsr modify ; offset $01: $B5 -> $AD + !byte $AD +swapper1 + lda #$FF ; modified at runtime + clc + adc #$07 + tax +swapper2 + lda #$FF ; modified at runtime + ldy #$01 + jsr modify ; offset $08: $D5 -> 9B + !byte $9B + +specific + lda gTrack + cmp #$02 + bcc strip + jmp protdos_exit +strip +; +; strip 6-digit numeric serial number +; (appears on both track 0 and 1, but +; in different sectors) +; + cmp #$01 + beq + + lda #BASEPAGE + clc + adc #$0B + tax + lda #$0B + jmp ++ ++ + ldx #BASEPAGE + inx + inx + lda #$02 +++ + stx serial+2 + stx serialb+2 + sta gDisplayBytes+3 + lda #$C5 + sta serial+1 + sta serialb+1 + ldy #$00 +serialloop + jsr serial + tax + jsr serial + jsr XA2byte + sta gDisplayBytes,y + iny + cpy #$03 + bne serialloop + lda #s_protserial + jsr PrintByID + + lda gTrack + beq track0 + +; +; disable RWTS swapper (technically make the +; "protected disk" mode the same as the +; "standard disk" mode) +; + lda #$02 + ldx #$AF + ldy #$0C + jsr compare ; if T01,S02,$AF == + !byte $A2,$B5,$86,$4E,$8E,$5D,$BD,$A2 + !byte $D5,$8E,$2C,$BF + bcs exitt1 + lda #$02 + ldx #$B0 + ldy #$01 + jsr modify ; then set T01,S02,$B0 = + !byte $AD + lda #$02 + ldx #$B7 + ldy #$01 + jsr modify ; and set T01,S02,$B7 = + !byte $9B + +exitt1 + jmp protdos_exit + +:track0 +; +; decrypt RWTS in track buffer +; + lda #s_protdosw + jsr PrintByID + ldx #BASEPAGE + inx + stx a+2 + stx b+2 + stx c+2 +a lda $FF06 ; modified at runtime + sta pdkey+1 + ldx #$09 + ldy #$1A +b lda $FF00,Y ; modified at runtime +pdkey eor #$FF ; modified at runtime +c sta $FF00,Y ; modified at runtime + iny + bne b + inc b+2 + inc c+2 + dex + bne b + +; +; disable decryption loop +; + lda #$01 + ldx #$07 + ldy #$01 + jsr modify ; set T00,S01,$07 = + !byte $2C + +; +; bypass check for duplicate T00,S00 +; + lda #$01 + ldx #$93 + ldy #$03 + jsr compare ; if T00,S01,$93 == + !byte $4C,00,$B8 + bcs skipcheck + ldy #$03 + jsr modify ; then set T00,S01,$93 = + !byte $AC,$E5,$B7 +skipcheck + +; +; fake "found disk volume" in RWTS parameter table +; so it's always 0 (many Davidson disks have +; multiple secondary checks for this) +; + lda #$05 + ldx #$15 + ldy #$02 + jsr compare ; if T00,S05,$15 == + !byte $A5,$2F + bcs protdos_exit + ldy #$02 + jsr modify ; then set T00,S05,$15 = + !byte $A9,00 + +; +; re-enable write mode if it was disabled +; + lda #$07 + ldx #$48 + ldy #$19 + jsr compare ; if T00,S07,$48 == + !byte $A0,04,$48,$68,$A0,$B9,$BD,$88 + !byte $D0,$F8,$A9,$97,$20,$B8,$BD,$A9 + !byte $97,$20,$B8,$BD,$A9,$97,$20,$B8 + !byte $BD + bcs writeIsOK + ldx #$4C + ldy #$01 + jsr modify ; then set T00,S07,$4C = + !byte $20 +writeIsOK + jmp protdos_exit + +; subroutines for getting (and erasing) the embedded +; 6-digit serial number and converting them to bytes +; for printing +serial + lda $FFFF ; modified at runtime + pha + lda #$B0 +serialb + sta $FFFF ; modified at runtime + pla + inc serial+1 + inc serialb+1 + inc gPatchCount + rts + +XA2byte + and #$0F + sta tmp + txa + asl + asl + asl + asl + ora tmp + rts + +protdos_exit diff --git a/src/patchers/rol1e.a b/src/patchers/rol1e.a new file mode 100755 index 0000000..f8598eb --- /dev/null +++ b/src/patchers/rol1e.a @@ -0,0 +1,35 @@ +;------------------------------- +; #ROL1E +; RWTS stores timing bits in $1E +; e.g. Spellicopter +;------------------------------- +_rol1e + lda #$03 + ldx #$00 + ldy #$2F + jsr compare ; if T00,S03,$00 == + !byte $86,$1B,$BA,$BD,02,01,$85,03 + !byte $18,$69,04,$85,05,$A0,00,$84 + !byte 02,$A0,$40,$84,04,$A0,$39,$A9 + !byte $93,$91,02,$C8,$A5,03,$91,02 + !byte $A0,$7F,$B1,04,$99,00,08,$88 + !byte $10,$F8,$A6,$1B,$4C,00,08 + bcs rol1e_exit + lda #$03 + ldx #$40 + ldy #$28 + jsr compare ; and T00,S03,$40 == + !byte $A9,00,$A0,$EC,$91,02,$C8,$91 + !byte 02,$A9,09,$A0,$F1,$91,02,$A9 + !byte 08,$A0,$E1,$91,02,$A9,$4C,$85 + !byte 01,$A9,$93,$85,02,$20,01,00 + !byte $A0,00,$84,02,$A5,$1E,$85,08 + bcs rol1e_exit + lda #s_rol1e + jsr PrintByID + lda #$03 + ldx #$64 + ldy #$02 + jsr modify ; then set T00,S03,$64 = + !byte $A9,$F7 +rol1e_exit diff --git a/src/patchers/runhello.a b/src/patchers/runhello.a new file mode 100755 index 0000000..e26248a --- /dev/null +++ b/src/patchers/runhello.a @@ -0,0 +1,52 @@ +;------------------------------- +; #RUNHELLO +; search and destroy a protection check +; in a startup file that runs the real +; startup program after succeeding +; e.g. Microzine 15, Alpine Tram Ride +;------------------------------- +_runhello + lda gIsProDOS ; this exact protection is only + beq runhello_exit ; on DOS 3.3 disks (other patchers + lda gIsPascal ; will catch other variations) + beq runhello_exit + lda #$0F + sta rhsector+1 +rhsector lda #$FF ; modified at runtime + ldx #$04 + ldy #$05 + jsr compare + !byte $20,$E3,03,$85,$FB + bcc + + jmp rhnextsector ++ + lda rhsector+1 + ldx #$19 + ldy #$06 + jsr compare + !byte $CA,$10,$F8,$8A,$48,$20 + bcc + + jmp rhnextsector ++ + lda rhsector+1 + ldx #$21 + ldy #$06 + jsr compare + !byte $A0,01,$B1,$FA,$AA,$20 + bcc + + jmp rhnextsector ++ + lda rhsector+1 + sta gDisplayBytes + lda #s_runhello + jsr PrintByID + lda rhsector+1 + ldx #$26 + ldy #$01 + jsr modify + !byte $2C +rhnextsector + dec rhsector+1 + bmi runhello_exit + jmp rhsector +runhello_exit diff --git a/src/patchers/rwts.a b/src/patchers/rwts.a new file mode 100755 index 0000000..2d0ecfe --- /dev/null +++ b/src/patchers/rwts.a @@ -0,0 +1,664 @@ +;------------------------------- +; RWTS fixup #AP1R +; address prologue byte 1 (read) +;------------------------------- +rwtspatcher + lda gIsRWTS ; if DOS 3.3 RWTS + bne ap1r + lda #$03 + ldx #$4F + ldy #$06 + jsr compare ; and T00,S03,$4F == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs ap1r + ldx #$56 + ldy #$03 + jsr compare ; and T00,S03,$56 == + !byte $D0,$F0,$EA + bcs ap1r + ldx #$55 + ldy #$01 + jsr compare ; and T00,S03,$55 != + !byte $D5 + bcc ap1r + ldy #$01 + jsr modify ; then set T00,S03,$55 = + !byte $D5 +ap1r + +;------------------------------- +; RWTS fixup #AP2R +; address prologue byte 2 (read) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ap2r + lda #$03 + ldx #$59 + ldy #$06 + jsr compare ; and T00,S03,$59 == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs ap2r + ldx #$60 + ldy #$04 + jsr compare ; and T00,S03,$60 == + !byte $D0,$F2,$A0,$03 + bcs ap2r + ldx #$5F + ldy #$01 + jsr compare ; and T00,S03,$5F != + !byte $AA + bcc ap2r + ldy #$01 + jsr modify ; then set T00,S03,$5F = + !byte $AA +ap2r + +;------------------------------- +; RWTS fixup #AP3R +; address prologue byte 3 (read) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ap3r + lda #$03 + ldx #$64 + ldy #$06 + jsr compare ; and T00,S03,$64 == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs ap3r + ldx #$6B + ldy #$02 + jsr compare ; and T00,S03,$6B == + !byte $D0,$E7 + bcs ap3r + ldx #$6A + ldy #$01 + jsr compare ; and T00,S03,$6A != + !byte $96 + bcc ap3r + ldy #$01 + jsr modify ; then set T00,S03,$6A = + !byte $96 +ap3r + +;------------------------------- +; RWTS fixup #AE1R +; address epilogue byte 1 (read) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ae1r + lda #$03 + ldx #$8B + ldy #$06 + jsr compare ; and T00,S03,$8B == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs ae1r + ldx #$92 + ldy #$03 + jsr compare ; and T00,S03,$92 == + !byte $D0,$AE,$EA + bcs ae1r + ldx #$91 + ldy #$01 + jsr compare ; and T00,S03,$91 != + !byte $DE + bcc ae1r + ldy #$01 + jsr modify ; then set T00,S03,$91 = + !byte $DE +ae1r + +;------------------------------- +; RWTS fixup #AE2R +; address epilogue byte 2 (read) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ae2r + lda #$03 + ldx #$95 + ldy #$06 + jsr compare ; and T00,S03,$95 == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs ae2r + ldx #$9C + ldy #$03 + jsr compare ; and T00,S03,$9C == + !byte $D0,$A4,$18 + bcs ae2r + ldx #$9B + ldy #$01 + jsr compare ; and T00,S03,$9B != + !byte $AA + bcc ae2r + ldy #$01 + jsr modify ; then set T00,S03,$9B = + !byte $AA +ae2r + +;------------------------------- +; RWTS fixus #DP1R +; data prologue byte 1 (read) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne dp1r + lda #$02 + ldx #$E1 + ldy #$06 + jsr compare ; and T00,S02,$E1 == + !byte $BD,$8C,$C0,$10,$FB,$49 + bcs dp1r + ldx #$E8 + ldy #$03 + jsr compare ; and T00,S02,$E8 == + !byte $D0,$F4,$EA + bcs dp1r + ldx #$E7 + ldy #$01 + jsr compare ; and T00,S02,$E7 != + !byte $D5 + bcc dp1r + ldy #$01 + jsr modify ; then set T00,S02,$E7 = + !byte $D5 +dp1r + +;------------------------------- +; RWTS fixup #DP2R +; data prologue byte 2 (read) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne dp2r + lda #$02 + ldx #$EB + ldy #$06 + jsr compare ; and T00,S02,$EB == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs dp2r + ldx #$F2 + ldy #$04 + jsr compare ; and T00,S02,$F2 == + !byte $D0,$F2,$A0,$56 + bcs dp2r + ldx #$F1 + ldy #$01 + jsr compare ; and T00,S02,$F1 != + !byte $AA + bcc dp2r + ldy #$01 + jsr modify ; then set T00,S02,$F1 = + !byte $AA +dp2r + +;------------------------------- +; RWTS fixup #DP3R +; data prologue byte 3 (read) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne dp3r + lda #$02 + ldx #$F6 + ldy #$06 + jsr compare ; and T00,S02,$F6 == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs dp3r + ldx #$FD + ldy #$02 + jsr compare ; and T00,S02,$FD == + !byte $D0,$E7 + bcs dp3r + ldx #$FC + ldy #$01 + jsr compare ; and T00,S02,$FC != + !byte $AD + bcc dp3r + ldy #$01 + jsr modify ; then set T00,S02,$FC = + !byte $AD +dp3r + +;------------------------------- +; RWTS fixup #DE1R +; data epilogue byte 1 (read) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne de1r + lda #$03 + ldx #$2F + ldy #$06 + jsr compare ; and T00,S03,$2F == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs de1r + ldx #$36 + ldy #$03 + jsr compare ; and T00,S03,$36 == + !byte $D0,$0A,$EA + bcs de1r + ldx #$35 + ldy #$01 + jsr compare ; and T00,S03,$35 != + !byte $DE + bcc de1r + ldy #$01 + jsr modify ; then set T00,S03,$35 = + !byte $DE +de1r + +;------------------------------- +; RWTS fixup #DE2R +; data epilogue byte 2 (read) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne de2r + lda #$03 + ldx #$39 + ldy #$06 + jsr compare ; and T00,S03,$39 == + !byte $BD,$8C,$C0,$10,$FB,$C9 + bcs de2r + ldx #$40 + ldy #$03 + jsr compare ; and T00,S03,$40 == + !byte $F0,$5C,$38 + bcs de2r + ldx #$3F + ldy #$01 + jsr compare ; and T00,S03,$3F != + !byte $AA + bcc de2r + ldy #$01 + jsr modify ; then set T00,S03,$3F = + !byte $AA +de2r + +;------------------------------- +; RWTS fixup #AP1W +; address prologue byte 1 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ap1w + lda #$06 + ldx #$79 + ldy #$01 + jsr compare ; and T00,S06,$79 == + !byte $A9 + bcs ap1w + ldx #$7B + ldy #$02 + jsr compare ; and T00,S06,$7B == + !byte $20,$D5 + bcs ap1w + ldx #$7A + ldy #$01 + jsr compare ; and T00,S06,$7A != + !byte $D5 + bcc ap1w + ldy #$01 + jsr modify ; then set T00,S06,$7A = + !byte $D5 +ap1w + +;------------------------------- +; RWTS fixup #AP2W +; address prologue byte 2 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ap2w + lda #$06 + ldx #$7E + ldy #$01 + jsr compare ; and T00,S06,$7E == + !byte $A9 + bcs ap2w + ldx #$80 + ldy #$02 + jsr compare ; and T00,S06,$80 == + !byte $20,$D5 + bcs ap2w + ldx #$7F + ldy #$01 + jsr compare ; and T00,S06,$7F != + !byte $AA + bcc ap2w + ldy #$01 + jsr modify ; then set T00,S06,$7F = + !byte $AA +ap2w + +;------------------------------- +; RWTS fixup #AP3W +; address prologue byte 3 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ap3w + lda #$06 + ldx #$83 + ldy #$01 + jsr compare ; and T00,S06,$83 == + !byte $A9 + bcs ap3w + ldx #$85 + ldy #$02 + jsr compare ; and T00,S06,$85 == + !byte $20,$D5 + bcs ap3w + ldx #$84 + ldy #$01 + jsr compare ; and T00,S06,$84 != + !byte $96 + bcc ap3w + ldy #$01 + jsr modify ; then set T00,S06,$84 = + !byte $96 +ap3w + +;------------------------------- +; RWTS fixup #AE1W +; address epilogue byte 1 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ae1w + lda #$06 + ldx #$AD + ldy #$01 + jsr compare ; and T00,S06,$AD == + !byte $A9 + bcs ae1w + ldx #$AF + ldy #$02 + jsr compare ; and T00,S06,$AF == + !byte $20,$D5 + bcs ae1w + ldx #$AE + ldy #$01 + jsr compare ; and T00,S06,$AE != + !byte $DE + bcc ae1w + ldy #$01 + jsr modify ; then set T00,S06,$AE = + !byte $DE +ae1w + +;------------------------------- +; RWTS fixup #AE2W +; address epilogue byte 2 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ae2w + lda #$06 + ldx #$B2 + ldy #$01 + jsr compare ; and T00,S06,$B2 == + !byte $A9 + bcs ae2w + ldx #$B4 + ldy #$02 + jsr compare ; and T00,S06,$B4 == + !byte $20,$D5 + bcs ae2w + ldx #$B3 + ldy #$01 + jsr compare ; and T00,S06,$B3 != + !byte $AA + bcc ae2w + ldy #$01 + jsr modify ; then set T00,S06,$B3 = + !byte $AA +ae2w + +;------------------------------- +; RWTS fixup #AE3W +; address epilogue byte 3 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne ae3w + lda #$06 + ldx #$B7 + ldy #$01 + jsr compare ; and T00,S06,$B7 == + !byte $A9 + bcs ae3w + ldx #$B9 + ldy #$02 + jsr compare ; and T00,S06,$B9 == + !byte $20,$D5 + bcs ae3w + ldx #$B8 + ldy #$01 + jsr compare ; and T00,S06,$B8 != + !byte $EB + bcc ae3w + ldy #$01 + jsr modify ; then set T00,S06,$B8 = + !byte $EB +ae3w + +;------------------------------- +; RWTS fixup #DP1W +; data prologue byte 1 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne dp1w + lda #$02 + ldx #$52 + ldy #$01 + jsr compare ; and T00,S02,$52 == + !byte $A9 + bcs dp1w + ldx #$54 + ldy #$02 + jsr compare ; and T00,S02,$54 == + !byte $20,$B8 + bcs dp1w + ldx #$53 + ldy #$01 + jsr compare ; and T00,S02,$53 != + !byte $D5 + bcc dp1w + ldy #$01 + jsr modify ; then set T00,S02,$53 = + !byte $D5 +dp1w + +;------------------------------- +; RWTS fixup #DP2W +; data prologue byte 2 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne dp2w + lda #$02 + ldx #$57 + ldy #$01 + jsr compare ; and T00,S02,$57 == + !byte $A9 + bcs dp2w + ldx #$59 + ldy #$02 + jsr compare ; and T00,S02,$59 == + !byte $20,$B8 + bcs dp2w + ldx #$58 + ldy #$01 + jsr compare ; and T00,S02,$58 == + !byte $AA + bcc dp2w + ldy #$01 + jsr modify ; then set T00,S02,$58 = + !byte $AA +dp2w + +;------------------------------- +; RWTS fixup #DP3W +; data prologue byte 3 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne dp3w + lda #$02 + ldx #$5C + ldy #$01 + jsr compare ; and T00,S02,$5C == + !byte $A9 + bcs dp3w + ldx #$5E + ldy #$02 + jsr compare ; and T00,S02,$5E == + !byte $20,$B8 + bcs dp3w + ldx #$5D + ldy #$01 + jsr compare ; and T00,S02,$5D != + !byte $AD + bcc dp3w + ldy #$01 + jsr modify ; then set T00,S02,$5D = + !byte $AD +dp3w + +;------------------------------- +; RWTS fixup #DE1W +; data epilogue byte 1 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne de1w + lda #$02 + ldx #$9D + ldy #$01 + jsr compare ; and T00,S02,$9D == + !byte $A9 + bcs de1w + ldx #$9F + ldy #$02 + jsr compare ; and T00,S02,$9F == + !byte $20,$B8 + bcs de1w + ldx #$9E + ldy #$01 + jsr compare ; and T00,S02,$9E != + !byte $DE + bcc de1w + ldy #$01 + jsr modify ; then set T00,S02,$9E = + !byte $DE + +de1w + +;------------------------------- +; RWTS fixup #DE2W +; data epilogue byte 2 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne de2w + lda #$02 + ldx #$A2 + ldy #$01 + jsr compare ; and T00,S02,$A2 == + !byte $A9 + bcs de2w + ldx #$A4 + ldy #$02 + jsr compare ; and T00,S02,$A4 == + !byte $20,$B8 + bcs de2w + ldx #$A3 + ldy #$01 + jsr compare ; and T00,S02,$A3 != + !byte $AA + bcc de2w + ldy #$01 + jsr modify ; then set T00,S02,$A3 = + !byte $AA + +de2w + +;------------------------------- +; RWTS fixup #DE3W +; data epilogue byte 3 (write) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne de3w + lda #$02 + ldx #$A7 + ldy #$01 + jsr compare ; and T00,S02,$A7 == + !byte $A9 + bcs de3w + ldx #$A9 + ldy #$02 + jsr compare ; and T00,S02,$A9 == + !byte $20,$B8 + bcs de3w + ldx #$A8 + ldy #$01 + jsr compare ; and T00,S02,$A8 != + !byte $EB + bcc de3w + ldy #$01 + jsr modify ; then set T00,S02,$A8 = + !byte $EB +de3w + +;------------------------------- +; RWTS fixup #DE4W +; data epilogue byte 4 (write) +; needed by some Sunburst disks +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne de4w + lda #$02 + ldx #$AC + ldy #$01 + jsr compare ; and T00,S02,$AC == + !byte $A9 + bcs de4w + ldx #$AE + ldy #$02 + jsr compare ; and T00,S02,$AE == + !byte $20,$B8 + bcs de4w + ldx #$AD + ldy #$01 + jsr compare ; and T00,S02,$AD != + !byte $FF + bcc de4w + ldy #$01 + jsr modify ; then set T00,S02,$AD = + !byte $FF +de4w + +;------------------------------- +; RWTS "LSR $6A" identification +; disk allows either $D4 or $D5 for the +; first address prologue nibble +; (no patches required, but we want to +; log it) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne rwts_lsr6a + lda #$03 + ldx #$4F + ldy #$0A + jsr compare ; and T00,S03,$4F == + !byte $BD,$8C,$C0,$10,$FB,$4A,$97,$6A,$D0,$EF + bcs rwts_lsr6a + lda #s_lsr6a + jsr PrintByID + inc gPatchCount +rwts_lsr6a + +;------------------------------- +; RWTS "CMP #$08 / BCS" identification +; disk allows either $DE or a timing bit +; for the first address epilogue nibble +; (no patches required, but we want to +; log it) +;------------------------------- + lda gIsRWTS ; if DOS 3.3 RWTS + bne rwts_bcs08 + lda #$03 + ldx #$8B + ldy #$15 + jsr compare ; and T00,S03,$8B == + !byte $BD,$8C,$C0,$10,$FB,$C9,$DE,$F0,$0A,$48,$68,$BD,$8C,$C0,$C9,08,$B0,$A5,$EA,$18,$60 + bcs rwts_bcs08 + lda #s_bcs08 + jsr PrintByID + inc gPatchCount +rwts_bcs08 diff --git a/src/patchers/rwtsswap.a b/src/patchers/rwtsswap.a new file mode 100755 index 0000000..a44af72 --- /dev/null +++ b/src/patchers/rwtsswap.a @@ -0,0 +1,38 @@ +;------------------------------- +; #RWTSSWAP +; after DOS loads, program calls +; subroutines at $BA69 and $BA7F +; to swap RWTS parameters on the +; fly +; e.g. Puzzle Master +;------------------------------- +_rwtsswap + lda gIsBoot0 ; if DOS 3.3 boot0 loader + bne rwtsswap_exit + lda gIsBoot1 ; and DOS 3.3 boot1 loader + bne rwtsswap_exit + lda #$04 + ldx #$69 + ldy #$0B + jsr compare ; and T00,S04,$69 == + !byte $A0,07,$B9,$DF,$BC,$99,$94,$B9 + !byte $88,$10,$F7 + bcs rwtsswap_exit + lda #$04 + ldx #$7F + ldy #$0B + jsr compare ; and T00,S04,$7F == + !byte $A0,07,$B9,$E7,$BC,$99,$94,$B9 + !byte $88,$10,$F7 + bcs rwtsswap_exit + lda #$04 + ldx #$69 + ldy #$01 + jsr modify ; then set T00,S04,$69 = + !byte $60 + lda #$04 + ldx #$7F + ldy #$01 + jsr modify ; and set T00,S04,$7F = + !byte $60 +rwtsswap_exit diff --git a/src/patchers/rwtsswap2.a b/src/patchers/rwtsswap2.a new file mode 100755 index 0000000..5032617 --- /dev/null +++ b/src/patchers/rwtsswap2.a @@ -0,0 +1,38 @@ +;------------------------------- +; #RWTSSWAP2 +; after DOS loads, program calls +; subroutines at $BA69 and $BA7D +; to swap RWTS parameters on the +; fly +; e.g. Mask Parade +;------------------------------- +_rwtsswap2 + lda gIsBoot0 ; if DOS 3.3 boot0 loader + bne rwtsswap2_exit + lda #$04 + ldx #$69 + ldy #$13 + jsr compare ; and T00,S04,$69 == + !byte $A9,$AB,$8D,$4B,$B8,$A9,$FF,$20 + !byte $DF,$BC,$20,$EC,$BC,$A9,$AA,$8D + !byte $29,$BA,$60 + bcs rwtsswap2_exit + lda #$04 + ldx #$7D + ldy #$15 + jsr compare ; and T00,S04,$7D == + !byte $A9,$FF,$8D,$4B,$B8,$A9,$DE,$20 + !byte $DF,$BC,$A9,$AA,$20,$EC,$BC,$A9 + !byte $96,$8D,$29,$BA,$60 + bcs rwtsswap2_exit + lda #$04 + ldx #$69 + ldy #$01 + jsr modify ; then set T00,S04,$69 = + !byte $60 + lda #$04 + ldx #$7D + ldy #$01 + jsr modify ; and set T00,S04,$7D = + !byte $60 +rwtsswap2_exit diff --git a/src/patchers/rwtsswapmecc.a b/src/patchers/rwtsswapmecc.a new file mode 100755 index 0000000..7f61319 --- /dev/null +++ b/src/patchers/rwtsswapmecc.a @@ -0,0 +1,17 @@ +;------------------------------- +; #RWTSSWAPMECC +; post-boot RWTS swapper in MECC +; disks +;------------------------------- +_rwtsswapmecc + ldy #$11 + jsr SearchTrack + !byte $0A,$18,$69,$FF,$A8,$8D,$8B,$C0 + !byte $8D,$8B,$C0,$B9,$97,$97,$8D,$AC + !byte $D5 + bcs rwtsswapmecc_exit + sta gDisplayBytes + ldy #$03 + jsr modify + !byte $A9,00,$24 +rwtsswapmecc_exit diff --git a/src/patchers/sierra.a b/src/patchers/sierra.a new file mode 100755 index 0000000..f00e797 --- /dev/null +++ b/src/patchers/sierra.a @@ -0,0 +1 @@ + 獪 ፪ 卪 卪 卪፠ᠣƍᠺ򫱍ᠣƠ 占占ؠŰ㠺򍺰ᠺ򫱍占ؠư㠺򍺱ᠺ򫱍占ؠIJ㠺ᠺ򫱍占ؠIJ㠺򍺲ᠺ򫱍㍠㠣ōᠺ᫲ᠺ⫲፠ᠤư 卺⍠ư 占ᠺ򫱍ᠣ፠čᠺ򫱍ؠč㠺򫱍頺 \ No newline at end of file diff --git a/src/patchers/sunburst.a b/src/patchers/sunburst.a new file mode 100755 index 0000000..0d0dc24 --- /dev/null +++ b/src/patchers/sunburst.a @@ -0,0 +1,71 @@ +;------------------------------- +; #SUNBURST +; RWTS with track-based address +; and data prologue modifications +; e.g. The Incredible Laboratory +; NOTE: must be run before RWTS +; patchers due to overlapping bytes +;------------------------------- +_sunburst + sec + lda gIsRWTS ; if DOS 3.3 RWTS + bne sunburst_exit + lda #$03 + ldx #$40 + ldy #$01 + jsr compare ; and T00,S03,$40 == + !byte $D0 + bcs sunburst_exit + lda #$03 + ldx #$9C + ldy #$01 + jsr compare ; and T00,S03,$9C == + !byte $F0 + bcs sunburst_exit + lda #$04 + ldx #$69 + ldy #$2C + jsr compare ; and T00,S04,$69 == + !byte $48,$A5,$2A,$4A,$A8,$B9,$29,$BA + !byte $8D,$6A,$B9,$8D,$84,$BC,$B9,$34 + !byte $BA,$8D,$FC,$B8,$8D,$5D,$B8,$C0 + !byte $11,$D0,03,$A9,02,$AC,$A9,$0E + !byte $8D,$C0,$BF,$68,$69,00,$48,$AD + !byte $78,04,$90,$2B + bcs sunburst_exit + lda #$06 + ldx #$69 + ldy #$06 + jsr compare ; and T00,S06,$69 == + !byte $4C,$B8,$B6,$EA,$EA,$EA + bcs sunburst_exit + lda #$08 + ldx #$8C + ldy #$02 + jsr compare ; and T00,S08,$8C == + !byte $69,$BA + bcc sunburst_yes +sunburst_exit + bcs sunburst_exit2 +sunburst_yes + lda #$03 + ldx #$40 + ldy #$01 + jsr modify ; then set T00,S03,$40 = + !byte $F0 + lda #$03 + ldx #$9C + ldy #$01 + jsr modify ; and set T00,S03,$9C = + !byte $D0 + lda #$06 + ldx #$69 + ldy #$06 + jsr modify ; and set T00,S06,$69 = + !byte $20,$C3,$BC,$20,$C3,$BC + lda #$08 + ldx #$8C + ldy #$02 + jsr modify ; and set T00,S08,$8C = + !byte $A0,$B9 +sunburst_exit2 diff --git a/src/patchers/thunder.a b/src/patchers/thunder.a new file mode 100755 index 0000000..59c34d2 --- /dev/null +++ b/src/patchers/thunder.a @@ -0,0 +1,57 @@ +;------------------------------- +; #THUNDER +; boot1 jumps to $B3C1 to change RWTS, +; epilogue checker jumps to $B6B3 to +; check timing bits, late DOS routes +; through nibble check at $B74B +; e.g. Thunder Mountain versions of +; Dig Dug, Pac-Man, Galaxian +;------------------------------- +_thunder + lda gIsBoot0 ; if DOS 3.3 boot0 loader + bne thunder_no + lda gIsBoot1 ; and DOS 3.3 boot1 loader + bne thunder_no + lda #$03 + ldx #$3E + ldy #$04 + jsr compare ; and T00,S03,$3E == + !byte $4C,$B3,$B6,$EA + bcc + +thunder_no + jmp thunder_exit ++ + lda #$01 + ldx #$47 + ldy #$4C + jsr compare ; and T00,S01,$47 == + !byte $4C + !byte $C1,$B3,$60,$48,$A9,02,$8D,$EC + !byte $B7,$A9,00,$8D,$EB,$B7,$8D,$F2 + !byte $B7,$A9,05,$8D,$ED,$B7,$A9,$36 + !byte $8D,$F0,$B7,$A9,$B4,$8D,$F1,$B7 + !byte $A9,01,$8D,$E1,$B7,$8D,$F4,$B7 + !byte $20,$93,$B7,$90,09,$4C,$62,$FA + !byte $EA,$EA,$EA,$EA,$EA,$EA,$20,$36 + !byte $B4,$68,$F0,03,$6C,$72,$AA,$6C + !byte $58,$9D,00,$A9,00,$F0,$BC,$A9 + !byte 01,$D0,$B8 + bcs thunder_exit + lda #s_thunder + jsr PrintByID + lda #$01 + ldx #$48 + ldy #$02 + jsr modify ; then set T00,S01,$48 = + !byte $1F,$B4 + lda #$01 + ldx #$7E + ldy #$01 + jsr modify ; and set T00,S01,$7E = + !byte $2C + lda #$03 + ldx #$3E + ldy #$04 + jsr modify ; and set T00,S03,$3E = + !byte $C9,$AA,$F0,$5C +thunder_exit diff --git a/src/patchers/universale7.a b/src/patchers/universale7.a new file mode 100755 index 0000000..25d84b4 --- /dev/null +++ b/src/patchers/universale7.a @@ -0,0 +1,67 @@ +;------------------------------- +; #UNIVERSALE7 +; replace remnants of E7 bitstream +; with a compatible BYTEstream that +; fools most E7 protection checks +; (invented by qkumba, see PoC||GTFO 0x11 +; and 4am crack no. 655 Rocky's Boots 4.0) +;------------------------------- +_universale7 + lda #$0F + sta sector+1 +sector lda #$FF ; modified at runtime + ldx #$A0 + ldy #$60 + jsr compare + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + !byte $AC,00,$AC,00,$AC,00,$AC,00 + bcc + + jmp e7nextsector ++ + lda sector+1 + ldx #$00 + ldy #$80 + jsr compare + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + bcc + + jmp e7nextsector ++ + lda sector+1 + sta gDisplayBytes + lda #s_e7 + jsr PrintByID + lda sector+1 + ldx #$A3 + ldy #$0C + jsr modify + !byte $64,$B4,$44,$80,$2C,$DC,$18,$B4,$44,$80,$44,$B4 +e7nextsector + dec sector+1 + bmi universale7_exit + jmp sector +universale7_exit diff --git a/src/prefs.a b/src/prefs.a new file mode 100755 index 0000000..1daa2ae --- /dev/null +++ b/src/prefs.a @@ -0,0 +1,115 @@ +CURRENTVER = $30 ; ASCII "0" +DEFSLOT = $36 ; ASCII "6" +DEFDRIVE = $32 ; ASCII "2" + +PREFSFILE !byte prefs_e-prefs_b +prefs_b + !text "PASSPORT.CONF" +prefs_e +PREFSBUFFER = $B000 +PREFSREADLEN = $0003 + +PREFSVER !byte $FF +SLOT !byte $FF +DRIVE !byte $FF + !byte $8D + !ct "lcase.ct" + !text "|||",$8D + !text "||+---WRITE DRIVE (1-2)",$8D + !text "|+---WRITE SLOT (1-7)",$8D + !text "+---PREFS VERSION (DO NOT CHANGE)",$8D +PREFSWRITELEN = *-PREFSVER + +;------------------------------- +; LoadPrefs +; load preferences from file +; +; in: ProDOS must be in memory +;------------------------------- +LoadPrefs + lda #$FF + sta PREFSVER + jsr LoadFile1Shot + !word PREFSFILE + !word PREFSVER + !word PREFSREADLEN + !word PREFSBUFFER + jmp ValidatePrefs + +;------------------------------- +; SavePrefs +; save preferences to file +; +; in: ProDOS must be in memory +;------------------------------- +SavePrefs + jsr ValidatePrefs + jsr SaveFile1Shot + !word PREFSFILE + !byte 04 ; text file + !byte 00,00 ; no aux file type + !word PREFSVER + !word PREFSWRITELEN + !word PREFSBUFFER + rts + +;------------------------------- +; ValidatePrefs +; Sanity-check preferences and reset to +; default values for any variables that +; are out of range. +; If the first value (PREFSVER) is +; not recognized, all other values are +; reset to defaults. +; +; in: none +; out: C set if any prefs were changed +; C clear if all prefs were valid +; A,X clobbered +;------------------------------- +ValidatePrefs + ldx #$00 + lda PREFSVER + cmp #CURRENTVER + beq checkslot + lda #CURRENTVER + sta PREFSVER + lda #$FF + sta SLOT + sta DRIVE + inx +checkslot + lda SLOT + sec + sbc #$30 + beq badslot + cmp #$08 + bcc checkdrive +badslot + lda #DEFSLOT + sta SLOT + inx +checkdrive + lda DRIVE + sec + sbc #$30 + beq baddrive + cmp #$03 + bcc checks6d1 +baddrive + lda #DEFDRIVE + sta DRIVE + inx +checks6d1 + lda SLOT + cmp #$36 + bne prefs_done + lda DRIVE + cmp #$31 + bne prefs_done + lda #$32 + sta DRIVE + inx +prefs_done + cpx #$01 ; set carry if anything changed + rts diff --git a/src/print.a b/src/print.a new file mode 100755 index 0000000..e6c66dc --- /dev/null +++ b/src/print.a @@ -0,0 +1,175 @@ +kForceLower !byte $FF ; AND mask for lowercase letters + ; (set at program startup) +gDisplayBytes !fill 10 ; array of ten bytes for use as + ; substitution strings + +;------------------------------- +; PrintByID +; Print a string from the string table; +; handles string substitutions and +; auto-uppercases on older machines +; in A = string ID +; out C clear if string was printed +; C set if string ID was invalid +; all other flags clobbered +; X register preserved, others clobbered +;------------------------------- +PrintByID + stx x + ldy #0 ; substitution mode flag + cmp #STRINGCOUNT + bcs error + asl + tax + lda StringTable,x + sta print+1 + lda StringTable+1,x + sta print+2 +print + lda $FFFF ; modified at runtime + beq print_done + cpy #0 ; are we in substitution mode? + beq nosub ; no -> branch + ldy #0 + cmp #"t" ; "%t" = current track + bne sub1 + lda gTrack + bpl printbyte ; unconditional branch +sub1 + cmp #"s" ; "%s" = current sector + bne sub2 + lda gSector + bpl printbyte ; unconditional branch +sub2 + cmp #"S" ; write slot + bne sub3 + lda SLOT + bne printsd ; unconditional branch +sub3 + cmp #"D" ; write drive + bne sub4 + lda DRIVE +printsd + ora #$80 + jsr PrintA + bvc next ; unconditional branch +sub4 + cmp #"0" ; "%0" through "%9" + bcc nosub + cmp #":" + bcs nosub + sec + sbc #"0" + tax + lda gDisplayBytes,x +printbyte + jsr PrintByte + bvc next ; unconditional branch +nosub + cmp #"%" + bne stillnosub + iny ; switch to substitution mode + bne next ; (next character will be interpreted) +stillnosub + cmp #$E1 + bcc noforce + and kForceLower +noforce + jsr COUT +next + inc print+1 + bne print + inc print+2 + bne print +print_done + clc +error + ldx x + rts +x !byte 00 + +;------------------------------- +; PrintByte +; print a hexadecimal byte +; in A contains byte to print +; out all registers preserved +; all flags clobbered +; @tmpa clobbered +; @tmpx clobbered +; @tmpy clobbered +;------------------------------- +PrintByte + sta tmpa + stx tmpx + sty tmpy + jsr PRBYTE + lda tmpa + ldx tmpx + ldy tmpy + clv + rts + +;------------------------------- +; PrintA +; print a single character through COUT +; in A contains character to print +; out all registers preserved +; all flags clobbered +; @tmpa clobbered +; @tmpx clobbered +; @tmpy clobbered +;------------------------------- +PrintA + sta tmpa + stx tmpx + sty tmpy + jsr COUT + lda tmpa + ldx tmpx + ldy tmpy + clv + rts + +;------------------------------- +; ClearScreen +;------------------------------- +ClearScreen + jsr TEXT + lda $C061 + bpl home + lda $C062 + bpl home +begin + ldx #$04 + stx counter + stx loop+2 + stx change+2 + ldy #$00 + sty flag +loop + lda $FF00,y ; modified at runtime + cmp #$A0 + beq nochange + bcs down + clc + adc #$01 + bne change +down + sec + sbc #$01 +change + sta $FF00,y ; modified at runtime + sta flag +nochange + iny + bne loop + inc loop+2 + inc change+2 + dec counter + bne loop + lda #$01 + jsr WAIT + lda flag + bne begin +home + jmp HOME diff --git a/src/rwts.a b/src/rwts.a new file mode 100755 index 0000000..30d541a --- /dev/null +++ b/src/rwts.a @@ -0,0 +1,66 @@ +;------------------------------- +; ReadSector +; high-level function to read a single sector. +; in: gIsProtDOS is TRUE or FALSE +; if gProtDOS is FALSE, callrwts+2 has been set to +; the RWTS entry point (e.g. $BD or $3D or $FD) +; if RWTS is in LC RAM, the appropriate RAM bank +; has already been selected for read/write access +; out: all registers clobbered +; C clear if read was successful +; C set if read failed +;------------------------------- +ReadSector + lda #$AA ; lots of custom RWTS routines + sta $31 ; need these zero page locations + lda #$AD ; set to magic values + sta $4E + + lda gIsProtDOS + beq _protread + + ldy #gRWTSParams +callrwts jsr $FF00 ; modified at runtime (see Inspect1) + rts + +; +; "Protected.DOS" has enough differences that we just +; split everything out here. The hi/lo RWTS parameter +; table address is set in A/Y instead of Y/A. The +; RWTS entry point is $BA00. The third data prologue +; nibble is stored in zp$4E and varies based on track +; and sector. +; +_protread + lda gTrack ; T02,S05+ use "protected" mode + cmp #$03 ; (altered data prologue and + bcs protected ; nibble translate table) + cmp #$02 ; T00,S00 - T02,S04 use + bcc standard ; "standard" mode + lda gSector + cmp #$05 + bcs protected +standard + lda #$9B + sta $BF2C + bne go ; unconditional branch +protected + lda #$B5 + sta $4E + lda #$D5 + sta $BF2C ; execution falls through here +go + lda #gRWTSParams + jsr $BA00 ; note non-standard entry point + rts + +gRWTSParams ; used to read each sector + !byte 01,$60,01,00 +gTrack !byte 00 +gSector !byte 00 + !word dct +gAddress !word $1F00 + !byte 00,00,01,00,$FE,$60,01,00,00 +dct !byte 00,01,$EF,$D8,00 diff --git a/src/sectormap.a b/src/sectormap.a new file mode 100755 index 0000000..0eede1f --- /dev/null +++ b/src/sectormap.a @@ -0,0 +1,78 @@ +InitSectorMap + lda #sectormap + sta B+2 + lda #$FF + ldx #$22 +A ldy #$0F +B sta $FFFF + inc B+1 + bne + + inc B+2 ++ dey + bpl B + dex + bpl A + rts + +;------------------------------- +; This is a map of how much we care about each sector +; on the disk. Each byte is one sector, arranged in +; increasing logical sector order from T00,S00 to T22,S0F. +; Some sectors have their own individual labels just for +; convenience. +; e.g. LDA #$80 +; STA T00S0A +; will mark T00,S0A as optional +; +; Possible values for each sector: +; 00 = ignore this sector (don't even read it) +; 80 = sector is optional -- read, but ignore any errors +; FE = sector is required, and switch to the built-in RWTS +; after reading it (if we haven't already) +; $FF = sector is required -- read, and any error is fatal +; (this is the default value for all sectors) +;------------------------------- +sectormap +T00 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T00S09 !byte $FF +T00S0A !byte $FF + !byte $FF,$FF,$FF,$FF,$FF +T01 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T01S0F !byte $FF +T02 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T03 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T04 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T05 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T06 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T07 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T08 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T09 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T0A !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T0B !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T0C !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T0D !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T0E !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T0F !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T10 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T11 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T11S0F !byte $FF +T12 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T13 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T14 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T15 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T16 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T17 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T18 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T19 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T1A !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T1B !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T1C !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T1D !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T1E !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T1F !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T20 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T21 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T22 !byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF +T22S0F !byte $FF diff --git a/src/slots.a b/src/slots.a new file mode 100755 index 0000000..711b627 --- /dev/null +++ b/src/slots.a @@ -0,0 +1,74 @@ +DiskIIArray + !byte 00,00,00,00,00,00,00 + +;------------------------------- +; ScanForDiskII +; scan all slots for things that +; look like Disk II cards +; +; out: all registers clobbered +; all flags clobbered +; DiskIIArray filled with 00 or FF +;------------------------------- +ScanForDiskII + lda #$00 + sta cmp1 + ldx #$07 +fingerprint + txa + ora #$C0 + sta cmp1+1 + ldy #$01 + lda (cmp1),y + cmp #$20 + bne slots_next + ldy #$03 + lda (cmp1),y + bne slots_next + ldy #$05 + lda (cmp1),y + cmp #$03 + bne slots_next + ldy #$FF + lda (cmp1),y + bne slots_next + tya + sta DiskIIArray-1,x +slots_next + dex + bne fingerprint + rts + +;------------------------------- +; NextSlot +;------------------------------- +NextSlot + lda DRIVE + cmp #$31 + bne incslot + lda #$32 + sta DRIVE + bne slots_done ; unconditional branch +incslot + lda #$31 + sta DRIVE + inc SLOT + lda SLOT + cmp #$38 + bne nowrap + lda #$31 + sta SLOT +nowrap + sec + sbc #$30 + tax + lda DiskIIArray-1,x + beq incslot +slots_done + lda SLOT + cmp #$36 + bne reallydone + lda #$32 + sta DRIVE +reallydone + rts diff --git a/src/strings/en.a b/src/strings/en.a new file mode 100755 index 0000000..f7b59c8 --- /dev/null +++ b/src/strings/en.a @@ -0,0 +1,394 @@ +; +; Main menu keys +; (should match the text in mainmenu below) +; (these are NOT case-sensitive) +; +!ct "lcase.ct" +k_verify = "V" +k_demuffin = "D" +k_crack = "C" +k_slot = "S" +k_quit = "Q" +; will also quit + +; +; String IDs +; (pass in accumulator to PrintByID) +; +s_header = $00 +s_mainmenu = $01 +s_progbar = $02 +s_reading = $03 +s_diskrwts = $04 +s_bb00 = $05 +s_sunburst = $06 +s_optimum = $07 +s_builtin = $08 +s_switch = $09 +s_writing = $0A +s_unformat = $0B +s_f7 = $0C +s_sync = $0D +s_optbad = $0E +s_pass = $0F +s_passdemuf = $10 +s_passcrack = $11 +s_passcrack0 = $12 +s_fail = $13 +s_fatal0000 = $14 +s_fatal220f = $15 +s_done = $16 +s_noslot6 = $17 +s_writeerr = $18 +s_writeioerr = $19 +s_writenodev = $1A +s_writeprot = $1B +s_othermli = $1C +s_canttrace = $1D +s_canceled = $1E +s_bademu = $1F +s_reset = $20 +s_modify = $21 +s_modifyto = $22 +s_dosb0 = $23 +s_prodosb0 = $24 +s_pascalb0 = $25 +s_meccb0 = $26 +s_sierra = $27 +s_a6bc95 = $28 +s_jmpbcf0 = $29 +s_rol1e = $2A +s_runhello = $2B +s_e7 = $2C +s_jmpb4bb = $2D +s_jmpb400 = $2E +s_jmpbeca = $2F +s_jsrbb03 = $30 +s_thunder = $31 +s_jmpae8e = $32 +s_diskvol = $33 +s_d5d5f7 = $34 +s_meccm7 = $35 +s_datasoftb0 = $36 +s_datasoft = $37 +s_lsr6a = $38 +s_bcs08 = $39 +s_jmpb660 = $3A +s_protdos = $3B +s_protdosw = $3C +s_protserial = $3D +s_fbff = $3E +s_encoded44 = $3F +s_encoded53 = $40 +s_specdel = $41 +STRINGCOUNT = $42 + +StringTable + !word header + !word mainmenu + !word progbar + !word reading + !word diskrwts + !word bb00 + !word sunburst + !word optimum + !word builtin + !word switch + !word writing + !word unformat + !word f7 + !word sync + !word optbad + !word passver + !word passdemuf + !word passcrack + !word passcrack0 + !word fail + !word fatal0000 + !word fatal220f + !word done + !word noslot6 + !word writeerr + !word writeioerr + !word writenodev + !word writeprot + !word othermli + !word canttrace + !word canceled + !word bademu + !word reset + !word smodify + !word modifyto + !word dosboot0 + !word prodosboot0 + !word pascalboot0 + !word meccboot0 + !word sierra + !word a6bc95 + !word jmpbcf0 + !word rol1e + !word runhello + !word e7 + !word jmpb4bb + !word jmpb400 + !word jmpbeca + !word jsrbb03 + !word thunder + !word jmpae8e + !word diskvol + !word d5d5f7 + !word meccm7 + !word datasoftb0 + !word datasoft + !word lsr6a + !word bcs08 + !word jmpb660 + !word protdos + !word protdosw + !word protserial + !word fbff + !word encoded44 + !word encoded53 + !word specdel +; +; Text can contain substitution strings, which +; are replaced by current values at runtime. Each +; substitution string is two bytes long. The first +; byte is always "%", which puts the print routine +; into substitution mode. The next byte controls +; which value is printed (see list below), then +; substitution mode ends automatically. Unknown +; substitution strings are silently ignored and +; produce no output. +; +; Substitution strings are case-sensitive. +; +; Supported substitution strings +; %S destination (write) slot +; %D destination (write) drive +; %t current track (during read and patch) +; %s current sector (during read) +; +; In addition, it supports "%0" through "%9" +; for printing arbitrary hexadecimal values. +; These are stored in the gDisplayBytes array and +; can be set directly before calling PrintByID. +; +header + !text "Passport by 4am 20161230-en",00 +mainmenu + !text "________________________________________",$8D,$8D,$8D,$8D,$8D,$8D,$8D + !text " " + !scrxor $40, "V" + !text "erify disk",$8D,$8D + !text " " + !scrxor $40, "D" + !text "emuffin disk",$8D,$8D + !text " " + !scrxor $40, "C" + !text "rack disk",$8D,$8D + !text " " + !scrxor $40, "Q" + !text "uit",$8D,$8D,$8D,$8D,$8D,$8D,$8D + !text "source: S6,D1 target: " + !scrxor $40, "S" + !text "%S,D%D",00 +progbar + !byte $8D + !text " ______________________________________",$8D + !text " " + !scrxor $00, " " + !text "____________________________________" + !scrxor $00, " ",$8D,$8D,$8D,00 +reading + !text "Reading from S6,D1",$8D,00 +diskrwts + !text "Using disk's own RWTS",$8D,00 +bb00 + !text "T00,S05 Found $BB00 protection check",$8D + !text "T00,S0A might be unreadable",$8D,00 +sunburst + !text "T00,S04 Found Sunburst disk",$8D + !text "T11,S0F might be unreadable",$8D,00 +optimum + !text "T00,S00 Found Optimum Resource disk",$8D + !text "T01,S0F might be unreadable",$8D,00 +builtin + !text "Using built-in RWTS",$8D,00 +switch + !text "Switching to built-in RWTS",$8D,00 +writing + !text "Writing to S%S,D%D",$8D,00 +unformat + !text "T%t is unformatted",$8D,00 +f7 + !text "T%t Found $F7F6EFEEAB protection",$8D,00 +sync + !text "T%t Found nibble count protection",$8D,00 +optbad + !text "T%t,S%s is unreadable (ignoring)",$8D,00 +passver + !text "Verification complete. The disk is good.",00 +passdemuf + !text "Demuffin complete.",$8D,00 +passcrack + !text "Crack complete.",$8D,00 +passcrack0 + !byte $8D + !text "The disk was copied successfully, but",$8D + !text "Passport did not apply any patches.",$8D,$8D + !text "Possible reasons:",$8D + !text "- The source disk is not copy protected." + !text "- The target disk works without patches." + !text "- The disk uses an unknown protection,",$8D + !text " and Passport can not help any further.",00 +fail + !byte $8D + !text "T%t,S%s Fatal read error",$8D,00 +fatal0000 + !byte $8D + !text "Possible reasons:",$8D + !text "- There is no disk in S6,D1.",$8D + !text "- It is not an Apple ][ disk.",$8D + !text "- The disk is DOS 3.2-only.",$8D + !text "- The disk is unformatted.",$8D,00 +fatal220f + !byte $8D + !text "Passport does not work on this disk.",$8D,$8D + !text "Possible reasons:",$8D + !text "- This is not a 16-sector disk.",$8D + !text "- The disk modifies its RWTS in ways",$8D + !text " that Passport is not able to detect.",$8D,00 +done + !byte $8D + !text "Press any key to continue " + !scrxor $40, " ",00 +noslot6 + !text "Passport requires a Disk II drive in S6.",$8D + !text "Press any key to quit " + !scrxor $40, " ",00 +writeerr + !byte $8D + !text "T%t Fatal write error",$8D,$8D,00 +; +; MLI error $27 +; +writeioerr + !text "Possible reasons:",$8D + !text "- There is no disk in S%S,D%D.",$8D + !text "- The disk has bad sectors.",$8D + !text "- The disk is unformatted.",$8D,$8D,00 +; +; MLI error $28 +; +writenodev + !text "S%S,D%D does not exist.",$8D,00 +; +; MLI error $2B +; +writeprot + !text "The disk in S%S,D%D is write-protected.",$8D,00 +; +; other MLI error +; +othermli + !text "MLI error $%0.",$8D + !text "Please contact the developer.",$8D,00 + +canttrace + !text "Unrecognized drive, tracing is disabled",$8D,00 +canceled + !text "Canceled at your request.",$8D,00 +bademu + !byte 00 +reset + !byte $8D + !text "Press to continue.",$8D,00 +smodify + !text "T%t,S%0,$%1: ",00 +modifyto + !text " -> ",00 +dosboot0 + !text "T00,S00 Found DOS 3.3 bootloader",$8D,00 +prodosboot0 + !text "T00,S00 Found ProDOS bootloader",$8D,00 +pascalboot0 + !text "T00,S00 Found Pascal bootloader",$8D,00 +meccboot0 + !text "T00 Found MECC M8 bootloader",$8D,00 +sierra + !text "T%t,S%0 Found Sierra protection check",$8D,00 +a6bc95 + !text "T%t,S%0 Found A6BC95 protection check",$8D,00 +jmpbcf0 + !text "T00,S03 RWTS requires a timing bit after" + !text "the first data epilogue by jumping to",$8D + !text "$BCF0.",$8D,00 +rol1e + !text "T00,S03 RWTS accumulates timing bits in",$8D + !text "$1E and checks its value later.",$8D,00 +runhello + !text "T%t,S%0 Startup program executes a",$8D + !text "protection check before running the real" + !text "startup program.",$8D,00 +e7 + !text "T%t,S%0 Found E7 bitstream",$8D,00 +jmpb4bb + !text "T00,S0C Disk calls a protection check at" + !text "$B4BB before initializing DOS.",$8D,00 +jmpb400 + !text "T00,S01 Disk calls a protection check at" + !text "$B400 before initializing DOS.",$8D,00 +jmpbeca + !text "T00,S02 RWTS requires extra nibbles and",$8D + !text "timing bits after the data prologue by",$8D + !text "jumping to $BECA.",$8D,00 +jsrbb03 + !text "T00,S05 Found a self-decrypting",$8D + !text "protection check at $BB03.",$8D,00 +thunder + !text "T00,S03 RWTS counts timing bits and",$8D + !text "checks them later.",$8D,00 +jmpae8e + !text "T00,S0D Disk calls a protection check at" + !text "$AE8E after initializing DOS.",$8D,00 +diskvol + !text "T00,S08 RWTS requires a non-standard",$8D + !text "disk volume number.",$8D,00 +d5d5f7 + !text "T%t,S%0 Found D5D5F7 protection check",$8D,00 +meccm7 + !text "T00 Found MECC M7 bootloader",$8D,00 +datasoftb0 + !text "T00,S00 Found Datasoft bootloader",$8D,00 +datasoft + !text "T%t,S%0 Found Datasoft protection check",$8D,00 +lsr6a + !text "T00,S03 RWTS accepts $D4 or $D5 for the",$8D + !text "first address prologue nibble.",$8D,00 +bcs08 + !text "T00,S03 RWTS accepts $DE or a timing bit" + !text "for the first address epilogue nibble.",$8D,00 +jmpb660 + !text "T00,S02 RWTS requires timing bits after",$8D + !text "the data prologue by jumping to $B660.",$8D,00 +protdos + !text "T00,S01 Found encrypted RWTS, key=$%0",$8D,00 +protdosw + !text "T00 Decrypting RWTS before writing",$8D,00 +protserial + !text "T%t,S%3 Erasing serial number %0%1%2",$8D,00 +fbff + !text "T%t,S%0 Found FBFF protection check",$8D,00 +encoded44 + !byte $8D + !text "T00,S00 Fatal error",$8D,$8D + !text "Passport does not work on this disk,",$8D + !text "because it uses a 4-and-4 encoding.",$8D,00 +encoded53 + !byte $8D + !text "T00,S00 Fatal error",$8D,$8D + !text "Passport does not work on this disk,",$8D + !text "because it uses a 5-and-3 encoding.",$8D,00 +specdel + !text "T00,S00 Found DOS 3.3P bootloader",$8D,00 diff --git a/src/strings/fi.a b/src/strings/fi.a new file mode 100755 index 0000000..7d77291 --- /dev/null +++ b/src/strings/fi.a @@ -0,0 +1,349 @@ +* Finnish translation by Jorma Honkanen +* +* Main menu keys +* (should match the text in :mainmenu below) +* (these are NOT case-sensitive) +* +k_verify = "T" +k_demuffin = "M" +k_crack = "P" +k_slot = "S" +k_quit = "L" +* will also quit + +* Verify = T/arkista +* Demuffin = M/uunna levyke +* Crack = P/oista suojaus +* Slot = Liitin, Slot - but not to be changed! +* Quit = L/opeta + +* +* String IDs +* (pass in accumulator to PrintByID) +* +s_header = $00 +s_mainmenu = $01 +s_progbar = $02 +s_reading = $03 +s_diskrwts = $04 +s_bb00 = $05 +s_sunburst = $06 +s_optimum = $07 +s_builtin = $08 +s_switch = $09 +s_writing = $0A +s_unformat = $0B +s_f7 = $0C +s_sync = $0D +s_optbad = $0E +s_pass = $0F +s_passdemuf = $10 +s_passcrack = $11 +s_passcrack0 = $12 +s_fail = $13 +s_fatal0000 = $14 +s_fatal220f = $15 +s_done = $16 +s_noslot6 = $17 +s_writeerr = $18 +s_writeioerr = $19 +s_writenodev = $1A +s_writeprot = $1B +s_othermli = $1C +s_canttrace = $1D +s_canceled = $1E +s_bademu = $1F +s_reset = $20 +s_modify = $21 +s_modifyto = $22 +s_dosb0 = $23 +s_prodosb0 = $24 +s_pascalb0 = $25 +s_meccb0 = $26 +s_sierra = $27 +s_a6bc95 = $28 +s_jmpbcf0 = $29 +s_rol1e = $2A +s_runhello = $2B +s_e7 = $2C +s_jmpb4bb = $2D +s_jmpb400 = $2E +s_jmpbeca = $2F +s_jsrbb03 = $30 +s_thunder = $31 +s_jmpae8e = $32 +s_diskvol = $33 +s_d5d5f7 = $34 +s_meccm7 = $35 +STRINGCOUNT = $36 + +StringTable + da :header + da :mainmenu + da :progbar + da :reading + da :diskrwts + da :bb00 + da :sunburst + da :optimum + da :builtin + da :switch + da :writing + da :unformat + da :f7 + da :sync + da :optbad + da :passver + da :passdemuf + da :passcrack + da :passcrack0 + da :fail + da :fatal0000 + da :fatal220f + da :done + da :noslot6 + da :writeerr + da :writeioerr + da :writenodev + da :writeprot + da :othermli + da :canttrace + da :canceled + da :bademu + da :reset + da :modify + da :modifyto + da :dosboot0 + da :prodosboot0 + da :pascalboot0 + da :meccboot0 + da :sierra + da :a6bc95 + da :jmpbcf0 + da :rol1e + da :runhello + da :e7 + da :jmpb4bb + da :jmpb400 + da :jmpbeca + da :jsrbb03 + da :thunder + da :jmpae8e + da :diskvol + da :d5d5f7 + da :meccm7 + +* +* Text can contain substitution strings, which +* are replaced by current values at runtime. Each +* substitution string is two bytes long. The first +* byte is always "%", which puts the print routine +* into substitution mode. The next byte controls +* which value is printed (see list below), then +* substitution mode ends automatically. Unknown +* substitution strings are silently ignored and +* produce no output. +* +* Substitution strings are case-sensitive. +* +* Supported substitution strings: +* %S destination (write) slot +* %D destination (write) drive +* %t current track (during read and patch) +* %s current sector (during read) +* +* In addition, it supports "%0" through "%9" +* for printing arbitrary hexadecimal values. +* These are stored in the gDisplayBytes array and +* can be set directly before calling PrintByID. +* +:header + ASC "Passport / 4am 20160712-fi"00 +:mainmenu + ASC "________________________________________"8D8D8D8D8D8D8D + ASC " " + INV "T" + ASC "arkista levyke"8D8D + ASC " " + INV "M" + ASC "uunna levyke"8D8D + ASC " " + INV "P" + ASC "oista suojaus levykkeelt{"8D8D + ASC " " + INV "L" + ASC "opeta"8D8D8D8D8D8D8D + ASC "alkuper{inen: S6,D1 kohde: " + INV "S" + ASC "%S,D%D"00 +:progbar + HEX 8D + ASC " ______________________________________"8D + ASC " " + INV " " + ASC "____________________________________" + INV " "8D8D8D00 +:reading + ASC "Luetaan S6,D1"8D00 +:diskrwts + ASC "K{ytet{{n levykkeen omaa RWTS:{{"8D00 +:bb00 + ASC "T00,S05 L|ysi $BB00 suojaustarkastuksen"8D + ASC "T00,S0A voi olla lukukelvoton"8D00 +:sunburst + ASC "T00,S04 L|ysi Sunburst levykkeen"8D + ASC "T11,S0F voi olla lukukelvoton"8D00 +:optimum + ASC "T00,S00 L|ysi Optimum Resource levykkeen"8D + ASC "T01,S0F voi olla lukukelvoton"8D00 +:builtin + ASC "K{ytt{{ sis{{nrakennettua RWTS:{{"8D00 +:switch + ASC "Vaihtaa sis{{nrakennettuun RWTS:{{n"8D00 +:writing + ASC "Kirjoittaa S%S,D%D"8D00 +:unformat + ASC "T%t on alustamaton"8D00 +:f7 + ASC "T%t L|ysi $F7F6EFEEAB suojauksen"8D00 +:sync + ASC "T%t L|ysi Nibble Count suojauksen"8D00 +:optbad + ASC "T%t,S%s on lukukelvoton (ei v{litet{)"8D00 +:passver + ASC "Varmistus on valmis. Levyke on luettavissa."00 +:passdemuf + ASC "Siirto valmis."8D00 +:passcrack + ASC "Suojauksen poisto valmis."8D00 +:passcrack0 + HEX 8D + ASC "Levyke kopioitiin onnistuneesti, mutta"8D + ASC "Passport ei lis{nnyt korjauksia."8D8D + ASC "Mahdollisia syit{:"8D + ASC "- Alkuper{inen levyke ei ole kopiosuojattu." + ASC "- Kohdelevyke toimii ilman korjauksia." + ASC "- Levyke k{ytt{{ tuntematonta suojausta,"8D + ASC " ja Passport ei voi auttaa."00 +:fail + HEX 8D + ASC "T%t,S%s Vakava luku virhe"8D00 +:fatal0000 + HEX 8D + ASC "Mahdollisia syit{:"8D + ASC "- Ei levykett{ asemassa S6,D1."8D + ASC "- Levyke ei ole Apple ][ levyke."8D + ASC "- Levyke on DOS 3.2 (13 sektoria)."8D + ASC "- Levyke on alustamaton."8D00 +:fatal220f + HEX 8D + ASC "Passport ei toimi t{m{n levykkeen kanssa."8D8D + ASC "Mahdollisia syit{:"8D + ASC "- Levyke ei ole 16-sektorin levyke."8D + ASC "- Levyke muuntaa RWTS:{{ tavoilla"8D + ASC " joita Passport ei pysty havaitsemaan."8D00 +:done + HEX 8D + ASC "Paina jotain n{pp{int{ jatkaaksesi " + FLS " "00 +:noslot6 + ASC "Passport vaatii Disk II aseman S6."8D + ASC "Paina jotain n{pp{int{ lopettaaksesi " + FLS " "00 +:writeerr + HEX 8D + ASC "T%t Vakava kirjoitus virhe"8D8D00 +* +* MLI error $27 +* +:writeioerr + ASC "Mahdollisia syit{:"8D + ASC "- Ei levykett{ S%S,D%D."8D + ASC "- Levykkeell{ on huonoja sektoreita."8D + ASC "- Levyke on alustamaton."8D8D00 +* +* MLI error $28 +* +:writenodev + ASC "S%S,D%D ei ole olemassa."8D00 +* +* MLI error $2B +* +:writeprot + ASC "Levyke S%S,D%D on kirjoitussuojattu."8D00 +* +* other MLI error +* +:othermli + ASC "MLI virhe $%0."8D + ASC "Ota yhteytt{ ohjelman kehitt{j{{n."8D00 + +:canttrace + ASC "Tunnistamaton asema, j{ljitt{minen on poistettu"8D00 +:canceled + ASC "Keskeytetty pyynn|st{si."8D00 +:bademu + HEX 8D + ASC "VAROITUS! K{yt{t Passport-ohjelmaa"8D + ASC "emulaattorilla joka ei asianmukaisesti"8D + ASC "tue levyke asemia. Passport yritt{{"8D + ASC "kiert{{ t{m{n, mutta jotkut levykkeet"8D + ASC "voivat olla lukukelvottomia."8D8D00 +:reset + HEX 8D + ASC "Paita jatkaaksesi."8D00 +:modify + ASC "T%t,S%0,$%1: "00 +:modifyto + ASC " -> "00 +:dosboot0 + ASC "T00,S00 L|ysi DOS 3.3 k{ynnistyslataajan"8D00 +:prodosboot0 + ASC "T00,S00 L|ysi ProDOS k{ynnistyslataajan"8D00 +:pascalboot0 + ASC "T00,S00 L|ysi Pascal k{ynnistyslataajan"8D00 +:meccboot0 + ASC "T00,S00 L|ysi MECC M8 k{ynnistyslataajan"8D00 +:sierra + ASC "T%t,S%0 L|ysi Sierra suojaustarkastuksen"8D00 +:a6bc95 + ASC "T%t,S%0 L|ysi A6BC95 suojaustarkastuksen"8D00 +:jmpbcf0 + ASC "T00,S03 RWTS vaatii ajoitus bitin ensimm{isen" + ASC "data epilogin j{lkeen hypp{{m{ll{"8D + ASC "$BCF0."8D00 +:rol1e + ASC "T00,S03 RWTS kokoaa ajoitus bittej{"8D + ASC "$1E ja tarkistaa niiden arvot my|hemmin."8D00 +:runhello + ASC "T%t,S%0 Aloitusohjelma ajaa suojaus"8D + ASC "tarkastuksen ennen oikean aloitus ohjeman" + ASC "ajamista."8D00 +:e7 + ASC "T%t,S%0 L|ysi E7 bittivirran"8D00 +:jmpb4bb + ASC "T00,S0C Levyke kutsuu suojaus tarkastusta" + ASC "$B4BB ennen DOS:in alustamista."8D00 +:jmpb400 + ASC "T00,S01 Levyke kutsuu suojaus tarkastusta" + ASC "$B400 ennen DOS:in alustamista."8D00 +:jmpbeca + ASC "T00,S02 RWTS vaatii ylim{{r{isen nibblen ja"8D + ASC "ajoitus bitin ennen data prologia"8D + ASC "hypp{{m{ll{ $BECA."8D00 +:jsrbb03 + ASC "T00,S05 L|ysi itsepurkautuvan"8D + ASC "suojaustarkastuksen $BB03."8D00 +:thunder + ASC "T00,S03 RWTS laskee ajoitus bittej{ ja"8D + ASC "tarkistaa ne my|hemmin."8D00 +:jmpae8e + ASC "T00,S0D Levyke kutsuu suojaus tarkastusta" + ASC "$AE8E DOS:in alustamisen j{lkeen."8D00 +:diskvol + ASC "T00,S08 RWTS vaatii ep{standardin"8D + ASC "levyke numeroinnin."8D00 +:d5d5f7 + ASC "T%t,S%0 L|ysi D5D5F7 suojaustarkastuksen"8D00 +:meccm7 + ASC "T00,S00 L|ysi MECC M7 k{ynnistyslataajan"8D00 diff --git a/src/strings/fr.a b/src/strings/fr.a new file mode 100755 index 0000000..7e3ada8 --- /dev/null +++ b/src/strings/fr.a @@ -0,0 +1,343 @@ +* French translation by Antoine Vignau +* +* Main menu keys +* (should match the text in :mainmenu below) +* (these are NOT case-sensitive) +* +k_verify = "V" +k_demuffin = "D" +k_crack = "C" +k_slot = "S" +k_quit = "Q" +* will also quit + +* +* String IDs +* (pass in accumulator to PrintByID) +* +s_header = $00 +s_mainmenu = $01 +s_progbar = $02 +s_reading = $03 +s_diskrwts = $04 +s_bb00 = $05 +s_sunburst = $06 +s_optimum = $07 +s_builtin = $08 +s_switch = $09 +s_writing = $0A +s_unformat = $0B +s_f7 = $0C +s_sync = $0D +s_optbad = $0E +s_pass = $0F +s_passdemuf = $10 +s_passcrack = $11 +s_passcrack0 = $12 +s_fail = $13 +s_fatal0000 = $14 +s_fatal220f = $15 +s_done = $16 +s_noslot6 = $17 +s_writeerr = $18 +s_writeioerr = $19 +s_writenodev = $1A +s_writeprot = $1B +s_othermli = $1C +s_canttrace = $1D +s_canceled = $1E +s_bademu = $1F +s_reset = $20 +s_modify = $21 +s_modifyto = $22 +s_dosb0 = $23 +s_prodosb0 = $24 +s_pascalb0 = $25 +s_meccb0 = $26 +s_sierra = $27 +s_a6bc95 = $28 +s_jmpbcf0 = $29 +s_rol1e = $2A +s_runhello = $2B +s_e7 = $2C +s_jmpb4bb = $2D +s_jmpb400 = $2E +s_jmpbeca = $2F +s_jsrbb03 = $30 +s_thunder = $31 +s_jmpae8e = $32 +s_diskvol = $33 +s_d5d5f7 = $34 +s_meccm7 = $35 +STRINGCOUNT = $36 + +StringTable + da :header + da :mainmenu + da :progbar + da :reading + da :diskrwts + da :bb00 + da :sunburst + da :optimum + da :builtin + da :switch + da :writing + da :unformat + da :f7 + da :sync + da :optbad + da :passver + da :passdemuf + da :passcrack + da :passcrack0 + da :fail + da :fatal0000 + da :fatal220f + da :done + da :noslot6 + da :writeerr + da :writeioerr + da :writenodev + da :writeprot + da :othermli + da :canttrace + da :canceled + da :bademu + da :reset + da :modify + da :modifyto + da :dosboot0 + da :prodosboot0 + da :pascalboot0 + da :meccboot0 + da :sierra + da :a6bc95 + da :jmpbcf0 + da :rol1e + da :runhello + da :e7 + da :jmpb4bb + da :jmpb400 + da :jmpbeca + da :jsrbb03 + da :thunder + da :jmpae8e + da :diskvol + da :d5d5f7 + da :meccm7 +* +* Text can contain substitution strings, which +* are replaced by current values at runtime. Each +* substitution string is two bytes long. The first +* byte is always "%", which puts the print routine +* into substitution mode. The next byte controls +* which value is printed (see list below), then +* substitution mode ends automatically. Unknown +* substitution strings are silently ignored and +* produce no output. +* +* Substitution strings are case-sensitive. +* +* Supported substitution strings: +* %S destination (write) slot +* %D destination (write) drive +* %t current track +* %s current sector +* +* In addition, it supports "%0" through "%9" +* for printing arbitrary hexadecimal values. +* These are stored in the gDisplayBytes array and +* can be set directly before calling PrintByID. +* +:header + ASC "Passport par 4am 20160712-fr"00 +:mainmenu + ASC "________________________________________"8D8D8D8D8D8D8D + ASC " " + INV "V" + ASC "{rifier"8D8D + ASC " " + INV "D" + ASC "{muffiniser"8D8D + ASC " " + INV "C" + ASC "racker"8D8D + ASC " " + INV "Q" + ASC "uitter"8D8D8D8D8D8D8D + ASC "source: S6,D1 destination: " + INV "S" + ASC "%S,D%D"00 +:progbar + HEX 8D + ASC " ______________________________________"8D + ASC " " + INV " " + ASC "____________________________________" + INV " "8D8D8D00 +:reading + ASC "Lecture depuis S6,D1"8D00 +:diskrwts + ASC "Utilisation de la RWTS de la disquette"8D00 +:bb00 + ASC "V{rif. de protection en $BB00 d{tect{e"8D + ASC "P00,S0A probablement illisible"8D00 +:sunburst + ASC "Disquette Sunburst d{tect{e"8D + ASC "P11,S0F probablement illisible"8D00 +:optimum + ASC "Disquette Optimum Resource d{tect{e"8D + ASC "P01,S0F probablement illisible"8D00 +:builtin + ASC "Utilisation de la RWTS int{gr{e"8D00 +:switch + ASC "Bascule vers la RWTS int{gr{e"8D00 +:writing + ASC "Ecriture vers S%S,D%D"8D00 +:unformat + ASC "P%t non format{e"8D00 +:f7 + ASC "Protection $F7F6EFEEAB d{tect{e P%t"8D00 +:sync + ASC "Protection Nibble count d{tect{e P%t"8D00 +:optbad + ASC "P%t,S%s n'est pas lisible (ignor{)"8D00 +:passver + ASC "V{rif. termin{e. Disquette lisible."8D00 +:passdemuf + ASC "D{muffin termin{."8D00 +:passcrack + ASC "Crack termin{."8D00 +:passcrack0 + HEX 8D + ASC "La disquette a {t{ copi{e avec succ}s"8D + ASC "mais Passport ne l'a pas modifi{e."8D8D + ASC "Causes possibles :"8D + ASC "- Disquette source non prot{g{e."8D + ASC "- Disquette destination fonctionnelle."8D + ASC "- La disquette utilise une protection"8D + ASC " inconnue non g{r{e par Passport."00 +:fail + HEX 8D + ASC "Erreur fatale de lecture P%t,S%s"8D00 +:fatal0000 + HEX 8D + ASC "Causes possibles :"8D + ASC "- Pas de disquette en S6,D1."8D + ASC "- Disquette non Apple ][."8D + ASC "- Disquette uniquement DOS 3.2."8D + ASC "- Disquette non format{e."8D00 +:fatal220f + HEX 8D + ASC "Passport ne peut g{rer cette disquette."8D8D + ASC "Causes possibles :"8D + ASC "- Disquette non 16-secteurs."8D + ASC "- Disquette modifie sa RWTS et"8D + ASC " Passport ne peut pas le d{tecter."8D00 +:done + HEX 8D + ASC "Pressez une touche pour continuer " + FLS " "00 +:noslot6 + ASC "Passport requiert un Disk II en S6."8D + ASC "Pressez une touche pour quitter " + FLS " "00 +:writeerr + HEX 8D + ASC "Erreur fatale d'{criture P%t"8D8D00 +* +* MLI error $27 +* +:writeioerr + ASC "Causes possibles :"8D + ASC "- Pas de disquette en S%S,D%D."8D + ASC "- Secteurs illisibles sur la disquette."8D + ASC "- La disquette n'est pas format{e."8D8D00 +* +* MLI error $28 +* +:writenodev + ASC "S%S,D%D n'existe pas."8D00 +* +* MLI error $2B +* +:writeprot + ASC "Disque en S%S,D%D prot{g{ en {criture."8D00 +* +* other MLI error +* +:othermli + ASC "Erreur MLI $%0."8D + ASC "Veuillez contacter le d{veloppeur."8D00 +:canttrace + ASC "Lecteur inconnu, trace d{sactiv{e"8D00 +:canceled + ASC "Op{ration annul{e @ votre demande."8D00 +:bademu + HEX 8D + ASC "ATTENTION ! Vous utilisez Passport avec"8D + ASC "un {mulateur qui ne g}re pas bien les"8D + ASC "lecteurs de disquettes. Passport tentera" + ASC "de contourner le probl}me mais certaines" + ASC "disquettes ne seront pas lisibles."8D8D00 +:reset + HEX 8D + ASC "Pressez pour continuer."8D00 +:modify + ASC "P%t,S%0,$%1: "00 +:modifyto + ASC " -> "00 +:dosboot0 + ASC "P00,S00 Secteur de boot DOS 3.3 trouv{"8D00 +:prodosboot0 + ASC "P00,S00 Secteur de boot ProDOS trouv{"8D00 +:pascalboot0 + ASC "P00,S00 Secteur de boot Pascal trouv{"8D00 +:meccboot0 + ASC "P00 Secteur de boot MECC M8 trouv{"8D00 +:sierra + ASC "P%t,S%0 V{rif. de prot. Sierra trouv{e"8D00 +:a6bc95 + ASC "P%t,S%0 V{rif. de prot. A6BC95 trouv{e"8D00 +:jmpbcf0 + ASC "P00,S03 La RWTS requiert un bit de"8D + ASC "timing apr}s le premier {pilogue du"8D + ASC "champ de donn{es en sautant @ $BCF0."8D00 +:rol1e + ASC "P00,S03 La RWTS met les bits de timing"8D + ASC "en $1E et v{rifie la valeur plus tard."8D00 +:runhello + ASC "P%T,S%0 Le programme de d{marrage"8D + ASC "v{rifie la protection avant d'ex{cuter"8D + ASC "le vrai programme de d{marrage."8D00 +:e7 + ASC "P%t,S%0 Flux de bits E7 trouv{"8D00 +:jmpb4bb + ASC "P00,S0C Le disque v{rifie la protection"8D + ASC "en $B4BB avant d'initialiser le DOS."8D00 +:jmpb400 + ASC "P00,S01 Le disque v{rifie la protection"8D + ASC "en $B400 avant d'initialiser le DOS."8D00 +:jmpbeca + ASC "P00,S02 La RWTS requiert des nibbles"8D + ASC "suppl{mentaires et des bits de timing"8D + ASC "apr}s le prologue de donn{es en $BECA."8D00 +:jsrbb03 + ASC "P00,S05 V{rification de protection"8D + ASC "auto-d{chiffrable trouv{e en $BB03."8D00 +:thunder + ASC "P00,S03 La RWTS compte les bits de"8D + ASC "timing et les v{rifie plus tard."8D00 +:jmpae8e + ASC "P00,S0D Le disque v{rifie la protection"8D + ASC "en $AE8E apr}s l'initialisation du DOS."8D00 +:diskvol + ASC "P00,S08 La RWTS requiert un num{ro de"8D + ASC "volume de disque non standard."8D00 +:d5d5f7 + ASC "P%t,S%0 V{rif. de prot. D5D5F7 trouv{e"8D00 +:meccm7 + ASC "P00 Secteur de boot MECC M7 trouv{"8D00 + +* asc "1234567890123456789012345678901234567890" diff --git a/src/strings/it.a b/src/strings/it.a new file mode 100755 index 0000000..a3aed27 --- /dev/null +++ b/src/strings/it.a @@ -0,0 +1,351 @@ +* Italian translation by Marco Verpelli +* +* Main menu keys +* (should match the text in :mainmenu below) +* (these are NOT case-sensitive) +* +k_verify = "V" +k_demuffin = "D" +k_crack = "C" +k_slot = "S" +k_quit = "F" +* will also quit + +* +* String IDs +* (pass in accumulator to PrintByID) +* +s_header = $00 +s_mainmenu = $01 +s_progbar = $02 +s_reading = $03 +s_diskrwts = $04 +s_bb00 = $05 +s_sunburst = $06 +s_optimum = $07 +s_builtin = $08 +s_switch = $09 +s_writing = $0A +s_unformat = $0B +s_f7 = $0C +s_sync = $0D +s_optbad = $0E +s_pass = $0F +s_passdemuf = $10 +s_passcrack = $11 +s_passcrack0 = $12 +s_fail = $13 +s_fatal0000 = $14 +s_fatal220f = $15 +s_done = $16 +s_noslot6 = $17 +s_writeerr = $18 +s_writeioerr = $19 +s_writenodev = $1A +s_writeprot = $1B +s_othermli = $1C +s_canttrace = $1D +s_canceled = $1E +s_bademu = $1F +s_reset = $20 +s_modify = $21 +s_modifyto = $22 +s_dosb0 = $23 +s_prodosb0 = $24 +s_pascalb0 = $25 +s_meccb0 = $26 +s_sierra = $27 +s_a6bc95 = $28 +s_jmpbcf0 = $29 +s_rol1e = $2A +s_runhello = $2B +s_e7 = $2C +s_jmpb4bb = $2D +s_jmpb400 = $2E +s_jmpbeca = $2F +s_jsrbb03 = $30 +s_thunder = $31 +s_jmpae8e = $32 +s_diskvol = $33 +s_d5d5f7 = $34 +s_meccm7 = $35 +STRINGCOUNT = $36 + +StringTable + da :header + da :mainmenu + da :progbar + da :reading + da :diskrwts + da :bb00 + da :sunburst + da :optimum + da :builtin + da :switch + da :writing + da :unformat + da :f7 + da :sync + da :optbad + da :passver + da :passdemuf + da :passcrack + da :passcrack0 + da :fail + da :fatal0000 + da :fatal220f + da :done + da :noslot6 + da :writeerr + da :writeioerr + da :writenodev + da :writeprot + da :othermli + da :canttrace + da :canceled + da :bademu + da :reset + da :modify + da :modifyto + da :dosboot0 + da :prodosboot0 + da :pascalboot0 + da :meccboot0 + da :sierra + da :a6bc95 + da :jmpbcf0 + da :rol1e + da :runhello + da :e7 + da :jmpb4bb + da :jmpb400 + da :jmpbeca + da :jsrbb03 + da :thunder + da :jmpae8e + da :diskvol + da :d5d5f7 + da :meccm7 +* +* Text can contain substitution strings, which +* are replaced by current values at runtime. Each +* substitution string is two bytes long. The first +* byte is always "%", which puts the print routine +* into substitution mode. The next byte controls +* which value is printed (see list below), then +* substitution mode ends automatically. Unknown +* substitution strings are silently ignored and +* produce no output. +* +* Substitution strings are case-sensitive. +* +* Supported substitution strings: +* %S destination (write) slot +* %D destination (write) drive +* %t current track (during read and patch) +* %s current sector (during read) +* +* In addition, it supports "%0" through "%9" +* for printing arbitrary hexadecimal values. +* These are stored in the gDisplayBytes array and +* can be set directly before calling PrintByID. +* +:header + ASC "Passport di 4am 20160712-it"00 +:mainmenu + ASC "________________________________________"8D8D8D8D8D8D8D + ASC " " + INV "V" + ASC "erifica il disco"8D8D + ASC " " + INV "D" + ASC "emuffin (copia)"8D8D + ASC " " + INV "C" + ASC "ura il disco"8D8D + ASC " " + INV "F" + ASC "ine"8D8D8D8D8D8D8D + ASC "originale: S6,D1 copia: " + INV "S" + ASC "%S,D%D"00 +:progbar + HEX 8D + ASC " ______________________________________"8D + ASC " " + INV " " + ASC "____________________________________" + INV " "8D8D8D00 +:reading + ASC "Leggo dallo S6,D1"8D00 +:diskrwts + ASC "Uso la RWTS letta dal disco"8D00 +:bb00 + ASC "T00,S05 Trovata protezione $BB00"8D + ASC "T00,S0A potrebbe essere illeggibile"8D00 +:sunburst + ASC "T00,S04 Trovato disco della Sunburst"8D + ASC "T11,S0F potrebbe essere illeggibile"8D00 +:optimum + ASC "T00,S00 Trovato disco della"8D + ASC "Optimum Resource"8D + ASC "T01,S0F potrebbe essere illegibile"8D00 +:builtin + ASC "Uso la RWTS incorporata"8D00 +:switch + ASC "Passo alla RWTS incorporata"8D00 +:writing + ASC "Scrivo sullo S%S,D%D"8D00 +:unformat + ASC "La T%t non e' formattata"8D00 +:f7 + ASC "T%t Trovata protezione $F7F6EFEEAB"8D00 +:sync + ASC "T%t Trovata protezione conteggio nibble"8D00 +:optbad + ASC "T%t,S%s e' illeggibile (ignorata)"8D00 +:passver + ASC "Verifica completata. Il disco e' buono."8D00 +:passdemuf + ASC "Demuffin (copia) completata."8D00 +:passcrack + ASC "Cura completata."8D00 +:passcrack0 + HEX 8D + ASC "Il disco e' stato copiato con successo,"8D + ASC "ma Passport non ha applicato modifiche."8D8D + ASC "Possibili cause:"8D + ASC "- L'originale non era protetto da copia." + ASC "- La copia funziona senza modifiche."8D + ASC "- L'originale usa una protezione non"8D + ASC " conosciuta e Passport non puo' essere"8D + ASC " di ulteriore aiuto."00 +:fail + HEX 8D + ASC "T%t,S%s Errore grave in lettura"8D00 +:fatal0000 + HEX 8D + ASC "Possibili cause:"8D + ASC "- Non e' inserito un disco nello S6,D1."8D + ASC "- Non e' un disco Apple ][."8D + ASC "- Il disco e' solo per DOS 3.2."8D + ASC "- Il disco non e' formattato."8D00 +:fatal220f + HEX 8D + ASC "Passport non funziona con questo disco."8D8D + ASC "Possibili cause:"8D + ASC "- Questo non e' un disco a 16 settori."8D + ASC "- Il disco ha una RWTS modificata in"8D + ASC " un modo che Passport non e' in grado"8D + ASC " di identificare."8D00 +:done + HEX 8D + ASC "Premere un tasto per continuare " + FLS " "00 +:noslot6 + ASC "Passport richiede un drive Disk II."8D + ASC "nello S6."8D + ASC "Premere un tasto per finire " + FLS " "00 +:writeerr + HEX 8D + ASC "T%t Errore grave in scrittura"8D8D00 +* +* MLI error $27 +* +:writeioerr + ASC "Possibili cause:"8D + ASC "- Non e' inserito un disco nello S%S,D%D."8D + ASC "- Il disco ha dei settori danneggiati."8D + ASC "- Il disco non e' formattato."8D8D00 +* +* MLI error $28 +* +:writenodev + ASC "Lo S%S,D%D non esiste."8D00 +* +* MLI error $2B +* +:writeprot + ASC "Il disco nello S%S,D%D e' protetto da"8D + ASC "scrittura."8D00 +* +* other MLI error +* +:othermli + ASC "Errore MLI $%0."8D + ASC "Per favore contattate lo sviluppatore."8D00 + +:canttrace + ASC "Drive non riconosciuto, tracciamento"8D + ASC "disabilitato."8D00 +:canceled + ASC "Cancellato come hai richiesto."8D00 +:bademu + HEX 8D + ASC "ATTENZIONE! Stai eseguendo Passport con"8D + ASC "un emulatore che non supporta a pieno i"8D + ASC "floppy drivers. Passport cerchera' di"8D + ASC "rimediare a questa mancanza, ma certi"8D + ASC "dischi risulteranno illeggibili."8D8D00 +:reset + HEX 8D + ASC "Premere per continuare."8D00 +:modify + ASC "T%t,S%0,$%1: "00 +:modifyto + ASC " -> "00 +:dosboot0 + ASC "T00,S00 Trovato bootloader DOS 3.3"8D00 +:prodosboot0 + ASC "T00,S00 Trovato bootloader ProDOS"8D00 +:pascalboot0 + ASC "T00,S00 Trovato bootloader Pascal"8D00 +:meccboot0 + ASC "T00 Trovato bootloader MECC M8"8D00 +:sierra + ASC "T%t,S%0 Trovata protezione Sierra"8D00 +:a6bc95 + ASC "T%t,S%0 Trovata protezione A6BC95"8D00 +:jmpbcf0 + ASC "T00,S03 La RWTS richiede un timing bit"8D + ASC "dopo il primo epologo dati via salto a"8D + ASC "$BCF0."8D00 +:rol1e + ASC "T00,S03 La RWTS accumula timing bits"8D + ASC "in $1E e dopo ne controlla il valore."8D00 +:runhello + ASC "T%t,S%0 Il programma di avvio esegue"8D + ASC "un controllo di protezione prima di"8D + ASC "lanciare il vero programma di avvio."8D00 +:e7 + ASC "T%t,S%0 Trovato bitstream E7"8D00 +:jmpb4bb + ASC "T00,S0C Il disco chiama un controllo"8D + ASC "di protezione a $B4BB prima di"8D + ASC "inizializzare il DOS."8D00 +:jmpb400 + ASC "T00,S01 il disco chiama un controllo"8D + ASC "di protezione a $B400 prima di" + ASC "inizializzare il DOS."8D00 +:jmpbeca + ASC "T00,S02 La RWTS richiede sia nibbles"8D + ASC "extra che timing bits dopo il prologo"8D + ASC "dati via salto a $BECA."8D00 +:jsrbb03 + ASC "T00,S05 Trovato un controllo di"8D + ASC "protezione con auto-decodifica a $BB03."8D00 +:thunder + ASC "T00,S03 La RWTS conta i timing bits e"8D + ASC "dopo li controlla."8D00 +:jmpae8e + ASC "T00,S0D Il disco chiama un controllo"8D + ASC "di protezione a $AE8E dopo aver"8D + ASC "inizializzato il DOS."8D00 +:diskvol + ASC "T00,S08 La RWTS richiede un disco con"8D + ASC "un numero di volume non standard."8D00 +:d5d5f7 + ASC "T%t,S%0 Trovata protezione D5D5F7"8D00 +:meccm7 + ASC "T00 Trovato bootloader MECC M7"8D00 diff --git a/src/universalrwts.a b/src/universalrwts.a new file mode 100755 index 0000000..fc59ebb --- /dev/null +++ b/src/universalrwts.a @@ -0,0 +1,292 @@ +;------------------------------- +; Universal RWTS +; Binary dump of a modified DOS 3.3-style RWTS +; that reads 16-sector (6-and-2 encoded) disks +; - address prologue "D4 AA 96", "D5 AA 96", or +; "D5" followed by a timing bit +; - any address epilogue +; - data prologue "D5 AA AD" +; - any data epilogue +; +; It verifies data field checksum byte, but it +; ignores the address field checksum. It waits +; significantly longer than a normal RWTS to +; find an address prologue -- long enough that +; it will find the prologue even if there is +; only one sector on a track. +; +; It must be loaded at $B800..$BFFF. It uses the +; standard RWTS entry point at $BD00. +; +; Write and format support have been removed. +; Any attempt to pass $02 or $04 RWTS commands +; will crash. +;------------------------------- + + ;;!align 255, 0 ;ACME bug ignores second parm + !if (* & 255) > 0 { + !fill 256-(* & 255), 0 + } +universalrwts + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,$a0,00,$a2,$56,$ca,$30 + !byte $fb,$b9,00,$bb,$5e,00,$bc,$2a + !byte $5e,00,$bc,$2a,$91,$3e,$c8,$c4 + !byte $26,$d0,$eb,$60,$a0,$20,$88,$f0 + !byte $61,$bd,$8c,$c0,$10,$fb,$49,$d5 + !byte $d0,$f4,$ea,$bd,$8c,$c0,$10,$fb + !byte $c9,$aa,$d0,$f2,$a0,$56,$bd,$8c + !byte $c0,$10,$fb,$c9,$ad,$d0,$e7,$a9 + !byte 00,$88,$84,$26,$bc,$8c,$c0,$10 + !byte $fb,$59,00,$ba,$a4,$26,$99,00 + !byte $bc,$d0,$ee,$84,$26,$bc,$8c,$c0 + !byte $10,$fb,$59,00,$ba,$a4,$26,$99 + !byte 00,$bb,$c8,$d0,$ee,$bc,$8c,$c0 + !byte $10,$fb,$d9,00,$ba,$d0,$13,$18 + !byte $60,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,$38,$60,$a0,$fc,$84,$26 + !byte $c8,$d0,04,$e6,$26,$f0,$f3,$bd + !byte $8c,$c0,$10,$fb,$4a,$c9,$6a,$d0 + !byte $ef +_B959 !byte $bd +_B95A !byte $8c,$c0,$c9,$d5,$f0,$36 + !byte $bd,$8c,$c0,$10,$fb,$c9,$aa,$d0 + !byte $df,$bd,$8c,$c0,$10,$fb,$c9,$96 + !byte $d0,$d6,$a0,03,$a9,00,$85,$27 + !byte $bd,$8c,$c0,$10,$fb,$2a,$85,$26 + !byte $bd,$8c,$c0,$10,$fb,$25,$26,$99 + !byte $2c,00,$45,$27,$88,$10,$e7,$a8 + !byte $d0,00,$18,$60,$38,$60,$8D,$9B + !byte $B9,$F0,$D7,00,00,00,$18,$60 + !byte $86,$2b,$85,$2a,$cd,$78,$04,$f0 + !byte $53,$a9,00,$85,$26,$ad,$78,04 + !byte $85,$27,$38,$e5,$2a,$f0,$33,$b0 + !byte 07,$49,$ff,$ee,$78,04,$90,05 + !byte $69,$fe,$ce,$78,04,$c5,$26,$90 + !byte 02,$a5,$26,$c9,$0c,$b0,01,$a8 + !byte $38,$20,$ee,$b9,$b9,$11,$ba,$20 + !byte 00,$ba,$a5,$27,$18,$20,$f1,$b9 + !byte $b9,$1d,$ba,$20,00,$ba,$e6,$26 + !byte $d0,$c3,$20,00,$ba,$18,$ad,$78 + !byte 04,$29,03,$2a,05,$2b,$aa,$bd + !byte $80,$c0,$a6,$2b,$60,$aa,$a0,$a0 +nibtable !byte $a2,$11,$ca,$d0,$fd,$e6,$46,$d0 + !byte 02,$e6,$47,$38,$e9,01,$d0,$f0 + !byte $60,01,$30,$28,$24,$20,$1e,$1d + !byte $1c,$1c,$1c,$1c,$1c,$70,$2c,$26 + !byte $22,$1f,$1e,$1d,$1c,$1c,$1c,$1c + !byte $1c,$96,$97,$9a,$9b,$9d,$9e,$9f + !byte $a6,$a7,$ab,$ac,$ad,$ae,$af,$b2 + !byte $b3,$b4,$b5,$b6,$b7,$b9,$ba,$bb + !byte $bc,$bd,$be,$bf,$cb,$cd,$ce,$cf + !byte $d3,$d6,$d7,$d9,$da,$db,$dc,$dd + !byte $de,$df,$e5,$e6,$e7,$e9,$ea,$eb + !byte $ec,$ed,$ee,$ef,$f2,$f3,$f4,$f5 + !byte $f6,$f7,$f9,$fa,$fb,$fc,$fd,$fe + !byte $ff,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 +; these $FF bytes (at $BA80..$BA94) are used by the +; routine that checks whether a track is formatted + !byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff + !byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff + !byte $ff,$ff,$ff,$ff,$ff,$ff,00,01 + !byte $98,$99,02,03,$9c,04,05,06 + !byte $a0,$a1,$a2,$a3,$a4,$a5,07,08 + !byte $a8,$a9,$aa,09,$0a,$0b,$0c,$0d + !byte $b0,$b1,$0e,$0f,$10,$11,$12,$13 + !byte $b8,$14,$15,$16,$17,$18,$19,$1a + !byte $c0,$c1,$c2,$c3,$c4,$c5,$c6,$c7 + !byte $c8,$c9,$ca,$1b,$cc,$1c,$1d,$1e + !byte $d0,$d1,$d2,$1f,$d4,$d5,$20,$21 + !byte $d8,$22,$23,$24,$25,$26,$27,$28 + !byte $e0,$e1,$e2,$e3,$e4,$29,$2a,$2b + !byte $e8,$2c,$2d,$2e,$2f,$30,$31,$32 + !byte $f0,$f1,$33,$34,$35,$36,$37,$38 + !byte $f8,$39,$3a,$3b,$3c,$3d,$3e +nibtableff + !byte $3f + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte $84,$48,$85,$49,$a0,02,$8c,$f8 + !byte 06,$a0,04,$8c,$f8,04,$a0,01 + !byte $b1,$48,$aa,$a0,$0f,$d1,$48,$f0 + !byte $1b,$8a,$48,$b1,$48,$aa,$68,$48 + !byte $91,$48,$bd,$8e,$c0,$a0,08,$bd + !byte $8c,$c0,$dd,$8c,$c0,$d0,$f6,$88 + !byte $d0,$f8,$68,$aa,$bd,$8e,$c0,$bd + !byte $8c,$c0,$a0,08,$bd,$8c,$c0,$48 + !byte $68,$48,$68,$8e,$f8,05,$dd,$8c + !byte $c0,$d0,03,$88,$d0,$ee,08,$bd + !byte $89,$c0,$a0,06,$b1,$48,$99,$36 + !byte 00,$c8,$c0,$0a,$d0,$f6,$a0,03 + !byte $b1,$3c,$85,$47,$a0,02,$b1,$48 + !byte $a0,$10,$d1,$48,$f0,06,$91,$48 + !byte $28,$a0,00,08,$6a,$90,05,$bd + !byte $8a,$c0,$b0,03,$bd,$8b,$c0,$66 + !byte $35,$28,$08,$d0,$0b,$a0,07,$20 + !byte 00,$ba,$88,$d0,$fa,$ae,$f8,05 + !byte $a0,04,$b1,$48,$20,$5a,$be,$28 + !byte $d0,$11,$a4,$47,$10,$0d,$a0,$12 + !byte $88,$d0,$fd,$e6,$46,$d0,$f7,$e6 + !byte $47,$d0,$f3,$a0,$0c,$b1,$48,$f0 + !byte $5a,$c9,04,$f0,$58,$6a,08,$b0 + !byte 03,$20,00,$b8,$a0,$30,$8c,$78 + !byte 05,$ae,$f8,05,$20,$44,$b9,$90 + !byte $24,$ce,$78,05,$10,$f3,$ad,$78 + !byte 04,$48,$a9,$60,$20,$95,$be,$ce + !byte $f8,06,$f0,$28,$a9,$04,$8d,$f8 + !byte 04,$a9,00,$20,$5a,$be,$68,$20 + !byte $5a,$be,$4c,$bc,$bd,$a4,$2e,$cc + !byte $78,04,$f0,$1c,$ad,$78,04,$48 + !byte $98,$20,$95,$be,$68,$ce,$f8,04 + !byte $d0,$e5,$f0,$ca,$68,$a9,$40,$28 + !byte $4c,$48,$be,$f0,$39,$4c,$af,$be + !byte $a0,03,$b1,$48,$48,$a5,$2f,$a0 + !byte $0e,$91,$48,$68,$f0,08,$c5,$2f + !byte $f0,04,$a9,$20,$d0,$e1,$a0,05 + !byte $b1,$48,$a8,$b9,$b8,$bf,$c5,$2d + !byte $d0,$97,$28,$90,$1c,$20,$dc,$b8 + !byte 08,$b0,$8e,$28,$a2,00,$86,$26 + !byte $20,$c2,$b8,$ae,$f8,05,$18,$24 + !byte $38,$a0,$0d,$91,$48,$bd,$88,$c0 + !byte $60,$20,$2a,$b8,$90,$f0,$a9,$10 + !byte $b0,$ee,$48,$a0,01,$b1,$3c,$6a + !byte $68,$90,08,$0a,$20,$6b,$be,$4e + !byte $78,04,$60,$85,$2a,$20,$8e,$be + !byte $b9,$78,04,$24,$35,$30,03,$b9 + !byte $f8,04,$8d,$78,$04,$a5,$2a,$24 + !byte $35,$30,05,$99,$f8,04,$10,03 + !byte $99,$78,04,$4c,$a0,$b9,$8a,$4a + !byte $4a,$4a,$4a,$a8,$60,$48,$a0,02 + !byte $b1,$48,$6a,$66,$35,$20,$8e,$be + !byte $68,$0a,$24,$35,$30,05,$99,$f8 + !byte 04,$10,03,$99,$78,04,$60,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,$0d,$0b,09,07,05,03,01 + !byte $0e,$0c,$0a,08,06,04,02,$0f + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00 + !byte 00,00,00,00,00,00,00,00