; CP4CPM.ASM ; KERMIT - (Celtic for "FREE") ; ; This is the CP/M-80 implementation of the Columbia University ; KERMIT file transfer protocol. ; ; Version 4.0 ; ; Copyright June 1981,1982,1983,1984 ; Columbia University ; ; Originally written by Bill Catchings of the Columbia University Center for ; Computing Activities, 612 W. 115th St., New York, NY 10025. ; ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many ; others. ; ; This file duplicates the CP/M DIR and ERA functions so we don't have ; to exit. ; ; revision history: ; edit 3: July 8, 1984 (CJC) ; Merge modifications from Toad Hall: support LASM (linked by CP4TT, ; links to CP4WLD), use prcrlf where appropriate. ; ; edit 2: June 5, 1984 (CJC) ; documentation and formatting; delete unused code (dir13); add module ; version string. ; ; edit 1: May, 1984 (CJC) ; extracted from CPMBASE.M80 version 3.9; modifications are described in ; the accompanying .UPD file. ; cpmver: db 'CP4CPM.ASM (3) 8-Jul-84$' ; name, edit number, date npl EQU 04H ;Number of names per line for dir command. ; This is the DIR command. Display the name and size of all files ; matching the filespec. ; here from: kermit ; ; Note: This is abstracted from Keith Peterson's DIRF.ASM ; directory print function. Thanks again Keith. ; ; dir: lxi d,fcb ;Where to put the data, if any. mvi a,cmifin call comnd ;Parse a full or piece of file-spec jmp dir2 ;Didn't get a FULL file-spec jmp dir4 ;lets do it ; ; ;Make FCB all '?' to match any file dir2: lda fcb cpi ' ' ;CMIFIN leaves that as ' ' jnz dir2a ;he typed at least x: xra a sta fcb ;default drive dir2a: lxi h,fcb+1 mvi b,11 ;FN+FT count. dir3: mvi m,'?' ;Store '?'s in FCB. inx h dcr b jnz dir3 ;Print signon message and drive name dir4: lda fcb ora a ;if not zero, get default jnz dir4a lda curdsk ;get default dir4a: adi 'A'-1 ;Asciize it sta dnam14 ;Save it in message. call prcrlf lxi d,inms14 ;Point to message call prtstr ; ;Initialize number of names per line counter mvi a,npl ;Nr. names per line. sta nnams ;Init counter. ; call dir26 ;Get disk parameters dir5: call mfname ;get some names jnc dir6 ;got one jmp dir17 ;got none - do summary dir6: ;Check for console break mvi c,consta ;Ck status of kbd. call bdos ora a ;Any key pressed? jz dir6a ;nope, keep going mvi c,conin call bdos ;gobble key jmp dir17 ;and print summary only ;Print an entry dir6a: lxi h,fcb+1 ;point to Filename mvi b,8 ;File name length. call dir11 ;Type filename. mvi a,'.' ;Period after FN. call dir10 mvi b,3 ;Get the filetype. call dir11 call dir25 ;print size lxi h,nnams ;Point to names counter. dcr m ;One less on this line. push psw cnz dir7 ;No cr-lf needed, do fence. pop psw cz dir12 ;Cr-lf needed. jmp dir5 ;Print space, fence character, then space dir7: call dir9 mvi a,':' ;Fence character. call dir10 jmp dir9 ; dir8 - Print two spaces ; dir9 - Print one space ; dir10 - Type char in A register dir8: call dir9 dir9: mvi a,' ' dir10: push b push d push h mov e,a ;Char to E for CP/M. mvi c,conout ;Write char to console function. call bdos pop h pop d pop b ret ;Type (B) characters from memory (HL) dir11: mov a,m ani 7FH ;Remove CP/M 2.x attributes. call dir10 inx h dcr b jnz dir11 ret ;CR-LF routine. HL=NNAMS upon entry dir12: push b push d push h call prcrlf ;Print CR/LF [Toad Hall] pop h ;(did use call to dir10, but slooow) pop d pop b mvi m,npl ;Number of names per line. ret ;Exit - All done, return via jmp (as for all main commands) dir16: call prcrlf lda curdsk dcr a ;relative to 0 mov e,a mvi c,logdsk call bdos ;back to "logged in" disk jmp kermit ;...and return to kermit. ; ;Determines free space remaining ; dir17: xra a sta mfflg1 ;clean up MFNAME sta mfflg2 lda fcb ; get drive number from FCB ora a jz dir18 ; default? dcr a ; no, make requested drive current drive. mov e,a mvi c,logdsk call bdos dir18: call sysspc ; get space available for current drive push h lxi d,inms15 ;"Drive " call prtstr lda fcb ;If no drive, get ora a ;logged in drive jnz dir24 mvi c,rddrv call bdos inr a dir24: adi 'A'-1 sta inms16 lxi d,inms16 ;"x has " call prtstr pop h ;Get number of bytes available call nout lxi d,inms17 ;"K bytes free" call prtstr jmp dir16 ;all done ;Compute the size of the file dir25: mvi c,cflsz ;get file-size lxi d,fcb call bdos lda fcbrno ;shift least sign. part lxi b,0 ;init bc mov l,a ani 7 jz dir250 ;even K lxi b,1 ;save for later dir250: push b ;save 0 or 1 to add to size mvi b,3 ;shift 3 bits dir25a: xra a ;clear sign lda fcbrno+1 ;get most sig byte rar ;shift right sta fcbrno+1 ;put back lda fcbrno ;get least sig part rar sta fcbrno dcr b ;loop 3 times jnz dir25a mov l,a ;size in HL lda fcbrno+1 mov h,a pop b ;get 0 or 1 dad b ;round up to KB used lda bmask ;get (sectors/block)-1 rrc rrc ;get (K/block)-1 rrc ani 1FH mov c,a dad b ;add (K/block)-1 to size to round up cma ;make a mask ana l ;truncate after rounding up mov l,a push h lxi b,-10 ;subtract 10 dad b jc dir25d ;>= 10 call dir8 ; print a leading space jmp dir25e dir25d: pop h ;get size again push h lxi b,-100 ;subtract 100 dad b jc dir25e ;>= 100 call dir9 ; print another leading space dir25e: call dir9 ;a space pop h ;get size back call nout ;..go print it mvi a,'k' ;..and follow with K size call dir10 ret dir26: mvi c,gtdpar ;current DISK PARAMETER BLOCK 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 ret ; ; ERA command - erase a CP/M file ; here from: kermit era: mvi a,cmifi ;Parse a file-spec lxi d,fcb ;into FCB call comnd jmp kermit ;bad parse lxi d,fcb mvi c,sfirst ;check if valid call bdos inr a ;0 if FILE not found jnz era1 ;found at least one lxi d,erms15 ;"unable to find file" call prtstr jmp kermit era1: lxi d,fcb mvi c,delf call bdos lxi d,inms18 ;" File(s) erased" call prtstr jmp kermit IF lasm LINK CP4WLD ENDIF;lasm [Toad Hall]