diff --git a/nsc.s b/nsc.s new file mode 100644 index 0000000..9984fdd --- /dev/null +++ b/nsc.s @@ -0,0 +1,865 @@ +; 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+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 #) 8 + ; try internal $C100-$CFFF ROM + ; modify driver to save CX ROM status, enable it, and restore it + lda #>INTCXROM + ldy #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