migrate from 2016-12-30 Merlin source

This commit is contained in:
4am 2017-01-07 22:35:35 -05:00
parent c206b0aac0
commit e9e63efd94
72 changed files with 7875 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.DS_Store
/build/

32
Makefile Normal file
View File

@ -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

BIN
bin/AppleCommander.jar Normal file

Binary file not shown.

BIN
bin/V2Make.scpt Normal file

Binary file not shown.

1
res/readme.txt Executable file

File diff suppressed because one or more lines are too long

BIN
res/work.po Normal file

Binary file not shown.

293
src/analyze.a Executable file
View File

@ -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

128
src/applyglobals.a Executable file
View File

@ -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

202
src/compare.a Executable file
View File

@ -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 #<cont_search-branch_cont-2
sta branch_cont+1
; search...
cont_search
ldy #$d1 ; modified at runtime
search
lda $d100,y ; modified at runtime
iny
beq check_end
check_byte1
cmp #$d1 ; modified at runtime
bne search
; point to first byte
sty cont_search+1
check_match
tya
match_size1
sbc #$d1 ; modified at runtime
sta match_buffer2+1
ldx search+2
bcs plus03
dex
plus03
stx match_buffer2+2
ldy #$00
match_all
lda $d1d1,y ; modified at runtime
cmp #WILDCARD
beq found_wild
match_buffer2
cmp $d1d1,y ; modified at runtime
branch_cont
bne cont_search
found_wild
iny
match_size2
cpy #$d1 ; modified at runtime
bne match_all
; point to start of match
ldx match_buffer2+1
lda match_buffer2+2
sec
sbc #BASEPAGE
clc
rts
; cold path
check_end
inc search+2
ldx search+2
cpx #BASEPAGE+$10
bne check_byte1
ldx #<all_done_set-branch_cont-2
stx branch_cont+1
check_byte2
cmp #$d1 ; modified at runtime
beq check_match
all_done_set
sec
rts
;-------------------------------
; compare subroutine
; in: A = sector
; X = offset
; Y = string length
; stack = string to compare
; #WILDCARD in search string matches any 1 byte
; (like "." character in regular expressions)
; out: C clear if string matches
; or set if not matched
; A,X unchanged
; Y clobbered
; $tmp zero page clobbered
; $cmp1 zero page clobbered
; $cmp2 zero page clobbered
; stack set to first instruction after string
;-------------------------------
compare
clc
adc #BASEPAGE
CompareMemory
sta cmp1+1
stx cmp1
pla
sta cmp2
pla
sta cmp2+1
tax
tya
clc
adc cmp2
bcc +
inx
+ sta tmp
txa
pha
lda tmp
pha
xcmp
lda (cmp2),y
dey
bmi success
cmp (cmp1),y
beq xcmp
cmp #WILDCARD
beq xcmp
sec
!byte $24 ; hide CLC
success clc
php
lda cmp1+1
sec
sbc #BASEPAGE
ldx cmp1
plp
rts

32
src/id/datasoft.a Executable file
View File

@ -0,0 +1,32 @@
;-------------------------------
; IDDatasoft
; identify Datasoft encrypted bootloader
;
; in: track buffer contains T00,S00
; out: C clear if Datasoft encrypted bootloader found
; C set otherwise
; all registers clobbered
; all other flags clobbered
;-------------------------------
IDDatasoft
lda #$00
ldx #$00
ldy #$7E
jsr compare
!byte 01,$4C,$7E,08,04,$8A,$0C,$B8
!byte 00,$56,$10,$7A,00,00,$1A,$16
!byte $12,$0E,$0A,06,$53,$18,$9A,02
!byte $10,$1B,02,$10,$4D,$56,$15,$0B
!byte $BF,$14,$14,$54,$54,$54,$92,$81
!byte $1B,$10,$10,$41,06,$73,$0A,$10
!byte $33,$4E,00,$73,$12,$10,$33,$7C
!byte 00,$11,$20,$E3,$49,$50,$73,$1A
!byte $10,$41,00,$23,$80,$5B,$0A,$10
!byte $0B,$4E,$9D,$0A,$10,$9D,$0C,$10
!byte $60,$1E,$53,$10,$90,$53,$BC,$90
!byte $53,00,$90,$D8,$52,00,$D8,$7C
!byte 00,$53,$80,$0B,06,$41,00,09
!byte 04,$45,$0C,$63,04,$90,$94,$D0
!byte $D4,$23,04,$91,$A1,$EB,$CD,06
!byte $95,$A1,$E1,$98,$97,$86
rts

91
src/id/dos33.a Executable file
View File

@ -0,0 +1,91 @@
;-------------------------------
; IDDOS33
; identify DOS 3.3 bootloader or some variation
; that can be safely boot traced
;
; in: $0800..$08FF contains T00,S00
; first page of track buffer also contains T00,S00
; out: C clear if traceable DOS 3.3-style bootloader found
; C set otherwise
; all registers clobbered
; all other flags clobbered
;-------------------------------
IDDOS33
lda $08FE ; $08FE must be either $36 or $B6
cmp #$36 ; (prevents matching on some
beq match0 ; Infocom disks that would
cmp #$B6 ; otherwise match but then load
beq match0 ; boot1 over program space and crash)
jmp notd33boot0
match0
lda #$00 ; match first $1C bytes of T00S00
ldx #$00 ; against standard DOS 3.3 boot0
ldy #$1C
jsr compare
!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
bcc maybe_d33_1
jmp notd33boot0
maybe_d33_1
lda #$00 ; match more bytes of T00S00
ldx #$1F ; against standard DOS 3.3 boot0
ldy #$2B
jsr compare
!byte $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
bcc maybe_d33_2
jmp notd33boot0
maybe_d33_2
lda #$00 ; check sector order map
ldx #$4D
ldy #$10
jsr compare
!byte 00,$0D,$0B,09,07,05,03,01
!byte $0E,$0C,$0A,08,06,04,02,$0F
bcc maybe_d33_3
jmp notd33boot0
maybe_d33_3
lda #$00 ; match 3 final bytes of T00S00
ldx #$1C ; against standard DOS 3.3 boot0
ldy #$03
jsr compare
!byte $8D,$FE,08
bcs maybe_d33_4
jmp founddos33
maybe_d33_4
lda #$00 ; minor variation (e.g. Terrapin
ldx #$1C ; Logo 3.0) jumps to $08F0 and
ldy #$03 ; back, but still safe to trace
jsr compare
!byte $4C,$F0,08
bcc maybe_d33_5
jmp notd33boot0
maybe_d33_5
lda #$00
ldx #$F0
ldy #$09
jsr compare
!byte $8D,$FE,08,$EE,$F3,03,$4C,$1F
!byte 08
bcs notd33boot0
founddos33
clc
!byte $24 ; hide next SEC
notd33boot0
sec
rts

19
src/id/encode44.a Executable file
View File

@ -0,0 +1,19 @@
;-------------------------------
; IDEncoded44
; identify bootloader that loads
; 4-4-encoded data from track 0
; (these disks are unsupported)
;
; in: track buffer contains T00,S00
; out: C clear if 4-4-encoding loader found
; C set otherwise
; all registers clobbered
; all other flags clobbered
;-------------------------------
IDEncoded44
ldy #$07
jsr SearchTrack
!byte $BD,$8C,$C0,$10,$FB,$38,$2A
bcs encoded44_exit
encoded44_exit
rts

20
src/id/encode53.a Executable file
View File

@ -0,0 +1,20 @@
;-------------------------------
; IDEncoded53
; identify bootloader that loads
; 5-3-encoded data from track 0
; (these disks are unsupported)
;
; in: track buffer contains T00,S00
; out: C clear if 5-3-encoding loader found
; C set otherwise
; all registers clobbered
; all other flags clobbered
;-------------------------------
IDEncoded53
ldy #$10
jsr SearchTrack
!byte $BD,$8C,$C0,$10,$FB,$C9,$B5,$F0
!byte 09,$28,$90,$DF,$49,$AD,$F0,$1F
bcs encoded53_exit
encoded53_exit
rts

146
src/id/inspect0.a Executable file
View File

@ -0,0 +1,146 @@
;-------------------------------
; CheckT00S00
; main entry point to identify the bootloader
; based on T00,S00 (currently in memory at $0800)
;-------------------------------
CheckT00S00
lda #FALSE
sta gIsBoot0
sta gIsBoot1
sta gIsMaster
sta gIsRWTS
sta gIsProDOS
sta gIsPascal
sta gIsDatasoft
sta gIsProtDOS
lda #$00
sta gLastTrack
; Quick sanity check -- only recognized values for $0800
; are 1 or 2.
lda $0800
beq +
cmp #$03
bcc ++
+
jmp UseUniversal
++
;
; Copy the boot sector from $0800 to the track/sector buffer
; so we can reuse our standard compare functions.
; (TODO: this is probably unnecessary but I haven't ever
; refactored it since the Post-Demuffin Patcher days.)
;
lda #$08
ldx #BASEPAGE
ldy #$01
jsr CopyMemory
jsr ApplyGlobals
;
; Try to identify DOS 3.3-shaped bootloader, which
; we can maybe trace to capture the RWTS in memory.
;
jsr IDDOS33
bcs notdos33
lda #s_dosb0
jsr PrintByID
jmp TraceDOS33
notdos33
;
; Try to identify a variant bootloader that calls to $08B3
; early to munge the nibble tables used by the drive firmware.
;
jsr ID8b3
bcs not8b3
jmp found8b3
not8b3
;
; Try to identify all the different MECC fastloader variants.
;
jsr IDMECC
bcs notmecc
jsr IDMECCM8
bcs notmeccm8
jmp foundmeccm8
notmeccm8
jsr IDMECCM7
bcs notmeccm7
jmp foundmeccm7
notmeccm7
notmecc
;
; Try to identify the encrypted Datasoft bootloader.
;
jsr IDDatasoft
bcs notdatasoft
lda #s_datasoftb0
jsr PrintByID
lda #TRUE
sta gIsDatasoft
jmp useuniv
:notdatasoft
;
; Try to identify ProDOS bootloader.
;
lda gIsProDOS
bne notprodos
lda #s_prodosb0
jsr PrintByID
jmp useuniv
notprodos
;
; Try to identify Apple Pascal bootloader (all variants).
;
lda gIsPascal
bne notpascal
lda #s_pascalb0
jsr PrintByID
notpascal
jsr IDSpecDel
bcs notspecdel
lda #s_specdel
jsr PrintByID
jmp TraceSpecDel
notspecdel
;
; Try to detect whether there is code in the boot sector
; that loads 4-and-4-encoded data. This is an early escape
; hatch for disks that are guaranteed to fail later anyway.
;
jsr IDEncoded44
bcs notencoded44
lda #s_encoded44
jsr PrintByID
jmp TheEnd
notencoded44
;
; Try to detect whether there is code in the boot sector
; that loads 5-and-3-encoded data (like DOS 3.2 disks with
; a hybrid boot sector that loads on 16-sector drives).
; Passport has no support for converting DOS 3.2 disks, so
; this serves as an early escape hatch for disks that are
; guaranteed to fail later anyway.
;
jsr IDEncoded53
bcs notencoded53
lda #s_encoded53
jsr PrintByID
jmp TheEnd
notencoded53
useuniv
;
; We didn't recognize the boot sector, so use the universal
; (built-in) RWTS and hope for the best
;
jmp UseUniversal

77
src/id/jsr8b3.a Executable file
View File

@ -0,0 +1,77 @@
;-------------------------------
; ID8b3
; identify a bootloader that JSRs to $08B3
; to alter the nibble translate table used
; by the drive firmware at $C600
;
; in: track buffer contains T00,S00
; out: C clear if this bootloader was found
; C set otherwise
; all other flags clobbered
; all registers clobbered
;-------------------------------
ID8b3
lda #$00
ldx #$00
ldy #$5A
jsr compare
!byte 01,$20,$B3,08,$D0,$19,$EA,$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,$F0,$15,$8A,$EA,$EA,$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 $A2,$FF,$BD,00,08,$9D,00,$B6
!byte $CA,$E0,$FF,$D0,$F5,$20,$CC,08
!byte $A6,$2B
bcc jsr8b3_maybe
rts
jsr8b3_maybe
lda #$00
ldx #$B3
ldy #$36
jsr compare
!byte $A9,$3F,$8D,$6C,03
!byte $A9,$1C,$8D,$CC,03,$A9,00,$8D
!byte $D5,03,$A9,$37,$8D,$A3,03,$A5
!byte $27,$C9,09,$60,$A9,00,$85,00
!byte $A9,$B5,$85,01,$A0,$FF,$C8,$B9
!byte 00,$F0,$91,00,$C0,$FF,$D0,$F6
!byte $C6,01,$A9,08,$C5,01,$D0,$EC
!byte $60
rts
found8b3
tya
pha
ldy #$0F
lda #$00
A8b3 sta T00,y
dey
bpl A8b3
ldy #$0B
B8b3 sta T02,y
iny
cpy #$10
bne B8b3
pla
tay
lda #$4C
sta $085A
lda #<Inspect1_8b3
sta $085B
lda #>Inspect1_8b3
sta $085C
lda #$60
sta $08CC
lda #$2C
sta $083F
sta $0842
sta $0845
pla
plp
jmp $0801

230
src/id/mecc.a Executable file
View File

@ -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

54
src/id/protecteddos.a Executable file
View File

@ -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

244
src/id/specdelivery.a Executable file
View File

@ -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
ldx #>TraceSpecDel2
jmp Trace
TraceSpecDel2
lda #$4C
sta $0855
lda #<TraceSpecDel3
sta $0856
lda #>TraceSpecDel3
sta $0857
lda #$02
sec
jmp $0801
TraceSpecDel3
lda $1212
cmp #$D8
bne SDfail
lda #$4C
sta $10D5
lda #<TraceSpecDel4
sta $10D6
lda #>TraceSpecDel4
sta $10D7
lda #$4C
sta $10F0
lda #<TraceSpecDel4
sta $10F1
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

156
src/id/trace.a Executable file
View File

@ -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
lda #>gRWTSParams
jsr $BD00
bcc +
jmp FatalError
+
dec gSector
bne precheck
; pre-check passed, do the trace
lda #<TraceDOS33b
ldx #>TraceDOS33b
jmp Trace
;-------------------------------
; TraceDOS33b
; set up 2nd boot trace at $084A
;-------------------------------
TraceDOS33b
lda #$4C
sta $084A
lda #<TraceDOS33c
sta $084B
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

20
src/keys.a Executable file
View File

@ -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

4
src/lcase.a Executable file
View File

@ -0,0 +1,4 @@
!to "lcase.ct", plain
*=0
!for i, 128 {!byte i+127}
!for i, 256-128 {!byte i+127}

1
src/lcase.ct Executable file
View File

@ -0,0 +1 @@
€亗儎厗噲墛媽崕彁憭摂晼棙櫄洔潪煚、¥ウЖ┆<EFBFBD><EFBFBD><EFBFBD>辈炒刀犯购患骄坷谅媚牌侨墒颂臀闲岩釉罩棕仝圮蒉哙徕沅彐玷殛腱眍镳耱篝貊鼬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>€亗儎厗噲墛媽崕彁憭摂晼棙櫄洔潪煚、¥ウЖ┆<EFBFBD><EFBFBD><EFBFBD>辈炒刀犯购患骄坷谅媚牌侨墒颂臀闲岩釉罩棕仝圮蒉哙徕沅彐玷殛腱眍镳耱篝貊鼬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

126
src/memory.a Executable file
View File

@ -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

509
src/mli.a Executable file
View File

@ -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

73
src/modify.a Executable file
View File

@ -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

767
src/passport.a Executable file
View File

@ -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 $03F2
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 ; call universal RWTS to see
lda #>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
lda #>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+1
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
}

28
src/patchers/a6bc95.a Executable file
View File

@ -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

27
src/patchers/bademu.a Executable file
View File

@ -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

27
src/patchers/bademu2.a Executable file
View File

@ -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

24
src/patchers/d5d5f7.a Executable file
View File

@ -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

22
src/patchers/datasoft.a Executable file
View File

@ -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

49
src/patchers/davidbb03.a Executable file
View File

@ -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

46
src/patchers/diskvol.a Executable file
View File

@ -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

1
src/patchers/fbff.a Executable file
View File

@ -0,0 +1 @@
狎限限限限限限限限限限限限限限限龟 ␆藐<E29086><E89790> 蜧臇瀁 貗濻樍鏻瀁 蜼樍<E89CBC> 鐓敳龟 斀瀇<E69680><> 亠 勹 勹 勹 勹 鍣瞁懤龟 鵴嚬槴蜲 玃鐓 <20> 鶇樍氄殫 謯鐀殣<E99080><E6AEA3> 檴 鏻臄鍡 睾鏵 濎 瞂鐎槫<E9908E>狎限限限限限限限限限限限限限限限渘糋緧<E7B38B><EFBFBD> 迚仇<E8BF9A>𥻗麔 <20>槦蠆髫蠌蜱<E8A08C><E89CB1><EFBFBD>藏蜆簸掠亠簸亠襤<E4BAA0><E8A5A4><EFBFBD>鼴⑹偽鰻鰻藏蜆簸<E89C86><E7B0B8><EFBFBD>簸偶笠簞兜藏蜆簸<E89C86><E7B0B8><EFBFBD>掠亠簸勹襤譫⑹鷓<E291B9><E9B793><EFBFBD>藏蜆簸掠亠葩僩羅<E583A9><E7BE85><EFBFBD>偭襤藕薩蜆簸掠亠<E68EA0><E4BAA0><EFBFBD>雩笠眶<E7ACA0><EFBFBD> 舚氂濊<E6B082><EFBFBD>褔澞謽朅雙醲<E99B99>𦆭酃舚嶉<E8889A>𦆭鐖舚曮<E8889A>𥔱魟迚鵸糋緧<E7B38B><EFBFBD>唗濎蘌钃<E8988C>𥔱魟迚什<E8BF9A>𦆭酃舚蜧羻糮<E7BEBB>箝瀦隮𥔱噌迚化<E8BF9A><E58C96> 臩僸縃槼 敳 觶隮澼<E99AAE>罱臄舚氂濊<E6B082><EFBFBD>箇摫紇<E691AB><EFBFBD><E89CB5>鳲舚曮<E8889A>𦆭酃舚曮<E8889A>罱蝆舚<E89D86>𣳇鍏舚嶉<E8889A><EFBFBD><EFBFBD>綺摐籓紇<E7B193><EFBFBD>綰檷攠<E6AAB7>筵𥔱魟迚化<E8BF9A><E58C96> 臩僸縃槼 敳 觶隮澼<E99AAE>綿𥔱噌迚化<E8BF9A><E58C96> 臩僸縃槼 敳 觶隮澼<E99AAE>𥔱嘵迚什<E8BF9A>𥻗麔𡥄檷氄<E6AAB7>綰檷攠<E6AAB7><E694A0><EFBFBD>勹朌 臩僸縃槼 敳 觶隮澼<E99AAE>牐樍舚蜧羻糮<E7BEBB>𥻗艛舚蜧羻<E89CA7>箇摫<E7AE87><E691AB><EFBFBD>停偎捧冕偉㭲攠檁<E694A0>臈臢螩亅僕斑蜊<E69691>箏鼞<E7AE8F>

25
src/patchers/jmpae8e.a Executable file
View File

@ -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

26
src/patchers/jmpb400.a Executable file
View File

@ -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

39
src/patchers/jmpb4bb.a Executable file
View File

@ -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

24
src/patchers/jmpb4bbhi.a Executable file
View File

@ -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

26
src/patchers/jmpb660.a Executable file
View File

@ -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

24
src/patchers/jmpb720.a Executable file
View File

@ -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

21
src/patchers/jmpbbfe.a Executable file
View File

@ -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

25
src/patchers/jmpbcf0.a Executable file
View File

@ -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

46
src/patchers/jmpbeb1.a Executable file
View File

@ -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

27
src/patchers/jmpbeca.a Executable file
View File

@ -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

28
src/patchers/jmpbeca2.a Executable file
View File

@ -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

37
src/patchers/jsrbb03.a Executable file
View File

@ -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

126
src/patchers/meccm7.a Executable file
View File

@ -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

130
src/patchers/meccm8.a Executable file
View File

@ -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

136
src/patchers/nibtable.a Executable file
View File

@ -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

146
src/patchers/prodosmecc.a Executable file
View File

@ -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

38
src/patchers/prodosrwts.a Executable file
View File

@ -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

223
src/patchers/protecteddos.a Executable file
View File

@ -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

35
src/patchers/rol1e.a Executable file
View File

@ -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

52
src/patchers/runhello.a Executable file
View File

@ -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

664
src/patchers/rwts.a Executable file
View File

@ -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

38
src/patchers/rwtsswap.a Executable file
View File

@ -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

38
src/patchers/rwtsswap2.a Executable file
View File

@ -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

17
src/patchers/rwtsswapmecc.a Executable file
View File

@ -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

1
src/patchers/sierra.a Executable file
View File

@ -0,0 +1 @@
×­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­<EFBFBD>× £׃ֱֵֹׂׂ<D782>× ףובעדט במה הוףפעןש ב ףולז­הודעשנפימח<D79E>× נעןפודפיןמ דטודכ ץףוה ןמ םבמש ׃יועעב<D7A2>× היףכף ימ ב קבש פטבפ הןוףמ§פ פעינ פטו<D798>× פבםנוע דטודכ פטבפ דטודכףץםף פטו דןהו<D794>× ו®ח® ׃בםםש ּיחטפזןןפ¬ ֳעןףףזיעו<D7A2>×­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­<C2AD><C2AD>ףיועעב<D7A2> להב £₪°ֶ<C2B0> ףפב ÷ףודפןע«±<C2AB>÷ףודפןע להב £₪ֶֶ » םןהיזיוה בפ עץמפיםו<D79D> להר £₪°°<C2B0> להש £₪°²<C2B0> ךףע דןםנבעו<D7A2> ֵָ״ ֳֵ°³<C2B0> גדד ÷°<C3B7> ךםנ ÷מורפףודפןע<D79F>÷°<C3B7> להב ÷ףודפןע«±<C2AB> להר £₪°³<C2B0> להש £₪°²<C2B0> ךףע דןםנבעו<D7A2> ֵָ״ ֵֶ°³<C2B0> גדד ÷±<C3B7> ךםנ ÷מורפףודפןע<D79F>÷±<C3B7> להב ÷ףודפןע«±<C2AB> להר £₪°¶<C2B0> להש £₪°²<C2B0> ךףע דןםנבעו<D7A2> ֵָ״ ֱִ²¸<C2B2> גדד ÷²<C3B7> להב ÷ףודפןע«±<C2AB> להר £₪°¶<C2B0> להש £₪°²<C2B0> ךףע דןםנבעו<D7A2> ֵָ״ ֱִ²´<C2B2> גדד ÷²<C3B7> ךםנ ÷מורפףודפןע<D79F>÷²<C3B7> להב ÷ףודפןע«±<C2AB> דלד<D79C> בהד £ֱֲ׃ֵ׀ֱֵַ<D6B7> ףפב ÷דטודכב«²<C2AB> ףפב ÷דטודכג«²<C2AB>÷דטודכב<D79B> להב ₪ֶֶ°² » םןהיזיוה בגןצו<D7A6>÷דטודכג<D79B> דםנ ₪ֶֶ°µ » םןהיזיוה בגןצו<D7A6> גוס ÷שוף<D795> ךםנ ÷מורפףודפןע<D79F>÷שוף<D795> להב ÷ףודפןע«±<C2AB> ףפב חִיףנלבשֲשפוף<D795> להב £ף<C2A3>ףיועעב<D7A2> ךףע ׀עימפֲשִֹ<D6B9> להב ÷ףודפןע«±<C2AB> להר £₪°°<C2B0> להש £₪°²<C2B0> ךףע םןהיזש<D796> ֵָ״ ¶°ֱִ<D6B1>÷מורפףודפןע<D79F> הוד ÷ףודפןע«±<C2AB> גםי ÷וריפ<D799> ךםנ ÷ףודפןע<D79F>÷וריפ<D799>

71
src/patchers/sunburst.a Executable file
View File

@ -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

57
src/patchers/thunder.a Executable file
View File

@ -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

67
src/patchers/universale7.a Executable file
View File

@ -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

115
src/prefs.a Executable file
View File

@ -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

175
src/print.a Executable file
View File

@ -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

66
src/rwts.a Executable file
View File

@ -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
lda #>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
ldy #>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

78
src/sectormap.a Executable file
View File

@ -0,0 +1,78 @@
InitSectorMap
lda #<sectormap
sta B+1
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

74
src/slots.a Executable file
View File

@ -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

394
src/strings/en.a Executable file
View File

@ -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"
; <Esc> 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 <Ctrl-Reset> 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

349
src/strings/fi.a Executable file
View File

@ -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"
* <Esc> 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 <Ctrl-Reset> 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

343
src/strings/fr.a Executable file
View File

@ -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"
* <Esc> 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 <Ctrl-Reset> 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"

351
src/strings/it.a Executable file
View File

@ -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"
* <Esc> 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 <Ctrl-Reset> 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

292
src/universalrwts.a Executable file
View File

@ -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