home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / ccpm86 / cn8utl.a86 < prev    next >
Text File  |  2020-01-01  |  23KB  |  1,012 lines

  1. ;* * * * * * * * * * * * * * * version 2.9 * * * * * * * * * * * * * * *
  2. ; [35]  Correct TAKE file problems under Concurrent CP/M [mjh]
  3. ; [34c]    Make DMA initialization and buffer allocation global
  4. ; [34b]    Add LOCAL TYPE command
  5. ; [34a]    Fix bugs in directory listing file sizes
  6. ;* * * * * * * * * * * * * * * version 2.8 * * * * * * * * * * * * * * *
  7. ; [32d]    Add routines to get disk parameters for space calculation
  8. ; [32a]    Add routines to get and set default disk and user numbers
  9. ;* * * * * * * * * * * * * * * version 2.7 * * * * * * * * * * * * * * *
  10. ; [29c]  Clear FCB prior to opening or creating a file.
  11. ; [29b]  Add TAKE command file processing.
  12. ;    RonB, 04/08/84
  13. ;* * * * * * * * * * * * * * * version 2.6 * * * * * * * * * * * * * * *
  14. ;  [24a] Add terminal session logging
  15. ;    RonB, 03/15/84
  16. ; * * * * * * * * * * * * * * *  version 2.4  * * * * * * * * * * * * * * *
  17. ;  [20e] Add regular console status check, in addition to direct I/O check.
  18. ;    RonB,03/02/84
  19. ;  [19c] Give "bdos" mnemonic for vector 224.
  20. ; * * * * * * * * * * * * * * *  version 2.1  * * * * * * * * * * * * * * *
  21. ;  [7]    Do tab expansion and suppress nulls while in telnet mode.
  22. ;    RonB,12/24/83
  23. ; * * * * * * * * * * * * * * *  version 2.0  * * * * * * * * * * * * * * *
  24.  
  25. ; BDOS command codes
  26.  
  27. bdos    equ    224
  28. reset    EQU    00H
  29. conin    EQU    01H
  30. conout    EQU    02H
  31. rdrin    EQU    03H
  32. punout    EQU    04H
  33. lstout    EQU    05H
  34. dconio    EQU    06H
  35. gtiob    EQU    07H
  36. prstr    EQU    09H
  37. consta    EQU    0BH
  38. resetd    EQU    0DH                        ;[32a]
  39. stdrv    EQU    0EH                        ;[32a]
  40. opnfil    EQU    0FH
  41. clsfil    EQU    10H
  42. sfirst    EQU    11H
  43. snext    EQU    12H
  44. delf    EQU    13H
  45. readf    EQU    14H
  46. writef    EQU    15H
  47. makef    EQU    16H
  48. gtdrv    EQU    19H                        ;[32a]
  49. gtalv    EQU    1BH                        ;[32d]
  50. gtrov    EQU    1DH                        ;[32d]
  51. statr    EQU    1EH
  52. gtdpb    EQU    1FH                        ;[32d]
  53. stusr    EQU    20H                        ;[32a]
  54. readr    EQU    21H
  55. writer    EQU    22H
  56. cflsz    EQU    23H
  57. dmaset    EQU    1AH
  58. dmabas    EQU    33H
  59. allocm    EQU    37H                        ;[32d]
  60. freem    EQU    39H                        ;[32d]
  61.  
  62.     DSEG $                        ;[29b] begin
  63.  
  64. ; TAKE command file processing data area.
  65.  
  66. tkfcb    db    0,'KERMIT  INI',0,0,0,0        ;FCB with default name
  67.     rb    19
  68. tkbuf    rb    80h                ;Input buffer
  69. tkptr    dw    0                ;Buffer pointer
  70. tkflg    db    1                ;Initially enable file input
  71. tkusr    rb    1                ;User area at TAKE time [35]
  72. tkdrv    rb    1                ;Default drive at TAKE time [35]
  73.  
  74. ; Messages and storage for directory operations
  75.  
  76. dirm01    db    'Drive $'                    ;[32d] begin
  77. dirm02    db    ', User $'
  78. dirm03    db    '    K$'
  79. dirm04    db    ' : $'        ;directory column separator
  80. dirm05    db    ' files, $'
  81. dirm06    db    'K listed$'
  82. dirm07    db    '  $'        ;displayed at start of each row
  83. eram01    db    tab,'Delete? $'
  84. eram02    db    tab,'...not deleted$'
  85. eram03    db    tab,'...deleted$'
  86. eram04    db    ' $'        ;displayed at start of each row
  87. erahlp    db    cr,lf,'Respond with ''Y'' to delete this file,'
  88.     db    cr,lf,'             ''N'' to bypass this file,'
  89.     db    cr,lf,'         or ''ESC'' to return to the Kermit-86> prompt.$'
  90. spcm01    db    'K (out of $'
  91. spcm02    db    'K) remaining on drive $'
  92. morm01    db    '--more--$'
  93. morm02    db    'Return: next line, Space: next page, ^X: next file, ^Z: quit$'
  94. membuf    rb    5        ;memory control block
  95. dirbuf    rb    16
  96. dindex    dw    0        ;index to first entry in row
  97. dlngth    dw    0        ;length of directory list
  98. dircnt    dw    0        ;files in directory list
  99. dirsiz    dw    0        ;kbytes in directory list
  100. remK    dw    0        ;Kbytes remaining on disk
  101. maxK    dw    0        ;Kbytes available if disk was empty
  102. DSM    dw    0        ;drive maximum allocation blocks
  103. KPB    dw    0        ;drive Kbytes Per Block        ;[32d] end
  104.  
  105.     CSEG $            ;Resume coding segment.
  106.  
  107. tkst:    cmp    tkptr, 0    ;Is file open yet?
  108.     jne    tkst1
  109.     call    tkopn
  110.      jmp    r        ;If open failure
  111.     call    getusr        ;get user area            ; [35]
  112.     mov    tkusr, al    ;and save it            ; [35]
  113.     call    getdrv        ;get default drive        ; [35]
  114.     mov    tkdrv, al    ;and save that too        ; [35]
  115. tkst1:    mov    bx, tkptr    ;Do we need a new record?
  116.     cmp    bx, offset tkbuf+80h
  117.     jb    tkst2
  118.     call    tkread
  119.     mov    bx, tkptr
  120. tkst2:    cmp    byte ptr [bx], 1Ah    ;Are we at end of file?
  121.     je    tkst3
  122.     jmp    rskp        ;If not, say we have a character.
  123. tkst3:    call    tkcls        ;  otherwise end the file
  124.     jmp    r
  125.  
  126. tkin:    call    tkst        ;If no file input,
  127.      jmp    bin        ;  get it from the console.
  128.     mov    bx, tkptr
  129.     mov    al, [bx]    ;Get character from command file record.
  130.     inc    tkptr
  131.     cmp    al, lf        ;Ignore <lf> in file
  132.     je    tkin
  133.     push    ax
  134.     mov    dl, al        ;Echo it to the display.
  135.     call    bout
  136.     pop    ax
  137.     ret
  138.  
  139. tkopn:    mov    dx, offset tkfcb ;Open the command file
  140.     call    fcbzer        ;zero fcb trailer
  141.     mov    cl, opnfil
  142.     int    bdos
  143.     inc    al
  144.     jz    tkopn1
  145.     mov    tkptr, offset tkbuf+80h ;If success, show we need a read
  146.     jmp    rskp
  147. tkopn1:    mov    tkflg, 0    ;On failure, turn off file input flag.
  148.     ret
  149.  
  150. ;                                ; [35] start
  151. ;  To overcome the read/close checksum failure problems with concurrent
  152. ;  CP/M, the user area and default drive at the time of opening the TAKE
  153. ;  file must be temporarily restored.  Code in the "tkopn" code saves the
  154. ;  default drive and user areas at that time, and the following two routines
  155. ;  set it back (tkstud) and restore the current default (tkrsud).  [mjh]
  156. ;
  157.  
  158.     DSEG $
  159.  
  160. tmpusr    rb    1        ; current default USER area
  161. tmpdrv    rb    1        ; current default drive
  162.  
  163.     CSEG $
  164.  
  165. tkstud:    call    getusr        ;get current user number
  166.     mov    tmpusr, al    ;and save it
  167.     call    getdrv        ;get current default drive
  168.     mov    tmpdrv, al    ;and save that too
  169.     mov    dl, tkusr    ;reset to USER area at TAKE time
  170.     call    setusr
  171.     mov    dl, tkdrv    ;reset to default drive at TAKE time
  172.     call    setdrv
  173.     ret
  174.  
  175.  
  176. tkrsud:    mov    dl, tmpusr    ;restore default USER area
  177.     call    setusr
  178.     mov    dl, tmpdrv    ;restore default drive
  179.     call    setdrv
  180.     ret                            ; [35] end
  181.  
  182. tkread:    mov    dx, offset tkbuf ;Set dma to our location.
  183.     call    setdma
  184.     call    tkstud        ;set user and drive as at TAKE open  [35]
  185.     mov    dx, offset tkfcb
  186.     call    sinr        ;Read a record.
  187.  
  188.     push    ax        ;save error status        ; [35] start
  189.     call    tkrsud        ;restore default drive/user area 
  190.     pop    ax        ;restore error status        ; [35] end
  191.  
  192.     cmp    al, 0
  193.     je    tkrd1
  194.     mov    tkbuf, 1Ah    ;If failure, load buffer with EOF.
  195. tkrd1:    mov    tkptr, offset tkbuf    ;Reinitialize buffer pointer.
  196.     call    inidma        ;Reset dma to normal.
  197.     ret
  198.  
  199. tkcls:    call    tkstud        ;set user/def. drive as at TAKE time [35]
  200.     mov    dx, offset tkfcb ;Close command file.
  201.     call    closf
  202.     call    tkrsud        ; restore default user area/drive    [35]
  203.     mov    tkflg, 0    ;Turn off file input flag.
  204.     ret                            ;[29b] end
  205.  
  206.  
  207. ; Local directory operation
  208.  
  209. dirutl:    call    getwld        ;fill buffer with matching names
  210.      jmp    r        ;on failure a message has already been printed
  211.     cmp    dircnt,0
  212.     jne    locd3
  213.      ret
  214. locd3:    mov    dirsiz,0
  215.     mov    ax,dircnt
  216.     dec    ax        ;calculate number of entries in each column
  217.     shr    ax,1        ; = ((count-1)/4)+1
  218.     shr    ax,1
  219.     inc    ax
  220.     mov    dlngth,ax
  221.     call    tcrlf
  222.     mov    dx, offset dirm01 ;print header: Drive X, User nn:
  223.     call    tcrmsg
  224.     mov    dl,fcb        ;display the drive letter
  225.     add    dl,'A'-1
  226.     call    bout
  227.     mov    dx, offset dirm02
  228.     call    tmsg
  229.     mov    al,defusr    ;display the user number
  230.     cbw
  231.     call    nout
  232.     mov    dl,':'
  233.     call    bout
  234.     mov    dindex,0    ;table entry in first column
  235.     mov    cx,dlngth
  236. locd4a:    push    cx
  237.     mov    dx, offset dirm07 ;Start new row
  238.     call    tcrmsg
  239.     mov    si,dindex
  240.     mov    cx,4
  241. locd4b:    push    si
  242.     push    cx
  243.     push    ds
  244.     mov    ds,word ptr membuf
  245.     mov    cl,4        ;change entry number to table offset
  246.     shl    si,cl
  247.     inc    si        ;skip user number
  248.     mov    cx,8        ;Eight characters in filename
  249. locd5b:    lodsb            ;get a filename character
  250.     mov    dl,al
  251.     push    cx
  252.     call    bout        ;print it
  253.     pop    cx
  254.     loop    locd5b
  255.     mov    dl,'.'        ;separate filename and type with a period
  256.     call    bout
  257.     mov    cx,3        ;Three characters in file type
  258. locd5c:    lodsb            ;get a file type character
  259.     mov    dl,al
  260.     push    cx
  261.     call    bout        ;print it
  262.     pop    cx
  263.     loop    locd5c
  264.     lodsw            ;get file size
  265.     pop    ds
  266.     add    dirsiz,ax    ;add filesize to listing size
  267.     mov    di, offset dirm03 ;message for file size (____K)
  268.     mov    cx,3
  269. locd5d:    mov    byte ptr [di],' ' ;first blank out the last size
  270.     inc    di
  271.     loop    locd5d
  272.     mov    bx,10
  273. locd5e:    mov    dx,0        ;fill in current size
  274.     div    bx
  275.     add    dl,'0'
  276.     mov    [di],dl
  277.     dec    di
  278.     cmp    ax,0
  279.     jne    locd5e
  280.     mov    dx, offset dirm03 ;print size message
  281.     call    tmsg
  282.     pop    cx
  283.     cmp    cx,1        ;follow all but last column with separator
  284.     je    locd5f
  285.     mov    dx, offset dirm04 ;print column separator
  286.     push    cx
  287.     call    tmsg
  288.     pop    cx
  289. locd5f:    pop    si
  290.     add    si,dlngth
  291.     cmp    si,dircnt
  292.     jae    locd6
  293.     loop    locd4b
  294. locd6:    inc    dindex
  295.     pop    cx
  296.     dec    cx
  297.     jz    locd8
  298.     jmp    locd4a
  299. locd8:    call    tcrlf        ;end the last row
  300.     call    tcrlf        ;add a blank row
  301.     mov    ax,dircnt    ;display file count
  302.     call    nout
  303.     mov    dx, offset dirm05
  304.     call    tmsg
  305.     mov    ax,dirsiz    ;display total file size
  306.     call    nout
  307.     mov    dx, offset dirm06
  308.     call    tmsg
  309.     jmp    rskp
  310.  
  311.  
  312. ; Erase utility function
  313.  
  314. erautl:    call    getwld
  315.      jmp    r        ;On error a message has already been printed
  316.     mov    dindex,0
  317. loce3:    mov    si,dindex
  318.     cmp    si,dircnt
  319.     jb    loce4
  320.     jmp    loce9
  321. loce4:    mov    cl,4
  322.     shl    si,cl
  323.     inc    si
  324.     mov    di, offset fcb+1    ;FCB already has drive code
  325.     push    ds
  326.     pop    es
  327.     mov    ds, word ptr membuf
  328.     mov    cx,15
  329.     rep    movsb
  330.     push    es
  331.     pop    ds
  332.     mov    dx, offset eram04    ;Start new row
  333.     call    tcrmsg
  334.     mov    dx, offset fcb
  335.     call    tfile
  336.     mov    dx, offset eram01    ;'<tab>Delete? '
  337.     call    tmsg
  338. loce5a:    call    dbinst            ;clear out all typeahead
  339.      jmp    loce5b
  340.     call    dbin
  341.     jmps    loce5a
  342. loce5b:    call    dbin            ;get response
  343.     cmp    al,0            ;NUL is ignored
  344.     je    loce5b
  345.     cmp    al,cr            ;CR bypasses file
  346.     je    loce5d
  347.     cmp    al,' '            ;any nonprintable char aborts
  348.     jb    loce8
  349.     cmp    al,7Fh
  350.     jae    loce8
  351.     push    ax
  352.     mov    dl,al            ;echo the printable response
  353.     call    bout
  354.     pop    ax
  355.     cmp    al,'?'            ;request for help?
  356.     jne    loce5c
  357.     mov    dx, offset erahlp    ;help message
  358.     call    tcmsgc
  359.     jmp    loce3
  360. loce5c:    or    al,'a'-'A'        ;convert to lower case
  361.     cmp    al,'y'
  362.     je    loce6
  363. loce5d:    mov    dx, offset eram02    ;'    ...not deleted'
  364.     call    tmsg
  365.     jmp    loce7
  366. loce6:    cmp    byte ptr fcb+14,0    ;make file read-write if necessary
  367.     je    loce6a
  368.     mov    dx, offset fcb
  369.     call    setatr
  370. loce6a:    mov    dx, offset fcb        ;delete file
  371.     call    delete
  372.     mov    dx, offset eram03     ;'    ...deleted'
  373.     call    tmsg
  374. loce7:    inc    dindex
  375.     jmp    loce3
  376. loce8:    mov    dx, offset eram02    ;'    ...not deleted' when aborting
  377.     call    tmsg
  378. loce9:    call    tcrlf
  379.     jmp    rskp
  380.  
  381.  
  382. ; Type utility function
  383.  
  384. typutl:    call    getwld
  385.      jmp    r        ;On error a message has already been printed
  386.     mov    dindex,0
  387. loct3:    mov    si,dindex        ;Get next filename in table
  388.     cmp    si,dircnt
  389.     jb    loct4
  390.     jmp    loct9
  391. loct4:    mov    dlngth,1
  392.     mov    cl,4
  393.     shl    si,cl
  394.     inc    si
  395.     mov    di, offset fcb+1
  396.     push    ds
  397.     pop    es
  398.     mov    ds, word ptr membuf
  399.     mov    cx,15
  400.     rep    movsb
  401.     push    es
  402.     pop    ds
  403.     call    tcrlf            ;Display the filename
  404.     mov    dx, offset fcb
  405.     call    tfile
  406.     call    tcrlf
  407.     mov    dx, offset fcb
  408.     call    openf            ;Open the file
  409.     inc    al
  410.     jnz    loct5
  411.     jmp    loct6b
  412. loct5:    mov    dx, offset fcb        ;Read a record
  413.     call    sinr
  414.     cmp    al,0
  415.     jne    loct6
  416.     mov    bx,offset dma
  417. loct5a:    mov    dl,[bx]            ;Get a character
  418.     cmp    dl,1Ah
  419.     je    loct6
  420.     and    dl,7Fh
  421.     push    bx
  422.     push    dx
  423.     call    bout            ;Print the character
  424.     pop    dx
  425.     cmp    dl,lf
  426.     jne    loct5b
  427.     inc    dlngth            ;Count lf characters
  428.     cmp    dlngth,22        ;If more than 22, then pause for input
  429.     jb    loct5b
  430.     call    more
  431.      jmp    loct5c
  432. loct5b:    pop    bx
  433.     inc    bx
  434.     cmp    bx,offset dma+128
  435.     jb    loct5a
  436.     jmps    loct5
  437. loct5c:    pop    bx
  438.     jmps    loct6a
  439. loct6:    mov    ax,dindex        ;EOF in file
  440.     inc    ax
  441.     cmp    ax,dircnt
  442.     jae    loct6a
  443.     call    tcrlf
  444.     call    more
  445.      jmp    loct6a
  446. loct6a:    mov    dx, offset fcb        ;Close file
  447.     call    closf
  448.     call    tcrlf
  449. loct6b:    inc    dindex            ;Move on to next file
  450.     jmp    loct3
  451. loct9:    jmp    rskp
  452.  
  453.  
  454. more:    call    revon
  455.     mov    dx,offset morm01    ;Show --more-- message
  456.     call    tmsg
  457.     call    revoff
  458. more1:    call    dbin            ;Get response
  459.     cmp    al,0            ; ignore nulls
  460.     je    more1
  461.     push    ax
  462.     call    clrlin
  463.     mov    dl,tab            ;This is to fool CP/M so it
  464.     call    bout            ;  gets tab stops right
  465.     mov    dl,cr
  466.     call    bout
  467.     pop    ax
  468.     and    al,7Fh
  469.     cmp    al,'?'            ;? gives help
  470.     jne    more2
  471.     call    revon
  472.     mov    dx,offset morm02    ;Show help message
  473.     call    tmsg
  474.     call    revoff
  475.     jmps    more1
  476. more2:    cmp    al,cr            ;cr, lf go to next line
  477.     je    more4
  478.     cmp    al,lf
  479.     je    more4
  480.     mov    dlngth,0        ;Everything else resets line count
  481.     cmp    al,0Fh            ;^O, ^X go to next file
  482.     je    more6
  483.     cmp    al,18h
  484.     je    more6
  485.     cmp    al,03h            ;^C, ^Z, q quit
  486.     je    more5
  487.     cmp    al,1Ah
  488.     je    more5
  489.     or    al,'a'-'A'
  490.     cmp    al,'q'
  491.     je    more5
  492. more4:    jmp    rskp            ;Next line, page
  493. more5:    mov    ax,dircnt        ;Quit
  494.     mov    dindex,ax
  495. more6:    ret                ;Next file
  496.  
  497.  
  498. ; Space remaining utility
  499.  
  500. spcutl:    call    getprm        ;Get the disk parameters for calculation
  501.     call    tcrlf
  502.     mov    ax,remK        ;Display the number of Kbytes remaining
  503.     call    nout
  504.     mov    dx, offset spcm01
  505.     call    tmsg
  506.     mov    ax,maxK        ;And the total number on the drive.
  507.     call    nout
  508.     mov    dx, offset spcm02
  509.     call    tmsg
  510.     mov    dl,fcb        ;Finally say which drive it is.
  511.     add    dl,'A'-1
  512.     call    bout
  513.     mov    dl,':'
  514.     call    bout
  515.     call    tcrlf
  516.     jmp    rskp
  517.  
  518.  
  519. ; get and save disk parameters which relate to block allocation and size
  520.  
  521. getprm:    mov    newdrv,0    ;initialize flag
  522.     mov    dl,fcb        ;specified drive must be the default
  523.     dec    dl        ; which is true if drive was not specified
  524.     jl    gprm2
  525.     cmp    dl,defdrv    ; or if specified drive matches the default
  526.     je    gprm2
  527.     mov    newdrv,0FFh    ;otherwise show that we changed default
  528.     push    dx
  529.     call    getrov        ;make sure the desired drive is write enabled
  530.     pop    dx        ; or else the data may be inaccurate
  531.     mov    cl,dl
  532.     mov    ax,1
  533.     shl    ax,cl
  534.     and    ax,bx
  535.     jz    gprm1
  536.     push    dx
  537.     call    rstdsk        ;if read-only, reset all drives
  538.     pop    dx
  539. gprm1:    call    setdrv        ;select the new drive as default
  540. gprm2:    push    es
  541.     call    getdpb        ;get address of DPB in ES:BX
  542.     mov    cl,es:2[bx]    ;get Block Shift Factor
  543.     sub    cl,3
  544.     mov    ax,1
  545.     shl    ax,cl
  546.     mov    KPB,ax        ;save Kbytes Per Block
  547.     mov    cx,es:5[bx]    ;get DSM maximum block number
  548.     mov    DSM,cx        ;save for file size and allocation calculation
  549.     inc    cx        ;number of blocks includes block 0
  550.     mul    cx
  551.     mov    maxK,ax        ;Maximum number of Kbytes
  552.     mov    remK,ax        ;Kbytes remaining
  553.     mov    ax,es:7[bx]    ;subtract directory allocation from maxK
  554.     mov    cl,5
  555.     shr    ax,cl
  556.     inc    ax
  557.     sub    maxK,ax
  558.     call    getalv        ;get address of allocation vector in ES:BX
  559.     mov    ax,DSM        ;compute length of vector = (DSM/8)+1
  560.     mov    cl,3
  561.     shr    ax,cl
  562.     inc    ax
  563.     mov    cx,ax
  564.     mov    ax,0        ;Count allocated blocks:
  565. gprm3:    mov    dl,es:[bx]    ;for each byte in vector,
  566.     inc    bx
  567.     push    cx
  568.     mov    cx,8        ;  for each bit in byte,
  569. gprm4:    test    dl,1
  570.     jz    gprm5
  571.     inc    ax        ;    if bit is set, then block is allocated
  572. gprm5:    shr    dl,1
  573.     loop    gprm4
  574.     pop    cx
  575.     loop    gprm3
  576.     mul    KPB        ;convert allocated blocks to Kbytes
  577.     sub    remK,ax        ;subtract allocated Kbytes from remK
  578.     pop    es
  579.     cmp    newdrv,0    ;reset default drive if we changed it
  580.     je    gprm6
  581.     mov    dl,defdrv
  582.     call    setdrv
  583. gprm6:    ret
  584.  
  585.  
  586. ; This subroutine fills the previously allocated memory buffer with a sorted
  587. ; list of filenames matching the wild name in fcb.  On failure, if there were
  588. ; no files, it prints an appropriate error message and simply returns.  On
  589. ; success, it returns to the skip location with the number of entries
  590. ; in the list in dircnt.  Each buffer entry is 16 bytes long and contains
  591. ; the user number at offset 0, the filename (with all attribute bits stripped)
  592. ; at offset 1-11, the allocated size in Kbytes at offset 12-13, and the
  593. ; read-only and system flags at offsets 14 and 15.
  594.  
  595. getwld:    mov    byte ptr fcb+12,'?' ;Match any extent
  596.     mov    byte ptr fcb+13,'?'
  597.     mov    byte ptr fcb+14,'?'
  598.     call    getprm        ;get disk parameters for size calculation
  599.     mov    dircnt,0    ;zero file count and total space occupied
  600.     mov    dx, offset fcb
  601.     call    gtjfn        ;get first filename
  602.     cmp    al,0FFh
  603.     jne    gwld2
  604.     mov    dx, offset erms15 ;unable to find file
  605.     call    tcrmsg
  606.     mov    dx, offset fcb
  607.     call    tfile
  608.      ret
  609. gwld2:    mov    cl,5        ;find file directory entry
  610.     shl    al,cl
  611.     mov    ah,0
  612.     mov    si, offset dma
  613.     add    si,ax        ;pointer to filename (incl. user number)
  614.     mov    di, offset dirbuf
  615.     push    ds
  616.     pop    es
  617.     mov    ax,9[si]    ;get read-only and system flags
  618.     and    ax,8080h    ;keep only attribute bits
  619.     mov    14[di],ax    ;save flags at end of buffer
  620.     mov    cx,12
  621. gwld2a:    lodsb
  622.     and    al,7Fh        ;get rid of all attribute bits
  623.     stosb
  624.     loop    gwld2a
  625.     add    si,4        ;look at allocation area
  626.     mov    ax,0        ;initialize block count
  627.     cmp    DSM,256        ;if <256 blocks, then each takes a byte
  628.     jb    gwld2c
  629.     mov    cx,8        ;8 blocks, one word each
  630. gwld2b:    cmp    word ptr [si],0
  631.     je    gwld2e
  632.     inc    si
  633.     inc    si
  634.     inc    ax
  635.     loop    gwld2b
  636.     jmps    gwld2e
  637. gwld2c:    mov    cx,16        ;16 blocks, one byte each
  638. gwld2d:    cmp    byte ptr [si],0
  639.     je    gwld2e
  640.     inc    si
  641.     inc    ax
  642.     loop    gwld2d
  643. gwld2e:    mul    KPB        ;convert blocks to kbytes
  644.     stosw            ;save this FCB's allocation
  645.     mov    ax,dircnt
  646.     cmp    ax,word ptr membuf+2 ;don't exceed buffer length
  647.     jb    gwld2f
  648.     mov    dx,offset erms27 ; if memory exceeded, print warning
  649.     call    tcmsgc        ;     and use what info we have
  650.     jmp    gwld4
  651. gwld2f:    mov    si, offset dirbuf ;go back to start of filename
  652.     mov    es,word ptr membuf ;find correct location in sorted file list
  653.     mov    di,0
  654.     mov    cx,dircnt    ;number of entries already in list
  655.     jcxz    gwld3e
  656. gwld3a:    push    cx
  657.     push    si
  658.     push    di
  659.     mov    cx,12
  660.     repe    cmpsb
  661.     jb    gwld3d        ;table entry greater than this file, insert
  662.     ja    gwld3c        ;table entry less than this file, keep looking
  663.     lodsw            ;else table entry same as file
  664.     add    es:[di],ax    ; ...add this FCB's allocation to size
  665. gwld3b:    pop    di
  666.     pop    si
  667.     pop    cx
  668.     jmp    gwld3f        ;go get next filename
  669. gwld3c:    pop    di        ;haven't found insert location yet
  670.     pop    si
  671.     pop    cx
  672.     add    di,16
  673.     loop    gwld3a
  674.     jmp    gwld3e        ;if greater than all entries, insert at end
  675. gwld3d:    pop    di        ;insertion point
  676.     pop    si        ;filename pointer
  677.     pop    ax        ;number of entries following insertion point
  678.     push    si
  679.     push    di
  680.     mov    cl,4        ;each entry occupies 16 bytes
  681.     shl    ax,cl
  682.     add    di,ax
  683.     dec    di
  684.     mov    si,di        ;point to last byte of table
  685.     add    di,16        ;move last part down 16 bytes
  686.     mov    cx,ax
  687.     push    ds        ;save filename segment
  688.     push    es        ;make all action in table segment
  689.     pop    ds
  690.     std            ;decrement pointers after each move
  691.     rep    movsb
  692.     cld
  693.     pop    ds        ;restore filename segment
  694.     pop    di        ;insertion point
  695.     pop    si        ;filename pointer
  696. gwld3e:    mov    cx,16        ;insert filename in table
  697.     rep    movsb
  698.     inc    dircnt        ;count new entry
  699. gwld3f:    mov    dx, offset fcb    ;look for another matching filename
  700.     call    gnjfn
  701.     cmp    al,0FFh
  702.     je    gwld4
  703.     jmp    gwld2        ;go process next filename
  704. gwld4:    push    ds
  705.     pop    es
  706.     jmp    rskp
  707.  
  708. ; General output utility routines
  709.  
  710. tmsgcr:    call    tmsg        ;Print the string
  711.     call    tcrlf        ;Print a CRLF.
  712.     ret
  713.  
  714. tcrmsg:    push    dx        ;Don't trash our string.
  715.     call    tcrlf        ;Print a CRLF.
  716.     pop    dx        ;Restore our string.
  717.     call    tmsg        ;Print the string
  718.     ret
  719.  
  720. tcmsgc:    push    dx        ;Don't trash our string.
  721.     call    tcrlf        ;Print a CRLF.
  722.     pop    dx        ;Restore our string.
  723.     call    tmsg        ;Print the string
  724.     call    tcrlf        ;Print a CRLF.
  725.     ret
  726.  
  727. tcrlf:    mov    dl,cr        ;print a crlf
  728.     call    bout
  729.     mov    dl,lf
  730.     call    bout
  731.     ret
  732.  
  733. tmsg:    push    bx        ;Don't clobber my ACs.
  734.     mov    cl, prstr    ;Ask BDOS for string printing.
  735.     int    bdos        ;What a way to call the BDOS.
  736.     pop    bx
  737.     ret
  738.  
  739. tfile:    mov    bx, dx        ;Print filename in [dx]'s FCB    ;[24a] begin
  740.     mov    dl, [bx]    ;If explicit drive number, display it.
  741.     cmp    dl, 0
  742.     je    tfil1
  743.     add    dl, 'A'-1
  744.     push    bx
  745.     call    bout
  746.     mov    dl, ':'
  747.     call    bout
  748.     pop    bx
  749. tfil1:    mov    cx, 11        ;Now display 11 chars of filename
  750. tfil2:    push    cx
  751.     cmp    cx, 3        ;With period before file type
  752.     jne    tfil3
  753.     push    bx
  754.     mov    dl, '.'
  755.     call    bout
  756.     pop    bx
  757. tfil3:    inc    bx
  758.     mov    dl, [bx]
  759.     cmp    dl, ' '        ;Don't include spaces
  760.     je    tfil4
  761.     push    bx
  762.     call    bout
  763.     pop    bx
  764. tfil4:    pop    cx
  765.     loop    tfil2
  766.     ret                            ;[24a] end
  767.  
  768.  
  769. bout:    mov    cl, conout    ;Ask BDOS for character printing.
  770.     int    bdos
  771.     ret
  772.  
  773. bin:    cmp    tkflg, 0    ;Check for command file input.    ;[29b] begin
  774.     je    bin1
  775.     jmp    tkin                        ;[29b] end
  776. bin1:    mov    cl, conin    ;Get a char from the console.
  777.     int    bdos
  778.     ret
  779.  
  780. binst:    cmp    tkflg, 0    ;Check for command file input.    ;[29b] begin
  781.     je    binst1
  782.     jmp    tkst                        ;[29b] end
  783. binst1:    mov    cl, consta    ;Console input status check    ;[20e] begin
  784.     int    bdos
  785.     or    al, al        ;Result 0 if no character ready
  786.     jz    bins2
  787.     jmp    rskp        ;Return SKIP if character ready
  788. bins2:    ret                            ;[20e] end
  789.  
  790. dbout:    cmp    dl, 0        ;Skip null fillers. 
  791.     je    dbout3
  792.     call    logchr        ;Log the character if necessary ;[24a]
  793.     call    dotab        ;Do any necessary tab expansion.
  794.     jmp    r        ; No more chars to output.
  795. dbout2:    mov    cl, dconio    ;Put a char to the console.
  796.     int    bdos
  797. dbout3:    ret
  798.  
  799. dbin:    push    dx
  800.     mov    cl, dconio    ;Get a char from the console without
  801.     mov    dl, 0FFH    ; interference.
  802.     int    bdos
  803.     pop    dx
  804.     ret
  805.  
  806. dbinst:    push    dx
  807.     mov    cl, dconio    ;Check the console's input status.
  808.     mov    dl, 0FEH
  809.     int    bdos
  810.     pop    dx
  811.     or    al, al        ;Result 0 if no character ready ;[20e] begin
  812.     jz    dbins2
  813.     jmp    rskp        ;Return SKIP if character ready
  814. dbins2:    ret                            ;[20e] end
  815.  
  816. ;Log the terminal output character
  817.  
  818. logchr:    cmp    logfil, 0    ;Only log if file is open    ;[24a] begin
  819.     je    logch9
  820.     mov    bx, bufpnt    ;Store the character in the buffer.
  821.     mov    [bx], dl
  822.     inc    bx
  823.     cmp    bx, offset dma+80h    ;Have we filled a buffer?
  824.     jb    logch1
  825.     push    dx        ;If so, write it to file.
  826.     mov    dx, offset lfcb
  827.     call    soutr
  828.     pop    dx
  829.     mov    bx, offset dma
  830. logch1:    mov    bufpnt, bx
  831. logch9:    ret            ;Return to output routine    ;[24a] end
  832.  
  833. ;Halt this program.
  834.  
  835. haltf:    mov    cl, reset    ;End this program.
  836.     int    bdos
  837.     ret            ;One never knows!
  838.  
  839. ;Reset the disk system to log in drives                ;[32a] begin
  840.  
  841. rstdsk:    mov    cl,resetd
  842.     int    bdos
  843.     call    inidma        ;Concurrent CP/M also resets DMA address
  844.     ret
  845.  
  846. ;Get and set the default disk drive
  847.  
  848. getdrv:    mov    cl,gtdrv
  849.     int    bdos
  850.     ret            ;returns drive in al (A=0 through P=15)
  851.  
  852. setdrv:    mov    cl,stdrv    ;new drive number (A=0 through P=15) in dl
  853.     int    bdos
  854.     ret
  855.  
  856. ;Get and set the default user number
  857.  
  858. getusr:    mov    cl,stusr
  859.     mov    dl,0FFh
  860.     int    bdos
  861.     ret            ;returns user in al (0-15)
  862.  
  863. setusr:    mov    cl,stusr    ;new user number (0-15) in dl
  864.     int    bdos
  865.     ret                            ;[32a] end
  866.  
  867.  
  868. ; Get the address of the disk allocation vector            ;[32d] begin
  869.  
  870. getalv:    mov    cl,gtalv
  871.     int    bdos
  872.     ret
  873.  
  874. ; Get the disk read-only vector
  875.  
  876. getrov:    mov    cl,gtrov
  877.     int    bdos
  878.     ret
  879.  
  880. ; Set file attributes according to FCB in dx
  881.  
  882. setatr:    mov    cl,statr
  883.     int    bdos
  884.     ret
  885.  
  886. ; Get the address of the DPB
  887.  
  888. getdpb:    mov    cl,gtdpb
  889.     int    bdos
  890.     ret
  891.  
  892. ; Allocate a block of memory.  MCB address is in dx.
  893.  
  894. allmem:    mov    cl,allocm
  895.     int    bdos
  896.     ret
  897.  
  898. ; Free a previously allocated block of memory.  MCB address is in dx.
  899.  
  900. fremem:    mov    cl,freem
  901.     int    bdos
  902.     ret                            ;[32d] end
  903.  
  904.  
  905. ; Get the first file in a wild card search.
  906.  
  907. gtjfn:    mov    cl, sfirst
  908.     int    bdos
  909.     ret
  910.  
  911. ; Get the next file in a wild card search.
  912.  
  913. gnjfn:    mov    cl, snext
  914.     int    bdos
  915.     ret
  916.  
  917. ; Close the file pointed to by the FCB in DX.
  918.  
  919. closf:    mov    cl, clsfil
  920.     int    bdos
  921.     ret
  922.  
  923. ; Open the file pointed to by the FCB in DX.
  924.  
  925. openf:    call    fcbzer        ;clear the fcb trailer        ;[29c]
  926.     mov    cl, opnfil
  927.     int    bdos
  928.     ret
  929.  
  930. ; Create the file pointed to by the FCB in DX.
  931.  
  932. create:    call    fcbzer        ;clear the fcb trailer        ;[29c]
  933.     mov    cl, makef
  934.     int    bdos
  935.     ret
  936.  
  937. fcbzer:    push    bx        ;Clear the end of the FCB    ;[29c] begin
  938.     push    cx        ;  prior to opening or creating a file.
  939.     mov    bx, dx
  940.     add    bx, 12
  941.     mov    ch, 0
  942.     mov    cl, 23
  943. fcbz1:    mov    [bx], ch
  944.     inc    bx
  945.     loop    fcbz1
  946.     pop    cx
  947.     pop    bx
  948.     ret                            ;[29c] end
  949.  
  950. ; Write a record to the file pointed to by the FCB in DX.
  951.  
  952. soutr:    mov    cl, writef
  953.     int    bdos
  954.     ret
  955.  
  956. ; Read a record from the file pointed to by the FCB in DX.
  957.  
  958. sinr:    mov    cl, readf
  959.     int    bdos
  960.     ret
  961.  
  962. ; Delete the file pointed to by the FCB in DX.
  963.  
  964. delete:    mov    cl, delf
  965.     int    bdos
  966.     ret
  967.  
  968. ; Sets dma to the default buffer.  Functions that change this must call this
  969. ; function to reset it before continuing
  970.  
  971. inidma:    push    dx
  972.     mov    dx, offset dma
  973.     call    setdma
  974.     pop    dx
  975.     ret
  976.  
  977. ; Sets the DMA to the offset pointed to in DX and the base in DS.
  978.  
  979. setdma:    mov    cl, dmaset
  980.     int    bdos
  981.     mov    dx, ds
  982.     mov    cl, dmabas
  983.     int    bdos
  984.     ret
  985.  
  986. ; Do random access read, write, or file size checks, FCB is in dx
  987.  
  988. rinr:    mov    cl, readr
  989.     int    bdos
  990.     ret
  991.  
  992. routr:    mov    cl, writer
  993.     int    bdos
  994.     ret
  995.  
  996. sizef:    mov    cl, cflsz
  997.     int    bdos
  998.     ret
  999.  
  1000. ; Jumping to this location is like retskp.  It assumes the instruction
  1001. ;   after the call is a jmp addr.
  1002.  
  1003. rskp:    pop    bp
  1004.     add    bp, 3
  1005.     push    bp
  1006.     ret
  1007.  
  1008.  
  1009. ; Jumping here is the same as a ret.
  1010.  
  1011. r:    ret
  1012.