LST OFF
*                                *
*     F I L E  M A N A G E R     *
*                                *
*  from the D O S - Source 1982  *
*                                *
**********************************
*
*
*
SCRATCH = $27
BOOTSLOT = $2B
ROMRWTS = $3E
SECNUM = $3D
OPRND = $44
BUFADR = $42
DOSIMG = $40
IOBADR = $48
DRV0TRAK = $478
DRV1TRAK = $4F8
DOSSTRT = $9D84
DOVERIFY = $A27D
DOCLOSE = $A2EA
RWC2 = $A546
FMDRVR = $A6A8
FMDRVR0 = $A6BC
DOERROR = $A6D2
LOCBUF = $A764
KWDRPRMS = $A909
CURSTAT = $AA51
CMDINDX = $AA5F
RWTSENT = $BD00
REBOOT = $BFC8
DISKFULL = $BFED
MEMTOP = $C000
MONINIT = $FB2F
CLRHOME = $FC58
RDCHAR = $FD0C
PRBYTE = $FDDA
COUT = $FDED
SETKBD = $FE89
SETVID = $FE93
*
 ORG $AAC1
*
*
* THE FOLLOWING ADDRESSES ARE
* SHARED WITH THE CDI FILE
*
RWTSPADR DA TBLTYPE
VTOCPADR DA VTOCSB
DIRPADR DA DIRSECBF
 DA MEMTOP
*
*
* File manager subroutine table.
*
*
FMFTBL DA NOERROR-1
 DA OPNHNDLR-1
 DA CLSHDLR-1
 DA RDHNDLR-1
 DA WRTHNDLR-1
 DA DELHNDL-1
 DA CATHNDL-1
 DA LCKHNDLR-1
 DA UNLKHDL-1
 DA RENHNDLR-1
 DA POSHNDLR-1
 DA INITHDL-1
 DA VFYHNDL-1
 DA NOERROR-1
*
* Read Subcode table.
*
*
FMRSUB DA NOERROR-1
 DA RD1BYTE-1
 DA RDRANGE-1
 DA POSRD1B-1
 DA POSRDR-1
 DA NOERROR-1
*
* Write subcode table.
*
FMWSUB DA NOERROR-1
 DA WRT1BYTE-1
 DA WRTRANGE-1
 DA POSWRT1B-1
 DA POSWRTR-1
 DA NOERROR-1
*
 ORG $AAFD
*
*
*
* EXTERNAL ENTRY POINT FOR FILE
* MANGER.
*
* X=0, allocate a new file if
* file not found in dir.
*
* X=1, do not allocate a new file
* if file not found.
*
*
*
FMEXT CPX #0
 BEQ FMEXT1
 LDX #2
FMEXT1 STX CMDINDX
*
*
*
* NORMAL ENTRY FOR FILE MANAGER
*
*
FILEMGR TSX
 STX STKSAVE
*
* GET FM PARMS
*
 JSR LDFMW
*
* CHECK TO SEE IF WE HAVE A VALID
* FM OPCODE..
*
 LDA FMOPCOD
 CMP #$D
 BCS FILEMGR1
*
* USING OPCODE AS INDEX INTO
* FMFTBL, JMP TO APPROPRIATE
* ROUTINE.
*
 ASL 
 TAX 
 LDA FMFTBL+1,X
 PHA 
 LDA FMFTBL,X
 PHA 
 RTS 
*
 ORG $AB1F
*
* JMP TO OPCODE RANGE ERROR
* HANDLER
*
FILEMGR1 JMP RANGERR
*
*
*
* OPNHNDLR- OPENS A FILE
*
OPNHNDLR JSR CMNOPN
 JMP NOERROR
*
*
* CMNOPN- USED TO OPEN A FILE,
* CALLED BY VARIOUS FILE MANAGER
* ROUTINES.
*
 ORG $AB28
*
*
* INIT FILE MANAGER WORK AREA
*
CMNOPN JSR INITFMW
*
* SET SECTOR LENGTH TO 256 BYTEST
*
 LDA #$1
 STA SECTLEN+1
*
* IF RECORD LEN = 0, SET TO 1
*
 LDX RECNUM+1
 LDA RECNUM
 BNE CMNOPN1
 CPX #0
 BNE CMNOPN1
 INX 
CMNOPN1 STA OPNRCLEN
 STX OPNRCLEN+1
*
* SEARCH FOR THE FILENAME IN THE
* DIRECTORY, ALLOCATE IF NOT FOUND
*
 JSR LCDIRENT
 BCC PLTSDIR
*
* FILE NOT FOUND IN DIRECTORY,
* SEE IF A FILE IS REQUIRED.
*
 STX DIRINDX
 LDX CMDINDX
 LDA KWDRPRMS,X
 LDX DIRINDX
 LSR 
 BCS CMNOPN3
*
*
* AT THIS POINT, THE FILE MUST BE
* PRESENT, SEE IF WE ARE LOADING
* APPLESOFT FROM DISK.
*
 LDA CURSTAT
 CMP #$C0
 BNE CMNOPN2
*
* LOADING AS. ERROR= LANG NOT AVL
*
 JMP LNOTAVL
*
* LOADING A NORMAL PROGRAM, PRINT
* FILE NOT FOUND.
*
CMNOPN2 JMP FNOTFND
*
 ORG $AB64
*
* FILE WAS NOT REQUIRED TO BE
* IN THE DIRECTORY, SET IT
* UP
*
*
* SET SECTOR COUNT TO 1
*
CMNOPN3 LDA #0
 STA FILESIZE+1,X
 LDA #$1
 STA FILESIZE,X
 STX DIRINDX
*
* ALLOCATE A SECTOR FOR T/S LIST
*
 JSR ALLOCSEC
*
* SET UP T/S LIST AND WORK BUFFER
*
 LDX DIRINDX
 STA TSSECTOR,X
 STA FTSS
 STA CURTSS
 LDA SCALAREA+1
 STA TSTRACK,X
 STA FTSTS
 STA CURTSTS
 LDA FILETYPE
 STA FILTYP,X
*
* WRITE DIRECTORY BACK TO DISK
*
 JSR WRTDIRSC
*
* INIT THE WORK BUFFER, DATA
* BUFFER, AND T/S BUFFERS
*
 JSR SELTSBUF
 JSR ZEROBUF
 JSR SETUPRW
*
* SET RETURN CODE TO FILE NOT FND
*
 LDX DIRINDX
 LDA #6
 STA RTNCODE
*
*
*
* FALL THROUGH FROM ABOVE (FILE
* CREATED AND ENTERED INTO DIR)
*
* -OR- 
*
* COME FROM DIR LOOKUP IF FILE
* WAS FOUND IN DIRECTORY.
*
*
*
* COPY T/S LIST INFO TO WORK 
* BUFFER
*
PLTSDIR LDA TSTRACK,X
 STA FTSTS
 LDA TSSECTOR,X
 STA FTSS
 LDA FILTYP,X
*
* COPY FILE TYPE TO WORK BUFFER
*
 STA FILETYPE
 STA FTYPE
*
* COPY FILE SIZE TO WORK BUFFER
*
 LDA FILESIZE,X
 STA SECCNT
 LDA FILESIZE+1,X
 STA SECCNT+1
 STX DIRSECIX+1
*
* INIT EOF TO 65535 (INFINITY) 
*
 LDA #$FF
 STA RELSLRD
 STA RELSLRD+1
*
* SET UP # OF ENTRIES IN T/S LIST
*
 LDA NUMTSENT
 STA SECPERTS
*
* READ IN THE FIRST T/S LIST
* (IF THERE IS ONE)
*
 CLC 
 JMP RDTSLST
*
 ORG $ABDC
*
* INITIALIZE FILE MANAGER WORK
* AREA.
*
*
* ZERO OUT T/S LIST
*
INITFMW LDA #0
 TAX 
INITFMW1 STA FTSTS,X
 INX 
 CPX #$2D
 BNE INITFMW1
*
* INIT VOLUME # (COMPLIMENTED),
* SLOT, AND DRIVE #.
*
 LDA VOLVAL
 EOR #$FF
 STA VOLNUMBR
 LDA DRVVAL
 STA DRVNUMBR
 LDA SLOTVAL
 ASL 
 ASL 
 ASL 
 ASL 
 TAX 
 STX SLOT16
*
* SET UP FOR DIRECTORY TRACK
*
 LDA #$11
 STA TRKNUMBR
 RTS 
*
 ORG $AC06
*
* CLOSE FILE HANDLER.
*
*
* CHECK TO SEE IF DATA BUFFER OR
* T/S BUFFER NEEDS TO BE WRITTEN
* TO DISK.
*
CLSHDLR JSR CHKBUF
 JSR CHKTS
*
* RELEASE ANY UNALLOCATED SECTORS
*
 JSR RLSALLC
*
* CHECK TO SEE IF FILE SIZE
* HAS CHANGED.
*
 LDA #2
 AND FLAGS
 BEQ CLSHDLR2
*
* IF SO, READ VTOC, UPDATE IT,
* READ DIR, AND UPDATE FILE SIZE
*
 JSR RWVTOC
 LDA #0
 CLC 
CLSHDLR1 JSR RDDIRSC
 SEC 
 DEC DIRSECIX
 BNE CLSHDLR1
 LDX DIRSECIX+1
 LDA SECCNT
 STA FILESIZE,X
 LDA SECCNT+1
 STA FILESIZE+1,X
 JSR WRTDIRSC
*
* NORMAL CLOSE EXIT PT.
*
CLSHDLR2 JMP NOERROR
*
 ORG $AC3A
*
* RENAME HANDLER.
*
RENHNDLR JSR CMNOPN ;LOOKUP FILE
*
* SEE IF THE FILE IS LOCKED
*
 LDA FTYPE
 BMI FILOCKED
*
*
* IF NOT, POINT BUFADR AT THE
* SECOND FILENAME AND COPY IT
* INTO THE DIRECTORY
*
 LDA RECNUM
 STA BUFADR
 LDA RECNUM+1
 STA BUFADR+1
 LDX DIRINDX
 JSR COPFNAM
*
* WRITE THE DIRECTORY BACK TO
* DISK
*
 JSR WRTDIRSC
 JMP NOERROR
*
 ORG $AC58
*
* READ FUNCTION HANDLER.
*
RDHNDLR LDA SUBCODE
*
* MAKE SURE SUBCODE IS < 5
*
 CMP #5
 BCS RDHNDLR1
*
* USE SUBCODE AS INDEX INTO FMRSUB
* TABLE, JUMP TO THAT ADDRESS
*
 ASL 
 TAX 
 LDA FMRSUB+1,X
 PHA 
 LDA FMRSUB,X
 PHA 
 RTS 
RDHNDLR1 JMP RANGERR2
*
* ERROR EXIT POINT IF THE
* FILE WAS LOCKED
*
FILOCKED JMP FILELOCK
*
 ORG $AC70
*
* WRITE FUNCTION HANDLER.
*
*
* MAKE SURE THE FILE IS NOT LOCKED
*
WRTHNDLR LDA FTYPE
 BMI FILOCKED
*
* CHECK SUBCODE (< 5)
*
 LDA SUBCODE
 CMP #5
 BCS RDHNDLR1
*
* USE SUBCODE AS INDEX INTO
* FMWSUB TABLE
*
 ASL 
 TAX 
 LDA FMWSUB+1,X
 PHA 
 LDA FMWSUB,X
 PHA 
 RTS 
*
 ORG $AC87
*
* POSITION AND READ 1 BYTE HANDLER
*
* (POSITIONS AND DROPS THROUGH TO
* READ ONE BYTE)
*
POSRD1B JSR CALPOSN
*
* READ ONE BYTE ROUTINE
*
RD1BYTE JSR RDABYTE
 STA DATABYTE
 JMP NOERROR
*
 ORG $AC93
*
* POSITION AND READ A RANGE OF
* BYTES
*
POSRDR JSR CALPOSN
*
* READ A RANGE OF BYTES
*
RDRANGE JSR DECRNG
 JSR RDABYTE
 PHA 
 JSR MOVRANG
 LDY #0
 PLA 
 STA (BUFADR),Y
 JMP RDRANGE
*
 ORG $ACA8
*
* RDABYTE READS A DATA BYTE FROM
* THE FILE, READING IN ADDITIONAL
* SECTORS AS NECESSARY.
*
RDABYTE JSR RDNXTDA
 BCS RDABYTE1
 LDA (BUFADR),Y
 PHA 
 JSR INCREC
 JSR INCPOS
 PLA 
 RTS 
RDABYTE1 JMP ENDATA
*
 ORG $ACBB
*
* POSITION AND WRITE ONE BYTE
* HANDLER.
*
POSWRT1B JSR CALPOSN
*
*
* WRITE ONE BYTE HANDLER
*
WRT1BYTE LDA DATABYTE
 JSR WRTBYTE
 JMP NOERROR
*
 ORG $ACC7
*
* POSITION AND WRITE RANGE
*
POSWRTR JSR CALPOSN
*
*
* WRITE A RANGE OF BYTES
*
WRTRANGE JSR MOVRANG
 LDY #0
 LDA (BUFADR),Y
 JSR WRTBYTE
 JSR DECRNG
 JMP WRTRANGE
*
 ORG $ACDA
*
* WRITE A SINGLE BYTE TO A FILE
*
WRTBYTE PHA 
 JSR RDNXTDA
 PLA 
 STA (BUFADR),Y
 LDA #$40
 ORA FLAGS
 STA FLAGS
 JSR INCREC
 JMP INCPOS
*
 ORG $ACEF
*
* LOCK FUNCTION HANDLER
*
LCKHNDLR LDA #$80
 STA ALLCFLG
 BNE UNLKHDL1
*
 ORG $ACF6
*
* UNLOCK FUNCTION HANDLER
*
UNLKHDL LDA #0
 STA ALLCFLG
UNLKHDL1 JSR CMNOPN
 LDX DIRINDX
 LDA FILTYP,X
 AND #$7F
 ORA ALLCFLG
 STA FILTYP,X
 JSR WRTDIRSC
UNLKHDL2 JMP NOERROR
*
 ORG $AD12
*
* POSITION FUNCTION HANDLER
*
POSHNDLR JSR CALPOSN
VFYHNDL2 JMP NOERROR
*
 ORG $AD18
*
* VERIFY HANDLER
*
VFYHNDL JSR CMNOPN
*
* READ UNTIL EOF
*
VFYHNDL1 JSR RDNXTDA
 BCS VFYHNDL2
 INC FILEPOSN
 BNE VFYHNDL1
 INC FILEPOSN+1
 JMP VFYHNDL1
*
 ORG $AD2B
*
* DELETE HANDLER
*
DELHNDL JSR CMNOPN
*
* SEE IF THE FILE IS LOCKED
*
 LDX DIRINDX
 LDA FILTYP,X
 BPL DELHNDL1
 JMP FILELOCK
*
* IF THE FILE IS NOT LOCKED,
* COPY THE T/S LIST POINTER
* AND PUT $FF IN THE OLD
* T/S LIST POINTER SPOT
*
DELHNDL1 LDX DIRINDX
 LDA TSTRACK,X
 STA FTSTS
 STA FILESIZE-1,X
 LDA #$FF
 STA TSTRACK,X
 LDY TSSECTOR,X
 STY FTSS
*
* WRITE DIRECTORY BACK TO DISK
*
 JSR WRTDIRSC
*
* READ THE T/S LIST SECTORS AND
* UPDATE VTOC UNTIL THERE ARE
* NO MORE T/S SECTORS
*
 CLC 
RDNXTS JSR RDTSLST
 BCS RDNXTS3
 JSR SELTSBUF
 LDY #$C
RDNXTS1 STY DIRINDX
 LDA (BUFADR),Y
*
* IF TRACK NUMBER IS ZERO OR
* MINUS, SKIP IT
*
 BMI RDNXTS2
 BEQ RDNXTS2
*
* OTHERWISE UPDATE VTOC
*
 PHA 
 INY 
 LDA (BUFADR),Y
 TAY 
 PLA 
 JSR FREESCT
*
* GET NEXT T/S PAIR
*
RDNXTS2 LDY DIRINDX
 INY 
 INY 
 BNE RDNXTS1
*
* IF AT END OF T/S SECTOR, FREE
* THE SECTOR IT USES AND TRY
* TO GET THE NEXT SECTOR
*
 LDA CURTSTS
 LDY CURTSS
 JSR FREESCT
 SEC 
 BCS RDNXTS
RDNXTS3 JSR WRTVTOC
 JMP NOERROR
*
 ORG $AD89
*
* FREESCT, DEALLOCATES A SECTOR
* IN THE TRACK BIT MAP
*
FREESCT SEC
 JSR RRBITMP
 LDA #0
 LDX #5
FREESCT1 STA SCALAREA,X
 DEX 
 BPL FREESCT1
 RTS 
*
 ORG $AD98
*
*
* CATALOG HANDLER
*
CATHNDL JSR INITFMW
*
* ALLOW ANY VOLUME OF DISK
* ($FF COMPLIMENTED = VOL 0)
*
 LDA #$FF
 STA VOLNUMBR
*
* READ VTOC TO FIND OUT WHERE
* THE CATALOG IS
*
 JSR RWVTOC
*
* SET UP COUNTER TO STOP EVERY 22
* LINES
*
 LDA #$16
 STA CNTR
*
*
* SKIP TWO LINES AND PRINT
* "DISK VOLUME"
*
 JSR SKIPLN
 JSR SKIPLN
 LDX #$B
CATHNDL1 LDA DISKVOL,X
 JSR COUT
 DEX 
 BPL CATHNDL1
*
* PRINT THE VOLUME NUMBER
*
 STX OPRND+1
 LDA VOLFND
 STA OPRND
 JSR PRTDEC
 JSR SKIPLN
 JSR SKIPLN
*
*
* PRINT ALL THE DIRECTORY ENTRIES
*
 CLC 
RDNXTDIR JSR RDDIRSC
 BCS DONEXT2
 LDX #0
GTRKNUM STX DIRINDX
 LDA TSTRACK,X
*
* IF TRACK BYTE IS ZERO, END OF
* DIRECTORY HAS BEEN REACHED,
* IF MINUS, FILE WAS DELETED AND
* SHOULD NOT BE LISTED.
*
 BEQ DONEXT2
 BMI DONEXT
*
* SEE IF THE FILE IS LOCKED
*
 LDY #" "
 LDA FILTYP,X
 BPL GTRKNUM1
 LDY #"*"
GTRKNUM1 TYA
 JSR COUT
*
*
* OUTPUT FILE TYPE
*
 LDA FILTYP,X
 AND #$7F
 LDY #7
 ASL 
GTRKNUM2 ASL
 BCS GTRKNUM3
 DEY 
 BNE GTRKNUM2
GTRKNUM3 LDA FTTBL,Y
 JSR COUT
 LDA #$A0
 JSR COUT
*
* OUTPUT FILE SIZE
*
 LDA FILESIZE,X
 STA OPRND
 LDA FILESIZE+1,X
 STA OPRND+1
 JSR PRTDEC
 LDA #$A0
 JSR COUT
 INX 
 INX 
 INX 
*
* OUTPUT FILE NAME
*
 LDY #$1D
GTRKNUM4 LDA TSTRACK,X
 JSR COUT
 INX 
 DEY 
 BPL GTRKNUM4
 JSR SKIPLN
*
* GET NEXT DIR ENTRY (READING A
* DIR SECTOR IF REQ'D)
*
DONEXT JSR NXTDIREN
 BCC GTRKNUM
 BCS RDNXTDIR
*
* DIR ALL DONE
*
DONEXT2 JMP NOERROR
*
* SKIPLN- PRINTS A <CR> AND
* CHECKS TO SEE IF THE CNTR
* HAS BECOME ZERO OR NOT
*
SKIPLN LDA #$8D
 JSR COUT
 DEC CNTR
 BNE SKIPLN1
 JSR RDCHAR
 LDA #$15
 STA CNTR
SKIPLN1 RTS
*
 ORG $AE42
*
* PRTDEC- PRINTS (OPRAND,OPRAND+1)
* AS A DECIMAL INTEGER.
*
PRTDEC LDY #2
PRTDEC1 LDA #0
 PHA 
PRTDEC2 LDA OPRND
 CMP DECTBL,Y
 BCC PRTDEC3
 SBC DECTBL,Y
 STA OPRND
 LDA OPRND+1
 SBC #0
 STA OPRND+1
 PLA 
 ADC #0
 PHA 
 JMP PRTDEC2
PRTDEC3 PLA
 ORA #$B0
 JSR COUT
 DEY 
 BPL PRTDEC1
 RTS 
*
 ORG $AE6A
*
* LOAD FILE MANAGER WORK AREA
* FROM THE FILE BUFFER.
*
LDFMW JSR SELBUF
 LDY #0
 STY RTNCODE
LDFMW1 LDA (BUFADR),Y
 STA FTSTS,Y
 INY 
 CPY #$2D
 BNE LDFMW1
 CLC 
 RTS 
*
 ORG $AE7E
*
* SAVE FILE MANAGER WORK AREA INTO
* FILE BUFFER
*
SAVFMW JSR SELBUF
 LDY #0
SAVFMW1 LDA FTSTS,Y
 STA (BUFADR),Y
 INY 
 CPY #$2D
 BNE SAVFMW1
 RTS 
*
 ORG $AE8E
*
* INIT FUNCTION HANDLER.
*
INITHDL JSR INITFMW
 LDA #4
*
*
* INIT VTOC INFO
*
 JSR STCMDCD
*
* Volume # must be complimented.
*
 LDA VOLNUMBR
 EOR #$FF
 STA DSKVOL
*
* Set up next track to allocate
* at track 17.
*
 LDA #$11
 STA NXTTOALC
*
* Allocate sectors in positive
* direction (from $11 up).
*
 LDA #$1
 STA ALLCDIR
*
* Mark the "possible" 56 tracks
* as all being used.
*
 LDX #$38
 LDA #0
INITHDL1 STA VTOCSB,X
 INX 
 BNE INITHDL1
*
* Mark the Apple's 35 tracks as
* unused.
*
* Track 0 is not marked as unused
*
*
 LDX #$C
INITHDL2 CPX #$8C
 BEQ INITHDL4
 LDY #3
INITHDL3 LDA FREEMASK,Y
 STA BITMAP,X
 INX 
 DEY 
 BPL INITHDL3
 CPX #$44
 BNE INITHDL2
 LDX #$48
 BNE INITHDL2
INITHDL4 JSR WRTVTOC
*
* INIT DIRECTORY INFO
*
 LDX #0
 TXA 
INITHDL5 STA DIRSECBF,X
 INX 
 BNE INITHDL5
 JSR PRWTSDIR
*
* Set up for directory track
*
 LDA #$11
*
* Set up for dir sector.
*
 LDY NUMSCTRS
 DEY 
 DEY 
 STA TNUM
*
* Write directory sectors out to
* disk.
*
INITHDL6 STA TSNXTDIR
INITHDL7 STY TSNXTDIR+1
 INY 
 STY SNUM
 LDA #2
 JSR STCMDCD
 LDY TSNXTDIR+1
 DEY 
 BMI INITHDL8
 BNE INITHDL7
 TYA
 BEQ INITHDL6
INITHDL8 JSR RWTSPRMS
*
* WRITE DOS OUT TO DISK
*
 JSR PUTDOS
 JMP NOERROR
*
 ORG $AF08
*
* SELECT A BUFFER,
*
* FILE MANAGER WORK BUFFER
*
SELBUF LDX #0
 BEQ SELDABUF1
*
* SELECT T/S LIST BUFFER
*
SELTSBUF LDX #2
 BNE SELDABUF1
*
*
* SELECT DATA BUFFER
*
SLDABUF LDX #4
SELDABUF1 LDA WBADR,X
 STA BUFADR
 LDA WBADR+1,X
 STA BUFADR+1
 RTS 
*
 ORG $AF1D
*
* CHECK DATA BUFFER TO SEE IF IT
* NEEDS TO BE WRITTEN TO DISK
*
CHKBUF BIT FLAGS
 BVS CHKBUF1
 RTS 
CHKBUF1 JSR PREPDATA
 LDA #2
 JSR RWTSDRVR
 LDA #$BF
 AND FLAGS
 STA FLAGS
 RTS 
*
 ORG $AF34
*
* CHECK T/S LIST BUFFER TO SEE
* IF IT MUST BE WRITTEN TO DISK
*
CHKTS LDA FLAGS
 BMI SETUPRW
 RTS 
SETUPRW JSR PREPRWTS
 LDA #2
 JSR RWTSDRVR
 LDA #$7F
 AND FLAGS
 STA FLAGS
 RTS 
*
 ORG $AF4B
*
* SET UP IOB FOR RWTS CALL
*
PREPRWTS LDA TSLSTADR
 STA USRBUF
 LDA TSLSTADR+1
 STA USRBUF+1
 LDX CURTSTS
 LDY CURTSS
 RTS 
*
 ORG $AF5E
*
* READ A T/S LIST INTO THE FILE
* BUFFER.
*
* ON ENTRY C=0 IF FIRST T/S SECTOR
* IS DESIRED, C=1 IF THE NEXT
* T/S SECTOR IS DESIRED.
*
RDTSLST PHP
*
* First, check to see if the
* current T/S list must be
* written to disk.
*
 JSR CHKTS
 JSR PREPRWTS
 JSR SELTSBUF
 PLP 
 BCS RDTSLST1
*
* If the carry flag is cleared,
* read the first sector of the
* T/S list.
*
 LDX FTSTS
 LDY FTSS
 JMP OLDRWTS
*
* If the carry flag was set read
* in the next sector of the
* T/S list.
*
RDTSLST1 LDY #$1
*
* If the track number of the next
* sector is zero, there isn't
* another T/S sector available.
*
 LDA (BUFADR),Y
 BEQ RDTSLST2
*
* If there is another T/S list
* available read it in.
*
 TAX 
 INY 
 LDA (BUFADR),Y
 TAY 
 JMP OLDRWTS
*
* If the File Manager Opcode is
* isn't write, exit with error
* status passed in carry.
*
RDTSLST2 LDA FMOPCOD
 CMP #4
 BEQ RDTSLST3
 SEC 
 RTS 
*
* If writing to disk, simply
* allocate another sector for
* the T/S list and continue.
*
RDTSLST3 JSR ALLOCSEC
 LDY #2
 STA (BUFADR),Y
 PHA 
 DEY 
 LDA SCALAREA+1
 STA (BUFADR),Y
 PHA 
 JSR SETUPRW
 JSR ZEROBUF
 LDY #5
 LDA RELSLAST
 STA (BUFADR),Y
 INY 
 LDA RELSLAST+1
 STA (BUFADR),Y
 PLA 
 TAX 
 PLA 
 TAY 
 LDA #2
 BNE OLDRWTS1
*
* If Acc=1, read old T/S list.
* If Acc=2, write new sector for
* T/S list.
*
OLDRWTS LDA #$1
OLDRWTS1 STX CURTSTS
 STY CURTSS
 JSR RWTSDRVR
*
* Compute relative sector number
* of the last sector represented
* in this T/S list and store
* in workarea.
*
 LDY #5
 LDA (BUFADR),Y
 STA RELSFRST
 CLC 
 ADC SECPERTS
 STA RELSLAST
 INY 
 LDA (BUFADR),Y
 STA RELSFRST+1
 ADC SECPERTS+1
 STA RELSLAST+1
 CLC 
 RTS 
*
 ORG $AFDC
*
* READ A DATA SECTOR
*
RDDASEC JSR PREPDATA
 LDA #$1
 JMP RWTSDRVR
*
* PREP RWTS' IOB FOR READING
* A DATA SECTOR.
*
PREPDATA LDY DATASADR
 LDA DATASADR+1
 STY USRBUF
 STA USRBUF+1
 LDX CURDATS
 LDY CURDAS
 RTS 
*
 ORG $AFF7
*
* READ OR WRITE THE VTOC
*
RWVTOC LDA #$1
 BNE WRTVTOC1
WRTVTOC LDA #2
WRTVTOC1 LDY VTOCPADR
 STY USRBUF
 LDY VTOCPADR+1
 STY USRBUF+1
 LDX TRKNUMBR
 LDY #0
 JMP RWTSDRVR
*
 ORG $B011
*
* READ A DIRECTORY SECTOR
*
* If C=0 read first dir sector.
* If C=1 read next dir sector.
*
*
RDDIRSC PHP
 JSR PRWTSDIR
 PLP 
 BCS RDDIRSC1
*
* Read first directory sector here
*
 LDY FRSTTS+1
 LDX FRSTTS
 BNE RDDIRSC3
RDDIRSC1 LDX TSNXTDIR
 BNE RDDIRSC2
*
*
* If there are no more dir
* sectors, exit with error flag
* (carry) set.
*
 SEC 
 RTS 
*
* Read next dir sector in chain
* here.
*
RDDIRSC2 LDY TSNXTDIR+1
RDDIRSC3 STX DIRTS
 STY DIRTS+1
 LDA #$1
 JSR RWTSDRVR
 CLC 
 RTS 
*
 ORG $B037
*
* WRITE A DIRECTORY SECTOR
*
WRTDIRSC JSR PRWTSDIR
 LDX DIRTS
 LDY DIRTS+1
 LDA #2
 JMP RWTSDRVR
*
*
* PREP RWTS FOR DIRECTORY READ/WRT
*
PRWTSDIR LDA DIRPADR
 STA USRBUF
 LDA DIRPADR+1
 STA USRBUF+1
 RTS 
*
 ORG $B052
*
* RWTS DRIVER, FINISHES UP THE IOB
* AND CALLS THE RWTS ROUTINE
*
RWTSDRVR STX TNUM
 STY SNUM
STCMDCD STA CMDCODE
 CMP #2
 BNE STCMDCD1
*
* If writing to disk, note this
* in "FLAGS".
*
 ORA FLAGS
 STA FLAGS
*
* Compliment the volume number
*
STCMDCD1 LDA VOLNUMBR
 EOR #$FF
 STA VOLEXPT
*
* Init such niceties as slot,
* drive, sector, etc.
*
 LDA SLOT16
 STA SNUM16
 LDA DRVNUMBR
 STA DNUM
 LDA SECTLEN
 STA BYTCNT
 LDA SECTLEN+1
 STA BYTCNT+1
 LDA #$1
 STA TBLTYPE
*
* Call the RWTS subroutine
*
 LDY RWTSPADR
 LDA RWTSPADR+1
 JSR CLLRWTS
*
* Fiddle with the volume numbers
* before checking for an error
*
*
 LDA VOLFND
 STA VOLVAL
 LDA #$FF
 STA VOLEXPT
*
* If no error, quit
*
 BCS STCMDCD2
 RTS 
*
 ORG $B0A1
*
* Convert RWTS error # to an
* error number usable by the
* file manager.
*
STCMDCD2 LDA ERRRCODE
 LDY #7
 CMP #$20
 BEQ STCMDCD3
 LDY #4
 CMP #$10
 BEQ STCMDCD3
 LDY #8
STCMDCD3 TYA
 JMP SETERRR
*
 ORG $B0B6
*
* READ NEXT DATA SECTOR IF REQ'D
*
*
* Check to see if the current file
* position is in the current data
* sector buffered up in memory.
*
RDNXTDA LDA FILEPOSN
 CMP RELSLRD
 BNE RDNXTDA1
 LDA FILEPOSN+1
 CMP RELSLRD+1
 BEQ SLDBUF2
*
* If not, see if the current
* sector needs to be written to
* disk.
*
RDNXTDA1 JSR CHKBUF
*
*
* Is the desired file position
* within the range of sectors
* represented by the T/S list
* currently buffered in memory?
*
RDNXTDA2 LDA FILEPOSN+1
 CMP RELSFRST+1
 BCC RDNXTDA4 ;go if <
 BNE RDNXTDA3 ;go if >
 LDA FILEPOSN
 CMP RELSFRST
 BCC RDNXTDA4
*
RDNXTDA3 LDA FILEPOSN+1
 CMP RELSLAST+1
 BCC FNDTS
 BNE RDNXTDA4
 LDA FILEPOSN
 CMP RELSLAST
 BCC FNDTS
*
* Read in new T/S list, Carry is
* set or cleared from CMP's above.
*
*
RDNXTDA4 JSR RDTSLST
 BCC RDNXTDA2
 RTS
*
 ORG $B0F3
*
* DATA WAS FOUND IN CURRENT T/S
* LIST, GET ENTRY IN THIS T/S LIST
*
FNDTS SEC 
 LDA FILEPOSN
 SBC RELSFRST
 ASL 
 ADC #$C
 TAY 
 JSR SELTSBUF
 LDA (BUFADR),Y
 BNE READOLD
 LDA FMOPCOD
 CMP #4
 BEQ FNDTS1
 SEC 
 RTS 
FNDTS1 JSR ADDATA
 JMP SAVSECNM
*
 ORG $B114
*
* READ EXISTING DATA USING CURRENT
* T/S LIST
*
READOLD STA CURDATS
 INY 
 LDA (BUFADR),Y
 STA CURDAS
 JSR RDDASEC
*
* SAVE SECTOR NUMBER OF SECTOR
* LAST READ IN THE WORKAREA
*
SAVSECNM LDA FILEPOSN
 STA RELSLRD
 LDA FILEPOSN+1
 STA RELSLRD+1
*
*
* SELECT DATA BUFFER
*
SLDBUF2 JSR SLDABUF
 LDY FILEPOSN+2
 CLC 
 RTS 
*
 ORG $B134
*
* ADD A NEW DATA SECTOR TO THE
* FILE
*
ADDATA STY CNTR
*
* Allocate a sector for the data.
*
 JSR ALLOCSEC
*
* Put T/S numbers into T/S list.
*
 LDY CNTR
 INY 
 STA (BUFADR),Y
 STA CURDAS
 DEY 
 LDA SCALAREA+1
 STA (BUFADR),Y
 STA CURDATS
*
* Select data buffer and zero it
* out.
*
 JSR SLDABUF
 JSR ZEROBUF
*
* set up flags noting that the
* current data and T/S sectors
* must be written to disk.
*
 LDA #$C0
 ORA FLAGS
 STA FLAGS
 RTS 
*
 ORG $B15B
*
*
* VARIOUS UTILITIES USED ALL OVER
* THE PLACE
*
*
* INCREMENT RECORD NUMBER AND
* BYTE OFFSET INTO THE FILE
*
INCREC LDX RECNUMBR
 STX RECNUM
 LDX RECNUMBR+1
 STX RECNUM+1
 LDX BYTEOFFS
 LDY BYTEOFFS+1
 STX VOLVAL
 STY DRVVAL
 INX 
 BNE INCREC1
 INY 
INCREC1 CPY OPNRCLEN+1
 BNE INCREC2
 CPX OPNRCLEN
 BNE INCREC2
 LDX #0
 LDY #0
 INC RECNUMBR
 BNE INCREC2
 INC RECNUMBR+1
INCREC2 STX BYTEOFFS
 STY BYTEOFFS+1
 RTS 
*
 ORG $B194
*
* INCREMENT FILE POSITION
* OFFSET
*
INCPOS INC FILEPOSN+2
 BNE INCPOS1
 INC FILEPOSN
 BNE INCPOS1
 INC FILEPOSN+1
INCPOS1 RTS
*
 ORG $B1A2
*
* COPY AND ADVANCE RANGE ADDRESS
*
MOVRANG LDY DATABYTE
 LDX DATABYTE+1
 STY BUFADR
 STX BUFADR+1
 INC DATABYTE
 BNE MOVRANG1
 INC DATABYTE+1
MOVRANG1 RTS
*
 ORG $B1B5
*
* DECREMENT RANGE ADDRESS
*
DECRNG LDY SLOTVAL
 BNE DECRNG1
 LDX FILETYPE
 BEQ DECRNG2
 DEC FILETYPE
DECRNG1 DEC SLOTVAL
 RTS
DECRNG2 JMP NOERROR
*
 ORG $B1C9
*
* LOCATE A DIRECTORY ENTRY.
* LOOKS UP A FILENAME IN THE
* DIRECTORY.
*
*
* Read VTOC to get track and
* sector number of first dir
* sector.
*
LCDIRENT JSR RWVTOC
 LDA FNADR
 STA BUFADR
 LDA FNADR+1
 STA BUFADR+1
*
* Set up for two passes through
* the directory.
*
 LDA #$1
INITDIR STA CNTR
*
* Set up index into VTOC for
* the dir track.
*
 LDA #0
 STA DIRSECIX
 CLC 
*
* Read in the current dir sector.
*
INCSECOF INC DIRSECIX
 JSR RDDIRSC
 BCS PASS2
*
* Check for end of dir (if first
* byte is zero) or a deleted
* file (if minus, really should
* be $FF).
*
 LDX #0
GETRACK STX DIRINDX
 LDA TSTRACK,X
 BEQ DOPASS2
 BMI CHKPASS
 LDY #0
 INX 
 INX 
*
* Compare the filename against
* the current dir entry.
*
GETRACK1 INX
 LDA (BUFADR),Y
 CMP TSTRACK,X
 BNE GETRACK2
 INY 
 CPY #$1E
 BNE GETRACK1
*
* If found, return with index
* into sector in the X register
* and the carry flag cleared.
*
 LDX DIRINDX
 CLC 
 RTS 
*
 ORG $B20B
*
* If filename doesn't match
* current entry, on to the next 1.
*
GETRACK2 JSR NXTDIREN
 BCC GETRACK
 BCS INCSECOF
DOPASS2 LDY CNTR
 BNE INITDIR
CHKPASS LDY CNTR
 BNE GETRACK2
*
 ORG $B21C
*
* COPY FILE NAME TO DIRECTORY
* ENTRY.
*
COPFNAM LDY #0
 INX 
 INX 
COPFNAM1 INX
 LDA (BUFADR),Y
 STA TSTRACK,X
 INY 
 CPY #$1E
 BNE COPFNAM1
 LDX DIRINDX
 SEC 
 RTS 
*
 ORG $B230
*
* MOVE ON TO THE NEXT DIRECTORY
* ENTRY.
*
NXTDIREN CLC 
 LDA DIRINDX
 ADC #$23
 TAX 
 CPX #$F5
 RTS 
PASS2 LDA #0
 LDY CNTR
 BNE INITDIR
 JMP DSKFULL
*
 ORG $B244
*
* ALLOCATE A DISK SECTOR.
*
* This routine finds a track in
* the track bit map stored in
* memory that has some empty
* sectors left.
* ALLOCSEC then allocates the
* rest of those sectors and
* gives them to the requesting
* file.
*
*
* First, see if there is a
* track already allocated to this
* file.
*
ALLOCSEC LDA SCALAREA+1
 BEQ NOTRKAVL
*
* If so, decrement sector count
* to find the next possible
* sector #.
*
TSTNXT DEC SCALAREA
 BMI NOSECAVL
*
* If a valid sector, rotate the
* bit map to see if it is free.
*
 CLC 
 LDX #4
TSTNXT1 ROL SCALAREA+1,X
 DEX 
 BNE TSTNXT1
*
* If not free, repeat for next
* sector.
*
 BCC TSTNXT
*
* If free, allocate and increment
* file size by one.
*
 INC SECCNT
 BNE TSTNXT2
 INC SECCNT+1
TSTNXT2 LDA SCALAREA
 RTS 
*
 ORG $B265
*
* Indicate that a track is not
* currently allocated.
*
NOSECAVL LDA #0
 STA SCALAREA+1
*
* Reset allocation flag to
* allow a complete scan of the
* bit map for available sectors.
*
NOTRKAVL LDA #0
 STA ALLCFLG
 JSR RWVTOC
*
* Add allocation director to
* NXTTOALLC and see if we are
* at track zero, or past
* track 34.
*
ADDIRCTN CLC 
 LDA NXTTOALC
 ADC ALLCDIR
 BEQ SCNDTIME
 CMP NUMTRKS
 BCC ADIRTRK1
*
* If past track 34, set allocation
* direction to -1.
*
 LDA #$FF
 BNE ADIRTRK
SCNDTIME LDA ALLCFLG
 BNE DODSKFUL
 LDA #$1
 STA ALLCFLG
*
* Start at the dir track and
* work backwards.
*
ADIRTRK STA ALLCDIR
 CLC 
 ADC #$11
ADIRTRK1 STA NXTTOALC
 STA SCALAREA+1
 TAY 
 ASL 
 ASL 
 TAY 
 LDX #4
 CLC 
ADIRTRK2 LDA BTMPEND,Y
 STA SCALAREA+1,X
 BEQ ADIRTRK3
 SEC 
 LDA #0
 STA BTMPEND,Y
ADIRTRK3 DEY
 DEX 
 BNE ADIRTRK2
 BCC ADDIRCTN
*
* Allocated an entire track,
* write out the VTOC so other
* files don't use 'em
*
 JSR WRTVTOC
 LDA NUMSCTRS
 STA SCALAREA
 BNE TSTNXT
DODSKFUL JMP DSKFULL
*
 ORG $B2C3
*
* RELEASE ANY ALLOCATED SECTORS
* THAT WERE NOT USED.
*
RLSALLC LDA SCALAREA+1
 BNE RLSALLC1
 RTS 
RLSALLC1 PHA
 JSR RWVTOC
 LDY SCALAREA
 PLA 
 CLC 
 JSR RRBITMP
 LDA #0
 STA SCALAREA+1
 JMP WRTVTOC
*
 ORG $B2DD
*
* ROTATE THE BIT MAP RIGHT ONE
* BIT.
* THIS CHECKS FOR AVAILABLE SECS
*
RRBITMP LDX #$FC
RRBITMP1 ROR TMPBITMP,X
 INX 
 BNE RRBITMP1
 INY 
 CPY NUMSCTRS
 BNE RRBITMP
 ASL 
 ASL 
 TAY 
 BEQ RRBITMP3
 LDX #4
RRBITMP2 LDA SCALAREA+1,X
 ORA BTMPEND,Y
 STA BTMPEND,Y
 DEY 
 DEX 
 BNE RRBITMP2
RRBITMP3 RTS
*
 ORG $B300
*
* CALCULATE FILE POSITION.
*
* GIVEN A RECORD NUMBER, A FILE
* LENGTH, AND A BYTE OFFSET THIS
* ROUTINE CALCULATES THE OFFSET
* INTO THE FILE TO FIND THE
* DESIRED RECORD.
*
CALPOSN LDA RECNUM
 STA FILEPOSN+2
 STA RECNUMBR
 LDA RECNUM+1
 STA FILEPOSN
 STA RECNUMBR+1
 LDA #0
 STA FILEPOSN+1
 LDY #$10
CALPOSN1 TAX
 LDA FILEPOSN+2
 LSR 
 BCS CALPOSN2
 TXA 
 BCC CALPOSN3
CALPOSN2 CLC
 LDA FILEPOSN+1
 ADC OPNRCLEN
 STA FILEPOSN+1
 TXA 
 ADC OPNRCLEN+1
CALPOSN3 ROR
 ROR FILEPOSN+1
 ROR FILEPOSN
 ROR FILEPOSN+2
 DEY 
 BNE CALPOSN1
 LDA VOLVAL
 STA BYTEOFFS
 ADC FILEPOSN+2
 STA FILEPOSN+2
 LDA DRVVAL
 STA BYTEOFFS+1
 ADC FILEPOSN
 STA FILEPOSN
 LDA #0
 ADC FILEPOSN+1
 STA FILEPOSN+1
 RTS 
*
 ORG $B35F
*
* MULTIPLY CALLED ERROR MESSAGES
*
LNOTAVL LDA #$1
 BNE SETERRR
RANGERR LDA #2
 BNE SETERRR
RANGERR2 LDA #3
 BNE SETERRR
 LDA #4
 BNE SETERRR
ENDATA LDA #5
 BNE SETERRR
FNOTFND LDA #6
 BNE SETERRR
DSKFULL JMP DISKFULL
 NOP 
FILELOCK LDA #$A
 BNE SETERRR
NOERROR LDA RTNCODE
 CLC 
 BCC SETERRR1
*
 ORG $B385
*
* STANDARD ERROR ENTRY POINT
*
SETERRR SEC
SETERRR1 PHP
 STA RTNCODE
 LDA #0
 STA IOBADR
 JSR SAVFMW
 PLP 
 LDX STKSAVE
 TXS 
 RTS 
*
 ORG $B397
*
* VARIABLES ETC.
*
DIRTS DS 2
 DS 2
STKSAVE DS 1
DIRINDX DS 1
CNTR DS 1
ALLCFLG DS 2
FREEMASK DS 4
DECTBL HEX 010A64
FTTBL ASC "TIABSRAB"
DISKVOL ASC " EMULOV KSID"
VTOCSB DS 1
FRSTTS DS 2
DOSRLS HEX 03
 DS 2
DSKVOL DS $21
NUMTSENT DS 9
NXTTOALC DS 1
ALLCDIR DS 3
NUMTRKS DS 1
NUMSCTRS DS 3
BITMAP DS 3
BTMPEND DS $C5
DIRSECBF DS 1
TSNXTDIR DS 10
TSTRACK DS 1
TSSECTOR DS 1
FILTYP DS $1F
FILESIZE DS $F
TMPBITMP DS $AE
PTCHSAV DS $17
*
*
*
FMOPCOD DS 1
SUBCODE DS 1
RECNUM DS 2
VOLVAL DS 1
DRVVAL DS 1
SLOTVAL DS 1
FILETYPE DS 1
DATABYTE = *
FNADR DS 2
RTNCODE DS 2
WBADR DS 2
TSLSTADR DS 2
DATASADR DS 2
 DS 4
FTSTS DS 1
FTSS DS 1
CURTSTS DS 1
CURTSS DS 1
FLAGS DS 1
CURDATS DS 1
CURDAS DS 1
DIRSECIX DS 2
SECPERTS DS 2
RELSFRST DS 2
RELSLAST DS 2
RELSLRD DS 2
SECTLEN DS 2
FILEPOSN DS 3
 DS 1
OPNRCLEN DS 2
RECNUMBR DS 2
BYTEOFFS DS 2
SECCNT DS 2
SCALAREA DS 1
 DS 5
FTYPE DS 1
SLOT16 DS 1
DRVNUMBR DS 1
VOLNUMBR DS 1
TRKNUMBR DS 6
*
 ORG $800
*
* START OF 2ND STAGE BOOTSTRAP
*
BOOT HEX 01
 LDA SCRATCH
 CMP #9
 BNE BOOT1
 LDA BOOTSLOT
 LSR 
 LSR 
 LSR 
 LSR 
 ORA #$C0
 STA ROMRWTS+1
 LDA #$5C
 STA ROMRWTS
 CLC 
 LDA FRSTPAG
 ADC NUMSECS
 STA FRSTPAG
BOOT1 LDX NUMSECS
 BMI BOOT2
 LDA SECTABL,X
 STA SECNUM
 DEC NUMSECS
 LDA FRSTPAG
 STA SCRATCH
 DEC FRSTPAG
 LDX BOOTSLOT
 JMP (ROMRWTS)
BOOT2 INC FRSTPAG
 INC FRSTPAG
 JSR SETKBD
 JSR SETVID
 JSR MONINIT
 LDX BOOTSLOT
 JMP (JMP2BOOT)
*
*
SECTABL HEX 000D0B0907
 HEX 0503010E0C
 HEX 0A080604
 HEX 02
 HEX 0F
*
*
* THE FOLLOWING ARE ALL PATCHES
* FOR APPEND AND VERIFY
*
*
APPFLG DFB 0
APDPTCH JSR LOCBUF
 BCS APDPTCH1
 LDA #0
 TAY 
 STA APPFLG
 STA (DOSIMG),Y
APDPTCH1 LDA RTNCODE
 JMP DOERROR
 LDA APPFLG
 BEQ APDPTCH2
 INC RECNUM
 BNE APDPTCH2
 INC RECNUM+1
APDPTCH2 LDA #0
 STA APPFLG
 JMP RWC2
 STA SUBCODE
 JSR FMDRVR
 JSR DOCLOSE
 JMP DOVERIFY
 LDY #$13
APDPTCH3 LDA (BUFADR),Y
 BNE APDPTCH6
 INY 
 CPY #$17
 BNE APDPTCH3
 LDY #$19
APDPTCH4 LDA (BUFADR),Y
 STA PTCHSAV,Y
 INY 
 CPY #$1D
 BNE APDPTCH4
APDPTCH5 JMP FMDRVR0
APDPTCH6 LDX #$FF
 STX APPFLG
 BNE APDPTCH5
*
*
 DS 19
 DS 24
 DS 31
*
JMP2BOOT DS 1
FRSTPAG HEX 36
NUMSECS HEX 09
*
 ORG $3600
*
* DOS SECOND STAGE BOOT PGM
*
 STX SNUM16
 STX SLOTFND
 LDA #$1
 STA DRVFND
 STA DNUM
 LDA NUMPGS
 STA NSECSRW
 LDA #2
 STA TNUM
 LDA #4
 STA SNUM
 LDY FRSTBOOT+1
 DEY 
 STY USRBUF+1
 LDA #$1
 STA CMDCODE
 TXA 
 LSR 
 LSR 
 LSR 
 LSR 
 TAX 
 LDA #0
 STA DRV1TRAK,X
 STA DRV0TRAK,X
 JSR RWPAGES
 LDX #$FF
 TXS 
 STX VOLEXPT
 JMP REBOOT
 JSR SETKBD
 JMP DOSSTRT
*
* PUTDOS- WRITES DOS ON FIRST
* TWO TRACKS OF DISK
*
PUTDOS LDA FRSTBOOT+1
 SEC 
 SBC USRBUF+1
 STA NSECSRW
 LDA FRSTBOOT+1
 STA USRBUF+1
 DEC USRBUF+1
 LDA #2
 STA TNUM
 LDA #4
 STA SNUM
 LDA #2
 STA CMDCODE
 JSR RWPAGES
 LDA FRSTBOOT+1
 STA FRSTPAG
 CLC 
 ADC #9
 STA USRBUF+1
 LDA #$A
 STA NSECSRW
 SEC 
 SBC #$1
 STA NUMSECS
 STA SNUM
 JSR RWPAGES
 RTS 
 DS 6
RWPAGES LDA RWTSPPTR+1
 LDY RWTSPPTR
 JSR CLLRWTS
 LDY SNUM
 DEY 
 BPL RWPAGES1
 LDY #$F
 NOP 
 NOP 
 DEC TNUM
RWPAGES1 STY SNUM
 DEC USRBUF+1
 DEC NSECSRW
 BNE RWPAGES
 RTS 
*
 ORG $B7B5
*
CLLRWTS PHP
 SEI 
 JSR RWTSENT
 BCS CLLRWTS1
 PLP 
 CLC 
 RTS 
CLLRWTS1 PLP
 SEC 
 RTS 
RWTSPRMS LDA SUBCODE
 STA USRBUF+1
 LDA #0
 STA USRBUF
 LDA VOLNUMBR
 EOR #$FF
 STA VOLEXPT
 RTS 
ZEROBUF LDA #0
 TAY 
ZEROBUF1 STA (BUFADR),Y
 INY 
 BNE ZEROBUF1
 RTS 
 HEX 00
NUMPGS HEX 1B
NSECSRW HEX 000A1B
RWTSPPTR DA $B7E8
FRSTBOOT DA $B600
IOB = *
TBLTYPE HEX 01
SNUM16 HEX 60
DNUM HEX 01
VOLEXPT HEX FF
TNUM HEX 0C
SNUM HEX 08
 DA DVCTBL
USRBUF DA $9600
BYTCNT DA $100
CMDCODE HEX 02
ERRRCODE HEX 07
VOLFND HEX FE
SLOTFND HEX 60
DRVFND HEX 01
UNUSED HEX 000000
DVCTBL HEX 01EFD800
000000
DVCTBL HEX 01EFD800