;
; PUT A SINGLE CHARACTER ON THE SCREEN
;
CHRPUT	LDX	#PUTCHR
	STX	ICMD
	LDX	#0
	STX	ILEN
	STX	ILEN+1
	JMP	CIOV
;
; PUT MESSAGE TO THE SCREEN
;
PRTMSG	STA	RAMLO
	STX	RAMLO+1
PRTNXT	LDX	#0
	LDA	(RAMLO,X)
	BEQ	PRTXIT
	JSR	CHRPUT
PRTENT	INC	RAMLO
	BNE	PRTNXT
	INC	RAMLO+1
	BNE	PRTNXT
PRTXIT	RTS
;
; PRINT AN IN-LINE STRING
;
PRINT	PLA
	STA	RAMLO
	PLA
	STA	RAMLO+1
PRTMEN	JSR	PRTENT
	LDA	RAMLO+1
	PHA
	LDA	RAMLO
	PHA
	RTS
;
; READ A BYTE FROM THE KEYBOARD
;
CHRGET	JSR	XE424	;FETCH THE BYTE
	CPY	#0
	BMI	KILLRD	;IF BREAK OR EOF, ABORT COMMAND
	CMP	#'z'+1	;> LOWER CASE Z?
	BCS	NCHGCS
	CMP	#'a'	;< LOWER CASE A?
	BCC	NCHGCS
	SBC	#$20	;CONVERT TO UPPER CASE
NCHGCS	PHA		;SAVE IT
	CMP	#$9B
	BEQ	CHRXIT	;IF EOL, ECHO IT
	JSR	CHRPUT	;ELSE, ECHO IT
	LDA	#$9B	;FOLLOWED BY EOL
CHRXIT	JSR	CHRPUT
	PLA		;RESTORE FOR PROGRAM
	RTS		;THEN EXIT
KILLRD	JSR	CHRPUT	;MOVE TO NEXT LINE AND
	JMP	MENUSL	;EXIT WITHOUT RETURN TO COMMAND
;
XE424	ldx	#$70		;Get a character from the keyboard [Bob Puff]
	jsr	CLOS2		;Close IOCB $70
;
	jsr	SOPEN		;Open IOCB #$70 for keyboard input
	db	4
	db	OPEN
	dw	KDEV
;
	jsr	DOIO		;get a character
	db	$70		;IOCB $70
	dw	0		;Buffer length (0=return 1 byte in ACC)
	db	GETCHR
	dw	0		;Buffer address (unused)
	pha			;save the character for a sec.
;
	ldx	#$70
	jsr	CLOS2		;Close IOCB $70 again
;
	pla			;get character back
	rts			;that's all, folks!
;
KDEV	db	'K:',$9B	;Keyboard handler addr.
;
CLOSE7	jsr	DOIO	;close IOCB #7
	db	$70
	dw	0
	db	$0C
	dw	0
 rts 
;
; RAW SECTOR READ/WRITE FUNCTIONS
;
RSEC1	LDA	CSRC
RSEC2	CLC
;
SECTIO	STA	DUNIT
	LDX	SECSIZ+1
	INX
	STX	SECDAT
BOOT1	LDX	#3
	STX	RCNT
CLD1	LDX	SECDAT
	PHP
	JSR	DKIO2
	BPL	DRTS
	CMP	#$80
	BEQ	TOERR2
	PLP
	DEC	RCNT
	BPL	CLD1
	PHP
TOERR2	PLP
	JMP	CIOER1
;
DRTS	PLP
	RTS
;
;  BOOT SECTOR I/O ROUTINE (USED TO COPY DOS.SYS)
;
DOBOOT
	LDA	#HIGH[BOOTBUF-128]
	STA	DBUF+1
	LDA	#LOW[BOOTBUF-128]
	STA	DBUF		;INITIALIZE THE BUFFER ADDRESS
	LDA	#0		;START WITH SECTOR #1
	STA	DAUX
;
	JSR	BOOTIO
;
	JSR	BOOTIO		;2 CALLS, THEN FALL THROUGH (TRANSFER 3 SECTORS)
;
BOOTIO
	JSR	STEPBP
	INY
	STY	DAUX
	JMP	BOOT1		;JUMP ALWAYS!
;
; CHECK FOR 2-COLUMN DIRECTORY LIST
;
CLEARIT	LDX	CSRC
	LDA	ICMD,X
	CMP	#GETCHR
	BEQ	CLERXIT
	LDA	TEMPBUF+1
	CMP	#'0'
	BCS	EOFEXIT
	LDY	ILEN,X
	CPY	#20
	BCC	SHFNL
	DEC	ILEN,X
	LDY	#-24
SFTSIZ	LDA	TEMPBUF+39-256,Y
	STA	TEMPBUF+39-1-256,Y
	INY
	BNE	SFTSIZ
SHFNL	LDA	TOGGL
	EOR	#$BB
	STA	TOGGL
	STA	TEMPBUF+19
CLERXIT	RTS
;
EOFEXIT	LDA	#$9B
	CMP	TOGGL
	BEQ	CLERXIT
	DEC	IBUF,X
	INC	ILEN,X
	STA	TEMPBUF
	RTS
;
TOGGL	DB	$9B
;
; COPY ONE FILE (AS MANY MEMORY LOADS AS NEEDED)
;
COPYFL	LDX	CSRC
	LDA	ILEN,X
	ORA	ILEN+1,X
	BEQ	NOOUTP
	LDA	SWPFLG
	BPL	WRFILE
	LDA	#LOW[IDD]
	LDX	#HIGH[IDD]
	JSR	PRTMSG
	JSR	CHRGET
	LDX	CDES
	JSR	RESET
WRFILE	LDX	CDES
	BNE	DOWRFI
	JSR	CLEARIT
	LDX	#$00
DOWRFI	LDA	IOCB,X	;OPEN?
	BPL	PUTOUT	;YES, WRITE NEXT BLOCK
;
	LDX	OPT
	LDA	#8
	CPX	#'A'	;APPEND?
	BNE	DOPO1
	LDA	#9
DOPO1	LDX	CDES
	STA	IAUX,X
	JSR	ANYDEN	;OPEN THE OUTPUT FILE
	BMI	TOCIOR
;
PUTOUT	LDX	CDES
	LDY	CSRC
	LDA	ILEN,Y
	STA	ILEN,X
	LDA	ILEN+1,Y
	STA	ILEN+1,X
	LDA	IBUF,Y
	STA	IBUF,X
	LDA	IBUF+1,Y
	STA	IBUF+1,X
	LDA	#PUTCHR
	STA	ICMD,X
	JSR	CIOCL		;WRITE NEXT BLOCK OF DATA
NOOUTP	LDX	CSRC
	LDA	ISTAT,X		;EOF?
	CMP	#$88
	BEQ	CPYXIT
	LDA	SWPFLG
	BPL	RECOPY
	LDA	#LOW[ISD]
	LDX	#HIGH[ISD]
	JSR	PRTMSG
	JSR	CHRGET
	LDX	CSRC
	JSR	RESET
	JMP	RECOPY
;
COPYF	LDX	CSRC
	STA	ICMD,X
	LDA	#$9B
	STA	TOGGL
RECOPY	LDX	CSRC
	LDA	#0
	STA	TEMPBUF+22
	LDA	BUFAD
	LDY	BUFAD+1
	JSR	DEFBUF
	LDA	BUFLEN
	STA	ILEN,X
	LDA	BUFLEN+1
	STA	ILEN+1,X
	JSR	CIOV		;READ DIRECTORY DATA
	BPL	TOCPFL
	CPY	#$88		;END OF FILE?
	BNE	TOCIOR		;IF ERROR, ABORT
TOCPFL	JMP	COPYFL
TOCIOR	JMP	CIOER1
;
CPYXIT	LDX	CDES
	BEQ	NOTCL
	JSR	CLOS2
NOTCL	LDX	CSRC
	JMP	CLOS2
;
;  FIX UP DOS COPY OPERATION
;
DLKMSK	=	*-1
	DB	$03,$FF
DLKLOC	=	*-1
	DB	$7D,$FD
FIXUPDOS
	LDX	SECDAT		;STASH SECTOR SIZE INFO
	STX	SECDAT-$0700+BOOTBUF
	LDA	DLKLOC,X	;STASH LINK LOCATION IN THE SECTOR
	STX	DLINK-$0700+BOOTBUF
	LDY	#$14
NOTRITE	LDA	#$29		;AND COMMAND CODE
FNDAND	INY
	BMI	NOAND
	CMP	BOOTBUF-1,Y
	BNE	FNDAND
	LDA	BOOTBUF,Y
	CMP	#$03
	BEQ	ANDOK
	CMP	#$FF
	BNE	NOTRITE
ANDOK	LDA	DLKMSK,X	;STASH THE MASK FOR 10 BIT OR 16 BIT LINKS
	STA	BOOTBUF,Y
;
NOAND	SEC			;WRITE BOOT SECTORS
	JSR	DOBOOT		;DO BOOT I/O
;
	LDX	#$30		;USE THE DESTINATION IOCB ($30 IS ALWAYS OK)
	JSR	SOPEN		;IF COPYING DOS.SYS (REALLY 'DIAMOND'OS.SYS)
	DB	0		;AUX
	DB	DELETE		;CMD
	DW	DOSSYS		;FILENAME -- DELETE EXISTING DOS.SYS
;
	LDX	#$30		;USE THE DESTINATION IOCB ($30 IS ALWAYS OK)
	JSR	SOPEN
	DB	0
	DB	RENAME
	DW	DOSRNM		;MAKE NEW ONE
	RTS
;
;
;	SCAN DIRECTORY AND BUILD THE NEXT FILE NAME
;	EXIT WITH NOT-EQUAL IF AT END
;
SCNDIR	LDA	#LOW[DATA]
	LDY	#HIGH[DATA]
	JSR	DBUF10
	LDA	#GETREC
	STA	ICMD+$10
	LDA	#32
	STA	ILEN+$10
	LDA	#0
	STA	ILEN+1+$10
	STA	CBYTE		;ASSUME NOT A DIRECTORY
	JSR	CIOCL		;READ A FILE NAME
	LDA	DATA+1
	CMP	#':'
	BCS	NOTDIR
	CMP	#'0'
	BCS	SCNDX
NOTDIR	BEQ	GOTSPC
	LDA	DATA+10
	CMP	CBSAV
	BNE	NOTSYS
GOTSPC	DEC	CBYTE
NOTSYS	LDX	FNPT
	LDY	#2
;
MDN1	LDA	DATA,Y
	CMP	#' '
	BEQ	MDN2
	STA	PAR,X
	INX
	INY
	CPY	#10
	BCC	MDN1
;
MDN2	LDA	#'.'
	STA	PAR,X
	INX
	LDY	#10
MDN3	LDA	DATA,Y
	CMP	#' '
	BEQ	MDN4
	STA	PAR,X
	INY
	INX
	CPY	#13
	BCC	MDN3
MDN4	LDA	#'.'
	CMP	PAR-1,X
	BNE	MDN5
	DEX
MDN5	LDA	#0		;TERMINATE FILE NAME
	STA	PAR,X
	CLC
SCNDX	RTS
;
GETLIN	LDA	#LOW[DATA+3]
	STA	FNPTR
	STA	IBUF
	LDA	#HIGH[DATA+3]
	STA	FNPTR+1
	STA	IBUF+1
	LDA	#GETREC
	STA	ICMD
	LDX	#1
	STX	ILEN+1
	DEX
	STX	ILEN
	LDY	#0
	STY	PTR
;
CIOCL	JSR	CIOV
	TYA
	BMI	CIOER1
	RTS
CIOER1	STY	FR0
	LDA	#0
	STA	FR0+1
	JSR	IFP
	JSR	FASCII
	LDY	#0
	LDA	(INBUFF),Y
	STA	CIERC
	INY
	LDA	(INBUFF),Y
	STA	CIERC+1
	INY
	LDA	(INBUFF),Y
	AND	#$7F
	STA	CIERC+2
	JSR	ERRXIT
	DB	'Error -- '
CIERC	DB	'000',$9B,0
;
HEXDEF	LDY	DATA+3
	CPY	#$9B
	BNE	GETNO2
	RTS
;
GETNUM	CLC
	DB	$24	;SKIP SINGLE BYTE
;
GETNO2	SEC
	ROR	TEMP2
	JSR	NXTFLD
	STY	VECTOR
	STY	VECTOR+1
GETND	LDA	(FNPTR),Y
	INY
	CMP	#'F'+1	;IS IT A DIGIT
	BCS	GETNDE
	SBC	#'0'-1	;NOTE THAT CY=0
	BCC	GETND1
	CMP	#10	;0-9?
	BIT	TEMP2
	BPL	GOT10
	BCC	GOT1	;YES, SHIFT INTO NUMBER
	CMP	#17	;A-F?
	BCS	GOT16	;YES, HANDLE IT
GETND1	SEC
	ADC	#'0'-1
GETNDE	STY	PTR
	TAY
	LDA	VECTOR
	LDX	VECTOR+1
	RTS
;
GOT10	BCS	GETND1
	PHA
	ASL	VECTOR
	ROL	VECTOR+1
	LDA	VECTOR
	LDX	VECTOR+1
	ASL	VECTOR
	ROL	VECTOR+1
	ASL	VECTOR
	ROL	VECTOR+1
	CLC
	ADC	VECTOR
	STA	VECTOR
	PLA
	PHP
	CLC			;[Bob Puff]
	ADC	VECTOR
	STA	VECTOR
	TXA
	ADC	VECTOR+1
	PLP
	ADC	#0
	STA	VECTOR+1
	JMP	GETND
;
GOT16	SBC	#7
GOT1	ASL	VECTOR
	ROL	VECTOR+1
	ASL	VECTOR
	ROL	VECTOR+1
	ASL	VECTOR
	ROL	VECTOR+1
	ASL	VECTOR
	ROL	VECTOR+1
	ORA	VECTOR
	STA	VECTOR
	JMP	GETND
;
; GETFN -- READ A LINE, GET FILENAME FROM IT
;
GETFN	LDA	#0
	STA	DOSRNM+1
	JSR	GETLIN
	BEQ	WCTSTL
;
; GETFN2 -- EXTRACT A FILENAME FROM A LINE ALREADY READ IN
;           X IS THE OFFSET IN THE BUFFER
;
GETFN2	JSR	NXTFLD
WCTSTL	LDA	(FNPTR),Y
	INY
	CMP	#'?'
	BEQ	SETWC	;IF ? OR * FOUND,
	CMP	#'*'
	BNE	CKEOFN	;SET FLAG, FIND FIRST MATCH
SETWC	LDA	#0
	STA	CPYTYP
	BEQ	WCTSTL
;
CKEOFN	CMP	#$9B	;IF EOL, CONTINUE WIT SINGLE FILE
	BEQ	FNSET
	CMP	#'.'
	BEQ	WCTSTL
	CMP	#'/'
	BCC	FNSET
	BNE	WCTSTL
SLSHLP	LDA	(FNPTR),Y
	CMP	#'S'
	BNE	NCPSYS
	STA	CBSAV
	BEQ	SAVED
NCPSYS	CMP	#'X'
	BNE	NOTSWP
	LDA	#$80
	STA	SWPFLG
	BMI	SAVED
NOTSWP	STA	OPT	;SAVE OPTION CODE
SAVED	DEY
	LDA	#0
	STA	(FNPTR),Y
	INY
	INY
	LDA	(FNPTR),Y
	INY
	CMP	#'/'
	BEQ	SLSHLP
	CMP	#'.'
	BCC	FNSET
	CMP	#$9B
	BEQ	FNSET
	DEY
;
FNSET	STY	PTR	;SAVE POINTER TO SECOND ARG.
	DEY
	LDA	(FNPTR),Y
	STA	DELIM
	LDA	#0
	STA	(FNPTR),Y
	TAY
	LDA	(FNPTR),Y
	CMP	#'0'
	BCC	DEFDRV
	CMP	#':'
	BEQ	DEFDRV
	INY
	BCS	LKFCOL
	TAX
	LDA	#':'
	CMP	(FNPTR),Y
	BEQ	DBEFOR
	DEY
	STA	(FNPTR),Y
	TXA
	BNE	DGTCOD
;
LKFCOL	LDA	(FNPTR),Y ;SCAN FOR DRIVE ID
	BEQ	DEFDRV
	CMP	#':'
	BEQ	DEVINC	;DEVICE INCLUDED
	INY
	LDA	(FNPTR),Y
	CMP	#':'
	BEQ	DEVINC
;
DEFDRV	LDA	#':'
DGTCOD	JSR	DECFNP
DBEFOR	LDA	#'D'
	JSR	DECFNP
DEVINC	LDY	FNPTR
	LDA	FNPTR+1
	RTS
;
NXTFLD	CLC
	LDA	PTR	;MOVE INDEX TO A
	ADC	FNPTR
	STA	FNPTR
	LDA	#0
	TAY
	ADC	FNPTR+1
	STA	FNPTR+1
	RTS
;
DECFNP	LDY	FNPTR
	BNE	DECFP1
	DEC	FNPTR+1
DECFP1	DEC	FNPTR
	INC	PTR
	LDY	#0
	STA	(FNPTR),Y
GETDN1	RTS
;
;	REQUIRE A DISK DRIVE (NO FILE SPECIFICATION)
;
GETDN2	JSR	GETFN2	;GET NEXT FILE NAME
	JMP	GETDNE	;THEN CHECK FOR DRIVE ONLY
GETDN	JSR	GETFN
GETDNE	STY	IBUF+$10
	STA	IBUF+1+$10
	LDY	#$FF
GETDNL	INY
	TAX
	LDA	(FNPTR),Y
	BNE	GETDNL
	CPX	#':'	;ANY FILE NAME INCLUDED?
	BEQ	GETDN1	;NO, THEN RETURN
	JSR	ERRXIT
	DB	'File name not allowed!',$9B,0
;
; UPDATE DENSITY OF DISK IN DRIVE
;
GETDEN	CMP	#':'
	BNE	GTDEN2
	LDA	DFUNIT
GTDEN2	AND	#$0F	;MAKE UNIT BINARY
	LDX	#0
	STX	DAUX+1
	INX
	STX	DAUX
	LDX	#LOW[TEMPBUF]
	STX	DBUF
	LDX	#HIGH[TEMPBUF]
	STX	DBUF+1
	JSR	RSEC2
	BMI	GETDN3
	JMP	RDCONF
;
;	REQUIRE A DISK FILE NAME, SAVING THE POINTER IN IOCB10
;
CKDSK	STY	IBUF+$10
	STA	IBUF+1+$10
	LDY	#0
	LDA	(FNPTR),Y
	CMP	#'D'
	BEQ	GETDN3
	JSR	ERRXIT
	DB	'Not a disk file!',$9B,0
;
; WAIT FOR SOURCE DISK
;
CWFSD	LDA	SWPFLG
	BMI	WFSD
GETDN3	RTS		;IF NO WAIT REQUIRED
WFSD	JSR	PRINT
ISD	DB	'Insert SOURCE disk, press '
	DC	'R','E','T','U','R','N'
	DB	0
	JSR	CHRGET
	BIT	SWPFLG
	BVS	GETDN3	;IF IN DUP-DISK
	LDX	CSRC
;
RESET	LDY	IOCB+1,X
	STY	UNNO
	LDA	IAUX+5,X
	BEQ	NOCHG
	CMP	#3
	BCS	NOCHG
SETDEN	STA	DKTYPE-1,Y
	LDX	#15
SAVMAP	LDA	MAPBUF,X
	STA	SAXMAP,X
	DEX
	BPL	SAVMAP
	JSR	DOFSIN
	LDX	#15
RSTMAP	LDA	SAXMAP,X
	STA	MAPBUF,X
	DEX
	BPL	RSTMAP
;
NOCHG	RTS
;
SAXMAP	DB	0,0,0,0,0,0,0,0
	DB	0,0,0,0,0,0,0,0
;
;  RECONFIGURE DENSITY OR CONFIGURATION
;
DOFSIN	LDX	#9
DOFLOP	LDA	WOTDCB,X
	STA	DUNIT+1,X
	DEX
	BPL	DOFLOP
	LDX	#$31
	STX	DUNIT-1
	LDX	UNNO
	STX	DUNIT		;TELL SIO DRIVE TO CONFIGURE
	LDY	DKTYPE-1,X	;GET DENSITY/SECTOR SIZE
	LDA	DRVDEF-1,X	;GET DRIVE SPECIFICATION
	JMP	CONFIGR		;GO CONFIGURE DRIVE
;
;	SET UP PAR AND IOCB10 FOR A DIRECTORY SCAN (MULTI-FILE ACTIVITY)
;
SETSCN	STA	ICMD+$20
	LDA	#LOW[PAR]
	LDX	#HIGH[PAR]
	STA	IBUF+$20
	STX	IBUF+1+$20
	JSR	SETPTR
	LDX	#$10	;OPEN IOCB10 AS DIRECTORY
;
OPDIR	LDA	#6	;OPEN IOCB AS DIRECTORY
	STA	IAUX,X
;
; OPEN A FILE INDEPENDENT OF DRIVE DENSITY
;
ANYDEN	LDA	#0
	STA	IAUX+1,X
	STA	IAUX+5,X
	LDA	#OPEN
	JSR	SCMD
	BPL	SAVDEN
	JMP	CIOER1
;
SAVDEN	LDY	DUNIT
	LDA	DKTYPE-1,Y
	STA	IAUX+5,X
	RTS
;
; SET UP 'PAR' FOR A WILD CARD COPY
;
DEFPAR	JSR	SETPTR
	LDA	(FNPTR),Y
	BNE	DEFPX
	STA	CPYTYP
	STA	PAR+2,Y
	LDA	#'*'
	STA	PAR,Y
	STA	PAR+1,Y
	lda	#$9B		;termination!!!
	sta	PAR+2,Y		;[Bob Puff]
DEFPX	RTS
;
SETPTR	LDY	#$FF
SETLP1	INY
	LDA	(FNPTR),Y
	STA	PAR,Y
	BNE	SETLP1
SETLP2	DEY
	LDA	PAR,Y
	cmp	#'>'		;account for sparta type
	beq	SETLP3		;[Bob Puff]
	CMP	#':'
	BNE	SETLP2
SETLP3	INY
	STY	FNPT
	RTS
;
; REPORT ERROR, THEN RETURN TO MENU
;
ERRXIT	PLA
	STA	RAMLO
	PLA
	STA	RAMLO+1
	JSR	PRTENT	;WRITE ERROR MESSAGE FOLLOWING 'JSR ERRXIT'
	JMP	MENUSL	;THEN RETURN TO MENU
;
DOSRNM	DB	'D',0,':',$60,'OS.SYS,'
CKDTST	DB	'DOS.SYS',0
