home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / cpm80 / cpscpm.asm < prev    next >
Assembly Source File  |  2020-01-01  |  27KB  |  933 lines

  1. ; CPSCPM.ASM
  2. ;       KERMIT - (Celtic for "FREE")
  3. ;
  4. ;       This is the CP/M-80 implementation of the Columbia University
  5. ;       KERMIT file transfer protocol.
  6. ;
  7. ;       Version 4.0
  8. ;
  9. ;       Copyright June 1981,1982,1983,1984
  10. ;       Columbia University
  11. ;
  12. ; Originally written by Bill Catchings of the Columbia University Center for
  13. ; Computing Activities, 612 W. 115th St., New York, NY 10025.
  14. ;
  15. ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
  16. ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
  17. ; others. 
  18. ;
  19. ;       This file duplicates the CP/M DIR and ERA functions so we don't have
  20. ;       to exit.
  21. ;
  22. ; revision history:
  23. ;
  24. ;edit 14, 1-Apr-1991 by MF. Correct a bug which crept in with edit 13 which
  25. ;    caused any control-key other than ^Y or ^Z to act like ^X after a key
  26. ;    had been depressed to halt output of the TYPE/PRINT commands.
  27. ;edit 13, 25-Mar-1991 by MF. Make the TYPE command always abort to Kermit
  28. ;    command-level if ^C is entered on the console even if multiple files
  29. ;    are being typed via wild-cards. Make ^X typed on the console abort
  30. ;    typeout of the current file and begin typeout of the next file,
  31. ;    if any, otherwise go back to Kermit command-level.
  32. ;    The foregoing also applies to the PRINT command.
  33. ;edit 12, 14-Feb-1991 by MF. Call "clrtop" in TYPE command at "type1"
  34. ;    rather than sending a <ff> directly to the terminal as some
  35. ;    terminals don't respond to <ff> characters. Thus the screen will be
  36. ;    cleared (if the terminal allows) before each file is typed.
  37. ;    Also use "getfil" rather than the bdos "openf" call to open
  38. ;    files for typing (label "type2"). This tightens up the code.
  39. ;    Zero "fcbcnt" before starting to type files (label "type0b").
  40. ;    This apparently fixes a phantom bug which caused incorrect lookup (and
  41. ;    hence garbage typeout) of files occassionally after a new disk
  42. ;    was inserted and a SET DEFAULT-DISK was performed to reset the disk
  43. ;    system. (It looked like parts of other files were being typed, as
  44. ;    if the directory had been misread or had not been reset.)
  45. ;edit 11, 8-Feb-1991 by MF. Cause the bdos call for direct console input
  46. ;    in "ckchr" **not** to go thru the bdos trap but to call bdos at 0005h
  47. ;    directly. This corrects a bug wherein if commands such as INPUT
  48. ;    (which check to see if a keyboard key has been pressed) were executed
  49. ;    from a TAKE-file, the character following the terminator of such
  50. ;    commands was being interpreted as that keyboard input, thus causing
  51. ;    the next command in the TAKE-file to be unrecognized since its
  52. ;    first character had been eaten as a result of the keyboard check.
  53. ;    This bug **may** be the cause of a report received by Dr. Martin
  54. ;    J. Carter of Nottingham University in the U.K. in which Kermit
  55. ;    was reported to have read a character beyond a command terminator
  56. ;    in a TAKE-file, making the subsequent command unrecognizable since
  57. ;    its first character was missing.
  58. ;edit 10, 29-Jan-1991 by MF. Use the big buffer for TYPE/PRINT commands.
  59. ;    Thus, edit 9 has been superseded.
  60. ;edit 9, 29-Jan-1991 by MF. Corrected EOF check in TYPE command routine
  61. ;    following label "type20". a READF call, if successful, gives A=0
  62. ;    (not A=0FFH) and A not zero if failure. Thus the "INR A" instruction
  63. ;    checking for EOF was **always** nonzero. The reason the TYPE command
  64. ;    worked is that CP/M text files indicate the text end-of-file with a
  65. ;    Control-Z, in which case the TYPE routine branched correctly. In
  66. ;    other words, this edit is more for aesthetic purposes to satisfy
  67. ;    purists than something brought about by dire necessity!
  68. ;edit 8, 28-Jan-1991 by MF. Added code courtesy of Dr. Martin J. Carter
  69. ;    of Nottingham University, UK, to use the big buffer for the COPY
  70. ;    command.
  71. ;edit 7, 18-Sep-1990 by MF.  Added RENAME routine to implement the
  72. ;    RENAME (FRENAME) command to rename a CP/M file.
  73. ;    Modified COPY routine to explicitly reject wild-carded filenames
  74. ;    by using COMND function CMOFI rather than functions CMIFI and
  75. ;    CMIFIN to get input and output filenames.
  76. ;    Modified ERA and COPY routines to not act upon the respective
  77. ;    commands until a "confirm" is typed.  This prevents these
  78. ;    routines from taking off upon recognition of action characters
  79. ;    like "?", which can be quite annoying if one is an inexperienced user.
  80. ; edit 6, March 11, 1987 by OBSchou.  Added in the TYPE and PRINT commands
  81. ;    Both type to the screen, print also echoes to printer.
  82. ;
  83. ; edit 5 20 June, 1986.  Added support for multiple file FCB buffering.
  84. ;
  85. ; edit 4: June 16, 1986 OBSchou at Loughborough University, UK
  86. ;       added in a test to prevent a DIR command issued from a TAKE command
  87. ;       being interruped by the next character in the take command buffer.
  88. ;       Also added code for USER nn. (Well, its OS related,is it not?)
  89. ;
  90. ; edit 3: July 8, 1984 (CJC)
  91. ;       Merge modifications from Toad Hall: support LASM (linked by CPSTT,
  92. ;       links to CPSWLD), use prcrlf where appropriate.
  93. ;
  94. ; edit 2: June 5, 1984 (CJC)
  95. ;       documentation and formatting; delete unused code (dir13); add module
  96. ;       version string.
  97. ;
  98. ; edit 1: May, 1984 (CJC)
  99. ;       extracted from CPMBASE.M80 version 3.9; modifications are described in
  100. ;       the accompanying .UPD file.
  101. ;
  102. cpmver:    db    'CPSCPM.ASM (14)  1-Apr-1991$'    ; name, edit number, date
  103.  
  104. npl    EQU    04H    ;Number of names per line for dir command.
  105.  
  106. ;       This is the DIR command.  Display the name and size of all files
  107. ;       matching the filespec.
  108. ;       here from: kermit
  109. ;
  110. ;       Note: This is abstracted from Keith Peterson's DIRF.ASM
  111. ;               directory print function.  Thanks again Keith.
  112. ;
  113. ;
  114. dir:    lxi    d,fcb        ;Where to put the data, if any.
  115.     mvi    a,cmifin
  116.     call    comnd        ;Parse a full or piece of file-spec
  117.     jmp    dir2        ;Didn't get a FULL file-spec
  118.     jmp    dir4        ;lets do it
  119. ;
  120. ;
  121. ;Make FCB all '?' to match any file
  122. dir2:    lda    fcb
  123.     cpi    ' '             ;CMIFIN leaves that as ' '
  124.     jnz    dir2a        ;he typed at least x:
  125.     xra    a
  126.     sta    fcb        ;default drive
  127. dir2a:    lxi    h,fcb+1
  128.     mvi    b,11        ;FN+FT count.
  129.  
  130. dir3:    mvi    m,'?'           ;Store '?'s in FCB.
  131.     inx    h
  132.     dcr    b
  133.     jnz    dir3
  134. ;Print signon message and drive name
  135. dir4:    call    getun        ; get current user number
  136.     lda    fcb
  137.     ora    a        ;if not zero, get default
  138.     jnz    dir4a
  139.     lda    curdsk        ;get default
  140. dir4a:    adi    'A'-1           ;Asciize it
  141.     sta    dnam14+2    ;[4] add in user no, and Save it in message.
  142.     lda    temp1+1        ;[4] most sig. user number
  143.     cpi    '0'             ;[4] if zero set space
  144.     jnz    dir4b
  145.     mvi    a,' '           ;[4] space
  146. dir4b:    sta    dnam14        ;[4]
  147.     lda    temp1
  148.     sta    dnam14+1    ;[4] ls user number digit
  149.     call    prcrlf
  150.     lxi    d,inms14    ;Point to message
  151.     call    prtstr
  152. ;
  153. ;Initialize number of names per line counter
  154.     mvi    a,npl        ;Nr. names per line.
  155.     sta    nnams        ;Init counter.
  156.     lda    hidefs        ; are we doing file size?
  157.     ana    a
  158.     jnz    dir4c        ; we are not showing file size,
  159.     lda    nnams
  160.     inr    a
  161.     sta    nnams        ; so we can show another name per line
  162.  
  163. dir4c:    xra    a        ; clear the flags ready for multi-sector buffering
  164.     sta    fcbcnt        ; clear fcb counter
  165.     sta    mfflg1
  166.     sta    mfflg2
  167.     sta    mfflg3
  168.     lxi    h,fcb0        ; reset pointer for fcb save space
  169.     shld    xfcbptr
  170. ;
  171.     call    dir26        ;Get disk parameters
  172.     xra    a        ;[5] say first time round, so no spare fcbs
  173.     sta    fcbcnt        ;[5]
  174. dir5:    call    mfname        ;get some names
  175.     jnc    dir6        ;got one
  176.     jmp    dir17        ;got none - do summary
  177.  
  178. dir6:                ;Check for console break
  179.     lda    takflg        ;[4] ... but not if issued from TAKE....
  180.     ana    a        ;[4]
  181.     jnz    dir6a        ;[4] we do the lot regardless.
  182.  
  183.     mvi    c,consta    ;Ck status of kbd.
  184.     call    bdos
  185.     ora    a        ;Any key pressed?
  186.     jz    dir6a        ;nope, keep going
  187.     mvi    c,conin
  188.     call    bdos        ;gobble key
  189.     jmp    dir17        ;and print summary only
  190.  
  191. ;Print an entry
  192. dir6a:
  193.     lxi    h,fcb+1        ;point to Filename
  194.     mvi    b,8        ;File name length.
  195.     call    dir11        ;Type filename.
  196.     mvi    a,'.'           ;Period after FN.
  197.     call    dir10
  198.     mvi    b,3        ;Get the filetype.
  199.     call    dir11
  200.     call    dir25        ;print size
  201.     lxi    h,nnams        ;Point to names counter.
  202.     dcr    m        ;One less on this line.
  203.     push    psw
  204.     cnz    dir7        ;No cr-lf needed, do fence.
  205.     pop    psw
  206.     cz    dir12        ;Cr-lf needed.
  207.     jmp    dir5
  208.  
  209. ;Print space, fence character, then space
  210. dir7:    call    dir9
  211.     mvi    a,':'           ;Fence character.
  212.     call    dir10
  213.     jmp    dir9
  214.  
  215. ; dir8 - Print two spaces
  216. ; dir9 - Print one space
  217. ; dir10 - Type char in A register
  218. dir8:    call    dir9
  219. dir9:    mvi    a,' '
  220. dir10:    push    b
  221.     push    d
  222.     push    h
  223.     mov    e,a        ;Char to E for CP/M.
  224.     mvi    c,conout    ;Write char to console function.
  225.     call    bdos
  226.     pop    h
  227.     pop    d
  228.     pop    b
  229.     ret
  230.  
  231. ;Type (B) characters from memory (HL)
  232. dir11:    mov    a,m
  233.     ani    7FH        ;Remove CP/M 2.x attributes.
  234.     call    dir10
  235.     inx    h
  236.     dcr    b
  237.     jnz    dir11
  238.     ret
  239.  
  240. ;CR-LF routine. HL=NNAMS upon entry
  241. dir12:    push    b
  242.     push    d
  243.     push    h
  244.     call    prcrlf        ;Print CR/LF [Toad Hall]
  245.     pop    h        ;(did use call to dir10, but slooow)
  246.     pop    d
  247.     pop    b
  248.     mvi    m,npl        ;Number of names per line.
  249.     lda    hidefs        ; are we showing file size?
  250.     ana    a
  251.     rnz            ; no, so all ok
  252.     inr    m        ; else show another file per line
  253.     ret
  254.  
  255. ;Exit - All done, return via jmp (as for all main commands)
  256. dir16:    call    prcrlf
  257.     lda    curdsk
  258.     dcr    a        ;relative to 0
  259.     mov    e,a
  260.     mvi    c,logdsk
  261.     call    bdos        ;back to "logged in" disk
  262.     jmp    kermit        ;...and return to kermit.
  263.  
  264. ;
  265. ;Determines free space remaining
  266. ;
  267. dir17:    xra    a
  268.     sta    mfflg1        ;clean up MFNAME
  269.     sta    mfflg2
  270.     lda    fcb        ; get drive number from FCB
  271.     ora    a
  272.     jz    dir18        ; default?
  273.     dcr    a        ; no, make requested drive current drive.
  274.     mov    e,a
  275.     mvi    c,logdsk
  276.     call    bdos
  277. dir18:    call    sysspc        ; get space available for current drive
  278.     push    h
  279.     lxi    d,inms15    ;"Drive "
  280.     call    prtstr
  281.     lda    fcb        ;If no drive, get
  282.     ora    a        ;logged in drive
  283.     jnz    dir24
  284.     mvi    c,rddrv
  285.     call    bdos
  286.     inr    a
  287. dir24:    adi    'A'-1
  288.     sta    inms16
  289.     lxi    d,inms16    ;"x has "
  290.     call    prtstr
  291.     pop    h        ;Get number of bytes available
  292.     call    nout
  293.     lxi    d,inms17    ;"K bytes free"
  294.     call    prtstr
  295.     jmp    dir16        ;all done
  296.  
  297. ;Compute the size of the file
  298.  
  299. dir25:    lda    hidefs        ; do we show file size?
  300.     ana    a        ; if non zero, we dont.
  301.     rz            ; so just return
  302.     mvi    c,cflsz        ;get file-size
  303.     lxi    d,fcb
  304.     call    bdos
  305.     lda    fcbrno        ;shift least sign. part
  306.     lxi    b,0        ;init bc
  307.     mov    l,a
  308.     ani    7
  309.     jz    dir250        ;even K
  310.     lxi    b,1        ;save for later
  311. dir250:    push    b        ;save 0 or 1 to add to size
  312.     mvi    b,3        ;shift 3 bits
  313. dir25a:    xra    a        ;clear sign
  314.     lda    fcbrno+1    ;get most sig byte
  315.     rar            ;shift right
  316.     sta    fcbrno+1    ;put back
  317.     lda    fcbrno        ;get least sig part
  318.     rar
  319.     sta    fcbrno
  320.     dcr    b        ;loop 3 times
  321.     jnz    dir25a
  322.     mov    l,a        ;size in HL
  323.     lda    fcbrno+1
  324.     mov    h,a
  325.     pop    b        ;get 0 or 1
  326.     dad    b        ;round up to KB used
  327.     lda    bmask        ;get (sectors/block)-1
  328.     rrc
  329.     rrc            ;get (K/block)-1
  330.     rrc
  331.     ani    1FH
  332.     mov    c,a
  333.     dad    b        ;add (K/block)-1 to size to round up
  334.     cma            ;make a mask
  335.     ana    l        ;truncate after rounding up
  336.     mov    l,a
  337.     push    h
  338.     lxi    b,-10        ;subtract 10
  339.     dad    b
  340.     jc    dir25d        ;>= 10
  341.     call    dir8        ; print a leading space
  342.     jmp    dir25e
  343.  
  344. dir25d:    pop    h        ;get size again
  345.     push    h
  346.     lxi    b,-100        ;subtract 100
  347.     dad    b
  348.     jc    dir25e        ;>= 100
  349.     call    dir9        ; print another leading space
  350. dir25e:    call    dir9        ;a space
  351.     pop    h        ;get size back
  352.     call    nout        ;..go print it
  353.     mvi    a,'k'           ;..and follow with K size
  354.     call    dir10
  355.     ret
  356.  
  357. dir26:    mvi    c,gtdpar    ;current DISK PARAMETER BLOCK
  358.     call    bdos
  359.     inx    h
  360.     inx    h
  361.     mov    a,m        ;Get Block Shift Factor
  362.     sta    bshiftf
  363.     inx    h        ;Bump to Block Mask
  364.     mov    a,m        ;get it
  365.     sta    bmask
  366.     inx    h
  367.     inx    h
  368.     mov    e,m        ;Get Max Block number
  369.     inx    h
  370.     mov    d,m
  371.     xchg
  372.     shld    bmax        ;Put it away
  373.     ret
  374. ;
  375. ;       ERA command - erase a CP/M file
  376. ;       here from: kermit
  377.  
  378. era:    mvi    a,cmifi        ;Parse a file-spec
  379.     lxi    d,fcb        ;into FCB
  380.     call    comnd
  381.     jmp    kermit        ;bad parse
  382.     mvi    a,cmcfm        ;[MF]Get a confirm from the user
  383.     call    comnd        ;[MF]...
  384.     jmp    kermit        ;[MF]NO? try another command
  385.     lxi    d,fcb
  386.     mvi    c,sfirst    ;check if valid
  387.     call    bdos
  388.     inr    a        ;0 if FILE not found
  389.     jnz    era1        ;found at least one
  390.     lxi    d,erms15    ;"unable to find file"
  391.     call    prtstr
  392.     jmp    kermit
  393.  
  394. era1:    lxi    d,fcb
  395.     mvi    c,delf
  396.     call    bdos
  397.     lxi    d,inms18    ;" File(s) erased"
  398.     call    prtstr
  399.     jmp    kermit
  400.  
  401. ; USER - select a new user.  This is an unusual routine in that the user 
  402. ;       enters a number.  The others take on/off or filename (except
  403. ;       set escape
  404. ;
  405. user:    mvi    a,cmnum        ; go parse a number
  406.     call    comnd
  407.     jmp    kermit        ; if we can not do it, quit to command loop
  408.     mvi    a,cmcfm    ; get a confirm from the user
  409.     call    comnd
  410.     jmp    kermit        ; if no, then try another command
  411.     lhld    number        ; else get the number...
  412.     xchg            ; until a non valid digit is typed (eg cr)
  413.     lxi    h,-32        ; if a carry, then ok
  414.     dad    d        ; ... else its above 32
  415.     jc    user1
  416.     xchg            ; restor number in hl again
  417.     mov    a,l        ; Lets save it
  418.     sta    curusr        ; as current user number
  419.     mov    e,l        ; get user no to e...
  420.     mvi    c,usrcod
  421.     call    bdos
  422.     call    getun        ; get user number to temp1 and temp2
  423.     lda    temp2
  424.     cpi    '0'
  425.     jnz    user0        ; dont do ms digit if a zero
  426.     mvi    a,' '
  427. user0:    sta    kerm1        ; save into string etc
  428.     sta    dnam14        ; also for dir command
  429.     lda    temp1
  430.     sta    kerm1+1
  431.     sta    dnam14+1    ; also for dir command
  432.     jmp    kermit
  433.  
  434. user1:    lxi    d,erms23    ; tell user sorry
  435.     call    prtstr
  436.     jmp    kermit
  437.  
  438.  
  439. ;
  440. ;    TYPE - type a file or files to the console.  
  441. ;
  442. ; This utility also used by print, where the characters printed to 
  443. ; the console are also copied to the printer if the prnfl flag 
  444. ; is non-zero.  Uses mfname to type (print) multiple names.  
  445. ; Each file is preceeded with a formfeed character (usually clears 
  446. ; the screen on a VDU)
  447. ;
  448.  
  449. type:    mvi    a,cmifi        ; parse a file name
  450.     lxi    d,fcb        ; let the parser know where the FCB is
  451.     call    comnd
  452.     jmp    type02        ; if error say so
  453.  
  454. type0b:
  455.     xra    a        ; clear some flags for mfname
  456.     sta    mfflg1
  457.     sta    mfflg2
  458.     sta    mfflg3
  459.     sta    fcbcnt        ;[12]...
  460.     lxi    h,fcb0        ; reset the fcb pointers etc
  461.     shld    fcbptr
  462.     call    mfname
  463.     jc    type02        ; match not found
  464.  
  465. ;[MF][10]The following code to type a file using a 1-sector buffer has
  466. ;[MF][10]been replaced by code to use the "big buffer" -- 30-Jan-1991
  467. ;type1:    lxi    d,buff        ; point to the default DMA address
  468. ;    mvi    c,setdma
  469. ;    call    bdos        ; tell bdos where to put the dma address
  470. ;    mvi    a,ff        ; do a form feed
  471. ;    call    typit
  472. ;    xra    a        ; clear the character count
  473. ;    sta    chrcnt
  474. ;
  475. ;type2:    mvi    c,openf        ; open the file for reading
  476. ;    lxi    d,fcb
  477. ;    xra    a        ; but first clear bits of fcb...
  478. ;    sta    fcb+12
  479. ;    sta    fcb+14
  480. ;    sta    fcb+15
  481. ;    sta    fcb+32
  482. ;    call    bdos        ; NOW open the file
  483. ;
  484. ;type20:    mvi    c,readf        ; open up the file and read first sector
  485. ;    lxi    d,fcb
  486. ;    call    bdos
  487. ;;[MF][9]Correct EOF test below (next two instructions)
  488. ;;    inr    a        ; if 0ffh returned, error. Assume EOF
  489. ;;    jz    typex        ; so exit from here
  490. ;    ora    a        ;[MF][9]If error, assume EOF
  491. ;    jnz    typex        ;[MF][9]so exit
  492. ;    lxi    h,0        ; else clear the pointer into the file
  493. ;    shld    typptr
  494. ;
  495. ;
  496. ;type2a:    lxi    d,buff        ;ok, so lets get the byte to print
  497. ;    lhld    typptr
  498. ;    dad    d        ; add offset to the DMA base
  499. ;    mov    a,m        ; and get character to type (print)
  500. ;    ani    7fh        ; make sure it is printable
  501. ;    cpi    20h        ; is it a control character?
  502. ;    jp    type3
  503. ;    cpi    09h        ; if its a tab, then expand it
  504. ;    jnz    type2b
  505. ;
  506. ;type2c:    mvi    a,' '        ; send a space
  507. ;    call    typit        ; type it
  508. ;    lda    chrcnt        ; get the number of chrs so far
  509. ;    ani    7h        ; see of an 8th pos?
  510. ;    jnz    type2c        ; loop until all spaces done, then exit
  511. ;    jmp    type4
  512. ;
  513. ;type2b:    cpi    cr        ; is it a cr or lf?
  514. ;    jnz    type2d
  515. ;    call    typit        ; do a cr
  516. ;    xra    a
  517. ;    sta    chrcnt        ; cr of lf => clear character count
  518. ;    jmp    type4        ; and exit
  519. ;
  520. ;type2d:    cpi    lf
  521. ;    jnz    type2e
  522. ;    call    typit        ; print the character
  523. ;    xra    a
  524. ;    sta    chrcnt        ; cr or lf clears the character count
  525. ;    jmp    type4
  526. ;
  527. ;type2e:    cpi    cntlz        ; is it end of file?
  528. ;    jnz    type2f
  529. ;    jmp    typex        ; yes, so close and try for another file
  530. ;
  531. ;type2f:    push    psw        ; control char - save the character
  532. ;    mvi    a,'^'        ; send control chars as ^A, for ex.
  533. ;    call    typit
  534. ;    pop    psw
  535. ;
  536. ;type3:    call    typit
  537. ;    
  538. ;
  539. ;type4:    lhld    typptr        ; get the pointer
  540. ;    inx    h
  541. ;    shld    typptr        ; up it by one character, and save it.
  542. ;    mov    a,l        ; lets see if the sector has been typed
  543. ;    ana    a
  544. ;    jm    type20        ; if 80h => read new sector
  545. ;    jmp    type2a        ; else just continue along
  546.  
  547. ;[MF][10]The following code uses the "big buffer" to read the file
  548. ;[MF][10]which is to be typed
  549. ;[12]Clear the screen explicitly as some terminals don't respond
  550. ;[12]to the <ff> character.
  551. ;type1:    mvi    a,ff        ; do a form feed
  552. ;    call    typit
  553. type1:    call    clrtop        ;[12] Clear the screen
  554.     xra    a        ; clear the character count
  555.     sta    temp1        ;[MF]alias column counter
  556.  
  557. type2:
  558. ;[12]Eliminate call to openf in favor of call to "getfil"
  559. ;    mvi    c,openf        ; open the file for reading
  560.     lxi    d,fcb
  561. ;    xra    a        ; but first clear bits of fcb...
  562. ;    sta    fcb+12
  563. ;    sta    fcb+14
  564. ;    sta    fcb+15
  565. ;    sta    fcb+32
  566. ;    call    bdos        ; NOW open the file
  567.     call    getfil        ;[12] NOW open the file
  568.  
  569. type20:    call    inbuf        ;[MF]Fill input buffers
  570.     jmp    typex        ;[MF]Tru end-of-file reached
  571.     jmp    type21        ;[MF]Begin typing/printing characters
  572.  
  573. type2a:    lda    chrcnt        ;[MF]Get buffer character counter
  574.     dcr    a        ;[MF]and decrement it
  575.     jm    type20        ;[MF]Get more characters if needed
  576. type21:    sta    chrcnt        ;[MF]else remember new buffer character counter
  577.     lhld    bufpnt        ;[MF]Now get character pointer
  578.     mov    a,m        ; and get character to type (print)
  579.     inx    h        ;[MF]Increment the pointer
  580.     shld    bufpnt        ;[MF]and remember it
  581.     ani    7fh        ; make sure character is printable
  582.     cpi    20h        ; is it a control character?
  583.     jp    type3
  584.     cpi    09h        ; if its a tab, then expand it
  585.     jnz    type2b
  586.  
  587. type2c:    mvi    a,' '        ; send a space
  588.     call    typit        ; type it
  589.     lda    temp1        ;[MF]Get the number of characters so far
  590.     ani    7h        ; see if an 8th pos?
  591.     jnz    type2c        ; loop until all spaces done, then exit
  592.     jmp    type2a        ;[MF]and continue
  593.  
  594. type2b:    cpi    cr        ; is it a cr or lf?
  595.     jnz    type2d
  596.     call    typit        ; do a cr
  597.     xra    a
  598.     sta    temp1        ; cr or lf => clear character count
  599.     jmp    type2a        ;[MF]and continue
  600.  
  601. type2d:    cpi    lf
  602.     jnz    type2e
  603.     call    typit        ; print the character
  604.     xra    a
  605.     sta    temp1        ; cr or lf clears the character count
  606.     jmp    type2a        ;[MF]and continue
  607.  
  608. type2e:    cpi    cntlz        ; is it end of file?
  609.     jnz    type2f
  610.     jmp    typex        ; yes, so close and try for another file
  611.  
  612. type2f:    push    psw        ; control char - save the character
  613.     mvi    a,'^'        ; send control chars as ^A, for ex.
  614.     call    typit
  615.     pop    psw
  616.  
  617. type3:    call    typit
  618.     jmp    type2a        ; and continue along
  619.  
  620. typex:    mvi    c,closf
  621.     lxi    d,fcb
  622.     call    bdos        ; close the file
  623.     mvi    a,cr        ; send cr lf to screen/printer to clear buffers
  624.     call    typit
  625.     mvi    a,lf
  626.     call    typit
  627.     call    mfname        ; and see if there are other files to type
  628.     jnc    type1        ; yup, so go do it
  629.     xra    a        ; make sure the flag is reset
  630.     sta    prnfl
  631.     jmp    kermit        ; then exit.
  632.  
  633. typex0:    mvi    c,closf        ;[MF]Close the file
  634.     lxi    d,fcb        ;[MF]...
  635.     call    bdos        ;[MF]...
  636.     mvi    a,cr        ;[MF]Clear buffers
  637.     call    typit        ;[MF]...
  638.     mvi    a,lf        ;[MF]...
  639.     call    typit        ;[MF]...
  640.     xra    a        ;[MF]Clear flag
  641.     sta    prnfl        ;[MF]...
  642.     lda    takflg        ;[MF]See if we're TAKEing commands
  643.     ani    1        ;[MF]from a file
  644.     cnz    closet        ;[MF]If we are, abort TAKE-file processing
  645.     jmp    kermit        ;[MF]Back to Kermit command-level
  646.  
  647. ; error for file not found for type
  648. type02:    lxi    d,nofile    ; say no file name (its invalid)
  649.     call    prtstr
  650.     xra    a
  651.     sta    prnfl        ; clear the flag
  652.     jmp    kermit        ; so abort
  653.  
  654.  
  655. typit:    mov    e,a
  656.     call    ckqtyp        ; see if a cntl-c or other character from user
  657.     jmp    typit2        ;[MF] Control-C entered, abort
  658.     jc    typit1        ; CNTL-X entered, so abort file [MF]
  659.     push    d        ; save for a bit
  660.     call    outcon        ; send it to the console
  661.     lda    temp1        ; update the number of characters sent[MF]
  662.     inr    a
  663.     sta    temp1        ;[MF]
  664.     pop    d
  665.     lda    prnfl        ; see if we have to print it too
  666.     ana    a
  667.     rz
  668.     call    outprn        ; send character to printer (buffer)
  669.     ret
  670.  
  671. typit1:    pop    d        ; adjust stack again
  672.     jmp    typex        ; and say we are done (for this file)
  673.  
  674. typit2:    pop    d        ;[MF] Adjust the stack
  675.     jmp    typex0        ;[MF] and abort file typeout completely
  676.  
  677.  
  678. ; CKQTYP - CHeck for requested Quiet TYPe (ie hang on a second)
  679. ;    Routine sees if the user has typed ANY key.  If a key HAS been pressed
  680. ;    see if its a Control-c.  If so, flag for an abort, else wait for 
  681. ;    a second entry from the user. If its a Control C, flag an abort
  682. ;    else continue with the print.
  683. ;    note: only the DE  registers maintained.  All others destroyed.
  684. ;    **NOTE** CKQTYP now gives a nonskip return if Control-C is typed,
  685. ;    a skip-return with carry set if a Control-X is typed and a skip-return
  686. ;    with carry clear if any other character is typed as the second
  687. ;    character.
  688.  
  689. ckqtyp:    push    d        ; save the character to be printed
  690.     call    ckchr        ; see if user entered a character
  691.     ani    7fh        ; strip parity etc
  692.     jz    ckqty3        ; nothing entered, so go on as usual (See below)
  693.     cpi    ctrlc        ; control c?
  694.     jz    ckqt1a        ;[MF] Yup, give nonskip return
  695.     cpi    'X'-100o    ;[MF] If Control-X,
  696.     jz    ckqty1        ; yup, set carry and exit
  697. ckqty2:    call    ckchr        ; another character to wait for (ie pause)
  698.     ani    7fh
  699.     jz    ckqty2        ; wait until some input
  700.     cpi    ctrlc        ; if control c, abort
  701.     jz    ckqt1a        ;[MF] ...
  702.     cpi    'X'-100o    ;[MF] Control-X?
  703.     jz    ckqty1        ; yuss, so flag abort file [MF]
  704. ckqty3:    pop    d        ; else restore the character to be typed [MF]
  705. ;    ret            ; no, so continue with type/print
  706.     stc            ;[MF]Set carry
  707.     cmc            ;[MF]Then clear it
  708.     jmp    rskp        ;[MF] Continue with type/print (skip ret)
  709.  
  710. ckqty1:    pop    d        ; restore stack again
  711.     stc            ; set carry and return
  712. ;    ret
  713.     jmp    rskp        ;[MF] ...
  714.  
  715. ckqt1a:    pop    d        ;[MF] Adjust stack
  716.     ret            ;[MF] and return
  717.  
  718. ;[MF][14]No longer need these lines
  719. ;ckqty3:    pop    d        ; restore stack again
  720. ;;    ret
  721. ;    stc            ;[MF] Clear carry
  722. ;    cmc            ;[MF] ...
  723. ;    jmp    rskp        ;[MF] and give skip return
  724.  
  725. ckchr:    call    selcon        ; make sure we are talking to the console
  726.     mvi    e,0ffh        ; see if user has any input for us
  727.     mvi    c,dconio
  728. ;    call    bdos        ;[11]Don't go thru bdos trap
  729.     call    0005h        ;[11]Call bdos directly
  730.     ret            ; This routine does not care what comes back
  731.  
  732.     
  733. ;
  734. ; COPY - routine to copy from a source file to a destination file 
  735. ;    from the Kermit command state.
  736. ;
  737. ;    Note.  This could be tricky, as there are several forms of copy
  738. ;        copy d:source.ext d:dest.ext    (Easy one)
  739. ;        copy d:source.ext d:        (File to another drive)
  740. ;        copy d:source.??? d:        (several files)
  741. ;        copy d:*.* d:            (Several files)
  742. ;
  743. ;    Initially, lets make it top one, and see how we go, ok?
  744. ;
  745. ;
  746. ;Things to do for copy:
  747. ;    1) get source name
  748. ;    2) get target name
  749. ;    3) if both source and destination = abort
  750. ;    4) if source does not exist abort
  751. ;    5) attempt to delete destination file if it exists
  752. ;    6) open source and destination files
  753. ;    7) copy file across
  754. ;    8) close all files
  755. ;    9) return to command mode
  756. ;
  757. copy:            ; Here goes...
  758. ;    1) get source file name
  759.     mvi    a,cmofi        ; go parse a file name
  760.                 ;[MF]Nonwild
  761.     lxi    d,cfcbs        ; use the source for copy FCB (Allows copy
  762.     call    comnd        ; from a TAKE file etc)
  763.     jmp    kermit        ; if error, abort
  764.  
  765. ;    2) get target name
  766.     mvi    a,cmofi        ; go parse a target file name
  767.                 ;[MF]Again, nonwild
  768.     lxi    d,cfcbd        ; use destination fcb
  769.     call    comnd        ; get it
  770.     jmp    kermit        ;[MF]Couldn't.
  771.     mvi    a,cmcfm        ;[MF]Get a confirm from the user
  772.     call    comnd        ;[MF]...
  773.     jmp    kermit        ;[MF]No? try another command
  774.  
  775. ;    3) see if both target and source are equal
  776. copy0:    mvi    b,12        ; we are gonna test drive, file and extention
  777.     lxi    d,cfcbs        ; from source file name...
  778.     lxi    h,cfcbd        ; to destination file name
  779.     xra    a        ; clear flag for difference found
  780.     sta    equflg
  781. copy1:    ldax    d        ; get source file name character
  782.     cmp    m        ; test with targer file name
  783.     jz    copy2        ; if equal, do nothing
  784.     lda    equflg        ; else update flage (ie files are different)
  785.     inr    a
  786.     sta    equflg
  787. copy2:    inx    h
  788.     inx    d
  789.     dcr    b
  790.     jnz    copy1        ; up pointers and test for next char
  791.  
  792.     lda    equflg        ; if still null, then its a daft thing to do
  793.     ana    a
  794.     jnz    copy3        ; its not a daft thing to do
  795.     lxi    d,samems    ; load up "File source and destination the same"
  796.     call    prtstr        ; tell user
  797.     jmp    kermit        ; and try again
  798.  
  799. ;    4) If source does not exist, abort.  Assume we have a full file name.
  800. copy3:
  801.     lxi    d,cfcbs        ; load up source fcb
  802.     mvi    c,openf        ; open file
  803.     call    bdos
  804.     inr    a        ; error on open?
  805.     jnz    copy4
  806.     lxi    d,nofile    ; assume file not found
  807.     call    prtstr
  808.     jmp    kermit        ; and die
  809.  
  810. copy4:    lxi    d,cfcbd        ; load up destination fcb
  811.     mvi    c,delf        ; destroy target name if it exists
  812.     call    bdos        ; ignore error messages
  813.     lxi    d,cfcbd        ; load up destination fcb
  814.     mvi    c,makef        ; make a file
  815.     call    bdos
  816.     inr    a        ; make error?
  817.     jnz    copy4a
  818.     lxi    d,erms12    ; no directory space
  819.     call    prtstr
  820.     jmp    copy7        ; close source file
  821.  
  822. copy4a:    lxi    d,cfcbd        ; load up destination fcb...
  823.     mvi    c,openf        ; for open
  824.     call    bdos
  825.     inr    a        ; error on open?
  826.     jnz    copy5        ; could do with better error detection...
  827.     lxi    d,erms15    ;... but assume its a disk full
  828.     call    prtstr
  829.     jmp    copy7        ; close source file and jmp kermit
  830.  
  831. ;copy5:    lxi    d,buff        ; set default dma address to 80h
  832. ;    mvi    c,setdma
  833. ;    call    bdos
  834. ;
  835. ;copy6:    lxi    d,cfcbs        ; copy routine proper.. get a sector
  836. ;    mvi    c,readf
  837. ;    call    bdos
  838. ;    ana    a        ; error reading the file?
  839. ;    jnz    copy8        ; yes, then cope with it (could be EOF)
  840. ; [MaJoC 910128] The above code, which reads single logical sectors,
  841. ; is grossly inefficient with systems (most of them) with larger physical
  842. ; disk blocks and a single shared read/write buffer.  Use of INBUF below
  843. ; is functionally equivalent at this level, but does actual disk reads
  844. ; by the Big Buffer-ful.
  845. copy5:
  846.     xra    a        ; Initialise INBUF, to force reading of
  847.     sta    seccnt        ;  the first Big Buffer-ful.  Redundant
  848.     sta    endsts        ;  if file opened by GETFIL (or variant).
  849.     sta    eoflag        ;[MF]...
  850.     lxi    h,cfcbs        ;[MF]Copy source fcb to default fcb
  851.     lxi    d,fcb        ;[MF]since INBUF uses the default fcb
  852.     lxi    b,33        ;[MF]...
  853.     call    mover        ;[MF]...
  854. copy6:
  855. ; INBUF returns a pointer to the next logical bufferful via bufpnt, filling
  856. ; the Big Buffer as necessary, with skip return for success and nonskip on
  857. ; error or EOF.
  858.     call    inbuf        ; Start of copy proper: get bufferful.
  859.     jmp    copy8        ; Nonskip return: treat as EOF.
  860.     lhld    bufpnt        ; Skip return => OK: pick up buffer pointer.
  861.     xchg
  862.     mvi    c, setdma    ; Tell system where to write from.
  863.     call    bdos
  864. ; [majoc 910128: end]
  865.     lxi    d,cfcbd        ; send sector to destination
  866.     mvi    c,writef
  867.     call    bdos
  868.     ana    a        ; error on write (disk full?)
  869.     jz    copy6        ; no error, so do another sector.
  870.     lxi    d,erms17    ; say disk is full
  871.     call    prtstr
  872.     lxi    d,cfcbd        ; close the output file...
  873.     mvi    c,closf
  874.     call    bdos
  875.     lxi    d,cfcbd        ; ... and then delete it
  876.     mvi    c,delf
  877.     call    bdos        ; ... and then drop through to...
  878.  
  879. copy7:    lxi    d,cfcbs        ; here to close the source FCB
  880.     mvi    c,closf
  881.     call    bdos
  882.     jmp    kermit
  883.  
  884. copy8:    lxi    d,cfcbd        ; orderly close of destination file
  885.     mvi    c,closf
  886.     call    bdos
  887.     jmp    copy7        ; now close the source file as well.
  888.  
  889. ;
  890. ;[MF]RENAME - Rename a file
  891. ;
  892. rename:    mvi    a,cmofi        ;[MF]Get nonwild filename
  893.     lxi    d,cfcbs        ;[MF]Use "COPY" fcb's
  894.     call    comnd        ;[MF]...
  895.     jmp    kermit        ;[MF]Couldn't get it.
  896.     mvi    a,cmofi    ;[MF]Get filespec to rename it to
  897.     lxi    d,cfcbd        ;[MF]...
  898.     call    comnd        ;[MF]...
  899.     jmp    kermit        ;[MF]Couldn't.
  900. renam0:    lxi    d,cfcbs        ;[MF]See if file to be renamed exists
  901.     mvi    c,openf        ;[MF]by trying to open it
  902.     call    bdos        ;[MF]...
  903.     inr    a        ;[MF]Does the file exist?
  904.     jnz    renam1        ;[MF]Yes
  905.     lxi    d,nofile    ;[MF]No, inform the user
  906.     call    prtstr        ;[MF]...
  907.     jmp    kermit        ;[MF]and bomb
  908. renam1:    lxi    d,cfcbd        ;[MF]Point to rename filespec
  909.     mvi    c,openf        ;[MF]Set function code to
  910.     call    bdos        ;[MF]See if rename file exists
  911.     inr    a        ;[MF]Does it?
  912.     jz    renam2        ;[MF]No
  913.     lxi    d,erms31    ;[MF]Yes, complain
  914.     call    prtstr        ;[MF]...
  915.     jmp    kermit        ;[MF]and depart with tail between legs
  916. renam2:    lxi    h,cfcbd        ;[MF]Now get rename filespec again
  917.     lxi    d,cfcbs+16    ;[MF]and where to copy it to
  918.     lxi    b,16        ;[MF]We copy drive, filename, filetype, extent
  919.     call    mover        ;[MF]...
  920.     lxi    d,cfcbs        ;[MF]Point to fcb for rename
  921.     mvi    c,renam    ;[MF]Get rename function
  922.     call    bdos        ;[MF]Try to rename the file
  923.     inr    a        ;[MF]Did we succeed?
  924.     jnz    kermit        ;[MF]Yes, done
  925.     lxi    d,erms16    ;[MF]No, complain
  926.     call    prtstr        ;[MF]...
  927.     jmp    kermit        ;[MF]and start over
  928.  
  929.  
  930. IF lasm
  931.     LINK    CPSWLD
  932. ENDIF;lasm  [Toad Hall]
  933.