Created
April 2, 2016 01:40
-
-
Save claus/118a26c6bef7ae6ebe338797b074a7e1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; | |
; Apple DOS 3.1 Disassembly - (Patched Release - RAWDOS) | |
; | |
; This disassembly is based on the original pre-release Apple DOS source | |
; code written in 1978 by Paul Laughton, then an employee of Shepardson | |
; Microsystems. The source document is identified on the title page with | |
; the following text: | |
; | |
; .TITLE SHEP,'APPLE DOS' | |
; 6.3 10-6-78 | |
; 8 BIT ASSEMBLER | |
; .M6502 | |
; | |
; The binary produced by assembling this source has been compared to | |
; the RAWDOS binary included on the Apple DOS 3.1 Master Disk and was | |
; was found to be identical with one exception: | |
; | |
; Assembling this source code into a binary will generally initialize | |
; reserved memory byte (RMB) address spaces as well as any unused address | |
; space (addresses located between the end of a given section of code and | |
; a new ORG directive) to 0x00 or 0xff, depending on the assembler used. | |
; | |
; Accordingly, all comparisons to the original DOS 3.1 binary insured | |
; that the only differences were with byte values that were located in | |
; unused address locations or in RMB address locations. | |
; | |
; | |
; Scott LaBombard | |
; labomb@rochester.rr.com | |
; 12/04/2013 | |
; | |
#INCLUDE "MOTO.H" | |
.TITLE "APPLE DOS 3.1" | |
* | |
************************************************************************************** | |
* (C) COPYRIGHT 1978 APPLE COMPUTER, INC | |
************************************************************************************** | |
ORG1 EQU $1B00 | |
ORG2 EQU $3600 | |
DISKIO EQU $3D00 | |
ASC1 EQU $3800 | |
AEC1 EQU $3A8F | |
ASC2 EQU $3D00 | |
AEC2 EQU $3FFF | |
EDOS EQU $4000 | |
PAGE | |
ORG ORG1 | |
BEGIN JMP DBINIT | |
; | |
DOSREL | |
; | |
; GET RELOCATION PARMS | |
; | |
DR0 | |
LOC1 EQU $26 | |
LDA #$BF ; START AT BF00 | |
STA !ZPGWRK+1 ; TO LOOK FOR | |
LDX #0 ; HIGH RAM | |
STX !ZPGWRK | |
DR1B | |
LDY #0 ;APPLE TEST | |
LDA (ZPGWRK,X) | |
STA LOC1 | |
DR1 TYA | |
EOR LOC1 | |
STA LOC1 | |
TYA | |
EOR (ZPGWRK,X) | |
STA (ZPGWRK,X) | |
CMP LOC1 | |
BNE DR1A | |
INY | |
BNE DR1 | |
BEQ DR2 ; BR IF TOOK | |
DR1A | |
DEC !ZPGWRK+1 ; NOT RAM | |
BNE DR1B ; TRY NEXT PAGE | |
; | |
DR2 | |
; | |
JSR DR2PAT ; *** PATCH *** | |
INY ; NEW END OF DOS | |
STY NEPAGE | |
SEC | |
TYA | |
SBC DOSLNG ; MINUS DOS LENGTH | |
STA NSPAGE ; IS NEW START OF DOS | |
SEC | |
SBC RSPAGE ; MINUS OLD DOS START | |
BEQ BEGIN ; (BREIF NO DELTA) | |
STA DELTA ; IS DELTA | |
PAGE | |
LDA RSPAGE ; RESET START PAGE TO NORMAL | |
STA ASTART+1 | |
; | |
LDA #DBINIT/256 ;RESET PI RTN TO NORMAL | |
STA DI3+2 | |
LDA #DBINIT&255 | |
STA DI3+1 | |
; | |
; | |
PAGE | |
; | |
; | |
; RELOCATE ADR TABLES | |
; | |
LDX #0 | |
STX !ZPGWRK | |
DR3 | |
LDA ADRTAB+1,X | |
TAY | |
LDA ADRTAB+2,X | |
STA !ZPGWRK+1 | |
JMP DR5 | |
; | |
DR4 | |
CLC | |
LDA (ZPGWRK),Y | |
ADC DELTA | |
STA (ZPGWRK),Y | |
INY | |
BNE DR5 | |
INC !ZPGWRK+1 | |
DR5 INY | |
BNE DR6 | |
INC !ZPGWRK+1 | |
; | |
DR6 | |
LDA !ZPGWRK+1 | |
CMP ADRTAB+4,X | |
BCC DR4 | |
TYA | |
CMP ADRTAB+3,X | |
BCC DR4 | |
; | |
TXA | |
CLC | |
ADC #4 | |
TAX | |
CPX ADRTAB | |
BCC DR3 | |
PAGE | |
; | |
; RELOCATE CODE | |
; | |
LDX #0 | |
DR7 STX TEMP1 | |
; | |
LDA CDETAB+1,X ; GET A START OF CODE ADR | |
STA !ZPGWRK ; PUT IN ZPG | |
LDA CDETAB+2,X | |
STA !ZPGWRK+1 | |
; | |
DR8 LDX #0 | |
LDA (ZPGWRK,X) ; GET OP CODE | |
JSR INSDS2 ; GO FIND OUT HOW LONG | |
; | |
LDY !LENGTH ; GET HOW LONG | |
CPY #2 ; IF IT AIN’T | |
BNE DR9 ; 3 THEN DON’T RELOC | |
LDA (ZPGWRK),Y ; GET PAGE FROM INST | |
CMP RSPAGE ; IF PAGE < REL START | |
BCC DR9 ; THEN IGNORE | |
CMP REPAGE ; IF PAGE >= REL END | |
BCS DR9 ; THEN IGNORE | |
ADC DELTA ; ELSE ADD DELTA | |
STA (ZPGWRK),Y ; TO RELOCATE | |
; | |
DR9 SEC | |
LDA !LENGTH ; ADD LENGTH | |
ADC !ZPGWRK ; TO PC | |
STA !ZPGWRK | |
LDA #0 | |
ADC !ZPGWRK+1 | |
STA !ZPGWRK+1 | |
; | |
LDX TEMP1 ; CHECK FOR END | |
CMP CDETAB+4,X ; OF CODE SEGMENT | |
BCC DR8 ; BR NOT END | |
LDA !ZPGWRK | |
CMP CDETAB+3,X | |
BCC DR8 ; BR NOT END | |
; | |
TXA | |
CLC | |
ADC #4 ; INCREMENT TABLE INDEX | |
TAX | |
CPX CDETAB ; DONE | |
BCC DR7 ; BR IF NOT | |
; | |
PAGE | |
; | |
; MOVE TO RELOCATED CODE | |
; | |
LDA #DEPAGE-1 | |
STA !ZPGWRK+1 ; ZPGWRK=FROM | |
LDY NEPAGE | |
DEY | |
STY !ZPGFCB+1 ; ZPGFCB = TOO | |
LDA #0 | |
STA !ZPGWRK | |
STA !ZPGFCB | |
TAY | |
; | |
DR10 LDA (ZPGWRK),Y ; BYTE FROM | |
STA (ZPGFCB),Y ; BYTE TO | |
INY ; INCREMENT | |
BNE DR10 ; BR NOT FULL PAGE | |
DEC DPGCNT ; DECREMENT PAGE CNT | |
BEQ DR11 ; BR IF DONE | |
DEC !ZPGWRK+1 ; INC FROM PAGE | |
DEC !ZPGFCB+1 ; INC TOO PAGE | |
BNE DR10 ; MOVE PAGE | |
; | |
DR11 JMP DBVECT+3 ; DONE | |
PAGE | |
DEPAGE EQU EDOS/256 | |
DSPAGE EQU STARTT/256 | |
INSDS2 EQU $F88E | |
LENGTH EQU $2F | |
ADRTAB DB 9*4 | |
DW @@SAT1,@@EAT1 | |
DW @@RUN,@@RUN+2 | |
DW @@IBVT+2,@@IBVT+4 | |
DW @@AS1VT,@@AS1VT+4 | |
DW @@AS2VT,@@AS2VT+4 | |
DW @@AS2VT+6,@@AS2VT+8 | |
DW @@SAT2,@@EAT2 | |
DW @@BAIOB,@@ADOSLD+2 | |
DW @@IBDCTP,@@IBDCTP+2 | |
DW @0,@0 | |
DW @0,@0 | |
DW @0,@0 | |
CDETAB | |
DB 6*4 | |
DW @@SC1,@@EC1 | |
DW @@SC2,@@EC2 | |
DW @@SC3,@@EC3 | |
DW @@SDP1,@@EDP1 | |
DW @@ASC1,@@AEC1 | |
DW @@ASC2,@@AEC2 | |
DW @0,@0 | |
; | |
RSPAGE DB DSPAGE | |
REPAGE DB DEPAGE | |
; | |
NSPAGE DB 0 | |
NEPAGE DB 0 | |
; | |
DOSLNG DB DEPAGE-DSPAGE | |
; | |
DELTA DB 0 | |
DPGCNT DB DEPAGE-DSPAGE | |
PAGE | |
BOUND 256 | |
; | |
; RELOCATION TABLES | |
; | |
START | |
SAT1 | |
FTAB DW @@*-45 ;START OF FTABS | |
CINA DW @@CHRIN ;CHAR IN ADR | |
COUTA DW @@CHROUT ;CHAR OUT ADR | |
FN1ADR DW @@FNAME1 | |
FN2ADR DW @@FNAME2 | |
SVBLA DW @@SVBL | |
ASTART DW @@BEGIN ; CHANGED TO START BY RELOCATE | |
CCBADR DW @@CCB | |
; | |
OUTSVT ;CHAR OUTPUT STATE VECTOR TABLE | |
DW @@COS0-1 | |
DW @@COS1-1 | |
DW @@COS2-1 | |
DW @@COS3-1 | |
DW @@COS4-1 | |
DW @@COS5-1 | |
DW @@COS6-1 | |
; COMMAND EXECUTION TABLE | |
CMDETB | |
DW @@EINIT-1 | |
DW @@ELOAD-1 | |
DW @@ESAVE-1 | |
DW @@ERUN-1 | |
DW @@ECHAIN-1 | |
DW @@EDEL-1 | |
DW @@ELOCK-1 | |
DW @@EUNLK-1 | |
DW @@ECLOSE-1 | |
DW @@EREAD-1 | |
DW @@EEXEC-1 | |
DW @@EWRITE-1 | |
DW @@EPOS-1 | |
DW @@EOPEN-1 | |
DW @@EAPND-1 | |
DW @@EREN-1 | |
DW @@ECAT-1 | |
DW @@EMON-1 | |
DW @@ENOMON-1 | |
DW @@EPR-1 | |
DW @@EIN-1 | |
DW @@EMAXF-1 | |
DW @@EAS-1 | |
DW @@EINT-1 | |
DW @@EBSV-1 | |
DW @@EBLD-1 | |
DW @@EBRUN-1 | |
DW @@EVAR-1 | |
EAT1 | |
PAGE | |
; | |
; NON-RELOCATING ADRS | |
; | |
IBASVT | |
CHAIN DW @@IBCHN | |
RUN DW @@IBRUN | |
BREAK DW @@IBBRK | |
GO DW @@IBGO | |
CONT DW @@IBCONT ;BASIC CONT ENTRY POINT | |
IBVT DW @@IBCHN,@@IBRUN,@@IBBRK | |
DW @@IBGO,@@IBCONT | |
IBVTL EQU *-IBVT | |
; | |
AS1VT DW @@ASRUN1,@@ASRUN1,@@ASBRK1 | |
DW @@IBGO,@@0 | |
AS1VTL EQU *-AS1VT | |
; | |
AS2VT DW @@ASRUN2,@@ASRUN2,@@ASBRK2 | |
DW @@DBINIT,@@0 | |
AS2VTL EQU *-AS2VT | |
PAGE | |
; | |
; EQUATES REQD TO FIND THINGS IN APPLE II | |
; | |
SETVID EQU $FE93 | |
SETKBD EQU $FE89 | |
PROMPT EQU $33 ; PROMPT CHAR | |
OUTSW EQU $36 ;OUTPUT VECTOR SWITCH | |
INSW EQU $38 ;INPUT VECTOR SWITCH | |
ZPGWRK EQU $40 ;ZERO PAGE WORK CELL | |
CNUM EQU $44 ;CONVERTED NUMERIC | |
LBUFF EQU $200 ;LINE BUFFER | |
MULT EQU $FB63 ;MULT ROUTINE | |
INPRT EQU $FE8B ;SET IN PORT | |
OUTPRT EQU $FE95 ; SET OUT PORT | |
IBCHN EQU $E836 ;BASIC RUN | |
IBLMEM EQU $4A ;BASIC LOW MEMORY | |
IBHMEM EQU $4C ;INTEGER BASIC HIMEM | |
IBSOP EQU $CA ;INTEGER BASIC START OF CGM | |
IBBRK EQU $E3E3 ; BASIC BREAK | |
IBGO EQU $E000 ; BASIC ENTRY POINT | |
IBCONT EQU $E003 ; BASIC CONTINUE ENTRY POINT | |
IBSOV EQU $CC ; BASIC START OF VARIABLES | |
ASSOP EQU $67 ; AS START OF PROGRAM | |
ASEOP EQU $AF ; AS END OF PROGRAM | |
ASEOP2 EQU $69 ;AS END-OF PGM 2 | |
ASHM1 EQU $73 ; AS HIGH MEM 1 | |
ASHM2 EQU $6F ; AS HIGH MEM 2 | |
ASLMEM EQU ASSOP ; AS LOW MEM | |
ASBRK1 EQU $D865 ; AS ROM BREAK | |
ASBRK2 EQU $1067 ; AS RAM BREAK | |
AITSTL EQU $E000 ; AS 1 IB TEST LOC | |
ATSTV EQU $4C ; AS TEST VALUE | |
ITSTV EQU $20 ; IB TEST VALUE | |
BOOTSL EQU $2E ;BOOT FROM SLOT | |
ZPGFCB EQU $42 ;ZERO PAGE WORK CELL | |
HOME EQU $FC58 | |
PRINT EQU $FDED | |
GETKEY EQU $FD0C | |
PAGE | |
; | |
; DOS BASIC INTERPRETER – INITIAL ENTRY | |
; | |
SC1 | |
DBINIT | |
LDA IBSLOT ;GET BOOT SLOT | |
LSRA | |
LSRA | |
LSRA | |
LSRA | |
STA CS ;SET AS CURRENT SLOT | |
LDA IBDRVN ;GET BOOT DRIVE NUMBER | |
STA CD ;SET AS CURRENT DRIVE | |
LDA AITSTL ; GET APPLESOFT/IB TEST | |
EOR #ITSTV ; IF AS THEN | |
BNE IAS1 ; GO TO AS INIT | |
; ; ELSE INIT FOR IB | |
STA ASIBSW ; SET SW FOR IB | |
LDX #IBVTL ; GET IB VT LENGTH | |
IIB1 LDA IBVT-1,X ; MOVE IB ADDR | |
STA IBASVT-1,X | |
DEX | |
BNE IIB1 | |
JMP INITAA | |
; | |
IAS1 | |
LDA #$40 ; INDICATE ROM APPLESOFT | |
STA ASIBSW | |
LDX #AS1VTL | |
IAS1A LDA AS1VT-1,X ; MOVE ROM AS ADRS | |
STA IBASVT-1,X | |
DEX | |
BNE IAS1A | |
; | |
INITAA | |
SEC ; INDICATE INIT | |
BCS INITA | |
DBRST | |
CLC ; INDICATE RESET | |
; | |
INITA | |
PHP ; SAVE INIT/RESET | |
JSR MVCSW ; GO MOVE CHAR SWITCH | |
LDA #MC+MI+MO ; SET MONITOR MODES | |
STA MONMOD | |
LDA #0 | |
STA OSTATE ; CLEAR OUTSTATE AND EXECUTE STATE | |
PLP ; GET INIT/RESET | |
RORA ;SHIFT CARRY TO MSB | |
STA ISTATE ; SAVE INSTATE | |
BMI INITB ; BR IF INIT | |
JMP (CONT) ;GO TO CONTINUE ENTRY | |
INITB JMP (GO) ; GO TO ENTRY | |
PAGE | |
INITC | |
ASLA ; OF ISTATE NOT ON | |
BPL INITD ; THEN NOT RAM AS | |
STA ASIBSW ; SET RAM AS | |
LDX #AS2VTL | |
IAS2A LDA AS2VT-1,X ; MOVE RAM AS ADRS | |
STA IBASVT-1,X | |
DEX | |
BNE IAS2A | |
LDX #29 | |
IAS2B LDA FNAME2,X | |
STA FNAME1,X | |
DEX | |
BPL IAS2B | |
; | |
INITD | |
LDA DFNFTS ; GO BUILD FILE TABS | |
STA CNFTBS ; AND SET MEM BOUNDS | |
JSR BLDFTB | |
LDA ESTATE ;GET EXEC STATE | |
BEQ INITZ ; BR IF NOT EXECTUTE | |
PHA ;SVE CHAR | |
JSR MVEFTA ;GO MOVE EX FILE TAB ADR TO ZP | |
PLA ;GET SAVED CHAR | |
LDY #0 | |
STA (ZPGWRK),Y ; | |
INITZ | |
JSR CLRSTS ; SET IN AND OUT STATES TO ZERO | |
LDX #IFBL | |
INITE LDA DBVECT,X ;MOVE RESTART VECTORS | |
STA $3D0,X | |
DEX | |
BPL INITE | |
LDA CMDNO ; IF NOT BOOT | |
BNE INITF ; THEN DONE | |
LDA FNAME1 ; IF FN1 | |
EOR #$A0 ; NOT DONE | |
BEQ INITF ; THEN DONE | |
JMP ERUN ; ELSE | |
; | |
IFB | |
INITF | |
LDA SVCMD | |
BEQ INITG | |
STA CMDNO | |
JMP CMDGO | |
INITG | |
JMP ORTN | |
; | |
DBVECT JMP DBRST | |
JMP DBINIT | |
JMP DOSENT | |
JMP DISKIO | |
CCBLDR | |
LDA CCBADR+1 | |
LDY CCBADR | |
RTS | |
IOBLDR | |
LDA AIOB+1 | |
LDY AIOB | |
RTS | |
IFBL EQU *-IFB-1 | |
PAGE | |
; | |
; CHRIN – CHAR RCVD VIA IN SWITCH | |
; | |
CHRIN | |
JSR SVREGS | |
LDA ISTATE ;IF NOT DISKIN | |
BEQ CHIN1 ;THEN BRANCH, ELSE | |
BPL CHIN0 | |
JMP INITC | |
CHIN0 | |
LDA SVA | |
STA ($28),Y | |
JMP INCFD ;AND GET CHAR FROM DISK | |
CHIN1 | |
LDA ESTATE | |
BEQ CHIN2 | |
JMP NXTEXC | |
CHIN2 | |
LDA #3 ;SET OUT CHAR | |
STA OSTATE ;STATE TO INPUT ECHO | |
JSR LDREGS | |
JSR GETIN | |
STA SVA | |
JMP ORTN | |
; | |
GETIN JMP (INSW) | |
; | |
; CHROUT – CHAR RCVD VIA OUTPUT SWITCH | |
; | |
CHROUT | |
JSR SVREGS ;SAVE REGS | |
; | |
LDA OSTATE ;GET OUT SPARE | |
ASLA | |
TAX | |
LDA OUTSVT+1,x ;GET ROUTINE ADR | |
PHA | |
LDA OUTSVT,x | |
PHA | |
LDA SVA | |
RTS ;GO TO ROUTINE | |
; | |
; SVREGS – SAVE REGS WHILE PROCESSING CHARS | |
; | |
SVREGS | |
STA SVA ;SAVE ACU | |
STX SVX | |
STY SVY | |
TSX | |
INX | |
INX | |
STX SVSTK | |
LDX #3 ;SET FOR FOUR BYTE MOVE | |
SVRB LDA SVOUTS,X ;MOVE SAVED OUT AND IN SW | |
STA OUTSW,X ;TO APPLE OUT/IN SW | |
DEX | |
BPL SVRB | |
RTS ;DONE | |
PAGE | |
; | |
; COS0 – 1ST CHAR OF PRINTED OUTPUT LINE | |
; CHECK FOR CNTL-D | |
; | |
COS0 | |
LDX ISTATE ; IS IN STATE NOT ZERO | |
BEQ COS01 | |
CMP #'?'+$80 ;THEN IS THIS ? | |
BEQ COS6 ;THEN PRINT ONLY IF MONITOR | |
CMP PROMPT | |
BEQ COS6 | |
COS01 | |
LDX #2 | |
STX OSTATE | |
CMP CCHAR ;IF NOT CNTL-D | |
BNE COS2 ; THEN GO TO STATE 2 | |
DEX | |
STX OSTATE ;ELSE STATE = 1 | |
DEX | |
STX LBUFD ;AND LBUFD=0 | |
; | |
; COS1 – ACCUMULATE CMD FROM PRINTED OUTPUT | |
; | |
COS1 | |
LDX LBUFD ;GET LINE BUFF DISPL | |
COS1A STA LBUFF,X ;PUT CHAR IN BUFF | |
INX ;INCR PTR | |
STX LBUFD ;SAVE PTR | |
CMP #$8D ;WAS THIS A CR | |
BNE CMDRTN ;IF NOT THEN PR CHAR | |
; | |
JMP SCNCMD ;GO SCAN COMMAND | |
; | |
; COS2 – PRINTED OUTPUT, NOT FIRST CHAR | |
; | |
COS2 | |
CMP #$8D ;IS IT A CR | |
BNE PRRTN ;BR IF NOT | |
LDX #0 ;SET FOR POSSIBLE C-D NEXT | |
STX OSTATE ;NEXT STATE | |
JMP PRRTN ;GO PRINT CHAR | |
PAGE | |
; | |
; COS3 – KEY IN ECHO PRINT | |
; | |
COS3 | |
LDX #0 | |
STX OSTATE ;RESET OUT STATE | |
CMP #$8D ;IS IT CR | |
BEQ COS3A ; IF CR THEN CMD CHECK | |
LDA ESTATE ;ELSE: IF NOT EXECUTE | |
BEQ PRRTN ; THEN PRINT CHAR | |
BNE DRTNI ; ELSE: PRINT IF MON INPUT | |
COS3A | |
LDX SVX ;GET LINE INDEX | |
JMP COS1A | |
; | |
; COS4 – DISK OUTPUT MODE | |
; | |
COS4 | |
CMP #$8D ;IS IT CR | |
BNE COS4A ;BR IF NOT CR | |
LDA #5 ;SET STATE FOR CNTL-D | |
STA OSTATE ;EXAMINE | |
COS4A JSR OCTD ;GO OUTPUT CHAR TO DISK | |
JMP DRTNO ;GO TO DATA RETURN (OUT) | |
; | |
; COS5 – DISK OUTPUT MODE – 1ST CHAR OF A LINE | |
; | |
COS5 | |
CMP CCHAR ;IS IT CNTL D | |
BEQ COS0 ;BR IF CNTL– D | |
CMP #$8A ;LINE FEED? | |
BEQ COS4A | |
LDX #4 | |
STX OSTATE ;SET NEW OUT STATE | |
BNE COS4 ;BR IF NOT CNTL D | |
; | |
; COS6 – DISK INPUT ECHO | |
; | |
COS6 LDA #0 | |
STA OSTATE ;RESET OUT STATE = 0 | |
BEQ DRTNI ;GO TO DATA IN RETURN | |
PAGE | |
; | |
; PRRTN – PRINT CHAR RETURN | |
; | |
; | |
; CMDRTN – PRINT CHAR IF MONITOR CMBS MODE | |
; DRTNO – PRINT CHAR IF MONITOR DATA OUT | |
; DRTNI – PRINT CHAR IF MONITOR DATA IN | |
; | |
CERTN | |
LDA LBUFF ; CHECK FOR PRINTED COMMAND | |
CMP CCHAR | |
BEQ CMDRTN ; IF PC THEN NO RESET X REG | |
LDA #$A0 ;BLANK | |
STA LBUFF | |
LDA #$8D ;PLUS CR | |
STA LBUFF+1 ; TO OUT BUFFER | |
LDX #0 ;RESET TO SOL | |
STX SVX | |
CMDRTN LDA #MC | |
BNE MODECK | |
DRTNO LDA #MO | |
BNE MODECK | |
DRTNI LDA #MI | |
; | |
MODECK | |
AND MONMOD ;AND WITH MODE | |
BEQ ORTN ;BR IF NOT PRINT | |
PRRTN JSR LDREGS | |
JSR ORTN1 | |
ORTN | |
JSR MVCSW | |
LDX SVSTK | |
TXS | |
LDREGS | |
LDA SVA ;ACU | |
LDY SVY ;Y | |
LDX SVX ;X | |
RTS ;BY PASS PRINT | |
; | |
ORTN1 JMP (OUTSW) | |
; | |
; PRCRIF – PRINT CR IF MON CMDS | |
; | |
PRCRIF | |
BIT MONMOD ; IF NOT MON CMDS | |
BVC PRCIFR ; THEN RETURN | |
LDA #$8D ; ELSE PRINT CR | |
JSR ORTN1 | |
PRCIFR RTS | |
PAGE | |
; | |
; SCNCMD – SCAN COMMAND | |
; | |
SCNCMD | |
LDY #$FF | |
STY CMDNO ;RESET COMMAND NUMBER | |
INY | |
STY SVCMD | |
SC0 | |
INC CMDNO ;INCR CMD NO | |
LDX #0 ;RESET LINE INDEX TO 0 | |
PHP ; SAVE EQ STATUS | |
LDA LBUFF,X ;GET 1ST LINE CHAR | |
CMP CCHAR ; IS IT CONTROL D | |
BNE SC0A ; BR /IF NOT | |
INX ;INCR OVER CNTLD | |
SC0A STX LBUFD | |
; | |
SC1X | |
JSR GNBC ; GET NON BLANK INPUT CHAR | |
AND #$7F ; MSB OF CHAR OFF | |
EOR CMDNTB,Y ; EOR WITH INPUT | |
INY ; INCREMENT TABLE INDEX | |
ASLA ; IF MSB OF EOR RESULT ON | |
BEQ SC1A ; IF RESULT NOT NOW ZERO | |
PLA ; THEN INPUT DOES NOT | |
PHP ; EQUAL ENTRY | |
SC1A BCC SC1X ; LOOP FOR END ENTRY | |
; | |
PLP ; IF INPUT EQUALS END | |
BEQ SYNTAX ; THEN GO SYNTAX | |
; | |
LDA CMDNTB,Y ; IF NEXT TABLE CHAR NOT ZERO | |
BNE SC0 ; THEN SCAN THE NEXT TABLE ENTRY | |
CNF ;COMMAND NOT FOUND | |
LDA LBUFF ;LINE IS A CONTROL-D | |
CMP CCHAR ; THEN THIS IS A | |
BEQ CNF1 ;POSSIBLE SYNTAX ERROR, ELSE | |
JMP PRRTN ;IT’S A BASIC INPUT LINE | |
CNF1 | |
LDA LBUFF+1 ;GET NEXT CHAR | |
CMP #$8D ;IS IT A CR | |
BNE CSERR ;BR IF CR | |
JSR CLRSTS ; CLEAR THE STATES | |
JMP CMDRTN ;CNTL-D ONLY | |
; | |
CSERR JMP ESYNTX | |
PAGE | |
; | |
; SYNTAX – FIGURE OUT WHAT WE GOT HERE | |
; | |
SYNTAX | |
LDA CMDNO ;CMDNO=CMDNO*2 | |
ASLA | |
STA CMDNO | |
; | |
TAY | |
LDA #FN1 | |
AND CMDSTB,Y ;IS FN1 REGD | |
BEQ SN10 ;BR IF NOT | |
JSR CLRFNS | |
PHP ; SAVE EG STATUS | |
SN2 | |
JSR GNBC ;GET NON BLANK CHAR | |
BEQ SN6 ;BR IF CR OR COMMA | |
ASLA ; TEST FOR ALPHA | |
BCC SN2A ; BR IF ALPHA | |
BMI SN2A ; BR IS ALPHA | |
JMP CNF ; LURCH IF NOT ALPHA | |
SN2A RORA ;RESTORE BITS | |
JMP SN4 ;AWAY WE GO | |
SN3 JSR GNXTC ;GO GET NEXT CHAR | |
BEQ SN6 ;BR IF COMMA OR CHAR | |
SN4 STA FNAME1,Y ;PUT INTO FILENAME | |
INY ;INC FN INDEX | |
CPY #60 ; ATFN FN INDEX | |
BCC SN3 ;BR IF NOT | |
SN5 JSR GNXTC ;LOOP UNTIL CR OR COMMA | |
BEQ SN5 | |
; | |
SN6 PLP ;WAS THIS FN2 L OO | |
BNE SN7 ;BR IF IT WAS | |
; | |
LDY CMDNO | |
LDA #FN2 | |
AND CMDSTB,Y ;IF FN2 NOT REGD THEN | |
BEQ SN8 ;BRANCH | |
; | |
LDY #30 ; SET FN2 INDEX | |
PHP ; INDICATE FN2 SEEK | |
BNE SN2 ;GO LOOK FOR FN2 | |
; | |
SN7 LDA FNAME2 ;IF 1ST CHAR OF | |
CMP #$A0 ;FN2 IS BLANK THEN | |
BEQ SERR1 ;SYNTAX ERROR | |
; | |
SN8 LDA FNAME1 ;IF 1ST CHAR OF | |
CMP #$A0 ;FN1 IS NOT BLANK | |
BNE SOPTS ;THEN GO LOOK FOR OPTIONS | |
; | |
LDY CMDNO | |
LDA #NPB+NPE ;IF CMD MUST HAVE FILENAME | |
AND CMDSTB,Y ;THEN | |
BEQ SERR1 ;THIS IS ERROR ELSE | |
; | |
BPL SOPTS ; ITS EXECUTABLE WITHOUT | |
; | |
SERR1 JMP CNF | |
; | |
CLRFNS | |
LDA #0 | |
LDY #60 | |
CLRFNA | |
LDA #$A0 | |
SN1 STA FNAME1-1,Y ;CLEAR FN1, FN2 | |
DEY | |
BNE SN1 | |
RTS | |
PAGE | |
SN10 ;FILE NAMES NOT REGD | |
STA FNAME1 | |
LDA #NUM1+NUM2 ;IF NEITHER NUM1 | |
AND CMDSTB,Y ;OR NUM2 IS REGD | |
BEQ SOPTS ;THEN GO LOOK AT OPTIONS | |
; | |
JSR GETNUM ;GO GET NUMERICS | |
BCS SERR1 | |
; | |
TAY ; IF HIGH DIGIT NOT | |
BNE SERR1 ;ZERO THEN BAD | |
; | |
CPX #17 ;IF LOW DIGIT GT 16 | |
BCS SERR1 ;THEN BAD | |
; | |
LDY CMDNO | |
LDA #NUM1 | |
AND CMDSTB,Y ;IF WE WANT NUM2 | |
BEQ SN11 | |
; | |
CPX #8 ;IF NUM2>1 | |
BCS SERR1 ;THEN ERROR, ELSE | |
BCC SOPTS ;GO SCAN OPTIONS | |
; | |
SN11 | |
TXA ;IF NUM1=0 | |
BEQ SERR1 ;THEN ERROR, ELSE | |
; | |
PAGE | |
; | |
; SOPTS – LOOK FOR SYNTAX OPTIONS | |
; | |
SOPTS | |
LDA #0 | |
STA INOPTS ;CLEAR INPUT OPTIONS | |
STA IMBITS | |
STA CL | |
STA CL+1 | |
STA TEMP1A | |
LDA LBUFD ;SET PASS 1 | |
; | |
SP1 JSR GNBC ;GO GET NON-BLANK CHAR | |
BNE SP2 ;BR IF NOT COMMA OR CR | |
CMP #$8D ;IF CHAR IS COMMA | |
BNE SP1 ;THEN GO GET CHAR | |
; | |
LDX CMDNO ;OPTIONS INPUT = I | |
LDA INOPTS ;ALLOW OPTS = A | |
ORA CMDSTB+1,X ;IF (A OR I) | |
EOR CMDSTB+1,X ;OR A NOT = 0 THEN | |
BNE SERR1 ;WE HAVE UNALLOWED OPTIONS | |
; | |
LDX TEMP1A ;IF THIS IS PASS 2 | |
BEQ CMDGO ;THEN DONE, | |
STA TEMP1A ;ELSE SET PASS | |
STX LBUFD ;RESTORE LBUFD AND | |
BNE SP1 ;GO DO PASS 2 | |
; | |
SP2 LDX #OPT1L ;COMPARE CHAR HAVE WITH | |
SP3 CMP OPTAB1-1,X ;CHARS IN OPT TABLE | |
BEQ SP4 ;IF NOT FOUND CONTINUE | |
DEX | |
BNE SP3 ;IF NOT FOUND | |
BEQ SERR2 ;THEN SYNTAX ERROR | |
; | |
SP4 LDA OPTAB2-1,X ;IF CORRESPONDING OP TAB 2 IS | |
BMI SP8 ;MINUS THEN IT MONITOR BITS | |
ORA INOPTS | |
STA INOPTS | |
DEX | |
; | |
STX TEMP2A ;ELSE A NUMERIC MUST FOLLOW | |
JSR GETNUM ;FOLLOW | |
BCS SERR2 | |
; | |
LDA TEMP2A ; GET IOTION NUMBER | |
ASLA ;MULT BY 4 | |
ASLA | |
TAY | |
; | |
LDA CNUM+1 ;IF RESULT NUM HI IS | |
BNE SP5 ;GT 0, THEN GT LOW RANGE | |
LDA CNUM ;TEST RESULT LOW | |
CMP OPTAB3,Y ;WITH LOW RANGE (LOW) | |
BCC SERR2 ;BR IF RESULT < LR | |
LDA CNUM+1 | |
SP5 CMP OPTAB3+3,Y | |
BCC SP6 ;BR IF LESS | |
BNE SERR2 ;BR IF GRREATER | |
LDA CNUM | |
CMP OPTAB3+2,Y | |
BCC SP6 ;BR IF LESS | |
BNE SERR2 ;BR IF GREATER | |
; | |
SP6 LDA TEMP1A ;IF PASS 1,THEN | |
BNE SP1 ;DON’T STORE RESULT | |
TYA | |
LSRA | |
TAY | |
; | |
LDA CNUM+1 ;STORE THE RESULT | |
STA CUROPT+1,Y | |
LDA CNUM | |
STA CUROPT,Y | |
SP7 JMP SP1 ;GO FOR NEXT OPT | |
; | |
SP8 ;MONITOR REG | |
PHA ;SAVE TYPE REG | |
LDA #CIO ;SET OPTION OF CIO | |
ORA INOPTS | |
STA INOPTS | |
PLA ;RESTORE REG | |
AND #$7F ;CLEAR CIO | |
ORA IMBITS ;OR WITH PREV IMBITS | |
STA IMBITS | |
BNE SP7 ;GO FOR NEXT | |
; | |
SERR2 JMP CNF | |
PAGE | |
; | |
; CMDGO – EXECUTE COMMAND | |
; | |
CMDGO | |
JSR CLRSTS | |
JSR CLRCCB ;GO CLEAR CCB | |
JSR ECMD ;GO EXECUTE | |
JMP CERTN | |
ECMD | |
LDA CMDNO ;COMMAND NO | |
TAX ;IS CMD EXEC TAB INDEX | |
LDA CMDETB+1,X ;GET CMD ADR | |
PHA ;ONTO STACK | |
LDA CMDETB,X | |
PHA | |
RTS ;AND GOTO COMMAND | |
; | |
; GNXTC – GET NEXT CHAR | |
; | |
GNXTC | |
LDX LBUFD | |
LDA LBUFF,X ;GET NEXT CHAR AND IF | |
CMP #$8D ;IT IS A CR | |
BEQ GNXTCR ;THEN RETURN WITHOUT | |
INX ;INCR TO NEXT CHAR | |
STX LBUFD | |
CMP #','+$80 ;TEST FOR COMMA | |
GNXTCR RTS | |
; | |
; GNBC – GET NON BLANK CHAR | |
; | |
GNBC: | |
JSR GNXTC ;GO GET NEXT CHAR | |
BEQ GNXTCR ;BR IF COMMA OR CR | |
CMP #$A0 ;IS IT BLANK | |
BEQ GNBC ;BR IF BLANK | |
RTS ;DONE | |
; | |
; CLRCCB – CLEAR CCB | |
; | |
CLRCCB | |
LDA #0 | |
LDY #CCBLEN ;CCB LENGTH | |
CLC1 STA CCB-1,Y ;CLEAR BYTE | |
DEY | |
BNE CLC1 | |
RTS | |
PAGE | |
; | |
; GETNUM – COVERT ASCII INPUT TO NUMERIC | |
; | |
GETNUM | |
LDA #0 ;CLEAR WORK AREA | |
STA CNUM | |
STA CNUM+1 | |
JSR GNBC | |
PHP | |
CMP #$A4 | |
BEQ HEXNUM | |
PLP | |
JMP GN2A | |
; | |
GN2 JSR GNBC ;GET NEXT NON BLANK | |
GN2A | |
BNE GN3 ;BR NOT COMMA OR CR | |
LDX CNUM ;X=RESULT LOW | |
LDA CNUM+1 ;Y=RESULT HI | |
CLC | |
RTS ;DONE | |
; | |
GN3 SEC | |
SBC #$B0 ;SUBTRACT ASCII 0 | |
BMI GN4 ;BR IF NOT NUM | |
CMP #10 | |
BCS GN4 ;BR IF NOT NUM | |
JSR GN5 ;OLD*2 | |
ADC CNUM ;PLUS NEW | |
TAX | |
LDA #0 | |
ADC CNUM+1 | |
TAY | |
JSR GN5 ;OLD*4 | |
JSR GN5 ;OLD*8 | |
TXA ;OLD*8 + OLD*2 + NEW | |
ADC CNUM | |
STA CNUM ;=OLD*10 + NEW | |
TYA | |
ADC CNUM+1 | |
STA CNUM+1 | |
BCC GN2 | |
; | |
GN4 | |
SEC | |
RTS ;DONE | |
GN5 | |
ASL CNUM ;CNUM * 2 | |
ROL CNUM+1 | |
BCS GN4 | |
RTS | |
PAGE | |
; | |
HEXNUM | |
PLP | |
HN0 | |
JSR GNBC ;GO GET CHAR | |
BEQ GN2A ;BR IF CR OR COMMA | |
; | |
SEC | |
SBC #$B0 ;CHAR – ASCII0 | |
BMI GN4 ;BR IF LT0 | |
CMP #10 ;IS IT LT10 | |
BCC HN1 ;BR IF LT | |
SBC #$7 ;SUB 7 FOR ASCII A | |
BMI GN4 ;BR IF LT A | |
CMP #16 ;TEST GT 15 | |
BCS GN4 ;BR GT 15 | |
HN1 JSR GN5 ;OLD*2 | |
JSR GN5 ;OLD*4 | |
JSR GN5 ;OLD*8 | |
JSR GN5 ;OLD*16 | |
ORA CNUM ;OR IN NEW | |
STA CNUM ;SAVE NEW | |
JMP HN0 ;GO FOR NEXT CHAR | |
PAGE | |
; | |
; EPR – EXECUTE PR# | |
; | |
EPR | |
LDA CNUM ;GET PORT | |
JMP OUTPRT ;GO DO IT | |
; | |
; EIN – EXECUTE IN# | |
; | |
EIN | |
LDA CNUM ;GET PORT | |
JMP INPRT ; GO DO IT | |
; | |
; EMON – EXECUTE MONITOR CMD | |
; | |
EMON | |
LDA MONMOD ;GET CURRETN BITS | |
ORA IMBITS ;OR IN NEW BITS | |
STA MONMOD ;SET NEW MODE | |
RTS | |
; | |
; ENOMON – EXECUTE NO MONITOR CMD | |
; | |
ENOMON | |
BIT IMBITS | |
BVC ENM1 | |
JSR PRCRIF | |
ENM1 | |
LDA #$70 | |
EOR IMBITS ;INVERT INPUT BITS | |
AND MONMOD ;AND WITH CURRENT | |
STA MONMOD ;SET NEW MODE | |
RTS | |
PAGE | |
; | |
; EMAXF – EXECUTE MAX FILES | |
; | |
EMAXF | |
LDA #0 ; RESET EXECUTE | |
STA ESTATE | |
LDA CNUM ;SAVE NEW NO FILES | |
PHA | |
JSR CLALL ;GO CLOSE ALL TBLS | |
PLA | |
STA CNFTBS ;SET NEW NO FILE TBLS | |
JMP BLDFTB ; GO BUILD NEW ONES | |
; | |
; EDEL – DELETE A FILE | |
; | |
EDEL | |
LDA #CRQDEL ;DELETE REQUEST | |
JSR OPEN ;GO OPEN | |
JSR FILSRC ;FIND FILE | |
LDY #0 | |
TYA | |
STA (ZPGWRK),Y ;RESET FN | |
RTS | |
; | |
; ELOCK – LOCK A FILE | |
; | |
ELOCK | |
LDA #CRQLCK ;SET LOCK | |
BNE ELGO | |
; | |
; EUNLK – UNLOCK A FILE | |
; | |
EUNLK | |
LDA #CRQUNL ;SET UNLOCK | |
ELGO | |
JSR OPEN ;OPEN FILE & UNLOCK | |
JMP ECLOSE ; CLOSE IT | |
; | |
; EVAR – VERIFY A FILE | |
; | |
EVAR | |
JMP DP1 ;*** PATCH *** | |
BRK | |
PAGE | |
; | |
; EREN – RENAME A FILE | |
; | |
EREN | |
LDA FN2ADR ;MOVE FILE NAME2 | |
STA CCBFN2 | |
LDA FN2ADR+1 | |
STA CCBFN2+1 | |
LDA #CRQRNM | |
STA TEMP1A ;SET RENAME | |
JSR EO3 ;GO OPEN AND RENAME | |
JMP ECLOSE ; GO CLOSE | |
; | |
; EAPND – OPEN FILE FOR APPEND | |
; | |
EAPND | |
JSR EOPEN ; GO OPEN | |
LDA #CREFNF | |
CMP CCBSTA ; IF FILE CREATED | |
BNE AP1 | |
RTS | |
AP1 | |
JSR RBYTE ; READ A BYTE | |
BNE AP1 ; BR IF NOT ZERO | |
; | |
JMP RWP3 ;GO RE-POSITION | |
PAGE | |
; | |
; EOPEN – OPEN A FILE | |
; | |
EOPEN | |
LDA #CRQOPN | |
OPEN | |
STA TEMP1A | |
LDA CL ;IF NO LENGTH ENTERED | |
BNE EO1 ;THEN SET DEFAULT OF 1 | |
LDA CL+1 | |
BNE EO1 | |
LDA #1 | |
STA CL | |
EO1 | |
LDA CL ;MOVE REC LENGTH | |
STA CCBRLN | |
LDA CL+1 | |
STA CCBRLN+1 | |
EO3 | |
JSR ECLOSE ;GO CLOSE IF OPEN | |
LDA CNUM+1 ;GET AVALL ENTRY | |
BNE EO5 ;BR IF ONE AVAIL | |
JMP ENFA ;DONE - NO FILES AVAIL | |
EO5 | |
STA ZPGWRK+1 ;MOVE AVAIL SLOT TO ZPG | |
LDA CNUM | |
STA ZPGWRK | |
JSR MVFN1 ;GO MOVE FILE NAME | |
JSR MVBUFP ;GO MOVE BUF PTRS | |
JSR OPNSUP ;GO SET UP OPEN | |
LDA TEMP1A ;SET OPEN REG | |
STA CCBREQ | |
JMP DOSGO ; GO OPEN | |
PAGE | |
; | |
; ECLOSE – EXECUTE CLOSE FILE COMMAND | |
; | |
ECLOSE | |
LDA FNAME1 | |
CMP #$A0 | |
BEQ CLALL | |
JSR FILSRC ;GO FIND FILE | |
BCS ECL1 ; BR IF NOT FOUND | |
JSR CLOSE ;GO CLOSE | |
JMP ECLOSE ;GO SEE IF ANY MORE OPEN | |
ECL1 RTS | |
; | |
; CLOSE – CLOSE A FILE | |
; | |
CLOSE | |
JSR TSTEXC | |
BNE CLX | |
LDA #0 | |
STA ESTATE | |
CLX | |
LDY #0 ;CLEAR 1ST FN | |
TYA ;CHAR TO ZERO | |
STA (ZPGWRK),Y | |
JSR MVBUFP ;MOVE BUFFER PTRS | |
LDA #CRQCLS ;SET CLOSE | |
STA CCBREQ | |
JMP DOSGO ;GO CLOSE | |
; | |
; CLALL – CLOSE ALL FILES | |
; | |
CLALL | |
JSR TSINIT ;GO INIT FILE SEARCH | |
BNE CL1 | |
CL0 | |
JSR TSNXT ;NEXT ENTRY | |
BEQ CL2 ;BR IF NO MORE | |
CL1 | |
JSR TSTEXC | |
BEQ CL0 | |
JSR TSTOPN ;GO TEST OPEN | |
BEQ CL0 ;BR NOT OPEN | |
JSR CLOSE ;GO CLOSE | |
JMP CLALL ;START OVER | |
CL2 RTS ;DONE | |
PAGE | |
; | |
; EBSV – EXECUTE BINARY SAVE | |
; | |
EBSV | |
LDA #A+L ; IF A+L | |
AND INOPTS | |
CMP #A+L | |
BEQ EBSV1 | |
JMP CNF ;THEN ERROR | |
EBSV1 | |
LDA #4 ; SET BINARY FILE | |
JSR SV1 ; GO OPEN & TEST | |
LDA CA+1 ; OUTPUTADR OF BLOCK | |
LDY CA | |
JSR SV2 | |
LDA CL+1 ; GO OPEN AND TEST | |
LDY CL | |
JSR SV2 ; OUTPUT LENGTH | |
LDA CA+1 ; GET ADR GIVEN | |
LDY CA | |
JMP SV3 ; OUTPUT BLOCK | |
; | |
; EBLD – EXECUTE BINARY LOAD | |
; | |
EBLD | |
JSR EOPEN | |
LDA #CREFNF | |
CMP CCBSTA | |
BNE EBLD2 | |
JMP KLUTZ | |
EBLD2 | |
LDA #$7F | |
AND CCBFUC | |
CMP #4 | |
BEQ EBLD3 | |
JMP ENBF | |
EBLD3 | |
LDA #4 ; SET BINARY FILE | |
JSR SV1 ; GO OPEN $ TEST | |
JSR LD2 ; GO GET ADR | |
TAX | |
LDA INOPTS | |
AND #A ; IF ADR NOT GIVEN | |
BNE EBLD1 | |
STX CA ; THEN USE ADR FROM FILE | |
STY CA+1 | |
EBLD1 | |
JSR LD2 ; GET LENGTH | |
LDX CA ; GET GIVEN ADR | |
LDY CA+1 | |
JMP LD3 ; GO GET BLOCK | |
; | |
; EBRUN – EXECUTE BINARY RUN | |
; | |
EBRUN | |
JSR EBLD ; GO LOAD FILE | |
JSR MVCSW ;GO RESTORE CHAR I/O SW | |
JMP (CA) ; GO EXEC THE STUFF | |
PAGE | |
; | |
; ESAVE – EXECUTE SAVE REQUEST | |
; | |
ESAVE | |
LDA ASIBSW ; IF IB THEN | |
BEQ EIBSV ; GO TO IB SAVE | |
LDA #2 ; GET APPLESOFT PGM | |
JSR SV1 ; GO OPEN AND TEST | |
; | |
SEC ; BLOCK LENGTH | |
LDA ASEOP ; =EOP-SOP | |
SBC ASSOP | |
TAY | |
LDA ASEOP+1 | |
SBC ASSOP+1 | |
JSR SV2 ; GO OUTPUT LRNGTH | |
; | |
LDA ASSOP+1 ; BLOCK ADR | |
LDY ASSOP ; =SOP | |
JMP SV3 ; GO OUTPUT BLOCK | |
; | |
EIBSV | |
LDA #1 ; SET IB PGM | |
JSR SV1 ; GO OPEN AND TEST | |
; | |
SEC ; BLOCK LENGTH | |
LDA IBHMEM ; =HIMEM-SOP | |
SBC IBSOP | |
TAY | |
LDA IBHMEM+1 | |
SBC IBSOP+1 | |
JSR SV2 ; GO OUTPUT LENGTH | |
; | |
LDA IBSOP+1 ; BLOCK ADR | |
LDY IBSOP ; =SOP | |
JMP SV3 ; GO OUTPUT BLOCK | |
; | |
SV1 | |
SV1A | |
STA CCBFUC ; SET PGM TYPE | |
PHA ; SAVE PGM TYPE | |
JSR EOPEN ; GO OPEN FILE | |
PLA ; GET SAVE TYPE | |
JMP TSTFUC ; GO CHECK | |
; | |
SV2 | |
STY CCBBLN ; SET BLOCK LENGTH | |
STY CCBDAT ; AND DATA BYTE | |
STA CCBBLN+1 | |
LDA #CRQWR ; INDICATE WRITE | |
STA CCBREQ | |
LDA #CRMNBT ; NEXT BYTE | |
STA CCBRQM | |
JSR DOSGO ; GO WRITE | |
LDA CCBBLN+1 ; OTHER BYTE TOO | |
STA CCBDAT | |
JMP DOSGO | |
; | |
SV3 STY CCBBBA ; SET BLOCK ADR | |
STA CCBBBA+1 | |
LDA #CRMNBL ; INDICATE BLOCK I/O | |
STA CCBRQM | |
JSR DOSGO ; GO DO IT | |
JMP ECLOSE ; CLOSE FILE | |
PAGE | |
NBPER JMP ERNUl | |
; | |
; ELOAD – EXECUTE LOAD REQUEST | |
; | |
ELOAD | |
JSR CLALL ;GO CLOSE ALL | |
JSR EOPEN ; OPEN FILE | |
LDA #CREFNF | |
CMP CCBSTA ; WAS FILE FOUND | |
BNE ELD1 ; BR IF FOUND | |
; | |
KLUTZ JSR EDEL ; DELETE NEW FILE | |
LDA #CREFNF ; FILE NOT FOUND MSG | |
JMP ERROR ; GO | |
; | |
ELD1 | |
LDA #$7F ; MASK PROTECT BIT | |
AND CCBFUC ; OUT OF FUC | |
BEQ NBPER ; BR IF ERROR | |
AND #$03 ; ISOLOLATE IB & AS | |
BEQ NBPER ; BR IF ERROR | |
STA CCBFUC ; SAVE IB/AS ONLY | |
LDA ASIBSW ; IF IB THEN | |
BEQ EIBL ; GO TO IB LOAD | |
LDA #2 | |
JSR LD1 ; GO OPEN AND TEST | |
; | |
JSR LD2 ; GO GET BLOCK LENGTH | |
; | |
CLC | |
ADC ASSOP ; ADD BLOCK LENGTH TO SOP | |
TAX | |
TYA | |
ADC ASSOP+1 | |
; | |
CMP ASHM1+1 ; IF BL+SOP >=HMEM | |
BCS MFULL ; THEN WON’T FIT | |
; | |
STA ASEOP+1 ; SET NEW EOP ADR | |
STA ASEOP2+1 | |
STX ASEOP | |
STX ASEOP2 | |
LDX ASSOP ; GET ADR WHERE TO LOAD | |
LDY ASSOP+1 | |
JMP LD3 ; GO LOAD | |
; | |
EIBL | |
LDA #1 ; SET IB PGM | |
JSR LD1 ; GO OPEN AND TEST | |
; | |
JSR LD2 ; GO GET BLOCK LENGTH | |
; | |
SEC ; HMEM - BLOK LENGTH | |
LDA IBHMEM ; IS NEW SOP | |
SBC SVBL | |
TAX | |
LDA IBHMEM+1 | |
SBC SVBL+1 | |
BCC MFULL | |
TAY | |
; | |
CPY IBLMEM+1 ; IF NEW SOP <= LMEM | |
BCC MFULL | |
BEQ MFULL | |
STY IBSOP+1 ; SET NEW SOP | |
STX IBSOP | |
JMP LD3 | |
; | |
LD2 | |
LDA SVBLA ; MOVE ADR OF WHERE | |
STA CCBBBA ; TO PUT DATA TO | |
LDA SVBLA+1 ; CCBN | |
STA CCBBBA+1 | |
LDA #0 | |
STA CCBBLN+1 ; READ INTO | |
LDA #2 | |
STA CCBBLN | |
LDA #CRQRD ; READ | |
STA CCBREQ | |
LDA #CRMNBL ; BLOCK | |
STA CCBRQM | |
JSR DOSGO | |
LDA SVBL+1 | |
STA CCBBLN+1 | |
TAY | |
LDA SVBL | |
STA CCBBLN | |
RTS | |
; | |
LD3 | |
STX CCBBBA ; SET BLOCK ADR | |
STY CCBBBA+1 | |
JSR DOSGO ; GET BLOCK | |
JMP ECLOSE ; GO CLOSE FILE | |
; | |
MFULL | |
JSR ECLOSE ; GO CLOSE FILE | |
JMP MFERR ; AND GIVE ERR MSG | |
LD1 | |
CMP CCBFUC ; TEST TYP | |
BEQ LD1C ; BR IF MATCH | |
LDX CMDNO | |
STX SVCMD | |
LSRA | |
BEQ LD1A ; BR IF PGM IS AS | |
JMP EINT ; GO FOR INTG BASIC | |
; | |
LD1A | |
LDX #29 ; SAVE FILE NAME | |
LD1B LDA FNAME1,X ; INCASE IS RAM APPLESOFT | |
STA FNAME2,X | |
DEX | |
BPL LD1B | |
JMP EAS ; GO FOR AS | |
; | |
LD1C RTS | |
PAGE | |
; | |
; ERUN – EXECUTE RUN REQUEST | |
; | |
ERUN | |
JSR ELOAD ;LOAD PGM | |
JSR PRCRIF | |
JSR MVCSW ;GO RESTORE CHAR I/O SW | |
JMP (RUN) | |
; | |
; IBRUN – INT BASIC RUN | |
; | |
IBRUN | |
LDA IBLMEM ;RESET START OF VARS | |
STA IBSOV | |
LDA IBLMEM+1 | |
STA IBSOV+1 | |
JMP (CHAIN) | |
; | |
; EHCAIN – EXECUTE CHAIN REQUEST | |
; | |
ECHAIN | |
JSR ELOAD ;LOAD PGM | |
JSR PRCRIF | |
JSR MVCSW ;GO RESTORE CHAR I/O SW | |
JMP (CHAIN) | |
ASRUN1 JSR $D665 ;ROM | |
JMP $D7D2 | |
ASRUN2 JSR $E65 ; RAM | |
JMP $FD4 | |
PAGE | |
; | |
; EWRITE – WRITE CMD EXECUTE | |
; | |
EWRITE | |
JSR RWPOSN ;GO POSITION FILE IF REQD | |
LDA #5 | |
STA OSTATE ;SET OSTATE=5 | |
JMP CERTN ;DONE | |
; | |
; EREAD – READ COMD EXECUTE | |
; | |
EREAD | |
JSR RWPOSN ;GO POSITION FILE IF REGD | |
LDA #1 | |
STA ISTATE ;SET ISTATE = DISK INPUT | |
JMP CERTN ;DONE | |
; | |
; RWPOSN – POSITION FOR READ/WRITE | |
; | |
RWPOSN | |
JSR FILSRC ;FIND THE FILE | |
BCC RWP1 ;BR IF FILE FOUND | |
JSR EOPEN ;GO OPEN FOR KLUTZ | |
JMP RWP2 ;THEN SKIP NEXT LINE | |
RWP1 | |
JSR MVBUFP ;MOVE BUFF POINTERS | |
RWP2 | |
LDA INOPTS ;GET IN OPTIONS | |
AND #R+B ;WAS IT B OR R | |
BEQ RWPR ;BR IF NOT | |
LDX #3 | |
RWP2A LDA CR,X ;MOVE REL REC | |
STA CCBRRN,X ;AND REL BYTE | |
DEX | |
BPL RWP2A | |
RWP3 | |
LDA #CRQPOS ;INDICATE POSITION REQUIRED | |
STA CCBREQ | |
JSR DOSGO | |
RWPR RTS ;DONE | |
PAGE | |
; | |
; | |
; EINIT – EXECUTE INIT COMMAND | |
; | |
EINIT | |
LDA #V ; MUST HAVE | |
AND INOPTS ; VOL OPTION | |
BEQ INER | |
LDA CV ; AND VOL MUST | |
BEQ INER ; BR GT 0 | |
LDA ASTART+1 | |
STA CCBBSA | |
LDA #CRQFMT | |
JSR OPEN | |
JMP ESAVE | |
; | |
INER JMP CNF | |
; | |
; ECAT – PRINT CATALOG | |
; | |
ECAT | |
LDA #CRQDIR | |
JSR OPEN ;GO PRETEND OPEN | |
LDA CCBVOL | |
STA CV | |
RTS | |
PAGE | |
; | |
; EAS – EXECUTE APPLESOFT REQUEST | |
; | |
EAS | |
LDA #ATSTV ; GET APPLESOFT TEST VALUE | |
JSR SWTST ; GO SWITCH AND TEST | |
BEQ GOINIT ; GO SWITCH AND TEST | |
LDA #0 | |
STA ASIBSW | |
; | |
LDY #30 | |
JSR CLRFNA | |
LDX #FASBL | |
EAS1 LDA FASB-1,X ; MOVE SYSTEM FILE NAME | |
STA FNAME1-1,X | |
DEX | |
BNE EAS1 | |
; | |
LDA #$C0 | |
STA ISTATE ; FOR RAM APPLESOFT | |
JMP ERUN ; GO LOAD AND RUN | |
; | |
; EINT – EXECUTE INTEGER REQUEST | |
; | |
EINT | |
LDA #ITSTV ; GET IB TEST VALUE | |
JSR SWTST ; GO SWITCH AND RUN | |
BNE EAS ; BR IF NOT IB | |
GOINIT | |
JMP DBINIT ; GO INIT DOS | |
SWTST | |
CMP AITSTL ; TEST CURRENT VALUE | |
BEQ SWTR | |
STA $C080 ; TRY SWITCH 1 | |
CMP AITSTL ; TEST AGAIN | |
BEQ SWTR ; BR IF NOW SAME | |
STA $C081 ; TRY SWITCH 2 | |
CMP AITSTL ; TEST AND | |
SWTR RTS ; RETURN | |
; | |
PAGE | |
; | |
; EEXEC – EXEC CMD | |
; | |
EEXEC | |
JSR EOPEN ; OPEN FILE | |
LDA CFTABA | |
STA EFTABA ; MOVE TABLE POINTERS | |
LDA CFTABA+1 | |
STA EFTABA+1 | |
LDA FNAME1 ;USE FILENAME | |
STA ESTATE ; SET EX STATE NON ZERO | |
BNE EXP2 | |
; | |
; | |
; EPOS – EXECUTE POSITION | |
; | |
EPOS | |
JSR FILSRC | |
BCC EXP1 | |
JSR EOPEN | |
JMP EXP2 | |
EXP1 JSR MVBUFP | |
EXP2 | |
LDA INOPTS ; GET OPTIONS | |
AND #R ; TEST R | |
BEQ EX2 ; BR IF NOT R | |
; | |
EX0 LDA CR ; IF CR NOT ZERO | |
BNE EX1A ; THEN DECREMENT | |
LDX CR+1 | |
BEQ EX2 | |
DEC CR+1 | |
EX1A DEC CR | |
EX1 JSR RBYTE ; AND READ A RECORD | |
BEQ ICFD4 | |
CMP #$8D ; UNTIL CR | |
BNE EX1 | |
BEQ EX0 ; THEN TEST CR AGAIN | |
; | |
EX2 RTS ; DONE | |
PAGE | |
; | |
; OCTD – OUTPUT A CHAR TO DISK | |
; | |
OCTD | |
JSR TSTRUN ;GO TEST RUN | |
LDA SVA ;CHAR IN SAVED ACU | |
STA CCBDAT ;PUT IN CCDBDATA AREA | |
LDA #CRQWR ;SET WRITE | |
STA CCBREQ | |
LDA #CRMNBT ;SET NEXT BYTE | |
STA CCBRQM | |
JMP DOSGO ; GO WRITE BYTE | |
; | |
; INCFD – INPUT A CHAR FROM DISK | |
; | |
INCFD | |
JSR TSTRUN ;GO TEST RUN | |
LDA #6 ;SET OUT STE = 6 | |
ICFD3 | |
STA OSTATE ;TO CATCH ECHO | |
JSR RBYTE | |
BNE ICFD1 ;BR IF NOT ZERO CHAR | |
; | |
JSR CLOSE | |
LDA #3 | |
CMP OSTATE | |
BEQ ICFD0 | |
ICFD4 | |
LDA #CREEOF | |
JMP ERROR ;GO TO ERROR | |
ICFD1 | |
STA SVA ;PUT INTO SAVED ACU | |
ICFD0 | |
JMP ORTN ;GO RESTORE REGS AND RTS | |
; | |
TSTRUN | |
LDA ASIBSW ;GET AS/INT BASIC SWITCH | |
BEQ TR1 ; BR IF INT | |
LDX $76 ;TEST AS RUN | |
JMP ASRWPAT ;AS READ/WRITE > LINE # 255 PATCH | |
TR1 | |
LDA $D9 ;GET INT RUN FLAG | |
BMI MVEFRT ; BR IF RUN | |
ICFDB ; NOT RUN MODE | |
JSR CLOSE ;GO CLOSE FILE | |
JSR CLRSTS ;GO CLEAR STATES | |
JMP ORTN | |
PAGE | |
; | |
; NXTEXC – NEXT EXECUTE CHAR | |
; | |
NXTEXC | |
JSR MVEFTA | |
JSR MVBUFP ; GO MOVE PTRS | |
LDA #3 | |
BNE ICFD3 | |
; | |
; RBYTE – READ NEXT BYTE | |
; | |
RBYTE | |
LDA #CRQRD ;SET READ | |
STA CCBREQ | |
LDA #CRMNBT ;SET NEXT BYTE | |
STA CCBRQM | |
JSR DOSGO ;GO TO DOS | |
LDA CCBDAT ;GET THE DATA BYTE | |
RTS | |
MVEFTA | |
LDA EFTABA+1 ; MOVE TABLE ADR | |
STA ZPGWRK+1 ; NO ZPG | |
LDA EFTABA | |
STA ZPGWRK | |
MVEFRT RTS | |
PAGE | |
; | |
; DOSGO – GOTO DOS | |
; | |
DOSGO | |
JSR DOSENT ;GO TO DOS | |
BCS DG1 ;BR IF ERROR | |
RTS ;DONE | |
; | |
DG1 | |
LDA CCBSTA ;GET STATUS OF I/O | |
CMP #CREEOF ;EOF ? | |
BNE DG2 ;BR IF NOT | |
LDX #0 ;SET OTHER EIF | |
STX CCBDAT ; DONE | |
RTS | |
DG2 | |
JMP ERROR ;GO DO ERROR | |
; | |
PAGE | |
; | |
; ERROR ROUTINE | |
; | |
ESYNTX LDA #CREFLK+1 | |
BNE ERROR | |
ENFA LDA #CREFLK+2 | |
BNE ERROR | |
MFERR LDA #CREFLK+4 | |
BNE ERROR | |
ERNUl LDA #CREFLK+3 | |
BNE ERROR | |
ENBF LDA #CREFLK+5 | |
; | |
ERROR | |
STA SVA ;SAVE MSG NUMBER | |
JSR CLRSTS | |
LDA ASIBSW ;GET AS/IN BASIC SWITCH | |
BEQ ERNAS ;BR IF NOT APPLESOFT | |
LDA $D8 ;GET ON ERR FLAG | |
BMI ERRTN ;BRT IF ON ERR IS GO | |
ERNAS | |
LDX #0 | |
JSR EMPR ;GO OUTPUT | |
LDX SVA ;GET SAVE MSG | |
JSR EMPR ;GO OUTPUT MSG | |
LDX #CREFLK+6 | |
JSR EMPR | |
ERRTN JSR MVCSW ;GO MOVE CHAR I/O SW | |
LDX SVA | |
LDA #03 | |
JMP (BREAK) | |
; | |
EMPR | |
LDA EMDTB,X ;GET ITS DISPL | |
TAX ;INTO X | |
EMPR1 | |
STX TEMP1A ;SAVE DISPL | |
LDA EMSG,X ;GET MSG CHAR | |
PHA ;SAVE CHAR | |
ORA #$80 ;SET MSB ON | |
JSR ORTN1 ;OUTPUT CHAR | |
LDX TEMP1A ;GET INDEX | |
INX ;INCREMENT IT | |
PLA ;RE-LOAD CHAR | |
BPL EMPR1 ;BR IF MORE CHARS | |
RTS ;DONE | |
PAGE | |
; | |
; OPNSUP – OPEN SET UP | |
; | |
OPNSUP | |
LDA CV ;VOLUME | |
STA CCBVOL | |
LDA CD ;DRIVE | |
STA CCBDRV | |
LDA CS ;SLOT | |
STA CCBSLT | |
LDA FN1ADR ;FILENAME 1 ADR | |
STA CCBFN1 | |
LDA FN1ADR+1 | |
STA CCBFN1+1 | |
LDA ZPGWRK | |
STA CFTABA | |
LDA ZPGWRK+1 | |
STA CFTABA+1 | |
RTS | |
; | |
; MVFN1 – MOVE FILE NAME 1 TO FILE PTR | |
; | |
MVFN1 | |
LDY #29 | |
MVFN1A LDA FNAME1,Y | |
STA (ZPGWRK),Y | |
DEY | |
BPL MVFN1A | |
RTS | |
; | |
; MVBUFP – MOVE BUFFER PTRS TO CCB | |
; | |
MVBUFP | |
LDY #30 | |
MVBP1 LDA (ZPGWRK),Y | |
STA CCBFCB-30,Y | |
INY | |
CPY #38 | |
BNE MVBP1 | |
RTS | |
; | |
; CLRSTS – CLEAR STATES | |
; | |
CLRSTS | |
LDY #0 | |
STY ISTATE | |
STY OSTATE | |
RTS | |
PAGE | |
; | |
; FILSRC – SEARCH FOR FILE NAME1 | |
; | |
FILSRC | |
LDA #0 ;CLEAR SV AVAIL | |
STA CNUM+1 | |
; | |
JSR TSINIT ;GO INIT SEARCH | |
JMP FLS1A | |
FLS1 JSR TSNXT ;LOOK AT NEXT | |
BEQ FLS4 ;BR IF NO NEXT | |
; | |
FLS1A JSR TSTOPN ;GO TEST OPEN | |
BNE FLS2 ;BR IF OPEN | |
; | |
LDA ZPGWRK ;SAVE AVAIL ENTRY ADR | |
STA CNUM | |
LDA ZPGWRK+1 | |
STA CNUM+1 | |
BNE FLS1 ;GO LOOK SOME MORE | |
; | |
FLS2 LDY #29 ; FILE HAD 30 CHARS | |
FLS3 LDA (ZPGWRK),Y ;GET CHAR | |
CMP FNAME1,Y ;TEST CHAR | |
BNE FLS1 ;BR NOT | |
DEY | |
BPL FLS3 ; LOOK AT 30 CHARS | |
CLC ;FOUND | |
RTS ;DONE | |
; | |
FLS4 SEC ;NOT FOUND | |
RTS ;DONE | |
PAGE | |
; | |
; TSINIT – INITIALIZE FOR FTAB SEARCH | |
; TSNXT – GET NEXT FTAB ENTRY | |
; | |
TSINIT | |
LDA FTAB ;GET 1ST PTR ADR | |
LDX FTAB+1 | |
BNE TSST | |
TSNXT | |
LDY #37 ; GET LINK | |
LDA (ZPGWRK),Y | |
BEQ TSR ;BR IF NO LINK | |
; | |
TAX | |
DEY | |
LDA (ZPGWRK),Y | |
TSST | |
STX ZPGWRK+1 | |
STA ZPGWRK | |
TXA ;SET NE CC | |
TSR RTS | |
; | |
; TSTOPN – TST FOR OPEN FILE | |
; | |
TSTOPN | |
LDY #0 ;GET 1ST CHAR OF FN | |
LDA (ZPGWRK),Y | |
RTS | |
; | |
; TSTEXC – TEST CURRENT FILE FOR EXECUTE | |
; | |
TSTEXC | |
LDA ESTATE ; IF ESTATE = 0 | |
BEQ TXC1 ; THEN NO EXECUTE FILE | |
LDA EFTABA ; TEST CURRENT | |
CMP ZPGWRK | |
BNE TXC2 ; IS NOT | |
LDA EFTABA+1 | |
CMP ZPGWRK+1 | |
BEQ TXC2 ; IS | |
TXC1 DEX ; IS NOT | |
TXC2 RTS ; DONE | |
PAGE | |
; | |
; TSTFUC – TEST FILE USE CODE FOR PGM | |
; | |
TSTFUC | |
EOR CCBFUC | |
BEQ TFUCR | |
AND #$7F | |
BEQ TFUCR | |
JSR ECLOSE ; GO CLOSE THE SOB | |
JMP ERNUl | |
TFUCR RTS | |
PAGE | |
; | |
; BLDFTB – BUILD FILE TABLES | |
; TABLE MAP: | |
; HIMEM,SOP | |
; SBUFF N (256) | |
; DBUFF N (256) | |
; FTB N (FCBLEN) | |
; HEADER N (38) | |
; | |
; | |
; SBUFF 1 | |
; DBUFF 1 | |
; FTB 1 | |
; HEADER 1 | |
; THIS PROGRAM | |
; | |
; HEADER MAP: | |
; FILENAME (30) | |
; FTB PTR (2) | |
; DBUF PTR (2) | |
; SBUF PTR (2) | |
; LINK (2) | |
; | |
BLDFTB | |
SEC | |
LDA FTAB ;START OF FTAB AREA | |
STA ZPGWRK ;IS 1ST FTB PTR | |
LDA FTAB+1 ;HEADER | |
STA ZPGWRK+1 | |
LDA CNFTBS ;MOVE NO FTABS | |
STA TEMP1A ;TO TEMP | |
; | |
BFT1 LDY #0 | |
TYA | |
STA (ZPGWRK),Y ;1ST CHAR FN=0 | |
LDY #30 ; INC Y TO FCB PTR | |
SEC | |
LDA ZPGWRK ;END OF PTR HEADER | |
SBC #FCBLEN ;MINUS FTAB LENGTH | |
STA (ZPGWRK),Y ;IS START OF FTB | |
PHA ;SAVE LOW ADR BYTE | |
LDA ZPGWRK+1 | |
SBC #0 | |
INY | |
STA (ZPGWRK),Y | |
TAX | |
DEX ;FTB ADR – 256 | |
PLA ;IS ADR DIR BUFF | |
PHA | |
INY | |
STA (ZPGWRK),Y ;SET DIR BUF PTR | |
TXA | |
INY | |
STA (ZPGWRK),Y | |
TAX | |
DEX ;DIR BUFF - 256 | |
PLA ;IS SBUFF ADR | |
PHA | |
INY | |
STA (ZPGWRK),Y | |
INY | |
TXA | |
STA (ZPGWRK),Y | |
; | |
DEC TEMP1A ;DECREMENT TABLE INDEX | |
BEQ BFT2 ;COUNT AND BR IF DONE | |
TAX | |
PLA | |
SEC | |
SBC #38 ; SBUFF ADR - 38 | |
INY | |
STA (ZPGWRK),Y ;IF ADR OF NEXT TAB | |
PHA ;WHICH GOES INTO | |
TXA ;LINK | |
SBC #0 | |
INY | |
STA (ZPGWRK),Y | |
STA ZPGWRK+1 ;AND INTO ZPGWRK | |
PLA ;FOR NEXT ENTRY | |
STA ZPGWRK ;BUILD | |
JMP BFT1 ;GO BUILD NEXT | |
; | |
BFT2 | |
PHA | |
LDA #0 ;SET LAST LINK | |
INY ;TO ZERO | |
STA (ZPGWRK),Y | |
INY | |
STA (ZPGWRK),Y | |
; | |
LDA ASIBSW ;IF IB THEN GO | |
BEQ BFT1B | |
; | |
PLA ; SET APPLESOFT | |
STA ASHM1+1 ; UPPER MEM LIMITS | |
STA ASHM2+1 | |
PLA | |
STA ASHM1 | |
STA ASHM2 | |
RTS | |
; | |
BFT1B | |
PLA ; SET IB | |
STA IBHMEM+1 ; UPPER MEM LIMITS | |
STA IBSOP+1 | |
PLA | |
STA IBHMEM | |
STA IBSOP | |
RTS | |
PAGE | |
; | |
; MVISW – MOVE INPUT SWITCH | |
; | |
MVCSW | |
LDA INSW+1 | |
CMP CINA+1 | |
BEQ MVOSW | |
STA SVINS+1 | |
LDA INSW ;SAVE CHAR IN SWITCH | |
STA SVINS | |
; | |
LDA CINA ;SET DB CHAR IN ADR | |
STA INSW | |
LDA CINA+1 | |
STA INSW+1 | |
; | |
; | |
; MVOSW – MOVE OUTPUT SWITCH | |
; | |
MVOSW | |
LDA OUTSW+1 | |
CMP COUTA+1 | |
BEQ MVSRTN | |
STA SVOUTS+1 | |
LDA OUTSW ;SAVE CHAR OUT SWITCH | |
STA SVOUTS | |
; | |
LDA COUTA ;SET DB CHAR OUT ADR | |
STA OUTSW | |
LDA COUTA+1 | |
STA OUTSW+1 | |
MVSRTN | |
RTS | |
PAGE | |
; | |
; COMMAND NAME TABLE | |
; | |
EC1 | |
CMDNTB | |
DB01 "INIT" | |
DB01 "LOAD" | |
DB01 "SAVE" | |
DB01 "RUN" | |
DB01 "CHAIN" | |
DB01 "DELETE" | |
DB01 "LOCK" | |
DB01 "UNLOCK" | |
DB01 "CLOSE" | |
DB01 "READ" | |
DB01 "EXEC" | |
DB01 "WRITE" | |
DB01 "POSITION" | |
DB01 "OPEN" | |
DB01 "APPEND" | |
DB01 "RENAME" | |
DB01 "CATALOG" | |
DB01 "MON" | |
DB01 "NOMON" | |
DB01 "PR#" | |
DB01 "IN#" | |
DB01 "MAXFILES" | |
DB01 "FP" | |
DB01 "INT" | |
DB01 "BSAVE" | |
DB01 "BLOAD" | |
DB01 "BRUN" | |
DB01 "VERIFY" | |
DB 0 | |
PAGE | |
; | |
; COMMAND SYNTAX OP EQUATES FOR SYNTAX BYTE ONE | |
; | |
NPB EQU $80 ;NO PARMS OK, COMMAND GOES TO BASIC | |
NPE EQU $40 ;NO PARMS OK, COMMAND TO EXECUTION RTN | |
FN1 EQU $20 ;FILE NAME1 REGD | |
FN2 EQU $10 ;FILE NAME2 REGD | |
NUM1 EQU $08 ;NUMERIC 0-7 REGD | |
NUM2 EQU $04 ;NUMERIC 1-10 REGD | |
; | |
; COMMAND SYNTAX OP EQUATES FOR SYNTAX BYTE TWO | |
; | |
V EQU $40 ;VOLUME ALLOWED | |
D EQU $20 ;DRIVE ALLOWED | |
S EQU $10 ;SLOT ALLOWED | |
L EQU $08 ;LENGTH ALLOWED | |
R EQU $04 ;RECORD NUMBER ALLOWED | |
B EQU $02 ;BYTE NUMBER ALLOWED | |
A EQU $01 ; ADDRESS | |
CIO EQU $80 ;C,I, OR O ALLOWED | |
; | |
; COMMAND SYNTAX TABLE | |
; EACH COMMAND HAS TWO BYTE ENTRY | |
; | |
CMDSTB | |
DB FN1,V+D+S ; INIT | |
DB NPB+FN1,V+D+S ;LOAD | |
DB NPB+FN1,V+D+S ;SAVE | |
DB NPB+FN1,V+D+S ;RUN | |
DB FN1,V+D+S ;CHAIN | |
DB FN1,V+D+S ;DELETE | |
DB FN1,V+D+S ;LOCK | |
DB FN1,V+D+S ;UNLOCK | |
DB NPE+FN1,0 ;CLOSE | |
DB FN1,B+R ;READ | |
DB FN1,R+V+D+S ; EXEC | |
DB FN1,B+R ;WRITE | |
DB FN1,R ;POSITION | |
DB FN1,L+V+D+S ;OPEN | |
DB FN1,L+V+D+S ; APPEND | |
DB FN1+FN2,V+D+S ;RENAME | |
DB NPE,V+D+S ;CATALOG | |
DB NPE,CIO ;MONITOR | |
DB NPE,CIO ;NO MONITOR | |
DB NUM1,0 ;PR# | |
DB NUM1,0 ;IN# | |
DB NUM2,0 ;MAXFILES | |
DB NPE,V+D+S ;APPLESOFT | |
DB NPE,0 ; INT | |
DB FN1,V+D+S+A+L ; BSAVE | |
DB FN1,V+D+S+A ; BLOAD | |
DB FN1,V+D+S+A ; BRUN | |
DB FN1,V+D+S ; VERIFY | |
PAGE | |
; | |
; OPTAB – OPTIONAL PARMS SYNTAX TABLES | |
; | |
OPTAB1 | |
DB11 "VDSLRBACIO" | |
OPT1L EQU *-OPTAB1 | |
OPTAB2 | |
DB V,D,S,L,R,B,A,CIO+MC,CIO+MI,CIO+MO | |
OPTAB3 | |
DW @@0,254 ;VOL RANGE | |
DW @@1,@@2 ;DRIVE RANGE | |
DW @@1,@@7 ;SLOT RANGE | |
DW @@1,32767 ;LENGTH RANGE | |
DW @@0,32767 ;REC NO RANGE | |
DW @@0,32767 ;REC BYTE NO RANGE | |
DW @@0,@@$C000 ;ADDRESS RANGE | |
PAGE | |
; | |
; ERROR MESSAGE TABLES | |
; | |
EMSG | |
DB $0D,$07 | |
DB01 "***DISK: " | |
EM1 EQU *-EMSG | |
EM2 EQU *-EMSG | |
EM3 EQU *-EMSG | |
DB01 "SYS" | |
EM4 EQU *-EMSG | |
DB01 "WRITE PROTECT" | |
EM5 EQU *-EMSG | |
DB01 "END OF DATA" | |
EM6 EQU *-EMSG | |
DB01 "FILE NOT FOUND" | |
EM7 EQU *-EMSG | |
DB01 "VOLUME MISMATCH" | |
EM8 EQU *-EMSG | |
DB01 "DISK I/O" | |
EM9 EQU *-EMSG | |
DB01 "DISK FULL" | |
EM10 EQU *-EMSG | |
DB01 "FILE LOCKED" | |
EM11 EQU *-EMSG | |
DB01 "CMD SYNTAX" | |
EM12 EQU *-EMSG | |
DB01 "NO FILE BUFFS AVAIL" | |
EM13 EQU *-EMSG | |
DB01 "NOT BASIC PROGRAM" | |
EM14 EQU *-EMSG | |
DB01 "PROGRAM TOO LARGE" | |
EM15 EQU *-EMSG | |
DB01 "NOT BINARY FILE" | |
; | |
EML EQU *-EMSG | |
DB " ERROR" | |
DB $8D | |
EMDTB | |
DB 0,EM1,EM2,EM3,EM4 | |
DB EM5,EM6,EM7,EM8,EM9 | |
DB EM10,EM11,EM12,EM13,EM14 | |
DB EM15,EML | |
PAGE | |
; | |
; MISC BUT REQD CELLS | |
; | |
CFTABA DW @@$182D ;CURRENT FILE TABLE POINTER | |
ISTATE DB $00 ;INPUT STATE | |
OSTATE DB $03 ;OUTPUT STATE | |
SVOUTS DW @@$FDF0 ;SAVED OUT SWITCH | |
SVINS DW @@$FD1B ;SAVED IN SWITCH | |
CNFTBS DB $03 ;CURRENT NO FILE TABLES | |
DFNFTB DB $03 ;DEFAULT NO FILE TABLES | |
SVSTK DB $F7 ;SAVED STACK PTR | |
SVX DB $00 ;DSAVED X REG | |
SVY DB $01 ;SAVED Y REG | |
SVA DB $A0 ;SAVED ACU | |
LBUFD DB $0E ;LINE BUFF DSPL | |
MONMOD DB $70 ;MONITOR MODE BITS | |
MC EQU $40 ;MONITOR CMDS | |
MI EQU $20 ;MONITOR INPUT | |
MO EQU $10 ;MONITOR OUTPUT | |
CMDNO DB $20 ;COMMAND NO | |
SVBL DB 0,0 | |
SVCMD DB 0 | |
TEMP1A DB $06 | |
TEMP2A DB 1 | |
INOPTS DB $30 ;INPUT OPTIONS | |
CUROPT ;CURRENT OPTIONS | |
CV DW @@$10 ;VOLUME | |
CD DW @@1 ;DRIVE | |
CS DW @@7 ;SLOT | |
CL DW @@1 ;RECORD LENGTH | |
CR DW @@0 ;RECORD NUMBER | |
CB DW @@0 ;RECORD BYTE | |
CA DW @@0 ;ADDRESS | |
IMBITS DB 0 | |
FNAME1 RMB 30 ;FILENAME 1 | |
FNAME2 RMB 30 ;FILENAME 2 | |
DFNFTS DB 3 ;DEFAULT FILE TABLES = 3 | |
CCHAR DB $84 ;CONTROL CHAR | |
ESTATE DB 0 ;EXECUTE STATE | |
EFTABA DB 0,0 ;EXECUTE FILE TABLE POINTER | |
ASIBSW DB 0 ;APPLESOFT, IB SWITCH | |
FASB DB11 "APPLESOFT" | |
FASBL EQU *-FASB | |
PAGE | |
; | |
; DOS ADR TABLES (RELOCATED) | |
; | |
SAT2 | |
AIOB DW @@IOB ;5-ADR IOB | |
AVTOC DW @@VTOC ;6-ADR VTOC | |
AVOLDR DW @@VOLDIR ;7-ADR VOLDIR | |
AEND DW @@EDOS ;END OF DOS | |
; | |
CMDVT DW @@GOODIO-1 ;0-NULL | |
DW @@FOPEN-1 ;1-OPEN FILE | |
DW @@FCLOSE-1 ;2-CLOSE FILE | |
DW @@FREAD-1 ;3-READ FILE | |
DW @@FWRITE-1 ;4-WRITE DATA | |
DW @@FDEL-1 ;5-DELETE FILE | |
DW @@RDIR-1 ;6-READ DIRECTORY | |
DW @@FLOCK-1 ;7-LOCK A FILE | |
DW @@FUNLCK-1 ;8-UNLOCK A FILE | |
DW @@FRNME-1 ;9-RENAME | |
DW @@FPOSTN-1 ;10-POSITION A FILE | |
DW @@FFMT-1 ;FORMAT | |
DW @@FVAR-1 ; VARIFY | |
DW @@GOODIO-1 ;11-SPARE | |
; | |
RVT | |
DW @@GOODIO-1 | |
DW @@RNXBYT-1 ;1-RD NEXT BYTE | |
DW @@RNXBLK-1 ;1-RD NEXT BLOCK | |
DW @@RSPBYT-1 ;2-RD SPECIFIC BYTE | |
DW @@RSPBLK-1 ;3-RD SPECIFIC BLOCK | |
DW @@GOODIO-1 ;4-SPARE | |
; | |
WVT | |
DW @@GOODIO-1 | |
DW @@WNXBYT-1 ;1-WR NEXT BYTE | |
DW @@WNXBLK-1 ;WR NEXT BLOCK | |
DW @@WSPBYT-1 ;2-WR SPECIFIC BYTE | |
DW @@WSPBLK-1 ;3-WR SPECIFIC BLOCK | |
DW @@GOODIO-1 ;4- SPARE | |
EAT2 | |
PAGE | |
; | |
; DOSENT – DOS EXTERNAL ENTRY POINT | |
; EXIT PARM | |
; CARRY CLEAR = OPERATION OK | |
; CARRY SET = ERROR | |
; | |
SC2 | |
DOSENT | |
TSX | |
STX ENTSTK | |
JSR CLCFCB ;GO CALCULATE FCB | |
LDA CCBREQ ;GET REQUEST | |
CMP #CRQMAX ;TTEST REQ RANGE | |
BCS ERR2 ;BR OUT OF RANGE | |
ASLA ;REQ CODE *2 | |
TAX | |
LDA CMDVT+1,X ;PUSH ADR ONTO STACK | |
PHA | |
LDA CMDVT,X | |
PHA | |
RTS | |
ERR2 JMP ERROR2 | |
PAGE | |
; | |
; FOPEN – OPEN A FILE | |
; | |
FOPEN | |
JSR DOPEN | |
JMP GOODIO | |
; | |
DOPEN | |
; | |
JSR DCBSUP | |
; | |
; | |
LDA #1 | |
STA DCBSDL+1 | |
LDX CCBRLN+1 ;MOVE RECORD LENGTH | |
LDA CCBRLN | |
BNE FO2 | |
CPX #0 | |
BNE FO2 | |
INX ;SET RL=256 | |
FO2 STA DCBRCL | |
STX DCBRCL+1 | |
; | |
JSR FNDFIL ;GO FIND FILE | |
BCC FO3 ;BR IF FOUND | |
; ;CREATE FILE | |
LDA #0 | |
STA VDFILE+34,X | |
LDA #1 | |
STA VDFILE+33,X | |
STX TEMP1 ;SAVE VDIR INDEX | |
STX DCBVDI | |
JSR GETSEC ;GO ALLOCATE SECTOR | |
LDX TEMP1 | |
STA VDFILE+1,X ;PUT SECTOR INTO VDIR | |
STA DCBFDS ;PUT SECTOR AS FIRST FILE DIR | |
STA DCBCDS ;PUT SECTOR AS CURRENT FILE DIR | |
; | |
LDA DCBATK ;GET ALLOCATED TRACK | |
STA VDFILE,X ;PUT INTO VDIR | |
STA DCBFDT ;AND AS 1ST FILE DIR | |
STA DCBCDT ;AND AS CURRENT FILE DIR | |
; | |
LDA CCBFUC ;SET USE CODE | |
STA VDFILE+2,X ;INTO DIRECTORY | |
; | |
JSR WRVDIR ;GO WRITE VOL DIRECTORY | |
; | |
JSR MVFCBD ;MOVE FILE DIR ADR TO ZP | |
JSR CLRSEC ;GO CLEAR IT | |
JSR WRFDGO ;GO WRITE FILE DIRECTORY DONE CREATION | |
; DONE CREATION | |
LDX TEMP1 ;RE-GET INDEX | |
LDA #CREFNF | |
STA CCBSTA | |
; | |
FO3 | |
LDA VDFILE,X ;MOVE FILE DIR TRACK | |
STA DCBFDT | |
LDA VDFILE+1,X ;MOVE FILE DIR SECTOR | |
STA DCBFDS | |
LDA VDFILE+2,X ;MOVE FILE USE CODE | |
STA CCBFUC | |
STA DCBFUC | |
LDA VDFILE+33,X | |
STA DCBNSA | |
LDA VDFILE+34,X | |
STA DCBNSA+1 | |
; | |
LDA #255 ;INDICATE NO SECTOR | |
STA DCBCMS ;IN MEMORY | |
STA DCBCMS+1 | |
LDA VTDMS ;MOVE MAX FD SECS | |
STA DCBDMS ;TO DCB | |
CLC | |
JMP RDFDIR ; READ 1ST DIRECTORY RECORD | |
; | |
; | |
; | |
; | |
DCBSUP | |
LDA #0 | |
TAX | |
FO1 STA FCBDCB,X ;CLEAR DCB | |
INX | |
CPX #DCBLEN | |
BNE FO1 | |
; | |
LDA CCBVOL ;MOVE VOL | |
EOR #$FF ;INVERT VOL BITS | |
STA DCBVOL | |
LDA CCBDRV ;MOVE DRIVE | |
STA DCBDRV | |
LDA CCBSLT ;GET USER SPEC SLOT | |
ASLA ;SLOT*16 | |
ASLA | |
ASLA | |
ASLA | |
TAX | |
STX DCBSLT | |
LDA #17 | |
STA DCBVTN | |
RTS | |
PAGE | |
; | |
; FCLOSE – CLOSE A FILE | |
; | |
FCLOSE | |
JSR WRSECT ;WRITE OPEN SECTOR | |
JSR WRFDIR ;GO WRITE FILE DIRECTORY | |
JSR FRETRK ;FREE UNUSED SECTORS | |
LDA #IBCWTS | |
AND DCBWRF | |
BEQ FC2 | |
; | |
JSR RDVTOC ; READ VTOC | |
LDA #0 | |
CLC | |
FC1 | |
JSR RDVDIR ; READ VDIR | |
SEC | |
DEC DCBVDR | |
BNE FC1 ; BR IF NOT | |
LDX DCBVDI ; GET FILES INDEX | |
LDA DCBNSA ; MOVE NO SECTIONS ALLOCATED | |
STA VDFILE+33,X | |
LDA DCBNSA+1 | |
STA VDFILE+34,X | |
JSR WRVDIR ; WRITE VOL DIR REC | |
; | |
; | |
FC2 | |
JMP GOODIO ;DONE | |
PAGE | |
; | |
; FRNME – RENAME A FILE | |
; | |
FRNME | |
JSR DOPEN ;GO OPEN FILE | |
LDA DCBFUC ;GET USE CODE | |
BMI ER10 ;BR IF LOCKED | |
LDA CCBFN2 ;MOVE NEW FN | |
STA ZPGFCB ;PTR TO ZPG | |
LDA CCBFN2+1 | |
STA ZPGFCB+1 | |
LDX TEMP1 ;GET VDIR INDEX | |
JSR MVFN ;GO MOVE FILE NAME | |
JSR WRVDIR ;GO WRITE FILE VDIR | |
JMP GOODIO ;DONE RENAME | |
PAGE | |
; | |
; FREAD – READ A FILE | |
; | |
FREAD | |
; | |
LDA CCBRQM ;GET REQ MOD | |
CMP #CRMMAX ;TEST LIMIT | |
BCS ERR3A | |
; | |
ASLA ;CODE*2 | |
TAX | |
LDA RVT+1,X ;GET READ ROUTINE | |
PHA ;VECTOR ADR | |
LDA RVT,X | |
PHA ;AND | |
RTS ;GO TO IT | |
; | |
ERR3A JMP ERROR3 | |
ER10 JMP ERRR10 | |
; | |
; FWRITE – WRITE A FILE | |
; | |
FWRITE | |
LDA DCBFUC ;IS FILE LOCKED | |
BMI ER10 ;BR IF LOCKED | |
LDA CCBRQM ;GET REQ MOD | |
CMP #CRMMAX ;IN RANGE | |
BCS ERR3A ;BR IF NOT IN RANGE | |
; | |
ASLA | |
TAX | |
LDA WVT+1,X ;GET ROUTINE ADR | |
PHA | |
LDA WVT,X | |
PHA | |
RTS ;AND GO TO IT | |
PAGE | |
; | |
; RSPBYT – READ A SPECIFIC BYTE | |
; | |
RSPBYT | |
JSR LOCSEC ;GO GET REQD REL SECTOR | |
; | |
; RNXBYT – READ NEXT BYTE | |
; | |
RNXBYT JSR GETBYT ;GO GET BYTE | |
STA CCBDAT ;PUT IN CCB | |
JMP GOODIO ;DONE | |
; | |
; RSPBLK – READ A SPECIFIC BLOCK | |
; | |
RSPBLK JSR LOCSEC ;GO LOCATE REL SECTOR | |
; | |
; RNXBLK – READ NEXT BLOCK | |
; | |
RNXBLK | |
JSR DTBLN ;GO DECR LEN (NOT RTN IF=0) | |
JSR GETBYT ;GO GET BYTE | |
PHA | |
JSR MIBDA ;GO MOVE BLOCK ADR AND INCR | |
LDY #0 | |
PLA | |
STA (ZPGFCB),Y ;SET DATA BYTE | |
JMP RNXBLK ;GO FOR NEXT BYTE | |
; | |
; GETBYT – GET A DATA BYTE | |
; | |
GETBYT | |
JSR LOCNXB ;LOCATE NEXT BYTE | |
BCS EOFIN ;BR IF EOF | |
LDA (ZPGFCB),Y ;BR IF EOF | |
PHA ;SAVE IT | |
JSR INCRRB ;INCR REC BYTE | |
JSR INCSCB ;INCR SAVED BYTE | |
PLA ;GET SAVED BYTE | |
RTS ;RETURN | |
; | |
EOFIN JMP ERROR5 ;GO TO EOF RTN | |
PAGE | |
; | |
; WSPBYT – WRITE SPECIFIC BYTE | |
; | |
WSPBYT | |
JSR LOCSEC ;GO LOCATE SECTOR | |
; | |
; WNXBYT – WRITE NEXT BYTE | |
; | |
WNXBYT | |
LDA CCBDAT ;GET THE BYTE | |
JSR PUTBYT ;GO WRITE BYTE | |
JMP GOODIO ;DONE | |
; | |
; WSPBLK – WRITE NEXT BLOCK | |
; | |
WSPBLK | |
JSR LOCSEC ;GO LOCATE SECTOR | |
; | |
; WNXBLK – WRITE BLOCK | |
; | |
WNXBLK | |
JSR MIBDA ;GO MOVE ADR TO ZPG AND DEC | |
LDY #0 | |
LDA (ZPGFCB),Y ;GET DATA BYTE | |
JSR PUTBYT ;GO PUT IT | |
JSR DTBLN ;GO DEC BLK LEN (NOT RTN IF = 0) | |
JMP WNXBLK | |
; | |
; PUTBYT – PUT OUT ONE BYTE | |
; | |
PUTBYT | |
PHA ;SAVE DATA BYTE | |
JSR LOCNXB ;GO LOCATE NEXT BYTE | |
; | |
PLA ;GO SAVED BYTE | |
STA (ZPGFCB),Y ;PUT THE BYTE | |
LDA #$40 ;SET WRITE SECTOR REQD | |
ORA DCBWRF | |
STA DCBWRF | |
; | |
JSR INCRRB ;INCR REL REC BYTE | |
JMP INCSCB ; INCR SECTOR BYTE | |
PAGE | |
; | |
; FLOCK – LOCK A FILE | |
; | |
FLOCK LDA #$80 ;REMEMBER LOCK | |
STA TEMP3 | |
BNE LCKGO | |
; | |
; FUNLCK – UNLOCK A FILE | |
; | |
FUNLCK LDA #00 ;REMEMBER UNLOCK | |
STA TEMP3 | |
; | |
LCKGO | |
; | |
JSR DOPEN ;GO OPEN FILE | |
LDX TEMP1 | |
LDA VDFILE+2,X ;GET FILE USE CODE | |
AND #$7F ;TURN OFF LOCK | |
ORA TEMP3 | |
STA VDFILE+2,X | |
JSR WRVDIR | |
JMP GOODIO | |
; | |
; FPOSTN – POSITION A FILE | |
FPOSTN JSR LOCSEC ;GO POSITION | |
JMP GOODIO ;DONE | |
; | |
; | |
; FVAR – VARIFY A FILE | |
; | |
FVAR | |
JSR DOPEN ; OPEN FILE | |
VAR1 JSR LOCNXB ; READ A SECTOR | |
BCS VAR2 ; BR IF EOF | |
INC DCBCRS ; INCREMENT SECTOR | |
BNE VAR1 | |
INC DCBCRS+1 | |
JMP VAR1 ; READ THIS ONE | |
VAR2 JMP GOODIO ; DONE | |
PAGE | |
; | |
; FDEL – DELETE A FILE | |
; | |
FDEL | |
JSR DOPEN ;GO OPEN FILE | |
; | |
LDX TEMP1 ;SAVED INDEX | |
LDA VDFILE+2,X ;IS FILE LOCKED | |
BPL FD3 ;BR NOT LOCKED | |
JMP ERRR10 | |
; | |
FD3 | |
LDX TEMP1 ;GET SAVED INDEX | |
LDA VDFILE,X ;GET DIR TRACK | |
STA DCBFDT ;SET AS 1ST FD TRACK | |
STA VDFILE+32,X ;SAVE IN LC OF FN | |
LDA #$FF ;DELETED FILE MARKER | |
STA VDFILE,X ;CLEAR ENTRY | |
LDY VDFILE+1,X ;GET DIR SECTOR | |
STY DCBFDS ;SET AS 1ST FD SEC | |
JSR WRVDIR ;GO WRITE VOLUME DIR | |
CLC | |
FD4 JSR RDFDIR ;GET 1ST FILE DIR SECTOR | |
BCS FD7 ;BR IF NO MORE | |
JSR MVFCBD ;MOVE DIR TO ZPG | |
LDY #FDENT ;POINT Y TO 1ST SEC ENT | |
FD5 STY TEMP1 ;SAVE Y | |
LDA (ZPGFCB),Y ;GET REACK | |
BMI FD6 ;BR IF DONE | |
BEQ FD6 ;BR IF END OF FILE | |
PHA ;SAVE TRK | |
INY | |
LDA (ZPGFCB),Y ;GET SECTOR | |
TAY ;TO Y | |
PLA ;GET TRK | |
JSR FDSUB ;GO FREE SECTOR | |
FD6 LDY TEMP1 ;GET DIR INDEX | |
INY ;INCR TO NEXT ENTRY | |
INY | |
BNE FD5 ;BR NOT DONE THIS DIR | |
LDA DCBCDT ;GET THIS DIR TRK | |
LDY DCBCDS ;AND SECTOR | |
JSR FDSUB ;AND GO FREE IT | |
SEC ;GO | |
BCS FD4 ;READ NEXT DIR | |
FD7 | |
JSR WRVTOC | |
JMP GOODIO | |
; | |
FDSUB | |
SEC ;SET FOR RE USE OF SEC | |
JSR FRESEC ;GO FREE SECTOR | |
LDA #0 ;CLEAR DCB BIT MAP | |
LDX #3 | |
FDS1 STA DCBALS,X | |
DEX | |
BPL FDS1 | |
RTS | |
PAGE | |
; | |
; RDIR – PRINT DIRECTORY | |
; | |
RDIR | |
JSR DCBSUP | |
LDA #$FF | |
STA DCBVOL | |
JSR RDVTOC | |
LDA #22 ; SET 21 LINES | |
STA TEMP2 | |
JSR PRCR ;GO PRINT | |
JSR PRCR ; PRINT ANOTHER CHAR | |
LDX #VML ; VOLUME MSG LENGTH | |
RD0 LDA VOLMES,X ; GET MSG CHAR | |
JSR PRINT ; PRINT IT | |
DEX ; DECREMENT COUNT | |
BPL RD0 ; BR IF MORE | |
; | |
STX CNUM+1 | |
LDA IBSMOD ; MOVE VOL NO FOR | |
STA CNUM ; CONVERSION | |
JSR PRNUM ; GO PRINT VOL NO | |
; | |
JSR PRCR ; PRINT CR | |
JSR PRCR ; AND AGAIN | |
; | |
CLC ;FIRST RECORD | |
; | |
RD1 JSR RDVDIR ;GO READ REC | |
BCS RD5 | |
LDX #0 ;SET INDEX=0 | |
RD2 STX TEMP1 ;SAVE INDEX | |
LDA VDFILE,X ;GET TRACK | |
BEQ RD5 ;BR IF END OF DIR | |
BMI RD4 ;BR IF DELETED | |
; | |
LDY #$A0 ; BLANK | |
LDA VDFILE+2,X ; GET TYPE | |
BPL RD2A ; BR IF NOT LOCKED | |
LDY #'*'+$80 ; AST | |
RD2A TYA ; ACU = AST OR BLANK | |
JSR PRINT ; PRINT ACU | |
; | |
LDA VDFILE+2,X ; GET TYPE | |
AND #$07 ; MASK OUT MISC | |
LDY #3 ; SET INDEX = 3 | |
RD2B LSRA ; SHIFT OUT LSB | |
BCS RD2C ;BR IF TYPE BIT OUT | |
DEY ; DEC INDEX | |
BNE RD2B ; BR IF NOT ACC BITS | |
RD2C | |
LDA FTTAB,Y ; GET TYPE CODE | |
JSR PRINT ; PRINT IT | |
LDA #$A0 ; BLANK | |
JSR PRINT ; PRINT | |
; | |
LDA VDFILE+33,X ; MOVE FILE LENGTH | |
STA CNUM ; TO CNUM | |
LDA VDFILE+34,X | |
STA CNUM+1 | |
JSR PRNUM ; GO PRINT NUMBER | |
LDA #$A0 ; BLANK | |
JSR PRINT ; PRINT | |
; | |
INX | |
INX | |
INX | |
LDY #29 | |
RD3 LDA VDFILE,X ;GET CHAR | |
JSR PRINT ;PRINT CHAR | |
INX | |
DEY | |
BPL RD3 | |
JSR PRCR ;GO PRINT CR | |
RD4 JSR VDINC ;INCR INDEX | |
BCC RD2 ;BR IF MORE IN DIR | |
BCS RD1 ;GO READ NEXT DIR SECT | |
; | |
RD5 JMP GOODIO ;DONE | |
; | |
PRCR | |
LDA #$8D ;CR | |
JSR PRINT ;PRINTED | |
DEC TEMP2 ;DEC LINE COUNTER | |
BNE PRCR1 ;BR IF NOT ZERO | |
JSR GETKEY ;WAIT FOR INPUT | |
LDA #21 ; RESET LINE COUNTER | |
STA TEMP2 | |
PRCR1 RTS ;DONE | |
PAGE | |
PRNUM | |
LDY #2 ; 3 DIGITS | |
PRN1 LDA #0 ; INIT DIGIT TO ZERO | |
PHA ; SAVE IT | |
; | |
PRN2 LDA CNUM ; GET NUMBER | |
CMP CVTAB,Y ; IF NUM < CVTAB ENTRY | |
BCC PRN3 ; THEN DONE THIS DIGIT | |
; | |
SBC CVTAB,Y ; SUBTRACT TABLE ENTRY | |
STA CNUM ; FROM NUM | |
LDA CNUM+1 | |
SBC #0 | |
STA CNUM+1 | |
PLA ; INCREMENT DIGIT | |
ADC #0 | |
PHA | |
JMP PRN2 ; TRY AGAIN | |
; | |
PRN3 | |
PLA ; GET DIGIT | |
ORA #$B0 ; ADD ASCII | |
JSR PRINT ; PRINT IT | |
DEY ; DECREMENT DIGIT COUNT | |
BPL PRN1 ; BR IF MORE DIGIT | |
; | |
RTS ; DONE | |
PAGE | |
; | |
; CLCFCB – GET FCB VIA INDEX AND MOVE IT | |
; | |
CLCFCB | |
; | |
JSR MVFCBP ;MOVE FCB PTR TO ZPG | |
LDY #0 | |
STY CCBSTA | |
CF3 LDA (ZPGFCB),Y ;MOVE FCB TO | |
STA FCBB,Y ;FCB WORK AREA | |
INY | |
CPY #FCBLEN | |
BNE CF3 | |
; | |
CLC ;DONE | |
RTS | |
; | |
; RTNFCB – MOVE FCB FROM WORK AREA TO FCB | |
; | |
RTNFCB | |
JSR MVFCBP ;MOVE FCB ADR TO ZPG | |
; | |
LDY #0 | |
RF1 LDA FCBB,Y | |
STA (ZPGFCB),Y | |
INY | |
CPY #FCBLEN | |
BNE RF1 | |
RTS | |
PAGE | |
; | |
; FFMT – EXECUTE FORMAT REQUEST | |
; | |
FFMT | |
JSR DCBSUP ; SET UP DCB | |
LDA #IBFMT | |
JSR DCBIO2 | |
LDA DCBVOL ; SET VOL NO | |
EOR #$FF | |
STA VVOLNO | |
LDA #17 | |
STA VALCA1 ; ALOCATE BYTE 1 | |
LDA #1 | |
STA VALCA2 ; ADD BYTE 2 | |
; | |
LDX #VSECAL-VTOC | |
LDA #0 | |
NT1 STA VTOC,X ; CLEAR SECTOR AREA | |
INX | |
BNE NT1 | |
; | |
LDX #3*4 ;START AT TRACK 3 | |
NT2 CPX #35*4 ; END AT TRACK 35 | |
BEQ NT4 | |
LDY #3 ; 4 BYTES OF INFO | |
NT3 LDA ALC10S,Y ; 10 SECTORS ALLOCATE | |
STA VSECAL,X | |
INX | |
DEY | |
BPL NT3 | |
CPX #17*4 ; AT TRACK 17 | |
BNE NT2 ; BR IF NOT | |
LDX #18*4 ; SKIP TO 18 | |
BNE NT2 | |
; | |
NT4 JSR WRVTOC ; WRITE NEW VTOC | |
; | |
LDX #0 | |
TXA | |
NT5 STA VOLDIR,X ; CLEAR VOLDIR | |
INX | |
BNE NT5 | |
; | |
JSR MVVDBA ; MOVE BUF PTRS | |
; | |
LDA #17 ; TRACK 17 | |
LDY VNOSEC | |
DEY | |
DEY | |
STA IBTRK ; INTO IOB | |
NT6 STA VDLTRK ; INTO LINK | |
NT7 STY VDLSEC | |
INY | |
STY IBSECT | |
LDA #IBCWTS | |
JSR DCBIO2 | |
LDY VDLSEC | |
DEY ; DECREMENT SECTOR | |
BMI NT8 ; BR LAST WRITTEN | |
BNE NT7 ; BR NOT LAST | |
TYA ; LAST, SET LINK TRK=0 | |
BEQ NT6 | |
; | |
NT8 | |
JSR DLDSUP ; GO SET UP FOR DOSLDR | |
JSR WBOOT ;GO WRITE THE BOOT | |
JMP GOODIO ; DONE | |
PAGE | |
; | |
; DLDSUP – SET UP FOR DOSLDR | |
; | |
DLDSUP | |
LDA CCBBSA | |
STA IBBUFP+1 ; START ADR | |
LDA #0 | |
STA IBBUFP | |
LDA DCBVOL ; VOL | |
EOR #$FF | |
STA IBVOL | |
RTS | |
PAGE | |
; | |
; MVFCBX – MOVE FCB ADRS TO ZPGFCB | |
; | |
MVFCBP LDX #0 ;MOVE FCB ADR | |
BEQ MVF1 | |
MVFCBD LDX #2 ;MOVE FCB DIR BUFF | |
BNE MVF1 | |
MVFCBS LDX #4 ;MOVE FCB SECTOR BUFF | |
; | |
MVF1 | |
LDA CFCBAD,X ;DO THE MOVE | |
STA ZPGFCB | |
LDA CFCBAD+1,X | |
STA ZPGFCB+1 | |
RTS | |
; | |
; CLRSEC – CLEAR SECTOR | |
; | |
CLRSEC | |
LDA #0 | |
TAY | |
CS1 STA (ZPGFCB),Y | |
INY | |
BNE CS1 | |
RTS | |
PAGE | |
; | |
; WRSECT – WRITE CURRENT SECTOR IF REQD | |
; | |
WRSECT | |
BIT DCBWRF ;GET WRITE REQD FLAG | |
BVS WRSGO ;BR IF WRITE SECTOR REQD | |
RTS ;RTS | |
; | |
WRSGO | |
JSR MVSBA ;GO MOVE SECT BUFF ADR | |
; | |
LDA #IBCWTS ;GET COMMAND | |
JSR DCBIO ;GO FILL IN IOB AND DO IO | |
; | |
LDA #$BF ;SET WRITE SECTOR REQD BIT OFF | |
AND DCBWRF | |
STA DCBWRF | |
RTS ;DONE | |
PAGE | |
; | |
; WRFDIR – WRITE FILE DIRECTORY IF REQD | |
; | |
WRFDIR | |
LDA DCBWRF ;GET WRITE REQD FLAG | |
BMI WRFDGO ;BR IF WRITE DIR REQD | |
RTS ;DONE IF NOT | |
; | |
WRFDGO | |
JSR MVFDBA | |
; | |
LDA #IBCWTS ;GET WRITE CMD | |
JSR DCBIO ;GO FILL IN IOB AND DO I/O | |
; | |
LDA #$7F ;TURN WRITE DIR REQD BIT OFF | |
AND DCBWRF | |
STA DCBWRF | |
RTS ;DONE | |
; | |
; MVFDBA – MOVE FILE DIRECTORY BUFF ASDR TO IOD | |
; | |
MVFDBA | |
LDA CFCBDR ;MOVE ADR | |
STA IBBUFP | |
LDA CFCBDR+1 | |
STA IBBUFP+1 | |
LDX DCBCDT ;GET TRACK | |
LDY DCBCDS ;GET SECTOR | |
RTS | |
PAGE | |
; | |
; RDFDIR – READ FILE DIRECTORY | |
; | |
RDFDIR | |
PHP ;SAVE STATUS | |
JSR WRFDIR ;GO WRITE CURRENT DIR IF REQD | |
JSR MVFDBA ;GO MOVE DBUFF ADR TO ZPG | |
JSR MVFCBD ;MOVE DBUFF ADR TO ZPG | |
PLP ;GET SAVED STATUS | |
BCS RFDNXT ;BR IF RD NEXT | |
; | |
LDX DCBFDT ;TRACK | |
LDY DCBFDS ;SECTOR | |
JMP RFDIO1 ;GO READ | |
; | |
RFDNXT | |
LDY #FDLTRK ;GET LINK TRACK | |
LDA (ZPGFCB),Y | |
BEQ RFDNL ;NR NO LINK | |
TAX ;PUT TRACK INTO X | |
INY | |
LDA (ZPGFCB),Y ;SET LINK SECTOR | |
TAY ;PUT SECTOR INTO Y | |
JMP RFDIO1 ;GO DO I/O | |
; | |
RFDNL | |
LDA CCBREQ ;THIS A WRITE | |
CMP #CRQWR | |
BEQ RFDNL1 ;BR IF WRITE | |
SEC ;SET EOF | |
RTS ;RETURN | |
; | |
RFDNL1 | |
JSR GETSEC ;GET A SECTOR | |
LDY #FDLSEC | |
STA (ZPGFCB),Y ;PUT IN LINK | |
PHA ;SAVE SECTOR | |
DEY | |
LDA DCBATK ;GET TRACK | |
STA (ZPGFCB),Y ;PUT IN LINK | |
PHA ;SAVE TRACK | |
JSR WRFDGO ;GO WRITE OLD DIR DEC | |
; | |
JSR CLRSEC ;CLEAN OUT DIR | |
LDY #FDFRS ;SET NEW DIR SEC 1ST REL | |
LDA DCBDNF ;FILE SECTOR | |
STA (ZPGFCB),Y | |
INY | |
LDA DCBDNF+1 | |
STA (ZPGFCB),Y | |
; | |
PLA ;GET SAVED TRACK | |
TAX ;INTO X | |
PLA ;GET SAVED SECTOR | |
TAY ;INTO Y | |
LDA #IBCWTS ;SET WRITE CMD | |
BNE RFDIO2 ;GO DO I/O | |
; | |
RFDIO1 LDA #IBCRTS ;SET READ CMD | |
RFDIO2 STX DCBCDT ;SET CURR TRACK | |
STY DCBCDS ;SET CURR SECTOR | |
JSR DCBIO ;GO I/O | |
; | |
LDY #FDFRS ;GET POINTER TO FIRST RE SECTOR | |
LDA (ZPGFCB),Y ;GET FRS | |
STA DCBDFS ;SET INTO DCB | |
CLC | |
ADC DCBDMS ;ADD MAX SECTORS | |
STA DCBDNF ;PUT INTO DCB | |
; | |
INY ;DO SAME FOR HI BYTE | |
LDA (ZPGFCB),Y | |
STA DCBDFS+1 | |
ADC DCBDMS+1 | |
STA DCBDNF+1 | |
; | |
CLC | |
RTS ;DONE | |
PAGE | |
; | |
; RDSECT – READ A SECTOR | |
; | |
RDSECT | |
JSR MVSBA ;GO MOVE SECTOR BUFFER ADR | |
; | |
LDA #IBCRTS | |
JMP DCBIO ;GO DO I/O | |
; | |
; MVSBA – MOVE SECTOR BUFFER ADR FOR I/O | |
; | |
MVSBA | |
LDY CFCBSB ;GET SECTOR BUFF ADR | |
LDA CFCBSB+1 | |
STY IBBUFP ;SET IOB SECTOR | |
STA IBBUFP+1 ;BUFF PTR | |
LDX DCBTRK ;GET TRACK | |
LDY DCBSEC ;GET SECTOR | |
RTS ;RTN | |
PAGE | |
; | |
; RDVTOC – READ VTOC | |
; WRVTOC – WRITE VTOC | |
; | |
RDVTOC | |
LDA #IBCRTS ;READ | |
BNE VTIO | |
WRVTOC | |
LDA #IBCWTS ;WRITE | |
; | |
VTIO LDY AVTOC ;MOVE BUFF ADR | |
STY IBBUFP | |
LDY AVTOC+1 | |
STY IBBUFP+1 | |
; | |
LDX DCBVTN ;GET TRACK | |
LDY #0 | |
JMP DCBIO ;GO DO I/O | |
PAGE | |
; | |
; RDVDIR – READ VOLUME DIRECTOR | |
; | |
RDVDIR | |
PHP ;SAVES STATUS | |
JSR MVVDBA | |
; | |
PLP ;GET STATUS | |
BCS RVDA ;BR IF R0 NEXT | |
; | |
LDY VDIRSC ;GET LINK SECTOR | |
LDX VDIRTK ;GET FIRST TRK | |
BNE RDVGO ;GO READ | |
; | |
RVDA | |
LDX VDLTRK ;GET SECTOR | |
BNE RDVC ;BR IF A LINK | |
SEC ; SET END OF DIR | |
RTS | |
; | |
RDVC LDY VDLSEC ;GET SECTOR | |
RDVGO | |
STX CVDTRK ;SET CUR TRACK | |
STY CVDSEC ;SET CUR SECTOR | |
LDA #IBCRTS ;GET CMD | |
JSR DCBIO ; GO DO I/O | |
CLC | |
RTS | |
PAGE | |
; | |
; WRVDIR – WRITE VOLUME DIRECTORY SECTOR | |
; | |
WRVDIR | |
JSR MVVDBA | |
; | |
LDX CVDTRK ;CURRENT TRACK | |
LDY CVDSEC ;CURRENT SECTOR | |
LDA #IBCWTS ;WRITE COMMAND | |
JMP DCBIO ;GO DO I/O | |
; | |
; MVVDBA – MOVE VOL DIR BUF ADR TO IOB | |
; | |
MVVDBA | |
LDA AVOLDR ;MOVE ADR | |
STA IBBUFP | |
LDA AVOLDR+1 | |
STA IBBUFP+1 | |
RTS | |
PAGE | |
; | |
; DCBIO – DO I/O FOR A DCB | |
; | |
DCBIO | |
STX IBTRK ;TRACK | |
STY IBSECT ;SECTOR | |
DCBIO2 | |
STA IBCMD ;COMMAND | |
CMP #IBCWTS | |
BNE DCBIO1 | |
ORA DCBWRF | |
STA DCBWRF | |
DCBIO1 | |
LDA DCBVOL ;VOL | |
EOR #$FF ;UNINVERT VOL BITS | |
STA IBVOL | |
LDA DCBSLT ;SLOT | |
STA IBSLOT | |
LDA DCBDRV ;DRIVE | |
STA IBDRVN | |
LDA DCBSDL ;LENGTH | |
STA IBDLEN | |
LDA DCBSDL+1 | |
STA IBDLEN+1 | |
LDA #1 ;IOB TYPE | |
STA IBTYPE | |
; | |
LDY AIOB ;IOB ADR | |
LDA AIOB+1 | |
JSR DISKIO ;GO DO I/O | |
; | |
LDA IBSMOD | |
STA CCBVOL | |
LDA #$FF ;RESET VOL | |
STA IBVOL | |
BCS BADIO ;BR IF BAD | |
RTS ;RTN IF GOOD | |
; | |
BADIO LDA IBSTAT ; GET STATUS | |
LDY #CREVMM | |
CMP #IBVMME ; WAS IT VOLUME MISMATCH | |
BEQ BD2 ; BR IF YES | |
LDY #CREPRO | |
CMP #IBWPER | |
BEQ BD2 | |
LDY #CREIOE | |
BD2 TYA | |
JMP ERRORB ;GO RTN | |
PAGE | |
; | |
; LOCNXB – LOCATE NEXT BYTE | |
; | |
LOCNXB | |
LDA DCBCRS ;IS THE CURRENT RELATIVE SECTOR | |
CMP DCBCMS ;EQUAL TO THE CURRENT MEM SECTOR | |
BNE LNB1 ;BR IF NOT EQ | |
LDA DCBCRS+1 | |
CMP DCBCMS+1 | |
BEQ LNB8 ;BR IF REQD SECTOR IN MEM | |
; | |
LNB1 ;NEED A DIFFERENT SECTOR IN MEM | |
JSR WRSECT ;GO WRITE SECTOR(IF REQD) | |
; | |
LNB2 LDA DCBCRS+1 ;IS CURRENT REL SECTORY | |
CMP DCBDFS+1 ;IS CURRENT DIRECTORY (LOW LIMIT) | |
BCC LNB4 ;BR IF IN A PREVIOUS DIR | |
BNE LNB3 ;BR IF MAYBE IN THIS ONE | |
LDA DCBCRS ;TEST LOW BYTES | |
CMP DCBDFS | |
BCC LNB4 ;BR IF IN PREVIOUS DIR | |
; | |
LNB3 LDA DCBCRS+1 ;IS CURRENT REL SECTOR | |
CMP DCBDNF+1 ;IN CURRENT DIRECTOR (HI LIMIT) | |
BCC LNB6 ;BR IF IN THIS ONE | |
BNE LNB4 ;BR IF IN A NEXT DIR | |
LDA DCBCRS | |
CMP DCBDNF | |
BCC LNB6 ;BR IF IN THIS ONE | |
; ;REQD SECTOR IN A NEXT DIRECTORY | |
LNB4 JSR RDFDIR ;GO READ NEXT FILE DIR | |
BCC LNB2 ;BR NXT AVAIL | |
RTS ;RETURN IF EOF DIR | |
; | |
; | |
LNB6 | |
SEC ;CALCULATE DISPL INTO DIR | |
LDA DCBCRS ;REQD REL SECTOR MINUS | |
SBC DCBDFS | |
ASLA ;TIMES 2 | |
ADC #FDENT ;PLUS DISPL TO 1ST | |
TAY | |
JSR MVFCBD ;MOVE ADR TO ZPG | |
LDA (ZPGFCB),Y ;GET TRACK | |
BNE LNB7 ;BR IF NOT ZERO | |
LDA CCBREQ | |
CMP #CRQWR ;WRITE! | |
BEQ LNB7A | |
SEC | |
RTS | |
LNB7A JSR GNWSEC ;GO GET A NEW SECTOR | |
JMP LNBCON | |
LNB7 STA DCBTRK ;SET TRK INTO DCB | |
INY | |
LDA (ZPGFCB),Y ;GET SECTOR | |
STA DCBSEC ;PUT INTO DCB | |
JSR RDSECT ;GO READ SECTOR | |
LNBCON LDA DCBCRS ;MOVE CUR REL SECTOR | |
STA DCBCMS | |
LDA DCBCRS+1 ;TO CUR MEM SECTOR | |
STA DCBCMS+1 | |
; | |
LNB8 | |
JSR MVFCBS ;MOVE SECTOR BUFF ADR TO ZP | |
LDY DCBCSB ;GET SECT BYTE | |
CLC ;CARRY CLEAR = ALL OK | |
RTS ;DONE | |
PAGE | |
; | |
; | |
GNWSEC ;NEED NEW SECTOR | |
STY TEMP2 ;SAVE DIR INDEX | |
JSR GETSEC ;GET A SECTOR | |
LDY TEMP2 | |
INY | |
STA (ZPGFCB),Y ;SET NEW TRACK | |
STA DCBSEC | |
DEY | |
LDA DCBATK | |
STA (ZPGFCB),Y ;SET NEW TRACK | |
STA DCBTRK | |
; | |
JSR MVFCBS | |
JSR CLRSEC ;GO CLEAR SECTOR | |
; | |
; | |
LDA #$C0 ;INDICATE BOTH | |
ORA DCBWRF ;DIR AND SECTOR | |
STA DCBWRF ;MUST BE WRITTEN | |
RTS ;DONE | |
PAGE | |
; | |
; INCRRB – INCREMENT RELATIVE RECORD BYTE | |
; | |
INCRRB | |
LDX DCBCRR ;MOVE BYTE JUST READ OR WRITTEN | |
STX CCBRRN | |
LDX DCBCRR+1 | |
STX CCBRRN+1 | |
LDX DCBCRB ;X=REL BYTE (LOW) | |
LDY DCBCRB+1 ;Y=REL BYTE HI | |
STX CCBBYT | |
STY CCBBYT+1 | |
INX ;INC REL BYTE (LOW) | |
BNE INCR1 ;BR IF NO CARRY | |
INY ;INC REL BYTE (HI) | |
; | |
INCR1 CPY DCBRCL+1 ;REL BYTE=REC LENGTH | |
BNE INCR2 ;BR IF NOT | |
CPX DCBRCL ;TEST LOW BYTES | |
BNE INCR2 | |
LDX #0 | |
LDY #0 ;RESET REL BYTE TO ZERO | |
INC DCBCRR ;AND INCR | |
BNE INCR2 ;RELATIVE RECORD | |
INC DCBCRR+1 | |
; | |
INCR2 STX DCBCRB ;SAVE NEW RELATIVE BYTE | |
STY DCBCRB+1 | |
; | |
RTS | |
PAGE | |
; | |
; INCSCB – INCREMENT SECTOR BYTE | |
; | |
INCSCB | |
INC DCBCSB ;INC SECTOR BYTE | |
BNE INCS2 ;BR IF NOT FULL | |
INC DCBCRS ;AND INCR | |
BNE INCS2 ;RELATIVE SECTOR | |
INC DCBCRS+1 | |
; | |
; | |
INCS2 | |
RTS ;DONE | |
PAGE | |
; | |
; MIBDA – MOVE AND INCREMENT CCBDAT | |
; | |
MIBDA | |
LDY CCBBBA ;Y=ADR LOW | |
LDX CCBBBA+1 ;X=ADR HI | |
STY ZPGFCB ;PUT ADR INTO ZPG | |
STX ZPGFCB+1 | |
; | |
INC CCBBBA ;INC ADR LOW | |
BNE MIB1 ;BR IF NOT ZERO | |
INC CCBBBA+1 ;INC ADR HI | |
MIB1 RTS ;DONE | |
; | |
; DTBLN – DECREMENT BLOCK LENGTH AND TEST ZERO | |
; | |
DTBLN | |
LDY CCBBLN ;GET LEN LOW | |
BNE DTB1 ;BR IF NOT ZERO | |
LDX CCBBLN+1 ;GET LEN HI | |
BEQ DTB2 ;BR IF LEN=0 | |
DEC CCBBLN+1 ;DEC LEN (HIGH) | |
DTB1 DEC CCBBLN ;DEC LEN (LOW) | |
RTS ;DONE | |
; | |
DTB2 JMP GOODIO ;FINISHED BLOCK | |
PAGE | |
; | |
; FNDFIL – FIND FILE NAME IN VOLUME DIR | |
; | |
FNDFIL | |
JSR RDVTOC ;GO GET VTOC | |
LDA CCBFN1 ;MOVE FN PTR | |
STA ZPGFCB ;TO ZERO PAGE | |
LDA CCBFN1+1 | |
STA ZPGFCB+1 | |
LDA #1 | |
FF1 STA TEMP2 | |
LDA #0 | |
STA DCBVDR | |
CLC | |
FF2 | |
INC DCBVDR | |
JSR RDVDIR ;GO GET VDIR SECTOR | |
BCS FF4A | |
LDX #0 ;SET FOR 1ST FILE | |
; | |
FF3 STX TEMP1 ;SAVE INDEX | |
LDA VDFILE,X ;GET FILE TRK | |
BEQ FF6 ;BR IF LAST ENTRY | |
BMI FF7 ;BR DELETED ENTRY | |
LDY #0 ;X=X+3 | |
INX | |
INX | |
FF4 INX | |
LDA (ZPGFCB),Y ;GET FN CHAR | |
CMP VDFILE,X ;COMPARE TO ENTRY CHAR | |
BNE FF5 ;BR IF NOT SAME | |
INY | |
CPY #30 ; ALL 30 CHARS | |
BNE FF4 ;BR IF NOT | |
LDX TEMP1 ;GET INDEX | |
CLC ;FILE FOUND | |
RTS ;RETURN | |
; | |
FF5 | |
JSR VDINC | |
BCC FF3 | |
BCS FF2 | |
; | |
FF6 LDY TEMP2 ;LOOKING FOR DELETED | |
BNE FF1 ;BR IF NOT (DO) | |
; | |
FF7 LDY TEMP2 ;LOOKING FOR EMPTY | |
BNE FF5 ;BR IF NOT | |
; | |
MVFN | |
LDY #0 ;HAVE NEW ENTTRY | |
INX | |
INX | |
FF8 INX | |
LDA (ZPGFCB),Y ;MOVE FILE NAME | |
STA VDFILE,X | |
INY | |
CPY #30 | |
BNE FF8 | |
; | |
LDX TEMP1 ;GET INDEX | |
SEC ;SET NOT OLD | |
RTS ;DONE | |
VDINC | |
CLC | |
LDA TEMP1 | |
ADC #35 | |
TAX | |
CPX #VDFLEN | |
RTS | |
FF4A | |
LDA #0 | |
LDY TEMP2 | |
BNE FF1 | |
JMP ERROR9 | |
PAGE | |
; | |
; GETSEC – GET A SECTOR | |
; | |
GETSEC | |
LDA DCBATK ;GET ALLOCATED TRK | |
BEQ GSS1 ;BR IF NONE | |
; | |
GS0 | |
DEC DCBALS ;DECREMENT SECTOR NO | |
BMI CS2 ;BR IF NO SECTORS REM | |
; | |
CLC | |
LDX #4 ;4 BYTE SHIFT | |
GS1 ROL DCBABM-1,X ;SHIFT BYTE LEFT | |
DEX | |
BNE GS1 | |
BCC GS0 ;BR IF NO SECTOR | |
; | |
INC DCBNSA | |
BNE GS1A | |
INC DCBNSA+1 | |
GS1A | |
LDA DCBALS ;GET ALLOCATED SECTOR | |
RTS ;RETURN | |
; | |
CS2 LDA #0 ;CLEAR ALLOCATED | |
STA DCBATK ;TRK | |
; | |
GSS1 LDA #0 ;SET SEARCH STATE=0 | |
STA TEMP3 | |
JSR RDVTOC ;GET VTOC | |
; | |
GS2 | |
CLC | |
LDA VALCA1 ;GET LAST ALLOCATED TRK | |
ADC VALCA2 ;AD (+1) OR (-1) | |
BEQ GS3 ;BR IF DECK TO ZERO | |
CMP VNOTRK | |
BCC GS5 ;BR IF NOT AT OUTER LIMIT | |
LDA #$FF ;SET (-1) | |
BNE GS4 | |
GS3 LDA TEMP3 ;GET SEARCH STATE | |
BNE ERR9 ;BR IF NOT ZERO | |
LDA #1 ;SET (+1) | |
STA TEMP3 ;SET SEARCH STATE = 1 | |
GS4 STA VALCA2 ;SET NEW (+1) OR (-1) | |
CLC | |
ADC #17 ; ADD VTOC TRK NO | |
GS5 STA VALCA1 ;SET NEW LAST ALLOCATED | |
STA DCBATK ;PUT IN DCB | |
; | |
TAY ;ALLOCATED TRACK | |
ASLA ;TIME 4 | |
ASLA | |
TAY | |
LDX #4 | |
CLC | |
GS6 LDA VSECAL+3,Y ;MOVE BIT MAP BYTE | |
STA DCBABM-1,X | |
BEQ GS7 ;BR IF NO BITS ON | |
SEC ;SET HAVE A SECTOR | |
LDA #0 ;CLEAR VTOC BYTE | |
STA VSECAL+3,Y | |
GS7 DEY | |
DEX | |
BNE GS6 ;BR IF MORE TO MOVE | |
BCC GS2 | |
JSR WRVTOC ;GO WRITE VTOC | |
LDA VNOSEC ;GET NO SECTORS | |
STA DCBALS ;SET IN DCB SECTOR BYTE | |
BNE GS0 ;GO ALLOCATED SECTOR | |
ERR9 JMP ERROR9 | |
PAGE | |
; | |
; FRETRK – FREE TRACK OF SECTORS | |
; | |
FRETRK | |
LDA DCBATK ;GET ALLOCATED TRACK | |
BNE FT1 ;BR IF NONE | |
RTS ;DONE | |
FT1 PHA | |
JSR RDVTOC ;GET VTOC | |
LDY DCBALS ;GET SECTORS | |
PLA ;GET TRACK | |
CLC ;SET FREE | |
JSR FRESEC ;GO FREE | |
LDA #0 ;CLEAR ALLOCATED TRK | |
STA DCBATK | |
JMP WRVTOC ;WRITE VTOC | |
; | |
; FRESEC – FREE A SECTOR | |
; A=TRK, Y=SECTOR, C=ON/OFF | |
; | |
FRESEC | |
FS1 LDX #252 ;4 BYTE SHIFT | |
FS2 ROR DCBABM-252,X ;SHIFT IN CARRY | |
INX ;NEXT BYTE | |
BNE FS2 ;BR IF NOT DONE | |
INY ;INC SECTOR NO | |
CPY VNOSEC ;NORMAL | |
BNE FS1 ;BR IF NOT | |
; | |
ASLA ;TRACK*4 | |
ASLA | |
TAY | |
BEQ FS4 | |
LDX #4 | |
FS3 LDA DCBABM-1,X ;GET BIT MAP BYTE | |
ORA VSECAL+3,Y ;GET BIT MAP BYTE | |
STA VSECAL+3,Y ;OR WITH VTOC BM | |
DEY | |
DEX | |
BNE FS3 | |
FS4 RTS ;DONE | |
PAGE | |
; | |
; LOCSEC – LOCATE SECTOR FOR RECORD I/O | |
; | |
; RELSEC = (REL REC * RECLEN + RELBYTE)/256 | |
; SECBYT = REMAINDER | |
; | |
LOCSEC | |
LDA CCBRRN ;RELATIVE RECORD NUMBER | |
STA DCBCSB ;TO CSB FOR MULT | |
STA DCBCRR ;AND CRR FOR SAVE | |
LDA CCBRRN+1 | |
STA DCBCRS | |
STA DCBCRR+1 | |
LDA #0 | |
STA DCBCRS+1 ;HIGH CRS=0 | |
LDY #16 ;16 BIT MULT | |
; | |
LS1 TAX ;SAVE MS BYTE | |
LDA DCBCSB | |
LSRA ;IF NO CARRY THEN NO PART PROD | |
BCS LS1A | |
TXA | |
BCC LS2 | |
LS1A CLC | |
LDA DCBCRS+1 ;FPORM PARTIAL PROD | |
ADC DCBRCL | |
STA DCBCRS+1 | |
TXA | |
ADC DCBRCL+1 | |
; | |
LS2 RORA ;MULT BY 2 | |
ROR DCBCRS+1 | |
ROR DCBCRS | |
ROR DCBCSB | |
DEY ;DEC BIT COUNT | |
BNE LS1 ;BR IF MORE BITS | |
; | |
LDA CCBBYT ;ADD REL BYTE RESULT | |
STA DCBCRB ;(SAVE REL BYTE) | |
ADC DCBCSB | |
STA DCBCSB | |
LDA CCBBYT+1 | |
STA DCBCRB+1 ;(SAVE REL BYTE) | |
ADC DCBCRS | |
STA DCBCRS | |
LDA #0 | |
ADC DCBCRS+1 | |
STA DCBCRS+1 | |
RTS | |
PAGE | |
ERROR1 LDA #CREFUN | |
BNE ERRORA | |
ERROR2 LDA #CRERR | |
BNE ERRORA | |
ERROR3 LDA #CREMRE | |
BNE ERRORA | |
ERROR4 LDA #CREPRO | |
BNE ERRORA | |
ERROR5 LDA #CREEOF | |
BNE ERRORA | |
ERROR6 LDA #CREFNF | |
BNE ERRORA | |
ERROR9 LDA #CRENSA | |
BNE ERRORA | |
ERRR10 LDA #CREFLK | |
BNE ERRORA | |
GOODIO LDA CCBSTA | |
CLC ;CARRY=CLR | |
BCC RETURN ;GO RETURN | |
ERRORA | |
ERRORB SEC ;CARRY=SET | |
RETURN | |
PHP | |
STA CCBSTA ;SET STA | |
JSR RTNFCB ;GO RTN FCB | |
PLP ;GET STATUS | |
LDX ENTSTK ;GET ENT STACK | |
TXS ;RESTORE STACK | |
RTS ;DONE | |
EC2 | |
PAGE | |
; | |
; MISC DOS WORK CELLS | |
; | |
CVDTRK DB $11 ;CUR VOL DIR TRK | |
CVDSEC DB $0B ;CUR VOL DIR SECTOR | |
CURCCB DB 0,0 ;CURRENT CCB ADR | |
ENTSTK DB $F5 ;ENTRY STACK POINTER | |
TEMP1 DB 0 ;TEMP BYTE 1 | |
TEMP2 DB $0C ;TEMP BYTE 2 | |
TEMP3 DB 0 ;TEMP BYTE 3 | |
ENTSLT DB 0 ;BOOT SLOT SAVED | |
ALC10S DB 0,0,$F8,$FF ;ALLOCATATION TRACK BIT MAP | |
CVTAB DB 1,10,100 ; CONVERSION TABLE | |
FTTAB DB11 "TBAI" ; FILE TYPE CONVERSION TABLE | |
VOLMES DB11 " EMULOV KSID" | |
VML EQU *-VOLMES-1 | |
PAGE | |
; | |
; VTOC RECORD AREA | |
; | |
VTOC | |
VDOST DB 1 ; DOS TYPE | |
VDIRTK DB 17 ;COLUME DIRECTORY SECTOR | |
VDIRSC DB 12 ;VOLUME DIRECTORY SECTOR | |
VDOSRN DB 1 ; DOS RELEASE NUMBER | |
DB 1 ; SPARE | |
DB 1 ; SPARE | |
VVOLNO DB 16 ;VOLUME NUMBER | |
RMB 32 ; SPARE | |
VTDMS DB 122 ;MAX SECTORS IN A FILE DIR | |
VSPARE RMB 8 ;SPARES | |
; | |
VALCA1 DB 30 ;ALOCATION ALGORITHM BYTE 1 | |
VALCA2 DB 1 ;AA BYTE 2 | |
VALCA3 DB 0 ;AA BYTE 3 | |
VALCA4 DB 0 ;AA BYTE 4 | |
VNOTRK DB 35 ;NO TRACKS ON VOL | |
VNOSEC DB 13 ; NO SECTORS PER TRACK | |
VSECLN DW 256 ;NO BYTES PER SECTOR | |
; | |
VSECAL EQU * ;SECTOR ALLOCATION AREA | |
; SECTORS ALLOCATED BY BIT MAP | |
; 4 BYTES OF BITS PER TRACK | |
; LEFT MOST BIT REPRESENTS SECTOR N | |
; WHERE N=NO SECTORS PER TRACK | |
; | |
; | |
PAGE | |
ORG VTOC+256 | |
; | |
; VOLUME DIRECTORY AREA | |
; | |
VOLDIR | |
VDTCDE DB 0 ; VOLUME DIRECTORY TYPECODE | |
VDLTRK RMB 1 ;VD LINK TRACK | |
VDLSEC RMB 1 ;VD LINK SECTOR | |
VDNF RMB 1 ;VD NUMBER FILES THIS SECTOR | |
VDSPAR RMB 7 ;SPARES | |
; | |
VDFILE EQU * ;FILE ALLOCATION AREA (7 FILES) | |
; EACH FILE | |
; FILE DIR TRK | |
; FILE DIR SECTOR | |
; FILE USE CODE | |
; FILE NAME (30) | |
; FILE SECTOR COUNT (2) | |
ORG VOLDIR+256 | |
VDEND EQU * | |
VDLEN EQU *-VOLDIR | |
VDFLEN EQU *-VDFILE | |
; | |
PAGE | |
; | |
; COMMAND CONTROL BLOCK (CCB) | |
; | |
CCB | |
CCBREQ RMB 1 ;USER REQUEST BYTE | |
CRQNUL EQU 0 ;0-NO REQUEST | |
CRQOPN EQU 1 ;1-OPEN FILE | |
CRQCLS EQU 2 ;2-CLOSE FILE | |
CRQRD EQU 3 ;3-READ DATA | |
CRQWR EQU 4 ;WRITE DATA | |
CRQDEL EQU 5 ;5-DELETE FILE | |
CRQDIR EQU 6 ;6-READ DIRECTORY | |
CRQLCK EQU 7 ;7-LOCK FILE | |
CRQUNL EQU 8 ;8-UNLOCK FILE | |
CRQRNM EQU 9 ;9-RENAME | |
CRQPOS EQU 10 ;10-POSITION FILE | |
CRQFMT EQU 11 ;11-FORMAT | |
CRQVAR EQU 12 ; 12-VERIFY | |
CRQMAX EQU 13 | |
; | |
CCBBSA ; FORMAT – BOOT START ADR PAGE | |
CCBRQM RMB 1 ;REQUEST MODIFIER BYTE | |
CRMNUL EQU 0 ;NO MODIFIER | |
CRMNBT EQU 1 ;R/W – 1 – NEXT BYTE | |
CRMNBL EQU 2 ;R/W – 2 – NEXT BLOCK | |
CRMSBT EQU 3 ;R/W – 3 – SPECIFC BYTE | |
CRMSBL EQU 4 ;R/W – 4 – SPECIFIC BLOCK | |
CRMMAX EQU 5 | |
; | |
CCBRRN ;I/O – RELATIVE RECORD NUMBER | |
CCBFN2 ;RENAME – FILE NAME 2 PTR | |
CCBRLN RMB 2 ;OPEN – RECORD LENGTH | |
; | |
CCBBYT ;I/O – RELATIVE RECORD NO(2 BYTES) | |
CCBVOL RMB 1 ;OPEN – VOL NO. | |
CCBDRV RMB 1 ;OPEN – DRIVE | |
; | |
CCBBLN ;I/O – BLOCK LENGTH (2 BYTES) | |
CCBSLT RMB 1 ;OPEN – SLOT NO. | |
CCBFUC RMB 1 ;OPEN - FILE USE CODE | |
; | |
CCBFN1 ;OPEN, DELETE, LOCK, UNLOCK, RENAME – FILENAME P | |
CCBBBA ;BLCOKK I/O – BLOCK BUFFER PTR | |
CCBDAT RMB 2 ;BYTE I/O – DTA BYTE | |
; | |
CCBSTA RMB 1 ;RESULT STATUS | |
CREFUN EQU 1 ;FCB UNALLOCATED | |
CRERR EQU 2 ;CCB REQ RANGE ERR | |
CREMRE EQU 3 ;REQ MOD RANGE ERR | |
CREPRO EQU 4 ; WRITE PROTECT | |
CREEOF EQU 5 ;END OF FILE ON READ | |
CREFNF EQU 6 ;FILE NOT FOUND | |
CREVMM EQU 7 ;VOL MIS MATCH | |
CREIOE EQU 8 ;I/O ERR | |
CRENSA EQU 9 ;NO SECTORS AVAILABLE | |
CREFLK EQU 10 ;FILE LOCKED | |
; | |
CCBSM RMB 1 ;STATUS MODIFIER | |
CCBFCB RMB 2 ;FCB PTR | |
CCBDBP RMB 2 ;DIR BUF PTR | |
CCBSBP RMB 2 ;SECTOR BUF PTR | |
CCBSPR RMB 4 ;SPARE | |
CCBLEN EQU *-CCB ;CCB LENGTH | |
CFCBAD EQU CCBFCB | |
CFCBDR EQU CCBDBP | |
CFCBSB EQU CCBSBP | |
PAGE | |
; | |
; FILE CONTROL BLOCK (FCB) DEFINITION | |
; DCB – FILE DATA CONTROL BLOCK | |
; | |
FCBB | |
; | |
; DATA CONTROL BLOCK | |
; | |
FCBDCB | |
DCBFDT RMB 1 ;1ST FILE DIRECTORY TRACK | |
DCBFDS RMB 1 ;1ST FILE DIRECTORY SECTOR | |
DCBCDT RMB 1 ;CURRENT FILE DIRECTORY | |
DCBCDS RMB 1 ;CURRENT FILE DIRECTORY | |
DCBWRF RMB 1 ;WRITE REQD FLAG | |
; ;$80=WRITE FILE DIR | |
; ;$40=WRITE SECTOR DIR | |
DCBTRK RMB 1 ;SECTOR TRACK ADR | |
DCBSEC RMB 1 ;SECTOR ADR | |
DCBVDR RMB 1 ; VOL DIR REC | |
DCBVDI RMB 1 ; VOL DIR INDEX | |
DCBDMS RMB 2 ;MAX NO DIRECTORY SECTORS | |
DCBDFS RMB 2 ;CURRENT DIR 1ST REL SECTRO | |
DCBDNF RMB 2 ;REL SECTOR OF NXT DIR | |
DCBCMS RMB 2 ;SECTOR CURRENTLY IN MEMORY | |
DCBSDL RMB 2 ;SECTOR DATA LENGTH | |
DCBCRS RMB 2 ;CURRENT RELATIVE SECTOR | |
DCBCSB RMB 2 ;REL SECTOR OF NXT DIR | |
DCBRCL RMB 2 ;SECTOR CURRENTLY IN MEMORY | |
DCBCRR RMB 2 ;SECTOR DATA LENGTH | |
DCBCRB RMB 2 ;CURRENT RELATIVE SECTOR | |
DCBNSA RMB 2 ; NO SECTORS ALLOCATED | |
; | |
DCBALS RMB 1 ;ALLOCATION SECTOR BYTE | |
DCBATK RMB 1 ;ALLOCATION TRACK | |
DCBABM RMB 4 ;ALLOCATION TRACK SECTOR BIT MAP | |
; | |
DCBFUC RMB 1 ;FILE USE CODE | |
DCBSLT RMB 1 ;SLOT NUMBER | |
DCBDRV RMB 1 ;DRIVE NUMBER | |
DCBVOL RMB 1 ;VOLUME DRIVER | |
DCBVTN RMB 1 ;VTOC TRACK NUMBER | |
; | |
DCBSPR RMB 3 ;SPARES | |
; | |
DCBLEN EQU *-FCBDCB ;DCB LENGTH | |
FCBLEN EQU *-FCBB ;FCB LENGTH | |
PAGE | |
; | |
; DOS PATCH AREA 1 | |
SDP1 | |
EDP1 EQU ORG2-2 | |
DB 0,0,0,0,0,0,0 | |
DB 0,0,0,0,0,0,0 | |
DR2PAT ;*** PATCH *** (DOSREL - FIND END OF DOS) | |
LDA ZPGWRK+1 ;GET TOP OF RAM PAGE FOUND | |
AND #$DF ;SAVE 8K LESS THAN TOP OF RAM IF 16K, 32K, OR 48K SYS | |
STA ZPGFCB+1 ;LEAVE AS IS IF 20K, 24K, OR 36K SYSTEM | |
STX ZPGFCB ;ZERO LO | |
LDA (ZPGFCB,X) ;GET BYTE FROM (POSSIBLY NEW) TOP OF RAM | |
PHA ;SAVE IT TO STACK | |
STA LOC1 ;TEST FOR RAM AGAIN | |
DR2P1 | |
TYA ;FIRST PASS=0 | |
EOR LOC1 | |
STA LOC1 | |
TYA | |
EOR (ZPGWRK,X) | |
STA (ZPGFCB,X) | |
CMP LOC1 | |
BNE DR2P3 ;BR IF NOT RAM | |
INY ;NEXT VERIFY PASS | |
BNE DR2P1 | |
LDY ZPGFCB+1 ;GET TOP OF RAM PAGE IF TOOK | |
PLA ;RESTORE LAST BYTE READ FROM RAM | |
RTS ;RTN WITH (POSSIBLY NEW) TOP OF RAM PAGE | |
; | |
DR2P3 | |
PLA ;RESTORE LAST BYTE READ FROM RAM | |
STA (ZPGFCB,X) ;PUT IT BACK IN RAM | |
LDY ZPGWRK+1 ;GET ORIG TOP OF RAM PAGE | |
RTS ;AND RETURN | |
; | |
; DOSLDR – DOS LOADER AND WRITTER | |
; | |
ORG ORG2 | |
DOSLDR | |
; GARBAGED BOOT REC 0 HERE | |
RMB 254 | |
GRSPG DB $36 | |
GRPGC DB $48 | |
PAGE | |
SC3 | |
; | |
; READ DOS AFTER BOOT | |
;; | |
STX IBSLOT ;SET BOOT SLOT | |
STX IBPSLT ; SET PREVIOUS SLOT | |
LDA #1 ;SET PREV DRIVE | |
STA IBPDRV | |
STA IBDRVN | |
; | |
LDA NDPGS ;COPY NO PAGES TO GET | |
STA BRWCNT | |
LDA #0 | |
STA IBTRK ; SET TRACK 0 | |
; | |
LDA BSDSEC ;COPY START DOS SECTOR | |
STA IBSECT | |
; | |
LDA BGNDOS ;COPY STARTR DOS ADR | |
STA IBBUFP+1 | |
; | |
LDA #IBCRTS ;SET READ | |
STA IBCMD | |
; | |
TXA ;SET PREV TRACK = 0 | |
LSRA | |
LSRA | |
LSRA | |
LSRA | |
TAX | |
LDA #0 | |
STA $4F8,X | |
STA $478,X | |
JSR BOOTIO ; GO READ DOS | |
; | |
; DOSINT – INITIALIZE DOS | |
; | |
DOSINT | |
LDX #$FF | |
TXS | |
STX IBVOL | |
JSR SETVID | |
JSR SETKBD | |
; | |
DI3 JMP DOSREL ; GO TO POST INIT ROUTINE | |
PAGE | |
WBOOT | |
LDA IBBUFP+1 ;GET START OF DOS | |
STA BGNDOS ;SAVE IR | |
SEC | |
LDA ADOSLD+1 ;CALCULATE | |
SBC BGNDOS | |
STA NDPGS ;NO DOS PAGES | |
; | |
LDA #0 | |
STA IBTRK ;TRACK=0 | |
STA IBSECT ;SECTOR=0 | |
STA IBBUFP | |
; | |
LDA ADOSLD+1 ;GET BOOT START ADR | |
STA IBBUFP+1 ;TO BUFP | |
STA GRSPG ;TO GARBAGE RECORD | |
; | |
LDA #10 ;NO OF BOOT PAGES | |
STA BRWCNT ;TO BOOT I/O COUNTER | |
STA BSDSEC | |
LDA #$48 | |
STA GRPGC | |
; | |
LDA #IBCWTS ;SET WRITE | |
STA IBCMD | |
; | |
JSR BOOTIO ; GO WRITE BOOT SECTORS | |
; | |
LDA BGNDOS ;SET START OF DOS | |
STA IBBUFP+1 | |
; | |
LDA NDPGS | |
STA BRWCNT | |
JSR BOOTIO ;GO WRITE DOS | |
; | |
RTS ;DONE | |
PAGE | |
BOOTIO | |
LDA BAIOB+1 | |
LDY BAIOB | |
JSR DISKIO | |
LDY IBSECT ;GET SECTOR | |
INY ;INCREMENT TO NEXT | |
CPY #13 ;AT END OF TRACK | |
BNE BIO1 ;BR IF NOT SECTOR ZERO | |
LDY #0 ;SET TO SECTOR ZERO | |
INC IBTRK | |
BIO1 STY IBSECT ;SET NEXT SECTOR | |
; | |
INC IBBUFP+1 ; INCREMENT BUFFER POINTER | |
DEC BRWCNT ;DECREMENT PAGE COUNTER | |
BNE BOOTIO ;BR IF NOT DONE | |
RTS | |
; | |
PAGE | |
; | |
; DOS PATCH AREA 1 | |
; | |
DP1 EQU * ;*** PATCH *** (EVAR) | |
LDA #CRQVAR ;VERIFY COMMAND | |
JSR OPEN ;TRY VERIFY | |
LDA #CREFNF ;FILE NOT FOUND ERROR CODE | |
CMP CCBSTA ;TEST FILE NOT FOUND | |
BNE DP11 ;BR IF FOUND | |
JMP KLUTZ ;ELSE GO FIX THINGS | |
DP11 | |
JMP ECLOSE ; FILE FOUND, CLOSE AND RTN | |
; | |
BOUND 256 | |
ORG *-$20 | |
EC3 | |
NDPGS DB 0 | |
BRWCNT DB 0 | |
BSDSEC DB 0 | |
BGNDOS DB 0 | |
BAIOB DW @@IOB | |
ADOSLD DW @@DOSLDR | |
PAGE | |
; | |
; IOB – INPUT / OUTPUT CONTROL BLOCK | |
; THE IOB IS USED FOR THE INTERFACE | |
; BETWEEN DOS AND THE DISK I/O ROUTINES | |
; | |
IOB | |
IBTYPE DB 1 ;IOB TYPE CODE | |
IBSLOT DB $60 ;CONTROLLER SLOT NO. | |
IBDRVN DB 1 ;DRIVE NUMBER | |
IBVOL DB $FF ;VOLUME NUMBER | |
IBTRK DB $11 ;TRACK NUMBER | |
IBSECT DB $0B ;SECTOR NUMBER | |
IBDCTP DW @@DCT | |
IBBUFP DW @@$33EF ;POINTER TO BUFFER | |
IBDLEN DW @@0 ;DATA LENGTH | |
IBCMD DB 1 ;COMMAND | |
IBCNUL EQU 0 ;0-NULL COMMAND | |
IBCRTS EQU 1 ;1-READ TRACK, SECTOR | |
IBCWTS EQU 2 ;2-WRITE TRACK, SECTOR | |
IBFMT EQU 4 ;4-FORMAT DISK | |
IBBOOT EQU 8 ;8-WRITE BOOT | |
IBSTAT DB 0 ;STATUS | |
IBRERR EQU $80 ;READ ERR | |
IBDERR EQU $40 ;DRIVE ERR | |
IBVMME EQU $20 ;VOLUME MISMATCH | |
IBWPER EQU $10 ;WRITE PROTECT ERROR | |
IBSMOD DB $10 ;STATUS MODIFIER BYTE | |
IBPSLT DB $60 ;PREVIOUS SLOT | |
IBPDRV DB 1 ;PREVIOUS DRIVE | |
IBSPAR RMB 2 ;IOB SPARES | |
DCT DB 0,1,$EF,$D8 | |
DB 0 | |
PAGE | |
; | |
; FILE DIRECTORY DEFINITION | |
; | |
; ORG 0 | |
;FILDIR | |
;FDUCDE RMB 1 ;FILE USE CODE | |
;FDLTRK RMB 1 ;LINK TO NXT DIR TRACK | |
;FDLSEC RMB 1 ;LINK TO NEXT DIR SECTOR | |
;FDNSA RMB 1 ;NO SECTOR ALLOCATED | |
;FDLSDL RMB 1 ;LAST SECTOR DATA LENGTH | |
;FDFRS RMB 2 ;1ST RELATIVE SECTOR IN THIS DIR | |
;FDSPAR RMB 5 ;SPARES | |
;; | |
;FDENT RMB 1 ;START OF FILE ENTRIES (122) | |
;FDTRK EQU 0 ;TRACK | |
;FDSEC EQU 1 ;SECTOR | |
;; | |
;FDLAST EQU FILDIR+256 | |
; | |
ZPORG EQU 0 | |
FILDIR EQU ZPORG | |
FDUCDE EQU ZPORG ;FILE USE CODE | |
FDLTRK EQU ZPORG+1 ;LINK TO NXT DIR TRACK | |
FDLSEC EQU ZPORG+2 ;LINK TO NEXT DIR SECTOR | |
FDNSA EQU ZPORG+3 ;NO SECTOR ALLOCATED | |
FDLSDL EQU ZPORG+4 ;LAST SECTOR DATA LENGTH | |
FDFRS EQU ZPORG+5 ;1ST RELATIVE SECTOR IN THIS DIR | |
FDSPAR EQU ZPORG+7 ;SPARES | |
; | |
FDENT EQU ZPORG+12 ;START OF FILE ENTRIES (122) | |
FDTRK EQU 0 ;TRACK | |
FDSEC EQU 1 ;SECTOR | |
; | |
FDLAST EQU FILDIR+256 | |
PAGE | |
; | |
*************************** | |
* DISC-II * | |
* 13-SECTOR FORMAT * | |
* READ AND WRITE * | |
* SUBROUTINES * | |
* * | |
*************************** | |
* * | |
* * | |
* COPYRIGHT 1978 * | |
* APPLE COMPUTER INC. * | |
* * | |
* ALL RIGHTS RESERVED * | |
* * | |
*************************** | |
* * | |
* MAY 25, 1978 * | |
* WOZ * | |
* R. WIGGINTON * | |
* * | |
*************************** | |
EJECT | |
*************************** | |
* * | |
* CRITICAL TIMING * | |
* REQUIRES PAGE BOUND * | |
* CONSIDERATIONS FOR * | |
* CODE AND DATA * | |
* * | |
* -----CODE----- * | |
* * | |
* VIRTUALLY THE ENTIRE * | |
* 'WRITE' ROUTINE * | |
* MUST NOT CROSS * | |
* PAGE BOUNDARIES. * | |
* * | |
* CRITICAL BRANCHES IN * | |
* THE 'WRITE', 'READ', * | |
* AND 'READ ADR' SUBRS * | |
* WHICH MUST NOT CROSS * | |
* PAGE BOUNDARIES ARE * | |
* NOTED IN COMMENTS. * | |
* * | |
* -----DATA----- * | |
* * | |
* NBUF1, NBUF2, NBUF3, * | |
* NBUF4, AND NBUF5 ARE * | |
* 51-BYTE RAM BUFFERS * | |
* WHICH SHOULD ALL BE * | |
* LOCATED ON A SINGLE * | |
* PAGE BEGINNING WITH * | |
* NBUF1. (NBUF5 IS 52). * | |
* * | |
* NBUF6, NBUF7, AND * | |
* NBUF8 MUST NOT CROSS * | |
* PAGE BOUNDARIES AND * | |
* SHOULD BE LOCATED * | |
* ON A PAGE BEGINNING * | |
* WITH NBUF6. NBUF6 * | |
* AND NBUF7 ARE 51 BYTES * | |
* WHILE NBUF8 IS 52. * | |
* * | |
* NIBLIZING TABLE 'NIBL' * | |
* (32 BYTES) MUST NOT * | |
* CROSS PAGE BOUNDARY. * | |
* CONVERTS 5-BIT NIBLS * | |
* TO 7-BIT NIBLS. * | |
* * | |
* DENIBLIZING TABLE * | |
* 'DNIBL' MUST BE ON A * | |
* PAGE BOUNDARY, BUT * | |
* ONLY DNIBL,$AB TO * | |
* DNIBL,$FF NEED BE * | |
* USED. CONVERTS 7-BIT * | |
* NIBLS TO 5-BIT NIBLS. * | |
* * | |
*************************** | |
EJECT | |
*************************** | |
* * | |
* EQUATES * | |
* * | |
*************************** | |
* * | |
* -----PRENIBL---- * | |
* AND POSTNIBL * | |
* * | |
*************************** | |
BUF EQU $3E ;TWO BYTE POINTER. | |
* | |
* POINTS TO 256-BYTE | |
* USER BUFFER ANYWHERE | |
* IN MEMORY. PRENIBL | |
* CONVERTS USER DATA | |
* (IN BUF) INTO 5-BIT | |
* NIBLS 000ABCDE IN | |
* NBUF1 THROUGH NBUF8 | |
* PRIOR TO 'WRITE'. | |
* POSTNIBL CONVERTS | |
* 5-BIT NIBLS ABCDE000 | |
* BACK TO USER DATA | |
* (IN BUF) AFTER 'READ'. | |
* | |
NBUF1 EQU $3B00 | |
NBUF2 EQU $3B33 ;OBSERVE THESE | |
NBUF3 EQU $3B66 ;PLACEMENTS | |
NBUF4 EQU $3B99 ;RELATIVE TO | |
NBUF5 EQU $3BCC ;PAGE STARTS! | |
NBUF6 EQU $3C00 | |
NBUF7 EQU $3C33 | |
NBUF8 EQU $3C66 ;(TO $BC99) | |
* | |
T0 EQU $26 ;TEMPS USED BY PRENIBL | |
T1 EQU $27 ; AND POSTNIBL. | |
T2 EQU $2A ;TEMP USED BY PRENIBL. | |
* | |
************************ | |
* * | |
* ----READADR---- * | |
* * | |
************************ | |
COUNT EQU $26 ;'MUST FIND' COUNT. | |
LAST EQU $26 ;'ODD BIT' NIBLS. | |
CSUM EQU $27 ;CHECKSUM BYTE. | |
CSSTV EQU $2C ;FOUR BYTES, | |
* CHECKSUM, SECTOR, TRACK, AND VOLUME. | |
* | |
************************ | |
* * | |
* ----WRITE---- * | |
* * | |
* USES ALL NBUFS * | |
* AND 32-BYTE * | |
* DATA TABLE 'NIBL' * | |
* * | |
************************ | |
WTEMP EQU $26 ;TEMP FOR DATA AT NBUF6,0. | |
SLOTZ EQU $27 ;SLOTNUM IN Z-PAG LOC. | |
SLOTABS EQU $678 ;SLOTNUM IN NON-ZPAG LOC. | |
* | |
************************ | |
* * | |
* -----READ---- * | |
* * | |
* USES ALL NBUFS * | |
* USES LAST 54 BYTES * | |
* OF A CODE PAGE FOR * | |
* USED BYTES OF DNIBL * | |
* TABLE. * | |
* * | |
************************ | |
IDX EQU $26 ;INDEX INTO (BUF). | |
DNIBL EQU $3A00 ;7-BIT TO 5-BIT NIBLS. | |
* | |
************************ | |
* * | |
* ---- SEEK ---- * | |
* * | |
************************ | |
TRKCNT EQU $26 ;HALFTRKS MOVED COUNT. | |
PRIOR EQU $27 ;PRIOR HALFTRACK. | |
TRKN EQU $2A ;DESIRED TRACK. | |
SLOTTEMP EQU $2B ;SLOT NUM TIMES $10. | |
CURTRK EQU $478 ;CURRENT TRACK ON ENTYR. | |
* | |
************************ | |
* * | |
* ---- MSWAIT ---- * | |
* * | |
************************ | |
MONTIMEL EQU $46 | |
MONTIMEH EQU $47 | |
* | |
************************ | |
* * | |
* DEVICE ADDRESS * | |
* ASSIGNMENTS * | |
* * | |
************************ | |
PHASEOFF EQU $C080 ;STEPPER PHASE OFF. | |
PHASEON EQU $C081 ;STEPPER PHASE ON. | |
Q6L EQU $C08C ;Q7L,Q6L=READ | |
Q6H EQU $C08D ;Q7L,Q6H=SENSE WPROT | |
Q7L EQU $C08E ;Q7H,Q6L=WRITE | |
Q7H EQU $C08F ;Q7H,Q6H=WRITE STORE | |
EJECT | |
**************************** | |
* * | |
* PRENIBLIZE SUBR * | |
* * | |
**************************** | |
* * | |
* CONVERTS 256 BYTES OF * | |
* USER DATA IN (BUF),0 * | |
* TO (BUF),255 INTO 410 * | |
* 5-BIT NIBLS (000ABCDE) * | |
* IN NBUF1 THROUGH NBUF8. * | |
* * | |
* ---- ON ENTRY ---- * | |
* * | |
* BUF IS 2-BYTE POINTER * | |
* TO 256 BYTES OF USER * | |
* DATA. * | |
* * | |
* ---- ON EXIT ----- * | |
* * | |
* A-REG: UNCERTAIN. * | |
* X-REG: UNCERTAIN. * | |
* Y-REG: HOLDS $FF. * | |
* CARRY: UNCERTAIN. * | |
* * | |
* NBUF1 THROUGH NBUF8 * | |
* CONTAIN 5-BIT NIBLS * | |
* OF FORM 000ABCDE. * | |
* * | |
* TEMPS T0, T1, T2 USED. * | |
* * | |
**************************** | |
ORG $3800 | |
* OBJ $B800 | |
PRENIBL LDX #$32 ;INDEX FOR (51) 5-BYTE PASSES. | |
LDY #$0 ;USER BUF INDEX. | |
PNIB1 LDA (BUF),Y ;FIRST OF 5 USER BYTES. | |
STA T0 ;(ONLY 3 LSB'S USED) | |
LSRA | |
LSRA ;5 MSB'S TO LOW BITS. | |
LSRA | |
STA NBUF1,X ;FIRST OF 8 5-BIT NIBLS. | |
INY | |
LDA (BUF),Y ;SECOND OF 5 USER BYTES. | |
STA T1 ;ONLY 3 LSB'S USED) | |
LSRA | |
LSRA ;5 MSB'S TO LOW BITS. | |
LSRA | |
STA NBUF2,X ;SECOND OF 8 5-BIT NIBLS. | |
INY | |
LDA (BUF),Y ;THIRD OF 5 USER BYTES. | |
STA T2 ;(ONLY 3 LSB'S USED) | |
LSRA | |
LSRA ;5 MSB'S TO LOW BITS. | |
LSRA | |
STA NBUF3,X ;THIRD OF 8 5-BIT NIBLS. | |
INY | |
LDA (BUF),Y ;FOURTH OF 5 USER BYTES. | |
LSRA | |
ROL T2 ;LSB INTO T2. | |
LSRA | |
ROL T1 ;NEXT LSB INTO T1. | |
LSRA | |
ROL T0 ;NEXT LSB INTO T0. | |
STA NBUF4,X ;FOURTH OF 8 5-BIT NIBLS. | |
INY | |
LDA (BUF),Y ;FIFTH OF 5 USER BYTES. | |
LSRA | |
ROL T2 ;LSB INTO T2. | |
LSRA | |
ROL T1 ;NEXT LSB INTO T1. | |
LSRA | |
STA NBUF5,X ;FIFTH OF 8 5-BIT NIBLS. | |
LDA T0 | |
ROLA ;NEXT LSB. | |
AND #$1F ;TRUNCATE TO 5 BITS. | |
STA NBUF6,X ;SIXTH OF 8 5-BIT NIBLS. | |
LDA T1 | |
AND #$1F ;TRUNCATE TO 5 BITS. | |
STA NBUF7,X ;SEVENTH OF 8 5-BIT NIBLS. | |
LDA T2 | |
AND #$1F ;TRUNCATE TO 5 BITS. | |
STA NBUF8,X ;EIGHTH OF 8 5-BIT NIBLS. | |
INY | |
DEX ;NEXT OF (51) 5-BYTE PASSES. | |
BPL PNIB1 | |
LDA (BUF),Y | |
TAX | |
AND #$7 ;3 LSB'S OF LAST | |
STA NBUF8+$33 ; USER BYTE. | |
TXA | |
LSRA | |
LSRA | |
LSRA ;5 MSB'S OF LAST | |
STA NBUF5+$33 ; USER BYTE. | |
RTS | |
EJECT | |
************************ | |
* * | |
* WRITE SUBR * | |
* * | |
************************ | |
* * | |
* WRITES DATA FROM * | |
* NBUF1 TO NBUF8 * | |
* CONVERTING 5-BIT * | |
* TO 7-BIT NIBLS * | |
* VIA 'NIBL' TABLE. : | |
* * | |
* FIRST, NBUF6 TO * | |
* NBUF8, HIGH TO LOW * | |
* THEN, NBUF1 TO * | |
* NBUF5, LOW TO HIGH * | |
* * | |
* ---- ON ENTRY ---- * | |
* * | |
* X-REG: SLOTNUM * | |
* TIMES $10. * | |
* * | |
* NBUF1 TO NBUF8 * | |
* HOLD NIBLS FROM * | |
* PRENIBL SUBR. * | |
* (000ABCDE) * | |
* * | |
* ---- ON EXIT ----- * | |
* * | |
* CARRY SET IF ERROR. * | |
* (W PROT VIOLATION) * | |
* * | |
* IF NO ERROR: * | |
* * | |
* A-REG: UNCERTAIN. * | |
* X-REG: UNCHANGED. * | |
* Y-REG: HOLDS $00. * | |
* CARRY CLEAR. * | |
* * | |
* SLOTABS, SLOTZ, * | |
* AND WTEMP USED. * | |
* * | |
* ---- ASSUMES ---- * | |
* * | |
* 1 USEC CYCLE TIME * | |
* * | |
************************ | |
WRITE SEC ;ANTICIPATE WPROT ERR. | |
LDA Q6H,X | |
LDA Q7L,X ;SENSE WPROT FLAG. | |
BMI WEXIT ; IF HIGH, THEN ERR. | |
STX SLOTZ ;FOR ZERO PAGE ACCESS. | |
STX SLOTABS ;FOR NON-ZERO PAGE. | |
LDA NBUF6 | |
STA WTEMP ;FOR ZERO-PAGE ACCESS. | |
LDA #$FF ;SYNC DATA. | |
STA Q7H,X ;(5) WRITE 1ST NIBL. | |
ORA Q6L,X ;(4) | |
PHA ;(3) | |
PLA ;(4) CRITICAL TIMING! | |
NOP ;(2) | |
LDY #$A ;(2) FOR 11 NIBLS. | |
WSYNC ORA WTEMP ;(3) FOR TIMING. | |
JSR WNIBL7 ;(13,9,6) WRITE SYNC. | |
DEY ;(2) | |
BNE WSYNC ;(2*) MUST NOT CROSS PAGE! | |
LDA #$D5 ;(2) 1ST DATA MARK. | |
JSR WNIBL9 ;(15,9,6) | |
LDA #$AA ;(2) 2ND DATA MARK. | |
JSR WNIBL9 ;(15,9,6) | |
LDA #$AD ;(2) 3RD DATA MARK. | |
JSR WNIBL9 ;(15,9,6) | |
TYA ;(2) CLEAR CHKSUM. | |
LDY #$9A ;(2) NBUF6-8 INDEX. | |
BNE WDATA1 ;(3) ALWAYS. NO PAGE CROSS!! | |
WDATA0 LDA NBUF6,Y ;(4) PRIOR 5-BIT NIBL. | |
WDATA1 EOR NBUF6-1,Y ;(5) XOR WITH CURRENT. | |
* (NBUF6 MUST BE ON PAGE BOUNDARY FOR TIMING!!) | |
TAX ;(2) INDEX TO 7-BIT NIBL. | |
LDA NIBL,X ;(4) MUST NOT CROSS PAGE! | |
LDX SLOTZ ;(3) CRITICAL TIMING! | |
STA Q6H,X ;(5) WRITE NIBL. | |
LDA Q6L,X ;(4) | |
DEY ;(2) NEXT NIBL. | |
BNE WDATA0 ;(2*) MUST NOT CROSS PAGE! | |
LDA WTEMP ;(3) PRIOR NIBL FROM BUF6. | |
NOP ;(2) CRITICAL TIMING. | |
WDATA2 EOR NBUF1,Y ;(4) XOR NBUF1 NIBL. | |
TAX ;(2) INDEX TO 7-BIT NIBL. | |
LDA NIBL,X ;(4) | |
LDX SLOTABS ;(4) TIMING CRITICAL. | |
STA Q6H,X ;(5) WRITE NIBL. | |
LDA Q6L,X ;(4) | |
LDA NBUF1,Y ;(4) PRIOR 5-BIT NIBL. | |
INY ;(2) NEXT NBUF1 NIBL. | |
BNE WDATA2 ;(2*) MUST NOT CROSS PAGE! | |
TAX ;(2) LAST NIBL AS CHKSUM. | |
LDA NIBL,X ;(4) INDEX TO 7-BIT NIBL. | |
LDX SLOTZ ;(3) | |
JSR WNIBL ;(6,9,6) WRITE CHKSUM. | |
LDA #$DE ;(2) DM4, BIT SLIP MARK. | |
JSR WNIBL9 ;(15,9,6) WRITE IT. | |
LDA #$AA ;(2) DM5, BIT SLIP MARK. | |
JSR WNIBL9 ;(15,9,6) WRITE IT. | |
LDA #$EB ;(2) DM6, BIT SLIP MARK. | |
JSR WNIBL9 ;(15,9,6) WRITE IT. | |
LDA Q7L,X ; OUT OF WRITE MODE. | |
WEXIT LDA Q6L,X ; TO READ MODE. | |
RTS ; RETURN FROM WRITE. | |
***************************** | |
* * | |
* 7-BIT NIBL WRITE SUBRS * | |
* * | |
* A-REG OR'D PRIOR EXIT * | |
* CARRY CLEARED * | |
* * | |
***************************** | |
WNIBL9 CLC ;(2) 9 CYCLES, THEN WRITE. | |
WNIBL7 PHA ;(3) 7 CYCLES, THEN WRITE. | |
PLA ;(4) | |
WNIBL STA Q6H,X ;(5) NIBL WRITE SUB. | |
ORA Q6L,X ;(4) CLOBBERS ACC, NOT CARRY. | |
RTS | |
EJECT | |
************************** | |
* * | |
* READ SUBROUTINE * | |
* * | |
************************** | |
* * | |
* READS 5-BIT NIBLS * | |
* (ABCDE000) INTO * | |
* NBUF1 THROUGH NBUF8 * | |
* CONVERTING 7-BIT * | |
* NIBLS TO 5-BIT * | |
* VIA 'DNIBL' TABLE * | |
* * | |
* FIRST READS NBUF6 TO * | |
* NBUF8 HIGH TO LOW, * | |
* THEN READS NBUF1 TO * | |
* NBUF5 LOW TO HIGH * | |
* * | |
* ---- ON ENTRY ---- * | |
* * | |
* X-REG: SLOTNUM * | |
* TIMES $10. * | |
* * | |
* READ MODE (Q6L, Q7L) * | |
* * | |
* ---- ON EXIT ----- * | |
* * | |
* CARRY SET IF ERROR. * | |
* * | |
* IF NO ERROR: * | |
* A-REG: HOLDS $AA * | |
* X-REG: UNCHANGED. * | |
* Y-REG: HOLDS $00 * | |
* CARRY CLEAR. * | |
* * | |
* NBUF1 TO NBUF8 * | |
* HOLD 5-BIT * | |
* NIBLS ABCDE000. * | |
* * | |
* USES TEMP 'IDX'. * | |
* * | |
* ---- CAUTION ----- * | |
* * | |
* OBSERVE * | |
* 'NO PAGE CROSS' * | |
* WARNINGS ON * | |
* SOME BRANCHES!! * | |
* * | |
* ---- ASSUMES ---- * | |
* * | |
* 1 USEC CYCLE TIME * | |
* * | |
************************** | |
READ LDY #$20 ;'MUST FIND' COUNT. | |
RSYNC DEY ;IF CAN'T FIND MARKS | |
BEQ RDERR ;THEN EXIT WITH CARRY SET. | |
RDD1 LDA Q6L,X ;READ NIBL. | |
BPL RDD1 ;*** NO PAGE CROSS! *** | |
RSYNC1 EOR #$D5 ;DATA MARK 1? | |
BNE RSYNC ; LOOP IF NOT. | |
NOP ;DELAY BETWEEN NIBLS. | |
RDD2 LDA Q6L,X | |
BPL RDD2 ;*** NO PAGE CROSS! *** | |
CMP #$AA ;DATA MARK 2? | |
BNE RSYNC1 ; (IF NOT, IS IT DM1?) | |
LDY #$9A ;INIT NBUF6 INDEX. | |
* (ADDED NIBL DELAY) | |
RDD3 LDA Q6L,X | |
BPL RDD3 ;*** NO PAGE CROSS! *** | |
CMP #$AD ;DATA MARK 3? | |
BNE RSYNC1 ; (IF NOT, IS IT DM1?) | |
* (CARRY SET IF DM3!) | |
LDA #$00 ;INIT CHECKSUM. | |
RDATA1 DEY | |
STY IDX | |
RDD4 LDY Q6L,X | |
BPL RDD4 ;*** NO PAGE CROSS! *** | |
EOR DNIBL,Y ;XOR 5-BIT NIBL. | |
LDY IDX | |
STA NBUF6,Y ;STORE IN NBUF6 PAGE. | |
BNE RDATA1 ;TAKEN IF Y-REG NONZERO. | |
RDATA2 STY IDX | |
RDD5 LDY Q6L,X | |
BPL RDD5 ;*** NO PAGE CROSS! *** | |
EOR DNIBL,Y ;XOR 5-BIT NIBL. | |
LDY IDX | |
STA NBUF1,Y ;STORE IN NBUF1 PAGE. | |
INY | |
BNE RDATA2 | |
RDD6 LDY Q6L,X ;READ 7-BIT CSUM NIBL. | |
BPL RDD6 ;*** NO PAGE CROSS! *** | |
CMP DNIBL,Y ;IF LAST NBUF1 NIBL NOT | |
BNE RDERR ;EQUAL CHKSUM NIBL THEN ERR. | |
RDD7 LDA Q6L,X | |
BPL RDD7 ;*** NO PAGE CROSS! *** | |
CMP #$DE ;FIRST BIT SLIP MARK? | |
BNE RDERR ; (ERR IF NOT) | |
NOP ;DELAY BETWEEN NIBLS. | |
RDD8 LDA Q6L,X | |
BPL RDD8 ;*** NO PAGE CROSS! *** | |
CMP #$AA ;SECOND BIT SLIP MARK? | |
BEQ RDEXIT ; (DONE IF IT IS) | |
RDERR SEC ;INDICATE 'ERROR EXIT'. | |
RTS ;RETURN FROM READ OR READADR. | |
EJECT | |
**************************** | |
* * | |
* READ ADDRESS FIELD * | |
* * | |
* SUBROUTINE * | |
* * | |
**************************** | |
* * | |
* READS VOLUME, TRACK * | |
* AND SECTOR * | |
* * | |
* ---- ON ENTRY ---- * | |
* * | |
* XREG: SLOTNUM TIMES $10 * | |
* * | |
* READ MODE (Q6L, Q7L) * | |
* * | |
* ---- ON EXIT ----- * | |
* * | |
* CARRY SET IF ERROR. * | |
* * | |
* IF NO ERROR: * | |
* A-REG: HOLDS $AA. * | |
* Y-REG: HOLDS $00. * | |
* X-REG: UNCHANGED. * | |
* CARRY CLEAR. * | |
* * | |
* CSSTV HOLDS CHKSUM, * | |
* SECTOR, TRACK, AND * | |
* VOLUME READ. * | |
* * | |
* USES TEMPS COUNT, * | |
* LAST, CSUM, AND * | |
* 4 BYTES AT CSSTV. * | |
* * | |
* ---- EXPECTS ---- * | |
* * | |
* NORMAL DENSITY NIBLS * | |
* (4-BIT), ODD BITS, * | |
* THEN EVEN. * | |
* * | |
* ---- CAUTION ---- * | |
* * | |
* OBSERVE * | |
* 'NO PAGE CROSS' * | |
* WARNINGS ON * | |
* SOME BRANCHES!! * | |
* * | |
* ---- ASSUMES ---- * | |
* * | |
* 1 USEC CYCLE TIME * | |
* * | |
**************************** | |
RDADR LDY #$F8 | |
STY COUNT ;'MUST FIND' COUNT. | |
RDASYN INY | |
BNE RDA1 ;LOW ORDER OF COUNT. | |
INC COUNT ;(2K NIBLS TO FIND | |
BEQ RDERR ; ADR MARK, ELSE ERR) | |
RDA1 LDA Q6L,X ;READ NIBL. | |
BPL RDA1 ;*** NO PAGE CROSS! *** | |
RDASN1 CMP #$D5 ;ADR MARK 1? | |
BNE RDASYN ; (LOOP IF NOT) | |
NOP ;ADDED NIBL DELAY. | |
RDA2 LDA Q6L,X | |
BPL RDA2 ;*** NO PAGE CROSS! *** | |
CMP #$AA ;ADR MARK 2? | |
BNE RDASN1 ; (IF NOT, IS IT AM1?) | |
LDY #$3 ;INDEX FOR 4-BYTE READ. | |
* (ADDED NIBL DELAY) | |
RDA3 LDA Q6L,X | |
BPL RDA3 ;*** NO PAGE CROSS! *** | |
CMP #$B5 ;ADR MARK 3? | |
BNE RDASN1 ; (IF NOT, IS IT AM1?) | |
* (LEAVES CARRY SET!) | |
LDA #$0 ;INIT CHECKSUM. | |
RDAFLD STA CSUM | |
RDA4 LDA Q6L,X ;READ 'ODD BIT' NIBL. | |
BPL RDA4 ;*** NO PAGE CROSS! *** | |
ROLA ;ALIGN ODD BITS, '1' INTO LSB. | |
STA LAST ; (SAVE THEM) | |
RDA5 LDA Q6L,X ;READ 'EVEN BIT' NIBL. | |
BPL RDA5 ;*** NO PAGE CROSS! *** | |
AND LAST ;MERGE ODD AND EVEN BITS. | |
STA CSSTV,Y ;STORE DATA BYTE. | |
EOR CSUM ;XOR CHECKSUM. | |
DEY | |
BPL RDAFLD ;LOOP ON 4 DATA BYTES. | |
TAY ;IF FINAL CHECKSUM | |
BNE RDERR ; NONZERO, THEN ERROR. | |
RDA6 LDA Q6L,X ;FIRST BIT-SLIP NIBL. | |
BPL RDA6 ;*** NO PAGE CROSS! *** | |
CMP #$DE | |
BNE RDERR ;ERROR IF NONMATCH. | |
NOP ;DELAY BETWEEN NIBLS. | |
RDA7 LDA Q6L,X ;SECOND BIT-SLIP NIBL. | |
BPL RDA7 ;*** NO PAGE CROSS! *** | |
CMP #$AA | |
BNE RDERR ;ERROR IF NONMATCH. | |
RDEXIT CLC ;CLEAR CARRY ON | |
RTS ;NORMAL READ EXITS. | |
EJECT | |
*************************** | |
* * | |
* POSTNIBLIZE SUBR * | |
* * | |
*************************** | |
* * | |
* CONVERTS 5-BIT NIBLS * | |
* OF FORM ABCDE000 IN * | |
* NBUF1 THROUGH NBUF8 * | |
* INTO 256 BYTES OF * | |
* USER DATA IN BUF. * | |
* * | |
* ---- ON ENTRY ---- * | |
* * | |
* X-REG: HOLDS SLOTNUM * | |
* TIMES $10. * | |
* * | |
* BUF IS 2-BYTE POINTER * | |
* TO 256 BYTES OF USER * | |
* DATA TO BE CONVERTED * | |
* TO 5-BIT NIBLS IN * | |
* NBUF1 THROUGH NBUF8 * | |
* PRIOR TO WRITE. * | |
* * | |
* ---- ON EXIT ----- * | |
* * | |
* A-REG: UNCERTAIN. * | |
* Y-REG: HOLDS $FF. * | |
* X-REG: HOLDS $FF. * | |
* CARRY: UNCERTAIN. * | |
* * | |
* 5-BIT NIBLS OF FORM * | |
* 000ABCDE IN 410 * | |
* BYTES FROM NBUF1 * | |
* TO NBUF8. * | |
* * | |
*************************** | |
POSTNIB LDX #$32 ;INDEX FOR 51 PASSES. | |
LDY #$0 ;INDEX TO USER BUF. | |
POSTNB1 LDA NBUF6,X | |
LSRA | |
LSRA | |
LSRA | |
STA T1 | |
LSRA | |
STA T0 | |
LSRA | |
ORA NBUF1,X | |
STA (BUF),Y ;FIRST OF 5 USER BYTES. | |
INY | |
LDA NBUF7,X | |
LSRA | |
LSRA | |
LSRA | |
LSRA | |
ROL T1 | |
LSRA | |
ROL T0 | |
ORA NBUF2,X | |
STA (BUF),Y ;SECOND OF 5 USER BYTES. | |
INY | |
LDA NBUF8,X | |
LSRA | |
LSRA | |
LSRA | |
LSRA | |
ROL T1 | |
LSRA | |
ROL T0 | |
ORA NBUF3,X | |
STA (BUF),Y ;THIRD OF 5 USER BYTES. | |
INY | |
LDA T0 | |
AND #$7 | |
ORA NBUF4,X | |
STA (BUF),Y ;FOURTH OF 5 USER BYTES. | |
INY | |
LDA T1 | |
AND #$7 | |
ORA NBUF5,X | |
STA (BUF),Y ;FIFTH OF 5 USER BYTES. | |
INY | |
DEX ;NEXT OF 51 PASSES. | |
BPL POSTNB1 ;HANDLE LAST USER | |
LDA NBUF8+$33 ; BYTE DIFFERENTLY. | |
LSRA | |
LSRA | |
LSRA | |
ORA NBUF5+$33 | |
STA (BUF),Y | |
RTS | |
EJECT | |
************************** | |
* * | |
* FAST SEEK SUBROUTINE * | |
* * | |
************************** | |
* * | |
* ---- ON ENTRY ---- * | |
* * | |
* X-REG HOLDS SLOTNUM * | |
* TIMES $10. * | |
* * | |
* A-REG HOLDS DESIRED * | |
* HALFTRACK. * | |
* (SINGLE PHASE) * | |
* * | |
* CURTRK HOLDS CURRENT * | |
* HALFTRACK. * | |
* * | |
* ---- ON EXIT ----- * | |
* * | |
* A-REG UNCERTAIN. * | |
* Y-REG UNCERTAIN. * | |
* X-REG UNDISTURBED. * | |
* * | |
* CURTRK AND TRKN HOLD * | |
* FINAL HALFTRACK. * | |
* * | |
* PRIOR HOLDS PRIOR * | |
* HALFTRACK IF SEEK * | |
* WAS REQUIRED. * | |
* * | |
* MONTIMEL AND MONTIMEH * | |
* ARE INCREMENTED BY * | |
* THE NUMBER OF * | |
* 100 USEC QUANTUMS * | |
* REQUIRED BY SEEK * | |
* FOR MOTOR ON TIME * | |
* OVERLAP. * | |
* * | |
* --- VARIABLES USED --- * | |
* * | |
* CURTRK, TRKN, COUNT, * | |
* PRIOR, SLOTTEMP * | |
* MONTIMEL, MONTIMEH * | |
* * | |
************************** | |
SEEK STA TRKN ;TARGET TRACK. | |
CMP CURTRK ;ON DESIRED TRACK? | |
BEQ SEEKXIT ; YES, HIT IT AND RETURN. | |
STX SLOTTEMP ;SAVE X-REG. | |
LDA #$0 | |
STA TRKCNT ;HALFTRACK COUNT. | |
SEEK2 LDA CURTRK ;SAVE CURTRK FOR | |
STA PRIOR ; DELAYED TURNOFF. | |
SEC | |
SBC TRKN ;DELTA-TRACKS. | |
BEQ SEEKEND ;DONE, FINISH SEEK. | |
BCS OUT ;(MOVE OUT, NOT IN) | |
EOR #$FF ;CALC TRKS TO GO. | |
INC CURTRK ;INCR CURRENT TRACK (IN). | |
BCC MINTST ;(ALWAYS TAKEN) | |
OUT ADC #$FE ;CALC TRKS TO GO. | |
DEC CURTRK ;DECR CURRENT TRACK (OUT). | |
MINTST CMP TRKCNT | |
BCC MAXTST ; AND 'TRKS MOVED'. | |
LDA TRKCNT | |
MAXTST CMP #$C | |
BCC STEP ;IF > $B, USE $B. | |
LDA #$B | |
STEP TAY ;ACCELLERATION INDEX. | |
LDA CURTRK | |
AND #$3 ;INDEX TO 'CURRENT | |
ASLA ; PHASE' OF 4-PHASE | |
ORA SLOTTEMP ; STEPPER. | |
TAX | |
LDA PHASEON,X ;HIT NEXT PHASE | |
LDA ONTABLE,Y ; FOR 'ONTIME'. | |
JSR MSWAIT ;(100 USEC INTERVALS) | |
LDA PRIOR | |
AND #$3 ;INDEX TO 'PRIOR PHASE' | |
ASLA ; OF 4-PHASE STEPPER. | |
ORA SLOTTEMP | |
TAX | |
LDA PHASEOFF,X ;PRIOR PHASE OFF, | |
LDA OFFTABLE,Y ; THEN WAIT 'OFFTIME'. | |
JSR MSWAIT ;(100 USEC INTERVALS) | |
INC TRKCNT ;'TRACKS MOVED' COUNT. | |
BNE SEEK2 ;(ALWAYS TAKEN) | |
SEEKEND LDA #$FF ;DELAY 9.5 MSEC FOR | |
JSR MSWAIT ; SETTLING TIME. | |
LDX SLOTTEMP ;RESTORE X-REG. | |
SEEKXIT RTS ;RETURN. | |
EJECT | |
************************** | |
* * | |
* MSWAIT SUBROUTINE * | |
* * | |
************************** | |
* * | |
* DELAYS A SPECIFIED * | |
* NUMBER OF 100 USEC * | |
* INTERVALS FOR MOTOR * | |
* ON TIMING. * | |
* * | |
* ---- ON ENTRY ---- * | |
* * | |
* A-REG: HOLDS NUMBER * | |
* OF 100 USEC * | |
* INTERVALS TO * | |
* DELAY. * | |
* * | |
* ---- ON EXIT ----- * | |
* * | |
* A-REG: HOLDS $00. * | |
* X-REG: HOLDS $00. * | |
* Y-REG: UNCHANGED. * | |
* CARRY: SET. * | |
* * | |
* MONTIMEL, MONTIMEH * | |
* ARE INCREMENTED ONCE * | |
* PER 100 USEC INTERVAL* | |
* FOR MOTON ON TIMING. * | |
* * | |
* ---- ASSUMES ---- * | |
* * | |
* 1 USEC CYCLE TIME * | |
* * | |
************************** | |
MSWAIT LDX #$11 | |
MSW1 DEX ;DELAY 86 USEC. | |
BNE MSW1 | |
INC MONTIMEL | |
BNE MSW2 ;DOUBLE-BYTE | |
INC MONTIMEH ; INCREMENT. | |
MSW2 SEC | |
SBC #$1 ;DONE 'N' INTERVALS? | |
BNE MSWAIT ;(A-REG COUNTS) | |
RTS | |
EJECT | |
************************** | |
* * | |
* PHASE ON-, OFF-TIME * | |
* TABLES IN 100-USEC * | |
* INTERVALS. (SEEK) * | |
* * | |
************************** | |
ONTABLE DB $01,$30,$28 | |
DB $24,$20,$1E | |
DB $1D,$1C,$1C | |
DB $1C,$1C,$1C | |
OFFTABLE DB $70,$2C,$26 | |
DB $22,$1F,$1E | |
DB $1D,$1C,$1C | |
DB $1C,$1C,$1C | |
EJECT | |
************************** | |
* * | |
* 7-BIT TO 5-BIT * | |
* 'DENIBLIZE' TABL * | |
* * | |
* VALID CODES * | |
* $AB TO $FF ONLY. * | |
* ($DA NOT VALID) * | |
* * | |
* ---- CAUTION ---- * | |
* * | |
* INSURE THAT FOLLOWING * | |
* 'RE-ORG' IS OK. * | |
* * | |
************************** | |
ORG $3AAB | |
* OBJ $BAAB | |
DB $00,$01,$08 | |
DB $10,$18,$02 | |
DB $03,$04,$05 | |
DB $06,$20,$28 | |
DB $30,$07,$09 | |
DB $38,$40,$0A | |
DB $48,$50,$58 | |
DB $0B,$0C,$0D | |
DB $0E,$0F,$11 | |
DB $12,$13,$14 | |
DB $15,$16,$17 | |
DB $19,$1A,$1B | |
DB $1C,$1D,$1E | |
DB $21,$22,$23 | |
DB $24,$60,$68 | |
DB $25,$26,$70 | |
DB $78,$27,$80 | |
DB $88,$90,$29 | |
DB $2A,$2B,$2C | |
DB $2D,$2E,$2F | |
DB $31,$32,$33 | |
DB $98,$A0,$34 | |
DB $A8,$B0,$B8 | |
DB $35,$36,$37 | |
DB $39,$3A,$C0 | |
DB $C8,$D0,$3B | |
DB $3C,$D8,$E0 | |
DB $3E,$E8,$F0 | |
DB $F8 | |
EJECT | |
************************** | |
* * | |
* 5-BIT TO 7-BIT * | |
* NIBL CONVERSION * | |
* TABLE * | |
* * | |
************************** | |
* * | |
* CODES $AA, $D5 * | |
* NOT USED * | |
* * | |
************************** | |
ORG $3C9A | |
* OBJ $BC9A | |
NIBL DB $AB,$AD,$AE | |
DB $AF,$B5,$B6 | |
DB $B7,$BA,$BB | |
DB $BD,$BE,$BF | |
DB $D6,$D7,$DA | |
DB $0DB,$DD,$DE | |
DB $DF,$EA,$EB | |
DB $ED,$EE,$EF | |
DB $F5,$F6,$F7 | |
DB $FA,$FB,$FD | |
DB $FE,$FF | |
DB $1C,$1C,$1C | |
* | |
DB $00,$00,$00 | |
DB $A4,$2D,$B9,$D0,$3C,$A0,$05,$4C | |
DB $0A,$3E,$00,$00,$00,$00,$00,$00 | |
DB $00,$05,$0A,$02,$07,$0C,$04,$09 | |
DB $01,$06,$0B,$03,$08,$00,$00,$00 | |
DB $00,$00,$00,$00,$00,$00,$00,$00 | |
DB $00,$00,$00,$00,$00,$00,$00,$00 | |
DB $00,$00,$00,$00,$00,$00,$00,$00 | |
DB $00,$00,$00,$00,$00,$00,$00,$00 | |
************************** | |
* * | |
* RWTS ENTRY POINT * | |
* * | |
************************** | |
VOLFND EQU $2F | |
TRKFND EQU $2E | |
SECFND EQU $2D | |
DRIVNO EQU $35 | |
DEVCTBL EQU $3C | |
FMTTRKC EQU $41 | |
IOBPL EQU $48 | |
FMTMASK EQU $4A | |
FMTSEC EQU $4B | |
RETRYCNT EQU $578 | |
SLOT EQU $5F8 | |
SETWRT EQU $C08F | |
SETRD EQU $C08E | |
WRTDAT EQU $C08D | |
RDDATA EQU $C08C | |
DRVSL2 EQU $C08B | |
DRVSL1 EQU $C08A | |
DRVON EQU $C089 | |
DRVOFF EQU $C088 | |
PHASE1OFF EQU $C082 | |
PHASE2OFF EQU $C084 | |
PHASE3OFF EQU $C086 | |
ORG DISKIO | |
* OBJ $BD00 | |
RWTS | |
STY IOBPL ;SAVE IOB ADDRESS | |
STA IOBPL+1 | |
LDY #$1 ;GET NEW SLOT # | |
LDA (IOBPL),Y | |
TAX ;SAVE SLOT # TO X | |
STY $4F8 ;SET SEEK CNT=1 | |
LDY #$F ;SEE IF SLOT HAS CHANGED | |
CMP (IOBPL),Y | |
BEQ L3D2D ;BR IF SAME SLOT | |
TXA ;SAVE NEW SLOT # | |
PHA | |
LDA (IOBPL),Y ;GET OLD SLOT # | |
TAX | |
PLA | |
PHA ;NEW SLOT # BACK TO STACK | |
STA (IOBPL),Y ;SET NEW SLOT NUMBER | |
LDA SETRD,X ;SET READ MODE | |
L3D1E | |
LDY #$8 ;DELAY UNTIL DATA IS STABLE | |
LDA RDDATA,X | |
L3D23 | |
CMP RDDATA,X | |
BNE L3D1E ;BR IF DRIVE STILL SPINNING | |
DEY | |
BNE L3D23 ;LONG ENOUGH? BR UNTIL OLD DRIVE OFF | |
PLA ;GET NEW SLOT # | |
TAX | |
L3D2D | |
LDA SETRD,X ;INSURE IN READ MODE | |
LDA RDDATA,X ;GET THE DATA | |
LDA RDDATA,X | |
PHA ;DELAY FOR DISK DATA TO CHANGE | |
PLA | |
STX SLOT ;SET SLOT | |
CMP RDDATA,X ;CHECK RUNNING | |
PHP ;SAVE CHECK RESULTS TO STACK | |
LDA DRVON,X ;TURN DRIVE ON | |
LDY #$6 ;MOVE IBDCTP & IBBUFP PTRS TO PAGE 0 | |
L3D44 | |
LDA (IOBPL),Y | |
STA $0036,Y ;PTRS DESTINATION ON PG 0 | |
INY | |
CPY #$A ;ALL PTRS MOVED? | |
BNE L3D44 ;MOVE MORE IF NOT | |
LDY #2 ;GET DRIVE # | |
LDA (IOBPL),Y | |
LDY #$10 ;SAME DRIVE USED BEFORE? | |
CMP (IOBPL),Y | |
BEQ L3D5E ;BR IS SO | |
STA (IOBPL),Y ;ELSE SET CURR DRV # | |
PLP ;RESTORE CHECK RUNNING STATUS | |
LDY #$0 ;SET Z FLAG | |
PHP | |
L3D5E | |
RORA ;BY GOING INTO CARRY | |
LDA DRVSL1,X ;SELECT DRIVE 1 | |
BCS L3D67 ;CARRY STILL SET - DRIVE 1 IT IS | |
LDA DRVSL2,X ;ELSE SELECT DRIVE 2 | |
L3D67 | |
ROR DRIVNO ;SAVE SELECTED DRV TO PG 0 | |
LDY #$2 ;GET MOT ON TIME LO FROM DEVCTBL | |
LDA (DEVCTBL),Y | |
STA MONTIMEL ;SAVE LO | |
INY | |
LDA (DEVCTBL),Y ;GET MOT ON TIME HI FROM DEVCTBL | |
STA MONTIMEH ;SAVE HI | |
INY ;Y=4, SET TO IOB TRK | |
LDA (IOBPL),Y ;GET DESIRED TRACK | |
JSR MYSEEK ;GO SEEK | |
PLP ;WAS MOTOR ON? | |
BNE L3D8A ;SKIP DELAY AND TRY TRACK IF SO | |
L3D7D | |
LDY #$12 ;DELAY 100 USEC PER COUNT | |
L3D7F | |
DEY | |
BNE L3D7F | |
INC MONTIMEL | |
BNE L3D7D | |
INC MONTIMEH | |
BNE L3D7D ;COUNT UP TO $0000 | |
* | |
* DISK IS UP TO SPEED | |
* IF NOT FORMAT, LOCATE CORRECT SECTOR | |
* | |
L3D8A | |
LDY #$C | |
LDA (IOBPL),Y ;GET COMMAND CODE # | |
BEQ L3DE5 ;BR IF NULL COMMAND | |
CMP #$4 ;FORMAT? | |
BEQ L3DE7 ;BR IF SO | |
RORA ;SET CARRY=1 FOR READ, 0 FOR WRITE | |
PHP ;AND SAVE THAT | |
BCS L3D9B ;BR IF READ | |
JSR PRENIBL ;MUST PRENIBBLIZE FOR WRITE | |
L3D9B | |
LDY #$30 ;48 RETRIES | |
STY RETRYCNT ;SAVE RETRY COUNT | |
L3DA0 | |
LDX SLOT ;GET SLOT # INTO X | |
JSR RDADR ;READ NEXT ADDRESS FIELD | |
BCC L3DC7 ;BR IF GOOD READ | |
L3DA8 | |
DEC RETRYCNT ;DEC RETRY COUNT | |
BPL L3DA0 ;IF HAVEN'T TRIED ENOUGH, TRY AGAIN | |
LDA $478 ;GET TRACK WE WANT | |
PHA ;SAVE IT | |
LDA #$60 ;RECALIBRATE TO TRK 96 | |
JSR L3E82 | |
DEC $4F8 ;ONCE TOO MANY? | |
BNE L3DDE ;TRIED TO RECAL TOO MANY | |
LDA #$0 ;MOVE TO TRK 0 | |
JSR MYSEEK | |
PLA | |
L3DC1 | |
JSR MYSEEK ;GO TO CORRECT TRACK | |
JMP L3D9B ;LOOP BACK, TRY AGAIN ON THIS TRK | |
L3DC7 | |
LDY TRKFND ;ON THE RIGHT TRACK? | |
CPY $478 | |
BEQ L3DF0 ;BR IF SO | |
LDA $478 ;SAVE DESTINATION TRK | |
PHA | |
TYA | |
JSR L3E82 | |
PLA | |
DEC RETRYCNT ;SHOULD WE RESEEK? | |
BPL L3DC1 ;YES - RESEEK | |
BMI L3DA8 ;NO - RECALIBRATE | |
L3DDE | |
PLA ;REMOVE CURTRK | |
LDA #$40 ;BAD DRIVE ERROR | |
L3DE1 | |
PLP | |
JMP L3E29 ;GO HANDLE ERROR | |
L3DE5 | |
BEQ L3E27 ;ALL DONE | |
L3DE7 | |
LDY #$3 ;GET VOLUME # | |
LDA (IOBPL),Y | |
STA VOLFND ;SAVE TO PG 0 | |
JMP DSKFORM ;GO FORMAT | |
L3DF0 | |
LDY #$3 ;IS THE RIGHT DISK IN? | |
LDA (IOBPL),Y ;GET DESIRED VOLUME | |
PHA ;SAVE VOLUME # | |
LDA VOLFND ;GET ACTUAL VOLUME | |
LDY #$E ;INDICATE VOLUME FOUND | |
STA (IOBPL),Y | |
PLA ;GET DESIRED VOLUME BACK | |
BEQ L3E06 ;DESIRED VOLUME MATCHES ALL | |
CMP VOLFND | |
BEQ L3E06 ;YES...IT WAS CORRECT | |
LDA #$20 ;SOMEONE SWITCHED DISKS! | |
BNE L3DE1 ;ALWAYS | |
L3E06 | |
LDY #$5 ;TO ALLOW FOR INTERLEAVE | |
LDA SECFND ;GET REQUESTED LOGICAL SECTOR | |
L3E0A | |
CMP (IOBPL),Y | |
BEQ L3E17 ;FOUND OUR DESIRED SECTOR | |
DEC RETRYCNT ;ADJUST RETRY COUNT | |
BPL L3DA0 | |
LDA #$80 | |
BNE L3DE1 ;NO, KEEP TRYING | |
* | |
* SECTOR FOUND | |
* | |
L3E17 | |
PLP ;GOT OUR SECTOR | |
BCC L3E32 ;CARRY WAS SET FOR WRITE OPERATION | |
JSR READ ;GO READ | |
PHP ;SAVE STATUS OF READ OPERATION | |
BCS L3DA8 ;CARRY SET IF BAD READ | |
PLP ;ADJUST STACK | |
JSR POSTNIB ;DECODE INTO REAL DATA | |
LDX SLOT ;GET SLOT # INTO X | |
L3E27 | |
CLC ;INDICATE NO ERROR | |
DB $24 ;SKIP NEXT SEC TO MAINTAIN NO ERROR | |
L3E29 ; DO USELESS BIT INSTR INSTEAD | |
SEC ;INDICATE AN ERROR | |
LDY #$D ;SET ERROR # | |
STA (IOBPL),Y | |
LDA DRVOFF,X ;TURN DRV MOTOR OFF | |
RTS | |
L3E32 | |
JSR WRITE ;WRITE NIBBLES NOW | |
BCC L3E27 ;BR IF NO ERRORS | |
LDA #$10 ;DISK IS WRITE PROTECTED | |
BCS L3E29 ;ALWAYS! | |
************************** | |
* * | |
* SEEK ROUTINE * | |
* * | |
* SEEKS TRACK 'N' IN * | |
* SLOT #X/16 * | |
* IF DRIVNO IS NEGATIVE, * | |
* ON DRIVE 1 * | |
* IF DRIVNO IS POSITIVE, * | |
* ON DRIVE 2 * | |
* * | |
************************** | |
MYSEEK | |
PHA ;PRESERVE ACC | |
LDY #$1 ;TWO PHASE DISK? | |
LDA (DEVCTBL),Y | |
RORA ;GET # OF PHASES INTO CARRY | |
PLA | |
BCC L3E4C ;BR IF 1 PHASE PER TRK | |
ASLA | |
JSR L3E4C | |
LSR $478 ;DIVIDE BACK DOWN | |
RTS | |
* | |
L3E4C | |
STA TRKFND ;SAVE DEST TRACK (*2) | |
LDA PHASEOFF,X | |
LDA PHASE1OFF,X | |
LDA PHASE2OFF,X | |
LDA PHASE3OFF,X | |
JSR L3E7B | |
LDA $478,Y | |
BIT DRIVNO ;IF MINUS, ON DRV 0 | |
BMI L3E67 | |
LDA $4F8,Y ;ELSE GET DRV 1 TRACK | |
L3E67 | |
STA $478 ;CURRENT TRACK | |
LDA TRKFND ;DESTINATION TRACK | |
BIT DRIVNO ;UPDATE SLOT DEPENDENT | |
BMI L3E75 ; LOCATIONS WITH TRACK | |
STA $4F8,Y ; INFORMATION | |
BPL L3E78 ;ALWAYS! | |
L3E75 STA $478,Y | |
L3E78 JMP SEEK ;GO SEEK | |
L3E7B | |
TXA ;SET Y=SLOT # | |
LSRA | |
LSRA | |
LSRA | |
LSRA | |
TAY | |
RTS | |
* | |
* SET SLOT DEPENDENT TRACK LOCATION | |
* | |
L3E82 | |
PHA ;SAVE DEST TRACK | |
LDY #$2 | |
LDA (IOBPL),Y | |
RORA ;GET DRIVE # INTO CARRY | |
ROR DRIVNO ;INTO (DRIVENO) | |
JSR L3E7B ;SETUP Y REG | |
PLA | |
ASLA ;ASSUME TRACK IS HELD *2 | |
BIT DRIVNO | |
BMI L3E98 ;IF ON DRIVE 1(1), DRIVNO MINUS | |
STA $4F8,Y ;SAVE DRV 2 TRACK | |
BPL L3E9B ;ALWAYS | |
L3E98 | |
STA $478,Y ;ELSE SAVE DRV 1 TRACK | |
L3E9B | |
RTS | |
************************** | |
* * | |
* FORMAT ROUTINE * | |
* * | |
************************** | |
DSKFORM | |
LDA #$80 ;FAKE DRV 0 TRACK | |
STA $478 | |
LDA #$0 ;SET TRACK TO 0 | |
STA FMTTRKC ;SAVE FORMAT TRACK COUNTER | |
JSR SEEK ;GO THERE | |
LDA #$AA ;MASK FOR ODD-EVEN ENCODING | |
STA FMTMASK ;SAVE TO PG 0 | |
LDY #$50 ;ATTEMPTS COUNT | |
L3EAE | |
STY MONTIMEH ;SAVE # OF ATTEMPTS | |
LDA #$27 ;39 SELF-SYNC NIBBLES | |
STA FMTSEC ;SAVE COUNT | |
LDA WRTDAT,X ;TURN OFF WRITE | |
LDA SETRD,X | |
* | |
* WRITE GAP | |
* | |
LDA #$FF ;GET SYNC BYTE | |
STA SETWRT,X ;WRITE IT | |
CMP RDDATA,X ;READ IT BACK | |
BIT $0000 | |
L3EC4 | |
DEY ;ADJUST WRITE ATTEMPTS | |
BEQ L3ED6 ;BR IF GOOD WRITE | |
PHA ;ELSE DELAY | |
PLA | |
NOP | |
L3ECA | |
PHA ;DELAY SOME MORE | |
PLA | |
NOP | |
NOP | |
STA WRTDAT,X ;WRITE AGAIN | |
CMP RDDATA,X ;READ IT BACK | |
BCS L3EC4 ;BR IF STILL NOT GOOD | |
L3ED6 | |
DEC FMTSEC ;GOOD WRITE, SO DEC SYNC COUNT | |
BNE L3ECA ;WRITE NEXT | |
LDY MONTIMEH | |
NOP | |
NOP | |
BNE L3EE6 ;BR IF MOTOR TIME GOOD | |
L3EE0 | |
PHA ;DELAYS | |
PLA | |
PHA | |
PLA | |
CMP ($0000,X) | |
L3EE6 | |
NOP ;DELAY | |
* | |
* WRITE SECTOR ROUTINE | |
* | |
L3EE7 | |
STA WRTDAT,X | |
CMP RDDATA,X | |
DEY | |
BNE L3EE0 | |
* | |
* WRITE ADDR FIELD PROLOGUE | |
* | |
LDA #$D5 ;ADDR MARK 1 | |
JSR WBYTE1 | |
LDA #$AA ;ADDR MARK 2 | |
JSR WBYTE | |
LDA #$B5 ;ADDR MARK 3 | |
JSR WBYTE | |
LDA VOLFND ;WRITE ODD-EVEN ENCODED VOLUME | |
JSR EOWBYTE | |
LDA FMTTRKC ;WRITE ODD-EVEN ENCODED TRACK | |
JSR EOWBYTE | |
LDA FMTSEC ;WRITE ODD-EVEN ENCODED SECTOR | |
JSR EOWBYTE | |
LDA VOLFND ;CALC CHECKSUM BY EOR'ING VOLUME, | |
EOR FMTTRKC ; TRACK, AND SECTOR | |
EOR FMTSEC | |
PHA | |
LSRA | |
ORA FMTMASK ;WITH $AA | |
STA WRTDAT,X ;WRITE CHECKSUM ODD BITS | |
CMP RDDATA,X | |
PLA | |
ORA #$AA | |
JSR WBYTE1 ;WRITE CHECKSUM EVEN BITS | |
* | |
* WRITE ADDR FIELD EPILOGUE | |
* | |
LDA #$DE ;BIT-SLIP 1 | |
JSR WBYTE | |
LDA #$AA ;BIT-SLIP 2 | |
JSR WBYTE | |
LDA #$EB ;BIT-SLIP 3 | |
JSR WBYTE | |
LDA #$FF ;WRITE SYNC BYTE | |
JSR WBYTE | |
* | |
* WRITE DATA FIELD | |
* | |
LDY #$2 ;WRITE IN TWO PASSES.... | |
STY MONTIMEL | |
LDY #$AD ;...OF 173 BYTES EACH PASS (346 BYTES) | |
BNE L3F46 | |
L3F40 | |
DEY ;ADJUST # BYTES WRITTEN | |
BEQ L3F50 | |
PHA ;GET $FF DATA FIELD BYTE BACK | |
PLA ;RE-SAVE IT | |
NOP ;DELAY SOME | |
L3F46 | |
PHA ;GET DATA BYE BACK | |
PLA ;RESAVE | |
STA WRTDAT,X ;WRITE IT | |
CMP RDDATA,X | |
BCS L3F40 ;WRITE SOME MORE | |
L3F50 | |
DEC MONTIMEL ;TWO PASSES COMPLETE? | |
BNE L3F46 ;DO ANOTHER PASS IF NOT | |
LDY MONTIMEH | |
CLC ;FOR ADC WITHOUT CARRY | |
BIT $0000 | |
STA WRTDAT,X | |
LDA RDDATA,X | |
LDA FMTSEC ;GET SECTOR | |
ADC #$A ;3 SECTOR INTERLEAVE | |
STA FMTSEC ;RESAVE SECTOR | |
SBC #$C ;13 SECTORS DONE? | |
BEQ L3F73 ;BR IF SO | |
BCS L3F6C ;MORE SECTORS TO WRITE | |
DB $2C ;SKIP NEXT STA OF SECTOR, DO USELESS BIT INSTEAD | |
L3F6C | |
STA FMTSEC | |
LDA #$FF ;SYNC BYTE | |
JMP L3EE7 ;GO WRITE ANOTHER SECTOR | |
L3F73 | |
PHA ;GET DATA BYTE BACK | |
PLA ;AND RESAVE | |
LDY MONTIMEH | |
LDA WRTDAT,X | |
LDA SETRD,X ;TURN OFF WRITE MODE | |
BMI L3FB3 | |
DEY | |
L3F80 | |
PHA ;DELAYS | |
PLA | |
NOP | |
NOP | |
BIT $0000 | |
PHA | |
PLA | |
DEY | |
BNE L3F80 | |
JSR RDADR ;VERIFY SECTOR ADDRESS | |
BCS L3F94 ;BR IF READ ADDRESS ERROR | |
LDA SECFND | |
BEQ L3F9E | |
L3F94 | |
LDY MONTIMEH ;GET TRACK FMT ATTEMPTS | |
DEY ;DEC ATTEMPTS MADE | |
CPY #$10 ;DID WE TRY ENOUGH? | |
BCC L3FB3 ;BR IF ERROR ... WE TRIED ENOUGH | |
JMP L3EAE ;ELSE TRY AGAIN | |
L3F9E | |
INC FMTTRKC ;INC TRACK PTR | |
LDA FMTTRKC ;GET NEXT TRACK | |
CMP #$23 ;DID WE DO ALL 35 TRACKS? | |
BCS L3FB8 ;BR IS SO | |
ASLA ;ELSE GO TO NEXT TRACK | |
JSR SEEK | |
LDY MONTIMEH ;ADJUST # OF ATTEMPTS | |
INY | |
INY | |
STY MONTIMEH | |
JMP L3EAE ;GO FORMAT NEXT TRACK | |
L3FB3 | |
LDA #$40 ;ERROR | |
JMP L3E29 | |
L3FB8 | |
JMP L3E27 ;ALL WENT WELL | |
* | |
* WRITE ODD BITS, THEN EVEN BITS OF A BYTE | |
* | |
EOWBYTE | |
PHA ;SAVE IT | |
LSRA ;ODD BITS FIRST | |
ORA FMTMASK ;WITH $AA | |
STA WRTDAT,X ;WRITE IT | |
CMP RDDATA,X | |
PLA ;RESTORE BYTE | |
CMP ($0000,X) | |
ORA #$AA ;GET EVEN BITS | |
************************** | |
* * | |
* WRITE A BYTE TO DISK * | |
* * | |
************************** | |
WBYTE1 | |
NOP | |
WBYTE | |
PHA ;SAVE BYTE TO STACK | |
PLA ;GET IT BACK | |
NOP ;DELAY | |
STA WRTDAT,X ;WRITE IT | |
CMP RDDATA,X | |
RTS | |
************************** | |
* * | |
* FIX FOR A BUG WITH * | |
* APPLESOFT II * | |
* READ/WRITE STATEMENTS * | |
* (LINES GT 255 ARE * | |
* IGNORED!) * | |
* * | |
************************** | |
ASRWPAT | |
INX ;BUMP HIGH BYTE OF LINE # | |
BEQ ASRWP1 ;BR IF HIGH AS WE CAN GO | |
RTS ;ELSE LINE # GT 255, SO RETURN | |
ASRWP1 JMP ICFDB ;NOT RUN MODE - CLOSE FILE | |
* | |
ORG AEC2 | |
DB 0 | |
END |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment