Original source code used .A86 but I named them .ASM for GitHub to provide syntax highlighting. Now I've decided that it's better to keep the names original.
475 lines
6.5 KiB
Plaintext
475 lines
6.5 KiB
Plaintext
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:
|
|
|