; ; FILES.A86 ; ;Disk file routines for MODEM9.xx. ; ; ;Multi-file access subroutine. Allows processing of multiple files ;(i.e., *.ASM) from disk. This routine builds the proper name in the ;FCB each time it is called. This command would be used in such pro- ;grams such as modem transfer, tape save, etc. in which you want to ;process single or multiple files. ; ;The FCB will be set up with the next name, ready to do normal proces- ;sing (OPEN, READ, etc.) when routine is called. ; ;Carry is set if no more names can be found ; MFNAME: ;INIT DMA ADDR, FCB MOV CL,STDMA MOV DX,OFFSET 80H INT 224 MOV byte ptr .FCBEXT,0 TEST MFFLG1,0FFH JNZ MFN01 ;IF FIRST TIME MOV MFFLG1,1 ;TURN OFF 1ST TIME SW MOV BX,OFFSET FCB ;SAVE THE REQUESTED NAME MOV DX,OFFSET MFREQ MOV CX,OFFSET 12 CALL MOVER MOV AL,BYTE PTR .FCB MOV MFCUR,AL ;SAVE DISK IN CURRENT FCB MOV BX,OFFSET MFREQ ;SRCHF REQ NAME MOV DX,OFFSET FCB MOV CX,OFFSET 12 CALL MOVER PUSH CX PUSH DX PUSH BX MOV CL,SRCHF MOV DX,OFFSET FCB INT 224 POP BX POP DX POP CX JMP MFN02 ; MFN01: MOV BX,OFFSET MFCUR ;SRCHF CURR NAME MOV DX,OFFSET FCB MOV CX,OFFSET 12 CALL MOVER MOV CL,SRCHF MOV DX,OFFSET FCB INT 224 MOV BX,OFFSET MFREQ ;SRCHN REQ NAME MOV DX,OFFSET FCB MOV CX,OFFSET 12 CALL MOVER MOV CL,SRCHN MOV DX,OFFSET FCB INT 224 MFN02: INC AL ;RETURN CARRY IF NOT FOUND STC JNZ MFFIX1 MOV MFFLG1,AL RET ; MFFIX1: DEC AL ;MOVE NAME FOUND TO CURR AND AL,3 ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,81H MOV BL,AL MOV BH,0 PUSH BX ;SAVE NAME POINTER MOV DX,OFFSET MFCUR+1 MOV CX,OFFSET 11 CALL MOVER POP BX ;MOVE NAME FOUND TO FCB MOV DX,OFFSET FCB+1 MOV CX,OFFSET 11 CALL MOVER XOR AL,AL ;SETUP FCB MOV BYTE PTR .FCBEXT,AL MOV BYTE PTR .FCBRNO,AL RET ; ; Move subroutine ; MOVER: MOV AL,BYTE PTR [BX] XCHG BX,DX MOV BYTE PTR [BX],AL XCHG BX,DX INC BX INC DX DEC CX JNZ MOVER RET ; ;Lists directory and gives free space remaining on the requested drive. ; DIRLST: MOV DX,OFFSET CMDBUF ;PUT COMMAND LINE IN FCB MOV BX,OFFSET 5CH CALL CPMLINE MOV BX,OFFSET SRCHFCB CALL INITFCBS MOV AL,BYTE PTR .6CH ;GET DRIVE # MOV SRCHFCB,AL MOV AL,BYTE PTR .6DH CMP AL,20H ;IF BLANK GET ALL NAMES PUSH AX JNZ DIRLST1 CALL QSTMARK DIRLST1: POP AX JZ DIRLST2 CALL MOVENAME ;ELSE MOVE NAME INTO FCB DIRLST2: MOV DX,OFFSET 80H MOV CL,STDMA INT 224 MOV NAMEGD,0 MOV AL,NOOFCOL ;GET NUMBER OF COLUMNS MOV NAMECT,AL ;STORE TO CALCULATE CRLF POSITION MOV DX,OFFSET SRCHFCB MOV CL,SRCHF ;DO FIRST SEARCH INT 224 CMP AL,0FFH JZ NOFILE PUSH AX DIRLP: POP AX CALL GETADD ADD BX,15 ;OFFSET FOR RECORD COUNT MOV AL,BYTE PTR [BX] OR AL,AL JZ NEXTSR ;NO LIST IF FILE IS ZERO LENGTH ADD BX,-5 ;POINT TO $SYS ATTRIB BYTE MOV AL,BYTE PTR [BX] AND AL,80H JNZ NEXTSR ;NO LIST IF $SYS FILE ADD BX,-10 ;POINT TO BEGINNING OF NAME INC BX ;POINT TO FIRST LETTER MOV DX,OFFSET PRNTNAME MOV CH,8 CALL MOVE INC DX MOV CH,3 CALL MOVE CALL ILPRT PRNTNAME: DB ' ','.',' ',' ', 0 ;8 SPACES, PERIOD, 3 SPACES, 1 SPACE MOV NAMEGD,0FFH NEXTSR: MOV DX,OFFSET SRCHFCB MOV CL,SRCHN ;DO NEXT SEARCH INT 224 CMP AL,0FFH JZ DIRDONE PUSH AX TEST NAMEGD,0FFH JZ DIRLP DEC NAMECT JNZ NEXTSR1 CALL NEWCT JMPS NEXTSR2 NEXTSR1: CALL FENCE NEXTSR2: MOV NAMEGD,0 JMP DIRLP ; NOFILE: CALL ILPRT DB 'NO FILE',0 ; ; Determines free space remaining ; DIRDONE: MOV AL,SRCHFCB OR AL,AL JZ DEFLT DEC AL MOV DL,AL MOV CL,SELDSK INT 224 DEFLT: MOV CL,GETPARM ;CURRENT DISK PARAMETER BLOACK INT 224 ADD BX,2 MOV AL,ES: BYTE PTR [BX] ;GET BLOCK SHIFT FACTOR MOV BSHIFTF,AL INC BX ;BUMP TO BLOCK MASK MOV AL,ES: BYTE PTR [BX] ;GET IT MOV BMASK,AL ADD BX,2 MOV DX,ES: WORD PTR [BX] ; GET MAX BLOCK NUMBER ; MOV DL,ES: BYTE PTR [BX] ;GET MAX BLOCK NUMBER ; INC BX ; MOV DH,ES: BYTE PTR [BX] ; XCHG BX,DX MOV BMAX,DX ;PUT IT AWAY MOV CL,GETALC ;ADDRESS OF CP/M ALLOCATION VECTOR INT 224 XCHG BX,DX ;GET ITS LENGTH MOV BX,BMAX INC BX MOV CX,0 ;INITIALIZE BLOCK COUNT TO ZERO GSPBYT: PUSH DX ;SAVE ALLOCATION ADDRESS XCHG BX,DX MOV AL,ES: BYTE PTR [BX] XCHG BX,DX MOV DL,8 ;SET TO PROCESS 8 BLOCKS GSPLUP: RCL AL,1 ;TEST BIT JC NOTFRE INC CX NOTFRE: MOV DH,AL ;SAVE BITS DEC BX MOV AL,BL OR AL,BH JZ ENDALC ;QUIT IF OUT OF BLOCKS MOV AL,DH ;RESTORE BITS DEC DL ;COUNT DOWN 8 BITS JNZ GSPLUP ;DO ANOTHER BIT POP DX ;BUMP TO NEXT COUNT OF ALLOCATION VECTOR INC DX JMP GSPBYT ;PROCESS IT ; ENDALC: POP DX ;CLEAR ALLOCATION VECTOR FROM STACK MOV BX,CX ; COPY TO BX MOV AL,BSHIFTF ;GET BLOCK SHIFT FACTOR SUB AL,3 ;CONVERT FROM RECORDS TO THOUSANDS JZ PRTFREE ;SKIP SHIFTS IF 1K BLOCKS FREKLP: ADD BX,BX ;MULTIPLY BLOCKS BY 'K PER BLOCK' DEC AL JNZ FREKLP PRTFREE: PUSH BX CALL ILPRT DB CR,LF,'Drive ',0 MOV AL,SRCHFCB ;IF NO DRIVE, GET OR AL,AL ;LOGGED IN DRIVE JNZ PRNTHD MOV CL,CURDSK INT 224 INC AL PRNTHD: ADD AL,'A'-1 MOV DRNAME,AL CALL ILPRT DRNAME DB ' has ',0 POP BX ;GET NUMBER OF BYTES AVAILABLE CALL DECOUT CALL ILPRT DB 'K bytes free',CR,LF,0 RET ; ; Subroutines ; FENCE: CALL ILPRT DB '| ',0 RET ; NEWCT: CALL CRLF MOV AL,NOOFCOL MOV NAMECT,AL RET ; QSTMARK: MOV AL,'?' ;IF BLANK IN FCB, PUT IN 11 ?'s MOV CH,11 MOV BX,OFFSET SRCHFCB+1 QSTLP: MOV BYTE PTR [BX],AL INC BX DEC CH JNZ QSTLP RET ; MOVENAME: MOV BX,OFFSET 6DH MOV DX,OFFSET SRCHFCB+1 MOV CH,11 CALL MOVE ;MOVE IN MAIN PROGRAM RET ; GETADD: AND AL,03H ;GET MOD4 FOR CP/M 1.4 ADD AL,AL ;ADD 32 ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL MOV DL,AL MOV DH,0 MOV BX,OFFSET 80H ;ADD DMA OFFSET ADD BX,DX RET ; ;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'. ; CKCPM2: MOV CL,STDMA MOV DX,OFFSET 80H INT 224 MOV CL,SRCHF ;SEARCH FOR FILE MOV DX,OFFSET FCB INT 224 CMP AL,0FFH JNZ CKCPM2A RET CKCPM2A: ADD AL,AL ADD AL,AL ;MULT A-REG BY.. ADD AL,AL ADD AL,AL ;..32 TO FIND.. ADD AL,AL ;..NAME IN DMA. MOV BX,OFFSET 80H ADD AL,BL MOV BL,AL ;HL POINTS TO DIR NAME MOV DX,OFFSET 9 ADD BX,DX ;POINT TO R/O ATTRIB BYTE MOV AL,BYTE PTR [BX] AND AL,80H ;TEST MSB JNZ MKCHG ;IF SET, MAKE CHANGE INC BX ;CHECK SYSTEM ATTRIB BYTE MOV AL,BYTE PTR [BX] AND AL,80H JNZ CKCPM2B ; IS $SYS OR $R/O RET CKCPM2B: DEC BX MKCHG: MOV DX, -8 ADD BX,DX ;POINT HL TO FILENAME + 1 MOV DX,OFFSET FCB+1 ;MOVE DIR NAME TO FCB.. MOV CH,11 ;..WITHOUT CHANGING DRIVE. CALL MOVE MOV BX,OFFSET FCB+9 ;R/O ATTRIB AND BYTE PTR [BX],07FH ; STRIP R/O ATTRIB INC BX AND BYTE PTR [BX],07FH ; STRIP SYS ATTRIB MOV DX,OFFSET FCB MOV CL,30 ;SET NEW ATTRIBS IN DIR INT 224 ; ;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE ; PLANCHG: MOV BX,OFFSET FCB ;CHANGE NAME TO TYPE "BAK" MOV DX,OFFSET 6CH MOV CH,9 ;MOVE DRIVE AND NAME (NOT TYPE) CALL MOVE MOV BX,OFFSET 75H ;START OF TYPE IN FCB2 MOV BYTE PTR [BX],'B' INC BX MOV BYTE PTR [BX],'A' INC BX MOV BYTE PTR [BX],'K' MOV DX,OFFSET 6CH MOV CL,ERASE ;ERASE ANY PREV BACKUPS INT 224 MOV BX,OFFSET 6CH ;FCB2 DR FIELD SHOULD.. MOV BYTE PTR [BX],0 ;..0 FOR RENAME. MOV DX,OFFSET FCB MOV CL,23 ;RENAME INT 224 RET ; CKBAKUP: MOV AL,BAKUPBYTE OR AL,AL JZ CKBAKUPR MOV CL,SRCHF MOV DX,OFFSET FCB INT 224 INC AL JZ CKBAKUPR JMP PLANCHG ;IN "CKCPM2" - RET DONE THERE CKBAKUPR: RET ; ERASFIL: MOV BX,OFFSET FCB ;CHECK FOR WILD CARDS MOV CH,11 ERASFIL1: INC BX MOV AL,BYTE PTR [BX] CMP AL,'?' ;IS IT A WILD CARD? JZ WILDERR ;GO IF SO DEC CH JNZ ERASFIL1 MOV AL,BATCHFLG ;DON'T ASK FOR ERASE.. OR AL,AL ;..IN MULTI-FILE MODE,.. JZ NOASK ;..JUST DO IT. MOV DX,OFFSET FCB MOV CL,SRCHF INT 224 INC AL JZ CKBAKUPR CALL ILPRT DB 'File exists -- Type ''Y'' to erase: ',BELL,0 CALL KEYIN PUSH AX CALL TIPE POP AX CALL UCASE CMP AL,'Y' JZ ERASEIT JMP MENU ERASEIT: CALL CRLF NOASK: MOV DX,OFFSET FCB MOV CL,ERASE INT 224 RET ; WILDERR: POP BX ;RESTORE STACK CALL ILPRT DB '++ No ambiguous file names allowed ++',CR,LF,BELL,0 JMP MENU ; BLKFILE: CALL ILPRT ;ROUTINE IF NO FILE IS NAMED FOR "SEND" OR "RECEIVE" DB CR,LF,'No file specified',CR,LF,BELL,0 JMP MENU MAKEFIL: MOV DX,OFFSET FCB MOV CL,MAKE INT 224 INC AL JZ MAKEFIL1 RET MAKEFIL1: CALL ERXIT DB 'Error - Can''t make file',CR,LF DB 'Directory is likely full',CR,LF,'$' ; CNREC: MOV CL,FILSIZ ;COMPUTE FILE SIZE FUNCTION IN CP/M 2.x MOV DX,OFFSET FCB ;POINT TO FILE CONTROL BLOCK INT 224 MOV BX,WORD PTR .FCB+33 ;GET RECORD COUNT MOV RCNT,BX ;STORE IT MOV BX, 0 ;ZERO HL MOV WORD PTR .FCB+33,BX ;RESET RANDOM RECORD IN FCB RET ; OPENFIL: XOR AL,AL MOV BYTE PTR .FCBEXT,AL MOV DX,OFFSET FCB MOV CL,OPEN INT 224 INC AL JNZ OPENOK CALL ERXIT DB 'Can''t open file$' OPENOK: MOV AL,QFLG OR AL,AL JNZ OPENOK1 RET OPENOK1: CALL SENDTIM ;A LIB MACRO SHOWS TIME TO SEND MOV BYTE PTR .FCBRNO,0 ; MJM - 9.01.05 FIX BATCH SEND MOV BYTE PTR .FCBEXT,0 ; MJM - 9.01.05 FIX BATCH SEND RET ; CLOSFIL: MOV DX,OFFSET FCB MOV CL,CLOSE INT 224 INC AL JZ CLOSFIL1 RET CLOSFIL1: CALL ERXIT DB 'Can''t close file$' RDSECT: DEC SECINBF JS RDBLOCK MOV BX,SECPTR MOV DX,OFFSET 80H CALL MOVE128 MOV SECPTR,BX RET ; RDBLOCK: MOV AL,EOFLG CMP AL,1 STC JNZ RDBLOCK1 RET RDBLOCK1: MOV CL,0 MOV DX,OFFSET DBUF RDSECLP: PUSH CX PUSH DX MOV CL,STDMA INT 224 MOV DX,OFFSET FCB MOV CL,READ INT 224 POP DX POP CX OR AL,AL JZ RDSECOK DEC AL JZ REOF CALL ERXIT DB '++ File read error ++$' RDSECOK: MOV BX,OFFSET 80H ADD BX,DX XCHG BX,DX INC CL MOV AL,CL CMP AL,DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS JZ RDBFULL JMP RDSECLP ; REOF: MOV AL,1 MOV EOFLG,AL MOV AL,CL RDBFULL: MOV SECINBF,AL MOV BX,OFFSET DBUF MOV SECPTR,BX MOV DX,OFFSET 80H MOV CL,STDMA INT 224 JMP RDSECT ; WRSECT: MOV BX,SECPTR XCHG BX,DX MOV BX,OFFSET 80H CALL MOVE128 XCHG BX,DX MOV SECPTR,BX MOV AL,SECINBF INC AL MOV SECINBF,AL CMP AL,DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS JZ WRBLOCK RET WRBLOCK: MOV AL,SECINBF OR AL,AL JNZ WRBLOCK1 RET WRBLOCK1: MOV CL,AL MOV DX,OFFSET DBUF DKWRLP: PUSH BX PUSH DX PUSH CX MOV CL,STDMA INT 224 MOV DX,OFFSET FCB MOV CL,WRITE INT 224 POP CX POP DX POP BX OR AL,AL JNZ WRERR MOV BX,OFFSET 80H ADD BX,DX XCHG BX,DX DEC CL JNZ DKWRLP XOR AL,AL MOV SECINBF,AL MOV BX,OFFSET DBUF MOV SECPTR,BX RET ; WRERR: MOV CL,CAN CALL SEND CALL ERXIT DB CR,LF,'Error writing file',CR,LF,'$' ;