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: