; ; ; PRINT SIZE OF A DISK FILE ARGUMENT IN K BYTES. ; ; ROBERT A. VAN VALZAH ; ; 7/16/77 ; * * *************************************************************** * * CP/M ASSEMBLER LIBRARY PROCEDURES * * INITIALIZATION OF TRANSIENT PROGRAM * * FILE NAME: THEAD.LIB * * 7/16/77 * * * THIS LIBRARY CAN BE USED TO SET UP A STANDARD * CP/M PROGRAM. TO USE, TYPE THE PROGRAM HEADER AND * PROGRAM CONSTANTS (EQUATES), THEN READ IN THE LIBRARY. * TO RETURN TO CP/M EXECUTE A JUMP TO EXIT. * USERS MAIN PROGRAM MUST BE LABLED MAIN (OR CHANGE JMP) * STACK SIZE IS SET TO 64 BYTES. * * * BDOS I/O EQUATES * INCON EQU 1 ;READ CONSOLE FUNCTION NO. OUTCON EQU 2 ;WRITE CONSOLE FUNCTION NO. INTAPE EQU 3 ;INPUT FROM TAPE READER FUNCTION NO. OUTTAPE EQU 4 ;OUTPUT TO PUNCH FUNCTION NO. OUTBUF EQU 9 ;OUTPUT STRING TERMINATED BY $ INBUF EQU 10 ;INPUT BUFFER FUNCTION NO. BDOS EQU 5 ;BDOS ENTRY POINT * * CONTROL CHARACTERS * CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED CNTRL EQU -40H ;CONTROL KEY OFFSET (I.E. CNTRL+'C') * * EXECUTION * ORG 100H START: LXI H,0 DAD SP SHLD OLDSP ;SAVE CP/M'S STACK POINTER LXI SP,STKTOP JMP MAIN * * * RETURN TO OPERATING SYSTEM EXIT: LHLD OLDSP ;RETURN CP/M'S STACK POINTER SPHL RET ;RETURN TO SYSTEM * * STACKS * OLDSP DS 2 ;RESERVED FOR SYSTEM STACK POINTER STACK DS 64 ;SPACE FOR USER STACK STKTOP EQU $ ;STACK WORKS UP FROM HERE * * END THEAD.LIB *************************************************************** * * * * *************************************************************** * * CP/M ASSEMBLER LIBRARY PROCEDURES * * DISK I/O EQUATES THRU CP/M * * FILE NAME DISKIOEQ.LIB * * 7/16/77 * * BUFF EQU 0080H ;DEFAULT DISK I/O BUFFER * * FILE CONTROL BLOCK DEFINITION AND SUB-DEFINITIONS * FCB EQU 005CH ;DEFAULT FILE CONTROL BLOCK * FCBDN EQU FCB+0 ;DISK NAME, 0=LOGGED IN DISK, 1=A, 2=B FCBFN EQU FCB+1 ;FILE NAME (8 CHARACTERS) FCBFT EQU FCB+9 ;FILE TYPE (3 CHARACTERS) FCBEX EQU FCB+12 ;FILE EXTENT, 0=FIRST 16K, 1=NEXT 16K FCBRC EQU FCB+15 ;RECORD COUNT, 80H=FULL EXTENT FCBNR EQU FCB+32 ;NEXT RECORD TO BE READ * * BDOS FUNCTION NUMBER EQUATES * OPENFF EQU 15 ;OPEN FILE FUNCTION, 255=NOT FOUND CLOSFF EQU 16 ;CLOSE FILE FUNCTION, 255=NOT FOUND SRCHF EQU 17 ;SEARCH FOR FILE, 255=NO MATCH SRCHN EQU 18 ;SEARCH FOR NEXT OCCURRENCE DELTFF EQU 19 ;DELETE FILE FUNCTION READRF EQU 20 ;READ NEXT RECORD FUNCTION, 0=READ OK, ;1=READ PAST END OF FILE, ;2=READING UNWRITTEN DATA IN RANDOM ;ACCESS WRITRF EQU 21 ;WRITE RECORD FUNCTION, 0=WRITE OK, ;1=ERROR IN EXTENDING FILE, ;2=NO MORE DISK DATA SPACE (>240K) ;255=NO MORE DIRECTORY SPACE MAKEFF EQU 22 ;MAKE FILE FUNCTION, 255=NO DIR. SPACE * * * END DISKIOEQ.LIB *************************************************************** * * ; ; MESSAGES ; LENMES: DB 'FILE LENGTH: $' KMES: DB 'K$' NOFILM: DB 'NO SUCH FILE$' ; MAIN: MVI B,0 ;CLEAR SIZE SUM REG OPEN: PUSH B ;SAVE SUM SO FAR LXI D,FCB ;OPEN AN EXTENT OF THE FILE MVI C,OPENFF CALL BDOS POP B ;GET SUM SO FAR BACK CPI 255 ;ABLE TO FIND THAT FILE? JZ NOTHER ;NOPE - GIVE ERROR AND EXIT ; ; FCBRC NOW CONTAINS THE NUMBER OF 128 BYTE RECORDS ; IN THIS EXTENT OF THE FILE. THUS, DIVIDING BY 8 ; WE CAN GET THE EXTENT LENGTH IN K BYTES. BUT THE ; DISK IS ALLOCATED IN 1K CHUNKS, SO A LENGTH OF 4.5K ; BYTES REALLY HAS 5K BYTES ALLOCATED FOR IT. ; THEREFORE, WE MUST ROUND UP TO GET THE TRUE AMMOUNT ; OF DISK SPACE ALLOCATED FOR A FILE. ; LDA FCBRC ;GET RECORD COUNT ADI 0000$0111B ;CAUSE CARRY INTO BIT 3 IF ;LENGTH IS NOT AN EVEN K (ROUND UP). ANI 1111$1000B ;REMOVE ANY FRACTION LEFT RRC ;DIVIDE RESULT BY 8 RRC RRC ADD B ;ADD TO OLD SUM MOV B,A ;UPDATE NEW SUM LDA FCBEX ;PREPARE TO OPEN NEXT EXTENT IF THIS INR A ;ONE IS FULL STA FCBEX LDA FCBRC ;EXTENT IS FULL IF RC=128 CPI 128 JZ OPEN ;IS FULL - OPEN AND ADD NEXT EXTENT ; ; REACHED LAST EXTENT, FILE LENGTH IN K BYTES IN IN B. ; PUSH B ;SAVE LENGTH LXI D,LENMES ;PRINT "FILE LENGTH: " MVI C,OUTBUF CALL BDOS POP B ;GET LENGTH BACK MOV A,B ;LENGTH -> A CALL DECA ;PRINT A AS A NUMBER 0 - 255 LXI D,KMES ;PRINT "K" JMP PRARET ;PRINT AND RETURN NOTHER: ;COMES HERE IF FILE CAN'T BE FOUND LXI D,NOFILM PRARET: ;PRINT MESSAGE AT DE AND EXIT MVI C,OUTBUF CALL BDOS JMP EXIT ; ; DECA PRINTS THE NUMBER IN THE A REG AS A DECIMAL ; NUMBER 0 - 255. CLOBBERS A AND E. ; DECA: MVI E,-1 AND 255 ;INITIALIZE QUOTITENT ; ; THIS LOOP DIVIDES THE A REG BY 10 THRU MULTIPLE ; SUBTRACTION. QUOTIENT IS LEFT IN E REG, ; REMAINDER-10 IS LEFT IN A. ; LOOP: INR E ;ADD ONE TO QUOTIENT FOR EACH SUBTRACT SUI 10 JNC LOOP ;HAVEN'T UNDERFLOWED YET ; ADI '0' + 10 ;CONVERT REMAINDER TO ASCII PUSH PSW ;PUT THIS DIGIT ON THE STACK MOV A,E ;GET REMAINDER -> A ORA A ;DONE WITH ALL DIGITS? CNZ DECA ;NO - DO THIS AGAIN WITH THE REMAINDER ; ; THE ASCII NUMBER IS NOW UP ON THE STACK, MSD FIRST ; TO COME OFF. BDOS WILL PROBABLY RETURN HERE. ; POP PSW MOV E,A MVI C,OUTCON JMP BDOS ; END ENTRY