Last active
September 4, 2022 13:34
-
-
Save mgcaret/ae2860c754fd029d2640107c4fe0bffd to your computer and use it in GitHub Desktop.
NS.CLOCK.SYSTEM.s - Complete disassembly of Apple II No-Slot Clock driver/driver loader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Fully disassembled and analyzed source to SMT | |
; NS.CLOCK.SYSTEM by M.G. - 04/20/2017 | |
; Assembles to a binary match for SMT code if | |
; IncludeJunk is set, see the .if IncludeJunk for details. | |
; other notes: | |
; * uses direct block access to read volume directory, | |
; so won't launch from an AppleShare volume. | |
; Build instructions: | |
; ca65 ns.clock.system.s -l ns.clock.system.lst | |
; ld65 -t none -o ns.clock.system ns.clock.system.o | |
; put ns.clock.system as a SYS file on a ProDOS disk. | |
.setcpu "6502" | |
IncludeJunk = 0 ; original file had a bunch of garbage | |
; setting this to 1 includes it | |
; ---------------------------------------------------------------------------- | |
; Zero page | |
POINTER := $A5 ; generic pointer used everywhere | |
ENTNUM := $A7 ; current file entry # in block (zero-based) | |
LENGTH := $A8 ; generic length byte used everywhere | |
; entry points | |
PRODOS := $BF00 | |
INIT := $FB2F | |
HOME := $FC58 | |
CROUT := $FD8E | |
PRBYTE := $FDDA | |
COUT := $FDED | |
SETNORM := $FE84 | |
SETKBD := $FE89 | |
SETVID := $FE93 | |
; buffers & other spaces | |
INBUF := $0200 ; input buffer | |
PATHBUF := $0280 ; path buffer | |
RELOCT := $1000 ; relocation target | |
BLOCKBUF := $1800 ; block & I/O buffer | |
SYSEXEC := $2000 ; location of SYS executables | |
SOFTEV := $03F2 ; RESET vector | |
; global Page entries | |
CLKENTRY := $BF06 ; clock routine entry point | |
DEVNUM := $BF30 ; most recent accessed device | |
MEMTABL := $BF58 ; system bitmap | |
DATELO := $BF90 | |
DATEHI := $BF91 | |
TIMELO := $BF92 | |
TIMEHI := $BF93 | |
MACHID := $BF98 ; machine ID | |
; I/O and hardware | |
ROMIn2 := $C082 ; access to read ROM/no write LC RAM | |
LCBank1 := $C08B ; Access twice to write LC bank 1 | |
KBD := $C000 ; keyboard | |
INTCXROMOFF := $C006 ; Disable internal $C100-$CFFF ROM | |
INTCXROMON := $C007 ; Enable interal $C100-$CFFF ROM | |
KBDSTR := $C010 ; keyboard strobe | |
INTCXROM := $C015 ; Read state of $C100-$CFFF soft switch | |
CLR80VID := $C00C ; Turn off 80-column mode | |
CLRALTCHAR := $C00E ; Turn off alt charset | |
SLOT3ROM := $C300 ; SLOT 3 ROM | |
C8OFF := $CFFF ; C8xx Slot ROM off | |
; Misc | |
CLKCODEMAX := $7D | |
; Macro to define ASCII string with high bit set. | |
.macro hasc Arg | |
.repeat .strlen(Arg), I | |
.byte .strat(Arg, I) | $80 | |
.endrep | |
.endmacro | |
; ---------------------------------------------------------------------------- | |
; relocate ourself from SYSEXEC to RELOCT | |
; note that we .org the whole thing, including this routine, at the target | |
; address and jump to it after the first page is relocated. | |
.org RELOCT ; note code initially runs at SYSEXEC | |
.proc Relocate | |
sec | |
bcs :+ ; skip version info | |
.byte $04, $21, $91 ; version date in BCD | |
: ldx #$05 ; page counter, do $0500 bytes | |
ldy #$00 ; byte counter | |
from: lda SYSEXEC,y ; start location | |
to: sta RELOCT,y ; end location | |
iny ; next byte offset | |
bne from ; if not zero, copy byte | |
inc from+2 ; otherwise increment source address high byte | |
inc to+2 ; and destination address high byte | |
dex ; dec page counter | |
beq Main ; when done start main code | |
jmp from ; live jump... into relocated code after first page loop | |
.endproc | |
; ---------------------------------------------------------------------------- | |
.proc Main | |
; figure out length of our name and stick in LENGTH | |
lda #$00 | |
sta LENGTH ; zero length | |
ldx PATHBUF ; length pf path | |
beq Main1 ; skip if length = 0 (no path) | |
: inc LENGTH ; length += 1 for each non-/ | |
dex ; previous char in path | |
beq CopyNm ; nothing left? Copy our name. | |
lda PATHBUF,x ; get character | |
; check for /... kinda wtf, as cmp #$2f would work... | |
eor #$2F ; roundabout check for '/' | |
asl a ; upper/lower case | |
bne :- ; keep examining if not '/' | |
; now save our name (assuming we weren't lied to) | |
CopyNm: ldy #$00 ; init destination offset | |
: iny ; increment destination offset | |
inx ; inc source offset | |
lda PATHBUF,x ; get source char | |
sta MyName,y ; write to save location | |
cpy LENGTH ; got it all? | |
bcc :- ; nope, copy more | |
sty MyName ; save length | |
; done moving stuff | |
Main1: cld | |
bit ROMIn2 ; make sure ROM enabled | |
; letter of the law with RESET vector | |
lda #<Main1 | |
sta SOFTEV | |
lda #>Main1 | |
sta SOFTEV+1 | |
eor #$A5 | |
sta SOFTEV+2 | |
lda #$95 ; control code | |
jsr COUT ; to quit 80-column firmware | |
ldx #$FF ; reset | |
txs ; stack pointer | |
; get video & keyboard I/O to known state | |
sta CLR80VID | |
sta CLRALTCHAR | |
jsr SETVID | |
jsr SETKBD | |
jsr SETNORM | |
jsr INIT | |
; initialize memory map | |
ldx #$17 ; there are $18 bytes total | |
lda #$01 ; last byte gets $01 (protect global page) | |
: sta MEMTABL,x | |
lda #$00 ; all but first byte get $00 (no protection) | |
dex | |
bne :- | |
lda #$CF ; first byte protect ZP, stack, text page 1 | |
sta MEMTABL | |
lda MACHID | |
and #$88 ; mask in bits indicating machine with lower case | |
bne :+ ; has lower case, skip over next few instructions | |
lda #$DF ; mask value | |
sta CaseCv ; to make print routine convert to upper case | |
: lda MACHID | |
and #$01 ; mask in clock bit | |
beq FindClock ; no clock yet, proceed | |
jsr HOME | |
jsr iprint | |
.byte $8D ; CR | |
hasc "Previous Clock Installed!" | |
.byte $87,$8D,$00 ; BELL, CR, done | |
jmp NextSys | |
.endproc | |
; go hunting for clock | |
.proc FindClock | |
ldy #$03 ; save old date and time | |
: lda DATELO,y ; because we are going to overwrite | |
sta DTSave,y ; during our probes | |
dey | |
bpl :- | |
; We are going to try slot ROMs first | |
lda #>C8OFF | |
ldy #<C8OFF | |
sta CDRdSwH | |
sty CDRdSwL | |
sta CDRsSwH | |
sty CDRsSwL | |
lda #$00 | |
sta Count ; init counter | |
; check slot 3 in system default state first | |
lda #$03 ; initial check slot 3 for Count=0 | |
CkSlot: ora #$C0 ; accumulator has current value of Count after first iteration | |
sta CDStRmH | |
CkOthr: sta CDRstA2 | |
sta CDUnlck | |
sta CDRdClk | |
lda #$03 ; Try to read clock 3 times | |
sta ClkTry | |
GetDT: jsr ClockDrv ; read clock | |
lda DATEHI ; now see if ProDOS time and date | |
ror a ; values make sense | |
lda DATELO | |
rol a | |
rol a | |
rol a | |
rol a | |
and #$0F | |
beq ClkNxt | |
cmp #$0D | |
bcs ClkNxt | |
lda DATELO | |
and #$1F | |
beq ClkNxt | |
cmp #$20 | |
bcs ClkNxt | |
lda TIMEHI | |
cmp #$18 | |
bcs ClkNxt | |
lda TIMELO | |
cmp #$3C | |
bcs ClkNxt | |
dec ClkTry | |
bne GetDT ; try again if successful this time | |
beq InstallDriver ; found clock! | |
ClkNxt: inc Count | |
lda Count | |
cmp #$08 | |
bcc CkSlot ; if Count < 8 | |
bne NoClock ; if Count != (thus >) 8 | |
; try internal $C100-$CFFF ROM | |
; modify driver to save CX ROM status, enable it, and restore it | |
lda #>INTCXROM | |
ldy #<INTCXROM | |
sta CDRdSwH | |
sty CDRdSwL | |
ldy #<INTCXROMON | |
sta CDStRmH | |
sty CDStRmL | |
dey ; y = $06 now | |
sta CDRsSwH ; and refers to INTCXROMOFF | |
sty CDRsSwL | |
lda #$C8 ; now reference $C800 space | |
bne CkOthr ; and look for clock | |
.endproc | |
.proc NoClock | |
ldy #$03 ; restore old date/time because | |
: lda DTSave,y ; we didn't find clock anywhere | |
sta DATELO,y | |
dey | |
bpl :- | |
jsr HOME | |
jsr iprint | |
.byte $8D | |
hasc "No-SLot Clock Not Found." ; typo is original | |
.byte $8D, $8D | |
hasc "Clock Not Installed!" | |
.byte $87, $8D, $00 | |
; launch next .system file | |
jmp NextSys | |
.endproc | |
DTSave: .byte $00,$00,$00,$00 ; Saved ProDOS Date/Time values | |
ClkTry: .byte $03 ; Counter for clock read tries left | |
Count: .byte $00 ; Count of slots/locations checked | |
; install driver, this does it the right way and looks at the vector | |
; and puts the driver there | |
.proc InstallDriver | |
; this code corrects reference to DS121x unlock sequence | |
lda CLKENTRY+1 | |
sta POINTER | |
clc | |
adc #(DSUnlk-ClockDrv) | |
sta CDULSqL | |
lda CLKENTRY+2 | |
sta POINTER+1 | |
adc #$00 | |
sta CDULSqH | |
; done correcting | |
lda LCBank1 ; make LC RAM writable | |
lda LCBank1 | |
ldy #DrvSize ; copy driver | |
: lda ClockDrv,y | |
sta (POINTER),y | |
dey | |
bpl :- | |
lda MACHID ; current MACHID | |
ora #$01 ; set clock installed bit | |
sta MACHID ; and put back | |
lda #$4C ; JMP | |
sta CLKENTRY ; into clock driver entry point | |
jsr CLKENTRY ; may as well give it a whirl | |
bit ROMIn2 ; LC write protect | |
jsr HOME | |
jsr iprint | |
.byte $8d | |
hasc "No-Slot Clock Installed " | |
.byte $00 | |
; print today's date | |
lda DATEHI | |
ror a | |
pha | |
lda DATELO | |
pha | |
rol a | |
rol a | |
rol a | |
rol a | |
and #$0F | |
jsr PrDec | |
lda #$AF | |
jsr COUT | |
pla | |
and #$1F | |
jsr PrDec | |
lda #$AF | |
jsr COUT | |
pla | |
jsr PrDec | |
jsr CROUT | |
.endproc | |
; This starts the process of finding & launching next system file | |
; unfortunately it also uses block reads and can't be run from an AppleShare | |
; volume. | |
.proc NextSys | |
; set reset vector to DoQUit | |
lda #<DoQuit | |
sta SOFTEV | |
lda #>DoQuit | |
sta SOFTEV+1 | |
eor #$A5 | |
sta SOFTEV+2 | |
lda DEVNUM ; last unit number accessed | |
sta PL_READ_BLOCK+1 ; put in parameter list | |
jsr GetBlock ; get first volume directory block | |
lda BLOCKBUF+$23 ; get entry_length | |
sta SMENTL ; modify code | |
lda BLOCKBUF+$24 ; get entries_per_block | |
sta SMEPB ; modify code | |
lda #$01 ; | |
sta ENTNUM ; init current entry number as second (from 0) | |
lda #<(BLOCKBUF+$2B) ; set pointer to that entry | |
sta POINTER ; making assumptions as we go | |
lda #>(BLOCKBUF+$2B) | |
sta POINTER+1 | |
; loop to examine file entries... | |
FEntLp: ldy #$10 ; offset of file_type | |
lda (POINTER),y | |
cmp #$FF ; SYS? | |
bne NxtEnt ; nope.. | |
ldy #$00 ; offset of storage_type & name_length | |
lda (POINTER),y | |
and #$30 ; mask interesting bits of storage_type | |
beq NxtEnt ; if not 1-3 (standard file organizations) | |
lda (POINTER),y ; get storage_type and name_length again | |
and #$0F ; mask in name_length | |
sta LENGTH ; save for later | |
tay ; and use as index for comparison | |
; comparison loop | |
ldx #$06 ; counter for size of ".SYSTEM" | |
: lda (POINTER),y ; get file name byte | |
cmp system,x ; compare to ".SYSTEM" | |
bne NxtEnt ; no match | |
dey | |
dex | |
bpl :- | |
; if we got here, have ".SYSTEM" file | |
ldy MyName ; length of our own file name | |
cpy LENGTH ; matches? | |
bne CkExec ; nope, see if we should exec | |
; loop to check if this is our own name | |
: lda (POINTER),y | |
cmp MyName,y | |
bne CkExec ; no match, see if we should exec | |
dey | |
bne :- | |
; if we got here, we have found our own self | |
sec | |
ror FdSelf ; flag it | |
; go to next entry | |
NxtEnt: lda POINTER ; low byte of entry pointer | |
clc ; ready for addition | |
adc #$27 ; add entry length that is | |
SMENTL = * - 1 ; self-modifed | |
sta POINTER ; save it | |
bcc :+ ; no need to do high byte if no carry | |
inc POINTER+1 ; only increment if carry | |
: inc ENTNUM ; next entry number | |
lda ENTNUM ; and get it | |
cmp #$0D ; check against number of entries that is | |
SMEPB = * - 1 ; self-modified | |
bcc FEntLp ; back to main search if not done with this block | |
lda BLOCKBUF+$02 ; update PL_BLOCK_READ for next directory block | |
sta PL_READ_BLOCK+4 | |
lda BLOCKBUF+$03 | |
sta PL_READ_BLOCK+5 | |
ora PL_READ_BLOCK+4 ; see if pointer is $00 | |
beq NoSys ; error if we hit the end and found nothing.. | |
jsr GetBlock ; get next volume directory block | |
lda #$00 | |
sta ENTNUM ; update current entry number | |
lda #<(BLOCKBUF+$04) ; and reset pointer | |
sta POINTER | |
lda #>(BLOCKBUF+$04) | |
sta POINTER+1 | |
jmp FEntLp ; go back to main loop | |
CkExec: bit FdSelf ; did we find our own name yet? | |
bpl NxtEnt ; nope... go to next entry | |
ldx PATHBUF ; get length of path in path buffer | |
beq CpyNam ; skip looking for / if zero | |
: dex ; | |
beq CpyNam ; done if zero | |
lda PATHBUF,x ; | |
eor #$2F ; is '/'? | |
asl a ; in roundabout way | |
bne :- ; no slash | |
; copy file name onto path, x already has position | |
CpyNam: ldy #$00 | |
: iny ; next source byte offset | |
inx ; next dest byte offset | |
lda (POINTER),y ; get filename char | |
sta PATHBUF,x ; put in path | |
cpy LENGTH ; copied all the chars? | |
bcc :- ; nope | |
stx PATHBUF ; update length of path | |
jmp LaunchSys ; try to launch it! | |
NoSys: jsr iprint | |
.byte $8D, $8D, $8D | |
hasc "* Unable to find next '.SYSTEM' file *" | |
.byte $8D, $00 | |
; wait for keyboard then quit to ProDOS | |
bit KBDSTR | |
: lda KBD | |
bpl :- | |
bit KBDSTR | |
jmp DoQuit | |
.endproc | |
; ---------------------------------------------------------------------------- | |
; inline print routine | |
; print chars after JSR until $00 encountered | |
; converts case via CaseCv ($FF = no conversion, $DF = to upper) | |
.proc iprint | |
pla | |
sta POINTER | |
pla | |
sta POINTER+1 | |
bne next | |
: cmp #$E1 | |
bcc noconv | |
and CaseCv | |
noconv: jsr COUT | |
next: inc POINTER | |
bne nohi | |
inc POINTER+1 | |
nohi: ldy #$00 | |
lda (POINTER),y | |
bne :- | |
lda POINTER+1 | |
pha | |
lda POINTER | |
pha | |
rts | |
.endproc | |
; ---------------------------------------------------------------------------- | |
; print one or two decimal digits | |
.proc PrDec | |
ldx #$B0 ; tens digit | |
cmp #$0A | |
bcc onedig | |
: sbc #$0A ; repeated subtraction, carry is already set | |
inx | |
cmp #$0A ; less than 10 yet? | |
bcs :- ; nope | |
onedig: pha | |
cpx #$B0 | |
beq nozero ; skip printing leading zero | |
txa | |
jsr COUT | |
nozero: pla | |
ora #$B0 | |
jsr COUT | |
rts | |
.endproc | |
CaseCv: .byte $FF ; default case conversion byte = none | |
; ---------------------------------------------------------------------------- | |
.proc DoQuit | |
jsr PRODOS | |
.byte $65 ; MLI QUIT | |
.word PL_QUIT | |
brk ; crash into monitor if QUIT fails | |
rts ; (!) if that doesn't work, go back to caller | |
PL_QUIT: | |
.byte $04 ; param count | |
.byte $00 ; quit type - $00 is only type | |
.word $0000 ; reserved | |
.byte $00 ; reserved | |
.word $0000 ; reserved | |
.endproc | |
.proc GetBlock | |
jsr PRODOS | |
.byte $80 ; READ_BLOCK | |
.word PL_READ_BLOCK | |
bcs LaunchFail | |
rts | |
.endproc | |
PL_READ_BLOCK: | |
.byte $03 | |
.byte $60 ; unit number | |
.word BLOCKBUF | |
.word $0002 ; first volume directory block | |
; ---------------------------------------------------------------------------- | |
; launch next .SYSTEM file | |
.proc LaunchSys | |
jsr PRODOS | |
.byte $C8 ; OPEN | |
.word PL_OPEN | |
bcs LaunchFail | |
lda PL_OPEN+$05 ; copy ref number | |
sta PL_READ+$01 ; into READ parameter list | |
jsr PRODOS | |
.byte $CA ; READ | |
.word PL_READ | |
bcs LaunchFail | |
; bug the first: Close should be done every time the OPEN call is successful | |
; but only done when the READ succeeds | |
; bug the second: Others may not consider this a bug, but we close all open | |
; files, even if we didn't open them. That's not very polite. | |
jsr PRODOS | |
.byte $CC ; CLOSE | |
.word PL_CLOSE | |
bcs LaunchFail | |
jmp SYSEXEC | |
.endproc | |
; ---------------------------------------------------------------------------- | |
; failed to launch next .SYSTEM file | |
.proc LaunchFail | |
pha | |
jsr iprint | |
.byte $8D, $8D, $8D | |
hasc "** Disk Error $" | |
.byte $00 | |
pla | |
jsr PRBYTE | |
jsr iprint | |
hasc " **" | |
.byte $8D, $00 | |
; wait for keyboard, then quit to ProDOS | |
bit KBDSTR | |
: lda KBD | |
bpl :- | |
bit KBDSTR | |
jmp DoQuit | |
.endproc | |
; ---------------------------------------------------------------------------- | |
PL_OPEN: | |
.byte $03 | |
.word PATHBUF | |
.word BLOCKBUF | |
.byte $01 ; ref num (default 1 wtf?) | |
PL_READ: | |
.byte $04 | |
.byte $01 ; ref num | |
.word SYSEXEC ; data buffer | |
.word $FFFF ; request count | |
.word $0000 ; transfer count | |
PL_CLOSE: | |
.byte $01 | |
.byte $00 ; ref num $00 = all files | |
; ---------------------------------------------------------------------------- | |
FdSelf: .byte $00 ; bit 7 set if we found our name in volume dir | |
system: .byte ".SYSTEM" | |
MyName: .byte $0F,"NS.CLOCK.SYSTEM" ; overwritten in the usual case | |
; actual clock driver follows | |
ClockDrv: | |
php | |
sei | |
lda C8OFF | |
CDRdSwL = * - 2 ; may modify to read INTCXROM state | |
CDRdSwH = * - 1 | |
; we save the value in case we have been modified to read state | |
; of a soft switch | |
pha | |
sta SLOT3ROM ; enable C8xx ROM for slot, default $C300 ROM | |
; seems to me that during probing, it might accidentally | |
; turn on a SoftCard-compatible CP/M card and crash... | |
CDStRmL = * - 2 ; may modify to set INTCXROMON | |
CDStRmH = * - 1 | |
lda SLOT3ROM+$04 ; will be modified to correct loc | |
CDRstA2 = * - 1 | |
ldx #$08 | |
ubytlp: lda DSUnlk,X | |
CDULSqL = * - 2 ; to be patched later when relocated into ProDOS | |
CDULSqH = * - 1 | |
sec ; bit 7 of a is going to be set | |
ror a ; first bit in byte of unlock seq in carry & b7 = 1 | |
ubitlp: pha ; remaining bits are in a, so save it | |
lda #$00 | |
rol a ; move unlock bit into low bit | |
tay ; put into y | |
lda SLOT3ROM,Y ; NSC looks for unlock on A0 line | |
CDUnlck = * - 1 ; may be patched to a different ROM loc | |
pla ; restore unlock seq in progress | |
lsr a ; next bit into cary | |
bne ubitlp ; do again until that 1 bit we set above rolls off | |
dex ; next byte of unlock sequence | |
bne ubytlp | |
ldx #$08 ; loop counter to read 8 bytes of clock data | |
rbytlp: ldy #$08 ; loop counter to read 8 bits of clock data | |
rbitlp: lda SLOT3ROM+$04 ; get data bit (NSC clocks reads off of A2) | |
CDRdClk = * - 1 ; may be patched for different loc | |
ror a ; put into carry | |
ror INBUF-1,x ; and then rotate into relative input buffer loc | |
dey | |
bne rbitlp ; next bit | |
lda INBUF-1,x ; now BCD->Binary | |
lsr a | |
lsr a | |
lsr a | |
lsr a | |
tay | |
beq notens ; no tens digit | |
lda INBUF-1,x | |
and #$0F | |
clc ; repeated addition for tens | |
: adc #$0A | |
dey | |
bne :- | |
sta INBUF-1,X ; update value to binary equiv | |
notens: dex | |
bne rbytlp ; next byte | |
; put values into ProDOS time locations | |
lda INBUF+4 | |
sta TIMEHI | |
lda INBUF+5 | |
sta TIMELO | |
lda INBUF+1 | |
asl a | |
asl a | |
asl a | |
asl a | |
asl a | |
ora INBUF+2 | |
sta DATELO | |
lda INBUF | |
rol a | |
sta DATEHI | |
pla ; Bit 7 clear if we need to hit soft switch | |
bmi :+ | |
sta C8OFF ; safely default to release C8xx ROM space | |
CDRsSwL = * - 2 ; may be modified to set INTCXROMOFF | |
CDRsSwH = * - 1 | |
: plp | |
rts | |
; Dallas unlock sequence | |
DSUnlk = * - 1 | |
.byte $5C, $A3, $3A, $C5, $5C, $A3, $3A, $C5 | |
DrvSize = * - ClockDrv | |
.assert DrvSize < CLKCODEMAX, error, "NS CLOCK driver too big" | |
; ---------------------------------------------------------------------------- | |
; the rest of this looks like junk that was accidentally saved with the file | |
; there are no references from the previous code. Didn't feel like disassembling. | |
.if IncludeJunk | |
.setcpu "6502" | |
BASWARM := $D43F ; warm start BASIC | |
FNDLIN := $D61A ; BASIC search for line | |
SETPTRS := $D665 | |
L008D := $008D | |
L0EA1 := $0EA1 | |
L161F := $161F | |
L2020 := $2020 | |
L434F := $434F | |
L522F := $522F | |
L9A17 := $9A17 | |
LAC08 := $AC08 | |
LAC0D := $AC0D | |
LAC1F := $AC1F | |
LAC6B := $AC6B | |
LAD50 := $AD50 | |
LAFD3 := $AFD3 | |
LAFD7 := $AFD7 | |
LB1D3 := $B1D3 | |
LB531 := $B531 | |
LBE70 := $BE70 | |
LFFFF := $FFFF | |
.byte $00 | |
stz $F5,x ; 147C 74 F5 t. | |
.byte $D3 ; 147E D3 . | |
adc $8DB3 ; 147F 6D B3 8D m.. | |
lsr $BE,x ; 1482 56 BE V. | |
jmp L2020 ; 1484 4C 20 20 L | |
; ---------------------------------------------------------------------------- | |
bbr2 $43,L14DE ; 1487 2F 43 54 /CT | |
rol $2031 ; 148A 2E 31 20 .1 | |
sta $AE00 ; 148D 8D 00 AE ... | |
lda $CABB,x ; 1490 BD BB CA ... | |
stx $74 ; 1493 86 74 .t | |
jsr LAC0D ; 1495 20 0D AC .. | |
ldx $20A9 ; 1498 AE A9 20 .. | |
bbr2 $48,L14DF ; 149B 2F 48 41 /HA | |
eor ($44) ; 149E 52 44 RD | |
and ($20),y ; 14A0 31 20 1 | |
sta $A400 ; 14A2 8D 00 A4 ... | |
lda #$00 ; 14A5 A9 00 .. | |
beq L14BE ; 14A7 F0 15 .. | |
lda #$00 ; 14A9 A9 00 .. | |
sta $BE44 ; 14AB 8D 44 BE .D. | |
jsr L522F ; 14AE 20 2F 52 /R | |
eor ($4D,x) ; 14B1 41 4D AM | |
jsr L008D ; 14B3 20 8D 00 .. | |
jsr LAC08 ; 14B6 20 08 AC .. | |
bcs L150B ; 14B9 B0 50 .P | |
jsr SETPTRS ; 14BB 20 65 D6 e. | |
L14BE: sta $D8 ; 14BE 85 D8 .. | |
jsr L0EA1 ; 14C0 20 A1 0E .. | |
bbr2 $4E,L1515 ; 14C3 2F 4E 4F /NO | |
rol $4C53 ; 14C6 2E 53 4C .SL | |
bbr4 $54,L14FA ; 14C9 4F 54 2E OT. | |
.byte $43 ; 14CC 43 C | |
jmp L434F ; 14CD 4C 4F 43 LOC | |
; ---------------------------------------------------------------------------- | |
.byte $4B ; 14D0 4B K | |
jsr L008D ; 14D1 20 8D 00 .. | |
lda #$FF ; 14D4 A9 FF .. | |
jsr L522F ; 14D6 20 2F 52 /R | |
eor ($4D,x) ; 14D9 41 4D AM | |
jsr L008D ; 14DB 20 8D 00 .. | |
L14DE: .byte $76 ; 14DE 76 v | |
L14DF: bbs1 $4C,L1525 ; 14DF 9F 4C 43 .LC | |
tay ; 14E2 A8 . | |
jsr LAC08 ; 14E3 20 08 AC .. | |
bcs L150B ; 14E6 B0 23 .# | |
jsr SETPTRS ; 14E8 20 65 D6 e. | |
jsr L9A17 ; 14EB 20 17 9A .. | |
lda #$00 ; 14EE A9 00 .. | |
sta $24 ; 14F0 85 24 .$ | |
jmp BASWARM ; 14F2 4C 3F D4 L?. | |
; ---------------------------------------------------------------------------- | |
jsr LB531 ; 14F5 20 31 B5 1. | |
bcs L150B ; 14F8 B0 11 .. | |
L14FA: jsr LAC1F ; 14FA 20 1F AC .. | |
bcs L150B ; 14FD B0 0C .. | |
sty $6B ; 14FF 84 6B .k | |
sty $69 ; 1501 84 69 .i | |
sty $6D ; 1503 84 6D .m | |
stx $6C ; 1505 86 6C .l | |
stx $6A ; 1507 86 6A .j | |
stx $6E ; 1509 86 6E .n | |
L150B: rts ; 150B 60 ` | |
; ---------------------------------------------------------------------------- | |
lda #$01 ; 150C A9 01 .. | |
ldx #$FC ; 150E A2 FC .. | |
jsr LB1D3 ; 1510 20 D3 B1 .. | |
bcs L150B ; 1513 B0 F6 .. | |
L1515: lda #$D1 ; 1515 A9 D1 .. | |
jsr LBE70 ; 1517 20 70 BE p. | |
bcs L150B ; 151A B0 EF .. | |
lda $67 ; 151C A5 67 .g | |
sta $BED7 ; 151E 8D D7 BE ... | |
adc $BEC8 ; 1521 6D C8 BE m.. | |
.byte $8D ; 1524 8D . | |
L1525: cli ; 1525 58 X | |
ldx $68A5,y ; 1526 BE A5 68 ..h | |
sta $BED8 ; 1529 8D D8 BE ... | |
adc $BEC9 ; 152C 6D C9 BE m.. | |
sta $BE59 ; 152F 8D 59 BE .Y. | |
bcs L1536 ; 1532 B0 02 .. | |
cmp $74 ; 1534 C5 74 .t | |
L1536: lda #$0E ; 1536 A9 0E .. | |
bcs L150B ; 1538 B0 D1 .. | |
ldx $BEC8 ; 153A AE C8 BE ... | |
ldy $BEC9 ; 153D AC C9 BE ... | |
jsr LAFD7 ; 1540 20 D7 AF .. | |
bcs L150B ; 1543 B0 C6 .. | |
jsr LAFD3 ; 1545 20 D3 AF .. | |
bcs L150B ; 1548 B0 C1 .. | |
jsr LAC6B ; 154A 20 6B AC k. | |
ldx $BE59 ; 154D AE 59 BE .Y. | |
ldy $BE58 ; 1550 AC 58 BE .X. | |
stx $B0 ; 1553 86 B0 .. | |
sty $AF ; 1555 84 AF .. | |
rts ; 1557 60 ` | |
; ---------------------------------------------------------------------------- | |
sec ; 1558 38 8 | |
lda $67 ; 1559 A5 67 .g | |
sbc $BEB9 ; 155B ED B9 BE ... | |
sta $3C ; 155E 85 3C .< | |
lda $68 ; 1560 A5 68 .h | |
sbc $BEBA ; 1562 ED BA BE ... | |
sta $3D ; 1565 85 3D .= | |
ora $3C ; 1567 05 3C .< | |
clc ; 1569 18 . | |
beq L15B1 ; 156A F0 45 .E | |
ldx $67 ; 156C A6 67 .g | |
lda $68 ; 156E A5 68 .h | |
L1570: stx $3A ; 1570 86 3A .: | |
sta $3B ; 1572 85 3B .; | |
ldy #$01 ; 1574 A0 01 .. | |
lda ($3A),y ; 1576 B1 3A .: | |
dey ; 1578 88 . | |
ora ($3A),y ; 1579 11 3A .: | |
beq L15B1 ; 157B F0 34 .4 | |
lda ($3A),y ; 157D B1 3A .: | |
adc $3C ; 157F 65 3C e< | |
tax ; 1581 AA . | |
sta ($3A),y ; 1582 91 3A .: | |
iny ; 1584 C8 . | |
lda ($3A),y ; 1585 B1 3A .: | |
adc $3D ; 1587 65 3D e= | |
sta ($3A),y ; 1589 91 3A .: | |
clc ; 158B 18 . | |
bcc L1570 ; 158C 90 E2 .. | |
lda $BE57 ; 158E AD 57 BE .W. | |
and #$08 ; 1591 29 08 ). | |
clc ; 1593 18 . | |
beq L15B1 ; 1594 F0 1B .. | |
lda $BE68 ; 1596 AD 68 BE .h. | |
sta $50 ; 1599 85 50 .P | |
lda $BE69 ; 159B AD 69 BE .i. | |
sta $51 ; 159E 85 51 .Q | |
jsr FNDLIN ; 15A0 20 1A D6 .. | |
clc ; 15A3 18 . | |
lda $9B ; 15A4 A5 9B .. | |
adc #$FF ; 15A6 69 FF i. | |
sta $B8 ; 15A8 85 B8 .. | |
lda $9C ; 15AA A5 9C .. | |
adc #$FF ; 15AC 69 FF i. | |
sta $B9 ; 15AE 85 B9 .. | |
clc ; 15B0 18 . | |
L15B1: rts ; 15B1 60 ` | |
; ---------------------------------------------------------------------------- | |
bcc L15D6 ; 15B2 90 22 ." | |
lda #$FC ; 15B4 A9 FC .. | |
sta $BE6A ; 15B6 8D 6A BE .j. | |
sta $BEB8 ; 15B9 8D B8 BE ... | |
lda #$C3 ; 15BC A9 C3 .. | |
sta $BEB7 ; 15BE 8D B7 BE ... | |
lda $67 ; 15C1 A5 67 .g | |
sta $BEA5 ; 15C3 8D A5 BE ... | |
sta $BEB9 ; 15C6 8D B9 BE ... | |
lda $68 ; 15C9 A5 68 .h | |
sta $BEA6 ; 15CB 8D A6 BE ... | |
sta $BEBA ; 15CE 8D BA BE ... | |
jsr LAD50 ; 15D1 20 50 AD P. | |
bcs L161F ; 15D4 B0 49 .I | |
L15D6: lda #$02 ; 15D6 A9 02 .. | |
ldx #$FC ; 15D8 A2 FC .. | |
jsr LB1D3 ; 15DA 20 D3 B1 .. | |
bcs L161F ; 15DD B0 40 .@ | |
lda $AF ; 15DF A5 AF .. | |
sec ; 15E1 38 8 | |
sbc $67 ; 15E2 E5 67 .g | |
tax ; 15E4 AA . | |
sta $BEC8 ; 15E5 8D C8 BE ... | |
lda $B0 ; 15E8 A5 B0 .. | |
sbc $68 ; 15EA E5 68 .h | |
tay ; 15EC A8 . | |
sta $BEC9 ; 15ED 8D C9 BE ... | |
lda #$00 ; 15F0 A9 00 .. | |
sta $BECA ; 15F2 8D CA BE ... | |
lda $67 ; 15F5 A5 67 .g | |
sta $BED7 ; 15F7 8D D7 BE ... | |
lda $68 ; 15FA A5 68 .h | |
sta $BED8 ; 15FC 8D D8 BE ... | |
.byte $20 ; 15FF 20 | |
.endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The rest, that is assumed to be junk is where the driver works through directory block data. The memory will be overwritten and in the original was all zeros.