	.TITLE	"SHEP	APPLE DOS"
*	6.3	10-6-78
*	8 BIT ASSEMBLER
*	.M6502
*
**************************************************************************************
*	(C)  COPYRIGHT 1978  APPLE COMPUTER, INC
**************************************************************************************
*
#INCLUDE "MOTO.H"

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
	LDY	#0		;APPLE TEST
DR1B
	LDA	(ZPGWRK,X)
	STA	LOC1
DR1	TYA
	EOR	LOC1
	STA	LOC1
	TYA
	EOR	(ZPGWRK,X)
	STA	(ZPGWRK,X)
	CMP	LOC1
	BNE	DR1A
	INY
	BNE	DR1B
	BEQ	DR2		; BR IF TOOK
DR1A
	DEC	!ZPGWRK+1	; NOT RAM
	BNE	DR1		; TRY NEXT PAGE
;
DR2
;	
	LDY	!ZPGWRK+1
	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 AINT
	BNE	DR9		; 3 THEN DONT RELOC
	LDA	(ZPGWRK),Y	; GET PAGE FROM INST
	CMP	RSPAGE		; IF PAGE < REL START
	BCC	DR9		; THE IGNOR
	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 OUT 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
	LDA	ASIBSW		;GET AS/IB FLAG
	BNE	INITA1		;BR IF NOT IB
	LDA	#ITSTV		;GET IB TEST VALUE
	BNE	INITA2		;GO SET IB
INITA1	ASLA			;TST ROM AS
	BPL	INITA3		;BR IF NOT ROM TEST VALUE
	LDA	#ATSTV		;GET AS ROM TEST VALUE
INITA2	JSR	SWTST		;GO SET
INITA3
	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 INSTATE
	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 GO 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	ICFD		;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
SVRGSA
	STX	SVX		;SAVE X
	STY	SVY		;SAVE Y
	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		;IS CR THEN CMD CHECK
COS3B
	LDA	ESTATE		;ELSE IF NOT EXECUTE
	BEQ	PRRTN		;THEN PRINT CHAR
	BNE	DRTNI		;ELSE PRINT IF MON INPUT
COS3A
;
	JSR	TSTRUN
	BCS	COS3B
	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
	STA	SVA
	STY	SVY
	STX	SVX
;
ORTN
	JSR	MVCSW		;GO MOVE CHAR I/O SWITCH
LDREGS
	LDA	SVA		;ACU
	LDY	SVY		;Y
	LDX	SVX		;X
	SEC
	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		;ITS 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 ILENAME
	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
	LDA	LBUFD		;SET PASS 1
	STA	TEMP1A
;
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	;XOR 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		;DONT 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		;CCBLENGTH
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 LTO
	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
	JSR	TSTFNF
	JMP	ECLOSE
;
;	EVAR  VERIFY A FILE
;
EVAR
	LDA	#CRQVAR		;SET VARIFY
	BNE	ELGO
	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
EO4
	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
EO6
	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		;GOL 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
	JSR	TSTFNF
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
TSTFNF	LDA	#CREFNF		;FILE NOT FOUND ERROR CODE
	CMP	CCBSTA		;TEST FILE NOT FOUND
	BEQ	FNF		;BR IF FILE NOT FOUND
	RTS			;FILE FOUND, RETURN
FNF	JMP	KLUTZ		;GO FIX THINGS
	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 LENGTH
;
	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
;
SV1
SV1A
	STA	CCBFUC		;SET BLOCK	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/L
	STA	CCBRQM
	JSR	DOSGO		;GO DO IT
	JMP	ECLOSE		;CLOSE FILE
	PAGE
NBPER	JMP	ERNU1
;
;	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 WONT FIT
;
EASL1
	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  BLOCK 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		;GEET BLOCK
	JMP	ECLOSE		;GO CLOSE FILE
;
MFULL
	JSR	ECLOSE		;GO CLOSE FILE
	JMP	MFERR		;AND GIVE ERR MSG
LD1
	CMP	CCBFUC		;TEST TYPE
	BEQ	LD1C		;BR IF MATCH
	LDX	CMDNO
	STX	SVCMD
	LSRA
	BEQ	LD1A		;BR IF PGM IS AS
	JMP	EINT		;GO FOR INTO 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 REGD
	JSR	TSTFNF
	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
	BEQ	INER		;BE 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
;
EAS0
	LDY	#30
	JSR	CLRFNA
	LDX	#FASBL
EAS1	LDA	FASB-1,X	;MOVE SYSTEM FILE NAME
	STA	FNAME1-1,X
	DEX
	BNE	EAS1
;
EAS2
	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
;
	PAGE
;
;	EEXEC  EXEC CMD
;
EEXEC
	JSR	EOPEN		;OPEN FILE
	JSR	TSTFNF
	LDA	CFTABA		;MOVE TABLE POINTERS
	STA	EFTABA
	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
	JSR	TSTFNF
	JMP	EXP2
EXP1	JSR	MVBUFP
EXP2
	LDA	INOPTS		;GET OPTIONS
	AND	#R		;TEST R
	BEQ	EX2		;BR 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 RCORD
	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
	BCS	ICFDB
	LDA	SVA		;CHAR IN SAVED ACU
	STA	CCBDAT		;PUT INTO CCBDATA 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
;
ICFD
	JSR	TSTRUN		;GO TEST RUN
	BCS	ICFDB
	LDA	#6		;SET OUT STE = 6
ICFD3
	STA	OSTATE		;TO CATCH ECHO
	JSR	RBYTE
	BNE	ICFD1		;BR IF NOT ZERO CHAR
ICCFD2
	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
	BNE	NOTRUN		;BR IF NOT RUN
TR0	CLC
	RTS
TR1
	LDA	$D9		;GET INT RUN FLAG
	BMI	TR0		;BR IF RUN
NOTRUN	SEC
	RTS
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
	RTS
	PAGE
;
;	DOSGO  GOTO DOS
;
DOSGO
	JSR	DOSENT		;GO TO DOS
	BCS	DG1		;BR IF ERROR
	RTS			;DONE
;
DG1				;*** ERROR ***
	JSR	FILSRC		;GET FILE TABLE
	BCS	DG2		;BR IF NOT FOUND
	LDA	#0
	TAY
	STA	(ZPGWRK), Y	;CLOSE FILE HERE
DG2
	LDA	CCBSTA		;GET STATUS OF I/O
	CMP	#CREEOF		;EOF ?
	BNE	DG3		;BR IF NOT
	LDX	#0		;SET OTHER EIF
	STX	CCBDAT		;DONE
	RTS
DG3
	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
ERNU1	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/ 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			;RTN
;
;	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	ERNU1
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	BFTIB
;
	PLA			;SET APPLESOFT
	STA	ASHM1+1		;UPPER MEM LIMITS
	STA	ASHM2+1
	PLA
	STA	ASHM1
	STA	ASHM2
	RTS
;
BFTIB
	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 INSWITCH
	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	@0		;CURRENT FILE TABLE POINTER
ISTATE	DB	0		;INPUT STATE
OSTATE	DB	0		;OUTPUT STATE
SVOUTS	DW	@0		;SAVED OUT SWITCH
SVINS	DW	@0		;SAVED IN SWITCH
CNFTBS	DB	0		;CURRENT NO FILE TABLES
DFNFTB	DB	3		;DEFAULT NO FILE TABLES
SVSTK	DB	0		;SAVED STACK PTR
SVX	DB	0		;DSAVED X REG
SVY	DB	0		;SAVED Y REG
SVA	DB	0		;SAVED ACU
LBUFD	DB	0		;LINE BUFF DSPL
MONMOD	DB	0		;MONITOR MODE BITS
MC	EQU	$40		;MONITOR CMDS
MI	EQU	$20		;MONITOR INPUT
MO	EQU	$10		;MONITOR OUTPUT
CMDNO	DB	$FF		;COMMAND NO
SVBL	DB	0,0
SVCMD	DB	0
TEMP1A	DB	0
TEMP2A	DB	0
INOPTS	DB	0		;INPUT OPTIONS
CUROPT				;CURRENT OPTIONS
CV	DW	@@0		;VOLUME
CD	DW	@@0		;DRIVE
CS	DW	@@0		;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		;FEND 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
;				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
DENRTS	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	F02
	CPX	#0
	BNE	F02
	INX			;SET RL=256
F02	STA	DCBRCL
	STX	DCBRCL+1
;
	JSR	FNDFIL		;GO FIND FILE
	BCC	F03		;BR IF FOUND
;				;CREATE FILE
	LDA	#0
	STA	VDFILE+34,X
	LDA	#1
	STA	VDFILE+33,X
	STX	TEMP1		;SAVE VDIR INDEX
	JSR	GETSEC		;GO ALLOCATE SECTOR
	LDX	TEMP1
	STA	VDFILE+1,X	;PUT SECTOR INTO VDIR
	STA	DCBFDS		;PUT SECTOR AS 1ST 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
;
	LDX	TEMP1		;RE-GET INDEX
	LDA	#CREFNF
	STA	CCBSTA
;
F03
	LDA	VDFILE,X	;MOVE FILE DIR TRACK
	STA	DCBFDT
	LDA	VDFILE+1,X	;MOVE FILE DIR SECTOR
	STA	DCBFDS
	LDA	VDFILE+2,X	;70VE FILE USE CODE
	STA	CCBFUC
	STA	DCBFUC
	LDA	VDFILE+33,X
	STA	DCBNSA
	LDA	VDFILE+34,X
	STA	DCBNSA+1
	STX	DCBVDI		;SAVE DIR INDEX
;
	LDA	#255		;INDICATE NO SECTOR
	STA	DCBCMS		;IN MEMORY
	STA	DCBCMS+1
	LDA	VTDMS		;MOVE MAX FD SECTS
	STA	DCBDMS		;TO DCB
	CLC
	JMP	RDFDIR		;READ 1ST DIRECTORY RECORD
;
;
;
;
DCBSUP
	LDA	#0
	TAX
F01	STA	FCBDCB,X	;CLEAR DCB
	INX
	CPX	#DCBLEN
	BNE	F01
;
	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
F01A	
	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 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
;
PB0	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
;
FD2	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
RD3A
	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
;
RDFDC	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	
MSB1	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
;
RVDC	LDY	VDIRSC		;GET LINK SECTOR
	LDX	VDIRTK		;GET FIRST TRK
	BNE	RVDGO		;GO READ
;
RVDA
	LDX	VDLTRK		;GET SECTOR
	BNE	RDVC		;BR IF A LINK
	SEC			;SET END OF DIR
	RTS
;
RDVC	LDY	VDLSEC		;GET SECTOR
RVDGO
	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 ENTRY
	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		;LADD 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	0		;CUR VOL DIR TRK
CVDSEC	DB	0		;CUR VOL DIR SECTOR
CURCCB	DB	0,0		;CURRENT CCB ADR
ENTSTK	DB	0		;ENTRY STACK POINTER
TEMP1	DB	0		;TEMP BYTE 1
TEMP2	DB	0		;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	2		;DOS TYPE
VDIRTK	DB	17		;COLUME DIRECTORY SECTOR
VDIRSC	DB	12		;VOLUME DIRECTORY SECTOR
VDOSRN	DB	2		;DOS RELEASE NUMBER
	DB	0		;SPARE
	DB	0		;SPARE
VVOLNO	DB	0		;VOLUME NUMBER
	RMB	32		;SPARE
VTDMS	DB	122		;MAX SECTORS IN A FILE DIR
VSPARE	RMB	8		;SPARES
;
VALCA1	DB	17		;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	2		;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

;
;	DOSLDR  DOS LOADER AND WRITTER
;
	ORG	ORG2
DOSLDR
;	GARBAGED BOOT REC 0 HERE
	RMB	254
GRSPG	DB	0
GRPGC	DB	0
	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	*
	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	7		;CONTROLLER SLOT NO.
IBDRVN	DB	0		;DRIVE NUMBER
IBVOL	DB	$FF		;VOLUME NUMBER
IBTRK	DB	0		;TRACK NUMBER
IBSECT	DB	0		;SECTOR NUMBER
IBDCTP	DW	@@DCT
IBBUFP	DW	@@0		;POINTER TO BUFFER
IBDLEN	DW	256		;DATA LENGTH
IBCMD	DB	0		;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	0		;STATUS MODIFIER BYTE
IBPSLT	DB	0		;PREVIOUS SLOT
IBPDRV	DB	0		;PREVIOUS SLOT
IBSPAR	RMB	2		;IOB SPARES
DCT	DB	0,1,$EF,$D8
	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
	PAGE
	END
