FCB	EQU	5CH
DSKRESET EQU	13
SETBASE	EQU	38
SRCHFRST EQU	17
SRCHNXT	EQU	18
RENAM	EQU	23
INCHAR	EQU	1
GETFAT	EQU	27
OPEN	EQU	15
CLOSE	EQU	16
MAKE	EQU	22
DELETE	EQU	19
RDBLK	EQU	39
WRBLK	EQU	40
SETDMA	EQU	26
SELDRV	EQU	14
GETDRV	EQU	25
PRINTBUF EQU	9
OUTCH	EQU	2
INBUF	EQU	10
RR	EQU	33
SYSTEM	EQU	5

	ORG	100H
	PUT	100H

	MOV	SP,STACK
	CLD
	MOV	DL,0		;Start with A:
SETDRV:
	MOV	CL,SELDRV
	CALL	SYSTEM
COMMAND:
	MOV	SP,STACK
	CLD
	MOV	AX,CS
	MOV	SS,AX
	MOV	ES,AX
	MOV	DS,AX
	MOV	CX,[6]
	SUB	CX,TPA
	AND	CL,80H		;Round down
	ROL	CX
	XCHG	CH,CL
	MOV	[NUMREC],CX	;Number of records each time
	MOV	DX,CRLF
	MOV	CL,PRINTBUF
	CALL	SYSTEM
	MOV	DX,COMMAND
	MOV	AX,2522H	;Set vector 34 (terminate)
	INT	33
	MOV	AX,2523H	;Set vector 35 (CTRL-C)
	INT	33
GETCOM:
	MOV	CL,GETDRV
	CALL	SYSTEM
	ADD	AL,"A"
	MOV	CL,OUTCH
	MOV	DL,AL
	CALL	SYSTEM		;Print drive letter
	MOV	DL,":"
	MOV	CL,OUTCH
	CALL	SYSTEM		;Print :
	MOV	DX,LINBUF
	MOV	CL,INBUF
	CALL	SYSTEM
	MOV	DL,10
	MOV	CL,OUTCH
	CALL	SYSTEM		;New line
	MOV	CH,0
	MOV	SI,FILIFO	;8 spaces
	MOV	DI,ID
	CALL	FILLBUF
	MOV	DI,FCB
	CALL	FILLBUF
	MOV	SI,LINBUF+2
	MOV	DI,ID
	CALL	FILEDRV		;Get COM drive
	MOV	[SPECDRV],AL
	MOV	CX,8
	CALL	COPYNAM		;Copy file name
	MOV	AL,9
	SUB	AL,CL
	MOV	[IDLEN],AL
	MOV	DI,81H
	MOV	CX,0
	PUSH	SI
COMTAIL:
	LODB
	STOB		;Move command tail to 80H
	CMP	AL,13
	LOOPNZ	COMTAIL
	NOT	CL
	MOV	[80H],CL
	POP	SI
	MOV	DI,FCB
	CALL	PARSENAM
	MOV	DI,FCB+10H
	CALL	PARSENAM
	MOV	AL,[IDLEN]
	MOV	DL,[SPECDRV]
	OR	DL,DL		;Check if drive was specified
	JNZ	DRVCHK
	DEC	AL		;Check for null command
	JZ	GETCOM
	MOV	SI,COMTAB
FINDCOM:
	MOV	DI,IDLEN
	MOV	CL,[SI]
	JCXZ	EXTERNAL
	REPE
	CMPB
	LAHF
	ADD	SI,CX		;Bump to next position without affecting flags
	SAHF
	LODW		;Get address of command
	JNZ	FINDCOM
	CALL	AX	;Call command
	JMP	COMMAND
SETDRV1:
	JMP	SETDRV
DRVCHK:
	DEC	DL		;Adjust for correct drive number
	DEC	AL		;Check if anything else is on line
	JZ	SETDRV1
EXTERNAL:
	MOV	AL,[SPECDRV]
	MOV	[IDLEN],AL
	PUSH	DS
	MOV	DX,TPA
	ADD	DX,0FH		;Round to next paragraph
	SHR	DX
	SHR	DX
	SHR	DX
	SHR	DX		;Divide 16
	MOV	CX,CS
	ADD	DX,CX		;New segment
	MOV	DS,DX
	MOV	AH,SETBASE
	INT	33
	MOV	DX,100H
	MOV	CL,SETDMA
	CALL	SYSTEM
	MOV	BX,DS		;New segment into BX
	POP	DS
	MOV	DX,IDLEN
	MOV	AH,OPEN
	INT	33
	OR	AL,AL
	JNZ	BADCOM
	MOV	[IDLEN+RR],0
	MOV	CX,512		;512 records
	MOV	AH,RDBLK
	INT	33
	MOV	DS,BX
	MOV	ES,BX
	MOV	SS,BX
	MOV	SP,40H
	MOV	AX,0
	PUSH	AX
	MOV	AX,100H
	PUSH	BX
	PUSH	AX
	MOV	CL,SETDMA
	MOV	DX,80H
	CALL	SYSTEM
	RET	L
BADCOM:
	MOV	DX,BADNAM
	MOV	CL,PRINTBUF
	CALL	SYSTEM
	JMP	COMMAND

NEXTCHR:
;Convert lower case input to upper case
	LODB
	CMP	AL,"a"-1
	JB	DELIM
	CMP	AL,"z"
	JA	DELIM
	SUB	AL,20H		;Lower-case changed to upper-case
DELIM:
	CMP	AL," "
	JZ	RET
	CMP	AL,"="
	JZ	RET
	CMP	AL,","
	JZ	RET
	CMP	AL,";"
	JZ	RET
	CMP	AL,9		;Check for TAB character
	RET

FILEDRV:
	CALL	NEXTCHR
	JZ	FILEDRV		;Skip delim
	CMP	AL,13
	JZ	NOMATCH
	CMP	B,[SI],":"
	JNZ	NOMATCH
	SUB	AL,40H		;A => 1, B => 2
	INC	SI
	RET

PARSENAM:
	CALL	NEXTCHR
	JZ	ISDELIM
	CMP	AL,13
	JNZ	PARSENAM
	DEC	SI
ISDELIM:
	CALL	FILEDRV
	STOB
	MOV	CX,11
	CALL	COPYNAM
	ADD	DI,CX
	CMP	CX,3
	JB	RET
	SUB	DI,3
	CMP	AL,"."
	JNZ	NOMATCH
	MOV	CX,3
COPYNAM:
	CALL	NEXTCHR
	JZ	NOMATCH
	CMP	AL,13
	JZ	NOMATCH
	CMP	AL,"."
	JZ	RET
	STOB
	LOOP	COPYNAM
NOMATCH:
	XOR	AL,AL
	DEC	SI
	RET

FILLBUF:
	LODB
	MOV	CL,AL
	JCXZ	RET
	LODB
	REP
	STOB
	JP	FILLBUF

DIR:
	CMP	B,[FCB+1]," "
	JNZ	HASNAME
	MOV	SI,FCBFIL
	MOV	DI,FCB+1
	CALL	FILLBUF		;Fill 11 bytes with "?"
HASNAME:
	MOV	DX,LINBUF+2+1
	MOV	CL,SETDMA
	CALL	SYSTEM
	MOV	CL,SRCHFRST
	MOV	DX,FCB
EACHFILE:
	CALL	SYSTEM
	INC	AL		;FF = file not found
	JZ	RET
	MOV	SI,LINBUF+2+1
	MOV	CX,8
	CALL	OUTCNT		;Print 8 chars (name)
	MOV	CL,OUTCH
	MOV	DL," "
	CALL	SYSTEM		;Print space
	MOV	SI,LINBUF+2+9
	MOV	CX,3
	CALL	OUTCNT		;Print 3 chars (ext)
	MOV	DX,CRLF
	MOV	CL,PRINTBUF
	CALL	SYSTEM		;Print new line
	MOV	CL,SRCHNXT
	JP	EACHFILE
OUTCNT:
	LODB
	PUSH	CX
	PUSH	SI
	MOV	DL,AL
	MOV	CL,OUTCH
	CALL	SYSTEM
	POP	SI
	POP	CX
	LOOP	OUTCNT
	RET

RENAME:
	MOV	CL,RENAM
	MOV	DX,FCB
	JMP	5

ERASE:
	MOV	CL,DELETE
	MOV	DX,FCB
	JMP	5

CREATE:
	MOV	CL,MAKE
	MOV	DX,FCB
	JMP	5

TYPE:
	MOV	DX,TPA
	MOV	CL,SETDMA
	CALL	SYSTEM
	MOV	DX,FCB
	MOV	AH,OPEN
	INT	33
	OR	AL,AL
	JNZ	RET		; Not found
	MOV	[FCB+RR],0
	MOV	CX,512
	MOV	AH,RDBLK
	INT	33
	MOV	SI,TPA
OUTLP:
	LODB
	CMP	AL,1AH		;Is EOF?
	JZ	RET
	MOV	CL,OUTCH
	MOV	DL,AL
	CALL	SYSTEM
	JP	OUTLP
	RET

CLEAR:
	MOV	DX,ERAMES
	MOV	CL,PRINTBUF
	CALL	SYSTEM		;Confirm erase
	MOV	CL,INCHAR
	CALL	SYSTEM
	CMP	AL,"Y"
	JZ	DOCLEAR
	CMP	AL,"y"
	JZ	DOCLEAR
	RET
DOCLEAR:
	MOV	DL,[FCB]
	OR	DL,DL
	JZ	CLRDSK
	DEC	DL
	MOV	CL,SELDRV
	CALL	SYSTEM
CLRDSK:
	MOV	CL,GETFAT
	CALL	SYSTEM
	MOV	CX,DX
	INC	DX
	SHR	DX
	ADD	CX,DX
	MOV	AX,DS
	MOV	ES,AX
	MOV	DI,BX
	MOV	AX,0FFFFH
	STOW
	STOB		;Fill first 3 bytes with FF
	INC	AX	;AX = 0
	SHR	CX
	JNC	DOFILL
	STOB		;Odd byte
DOFILL:
	REP
	STOW
	MOV	AX,CS
	MOV	DS,AX
	MOV	ES,AX
	MOV	SI,FCBFIL
	MOV	DI,FCB+1
	CALL	FILLBUF
	MOV	DX,FCB
	MOV	CL,DELETE
	CALL	SYSTEM		;Delete all files
	MOV	CL,DSKRESET
	JMP	5

COPY:
	MOV	SI,FCB+10H
	MOV	DI,DSTFCB
	MOVB
	CMP	B,[SI]," "		;Has file name?
	JNZ	HASDSTNAM
	MOV	SI,FCB+1
HASDSTNAM:
	MOVB
	MOV	CX,7
	REP
	MOVW
	MOV	DX,FCB
	MOV	AH,OPEN
	INT	33
	OR	AL,AL
	JNZ	NOSRC
	MOV	DX,DSTFCB
	MOV	AH,DELETE
	INT	33
	MOV	AH,MAKE
	INT	33
	MOV	DX,TPA
	MOV	AH,SETDMA
	INT	33
	MOV	[FCB+RR],0
	MOV	[DSTFCB+RR],0
CPYBLK:
	MOV	DX,FCB
	MOV	CX,[NUMREC]
	MOV	AH,RDBLK
	INT	33
	JCXZ	CPYDONE
	MOV	DX,DSTFCB
	MOV	AH,WRBLK
	INT	33
	OR	AL,AL
	JZ	CPYBLK
	MOV	DX,NOSPCE
	MOV	AH,PRINTBUF
	INT	33
CPYDONE:
	MOV	DX,DSTFCB
	MOV	AH,CLOSE
	INT	33
	RET
NOSRC:
	MOV	DX,NOTFND
	MOV	AH,PRINTBUF
	INT	33
	RET

	DS	40
STACK:

BADNAM:	DB	"Bad command or file name"
CRLF:	DB	13,10,"$"
ERAMES:	DB	"Erase all files (Y/N)? $"
NOTFND:	DB	"Source file not found$"
NOSPCE:	DB	"Insufficient disk space$"

FCBFIL:	DB	11,"?"
	DB	0

SPECDRV: DS	1
NUMREC:	DS	2

IDLEN:	DS	1
ID:	DS	8
COM:	DB	"COM"
DSTFCB:	DS	36

LINBUF:	DB	80H,1,13
	DS	80H

FILIFO:	DB	8," "
	DB	0
	DB	12," ",4,0
	DB	12," ",8,0
	DB	0

COMTAB:	DB	4,"DIR"
	DW	DIR
	DB	7,"RENAME"
	DW	RENAME
	DB	6,"ERASE"
	DW	ERASE
	DB	7,"CREATE"
	DW	CREATE
	DB	5,"TYPE"
	DW	TYPE
	DB	6,"CLEAR"
	DW	CLEAR
	DB	5,"COPY"
	DW	COPY
	DB	0

TPA:
