
 1000  *---------------------------------
 1010  *      DOS 3.2.1/3.3 FILE MANAGER $B052-B0B5
 1020  *---------------------------------
 1030         .OR $B052
 1040         .TA $0852
 1050  *---------------------------------
 1060  MON.STATUS .EQ $48
 1070  IOB.ADDR   .EQ $AAC1
 1080  SAVE.FMW   .EQ $AE7E
 1090  RWTS       .EQ $BD00
 1100  MON.INIT   .EQ $FB2F
 1110  MON.HOME   .EQ $FC58
 1120  MON.PRBYTE .EQ $FDDA
 1130  MON.COUT   .EQ $FDED
 1140  MON.SETKBD .EQ $FE89
 1150  MON.SETVID .EQ $FE93
 1160  *---------------------------------
 1170  CALL.RWTS
 1180         STX IOB.TRACK
 1190         STY IOB.SECTOR
 1200  CALL.RWTS.1
 1210         STA IOB.OPCODE (SEEK=0, READ=1, WRITE=2, FORMAT=4)
 1220         CMP #2       OPCODE="WRITE"?
 1230         BNE .1
 1240         ORA FMW.FLAGS SET "LAST OP WAS WRITE" FLAG
 1250         STA FMW.FLAGS
 1260  .1     LDA FMW.VOLUME
 1270         EOR #$FF     UN-COMPLEMENT THE VOLUME #
 1280         STA IOB.VOLUME
 1290         LDA FMW.SLOT16  SLOT # TIMES 16
 1300         STA IOB.SLOT16
 1310         LDA FMW.DRIVE   DRIVE #
 1320         STA IOB.DRIVE
 1330         LDA FMW.SECTSZ  SECTOR LENGTH IN BYTES
 1340         STA IOB.SECTSZ
 1350         LDA FMW.SECTSZ+1
 1360         STA IOB.SECTSZ+1
 1370         LDA #1       SET TABLE TYPE
 1380         STA IOB.TYPE
 1390         LDY IOB.ADDR GET ADDRESS OF IOB
 1400         LDA IOB.ADDR+1
 1410         JSR ENTER.RWTS   PERFORM THE OPERATION
 1420         LDA IOB.ACTVOL   VOUME # FOUND
 1430         STA FMP.DATA+2
 1440         LDA #$FF     RESET VOLUME EXPECTED IN IOB
 1450         STA IOB.VOLUME
 1460         BCS .2       CARRY SET IF RWTS ERROR
 1470         RTS          RETURN TO CALLER
 1480  .2     LDA IOB.ERROR  GET ERROR CODE
 1490         LDY #7       ERR=7 IF VOLUME MISMATCH
 1500         CMP #$20     VOLUME MISMATCH?
 1510         BEQ .3       YES
 1520         LDY #4       ERR=4 IF WRITE PROTECTED
 1530         CMP #$10     WRITE PROTECTED?
 1540         BEQ .3       YES
 1550         LDY #8       ERR=8 (I/O ERROR) FOR ALL OTHERS
 1560  .3     TYA          ERR IN A-REG
 1570         JMP FM.EXIT.ERROR
 1580  *---------------------------------
 1590  *      DOS 3.3 FILE MANAGER $B35F-B5FF
 1600  *---------------------------------
 1610                .OR $B35F
 1620                .TA $0B5F
 1630  FM.EXIT.ERR1  LDA #1 "LANGUAGE NOT AVAILABLE"
 1640                BNE FM.EXIT.ERROR
 1650  FM.EXIT.ERR2  LDA #2 "RANGE ERROR" (OPCODE)
 1660                BNE FM.EXIT.ERROR
 1670  FM.EXIT.ERR3  LDA #3 "RANGE ERROR" (SUBCODE)
 1680                BNE FM.EXIT.ERROR
 1690  FM.EXIT.ERR4  LDA #4 "WRITE PROTECTED"
 1700                BNE FM.EXIT.ERROR
 1710  FM.EXIT.ERR5  LDA #5 "END OF DATA"
 1720                BNE FM.EXIT.ERROR
 1730  FM.EXIT.ERR6  LDA #6 "FILE NOT FOUND"
 1740                BNE FM.EXIT.ERROR
 1750  FM.EXIT.ERR9  JMP $BFED "DISK FULL"
 1760                NOP
 1770  FM.EXIT.ERR10 LDA #10 "FILE LOCKED"
 1780                BNE FM.EXIT.ERROR
 1790  *---------------------------------
 1800  FM.EXIT.GOOD
 1810         LDA FMP.RETURN  GET RETURN CODE (ZERO)
 1820         CLC          SIGNAL NO ERROR
 1830         BCC FM.EXIT  ...ALWAYS
 1840  *---------------------------------
 1850  FM.EXIT.ERROR
 1860         SEC
 1870  *---------------------------------
 1880  FM.EXIT
 1890         PHP          SAVE STATUS ON STACK
 1900         STA FMP.RETURN  RETURN CODE
 1910         LDA #0       CLEAR MONITOR STATUS (JUST IN CASE)
 1920         STA MON.STATUS
 1930         JSR SAVE.FMW SAVE FM WORKAREA IN FILE BUFFER
 1940         PLP          RETRIEVE STATUS FROM STACK
 1950         LDX FMS.STACK RESTORE STACK POINTER
 1960         TXS
 1970         RTS          RETURN TO WHOEVER CALLED FM
 1980  *---------------------------------
 1990  *      SCRATCH AREA
 2000  *---------------------------------
 2010  FMS.TS.CD  .BS 2    T/S OF CURRENT DIRECTORY SECTOR
 2020             .BS 2    ?
 2030  FMS.STACK  .BS 1    S-REG WHEN FM CALLED
 2040  FMS.DIRNDX .BS 1    VARIOUS USES
 2050             .BS 1       "     "
 2060             .BS 2    ?
 2070             .HS 0000FFFF  USED BY INIT TO CLEAR VTOC ENTRY
 2080  *---------------------------------
 2090         .DA #1,#10,#100  DECIMAL CONVERSION TABLE
 2100         .AS -/TIABSRAB/  FILE TYPE CODES
 2110         .AS -/ EMULOV KSID/  MSG SPELLED BACKWARDS
 2120  *---------------------------------
 2130  *      VTOC SECTOR BUFFER
 2140  *---------------------------------
 2150         .BS 256
 2160  *---------------------------------
 2170  *      DIRECTORY SECTOR BUFFER
 2180  *---------------------------------
 2190         .BS 256
 2200  *---------------------------------
 2210  *      FILE MANAGER PARAMETERS
 2220  *---------------------------------
 2230  FMP.OPCODE    .BS 1
 2240  FMP.SUBCOD    .BS 1
 2250  FMP.DATA      .BS 8 USE DEPENDS ON OPCODE
 2260  FMP.RETURN    .BS 1 ERROR CODE
 2270                .BS 1 ?
 2280  FMP.PNTR.WORK .BS 2 ADDR OF WORKAREA IN FILE BUFFER
 2290  FMP.PNTR.TS   .BS 2 ADDR OF T/S LIST IN FILE BUFFER
 2300  FMP.PNTR.DATA .BS 2 ADDR OF DATA IN FILE BUFFER
 2310                .BS 4 ?
 2320  *---------------------------------
 2330  *      FILE MANAGER WORKAREA
 2340  *---------------------------------
 2350  FMW.TS.TS1  .BS 2 T/S OF FIRST T/S LIST SECTOR
 2360  FMW.TS.TSC  .BS 2 T/S OF CURRENT T/S LIST SECTOR
 2370  FMW.FLAGS   .BS 1 CHECKPOINT FLAGS
 2380  FMW.TS.DATA .BS 2 T/S OF CURRENT DATA SECTOR
 2390              .BS 2 DIRECTORY SECTOR INDEX
 2400              .BS 2  # SECTORS PER TS LIST
 2410              .BS 2  1ST SECTOR
 2420              .BS 2  LAST SECTOR+1
 2430              .BS 2  CURRENT SECTOR
 2440  FMW.SECTSZ  .BS 2  SECTOR SIZE IN BYTES
 2450              .BS 4 FILE POSITION
 2460              .BS 2 RECORD LENGTH FROM OPEN
 2470              .BS 2  RECORD NUMBER
 2480              .BS 2  BYTE OFFSET INTO RECORD
 2490              .BS 2  # SECTORS IN FILE
 2500              .BS 6 SECTOR ALLOCATION AREA
 2510  FMW.FILTYP  .BS 1
 2520  FMW.SLOT16  .BS 1
 2530  FMW.DRIVE   .BS 1
 2540  FMW.VOLUME  .BS 1  (COMPLEMENT FORM)
 2550  FMW.TRACK   .BS 1
 2560              .BS 5  <NOT USED>
 2570  *---------------------------------
 2580  *      STAGE 1 OF BOOT (EXECUTES AT $0800)
 2590  *---------------------------------
 2600         .OR $800
 2610         .TA $E00
 2620  BOOT.STAGE1
 2630         .HS 01
 2640  *   COMES HERE AFTER EACH SECTOR IS READ
 2650         LDA $27      NEXT PAGE TO READ INTO
 2660         CMP #9       FIRST TIME HERE?
 2670         BNE .1       NO, SKIP OVER INITIALIZATION
 2680         LDA $2B      SLOT*16
 2690         LSR          GET SLOT #
 2700         LSR
 2710         LSR
 2720         LSR
 2730         ORA #$C0     BUILD ADDRESS INTO ROM
 2740         STA $3F      FOR READING A SECTOR
 2750         LDA #$5C
 2760         STA $3E
 2770         CLC
 2780         LDA BT1.ADDR+1  COMPUTE ADDRESS OF LAST PAGE
 2790         ADC BT1.N       TO BE READ
 2800         STA BT1.ADDR+1
 2810  .1     LDX BT1.N    # PAGES LEFT TO READ - 1
 2820         BMI .2       FINISHED
 2830         LDA SECTOR.NUMBER,X  CONVERT TO PHYSICAL SECTOR #
 2840         STA $3D
 2850         DEC BT1.N
 2860         LDA BT1.ADDR+1
 2870         STA $27
 2880         DEC BT1.ADDR+1
 2890         LDX $2B      SLOT*16
 2900         JMP ($3E)    READ NEXT SECTOR
 2910  .2     INC BT1.ADDR+1  POINT AT STAGE 2 LOADER
 2920         INC BT1.ADDR+1
 2930         JSR MON.SETKBD
 2940         JSR MON.SETVID
 2950         JSR MON.INIT
 2960         LDX $2B      SLOT*16
 2970         JMP (BT1.ADDR)
 2980  *---------------------------------
 2990  SECTOR.NUMBER
 3000         .HS 000D0B0907050301
 3010         .HS 0E0C0A080604020F
 3020  *---------------------------------
 3030  *      DOS 3.3 PATCHES FOR APPEND AND VERIFY
 3040  *---------------------------------
 3050         .OR $B65D
 3060         .TA $0E5D
 3070  APPEND.FLAG .BS 1
 3080  PATCH.DOS33.1
 3090         JSR $A764    LOCATE AND FREE FILE BUFFER
 3100         BCS .1
 3110         LDA #0       CLEAR APPEND FLAG
 3120         TAY
 3130         STA APPEND.FLAG
 3140         STA ($40),Y
 3150  .1     LDA FMP.RETURN
 3160         JMP $A6D2
 3170  *---------------------------------
 3180  PATCH.DOS33.2
 3190         LDA APPEND.FLAG
 3200         BEQ .1
 3210         INC FMP.DATA
 3220         BNE .1
 3230         INC FMP.DATA+1
 3240  .1     LDA #0       CLEAR APPEND FLAG
 3250         STA APPEND.FLAG
 3260         JMP $A546
 3270  *---------------------------------
 3280  PATCH.DOS33.3
 3290         STA FMP.SUBCOD
 3300         JSR $A6A8
 3310         JSR $A2EA
 3320         JMP $A27D
 3330  *---------------------------------
 3340  PATCH.DOS33.4
 3350         LDY #19      LOOK AT FILE POSITION
 3360  .1     LDA ($42),Y
 3370         BNE .4       NOT AT 0000
 3380         INY
 3390         CPY #23
 3400         BNE .1       TEST 4 BYTES
 3410         LDY #25
 3420  .2     LDA ($42),Y
 3430         STA FMP.DATA-25,Y
 3440         INY
 3450         CPY #29      MOVE 4 BYTES
 3460         BNE .2
 3470  .3     JMP $A6BC
 3480  .4     LDX #$FF
 3490         STX APPEND.FLAG
 3500         BNE .3       ...ALWAYS
 3510         .BS 29       <NOT USED>
 3520  *---------------------------------
 3530  *      STRANGE CODE IN THE MIDDLE OF NOWHERE
 3540  *---------------------------------
 3550         JSR MON.HOME  CLEAR SCREEN
 3560         LDA #$C2      PRINT "B01-00"
 3570         JSR MON.COUT
 3580         LDA #1
 3590         JSR MON.PRBYTE
 3600         LDA #$AD
 3610         JSR MON.COUT
 3620         LDA #0
 3630         JSR MON.PRBYTE
 3640         RTS
 3650         .BS 21       <NOT USED>
 3660         .OR $08FD
 3670         .TA $0EFD
 3680  BT1.ADDR .DA $3600
 3690  BT1.N    .DA #9      
 3700  *---------------------------------
 3710  *      SECOND STAGE OF BOOT
 3720  *---------------------------------
 3730         .OR $B700
 3740         .TA $0F00
 3750  BOOT.STAGE2
 3760         STX IOB.SLOT16
 3770         STX IOB.PRVSLT
 3780         LDA #1
 3790         STA IOB.PRVDRV
 3800         STA IOB.DRIVE
 3810         LDA BT.N
 3820         STA BT.CNT
 3830         LDA #2
 3840         STA IOB.TRACK
 3850         LDA #4
 3860         STA IOB.SECTOR
 3870         LDY BT.BT1+1
 3880         DEY
 3890         STY IOB.BUFFER+1
 3900         LDA #1
 3910         STA IOB.OPCODE
 3920         TXA          SLOT*16
 3930         LSR          GET SLOT #
 3940         LSR
 3950         LSR
 3960         LSR
 3970         TAX
 3980         LDA #0
 3990         STA $4F8,X
 4000         STA $478,X
 4010         JSR RW.PAGES
 4020         LDX #$FF
 4030         TXS          EMPTY STACK
 4040         STX IOB.VOLUME
 4050         JMP $BFC8    PATCH TO SETVID AND CLOBBER
 4060  *                   THE LANGUAGE CARD, IF IN SLOT 0
 4070         JSR MON.SETKBD
 4080         JMP $9D84    DOS HARD ENTRY
 4090  *---------------------------------
 4100  *      WRITE DOS IMAGE ON TRACKS 0-2
 4110  *---------------------------------
 4120  WRITE.DOS.IMAGE
 4130         LDA BT.BT1+1 COMPUTE # OF PAGES
 4140         SEC
 4150         SBC IOB.BUFFER+1
 4160         STA BT.CNT
 4170         LDA BT.BT1+1 START AT END, WORK BACKWARD
 4180         STA IOB.BUFFER+1
 4190         DEC IOB.BUFFER+1
 4200         LDA #2       START ON TRACK 2
 4210         STA IOB.TRACK
 4220         LDA #4       SECTOR 4
 4230         STA IOB.SECTOR
 4240         LDA #2
 4250         STA IOB.OPCODE
 4260         JSR RW.PAGES WRITE STAGE2 PART OF DOS
 4270         LDA BT.BT1+1 SET UP BOOT SECTOR IMAGE
 4280         STA BT1.ADDR+1+$B600-$0800
 4290         CLC          COMPUTE STARTING ADDRESS OF WRITE
 4300         ADC #9
 4310         STA IOB.BUFFER+1
 4320         LDA #10      WRITE 10 PAGES
 4330         STA BT.CNT
 4340         SEC
 4350         SBC #1
 4360         STA BT1.N+$B600-$0800
 4370         STA IOB.SECTOR
 4380         JSR RW.PAGES WRITE SECTORS 9-0 ON TRACK 0
 4390         RTS
 4400  *---------------------------------
 4410         .HS 000000000000   <NOT USED>
 4420  *---------------------------------
 4430  *      READ/WRITE A GROUP OF PAGES
 4440  *
 4450  *      BT.CNT       # OF SECTORS TO READ/WRITE
 4460  *      IOB          SET UP FOR FIRST TS TO R/W
 4470  *---------------------------------
 4480  RW.PAGES
 4490         LDA BT.IOB+1 GET IOB ADDRESS
 4500         LDY BT.IOB
 4510         JSR ENTER.RWTS  READ/WRITE ONE SECTOR
 4520         LDY IOB.SECTOR  IGNORE ERRORS IF ANY
 4530         DEY             BACK UP SECTOR #
 4540         BPL .1          STILL IN SAME TRACK
 4550         LDY #15         START WITH SECTOR 15 IN NEXT TRACK
 4560         NOP
 4570         NOP
 4580         DEC IOB.TRACK   BACKWARD THROUGH THE TRACKS
 4590  .1     STY IOB.SECTOR
 4600         DEC IOB.BUFFER+1  DOWN ONE PAGE IN MEMORY
 4610         DEC BT.CNT      ANY MORE PAGES TO DO?
 4620         BNE RW.PAGES    YES
 4630         RTS             NO, RETURN
 4640  *---------------------------------
 4650  *      ENTER RWTS
 4660  *---------------------------------
 4670  ENTER.RWTS
 4680         PHP          SAVE STATUS ON STACK
 4690         SEI          DISABLE INTERRUPTS
 4700         JSR RWTS     CALL RWTS
 4710         BCS .1       ERROR RETURN
 4720         PLP          RESTORE STATUS
 4730         CLC          SIGNAL NO RWTS ERROR
 4740         RTS          RETURN TO CALLER
 4750  .1     PLP          RESTORE STATUS
 4760         SEC          SIGNAL RWTS ERROR
 4770         RTS          RETURN TO CALLER
 4780  *---------------------------------
 4790  *      SET UP RWTS TO WRITE DOS
 4800  *---------------------------------
 4810  SETUP.WRITE.DOS
 4820         LDA FMP.SUBCOD  IMAGE ADDRESS
 4830         STA IOB.BUFFER+1
 4840         LDA #0
 4850         STA IOB.BUFFER
 4860         LDA FMW.VOLUME  VOLUME #
 4870         EOR #$FF        UNCOMPLEMENT IT
 4880         STA IOB.VOLUME
 4890         RTS
 4900  *---------------------------------
 4910  *      CLEAR 256 BYTES STARTING AT ($42,43)
 4920  *---------------------------------
 4930  ZERO.CURRENT.BUFFER
 4940         LDA #0
 4950         TAY
 4960  .1     STA ($42),Y
 4970         INY
 4980         BNE .1
 4990         RTS
 5000  *---------------------------------
 5010  *      PARAMETERS FOR SECOND STAGE OF BOOT PROCESS
 5020  *---------------------------------
 5030         .BS 1        <NOT USED>
 5040  BT.N   .DA #27      # OF PAGES TO R/W (PARAMETER)
 5050  BT.CNT .BS 1        # OF PAGES TO R/W (VARIABLE)
 5060  BT.1S  .DA #10      1ST SECTOR # IN THIS STAGE
 5070         .BS 1
 5080  BT.IOB .DA IOB      ADDRESS OF IOB
 5090  BT.BT1 .DA BOOT.STAGE1+$B600-$0800  ADDR OF 1ST STAGE BOOT
 5100  *---------------------------------
 5110  *      IOB FOR RWTS CALLS
 5120  *---------------------------------
 5130  IOB
 5140  IOB.TYPE   .BS 1    0--MUST BE $01
 5150  IOB.SLOT16 .BS 1    1--SLOT # TIMES 16
 5160  IOB.DRIVE  .BS 1    2--DRIVE # (1 OR 2)
 5170  IOB.VOLUME .BS 1    3--DESIRED VOL # (0 MATCHES ANY)
 5180  IOB.TRACK  .BS 1    4--TRACK # (0 TO 34)
 5190  IOB.SECTOR .BS 1    5--SECTOR # (0 TO 15)
 5200  IOB.PNTDCT .DA DCT  6--ADDRESS OF DCT
 5210  IOB.BUFFER .BS 2    8--ADDRESS OF DATA
 5220  IOB.SECTSZ .BS 2   10--# BYTES IN A SECTOR
 5230  IOB.OPCODE .BS 1   12--0=SEEK, 1=READ, 2=WRITE, OR 4=FORMAT
 5240  IOB.ERROR  .BS 1   13--ERROR CODE: 0, 8, 10, 20, 40, 80
 5250  IOB.ACTVOL .BS 1   14--ACTUAL VOLUME # FOUND
 5260  IOB.PRVSLT .BS 1   15--PREVIOUS SLOT #
 5270  IOB.PRVDRV .BS 1   16--PREVIOUS DRIVE #
 5280             .BS 2
 5290  DCT    .HS 0001EFD8
 5300         .BS 1

