
 1000         .TI 76,PRODOS F800-FFFF.....COMMENTED BY RBS-C  11-8-83............
 1010  *SAVE S.PRODOS F800-FFFF
 1020  *--------------------------------
 1030  RUNNING.SUM        .EQ $3A
 1040  TBUF.0             .EQ $3A
 1050  BYTE.AT.BUF00      .EQ $3B
 1060  BYTE.AT.BUF01      .EQ $3C
 1070  LAST.BYTE          .EQ $3D
 1080  SLOT.X16           .EQ $3E
 1090  INDEX.OF.LAST.BYTE .EQ $3F
 1100  *--------------------------------
 1110  RWB.COMMAND .EQ $42
 1120  RWB.SLOT    .EQ $43   DSSSXXXX
 1130  RWB.BUFFER  .EQ $44,45
 1140  RWB.BLOCK   .EQ $46,47   0...279
 1150  *--------------------------------
 1160  BUFF.BASE .EQ $4700 DUMMY ADDRESS FOR ASSEMBLY ONLY
 1170  *--------------------------------
 1180  SAVE.LOC45 .EQ $BF56
 1190  SAVE.D000  .EQ $BF57
 1200  INTAREG    .EQ $BF88
 1210  INTBANKID  .EQ $BF8D
 1220  IRQXIT.3   .EQ $BFD3
 1230  *--------------------------------
 1240  DRV.PHASE  .EQ $C080
 1250  DRV.MTROFF .EQ $C088
 1260  DRV.MTRON  .EQ $C089
 1270  DRV.ENBL.0 .EQ $C08A
 1280  DRV.Q6L    .EQ $C08C
 1290  DRV.Q6H    .EQ $C08D
 1300  DRV.Q7L    .EQ $C08E
 1310  DRV.Q7H    .EQ $C08F
 1320  *--------------------------------
 1330  *                 <<<COMPUTED >>>
 1340  MODIFIER .EQ $60  <<<SLOT * 16>>>
 1350  *--------------------------------
 1360         .OR $F800
 1370         .TA $800
 1380  *--------------------------------
 1390  *      READ/WRITE A BLOCK
 1400  *
 1410  *      1.  ASSURE VALID BLOCK NUMBER (0...279)
 1420  *      2.  CONVERT BLOCK NUMBER TO TRACK/SECTOR
 1430  *          TRACK = INT(BLOCK/8)
 1440  *          BLOCK   SECTORS
 1450  *          -----  ---------
 1460  *            0     0 AND 2
 1470  *            1     4 AND 6
 1480  *            2     8 AND 10
 1490  *            3    12 AND 14
 1500  *            4     1 AND 3
 1510  *            5     5 AND 7
 1520  *            6     9 AND 11
 1530  *            7    13 AND 15
 1540  *      3.  CALL RWTS TWICE
 1550  *      4.  RETURN WITH ERROR STATUS
 1560  *--------------------------------
 1570  RWB
 1580         LDA RWB.BLOCK     BLOCK MUST BE 0...279
 1590         LDX RWB.BLOCK+1
 1600         STX RWTS.TRACK
 1610         BEQ .1       ...BLOCK # LESS THAN 256
 1620         DEX
 1630         BNE .5       ...BLOCK # MORE THAN 511
 1640         CMP #$18
 1650         BCS .5       ...BLOCK # MORE THAN 279
 1660  .1     LDY #5       SHIFT 5 BITS OF TRACK # 
 1670  .2     ASL              RWTS.TRACK   A-REG
 1680         ROL RWTS.TRACK   ----------   --------
 1690         DEY               00TTTTTT    ABC00000
 1700         BNE .2
 1710         ASL          TRANSFORM BLOCK # INTO SECTOR #
 1720         BCC .3       ABC00000 --> 0000BC0A
 1730         ORA #$10
 1740  .3     LSR
 1750         LSR
 1760         LSR
 1770         LSR
 1780         PHA
 1790         JSR RWTS     R/W FIRST SECTOR OF BLOCK
 1800         PLA
 1810         BCS .4       ...ERROR
 1820         INC RWB.BUFFER+1  
 1830         ADC #2
 1840         JSR RWTS     R/W SECOND SECTOR OF BLOCK
 1850         DEC RWB.BUFFER+1  
 1860  .4     LDA RWTS.ERROR
 1870         RTS
 1880  *---BLOCK NUMBER > 279-----------
 1890  .5     LDA #$27     I/O ERROR
 1900         SEC
 1910         RTS
 1920  *--------------------------------
 1930  *      READ/WRITE A GIVEN SECTOR
 1940  *--------------------------------
 1950  RWTS
 1960         LDY #1       TRY SEEKING TWICE
 1970         STY SEEK.COUNT
 1980         STA RWTS.SECTOR
 1990         LDA RWB.SLOT  
 2000         AND #$70     0SSS0000
 2010         STA SLOT.X16  
 2020         JSR WAIT.FOR.OLD.MOTOR.TO.STOP
 2030         JSR CHECK.IF.MOTOR.RUNNING
 2040         PHP          SAVE ANSWER (.NE. IF RUNNING)
 2050         LDA #$E8     MOTOR STARTING TIME
 2060         STA MOTOR.TIME+1  ONLY HI-BYTE NECESSARY
 2070         LDA RWB.SLOT      SAME SLOT AND DRIVE?
 2080         CMP OLD.SLOT
 2090         STA OLD.SLOT
 2100         PHP               SAVE ANSWER
 2110         ASL               DRIVE # TO C-BIT
 2120         LDA DRV.MTRON,X   START MOTOR
 2130         BCC .1            ...DRIVE 0
 2140         INX               ...DRIVE 1
 2150  .1     LDA DRV.ENBL.0,X  ENABLE DRIVE X
 2160         PLP               SAME SLOT/DRIVE?
 2170         BEQ .3            ...YES
 2180         PLP          DISCARD ANSWER ABOUT MOTOR GOING
 2190         LDY #7       DELAY 150-175 MILLISECS
 2200  .2     JSR DELAY.100     DELAY 25 MILLISECS
 2210         DEY
 2220         BNE .2
 2230         PHP          SAY MOTOR NOT ALREADY GOING
 2240  .3     LDA RWB.COMMAND   0=TEST, 1=READ, 2=WRITE
 2250         BEQ .4            ...0, MERELY TEST
 2260         LDA RWTS.TRACK
 2270         JSR SEEK.TRACK
 2280  .4     PLP          WAS MOTOR ALREADY GOING?
 2290         BNE .6       ...YES
 2300  .5     LDA #1       DELAY 100 USECS
 2310         JSR DELAY.100
 2320         LDA MOTOR.TIME+1
 2330         BMI .5       ...WAIT TILL IT OUGHT TO BE
 2340         JSR CHECK.IF.MOTOR.RUNNING
 2350         BEQ .14      ...NOT RUNNING YET, ERROR
 2360  .6     LDA RWB.COMMAND  
 2370         BEQ .17      CHECK IF WRITE PROTECTED
 2380         LSR          .CS. IF READ, .CC. IF WRITE
 2390         BCS .7       ...READ
 2400         JSR PRE.NYBBLE   ...WRITE
 2410  .7     LDY #64      TRY 64 TIMES TO FIND THE SECTOR
 2420         STY SEARCH.COUNT
 2430  .8     LDX SLOT.X16  
 2440         JSR READ.ADDRESS
 2450         BCC .10      ...FOUND IT
 2460  .9     DEC SEARCH.COUNT
 2470         BPL .8       ...KEEP LOOKING
 2480         LDA #$27     I/O ERROR CODE
 2490         DEC SEEK.COUNT   ANY TRIES LEFT?
 2500         BNE .14      ...NO, I/O ERROR
 2510         LDA CURRENT.TRACK
 2520         PHA
 2530         ASL          SLIGHT RE-CALIBRATION
 2540         ADC #$10
 2550         LDY #64      ANOTHER 64 TRIES
 2560         STY SEARCH.COUNT
 2570         BNE .11      ...ALWAYS
 2580  .10    LDY HDR.TRACK     ACTUAL TRACK FOUND
 2590         CPY CURRENT.TRACK
 2600         BEQ .12           FOUND THE RIGHT ONE
 2610         LDA CURRENT.TRACK WRONG ONE, TRY AGAIN
 2620         PHA
 2630         TYA          STARTING FROM TRACK FOUND
 2640         ASL
 2650  .11    JSR UPDATE.TRACK.TABLE
 2660         PLA
 2670         JSR SEEK.TRACK
 2680         BCC .8       ...ALWAYS
 2690  .12    LDA HDR.SECTOR
 2700         CMP RWTS.SECTOR
 2710         BNE .9
 2720         LDA RWB.COMMAND  
 2730         LSR
 2740         BCC .15           ...WRITE
 2750         JSR READ.SECTOR   ...READ
 2760         BCS .9            ...READ ERROR
 2770  .13    LDA #0       NO ERROR
 2780         .HS D0       "BNE"...NEVER, JUST SKIPS "SEC"
 2790  .14    SEC          ERROR
 2800         STA RWTS.ERROR    SAVE ERROR CODE
 2810         LDA DRV.MTROFF,X  STOP MOTOR
 2820         RTS               RETURN
 2830  *--------------------------------
 2840  .15    JSR WRITE.SECTOR
 2850  .16    BCC .13      ...NO ERROR
 2860         LDA #$2B     WRITE PROTECTED ERROR CODE
 2870         BNE .14      ...ALWAYS
 2880  .17    LDX SLOT.X16 CHECK IF WRITE PROTECTED
 2890         LDA DRV.Q6H,X
 2900         LDA DRV.Q7L,X
 2910         ROL
 2920         LDA DRV.Q6L,X
 2930         JMP .16      GIVE ERROR IF PROTECTED
 2940  *--------------------------------
 2950  SEEK.TRACK
 2960         ASL          GET PHYSICAL TRACK #
 2970         STA HDR.TRACK     ...SAVE HERE
 2980         JSR CLEAR.PHASES  (CARRY WAS CLEAR)
 2990         JSR GET.SSSD.IN.X
 3000         LDA OLD.TRACK.TABLE,X
 3010         STA CURRENT.TRACK
 3020         LDA HDR.TRACK
 3030         STA OLD.TRACK.TABLE,X
 3040         JSR SEEK.TRACK.ABSOLUTE
 3050  *--------------------------------
 3060  CLEAR.PHASES
 3070         LDY #3
 3080  .1     TYA
 3090         JSR PHASE.COMMANDER
 3100         DEY
 3110         BPL .1
 3120         LSR CURRENT.TRACK    BACK TO LOGICAL TRACK #
 3130         CLC          SIGNAL NO ERROR
 3140         RTS
 3150  *--------------------------------
 3160  SEEK.TRACK.ABSOLUTE
 3170         STA TARGET.TRACK  SAVE ACTUAL TRACK #
 3180         CMP CURRENT.TRACK ALREADY THERE?
 3190         BEQ .7            ...YES
 3200         LDA #0
 3210         STA STEP.CNT      # STEPS SO FAR
 3220  .1     LDA CURRENT.TRACK
 3230         STA CURRENT.TRACK.OLD
 3240         SEC
 3250         SBC TARGET.TRACK
 3260         BEQ .6            ...WE HAVE ARRIVED
 3270         BCS .2            CURRENT > DESIRED
 3280         EOR #$FF          CURRENT < DESIRED
 3290         INC CURRENT.TRACK
 3300         BCC .3            ...ALWAYS
 3310  .2     ADC #$FE          .CS., SO A=A-1
 3320         DEC CURRENT.TRACK
 3330  .3     CMP STEP.CNT GET MINIMUM OF:
 3340         BCC .4         1. # OF TRACKS TO MOVE LESS 1
 3350         LDA STEP.CNT   2. # OF STEPS SO FAR
 3360  .4     CMP #9         3. EIGHT
 3370         BCS .5
 3380         TAY
 3390         SEC          TURN NEW PHASE ON
 3400  .5     JSR .7
 3410         LDA ONTBL,Y  DELAY
 3420         JSR DELAY.100
 3430         LDA CURRENT.TRACK.OLD
 3440         CLC          TURN OLD PHASE OFF
 3450         JSR PHASE.COMMANDER
 3460         LDA OFFTBL,Y DELAY
 3470         JSR DELAY.100
 3480         INC STEP.CNT # OF STEPS SO FAR
 3490         BNE .1       ...ALWAYS
 3500  .6     JSR DELAY.100
 3510         CLC          TURN PHASE OFF
 3520  .7     LDA CURRENT.TRACK
 3530  *--------------------------------
 3540  *      (A) = TRACK #
 3550  *      .CC. THEN PHASE OFF
 3560  *      .CS. THEN PHASE ON
 3570  *--------------------------------
 3580  PHASE.COMMANDER
 3590         AND #3       ONLY KEEP LOWER TWO BITS
 3600         ROL               00000XXC
 3610         ORA SLOT.X16      0SSS0XXC
 3620         TAX
 3630         LDA DRV.PHASE,X
 3640         LDX SLOT.X16      RESTORE SLOT*16
 3650         RTS
 3660  *--------------------------------
 3670  *      VALUE READ FROM DISK IS INDEX INTO THIS TABLE
 3680  *      TABLE ENTRY GIVES TOP 6 BITS OF ACTUAL DATA
 3690  *
 3700  *      OTHER DATA TABLES ARE IMBEDDED IN THE UNUSED
 3710  *      PORTIONS OF THE BYTE.TABLE
 3720  *--------------------------------
 3730  BYTE.TABLE .EQ *-$96
 3740         .HS 0004FFFF080CFF101418
 3750  BIT.PAIR.LEFT
 3760         .HS 008040C0
 3770         .HS FFFF1C20FFFFFF24282C
 3780         .HS 3034FFFF383C4044
 3790         .HS 484CFF5054585C606468
 3800  BIT.PAIR.MIDDLE
 3810         .HS 00201030
 3820  DATA.TRAILER
 3830         .HS DEAAEBFF
 3840         .HS FFFFFF6CFF70
 3850         .HS 7478FFFFFF7CFFFF
 3860         .HS 8084FF888C9094989CA0
 3870  BIT.PAIR.RIGHT
 3880         .HS 0008040C
 3890         .HS FFA4A8ACFFB0B4B8BCC0
 3900         .HS C4C8FFFFCCD0D4D8
 3910         .HS DCE0FFE4E8ECF0F4
 3920         .HS F8FC
 3930  *--------------------------------
 3940  BIT.PAIR.TABLE
 3950         .HS 00000096
 3960         .HS 02000097
 3970         .HS 0100009A
 3980         .HS 0300009B
 3990         .HS 0002009D
 4000         .HS 0202009E
 4010         .HS 0102009F
 4020         .HS 030200A6
 4030         .HS 000100A7
 4040         .HS 020100AB
 4050         .HS 010100AC
 4060         .HS 030100AD
 4070         .HS 000300AE
 4080         .HS 020300AF
 4090         .HS 010300B2
 4100         .HS 030300B3
 4110         .HS 000002B4
 4120         .HS 020002B5
 4130         .HS 010002B6
 4140         .HS 030002B7
 4150         .HS 000202B9
 4160         .HS 020202BA
 4170         .HS 010202BB
 4180         .HS 030202BC
 4190         .HS 000102BD
 4200         .HS 020102BE
 4210         .HS 010102BF
 4220         .HS 030102CB
 4230         .HS 000302CD
 4240         .HS 020302CE
 4250         .HS 010302CF
 4260         .HS 030302D3
 4270         .HS 000001D6
 4280         .HS 020001D7
 4290         .HS 010001D9
 4300         .HS 030001DA
 4310         .HS 000201DB
 4320         .HS 020201DC
 4330         .HS 010201DD
 4340         .HS 030201DE
 4350         .HS 000101DF
 4360         .HS 020101E5
 4370         .HS 010101E6
 4380         .HS 030101E7
 4390         .HS 000301E9
 4400         .HS 020301EA
 4410         .HS 010301EB
 4420         .HS 030301EC
 4430         .HS 000003ED
 4440         .HS 020003EE
 4450         .HS 010003EF
 4460         .HS 030003F2
 4470         .HS 000203F3
 4480         .HS 020203F4
 4490         .HS 010203F5
 4500         .HS 030203F6
 4510         .HS 000103F7
 4520         .HS 020103F9
 4530         .HS 010103FA
 4540         .HS 030103FB
 4550         .HS 000303FC
 4560         .HS 020303FD
 4570         .HS 010303FE
 4580         .HS 030303FF
 4590  *--------------------------------
 4600  TBUF   .BS 86
 4610  *--------------------------------
 4620  RWTS.TRACK    .HS 07
 4630  RWTS.SECTOR   .HS 0F
 4640  RWTS.ERROR    .HS 00
 4650  OLD.SLOT      .HS 60
 4660  CURRENT.TRACK .HS 07
 4670                .HS 00
 4680  *--------------------------------
 4690  OLD.TRACK.TABLE .EQ *-4
 4700         .HS 0000     SLOT 2, DRIVE 0--DRIVE 1
 4710         .HS 0000     SLOT 3
 4720         .HS 0000     SLOT 4
 4730         .HS 0000     SLOT 5
 4740         .HS 0E00     SLOT 6
 4750         .HS 0000     SLOT 7
 4760  *--------------------------------
 4770         .HS 00
 4780  *--------------------------------
 4790  SEARCH.COUNT      .BS 1
 4800  SEEK.COUNT        .BS 1
 4810  STEP.CNT      .EQ *
 4820  SEEK.D5.CNT   .EQ * 
 4830  X1X1X1X1          .BS 1   ALSO STEP.CNT & SEEK.D5.CNT
 4840  CHECK.SUM         .BS 1
 4850  HDR.CHKSUM        .BS 1
 4860  HDR.SECTOR        .BS 1
 4870  HDR.TRACK     .EQ *
 4880  MOTOR.TIME        .BS 2   ALSO HDR.TRACK & HDR.VOLUME
 4890  CURRENT.TRACK.OLD .BS 1
 4900  TARGET.TRACK      .BS 1
 4910  *--------------------------------
 4920  *      DELAY TIMES FOR ACCELERATION & DECELERATION
 4930  *      OF TRACK STEPPING MOTOR
 4940  *--------------------------------
 4950  ONTBL  .HS 01302824201E1D1C1C
 4960  OFFTBL .HS 702C26221F1E1D1C1C 
 4970  *--------------------------------
 4980  *      DELAY ABOUT 100*A MICROSECONDS
 4990  *      RUN DOWN MOTOR.TIME WHILE DELAYING
 5000  *--------------------------------
 5010  DELAY.100
 5020  .1     LDX #17
 5030  .2     DEX
 5040         BNE .2
 5050         INC MOTOR.TIME
 5060         BNE .3
 5070         INC MOTOR.TIME+1
 5080  .3     SEC
 5090         SBC #1
 5100         BNE .1
 5110         RTS
 5120  *--------------------------------
 5130  READ.ADDRESS
 5140         LDY #$FC     TRY 772 TIMES TO FIND $D5
 5150         STY SEEK.D5.CNT        (FROM $FCFC TO $10000)
 5160  .1     INY
 5170         BNE .2       ...KEEP TRYING
 5180         INC SEEK.D5.CNT
 5190         BEQ .11      ...THAT IS ENUF!
 5200  .2     LDA DRV.Q6L,X     GET NEXT BYTE
 5210         BPL .2
 5220  .3     CMP #$D5     IS IT $D5?
 5230         BNE .1       ...NO, TRY AGAIN
 5240         NOP          ...YES, DELAY
 5250  .4     LDA DRV.Q6L,X     GET NEXT BYTE
 5260         BPL .4
 5270         CMP #$AA     NOW NEED $AA AND $96
 5280         BNE .3       ...NO, BACK TO $D5 SEARCH
 5290         LDY #3       (READ 3 BYTES LATER)
 5300  .5     LDA DRV.Q6L,X     GET NEXT BYTE
 5310         BPL .5
 5320         CMP #$96     BETTER BE...
 5330         BNE .3       ...IT IS NOT
 5340         SEI          ...NO INTERRUPTS NOW
 5350         LDA #0       START CHECK SUM
 5360  .6     STA CHECK.SUM
 5370  .7     LDA DRV.Q6L,X     GET NEXT BYTE
 5380         BPL .7       1X1X1X1X
 5390         ROL          X1X1X1X1
 5400         STA X1X1X1X1
 5410  .8     LDA DRV.Q6L,X     GET NEXT BYTE
 5420         BPL .8       1Y1Y1Y1Y
 5430         AND X1X1X1X1   XYXYXYXY
 5440         STA HDR.CHKSUM,Y
 5450         EOR CHECK.SUM
 5460         DEY
 5470         BPL .6
 5480         TAY          CHECK CHECKSUM
 5490         BNE .11      NON-ZERO, ERROR
 5500  .9     LDA DRV.Q6L,X     GET NEXT BYTE
 5510         BPL .9
 5520         CMP #$DE     TRAILER EXPECTED $DE.AA.EB
 5530         BNE .11      NO, ERROR
 5540         NOP
 5550  .10    LDA DRV.Q6L,X
 5560         BPL .10
 5570         CMP #$AA
 5580         BNE .11      NO, ERROR
 5590         CLC
 5600         RTS
 5610  .11    SEC
 5620         RTS
 5630  *--------------------------------
 5640  READ.SECTOR
 5650         TXA          SLOT*16 ($60 FOR SLOT 6)
 5660         ORA #$8C     BUILD Q6L ADDRESS FOR SLOT
 5670         STA .9+1     STORE INTO READ-DISK OPS
 5680         STA .12+1
 5690         STA .13+1
 5700         STA .15+1
 5710         STA .18+1
 5720         LDA RWB.BUFFER    PLUG CALLER'S BUFFER
 5730         LDY RWB.BUFFER+1  ADDRESS INTO STORE'S
 5740         STA .17+1    PNTR FOR LAST THIRD
 5750         STY .17+2
 5760         SEC          PNTR FOR MIDDLE THIRD
 5770         SBC #84
 5780         BCS .1
 5790         DEY
 5800  .1     STA .14+1
 5810         STY .14+2
 5820         SEC          PNTR FOR BOTTOM THIRD
 5830         SBC #87
 5840         BCS .2
 5850         DEY
 5860  .2     STA .11+1
 5870         STY .11+2
 5880  *---FIND $D5.AA.AD HEADER--------
 5890         LDY #32      MUST FIND $D5 WITHIN 32 BYTES
 5900  .3     DEY
 5910         BEQ .10      ERROR RETURN
 5920  .4     LDA DRV.Q6L,X
 5930         BPL .4
 5940  .5     EOR #$D5
 5950         BNE .3
 5960         NOP
 5970  .6     LDA DRV.Q6L,X
 5980         BPL .6
 5990         CMP #$AA
 6000         BNE .5
 6010         NOP
 6020  .7     LDA DRV.Q6L,X
 6030         BPL .7
 6040         CMP #$AD
 6050         BNE .5
 6060  *---READ 86 BYTES INTO TBUF...TBUF+85----------
 6070  *---THESE ARE THE PACKED LOWER TWO BITS--------
 6080  *---FROM EACH BYTE OF THE CALLER'S BUFFER.-----
 6090         LDY #170
 6100         LDA #0       INIT RUNNING EOR-SUM
 6110  .8     STA RUNNING.SUM  
 6120  .9     LDX DRV.Q6L+MODIFIER  READ NEXT BYTE
 6130         BPL .9
 6140         LDA BYTE.TABLE,X      DECODE DATA
 6150         STA TBUF-170,Y
 6160         EOR RUNNING.SUM  
 6170         INY
 6180         BNE .8
 6190  *---READ NEXT 86 BYTES-------------------------
 6200  *---STORE 1ST 85 IN BUFFER...BUFFER+84---------
 6210  *---SAVE THE 86TH BYTE ON THE STACK------------
 6220         LDY #170
 6230         BNE .12      ...ALWAYS
 6240  *--
 6250  .10    SEC          I/O ERROR EXIT
 6260         RTS
 6270  *--
 6280  .11    STA BUFF.BASE-171,Y
 6290  .12    LDX DRV.Q6L+MODIFIER  READ NEXT BYTE
 6300         BPL .12   
 6310         EOR BYTE.TABLE,X      DECODE DATA
 6320         LDX TBUF-170,Y        MERGE LOWER 2 BITS
 6330         EOR BIT.PAIR.TABLE,X
 6340         INY
 6350         BNE .11
 6360         PHA          SAVE LAST BYTE (LATER BUFFER+85)
 6370  *---READ NEXT 86 BYTES-----------
 6380  *---STORE AT BUFFER+86...BUFFER+171------------
 6390         AND #$FC              MASK FOR RUNNING EOR.SUM
 6400         LDY #170
 6410  .13    LDX DRV.Q6L+MODIFIER  READ NEXT BYTE
 6420         BPL .13   
 6430         EOR BYTE.TABLE,X      DECODE DATA
 6440         LDX TBUF-170,Y        MERGE LOWER 2 BITS
 6450         EOR BIT.PAIR.TABLE+1,X
 6460  .14    STA BUFF.BASE-84,Y
 6470         INY
 6480         BNE .13   
 6490  *---READ NEXT 84 BYTES-------------------------
 6500  *---INTO BUFFER+172...BUFFER+255---------------
 6510  .15    LDX DRV.Q6L+MODIFIER  READ NEXT BYTE
 6520         BPL .15   
 6530         AND #$FC
 6540         LDY #172
 6550  .16    EOR BYTE.TABLE,X      DECODE DATA
 6560         LDX TBUF-172,Y        MERGE LOWER 2 BITS
 6570         EOR BIT.PAIR.TABLE+2,X
 6580  .17    STA BUFF.BASE,Y
 6590  .18    LDX DRV.Q6L+MODIFIER  READ NEXT BYTE
 6600         BPL .18   
 6610         INY
 6620         BNE .16   
 6630         AND #$FC
 6640  *---END OF DATA------------------
 6650         EOR BYTE.TABLE,X      DECODE DATA
 6660         BNE .20           ...BAD CHECKSUM
 6670         LDX SLOT.X16      CHECK FOR TRAILER $DE
 6680  .19    LDA DRV.Q6L,X
 6690         BPL .19   
 6700         CMP #$DE
 6710         CLC
 6720         BEQ .21           ...GOOD READ!
 6730  .20    SEC               ...SIGNAL BAD READ
 6740  .21    PLA               STORE BYTE AT BUFFER+85
 6750         LDY #85
 6760         STA (RWB.BUFFER),Y
 6770         RTS
 6780  *--------------------------------
 6790  UPDATE.TRACK.TABLE
 6800         JSR GET.SSSD.IN.X
 6810         STA OLD.TRACK.TABLE,X
 6820         RTS
 6830  *--------------------------------
 6840  CHECK.IF.MOTOR.RUNNING
 6850         LDX SLOT.X16  
 6860  CHECK.IF.MOTOR.RUNNING.X
 6870         LDY #0
 6880  .1     LDA DRV.Q6L,X     READ CURRENT INPUT REGISTER
 6890         JSR .2            ...12 CYCLES...
 6900         PHA               ...7 MORE CYCLES...
 6910         PLA
 6920         CMP DRV.Q6L,X     BY NOW INPUT REGISTER
 6930         BNE .2            SHOULD HAVE CHANGED
 6940         LDA #$28     ERROR CODE: NO DEVICE CONNECTED
 6950         DEY          BUT TRY 255 MORE TIMES
 6960         BNE .1       ...RETURN .NE. IF MOVING...
 6970  .2     RTS          ...RETURN .EQ. IF NOT MOVING...
 6980  *--------------------------------
 6990  GET.SSSD.IN.X
 7000         PHA          SAVE A-REG
 7010         LDA RWB.SLOT     DSSSXXXX
 7020         LSR
 7030         LSR
 7040         LSR
 7050         LSR          0000DSSS
 7060         CMP #8       SET CARRY IF DRIVE 2
 7070         AND #7       00000SSS
 7080         ROL          0000SSSD
 7090         TAX          INTO X-REG
 7100         PLA          RESTORE A-REG
 7110         RTS
 7120  *--------------------------------
 7130  WRITE.SECTOR
 7140         SEC          IN CASE WRITE-PROTECTED
 7150         LDA DRV.Q6H,X
 7160         LDA DRV.Q7L,X
 7170         BPL .1       ...NOT WRITE PROTECTED
 7180         JMP WS.RET   ...PROTECTED, ERROR
 7190  *--------------------------------
 7200  .1     LDA TBUF
 7210         STA TBUF.0  
 7220  *---WRITE 5 SYNC BYTES-----------
 7230         LDA #$FF
 7240         STA DRV.Q7H,X
 7250         ORA DRV.Q6L,X
 7260         LDY #4
 7270         NOP          $FF AT 40-CYCLE INTERVALS LEAVES
 7280         PHA          TWO ZERO-BITS AFTER EACH $FF
 7290         PLA
 7300  .2     PHA
 7310         PLA
 7320         JSR WRITE2
 7330         DEY
 7340         BNE .2
 7350  *---WRITE $D5 AA AD HEADER-------
 7360         LDA #$D5
 7370         JSR WRITE1
 7380         LDA #$AA
 7390         JSR WRITE1
 7400         LDA #$AD
 7410         JSR WRITE1
 7420  *---WRITE 86 BYTES FROM TBUF-------------------
 7430  *---BACKWARDS:   TBUF+85...TBUF+1, TBUF.0------
 7440         TYA          =0
 7450         LDY #86
 7460         BNE .4
 7470  .3     LDA TBUF,Y
 7480  .4     EOR TBUF-1,Y
 7490         TAX
 7500         LDA BIT.PAIR.TABLE+3,X
 7510         LDX SLOT.X16  
 7520         STA DRV.Q6H,X
 7530         LDA DRV.Q6L,X
 7540         DEY
 7550         BNE .3
 7560         LDA TBUF.0  
 7570  *---WRITE PORTION OF BUFFER------
 7580  *---UP TO A PAGE BOUNDARY--------
 7590         LDY #*-*     FILLED IN WITH LO-BYTE OF BUFFER ADDRESS
 7600  WS...5 EOR BUFF.BASE,Y   HI-BYTE FILLED IN
 7610         AND #$FC
 7620         TAX
 7630         LDA BIT.PAIR.TABLE+3,X
 7640  WS...6 LDX #MODIFIER
 7650         STA DRV.Q6H,X
 7660         LDA DRV.Q6L,X
 7670  WS...7 LDA BUFF.BASE,Y   HI-BYTE FILLED IN
 7680         INY
 7690         BNE WS...5
 7700  *---BRANCH ACCORDING TO BUFFER BOUNDARY CONDITIONS-----
 7710         LDA BYTE.AT.BUF00  
 7720         BEQ WS..17   ...BUFFER ALL IN ONE PAGE
 7730         LDA INDEX.OF.LAST.BYTE  
 7740         BEQ WS..16   ...ONLY ONE BYTE IN NEXT PAGE
 7750  *---MORE THAN ONE BYTE IN NEXT PAGE--------------------
 7760         LSR          ...DELAY TWO CYCLES
 7770         LDA BYTE.AT.BUF00  PRE.NYBBLE ALREADY ENCODED
 7780         STA DRV.Q6H,X      THIS BYTE
 7790         LDA DRV.Q6L,X
 7800         LDA BYTE.AT.BUF01  
 7810         NOP
 7820         INY
 7830         BCS WS..12
 7840  WS...8 EOR BUFF.BASE+256,Y    HI-BYTE FILLED IN
 7850         AND #$FC
 7860         TAX
 7870         LDA BIT.PAIR.TABLE+3,X
 7880  WS...9 LDX #MODIFIER
 7890         STA DRV.Q6H,X
 7900         LDA DRV.Q6L,X
 7910  WS..10 LDA BUFF.BASE+256,Y    HI-BYTE FILLED IN
 7920         INY
 7930  WS..11 EOR BUFF.BASE+256,Y    HI-BYTE FILLED IN
 7940  WS..12 CPY INDEX.OF.LAST.BYTE  
 7950         AND #$FC
 7960         TAX
 7970         LDA BIT.PAIR.TABLE+3,X
 7980  WS..13 LDX #MODIFIER
 7990         STA DRV.Q6H,X
 8000         LDA DRV.Q6L,X
 8010  WS..14 LDA BUFF.BASE+256,Y    HI-BYTE FILLED IN
 8020         INY
 8030         BCC WS...8
 8040         BCS .15      ...3 CYCLE NOP
 8050  .15    BCS WS..17   ...ALWAYS
 8060  *---WRITE BYTE AT BUFFER.00---------------------------
 8070  WS..16 .DA #$AD,BYTE.AT.BUF00    4 CYCLES: LDA BYTE.AT.BUF00
 8080         STA DRV.Q6H,X
 8090         LDA DRV.Q6L,X
 8100         PHA
 8110         PLA
 8120         PHA
 8130         PLA
 8140  WS..17 LDX LAST.BYTE  
 8150         LDA BIT.PAIR.TABLE+3,X
 8160  WS..18 LDX #MODIFIER
 8170         STA DRV.Q6H,X
 8180         LDA DRV.Q6L,X
 8190         LDY #0
 8200         PHA
 8210         PLA
 8220  *---WRITE DATA TRAILER:  $DE AA EB FF----------
 8230         NOP
 8240         NOP
 8250  .19    LDA DATA.TRAILER,Y
 8260         JSR WRITE3
 8270         INY
 8280         CPY #4
 8290         BNE .19
 8300         CLC          SIGNAL NO ERROR
 8310  WS.RET LDA DRV.Q7L,X     DRIVE TO SAFE MODE
 8320         LDA DRV.Q6L,X
 8330         RTS
 8340  *--------------------------------
 8350  WRITE1 CLC
 8360  WRITE2 PHA
 8370         PLA
 8380  WRITE3 STA DRV.Q6H,X
 8390         ORA DRV.Q6L,X
 8400         RTS
 8410  *--------------------------------
 8420  PRE.NYBBLE
 8430         LDA RWB.BUFFER    PLUG IN ADDRESS TO LOOP BELOW
 8440         LDY RWB.BUFFER+1  
 8450         CLC
 8460         ADC #2
 8470         BCC .1
 8480         INY
 8490  .1     STA PN...6+1
 8500         STY PN...6+2
 8510         SEC
 8520         SBC #$56
 8530         BCS .2
 8540         DEY
 8550  .2     STA PN...5+1
 8560         STY PN...5+2
 8570         SEC
 8580         SBC #$56
 8590         BCS .3
 8600         DEY
 8610  .3     STA PN...4+1
 8620         STY PN...4+2
 8630  *---PACK THE LOWER TWO BITS INTO TBUF-------------
 8640         LDY #170
 8650  PN...4 LDA BUFF.BASE-170,Y   ADDRESS FILLED IN
 8660         AND #3
 8670         TAX
 8680         LDA BIT.PAIR.RIGHT,X
 8690         PHA
 8700  PN...5 LDA BUFF.BASE-84,Y
 8710         AND #3
 8720         TAX
 8730         PLA
 8740         ORA BIT.PAIR.MIDDLE,X
 8750         PHA
 8760  PN...6 LDA BUFF.BASE+2,Y
 8770         AND #3
 8780         TAX
 8790         PLA
 8800         ORA BIT.PAIR.LEFT,X
 8810         PHA
 8820         TYA
 8830         EOR #$FF
 8840         TAX
 8850         PLA
 8860         STA TBUF,X
 8870         INY
 8880         BNE PN...4
 8890  *---DETERMINE BUFFER BOUNDARY CONDITIONS----------
 8900  *---AND SETUP WRITE.SECTOR ACCORDINGLY------------
 8910         LDY RWB.BUFFER  
 8920         DEY
 8930         STY INDEX.OF.LAST.BYTE  
 8940         LDA RWB.BUFFER  
 8950         STA WS...5-1
 8960         BEQ .7
 8970         EOR #$FF
 8980         TAY
 8990         LDA (RWB.BUFFER),Y
 9000         INY
 9010         EOR (RWB.BUFFER),Y
 9020         AND #$FC
 9030         TAX
 9040         LDA BIT.PAIR.TABLE+3,X
 9050  .7     STA BYTE.AT.BUF00    =0 IF BUFFER NOT SPLIT
 9060         BEQ .9
 9070         LDA INDEX.OF.LAST.BYTE  
 9080         LSR
 9090         LDA (RWB.BUFFER),Y
 9100         BCC .8
 9110         INY
 9120         EOR (RWB.BUFFER),Y
 9130  .8     STA BYTE.AT.BUF01  
 9140  .9     LDY #$FF
 9150         LDA (RWB.BUFFER),Y
 9160         AND #$FC
 9170         STA LAST.BYTE  
 9180  *---INSTALL BUFFER ADDRESSES IN WRITE.SECTOR------
 9190         LDY RWB.BUFFER+1  
 9200         STY WS...5+2
 9210         STY WS...7+2
 9220         INY
 9230         STY WS...8+2
 9240         STY WS..10+2
 9250         STY WS..11+2
 9260         STY WS..14+2
 9270  *---INSTALL SLOT*16 IN WRITE.SECTOR---------------
 9280         LDX SLOT.X16  
 9290         STX WS...6+1
 9300         STX WS...9+1
 9310         STX WS..13+1
 9320         STX WS..18+1
 9330         RTS
 9340  *--------------------------------
 9350  WAIT.FOR.OLD.MOTOR.TO.STOP
 9360         EOR OLD.SLOT      SAME SLOT AS BEFORE?
 9370         ASL               (IGNORE DRIVE)
 9380         BEQ .2            ...YES
 9390         LDA #1       LONG MOTOR.TIME
 9400         STA MOTOR.TIME+1  (COUNTS BACKWARDS)
 9410  .1     LDA OLD.SLOT
 9420         AND #$70
 9430         TAX
 9440         BEQ .2       ...NO PREVIOUS MOTOR RUNNING
 9450         JSR CHECK.IF.MOTOR.RUNNING.X
 9460         BEQ .2       ...NOT RUNNING YET
 9470         LDA #1       DELAY ANOTHER 100 USECS
 9480         JSR DELAY.100
 9490         LDA MOTOR.TIME+1
 9500         BNE .1       KEEP WAITING
 9510  .2     RTS
 9520  *--------------------------------
 9530         .BS $FF9B-*       <<<<EMPTY SPACE>>>>
 9540  *--------------------------------
 9550  IRQ
 9560         PHA          SAVE A-REG
 9570         LDA $45     SAVE LOC $45
 9580         STA SAVE.LOC45
 9590         PLA          SAVE A-REG AT LOC $45
 9600         STA $45  
 9610         PLA          GET STATUS BEFORE IRQ
 9620         PHA
 9630         AND #$10     SEE IF "BRK"
 9640         BNE .2       ...YES, LET MONITOR DO IT
 9650         LDA $D000    SAVE $D000 BANK ID
 9660         EOR #$D8
 9670         BEQ .1
 9680         LDA #$FF
 9690  .1     STA INTBANKID
 9700         STA SAVE.D000
 9710         LDA #$BF     PUSH FAKE "RTI" VECTOR WITH
 9720         PHA               IRQ DISABLED
 9730         LDA #$50          AND SET TO RETURN TO $BF50
 9740         PHA
 9750         LDA #4
 9760         PHA
 9770  .2     LDA #$FA     PUSH "RTS" VECTOR FOR MONITOR
 9780         PHA
 9790         LDA #$41
 9800         PHA
 9810  CALL.MONITOR
 9820         STA $C082    SWITCH TO MOTHERBOARD
 9830  *--------------------------------
 9840  RESET
 9850         LDA RESET.VECTOR+1
 9860         PHA          PUSH "RTS" VECTOR FOR MONITOR
 9870         LDA RESET.VECTOR
 9880         PHA
 9890         JMP CALL.MONITOR
 9900  *--------------------------------
 9910  RESET.VECTOR
 9920         .DA $FA61    MON.RESET-1
 9930  *--------------------------------
 9940  INT.SPLICE
 9950         STA INTAREG
 9960         LDA SAVE.LOC45
 9970         STA $45  
 9980         LDA $C08B    SWITCH TO MAIN $D000 BANK
 9990         LDA SAVE.D000
10000         JMP IRQXIT.3
10010  *--------------------------------
10020         .BS $FFFA-*       <<<<<EMPTY SPACE>>>>>
10030  *--------------------------------
10040  V.NMI      .DA $03FB
10050  V.RESET    .DA RESET
10060  V.IRQ      .DA IRQ
10070  *--------------------------------

