; MACROS LIBRARY FOR CP/M ROUTINE SIMULATION 12/27/82 ; ; ; CONTAINS: ; ; 1) INBUF - Duplicates 'read buffer' routine same as CP/M ; function 10, but does not use CTL-C (reason for ; for the routine). Does allow controls U, R, E ; and H (backspace). Outputs bell if the input is ; greater than the buffer. ; 2) CMDLINE - Parses a CPM/M buffer into format same as CP/M ; command line. ; 3) INLNCOMP - Compares a string following 'CALL ILCOMP' to a ; string addressed by the 'DE' registers. ; 4) MFACCESS - Multi-file access routine from the CP/M user's ; group. ; 5) SENDTIME - Shows the time needed to send a file for current ; baud rate. (For 110-9600 baud). ; 6) PRTBAUD - Shows baud rates set for 'time to send' file ; transfer. ; 7) DIRLIST - Lists directory and gives free space remaining ; on the requested drive. ; ; INBUF MACRO ;NO PARAMETERS USED. ; LOCAL START,INBUFO,INBUFA,DELETE,NODEL,ALERT,INBUFLT,CLEAR LOCAL CLEARL,INBUFR,RETYPE,BKSPC,PCRLF,CONIN,COUNOUT,CONIN1 LOCAL CONOUT1,NOUCASE,CTLRLP,CONSTAT,CONST1,CONINLP ; PUSH PSW PUSH H PUSH B PUSH D ;'DE' REGISTERS MUST BE PUSHED LAST START CALL CLEAR ;CLEAR THE BUFFER AREA POP D ;GET ADDRESS OF BUFFER ON RETRIES PUSH D ;RESTORE STACK XRA A INX D ;ADDRESS COUNT FIELD STAX D ;INITIALIZE WITH A ZERO IN COUNT BYTE INX D XCHG ;ADDRESS FIRST BUFFER BYTE WITH 'HL' INBUFA CALL CONIN CPI 0DH ;IS IT A RETURN? JZ INBUFR ;IF SO, THEN RETURN CPI 7FH ;IS IT A DELETE? JZ DELETE CPI 8 ;CTL-H WILL BACKSPACE.. JZ DELETE ;..OVER DELETED CHAR. CPI 'U'-40H ;IS IT A CTL-U JZ INBUFO ;OUTPUT # CR-LF AND START OVER CPI 'R'-40H ;CTL-R RETYPES LINE JZ RETYPE CPI 'E'-40H JZ PCRLF CPI 20H ;NO CONTROL CHARACTERS OTHER.. JC INBUFA ;..THAN ABOVE ALLOWED. MOV B,A ;SAVE INPUTTED CHARACTER XCHG ;SAVE 'HL' IN 'DE' POP H ;GET ADDRESS OF BUFFER IN 'HL' PUSH H ;RESTORE STACK INX H ;ADDRESS COUNT BYTE INR M ;INCREASE COUNT BYTE DCX H ;ADDRESS MAXIMUM MOV A,M ;PUT MAXIMUM IN 'A' INX H ;ADDRESS COUNT CMP M ;COMPARE COUNT TO MAXIMUM JC ALERT ;IF MAXIMUM, RING BELL AND WAIT FOR CR XCHG ;RESTORE BUFFER POINTER TO 'HL' MOV M,B ;PUT INPUTTED CHARACTER IN BUFFER MOV A,B ;OUTPUT IT CALL CONOUT INX H ;BUMP POINTER JMP INBUFA ;GET NEXT CHARACTER ; DELETE XCHG ;SAVE BUFFER POINTER IN 'DE' POP H ;ADDRESS BEGINNING OF BUFFER PUSH H ;RESTORE STACK INX H ;ADDRESS COUNT FIELD MOV B,A ;SAVE DELETE CHAR - 7FH OR 08H MOV A,M SUI 1 ;DECREASE COUNT MOV M,A JC NODEL ;DON'T DELETE PAST BEGINING OF BUFFER. XCHG ;RESTORE BUFFER POINTER TO 'HL' DCX H ;POINT TO LAST BYTE INPUTTED MOV A,B ;GET BACK EITHER 7FH OR 08H MOV B,M ;GET CHARACTER BEING DELETED MVI M,20H ;RESTORE BLANK CPI 8 JZ BKSPC CPI 7FH JZ BKSPC0 JMP INBUFA ;GET NEXT CHARACTER ; NODEL INR M ;DON'T LEAVE COUNT NEGATIVE XCHG ;RESTORE POINTER TO 'HL' JMP INBUFA ; BKSPC0 MVI A,08H BKSPC CALL CONOUT ;TRUE ERASE IF 08H MVI A,20H CALL CONOUT MVI A,8 CALL CONOUT JMP INBUFA ; INBUFO MVI A,'#' CALL CONOUT MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT JMP START ; RETYPE POP D PUSH D INX D ;POINT TO CURRENT NUMBER.. LDAX D ;..OF CHARACTERS. MOV B,A MVI A,'#' CALL CONOUT MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT MOV A,B ;TEST IF ZERO INPUT ORA A JZ INBUFA CTLRLP INX D LDAX D CALL CONOUT DCR B JNZ CTLRLP JMP INBUFA ; ALERT MVI A,7 CALL CONOUT DCR M XCHG JMP INBUFA ; PCRLF MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT JMP INBUFA ; INBUFR MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT POP D POP B POP H POP PSW RET ; CLEAR POP D ;ACCOUNTS FOR CALL POP H ;ADDRESS BUFFER IN 'HL' PUSH H ;RESTORE.. PUSH D ;..STACK MOV B,M ;SAVE MAXIMUM IN 'B' INX H ;POINT TO FIRST.. INX H ;..BUFFER BYTE. MVI A,20H CLEARL MOV M,A INX H DCR B JNZ CLEARL RET ; CONIN PUSH H PUSH D PUSH B CONINLP CALL CONSTAT ORA A JZ CONINLP CALL CONIN1 CPI 61H ;CHANGE TO UPPER.. JC NOUCASE ;..CASE SINCE CP/M.. CPI 7BH ;..DOES THE SAME. JNC NOUCASE ANI 5FH NOUCASE POP B POP D POP H RET ; CONIN1 LHLD 1 LXI D,6 DAD D PCHL ; CONSTAT PUSH H PUSH D PUSH B CALL CONST1 POP B POP D POP H RET ; CONST1 LHLD 1 LXI D,3 DAD D PCHL ; CONOUT PUSH H PUSH D PUSH B PUSH PSW CALL CONOUT1 POP PSW POP B POP D POP H RET ; CONOUT1 LHLD 1 LXI D,9 DAD D MOV C,A PCHL ; ENDM ;..... ; ; CMDLINE MACRO ;NO PARAMETERS USED ; Loads a command line addressed by 'DE' registers (max # characters in ; line in 'DE', number of characters in the line in 'DE'+1, line starts ; in 'DE'+2) into FCB addressed by 'HL' registers. The FCB should be at ; least 33 bytes in length. The command line buffer must have a maximum ; length of at least one more than the greatest number of characters ; that will be needed. ; LOCAL CMDLINE,DEFDR,DONE,DRIVE,FILL1,FILL,FILL2,INIT,INITL1 LOCAL INITL2,INITL3,INITL4,NAME1,NAME2,SCAN,TRANS,TSTNAM LOCAL TSTTYP,TSTTYPL,TYPE1,TYPE2,NAME2C ; PUSH PSW PUSH B PUSH D PUSH H ; CALL INIT ;FILLS FCBS WITH BLANKS AND NULLS ; XCHG ;GET START OF COMMAND LINE IN 'HL' INX H ;ADDRESS # BYTES IN CMD LINE MOV E,M ;LOAD 'DE' PAIR WITH # BYTES MVI D,0 INX H DAD D ;POINT TO BYTE AFTER LAST CHAR.. MVI M,0DH ;..IN CMD LINE AND STORE DELIMITER POP H ;RESTORE 'HL' AND 'DE' POP D PUSH D PUSH H INX D ;ADDRESS START OF COMMAND INX D ; CALL DRIVE NAME1 MVI C,8 ;TRANSFER FIRST FILENAME TO FCB CALL TRANS CPI 0DH JZ DONE CPI 20H ;IF SPACE, THEN START OF.. JZ NAME2 ;..SECOND FILENAME. TYPE1 POP H ;FILETYPE MUST BE AFTER.. PUSH H ;..EIGHTH BYTE OF NAME LXI B,9 DAD B MVI C,3 ;TRANSFER TYPE OF FIRST FILE CALL TRANS CPI 0DH JZ DONE NAME2 LDAX D ;EAT MULTIPLE SPACES.. CPI 20H ;..BETWEEN NAMES JNZ NAME2C INX D JMP NAME2 LDAX D CPI 0DH ;TEST IF FIRST NAME.. JZ DONE ;..ONLY AND THEN SPACE NAME2C POP H ;SECOND NAME STARTS IN 16TH BYTE PUSH H ;POINT 'HL' TO THIS BYTE LXI B,16 DAD B CALL DRIVE MVI C,8 CALL TRANS CPI 0DH JZ DONE TYPE2 POP H ;SECOND TYPE STARTS IN 25TH BYTE. PUSH H LXI B,25 DAD B MVI C,3 CALL TRANS DONE POP H PUSH H INX H ;POINT TO 1ST CHAR OF 1ST NAME IN FCB CALL SCAN ;CHECK FOR * (AMBIGUOUS NAMES). POP H PUSH H LXI B,17 ;POINT TO 1ST CHAR OF 2ND NAME IN FCB. DAD B CALL SCAN POP H POP D POP B POP PSW RET ; ; INIT PUSH H ;INITIALIZES FCB WITH 1 NULL (FOR 1ST DRIVE),.. PUSH B ;..11 BLANKS, 4 NULLS, 1 NULL (FOR 2ND DRIVE),.. MVI M,0 ;..11 BLANKS, AND 4 NULLS INX H MVI B,11 MVI A,20H CALL INITFILL MVI B,5 MVI A,0 CALL INITFILL MVI B,11 MVI A,20H CALL INITFILL MVI B,4 MVI A,0 CALL INITFILL POP B POP H RET ; INITFILL MOV M,A INX H DCR B JNZ INITFILL RET ; DRIVE INX D ;CHECK 2ND BYTE OF FILENAME. IF IT.. LDAX D ;..IS A ":", THEN DRIVE WAS SPECIFIED DCX D CPI ':' JNZ DEFDR ;ELSE ZERO FOR DEFAULT DRIVE ('INIT' PUT ZERO) LDAX D ANI 5FH SUI 40H ;CALCULATE DRIVE (A=1, B=2,...).. MOV M,A ;..AND PLACE IT IN FCB INX D ;ADDRESS FIRST BYTE OF.. INX D ;..IN CMD LINE.. DEFDR INX H ;..AND NAME FIELD IN FCB RET ; TRANS LDAX D ;TRANSFER FROM CMD LINE TO FCB.. INX D ;..UP TO NUMBER OF CHARS SPECIFIED.. CPI 0DH ;..BY 'C' REG. KEEP SCANNING FIELD.. RZ ;..WITHOUT TRANSFER UNTIL A DELIMITING.. CPI '.' ;..FIELD CHAR SUCH AS '.', BLANK, OR.. RZ ;..C/R (FOR END OF CMD LINE) CPI 20H RZ DCR C JM TRANS ;ONCE 'C' REG IS LESS THAN '0' KEEP READING MOV M,A ;..CMD LINE BUT DO NOT TRANSFER TO FCB INX H JMP TRANS ; SCAN MVI B,8 ;SCAN FILE NAME ADDRESSED BY 'HL' TSTNAM MOV A,M CPI '*' ;IF '*' FOUND, FILL IN REST OF FIELD.. JZ FILL1 ;..WITH '?' FOR AMBIGUOUS NAME INX H DCR B JNZ TSTNAM JMP TSTTYP FILL1 CALL FILL TSTTYP MVI B,3 ;SCAN AND FILL TYPE FIELD FOR NAME.. TSTTYPL MOV A,M ;..SPECIFIED ABOVE CPI '*' JZ FILL2 INX H DCR B RZ JMP TSTTYPL ; FILL2 ; FILL MVI M,'?' ;ROUTINE TRANSFERS '?' INX H DCR B JNZ FILL RET ; ENDM ;..... ; ; INLNCOMP MACRO ;NO PARAMETERS USED ; ; In-line compare. Compares string addressed by 'DE' pair to string af- ; the call (ends with '0'). Return with carry set means strings not the ; same. All registers (except 'A') are unaffected. ; SAME. ALL REGISTERS EXCEPT A-REG ARE UNAFFECTED. ; LOCAL ILCOMPL,SAME,NOTSAME,NSLP ; XTHL ;POINT 'HL' TO 1ST CHARACTER PUSH D ILCOMPL MOV A,M ;'HL' POINTS TO IN-LINE STRING ORA A ;END OF STRING IF ZERO JZ SAME LDAX D CMP M JNZ NOTSAME INX H INX D JMP ILCOMPL ; NOTSAME MVI A,0 ;IF NOT SAME, FINISH THRU.. NSLP INX H ;..STRING SO RETURN WILL.. CMP M ;..GO TO INSTRUCTION AFTER.. JNZ NSLP ;..STRING AND NOT REMAINDER OF STRING STC SAME POP D INX H ;AVOIDS A NOP INSTRUCTION.. XTHL ;..WHEN RETURNING RET ; ENDM ;..... ; ; MFACCESS MACRO ;NO PARAMETERS USED ; ; 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 ; ; Define data move MACRO ; LOCAL MOVE,CPM,MFNAME,MFN01,MFN02,MFFIX1,MFREQ,MFCUR,MOVER LOCAL SRCHF,SRCHN,STDMA,BDOS,FCB,FCBEXT,FCBRNO ; ; ;MFFLG1 IS NOT SET LOCAL BECAUSE IT MUST ; ;BE RESET IN MAIN MODEM PROGRAM ON AN ; ;ABORT ; MOVE MACRO ?F,?T,?L,?I IF NOT NUL ?F LXI H,?F ENDIF IF NOT NUL ?T LXI D,?T ENDIF IF NOT NUL ?L LXI B,?L ENDIF IF NOT NUL ?I LOCAL ?B,?Z CALL ?Z ?B DB ?I ?Z POP H ;GET TO LXI B,?Z-?B ENDIF CALL MOVER MF SET -1 ;SHOW EXPANSION ENDM ;... ; ; ;DEFINE CP/M MACRO - CPM FNC,PARM ; CPM MACRO ?F,?P PUSH B PUSH D PUSH H IF NOT NUL ?F MVI C,?F ENDIF IF NOT NUL ?P LXI D,?P ENDIF CALL BDOS POP H POP D POP B ENDM ;... ; ; ; MULTI-FILE ACCESS SUBROUTINE ; ; The routine is commented in pseudo code, each pseudo code statement is ; in <<...>> ; MFNAME ; ;<> ; CPM STDMA,80H XRA A STA FCBEXT ; ;<> ; LDA MFFLG1 ORA A JNZ MFN01 ; ; <> ; MVI A,1 STA MFFLG1 ; ; <> ; MOVE FCB,MFREQ,12 ;SAVE ORIG REQ LDA FCB STA MFCUR ;SAVE DISK IN CURRENT FCB ; ; <> ; MOVE MFREQ,FCB,12 CPM SRCHF,FCB ; ;<> ; JMP MFN02 MFN01 ; ; <> ; MOVE MFCUR,FCB,12 CPM SRCHF,FCB ; ; <> ; MOVE MFREQ,FCB,12 CPM SRCHN,FCB ; ;<> ; MFN02 ; ;<> ; INR A STC JNZ MFFIX1 STA MFFLG1 RET ; ; MFFIX1 ; ;<> DCR A ANI 3 ADD A ADD A ADD A ADD A ADD A ADI 81H MOV L,A MVI H,0 PUSH H ;SAVE NAME POINTER MOVE ,MFCUR+1,11 ; ;<> ; POP H MOVE ,FCB+1,11 ; ;<> ; XRA A STA FCBEXT STA FCBRNO ; ;<> ; RET ; ; ; Multi-file access work area MFFLG1 DB 0 ;1ST TIME SW MFREQ DS 12 ;REQ NAME MFCUR DS 12 ;CURR NAME ; ; Move subroutine ; MOVER MOV A,M STAX D INX H INX D DCX B MOV A,B ORA C JNZ MOVER RET ; ; ; Equates used by multi-access subroutine SRCHF EQU 17 SRCHN EQU 18 STDMA EQU 26 BDOS EQU 5 FCB EQU 5CH FCBEXT EQU FCB+12 FCBRNO EQU FCB+32 ENDM ;..... ; ; SENDTIME MACRO ;NO PARAMETERS USED ; ; Shows the time to transfer a file at various baud rates ; LOCAL BTABLE,SECTBL,DVHLDE,DIVL1,MULHLA,MULLP,SHFTHL CALL ILPRT ;PRINT: DB 'File open: ',0 LHLD RCNT ;GET RECORD COUNT. CALL DECOUT ;PRINT DECIMAL NUMBER OF RECORDS CALL ILPRT DB ' (',0 CALL DHXOUT ;NOW PRINT SIZE IN HEX. CALL ILPRT DB ' Hex) Records',CR,LF DB 'Send time: ',0 LDA MSPEED ;GET THE SPEED INDICATOR MVI D,0 MOV E,A ;SET UP FOR TABLE ACCESS LXI H,BTABLE ;POINT TO BAUD FACTOR TABLE DAD D ;INDEX TO PROPER FACTOR DAD D ;FACTOR IN DE MOV E,M INX H MOV D,M LHLD RCNT ;GET # OF RECORDS CALL DVHLDE ;DIVIDE 'HL' BY VALUE IN DE (RECORDS/MIN) PUSH H MOV L,C MOV H,B CALL DECOUT ;PRINT THE MINUTES PORTION CALL ILPRT DB ' mins, ',0 LXI H,SECTBL ;POINT TO DIVISORS FOR SECONDS LXI D,0 ; CALCULATION LDA MSPEED ;GET INDEX FOR BAUD RATE MOV E,A DAD D ;INDEX INTO TABLE MOV A,M ;GET MULTIPLIER POP H ;GET REMAINDER CALL MULHLA ;MULTIPLY THE 'HL' x 'A' CALL SHFTHL CALL SHFTHL CALL SHFTHL CALL SHFTHL MVI H,0 CALL DECOUT ;PRINT THE SECONDS PORTION CALL ILPRT DB ' secs at ',0 CALL BAUDPRT CALL ILPRT DB 'To cancel: ctrl-X',CR,LF,0 RET ; ; BTABLE DW 5,13,19,25,29,49,96,192,384,0 ;RECORDS/MIN FOR 110-9600 BAUD SECTBL DB 192,74,51,38,33,20,11,5,3,0 ; ; ;----> DVHLDE: DIVIDES 'HL' BY VALUE IN 'DE', ; UPON EXIT: 'BC'=QUOTIENT,'L'=REMAINDER ; DVHLDE PUSH D ; SAVE DIVISOR MOV A,E CMA ; NEGATE DIVISOR MOV E,A MOV A,D CMA MOV D,A INX D ; DE IS NOW TWOS COMPLEMENTED LXI B,0 ; INIT QUOTIENT DIVL1: DAD D ; SUBTRACT DIVISOR FROM DIVIDEND INX B ; BUMP QUOTIENT JC DIVL1 ; LOOP TILL SIGN CHANGES DCX B ; ADJUST QUOTIENT POP D ; RETRIEVE DIVISOR DAD D ; ADJUST REMAINDER RET ; ; ;----> MULHLA: MULTIPLY THE VALUE IN 'HL' BY THE VALUE IN 'A' ; RETURN WITH ANSWER IN 'HL' MULHLA XCHG ; MULTIPLICAND TO DE LXI H,0 ; INIT PRODUCT INR A ; ADJUST MULTIPLIER FOR ZERO TEST MULLP DCR A RZ DAD D JMP MULLP ; ; ; SHIFT 'HL' REGISTER PAIR ONE BIT TO THE RIGHT ; SHFTHL MOV A,L RAR MOV L,A ORA A ;CLEAR THE CARRY MOV A,H RAR MOV H,A RNC MVI A,80H ORA L MOV L,A RET ; ENDM ;..... ; ; PRTBAUD MACRO ;NO PARAMETERS USED ; LOCAL BAUDSPD ; LXI H,BAUDSPD MVI D,0 LDA MSPEED ;GET BAUD RATE CODE MOV E,A ;X1 ADD A ;X2 ADD A ;X4 ADD E ;X5 MOV E,A DAD D ;POINT TO CORRECT RATE XCHG MVI C,PRINT CALL BDOS CALL ILPRT DB ' baud',CR,LF,0 RET ; BAUDSPD DB '110$',0,'300$',0,'450$',0,'600$',0,'710$',0 DB '1200$','2400$','4800$','9600$' ; ENDM ;..... ; ; DIRLIST MACRO ;NO PARAMETERS USED ; LOCAL DIRLP,PRTNAME,NOFILE,DIRDONE,QSTMARK,QSTLP,PRNTNAME LOCAL NEXTSR,MOVENAME,GETADD,SRCHFCB,NAMECT,PRNTHD,DRNAME LOCAL FENCE,GSPBYT,GSPLUP,NOTFRE,ENDALC,FREKLP,PRTFREE LOCAL PRTHD,DRNAME ; LXI D,CMDBUF ;PUT COMMAND LINE IN FCB LXI H,5CH CALL CPMLINE LXI H,SRCHFCB CALL INITFCBS LDA 6CH ;GET DRIVE # STA SRCHFCB LDA 6DH CPI 20H ;IF BLANK GET ALL NAMES PUSH PSW CZ QSTMARK POP PSW CNZ MOVENAME ;ELSE MOVE NAME INTO FCB LXI D,80H MVI C,STDMA CALL BDOS XRA A STA NAMEGD STA NAMECT ;CR AFTER 4 NAMES LXI D,SRCHFCB MVI C,SRCHF ;DO FIRST SEARCH CALL BDOS CPI 0FFH JZ NOFILE PUSH PSW DIRLP POP PSW CALL GETADD LXI D,15 ;OFFSET FOR RECORD COUNT DAD D MOV A,M ORA A JZ NEXTSR ;NO LIST IF FILE IS ZERO LENGTH LXI D,-5 DAD D ;POINT TO $SYS ATTRIB BYTE MOV A,M ANI 80H JNZ NEXTSR ;NO LIST IF $SYS FILE LXI D,-10 DAD D ;POINT TO BEGINNING OF NAME INX H ;POINT TO FIRST LETTER LXI D,PRNTNAME MVI B,8 CALL MOVE INX D MVI B,3 CALL MOVE CALL ILPRT PRNTNAME DB ' ','.',' ',' ', 0 ;8 SPACES, PERIOD, 3 SPACES, 1 SPACE MVI A,0FFH STA NAMEGD NEXTSR LXI D,SRCHFCB MVI C,SRCHN ;DO NEXT SEARCH CALL BDOS CPI 0FFH JZ DIRDONE PUSH PSW LDA NAMEGD ORA A JZ DIRLP LDA NAMECT INR A STA NAMECT ANI 03H ORA A CZ CRLF CNZ FENCE MVI A,0 STA NAMEGD JMP DIRLP ; NOFILE CALL ILPRT DB 'NO FILE',0 ; ; ; Determines free space remaining ; DIRDONE LDA SRCHFCB ORA A JZ DEFLT DCR A MOV E,A MVI C,SELDSK CALL BDOS DEFLT MVI C,GETPARM ;CURRENT DISK PARAMETER BLOACK CALL BDOS INX H INX H MOV A,M ;GET BLOCK SHIFT FACTOR STA BSHIFTF INX H ;BUMP TO BLOCK MASK MOV A,M ;GET IT STA BMASK INX H INX H MOV E,M ;GET MAX BLOCK NUMBER INX H MOV D,M XCHG SHLD BMAX ;PUT IT AWAY MVI C,GETALC ;ADDRESS OF CP/M ALLOCATION VECTOR CALL BDOS XCHG ;GET ITS LENGTH LHLD BMAX INX H LXI B,0 ;INITIALIZE BLOCK COUNT TO ZERO GSPBYT PUSH D ;SAVE ALLOCATION ADDRESS LDAX D MVI E,8 ;SET TO PROCESS 8 BLOCKS GSPLUP RAL ;TEST BIT JC NOTFRE INX B NOTFRE MOV D,A ;SAVE BITS DCX H MOV A,L ORA H JZ ENDALC ;QUIT IF OUT OF BLOCKS MOV A,D ;RESTORE BITS DCR E ;COUNT DOWN 8 BITS JNZ GSPLUP ;DO ANOTHER BIT POP D ;BUMP TO NEXT COUNT OF ALLOCATION VECTOR INX D JMP GSPBYT ;PROCESS IT ; ENDALC POP D ;CLEAR ALLOCATION VECTOR FROM STACK MOV L,C ;COPY BLOCK TO 'HL' MOV H,B LDA BSHIFTF ;GET BLOCK SHIFT FACTOR SUI 3 ;CONVERT FROM RECORDS TO THOUSANDS JZ PRTFREE ;SKIP SHIFTS IF 1K BLOCKS FREKLP DAD H ;MULTIPLY BLOCKS BY 'K PER BLOCK' DCR A JNZ FREKLP PRTFREE PUSH H CALL ILPRT DB CR,LF,'Drive ',0 LDA SRCHFCB ;IF NO DRIVE, GET ORA A ;LOGGED IN DRIVE JNZ PRNTHD MVI C,CURDSK CALL BDOS INR A PRNTHD ADI 'A'-1 STA DRNAME CALL ILPRT DRNAME DB ' has ',0 POP H ;GET NUMBER OF BYTES AVAILABLE CALL DECOUT CALL ILPRT DB 'K bytes free',CR,LF,0 RET ; ; Subroutines ; FENCE CALL ILPRT DB '| ',0 RET ; QSTMARK MVI A,'?' ;IF BLANK IN FCB, PUT IN 11 ?'s MVI B,11 LXI H,SRCHFCB+1 QSTLP MOV M,A INX H DCR B JNZ QSTLP RET ; MOVENAME LXI H,6DH LXI D,SRCHFCB+1 MVI B,11 JMP MOVE ;MOVE IN MAIN PROGRAM ; GETADD ANI 03H ;GET MOD4 FOR CP/M 1.4 ADD A ;ADD 32 ADD A ADD A ADD A ADD A MOV E,A MVI D,0 LXI H,80H ;ADD DMA OFFSET DAD D RET ; ; ; Parameters used ; GETALC EQU 27 ;CP/M ALLOCATION VECTOR ADDRESS GETPARM EQU 31 ;CURRENT DISK PARAMETERS ADDRESS ; ; ; Unitialized storage ; SRCHFCB DS 33 NAMEGD DS 1 NAMECT DS 1 BMAX DS 2 ;HIGHEST BLOCK NUMBER ON DRIVE BMASK DS 1 ;(RECORDS/BLOCK)-1 BSHIFTF DS 1 ;NUMBER OF SHIFTS TO MULTIPLY BY REC/BLOCK ; ENDM