home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / honeywellmicro / hl610.asm next >
Assembly Source File  |  2020-01-01  |  171KB  |  5,727 lines

  1.       PAGE 60,132
  2. ;     .XLIST
  3. ;******************** Version 1.20A *********************************
  4. ; [21] Added support for Honeywell L6/10 micro using MSDOS and
  5. ;      added support for Honeywell DPS6 as a host.  The DPS6
  6. ;      uses a \ as an escape character and to get one thru
  7. ;      2 need to be sent.
  8. ;      Terry Carlin, Honeywell Information Systems inc
  9. ;      3/27/84
  10. ;******************** Version 1.20  *********************************
  11. ; [20] (a) When in terminal emulation, if host sends an ESC-Z to
  12. ;      identify the terminal type being used, respond with "ESC / K".
  13. ;      (b) Allow ^X/^Z to interrupt sending a file or file group,
  14. ;      respectively.  (c) Ditto to interrupt receiving a file or file 
  15. ;      group.  (d) If get an error when receiving a file, clean up
  16. ;      and send an error packet.  Allow user to specify whether to
  17. ;      keep what made it over or to discard it.  (e) Before sending a
  18. ;      packet, clear the input buffer.  (f) Use one general routine
  19. ;      to send all error packets.  (g) Add U. of Arizona changes so
  20. ;      Kermit once again compiles on the Z100 (Joellen Windsor).  Move
  21. ;      IBM specific statements inside IBM conditional assembly blocks.
  22. ;      Daphne, 11/28/83
  23. ;******************** Version 1.19A *********************************
  24. ; [19] (a) Change NOUT to print numbers in decimal instead of hex.  
  25. ;      Routine is based on the one used in Generic Kermit.  Make a 
  26. ;      cosmetic change where print filenames & remove extraneous screen 
  27. ;      output.  Add "nop" in NAK because the jump to ABORT is only 
  28. ;      2 bytes.  Change ONTAB so the valid values are in alphabetical
  29. ;      order.  Also, keep only one copy of the code that sets the baud
  30. ;      rate and prints it's value.  (b) Allow users to choose between 
  31. ;      COM1 (default) and COM2.  Also, remind the user about which
  32. ;      communications port they are using and at what baud rate when
  33. ;      connecting to another system.  (c) Add SET BACKARROW so can 
  34. ;      set backarrow to backspace or delete. (William Dair)  Also,
  35. ;      set default to ON for renaming files due to filename conflicts. 
  36. ;      (d) When connecting to host, only bump up cursor if on line 25.
  37. ;      (e) Clean up parsing error messages.  Change VT52 emulation
  38. ;      messages to Heath-19.
  39. ;      Daphne, 10/21/83
  40. ;******************** Version 1.18 ********************************** 
  41. ; [18] A NAK for the next packet is not the same as an ACK for the
  42. ;      current packet if we're in Send-Init.  Also, account for
  43. ;      wraparound when comparing packet numbers that are off by one.
  44. ;      Daphne, 7/13/83
  45. ;******************** Version 1.3A ********************************** 
  46. ; [17] (a) Make command to SET BELL ON/OFF when transfer is complete.
  47. ;          Changed variable name to be consistent with other flags. 
  48. ;      (b) Make it more like a Heath/Zenith H19 (I/D L/C,inverse,24x80).
  49. ;      (c) Fix Telflg to be in CS so Telnet works.
  50. ;      Dave King (CMU), 7/1/83
  51. ;******************** Version 1.3 ********************************** 
  52. ; [16] Make adjustments to XT changes so that things that used to work
  53. ;      still do: pass along characters with the eighth bit on, and in
  54. ;      OUTCHR, don't overwrite character after setting the appropriate 
  55. ;      parity.
  56. ;      Daphne, 6/17/83
  57. ; [15] Add tabs stop and clear screen support.  Don't give checksum 
  58. ;      warnings.  Give keyboard input higher scheduling priority than 
  59. ;      port input.  This allows users to ^S, ^O, ^C, etc. the output 
  60. ;      when the port is full of characters.  Add a CMU conditional
  61. ;      to swap control-backspace (delete) with backspace since TOPS-20
  62. ;      and VMS are more delete than backspace oriented.
  63. ;      Glenn Marcy, 6/8/83
  64. ; [14] Add CMU changes that allow Kermit to work on the XT.  Plus add
  65. ;      a statement omitted previously when comparing packet numbers.   
  66. ;      Daphne, 5/26/83  (changes by Dave King, CMU)
  67. ;******************** Version 1.2 ********************************** 
  68. ; [13] When closing received file, handle case where number of bytes is
  69. ;      divisible by 128.
  70. ;      Daphne, 5/2/83
  71. ;******************** Version 1.1 ********************************** 
  72. ; [12] If "SET IBM", set local echo, XON/XOFF, and default (mark) parity.
  73. ;      Daphne, 4/15/83
  74. ; [11] In RPACK, don't push packet type, but store in temp variable.
  75. ;      If push and get an error, you pick up packet type as return addr.
  76. ;      Daphne, 4/15/83 
  77. ; [10] Add Set Parity Command.
  78. ;      Daphne, 4/12/83
  79. ; [9]  Allow single-character wildcard in filenames, use "=".
  80. ;      Daphne, 4/4/83
  81. ; [8]  Add Kermit server support.
  82. ;      Daphne, 3/17/83
  83. ; [7]  Allow wildcards in filename.
  84. ;      Daphne, 3/15/83
  85. ; [6]  Make format of "Set Escape" look like the other commands.
  86. ;      Daphne, 3/14/83
  87. ; [5]  Add Set "End-of-Line" (to the char used to terminate packets I send).
  88. ;      Daphne, 3/7/83
  89. ; [4]  Ring bell when done (when succeed and when fail).
  90. ;      Daphne, 2/10/83
  91. ; [3]  Match keyword if "?" is the terminator.
  92. ;      Daphne, 2/9/83
  93. ; [2]  Change "Inpkt" so ignores bare CR from any system. 
  94. ;      Daphne, 2/9/83
  95. ; [1]  Add "cmer04" - print error message if run off list of commands allowed.
  96. ;      Daphne, 2/9/83     
  97.  
  98. ;******************** Version 1.0 ********************************** 
  99. ; KERMIT - KL10 Error-free Reciprocal Micro Interconnect over TTY-lines
  100. ;       Program Version 1.20, Kermit Protocol Version 2
  101. ;    November 4, 1983
  102. ;       Based on the KERMIT Protocol.
  103. ;       Copyright (C) 1982,1983 Trustees of Columbia University
  104. ;
  105. ;       Daphne Tzoar
  106. ;       Columbia University Computer Center
  107. ;       612 W. 115th St.
  108. ;       New York City, NY  10025
  109. ;  Special thanks to Frank da Cruz, Bill Catchings, Steve Jensen,
  110. ;  Vace Kundakci, and Bernie Eiben for their help and contributions.
  111.  
  112.  
  113. ;  This file is the global data area for all the Kermit modules.
  114.  
  115.  
  116. CMU        EQU    0        ; CMU conditional assembly. [15]
  117. IBMPC    EQU    0         ; For IBM PC conditional assembly.
  118. Z100        EQU    0        ; For Heath/Zenith Z-100. 
  119. STEVE    EQU    0               ; For Steve's homebrew assembly.
  120. L610        EQU    1        ; For Honeywell L6/10 [21]
  121.  
  122. BELL    EQU     07Q
  123. TAB     EQU     11Q
  124. LF      EQU     12Q
  125. FF      EQU     14Q
  126. CR      EQU     15Q
  127. XON     EQU     21Q
  128. XOFF    EQU     23Q
  129. ESC     EQU     33Q
  130. DEL     EQU     177Q
  131. BS    EQU    08H
  132.  
  133. DOS     EQU     21H
  134.  
  135. CONIN   EQU     01H
  136. CONOUT  EQU     02H
  137. RDRIN   EQU     03H
  138. PUNOUT  EQU     04H
  139. LSTOUT  EQU     05H
  140. DCONIO  EQU     06H
  141. GTIOB   EQU     07H
  142. PRSTR   EQU     09H
  143. CONSTAT EQU     0BH
  144. OPENF   EQU     0FH
  145. CLOSF   EQU     10H
  146. SFIRST  EQU     11H
  147. SNEXT   EQU     12H
  148. DELF    EQU     13H
  149. READF   EQU     14H             ; Read from the file.
  150. WRITEF  EQU     15H
  151. MAKEF   EQU     16H
  152. SETDMA    EQU    1AH
  153. CFLSZ   EQU     23H
  154.  
  155. MAXPKT  EQU     '~'-' '+2Q      ; Maximum size of a packet.
  156. MAXTRY  EQU     05Q             ; Default number of retries on a packet.
  157. IMXTRY  EQU     20Q             ; Default number of retries send initiate.
  158. DRPSIZ  EQU     5EH             ; Default receive packet size.
  159. DSPSIZ  EQU     20H             ; Default send packet size.
  160. DSTIME  EQU     08H             ; Default send time out interval.
  161. DRTIME  EQU     05H             ; Default receive time out interval.
  162. DSPAD   EQU     00H             ; Default send padding.
  163. DRPAD   EQU     00H             ; Default receive padding.
  164. DSPADC  EQU     00H             ; Default send padding char.
  165. DRPADC  EQU     00H             ; Default receive padding char.
  166. DSEOL   EQU     CR              ; Default send EOL char.
  167. DREOL   EQU     CR              ; Default receive EOL char.
  168. DSQUOT  EQU     '#'             ; Default send quote char.
  169. DRQUOT  EQU     '#'             ; Default receive quote char.
  170.  
  171. PAREVN    EQU    00H        ; Even parity.            [10 start]
  172. PARMRK    EQU    01H        ; Mark parity.
  173. PARNON    EQU    02H        ; No parity.    
  174. PARODD    EQU    03H        ; Odd parity.
  175. PARSPC    EQU    04H        ; Space parity.
  176. DEFPAR    EQU    PAREVN        ; Default parity (EVEN.) 
  177. IBMPAR  EQU    PARMRK        ; IBM's parity (mark.)        [10 end]
  178.  
  179. SOH     EQU     01H             ; Start of header char.
  180. BUFSIZ  EQU     80H             ; Size of DMA.
  181. DIASW   EQU     01H             ; Default is diagnostics on.
  182.  
  183. CMKEY   EQU     01H             ; Parse a keyword.
  184. CMIFI   EQU     02H             ; Parse an input file spec (can be wild).
  185. CMOFI   EQU     03H             ; Parse an output file spec.
  186. CMCFM   EQU     04H             ; Parse a confirm.
  187. CMTXT    EQU    05H        ; Parse arbitrary text up to CR.   [8]
  188.  
  189. IF ibmpc
  190. BIOS    EQU     10H
  191. COMM    EQU    14H
  192. KEYB    EQU    16H
  193. DEFESC  EQU     ']'-100Q        ; The default escape character.
  194. MDMDAT1    EQU    03F8H        ; Address of modem port (data). [19b]
  195. MDMSTS1    EQU    03FDH        ; Address of modem port    status. [19b]
  196. MDMCOM1    EQU    03FBH        ; Address of modem port command. [19b]
  197. MDMDAT2    EQU    02F8H        ; Port 2 address. [19b]
  198. MDMSTS2    EQU    02FDH        ; Port 2 status. [19b]
  199. MDMCOM2    EQU    02FBH        ; Port 2 command. [19b]
  200. MDMINP    EQU    1        ; Input ready bit.
  201. BRKBIT    EQU    040H        ; Send-break bit. [20g]
  202. MDMINTV    EQU    0030H        ; Address of modem port interrupt vector.
  203. MDINTV2 EQU    002CH        ; Address for port 2. [19b] 
  204. MDMINTO    EQU    0EFH        ; Mask to enable interrupt for modem port.
  205. MDINTO2 EQU    0F7H        ; Enable interrupt level 3. [19b]
  206. MDMINTC    EQU    010H        ; Bit to set to disable interrupts for modem.
  207. MDINTC2 EQU    008H        ; Disable IRQ3. [19b]
  208. INTCONT    EQU    0021H        ; Address of 8259 interrupt controller ICW2-3.
  209. INTCON1    EQU    0020H        ; Address of 8259 ICW1.
  210. EOICOM    EQU    0064H        ; End of interrupt.
  211. EOICOM2    EQU    0063H        ; End of interrupt for COM2. [19b]
  212. TIMER    EQU    40H        ; Use to issue short beep.
  213. PORT_B    EQU    61H        ; Port B address.
  214.  
  215. B0300    EQU    180H        ; Variables for 300 baud, 1200, etc.
  216. B1200    EQU    60H
  217. B1800    EQU    40H
  218. B2400    EQU    30H
  219. B4800    EQU    18H
  220. B9600    EQU    0CH
  221. ENDIF
  222.  
  223. IF Z100
  224. MDMCOM    EQU    0EFH        ; Asynch port command register. [20g]
  225. BRKBIT    EQU    048H        ; Send-break bits. [20g]
  226. DEFESC  EQU     '\'-100Q        ; The default escape character.
  227.  
  228. ; BIOS entry points
  229.  
  230. BIOS_SEG SEGMENT AT 40H        ; Define segment where BIOS really is
  231.  
  232.     ORG    6*3
  233. BIOS_AUXOUT LABEL FAR        ; AUX output routine
  234.  
  235.     ORG    26*3
  236. BIOS_AUXFUNC LABEL FAR        ; AUX: function
  237.  
  238. BIOS_SEG ENDS            ; End of BIOS segment defs
  239.  
  240. ; Function codes for BIOS_AUXFUNC
  241. CHR_READ    EQU    1    ; Read character
  242. CHR_STATUS    EQU    2    ; Get status
  243.   CHR_SFGS    EQU    0    ; Get status subfunction
  244.   CHR_SFGC    EQU    1    ; Get config subfunction
  245. CHR_CONTROL    EQU    3    ; Control function
  246.  CHR_CFSU    EQU    0    ; Set new configuration parameters
  247.  
  248. B00455    EQU    0        ; 45.5 baud
  249. B0050    EQU    1        ; 50 baud
  250. B0075    EQU    2        ; 75 baud
  251. B0110    EQU    3        ; 110 baud
  252. B01345    EQU    4        ; 134.5 baud
  253. B0150    EQU    5        ; 150 baud
  254. B0300    EQU    6        ; 300 baud
  255. B0600    EQU    7        ; 600 baud
  256. B1200    EQU    8        ; 1200 baud
  257. B1800    EQU    9        ; 1800 baud
  258. B2000    EQU    10        ; 2000 baud
  259. B2400    EQU    11        ; 2400 baud
  260. B4800    EQU    12        ; 4800 baud
  261. B9600    EQU    13        ; 9600 baud
  262. B19200    EQU    14        ; 19200 baud
  263. B38400    EQU    15        ; 38400 baud 
  264. ENDIF
  265.  
  266. IF L610            ;[21]
  267. BIOS        EQU    10H
  268. COMM        EQU    14H
  269. KEYB        EQU    16H
  270. DEFESC    EQU    ']'-100Q    ;DEFAULT ESCAPE CHARACTER
  271.  
  272. BIT8        EQU    03H        ; 8 BIT CHARS
  273. BIT7        EQU    02H        ; 7 BIT CHARS
  274.  
  275. B0300    EQU    40H        ;300 BAUD
  276. B1200    EQU    80H        ;1200 BAUD
  277. B1800    EQU    0FFH        ;NOT AVAIL, JUST DUMMY FOR UTILITYS
  278. B2400    EQU    0A0H
  279. B4800    EQU    0C0H
  280. B9600    EQU    0E0H
  281.  
  282. EVENP    EQU    18H        ;EVEN PARITY
  283. ODDP        EQU    08H
  284. NONEP    EQU    00H        ;NO PARITY
  285.  
  286. STOP1    EQU    00H        ; ONE STOP BIT
  287. STOP2    EQU    04H
  288.  
  289. AUXPORT    EQU    0        ; AUX: PORT
  290. INIT_PORT    EQU    0        ; COMM FUNCTION TO INIT AUX PORT
  291. SEND_BYTE    EQU    1        ; SEND BYTE TO AUX: PORT
  292. READ_BYTE    EQU    2        ; READ BYTE FROM AUX:
  293. PORT_STAT    EQU    3        ; GET PORT STATUS
  294. ENDIF                ; L610        [21]
  295.  
  296. STACK   SEGMENT PARA STACK 'STACK'
  297.         DW      100 DUP(0)      ; Initialize stack to all zeros.
  298. STK    EQU    THIS WORD
  299. STACK   ENDS
  300.  
  301. DATAS   SEGMENT PARA PUBLIC 'DATAS'
  302.  
  303.         ; Pure storage.
  304.  
  305. versio  db      'CUCCA'
  306. IF ibmpc
  307.     db    ' IBM-PC' 
  308. ENDIF
  309. IF Z100
  310.     db    '/Stevens Heath/Zenith Z-100'
  311. ENDIF
  312. IF L610
  313.     db    ' Honeywell L6/10'
  314. ENDIF
  315.     db    ' Kermit-86 - ver 1.20',cr,lf,'$'       ;[19a]
  316. kerm    db      'Kermit-86>$'
  317. spmes   db    'Spack:  $'
  318. rpmes     db    'Rpack:  $'
  319. hibit    db    'Warning - Non Ascii char$'
  320. tmp    db    ?
  321. foo    db    '$'
  322. crlf    db      cr,lf,'$'
  323. ender    db    bell,bell,'$'             ;  [4]
  324. tmsg1    db    cr,lf,'[Connecting to host, type $' 
  325. tmsg3    db    ' C to return to PC$'     ; [17b, 19b]
  326. tmsg2    db    cr,lf,'[Back at micro]',cr,lf,'$'
  327. tmsg4    db    ', connecting over port COM$'  ; [19b]
  328. ermes1  db      cr,lf,'?Unregonized command$'
  329. ermes2  db      cr,lf,'?Illegal character$'
  330. ermes3  db      cr,lf,'?Not confirmed$'
  331. ermes4  db      'Unable to rename file$'
  332. ermes7  db      '?Unable to receive initiate$'
  333. ermes8  db      '?Unable to receive file name$'
  334. ermes9  db      '?Unable to receive end of file$'
  335. erms10  db      '?Unable to receive data$'
  336. erms11  db      '?Disk full$'
  337. erms14  db      '?Unable to receive an acknowledgement from the host$'
  338. erms15  db      '?Unable to find file$'
  339. erms17  db    'Record length exceeds size of buffer$'
  340. erms18    db    cr,lf,'?Unable to tell host that session is finished$'
  341. erms19    db    cr,lf,'?Unable to tell host to logout$'
  342. infms0  db      'Waiting .....$'
  343. infms1  db      'Receiving ...$'
  344. infms2  db      'Sending .....$'
  345. infms3  db      'Completed    $'
  346. infms4  db      'Failed       $'
  347. infms5  db      'Renaming file to $'
  348. infms6  db      'Interrupted  $'        ; [20b]
  349. infms7    db    'File interrupt: OK  $'       ; [20b] 
  350. infms8    db    'File group interrupt: OK  $'   ; [20b] 
  351.  
  352. cfrmes  db      ' Confirm with carriage return $'
  353. filhlp  db      ' Input file spec (possibly wild) $'
  354. esctl    db    'Control-$'         ; [6]
  355. spchar    db    24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
  356.     db    3CH,3EH,7BH,7DH,5FH,5CH,5EH,7EH,7CH,60H
  357. eschlp  db      cr,lf,'Enter literal value (ex: Cntrl ])  $'
  358. tophlp  db    cr,lf,'BYE to host (LOGOUT) and exit to DOS'
  359.     db      cr,lf,'CONNECT to host on selected port'
  360.         db      cr,lf,'EXIT to DOS'
  361.     db    cr,lf,'FINISH running Kermit on the host'
  362.         db      cr,lf,'HELP by giving this message'
  363.     db    cr,lf,'LOGOUT the host'
  364.         db      cr,lf,'RECEIVE file from host'
  365.         db      cr,lf,'SEND file to host'
  366.         db      cr,lf,'SET a parameter'
  367. ;        db      cr,lf,'SHOW the parameters'
  368.         db      cr,lf,'STATUS of Kermit$'
  369. sethlp    db    cr,lf,'BACKARROW to'        ; [19c]
  370.     db      cr,lf,'BAUD rate'    
  371.     db    cr,lf,'BELL'    ; [17a]
  372.     db    cr,lf,'DEBUG'
  373.     db    cr,lf,'END-OF-LINE character'
  374.     db      cr,lf,'ESCAPE character change'
  375.         db      cr,lf,'FILE-WARNING'
  376. IF ibmpc
  377.         db      cr,lf,'HEATH-19'        ; [19e]
  378. ENDIF
  379.     db    cr,lf,'IBM'
  380.     db    cr,lf,'DPS6'                ; [21]
  381.     db    cr,lf,'INCOMPLETE file'        ; [20d]
  382.         db      cr,lf,'LOCAL-ECHO echoing (half-duplex)'
  383.     db    cr,lf,'PARITY type'                 ; [10]
  384. IF ibmpc
  385.     db    cr,lf,'PORT for communication$'     ; [19b]
  386. ;        db      cr,lf,'VT52-EMULATION$'           ; [19e]
  387. ENDIF
  388. IF Z100 or L610                        ; [21]
  389.     db    '$'
  390. ENDIF    
  391. stshlp  db      cr,lf,'PAD-CHAR'
  392.         db      cr,lf,'PADDING$'
  393. onhlp   db      cr,lf,'OFF      ON$'
  394. yeshlp  db      cr,lf,'NO       YES$'
  395. abfhlp    db    cr,lf,'DISCARD      KEEP$'        ; [20d]
  396. comphlp    db    cr,lf,'1 (COM1)   2 (COM2)$'        ; [19b]
  397. IF L610                                ;[21]
  398. parhlp    db    cr,lf,'None   Odd    Even$'
  399. ELSE
  400. parhlp    db    cr,lf,'None   Mark   Odd   Even   Space$'   ; [10]
  401. ENDIF
  402. IF ibmpc
  403. bdhlp    db    cr,lf,'300   1200   1800   2400   4800   9600$'
  404. ENDIF
  405. IF Z100
  406. bdhlp    db    cr,lf,'45.5    50    75    110    134.5    150    300'
  407.     db    '    600    1200    1800'
  408.     db    cr,lf,'    2000    2400    4800    9600    19200    38400'
  409. ENDIF
  410. IF    L610                                ; [21]
  411. bdhlp    db    cr,lf,' 300    1200    2400    4800    9600$'
  412. ENDIF
  413. BShlp    db    cr,lf,'BACKSPACE      DELETE$'        ; [19c]
  414. eolhlp    db    cr,lf,'Decimal digit between 0 and 31$'   ; [5]
  415. eolerr    db    cr,lf,'Illegal end-of-line character$'  ; [5]
  416. inthlp  db      cr,lf,'?  This message'
  417.         db      cr,lf,'C  Close the connection'
  418.         db      cr,lf,'S  Status of the connection'
  419.     db    cr,lf,'B  Send a break'            ; [20g]
  420.         db      cr,lf,'Typing the escape character will send it to the host'
  421.         db      cr,lf,cr,lf,'Command>$'
  422. locst   db      cr,lf,'Local echo on$'
  423. remst   db      cr,lf,'Local echo off$'
  424. belon    db    cr,lf,'Ring bell at end of transfer$'     ; [17a - DT]
  425. beloff    db    cr,lf,'No bell at end of transfer$'       ; [17a - DT]
  426. IF ibmpc
  427. vtemst  db      cr,lf,'HEATH-19 emulation on$'        ; [19e]
  428. novtst  db      cr,lf,'HEATH-19 emulation off$'        ; [19e]
  429. cm1st    db    cr,lf,'Using communications port 1$'    ; [19b]
  430. cm2st    db    cr,lf,'Using communications port 2$'    ; [19b]
  431. ENDIF
  432. ibmst   db      cr,lf,'IBM on$'
  433. noibm   db      cr,lf,'IBM off$'
  434. l6st    db    cr,lf,'DPS6 on$'                    ; [21]
  435. nol6    db    cr,lf,'DPS6 off$'                ; [21]
  436. pnonst    db    cr,lf,'No parity$'               ; [10]
  437. poddst    db    cr,lf,'Odd parity$'                ; [10]
  438. pevnst    db    cr,lf,'Even parity$'               ; [10]
  439. pmrkst    db    cr,lf,'Mark parity$'               ; [10]
  440. pspcst    db    cr,lf,'Space parity$'              ; [10]
  441. IF Z100 
  442. b04st    db    cr,lf,'Baud rate is 45.5$'
  443. b05st    db    cr,lf,'Baud rate is 50$'
  444. b07st    db    cr,lf,'Baud rate is 75$'
  445. b11st    db    cr,lf,'Baud rate is 110$'
  446. b13st    db    cr,lf,'Baud rate is 134.5$'
  447. b15st    db    cr,lf,'Baud rate is 150$'
  448. b06st    db    cr,lf,'Baud rate is 600$'
  449. b20st    db    cr,lf,'Baud rate is 2000$'
  450. b19st    db    cr,lf,'Baud rate is 19200$'
  451. b38st    db    cr,lf,'Baud rate is 38400$'
  452. ENDIF
  453. b03st    db    cr,lf,'Baud rate is 300$'
  454. b12st    db    cr,lf,'Baud rate is 1200$'
  455. b18st    db    cr,lf,'Baud rate is 1800$'
  456. b24st    db    cr,lf,'Baud rate is 2400$'
  457. b48st    db    cr,lf,'Baud rate is 4800$'
  458. b96st    db    cr,lf,'Baud rate is 9600$'
  459. debon    db    cr,lf,'Debug mode on$'
  460. deboff    db    cr,lf,'Debug mode off$'    
  461. flwon    db    cr,lf,'File Warning on$'
  462. flwoff    db    cr,lf,'File Warning off$'
  463. bkbs    db      cr,lf,'Backarrow sends a backspace $'   ; [19c] 
  464. bkdel   db      cr,lf,'Backarrow sends a delete $'      ; [19c] 
  465. abfdst    db    cr,lf,'Discard incoming file if incomplete $'  ;[20d]
  466. abfkst    db    cr,lf,'Keep incoming file if incomplete $'   ;[20d]
  467. eolst    db    cr,lf,'End-of-line character is ^$'     ; [5]
  468. escmes  db      cr,lf,'Escape character is  $'          ; [6]
  469.  
  470.  
  471. outlin  db      cr,lf,'                CUCCA'
  472. IF ibmpc
  473.     db    ' IBM-PC'
  474. ENDIF
  475. IF Z100
  476.     db    '/Stevens Heath/Zenith Z-100'
  477. ENDIF
  478. IF L610                                    ; [21]
  479.     db    ' Honeywell L6/10'
  480. ENDIF
  481.     db    ' Kermit-86 V1.20',cr,lf
  482.         db      cr,lf,'Number of packets:   '    ; [19a]
  483.         db      cr,lf,'Number of retries:   '    ; [19a]
  484.         db      cr,lf,'File name $'
  485. delstr  db      10O,' ',10O,10O,'$'     ; Delete string.
  486. clrspc  db      ' ',10O,'$'             ; Clear space.
  487. escspc    db    10O,' ',10O,'$'        ; Clear escape.
  488. IF ibmpc or L610                    ; [21]
  489. clrlin  db      cr,'$'            ; Clear line (just the cr part).
  490. ENDIF
  491. IF Z100
  492. clrlin    db    cr,esc,'K$'        ; Clear line on Z-100
  493. clreol    db    esc,'K$'        ; Clear to end of line
  494. clrscr    db    esc,'H',esc,'J$'    ; Home and clear screen
  495. homcur    db    esc,'H$'        ; Home cursor
  496. ENDIF
  497. prsp    db    ' $'            ; Print a space.
  498.  
  499. ; Cursor addressing items.
  500.  
  501. IF ibmpc or L610                ; [21]
  502. scrhi    dw    0434H            ; Err when 8th bit is on.
  503. scrrpr    dw    0700H            ; Prompt when Kermit ends.
  504. screrr  dw      0600H                ; Place for error msgs. 
  505. scrfln  dw      050CH            ; Place for file name.
  506. scrnrt  dw      0415H                ; Place for number of retries.
  507. scrnp   dw      0315H                 ; Place for number of packets.
  508. scrfr    dw    0600H            ; Rename file.
  509. scrst    dw    0334H            ; Place for status.
  510. scrint    dw    0434H            ; Acknowledge interrupt. [20b]
  511. scrsp    dw    0800H            ; Place for send packet.
  512. scrrp    dw    0A00H            ; Place for receive packet.
  513. ENDIF
  514. IF ibmpc
  515. ttab    label    word            ; Table for cursor movement.
  516. ta    dw    curup            ; Cursor up.
  517. tb    dw    curdwn            ; Cursor down.
  518. tc    dw    currt              ; Cursor right.
  519. td    dw    curlft            ; Cursor left.
  520. te    dw    curclr            ; Clear display. [15]
  521. tf    dw    curskp            ; Enter graphics mode.
  522. tg    dw    curskp            ; Exit graphics mode.
  523. th    dw    curhm            ; Cursor home.
  524. ti    dw    curup            ; Reverse line feed.
  525. tj    dw    curscr            ; Clear to end of screen.
  526. tk    dw    curln            ; Clear to end of line.
  527. tl    dw    inslin            ; Insert line.
  528. tm    dw    dellin            ; Delete line.    
  529. tn    dw    delchr            ; Delete character. [17b] 
  530. to    dw    insmox            ; Cancel Insert Character. [17b] 
  531. ENDIF
  532.  
  533. IF Z100
  534. scrhi    db    esc,'Y',23H,54H,lf,'$'    ; 8th bit on in character
  535. scrrpr    db    esc,'Y',27H,20H,'$'    ; Prompt when Kermit ends
  536. screrr    db    esc,'Y',26H,20H,'$'    ; Error messages
  537. scrfln    db    esc,'Y',25H,2CH,'$'    ; File name
  538. scrnrt    db    esc,'Y',23H,35H,lf,'$'    ; Number of retries
  539. scrnp    db    esc,'Y',23H,35H,'$'    ; Number of packets
  540. scrfr    db    esc,'Y',26H,20H,'$'    ; Rename file
  541. scrst    db    esc,'Y',23H,54H,'$'    ; Status
  542. scrint  db    esc,'Y',24H,54H,'$'    ; Acknowledge interrupt. [20b]
  543. scrsp    db    esc,'Y',28H,20H,'$'    ; send packet
  544. scrrp    db    esc,'Y',2AH,20H,'$'    ; Receive packet
  545. ENDIF
  546.  
  547.         ; COMND tables
  548.  
  549. comtab  db      0AH                 ; Ten entries.
  550.     db    03H,'BYE$'
  551.     dw    bye
  552.         db      07H,'CONNECT$'
  553.         dw      telnet
  554.         db      04H,'EXIT$'
  555.         dw      exit
  556.     db    06H,'FINISH$'
  557.     dw    finish
  558.         db      04H,'HELP$'
  559.         dw      help
  560.     db    06H,'LOGOUT$'
  561.     dw    logout
  562.         db      07H,'RECEIVE$'
  563.         dw      read
  564.         db      04H,'SEND$'
  565.         dw      send
  566.         db      03H,'SET$'
  567.         dw      setcom
  568.         db      06H,'STATUS$'
  569.         dw      status
  570.  
  571. IF ibmpc
  572. settab  db      0EH             ; Fourteen entries.[17a][19b][19c][20d]
  573. ENDIF
  574. IF Z100 or L610                ; [21]
  575. settab  db      0CH             ; Twelve entries.[10][17a][19c][20d][21]
  576. ENDIF
  577.     db    09H,'BACKARROW$'    ; [19c]
  578.     dw    BSset             ; [19c]
  579.     db    04H,'BAUD$'
  580.     dw    baudst
  581.     db    04H,'BELL$'    ; [17a]
  582.     dw    bellst        ; [17a]
  583.     db    05H,'DEBUG$'
  584.     dw    debst
  585.     db    04H,'DPS6$'                ; [21]
  586.     dw    l6set
  587.     db    0BH,'END-OF-LINE$'             ;  [5]
  588.     dw    eolset                 ;  [5]
  589.     db      06H,'ESCAPE$'
  590.     dw      escape
  591.     db    0CH,'FILE-WARNING$'
  592.     dw    filwar
  593. IF ibmpc
  594.     db      0DH,'H19-EMULATION$'        ; [19e]
  595.     dw      vt52em                ; [19e]
  596. ENDIF
  597.     db      03H,'IBM$'
  598.     dw      ibmset
  599.     db    0AH,'INCOMPLETE$'       ; [20d]
  600.     dw    abfset            ; [20d]
  601.     db      0AH,'LOCAL-ECHO$'
  602.     dw      lcal
  603.     db    06H,'PARITY$'                ; [10]
  604.     dw    setpar                    ; [10]
  605. IF ibmpc
  606.     db    04H,'PORT$'            ; [19b]
  607.     dw    comset                ; [19b]
  608. ;        db      0EH,'VT52-EMULATION$'        ; [19e]
  609. ;        dw      vt52em                ; [19e]
  610. ENDIF
  611.  
  612. ontab   db      02H             ; Two entries.
  613.         db      03H,'OFF$'    ; Should be alphabetized.  [19a]
  614.         dw      00H
  615.         db      02H,'ON$'
  616.         dw      01H
  617.  
  618. ; If abort when receiving files, can keep what we have or discard. [20d]
  619.  
  620. abftab    db    02H        ; Only two options. 
  621.     db    07H,'DISCARD$'
  622.     dw    01H
  623.     db    04H,'KEEP$'
  624.     dw    00H
  625.  
  626. ; Entries for choosing communications port. [19b]
  627.  
  628. comptab    db    04H
  629.     db    01H,'1$'
  630.     dw    01H
  631.     db    01H,'2$'
  632.     dw    00H
  633.     db    04H,'COM1$'
  634.     dw    01H
  635.      db    04H,'COM2$'
  636.     dw    00H
  637.  
  638. yestab  db      02H             ; Two entries.
  639.         db      02H,'NO$'
  640.         dw      00H
  641.         db      03H,'YES$'
  642.         dw      01H
  643. IF L610                ; [21]
  644. partab    db    03H        ; three entries
  645.         db    04H,'EVEN$'    ; Implies 7 bit char
  646.         dw    PAREVN
  647.         db    04H,'NONE$'    ; Implies 8 bit char
  648.         dw    PARNON
  649.         db    03H,'ODD$'    ; Implies 7 bit char
  650.         dw    PARODD
  651. ELSE
  652. partab    db    05H        ; Five entries.            [10 start]
  653.     db    04H,'EVEN$'
  654.     dw    PAREVN
  655.     db    04H,'MARK$'
  656.     dw    PARMRK
  657.     db    04H,'NONE$'
  658.     dw    PARNON
  659.     db    03H,'ODD$'
  660.     dw    PARODD
  661.     db    05H,'SPACE$'
  662.     dw    PARSPC                        ;[10 end]
  663. ENDIF
  664.  
  665. BStab    db    02H            ;Two entries [19c start]
  666.     db    09H,'BACKSPACE$'
  667.     dw    00H
  668.     db    06H,'DELETE$'
  669.     dw    01H            ;[19c]
  670.  
  671. IF ibmpc
  672. bdtab    db    06H        ; Six entries.
  673.     db    04H,'1200$'
  674.     dw    B1200
  675.     db    04H,'1800$'
  676.     dw    B1800
  677.     db    04H,'2400$'
  678.     dw    B2400
  679.     db    03H,'300$'
  680.     dw    B0300
  681.     db    04H,'4800$'
  682.     dw    B4800
  683.     db    04H,'9600$'
  684.     dw    B9600
  685. ENDIF
  686. IF L610                ; [21]
  687. bdtab    db    05H        ; Six entries.
  688.     db    04H,'1200$'
  689.     dw    B1200
  690.     db    04H,'2400$'
  691.     dw    B2400
  692.     db    03H,'300$'
  693.     dw    B0300
  694.     db    04H,'4800$'
  695.     dw    B4800
  696.     db    04H,'9600$'
  697.     dw    B9600
  698. ENDIF
  699. IF Z100
  700. bdtab    db    010H        ; 16 entries
  701.     db    03H,'110$'
  702.     dw    b0110
  703.     db    04H,'1200$'
  704.     dw    b1200
  705.     db    03H,'134$'
  706.     dw    b01345
  707.     db    03H,'150$'
  708.     dw    b0150
  709.     db    04H,'1800$'
  710.     dw    b1800
  711.     db    05H,'19200$'
  712.     dw    b19200
  713.     db    04H,'2000$'
  714.     dw    b2000
  715.     db    04H,'2400$'
  716.     dw    b2400
  717.     db    03H,'300$'
  718.     dw    b0300
  719.     db    05H,'38400$'
  720.     dw    b38400
  721.     db    02H,'45$'
  722.     dw    b00455
  723.     db    04H,'4800$'
  724.     dw    b4800
  725.     db    02H,'50$'
  726.     dw    b0050
  727.     db    03H,'600$'
  728.     dw    b0600
  729.     db    02H,'75$'
  730.     dw    b0075
  731.     db    04H,'9600$'
  732.     dw    b9600
  733. ENDIF
  734.  
  735. ; COMND storage
  736.  
  737. cmer00  db      cr,lf,'?Program error   Invalid COMND call$'
  738. cmer01  db      cr,lf,'?Ambiguous$'
  739. cmer02  db      cr,lf,'?Illegal input file spec$'
  740. ;cmer03    db    cr,lf,'?Unrecognized instruction$'
  741. cmer03    db    cr,lf,'?Invalid command$'         ;  [19e]
  742. cmer04    db    cr,lf,'?Invalid command or operand$'     ;  [1]
  743. cmin00  db      ' Confirm with carriage return$'
  744. cmcrlf  db      cr,lf,'$'
  745.  
  746. cmstat  db      ?               ; What is presently being parsed.
  747. cmaflg  db      ?               ; Non-zero when an action char has been found.
  748. cmccnt  db      ?               ; Non-zero if a significant char is found.
  749. cmsflg  db      ?               ; Non-zero when the last char was a space.
  750. cmostp  dw      ?               ; Old stack pointer for reparse.
  751. cmrprs  dw      ?               ; Address to go to on reparse.
  752. cmprmp  dw      ?               ; Address of prompt.
  753. cmptab  dw      ?               ; Address of present keyword table.
  754. cmhlp   dw      ?               ; Address of present help.
  755. cmdbuf  db      80H DUP(?)      ; Buffer for command parsing.
  756. cmfcb   dw      ?               ; Pointer to FCB.
  757. cmfcb2  dw      ?               ; Pointer to position in FCB.
  758. cmcptr  dw      ?               ; Pointer for next char input.
  759. cmdptr  dw      ?               ; Pointer into the command buffer.
  760. cmsiz    dw    ?        ; Size info of user input.
  761. cmkptr  dw      ?               ; Pointer to keyword.
  762. cmsptr  dw      ?               ; Place to save a pointer.
  763. cmchr    db    ?        ; Save char when checking ambiguity.
  764.  
  765. ; Program storage.
  766.  
  767. oldstk  dw      ?               ; Storage for system stack.
  768. oldsts  dw      ?               ; System stack segment.
  769. ssp    dw    0        ; Save SP in Telnet.
  770. bufhex    dw    80H
  771. filsiz    dw    0,0        ; Double word for filesize (in bytes.)
  772. eoflag  db      ?               ; EOF flag; non-zero on EOF.
  773. wldflg    db    0        ; Assume no "*" in fn.         [7]
  774. ;telflg    db    0        ; Are we acting as a terminal. [16] [17c]
  775. belflg    db    1        ; Use bell  [17a -- DT]
  776. comflg    db    0        ; Use COM2 by default. [19b]
  777. cxzflg    db    0        ; ^X/^Z to interrupt file x-fer. [20b] 
  778. abfflg    db    1        ; Discard incoming file if abort. [20d]
  779. debug    db    0        ; Debugging mode (default off).
  780. hierr    db    0        ; Non-ascii char (non-zero if yes).
  781. filflg  db      ?               ; Non-zero when nothing in DMA buffer.
  782. ecoflg  db      1               ; Local echo flag (default on).
  783. parflg  db    defpar        ; Parity flag (default none.)  [10]
  784. escflg  db      0               ; Escape flag (start off).
  785.  
  786. IF ibmpc
  787. vtflg   db      1               ; VT52 emulation flag (default on).
  788. incmod    db    0        ; Insert Character mode.  [17b] [20g]
  789. curatt    dw    0007H        ; Video attributes. [17b]
  790. baud    dw    B1200        ; Use default of 1200.
  791. mddat    dw    MDMDAT2        ; Default to port 2. [19b start]
  792. mdstat    dw    MDMSTS2        ; Ditto. 
  793. mdcom    dw    MDMCOM2        ; Here too. 
  794. mden        db    MDINTO2
  795. mddis    db    MDINTC2
  796. mdmeoi    db    EOICOM2
  797. mdintv    dw    MDINTV2        ; [19b end]
  798. ENDIF
  799. IF Z100
  800. auxcnf    db    4 dup(?)    ; AUX port configuration info
  801. baud    db    ?        ; Baud rate
  802. auxcnf1    db    12 dup(?)    ; Rest of configuration info
  803. mdcom    dw    MDMCOM        ; Use to send a break. [20g]
  804. ENDIF
  805. IF L610                        ;[21]
  806. curatt    dw    0007H
  807. baud        db    B1200
  808. ENDIF
  809. flwflg  db      0               ; File warning flag (default off). [19c]
  810. l6flg   db      0              ; L6 flag (default off)
  811. ibmflg  db      0               ; IBM flag (default off).
  812. delflg    db    0        ; No BS to DEL translation. [19c]
  813. extflg  db      0               ; Exit flag (default off).
  814. escchr  db      defesc          ; Storage for the escape character.
  815. incnt    dw    ?        ; Number of chars read in from port.
  816. chrcnt  dw      ?               ; Number of chars in the file buffer.
  817. filcnt  dw      ?               ; Number of chars left to fill.
  818. outpnt  dw      ?               ; Position in packet.
  819. bufpnt  dw      ?               ; Position in file buffer.
  820. fcbptr  dw      ?               ; Position in FCB.
  821. datptr  dw      ?               ; Position in packet data buffer.
  822. cbfptr  dw      ?               ; Position in character buffer.
  823. pktptr  dw      ?               ; Poistion in receive packet.
  824. siz     dw      ?               ; Size of data from gtchr.
  825. spsiz   db      dspsiz          ; Send packet size.
  826. rpsiz   db      drpsiz          ; Receive packet size.
  827. stime   db      dstime          ; Send time out.
  828. rtime   db      drtime          ; Receive time out.
  829. spad    db      dspad           ; Send padding.
  830. rpad    db      drpad           ; Receive padding.
  831. spadch  db      dspadc          ; Send padding char.
  832. rpadch  db      drpadc          ; Receive padding char.
  833. seol    db      dseol           ; Send EOL char.
  834. reol    db      dreol           ; Receive EOL char.
  835. squote  db      dsquot          ; Send quote char.
  836. rquote  db      drquot          ; Receive quote char.
  837. pktnum  dw      ?               ; Packet number.
  838. numpkt  dw      ?               ; Total number of packets sent.
  839. numrtr  dw      ?               ; Total number of retries.
  840. numtry  db      ?               ; Number of tries on this packet.
  841. oldtry  db      ?               ; Number of tries on previous packet.
  842. state   db      ?               ; Present state of the automaton.
  843. savsci    dw    ?        ; Save for serial port interrupt vector. [14]
  844. savscs    dw    ?        ; Ditto.  [14]  
  845. packet  db      ?,?,?,?         ; Packet (data is part of it).
  846. data    db      5AH DUP(?)      ; Data and checksum field of packet.
  847. recpkt  db      60H DUP(?)      ; Receive packet storage (use the following).
  848. filbuf  db      60H DUP(?)      ; Character buffer.
  849. fcb    db    25H DUP(?)    ; Use as our FCB.
  850. cpfcb    db    25H DUP(?)    ; Save FCB in case of "*".   [7]
  851. buff    db    80H DUP(?)    ; Use as our DAT.
  852. rdbuf    db    80H DUP(?)
  853. cnt    dw    0
  854. temp    dw    0
  855. temp1   dw      ?               ; Temporary storage.
  856. temp2   dw      ?
  857. temp3   dw      ?
  858. temp4   dw      ?
  859. argblk  dw      ?               ; For subroutine arguments.
  860. argbk1  dw      ?
  861. argbk2  dw      ?
  862. argbk3  dw      ?
  863.  
  864. DATAS   ENDS                    ; End data segment
  865.  
  866.  
  867. MAIN    SEGMENT PARA PUBLIC 'MAIN'
  868. START   PROC  FAR
  869.         ASSUME  CS:MAIN,DS:DATAS,SS:STACK,ES:NOTHING
  870.  
  871.         push ds                 ; Save system data area.
  872.         sub ax,ax               ; Get a zero.
  873.         push ax                 ; Put zero return addr on stack.
  874.  
  875.         mov ax,datas            ; Initialize DS.
  876.         mov ds,ax
  877.     sub ax,ax
  878.  
  879.         mov oldstk,sp           ; Save old stack pointer.
  880.  
  881.         call cmblnk             ; Clear the screen.
  882.     call locate
  883.  
  884.         mov ah,prstr            ; Print the version header.
  885.         mov dx,offset versio
  886.         int dos
  887.  
  888.     mov ah,setdma        ; Set disk transfer address.
  889.     mov dx,offset buff
  890.     int dos
  891.  
  892.     call dobaud        ; Set the baud rate. [19a, 20g]
  893.  
  894. ; This is the main KERMIT loop.  It prompts for and gets the users commands.
  895.  
  896. kermit: mov dx,offset kerm
  897.         call prompt             ; Prompt the user.
  898.         mov dx,offset comtab
  899.         mov bx,offset tophlp
  900.         mov ah,cmkey
  901.         call comnd
  902.          jmp kermt2
  903.         call bx                 ; Call the routine returned.
  904.          jmp kermt3
  905.         cmp extflg,0            ;  Check if the exit flag is set.
  906.         jne krmend              ;  If so jump to KRMEND.
  907.         jmp kermit              ; Do it again.
  908.  
  909. kermt2: mov ah,prstr
  910.         mov dx,offset ermes1    ;  Give an error.
  911.         int dos
  912.         jmp kermit
  913.  
  914. kermt3: mov ah,prstr
  915.         mov dx,offset ermes3    ;  Give an error.
  916.         int dos
  917.         jmp kermit
  918.  
  919. krmend: 
  920.         mov sp,oldstk
  921.         ret
  922.  
  923. START   ENDP
  924.  
  925.  
  926. ; These are some utility routines.
  927.  
  928. ;       Abort
  929.  
  930. ABORT   PROC    NEAR
  931.         mov state,'A'           ; Otherwise abort.
  932.         ret
  933. ABORT   ENDP
  934.  
  935. ;       NAK
  936.  
  937. NAK     PROC    NEAR
  938.         mov ax,pktnum           ; Get the packet number we're waiting for.
  939.         mov argblk,ax
  940.         mov argbk1,0
  941.         mov ah,'N'              ; NAK that packet.
  942.         call spack
  943.      jmp abort
  944.      nop            ; So 'jmp rskp' in SPACK comes here. [19a]
  945.         ret                     ; Go around again.
  946. NAK     ENDP
  947.  
  948. ; Position cursor for an error message.
  949.  
  950. ERPOS    PROC     NEAR
  951. IF ibmpc OR L610            ;[21]
  952.     mov ah,2
  953.     mov bh,0
  954.     mov dx,screrr
  955.     int bios
  956.     ret
  957. ENDIF
  958. IF Z100
  959.     mov dx,offset screrr    ; Get address of string to position cursor
  960.     mov ah,prstr        ; Get the function code
  961.     int dos            ; Print the addressing string
  962.     ret            ; And return
  963. ENDIF
  964. ERPOS    ENDP
  965.  
  966. ; Position cursor for number of retries message.
  967.  
  968. RTPOS    PROC     NEAR
  969. IF ibmpc OR L610
  970.     mov ah,2
  971.     mov bh,0
  972.     mov dx,scrnrt
  973.     int bios
  974.     ret
  975. ENDIF
  976. IF Z100
  977.     mov ah,prstr        ; Get the function to print string
  978.     mov dx,offset scrnrt    ; Get the address of the string
  979.     int dos            ; Print the string
  980.     ret            ; And return
  981. ENDIF
  982. RTPOS    ENDP
  983.  
  984. ; Reassure user that we acknowledge his ^X/^Z.  [20b]
  985. INTMSG    PROC    NEAR
  986. IF ibmpc OR L610            ; Tell user we acknowledge it.
  987.     mov ah,2    
  988.     mov dx,scrint
  989.     mov bh,0
  990.     int bios
  991. ENDIF
  992. IF Z100
  993.     mov ah,prstr        ; Get print string function
  994.     mov dx,offset scrint    ; and string to move cursor
  995.     int dos            ; Print the string
  996. ENDIF
  997.     mov dx,offset infms7    ; File interrupted?
  998.     cmp cxzflg,'X'        ; Yes. 
  999.     je int0
  1000.     mov dx,offset infms8    ; File group interrupted.
  1001. int0:   mov ah,prstr
  1002.         int dos
  1003.     ret
  1004. INTMSG    ENDP
  1005.  
  1006. ; Print err message that found a non-standard-Ascii char in the file.
  1007.  
  1008. BITERR    PROC    NEAR
  1009.     push bx
  1010. IF ibmpc OR L610
  1011.     mov ah,2
  1012.     mov bh,0
  1013.     mov dx,scrhi
  1014.     int bios
  1015. ENDIF
  1016. IF Z100
  1017.     mov ah,prstr        ; Get the function to print string
  1018.     mov dx,offset scrhi    ; Get the address of the string
  1019.     int dos            ; Print the string
  1020. ENDIF
  1021.     mov ah,prstr
  1022.     mov dx,offset hibit
  1023.     int dos
  1024.     pop bx
  1025.     ret
  1026. BITERR    ENDP        
  1027.  
  1028. ;    This routine prints out the escape character in readable format.  
  1029.  
  1030. ESCPRT    PROC    NEAR        ; [6 start]
  1031.     mov dl,escchr
  1032.     cmp dl,' '
  1033.     jge escpr2
  1034.     push dx
  1035.     mov ah,prstr
  1036.     mov dx,offset esctl
  1037.     int dos
  1038.     pop dx
  1039.     add dl,040H        ; Make it printable.
  1040. escpr2:    mov ah,conout
  1041.     int dos
  1042.     ret
  1043. ESCPRT    ENDP            ; [6 end]
  1044.  
  1045. ;       FCB must be remembered if found "*" in filename.      [7 start]
  1046. ;     Copy from place addressed by BX to place addressed by DI.
  1047. ;    Also use to get the filename to the FCB from the DTA.
  1048.  
  1049. FCBCPY    PROC    NEAR
  1050. fcbcp1:    cmp cl,0
  1051.     je fcbcp2
  1052.     mov ah,[bx]
  1053.     mov [di],ah
  1054.     dec cl
  1055.     inc bx
  1056.     inc di
  1057.     jmp fcbcp1
  1058. fcbcp2:    ret
  1059. FCBCPY    ENDP    
  1060.  
  1061. ;       This routine sets up the data for init packet (either the
  1062. ;       Send_init or ACK packet).
  1063.  
  1064. RPAR    PROC    NEAR
  1065.         mov ah,rpsiz            ; Get the receive packet size.
  1066.         add ah,' '              ; Add a space to make it printable.
  1067.         mov [bx],ah             ; Put it in the packet.
  1068.         mov ah,rtime            ; Get the receive packet time out.
  1069.         add ah,' '              ; Add a space.
  1070.         mov 1[bx],ah            ; Put it in the packet.
  1071.         mov ah,rpad             ; Get the number of padding chars.
  1072.         add ah,' '
  1073.         mov 2[bx],ah            ; Put it in the packet.
  1074.         mov ah,rpadch           ; Get the padding char.
  1075.         add ah,100O             ; Uncontrol it.
  1076.         and ah,7FH
  1077.         mov 3[bx],ah            ; Put it in the packet.
  1078.         mov ah,reol             ; Get the EOL char.
  1079.         add ah,' '
  1080.         mov 4[bx],ah            ; Put it in the packet.
  1081.         mov ah,rquote           ; Get the quote char.
  1082.         mov 5[bx],ah            ; Put it in the packet.
  1083.         mov ah,06H              ; Six pieces of data.
  1084.         ret
  1085. RPAR    ENDP
  1086.  
  1087. ;       This routine reads in all the send_init packet information.
  1088.  
  1089. SPAR    PROC    NEAR
  1090.         mov temp4,ax            ; Save the number of arguments.
  1091.         mov ah,[bx]             ; Get the max packet size.
  1092.         sub ah,' '              ; Subtract a space.
  1093.         mov spsiz,ah            ; Save it.
  1094.         mov ax,temp4
  1095.         cmp al,3                ; Fewer than three pieces?
  1096.         jge spar1
  1097.         ret                     ; If so we are done.
  1098. spar1:  mov ah,2[bx]            ; Get the number of padding chars.
  1099.         sub ah,' '
  1100.         mov spad,ah
  1101.         mov ax,temp4
  1102.         cmp al,4                ; Fewer than four pieces?
  1103.         jge spar2
  1104.         ret                     ; If so we are done.
  1105. spar2:  mov ah,3[bx]            ; Get the padding char.
  1106.         add ah,100O             ; Re-controlify it.
  1107.         and ah,7FH
  1108.         mov spadch,ah
  1109.         mov ax,temp4
  1110.         cmp al,5                ; Fewer than five pieces?
  1111.         jge spar3
  1112.         ret                     ; If so we are done.
  1113. spar3:  mov ah,4[bx]            ; Get the EOL char.
  1114.         sub ah,' '
  1115.         mov seol,ah
  1116.         mov ax,temp4
  1117.         cmp al,6                ; Fewer than six pieces?
  1118.         jge spar4
  1119.         ret                     ; If so we are done.
  1120. spar4:  mov ah,5[bx]            ; Get the quote char.
  1121.         mov squote,ah
  1122.         ret
  1123. SPAR    ENDP
  1124.  
  1125.  
  1126. ;       Initialize buffers and clear line.
  1127.  
  1128. INIT    PROC    NEAR
  1129.     call cmblnk
  1130.     call locate
  1131.         mov ah,prstr            ; Put statistics headers on the screen.
  1132.         mov dx,offset outlin
  1133.         int dos
  1134.         call init1
  1135.         ret
  1136. INIT    ENDP
  1137.  
  1138. INIT1   PROC    NEAR
  1139.         mov chrcnt,bufsiz              ; Number of chars left.
  1140.         mov bufpnt,offset buff         ; Addr for beginning.
  1141.         ret
  1142. INIT1   ENDP
  1143.  
  1144. ;  Clear out message about interrupted file. [20b]
  1145. CXMSG    PROC    NEAR
  1146. IF ibmpc OR L610
  1147.     mov ah,2
  1148.     mov bh,0
  1149.     mov dx,scrint
  1150.     int bios
  1151.     mov ax,0920H
  1152.     mov bx,7
  1153.     mov cx,26
  1154.     int bios    
  1155.     ret
  1156. ENDIF
  1157. IF Z100
  1158.     mov ah,prstr
  1159.     mov dx,offset scrint    ; Move the cursor.
  1160.     int dos
  1161.     mov ah,prstr        ; Get the function again
  1162.     mov dx,offset clreol    ; And the sequence to clear to EOL
  1163.     int dos            ; Do it
  1164.     ret
  1165. ENDIF
  1166. CXMSG    ENDP
  1167.  
  1168. ;  Clear out the old filename on the screen. 
  1169.  
  1170. CLRFLN    PROC    NEAR
  1171. IF ibmpc OR L610
  1172.     mov ah,2
  1173.     mov bh,0
  1174.     mov dx,scrfln
  1175.     int bios
  1176.     call clreol        ; Clear to end of line. [19a]
  1177.     ret
  1178. ENDIF
  1179. IF Z100
  1180.     mov ah,prstr        ; Get print string function
  1181.     mov dx,offset scrfln    ; and string to move cursor
  1182.     int dos            ; Print the string
  1183.     mov ah,prstr        ; Get the function again
  1184.     mov dx,offset clreol    ; And the sequence to clear to EOL
  1185.     int dos            ; Do it
  1186.     ret            ; And return
  1187. ENDIF
  1188. CLRFLN    ENDP
  1189.  
  1190. ;       RECEIVE command
  1191.  
  1192. READ    PROC    NEAR
  1193.     mov bx,offset data    ; Where to put text (if any).  [8 start]
  1194.     mov ah,cmtxt
  1195.         call comnd              ; Get text or confirm.
  1196.          jmp kermt3
  1197.     cmp ah,0        ; Read in any chars?
  1198.     je read1        ; A regular receive.
  1199.     mov al,ah
  1200.     mov ah,0
  1201.     mov argbk1,ax        ; Remember number of chars we read.
  1202.     mov ah,'$'        ; Use for printing.
  1203.     mov [bx],ah
  1204.     call init        ; Clear line and initialize buffers.
  1205.     call clrfln        ; Prepare to print filename.
  1206.     mov ah,prstr
  1207.     mov dx,offset data    ; Print file name.
  1208.     int dos
  1209.     mov argblk,0        ; Start at packet zero.
  1210.     mov ah,'R'        ; Receive init packet.
  1211.     call spack        ; Send the packet.
  1212.      jmp kermt3
  1213.     jmp read12                        ; [8 end]
  1214. read1:  call init               ; Clear the line and initialize the buffers.
  1215. read12: mov numpkt,0            ; Set the number of packets to zero.
  1216.         mov numrtr,0            ; Set the number of retries to zero.
  1217.         mov pktnum,0            ; Set the packet number to zero.
  1218.         mov numtry,0            ; Set the number of tries to zero.
  1219.     mov cxzflg,0        ; Reset ^X/^Z flag. [20c] 
  1220.     call serini        ; Initialize serial port. [14]
  1221.         call rtpos        ; Position cursor.
  1222.         mov ax,numrtr
  1223.         call nout               ; Write the number of retries.
  1224.         mov state,'R'           ; Set the state to receive initiate.
  1225. read2:  
  1226. IF ibmpc OR L610
  1227.     mov ah,2        ; Position cursor.
  1228.     mov dx,scrst
  1229.     mov bh,0
  1230.     int bios
  1231. ENDIF
  1232. IF Z100
  1233.     mov ah,prstr        ; Get print string function
  1234.     mov dx,offset scrst    ; and string to move cursor
  1235.     int dos            ; Print the string
  1236. ENDIF
  1237.     mov ah,prstr            ; Be informative.
  1238.         mov dx,offset infms1
  1239.         int dos
  1240. IF ibmpc OR L610
  1241.     mov ah,2
  1242.     mov dx,scrnp
  1243.     mov bh,0
  1244.     int bios
  1245. ENDIF
  1246. IF Z100
  1247.     mov ah,prstr        ; Get print string function
  1248.     mov dx,offset scrnp    ; and string to move cursor
  1249.     int dos            ; Print the string
  1250. ENDIF
  1251.         mov ax,numpkt
  1252.         call nout               ; Write the number of packets.
  1253.         mov ah,state            ; Get the state.
  1254.         cmp ah,'D'              ; Are we in the data send state?
  1255.         jne read3
  1256.         call rdata
  1257.         jmp read2
  1258. read3:  cmp ah,'F'              ; Are we in the file receive state?
  1259.         jne read4
  1260.         call rfile              ; Call receive file.
  1261.         jmp read2
  1262. read4:  cmp ah,'R'              ; Are we in the receive initiate state?
  1263.         jne read5
  1264.         call rinit
  1265.         jmp read2
  1266. read5:  cmp ah,'C'              ; Are we in the receive complete state?
  1267.         jne read6
  1268.     call serrst        ; Reset serial port. [14]
  1269. IF ibmpc OR L610
  1270.     mov ah,2        ; Position cursor.
  1271.     mov dx,scrst
  1272.     mov bh,0
  1273.     int bios
  1274. ENDIF
  1275. IF Z100
  1276.     mov ah,prstr        ; Get print string function
  1277.     mov dx,offset scrst    ; and string to move cursor
  1278.     int dos            ; Print the string
  1279. ENDIF
  1280.         mov ah,prstr
  1281.         mov dx,offset infms3    ; Plus a little cuteness.
  1282.     cmp cxzflg,0        ; Completed or interrupted? [20c]
  1283.     je read13        ; Ended normally. [20c]
  1284.     mov dx,offset infms6    ; Say was interrupted. [20c]
  1285. read13: int dos
  1286.     cmp belflg,0        ; Bell desired?  [17a]
  1287.     je readnb        ; No.  [17a]
  1288.     mov dx,offset ender    ; Ring them bells.    [4]
  1289.     int dos            ; [4]
  1290. readnb:                ; [17a -- new label]
  1291. IF ibmpc OR L610
  1292.     mov ah,2
  1293.     mov dx,scrrpr        ; Put prompt here.
  1294.     mov bh,0
  1295.     int bios
  1296. ENDIF
  1297. IF Z100
  1298.     mov ah,prstr        ; Get print string function
  1299.     mov dx,offset scrrpr    ; and string to move cursor
  1300.     int dos            ; Print the string
  1301. ENDIF
  1302.         jmp rskp
  1303. read6:     call serrst        ; Reset serial port. [14]
  1304. IF ibmpc OR L610
  1305.     mov ah,2        ; Position cursor.
  1306.     mov dx,scrst
  1307.     mov bh,0
  1308.     int bios
  1309. ENDIF
  1310. IF Z100
  1311.     mov ah,prstr        ; Get print string function
  1312.     mov dx,offset scrst    ; and string to move cursor
  1313.     int dos            ; Print the string
  1314. ENDIF
  1315.         mov ah,prstr
  1316.     mov dx,offset infms4    ; Plus a little cuteness.
  1317.         int dos
  1318.     cmp belflg,0        ; Bell desired?  [17a]
  1319.     je read7        ; No.  [17a]
  1320.     mov dx,offset ender    ; Ring them bells.   [4]
  1321.     int dos            ;  [4]
  1322. read7:
  1323. IF ibmpc OR L610
  1324.     mov ah,2
  1325.     mov dx,scrrpr
  1326.     mov bh,0
  1327.     int bios
  1328. ENDIF
  1329. IF Z100
  1330.     mov ah,prstr        ; Get print string function
  1331.     mov dx,offset scrrpr    ; and string to move cursor
  1332.     int dos            ; Print the string
  1333. ENDIF
  1334.         jmp rskp
  1335. READ    ENDP
  1336.  
  1337.  
  1338. ;       Receive routines
  1339.  
  1340. ;       Receive init
  1341.  
  1342. RINIT   PROC    NEAR
  1343.         mov ah,numtry           ; Get the number of tries.
  1344.         cmp ah,imxtry           ; Have we reached the maximum number of tries?
  1345.         jl rinit2
  1346.     call erpos        ; Position cursor.
  1347.         mov dx,offset ermes7
  1348.         mov ah,prstr
  1349.         int dos                 ; Print an error message.
  1350.         jmp abort               ; Change the state to abort.
  1351. rinit2: inc ah                  ; Increment it.
  1352.         mov numtry,ah           ; Save the updated number of tries.
  1353.         call rpack              ; Get a packet.
  1354.          jmp nak                ;  Trashed packet: nak, retry.
  1355.         cmp ah,'S'              ; Is it a send initiate packet?
  1356.         jne rinit3              ; If not see if its an error.
  1357.         mov ah,numtry           ; Get the number of tries.
  1358.         mov oldtry,ah           ; Save it.
  1359.         mov numtry,0            ; Reset the number of tries.
  1360.         mov ax,argblk           ; Returned packet number.  (Synchronize them.)
  1361.         inc ax                  ; Increment it.
  1362.         and ax,3FH              ; Turn off the two high order bits.
  1363.         mov pktnum,ax           ; Save modulo 64 of the number.
  1364.         mov bx,numpkt
  1365.         inc bx                  ; Increment the number of packets.
  1366.         mov numpkt,bx
  1367.         mov ax,argbk1           ; Get the number of arguments received.
  1368.         mov bx,offset data      ; Get a pointer to the data.
  1369.         call spar               ; Get the data into the proper variables.
  1370.         mov bx,offset data      ; Get a pointer to our data block.
  1371.         call rpar               ; Set up the receive parameters.
  1372.     xchg ah,al
  1373.     mov ah,0
  1374.         mov argbk1,ax           ; Store the returned number of arguments.
  1375.         mov ah,'Y'              ; Acknowledge packet.
  1376.         call spack              ; Send the packet.
  1377.      jmp abort
  1378.         mov ah,'F'              ; Set the state to file send.
  1379.         mov state,ah
  1380.         ret
  1381. rinit3: cmp ah,'E'              ; Is it an error packet?
  1382.         jne rinit4
  1383.         call error
  1384. rinit4: jmp abort
  1385. RINIT   ENDP
  1386.  
  1387.  
  1388. ;       Receive file
  1389.  
  1390. RFILE   PROC    NEAR
  1391.         cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  1392.         jl rfile1
  1393.     call erpos        ; Position cursor.
  1394.         mov dx,offset ermes8
  1395.         mov ah,prstr
  1396.         int dos                 ; Print an error message.
  1397.         jmp abort               ; Change the state to abort.
  1398. rfile1: inc numtry              ; Save the updated number of tries.
  1399.         call rpack              ; Get a packet.
  1400.          jmp nak                ;  Trashed packet: nak, retry.
  1401.         cmp ah,'S'              ; Is it a send initiate packet?
  1402.         jne rfile2              ;  No, try next type.
  1403.         cmp oldtry,imxtry       ; Have we reached the maximum number of tries?
  1404.         jl rfil12               ; If not proceed.
  1405.     call erpos        ; Position cursor.
  1406.         mov dx,offset ermes7
  1407.         mov ah,prstr
  1408.         int dos                 ; Print an error message.
  1409.         jmp abort               ; Change the state to abort.
  1410. rfil12: inc oldtry              ; Save the updated number of tries.
  1411.         mov ax,pktnum           ; Get the present packet number.
  1412.     cmp ax,0        ; Had we wrapped around? [18 start]
  1413.     jne rfilx 
  1414.     mov ax,64
  1415. rfilx:  dec ax                  ; Decrement.  [18 end -- new label]
  1416.         cmp ax,argblk           ; Is the packet's number one less than now?
  1417.         je rfil13
  1418.         jmp nak                 ; No, NAK and try again.
  1419. rfil13: call rtpos              ; Position cursor.
  1420.         inc numrtr              ; Increment the number of retries.
  1421.         mov ax,numrtr
  1422.         call nout               ; Write the number of retries.
  1423.         mov numtry,0            ; Reset the number of tries.
  1424.         mov bx,offset data      ; Get a pointer to our data block.
  1425.         call rpar               ; Set up the parameter information.
  1426.     xchg ah,al
  1427.     mov ah,0
  1428.         mov argbk1,ax           ; Save the number of arguments.
  1429.         mov ah,'Y'              ; Acknowledge packet.
  1430.         call spack              ; Send the packet.
  1431.      jmp abort
  1432.         ret
  1433. rfile2: cmp ah,'Z'              ; Is it an EOF packet?
  1434.         jne rfile3              ;  No, try next type.
  1435.         cmp oldtry,maxtry       ; Have we reached the maximum number of tries?
  1436.         jl rfil21               ; If not proceed.
  1437.         call erpos              ; Position cursor.
  1438.         mov dx,offset ermes9
  1439.         mov ah,prstr
  1440.         int dos                 ; Print an error message.
  1441.         jmp abort               ; Change the state to abort.
  1442. rfil21: inc oldtry              ; Increment it.
  1443.         mov ax,pktnum           ; Get the present packet number.
  1444.     cmp ax,0        ; Had we wrapped around? [18 start]
  1445.     jne rfily
  1446.     mov ax,64
  1447. rfily:  dec ax                  ; Decrement.  [18 end -- new label]
  1448.         cmp ax,argblk           ; Is the packet's number one less than now?
  1449.         je rfil24
  1450.         jmp nak                 ; No, NAK and try again.
  1451. rfil24: call rtpos              ; Position cursor.
  1452.         inc numrtr              ; Increment the number of retries
  1453.         mov ax,numrtr
  1454.         call nout               ; Write the number of retries.
  1455.         mov numtry,0
  1456.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1457.         mov ah,'Y'              ; Acknowledge packet.
  1458.         call spack              ; Send the packet.
  1459.      jmp abort
  1460.         ret
  1461. rfile3: cmp ah,'F'              ; Start of file?
  1462.         jne rfile4
  1463.         mov ax,argblk           ; Get the packet number.
  1464.         cmp ax,pktnum           ; Is it the right packet number?
  1465.         je rfil32
  1466.         jmp nak                 ; No, NAK it and try again.
  1467. rfil32: inc ax                  ; Increment the packet number.
  1468.         and ax,3FH              ; Turn off the two high order bits.
  1469.         mov pktnum,ax           ; Save modulo 64 of the number.
  1470.         inc numpkt              ; Increment the number of packets.
  1471.         call gofil              ; Get a file to write to.
  1472.          jmp abort
  1473.         call init1              ; Initialize all the buffers.
  1474.         mov ah,numtry           ; Get the number of tries.
  1475.         mov oldtry,ah           ; Save it.
  1476.         mov numtry,0            ; Reset the number of tries.
  1477.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1478.         mov ah,'Y'              ; Acknowledge packet.
  1479.         call spack              ; Send the packet.
  1480.      jmp abort
  1481.         mov state,'D'           ; Set the state to data receive.
  1482.         ret
  1483. rfile4: cmp ah,'B'              ; End of transmission.
  1484.         jne rfile5
  1485.         mov ax,pktnum
  1486.         cmp ax,argblk           ; Do we match?
  1487.         je rfil41
  1488.         jmp nak                 ; No, NAK it and try again.
  1489. rfil41: mov argbk1,0            ; No data.  (Packet number already in argblk).
  1490.         mov ah,'Y'              ; Acknowledge packet.
  1491.         call spack              ; Send the packet.
  1492.      jmp abort
  1493.         mov state,'C'           ; Set the state to complete.
  1494.         ret
  1495. rfile5: cmp ah,'E'              ; Is it an error packet.
  1496.         jne rfile6
  1497.         call error
  1498. rfile6: jmp abort
  1499. RFILE   ENDP
  1500.  
  1501.  
  1502. ;       Receive data
  1503.  
  1504. RDATA   PROC    NEAR
  1505.         cmp numtry,maxtry       ; Get the number of tries.
  1506.         jl rdata1
  1507.         call erpos              ; Position cursor.
  1508.         mov dx,offset erms10
  1509.         mov ah,prstr
  1510.         int dos                 ; Print an error message.
  1511.         jmp abort               ; Change the state to abort.
  1512. rdata1: inc numtry              ; Save the updated number of tries.
  1513.         call rpack              ; Get a packet.
  1514.          jmp nak                ;  Trashed packet: nak, retry.
  1515.         cmp ah,'D'              ; Is it a data packet?
  1516.     je rdat11
  1517.         jmp rdata2              ;  No, try next type.
  1518. rdat11: mov ax,pktnum           ; Get the present packet number.
  1519.         cmp ax,argblk           ; Is the packet's number correct?
  1520.         jz rdat14
  1521.         cmp oldtry,maxtry       ; Have we reached the maximum number of tries?
  1522.         jl rdat12               ; If not proceed.
  1523.     call erpos              ; Position cursor.
  1524.         mov dx,offset erms10
  1525.         mov ah,prstr
  1526.         int dos                 ; Print an error message.
  1527.         jmp abort               ; Change the state to abort.
  1528. rdat12: inc oldtry              ; Save the updated number of tries.
  1529. ;        dec pktnum              ; Decrement present packet number.  [14]
  1530.         mov ax,pktnum
  1531.     cmp ax,0        ; Had we wrapped around? [18 start]
  1532.     jne rdatx
  1533.     mov ax,64
  1534. rdatx:    dec ax            ; [14] [18 end -- new label]
  1535.         cmp ax,argblk           ; Is the packet's number one less than now?
  1536.         je rdat13
  1537.         jmp nak                 ; No, NAK it and try again.
  1538. rdat13: call rtpos              ; Position cursor.
  1539.         inc numrtr              ; Increment the number of retries
  1540.         mov ax,numrtr
  1541.         call nout               ; Write the number of retries.
  1542.         mov numtry,0            ; Reset number of tries.
  1543.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1544.         mov ah,'Y'              ; Acknowledge packet.
  1545.         call spack              ; Send the packet.
  1546.      jmp abort
  1547.         ret
  1548. rdat14: inc ax                  ; Increment the packet number.
  1549.         and ax,3FH              ; Turn off the two high order bits.
  1550.         mov pktnum,ax           ; Save modulo 64 of the number.
  1551.         inc numpkt              ; Increment the number of packets.
  1552.         mov ah,numtry           ; Get the number of tries.
  1553.         mov oldtry,ah           ; Save it.
  1554.         mov ax,argbk1           ; Get the length of the data.
  1555.     cmp cxzflg,0        ; Has the user typed a ^X or ^Z? [20c]
  1556.     jne rdat15        ; If yes don't write data out to file. [20c]
  1557.     call ptchr
  1558.          jmp abort              ;  Unable to write out chars; abort.
  1559. rdat15: mov numtry,0            ; Reset the number of tries.
  1560.         mov argbk1,0            ; No data.  (Packet number still in argblk.)
  1561.     cmp cxzflg,0        ; Interrupt file transfer? [20c]
  1562.     je rdat16        ; Nope. [20c] 
  1563.     mov bx,offset data    ; Send data in ACK in case remote... [20c] 
  1564.     mov ah,cxzflg        ; ... knows about ^X/^Z. [20c]
  1565.     mov [bx],ah        ; Put data into the packet. [20c]
  1566.     mov argbk1,1        ; Set data size to 1. [20c]
  1567. rdat16: mov ah,'Y'              ; Acknowledge packet.
  1568.         call spack              ; Send the packet.
  1569.      jmp abort
  1570.         ret
  1571. rdata2: cmp ah,'F'              ; Start of file?
  1572.         jne rdata3              ;  No, try next type.
  1573.         cmp oldtry,maxtry       ; Have we reached the maximum number of tries?
  1574.         jl rdat21               ; If not proceed.
  1575.     call erpos        ; Position cursor.
  1576.         mov dx,offset ermes8
  1577.         mov ah,prstr
  1578.         int dos                 ; Print an error message.
  1579.         jmp abort               ; Change the state to abort.
  1580. rdat21: inc oldtry              ; Save the updated number of tries.
  1581.         mov ax,pktnum
  1582.     cmp ax,0        ; Had we wrapped around? [18 start]
  1583.     jne rdaty
  1584.     mov ax,64
  1585. rdaty:    dec ax            ; [14 Omitted accidentally - D.T.] [18 end]
  1586.         cmp ax,argblk           ; Is the packet's number one less than now?
  1587.         je rdat22
  1588.         jmp nak                 ; No, NAK it and try again.
  1589. rdat22: call rtpos              ; Position cursor.
  1590.         inc numrtr              ; Increment the number of retries
  1591.         mov ax,numrtr
  1592.         call nout               ; Write the number of retries.
  1593.         mov numtry,0            ; Reset number of tries.
  1594.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1595.         mov ah,'Y'              ; Acknowledge packet.
  1596.         call spack              ; Send the packet.
  1597.      jmp abort
  1598.         ret
  1599. rdata3: cmp ah,'Z'              ; Is it a EOF packet?
  1600.     je rdat3x                ; [13]
  1601.         jmp rdata4               ; Try and see if its an error. [13]
  1602. rdat3x: mov ax,pktnum           ; Get the present packet number. [13]
  1603.         cmp ax,argblk           ; Is the packet's number correct?
  1604.         je rdat32
  1605.         jmp nak                 ; No, NAK it and try again.
  1606. rdat32: inc ax                  ; Increment the packet number.
  1607.         and ax,3FH              ; Turn off the two high order bits.
  1608.         mov pktnum,ax           ; Save modulo 64 of the number.
  1609.         inc numpkt
  1610.     cmp cxzflg,0        ; Do we want to discard the file? [20c]
  1611.     jne rdt32x        ; Yes. [20c]
  1612.     cmp argbk1,1        ; One piece of data? [20c]
  1613.     jne rdat33        ; Nope - finish writing out file? [20c]
  1614.     mov bx,offset data    ; Get data area. [20c]
  1615.     mov ah,[bx]        ; Get the data. [20c]
  1616.     cmp ah,'D'        ; "D" for discard? [20c]
  1617.     jne rdat33        ; Nope - write out file. [20c]
  1618. rdt32x:    mov ah,delf        ; Delete the file if opened. [20c]
  1619.     mov dx,offset fcb    ; Give the file parameters. [20c]
  1620.     int dos            ; Kill it, ignore errors. [20c]
  1621.     cmp cxzflg,'X'        ; Kill one file or all? [20c]
  1622.     jne rdat36        ; No so leave flag alone. [20c]
  1623.     call cxmsg        ; Clear msg about interrupt. [20c]
  1624.     mov cxzflg,0        ; Reset - ^X only kills one file. [20c]
  1625.     jmp rdat36
  1626. rdat33: mov bx,bufpnt           ; Get the dma pointer.
  1627.     mov ax,80H
  1628.         sub ax,chrcnt           ; Get the number of chars left in the DMA.
  1629.     cmp ax,80H        ;   [13 start]
  1630.     jne rdat34
  1631.     call outbuf        ; Write out buffer if no room for ^Z.
  1632.      jmp abort
  1633.     mov ax,0        ;   [13 end]
  1634. rdat34: mov cl,'Z'-100O         ; Put in a ^Z for EOF.
  1635.         mov [bx],cl
  1636.     inc ax
  1637.     dec chrcnt
  1638.     mov cx,chrcnt
  1639.     mov temp,cx
  1640.     inc bx
  1641. rdt3:    inc ax
  1642.     cmp ax,80H
  1643.     jg rdat35        ; Pad till full.
  1644.     mov cl,0        ; Use nulls.
  1645.     mov [bx],cl
  1646.     inc bx
  1647.         jmp rdt3
  1648. rdat35: call outbuf             ; Output the last buffer.
  1649.          jmp abort              ;  Give up if the disk is full.
  1650.     call fixfcb
  1651.         mov ah,closf            ; Close up the file.
  1652.         mov dx,offset fcb
  1653.         int dos
  1654. rdat36: mov ah,numtry           ; Get the number of tries.
  1655.         mov oldtry,ah           ; Save it.
  1656.         mov numtry,0            ; Reset the number of tries.
  1657.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1658.         mov ah,'Y'              ; Acknowledge packet.
  1659.         call spack              ; Send the packet.
  1660.      jmp abort
  1661.         mov state,'F'
  1662.         ret
  1663. rdata4: cmp ah,'E'                      ; Is it an error packet.
  1664.         jne rdata5
  1665.         call error
  1666. rdata5: jmp abort
  1667. RDATA   ENDP
  1668.  
  1669. FIXFCB  PROC    NEAR    
  1670.     mov bx,offset fcb+18
  1671.     mov di,offset filsiz
  1672.     mov ax,[bx]
  1673.     mov [di],ax
  1674.     mov bx,offset fcb+16
  1675.     mov ax,[bx]
  1676.     mov 2[di],ax
  1677.     mov ax,temp        ; Get number of chars in last buffer full.
  1678.     sub filsiz+2,ax        ; Get real file size.
  1679.     sbb filsiz,0
  1680.     mov bx,offset fcb+18
  1681.     mov di,offset filsiz
  1682.     mov ax,[di]
  1683.     mov [bx],ax
  1684.     mov bx,offset fcb+16
  1685.     mov ax,2[di]
  1686.     mov [bx],ax
  1687.     ret
  1688. FIXFCB    ENDP
  1689.  
  1690.  
  1691. ;       Send command
  1692.  
  1693. SEND    PROC    NEAR
  1694.         mov ah,cmifi            ; Parse an input file spec.
  1695.         mov dx,offset fcb       ; Give the address for the FCB.
  1696.         call comnd
  1697.          jmp r                  ;  Give up on bad parse.
  1698. send1:  mov ah,cmcfm
  1699.         call comnd              ; Get a confirm.
  1700.          jmp r                  ;  Didn't get a confirm.
  1701. send11: mov ah,sfirst           ; Get the first file.
  1702.         mov dx,offset fcb
  1703.         int dos
  1704.         cmp al,0FFH             ; Any found?
  1705.         jne send12
  1706.     mov ah,prstr
  1707.     mov dx,offset crlf
  1708.     int dos
  1709.         mov ah,prstr
  1710.         mov dx,offset erms15
  1711.         int dos
  1712.         ret
  1713. send12: cmp wldflg,0        ; Any wildcards.      [7 start]
  1714.     je send16        ; Nope, so no problem.
  1715.     mov bx,offset fcb    ; Remember what FCB looked like.
  1716.     mov di,offset cpfcb
  1717.     mov cl,37        ; Size of FCB.
  1718.     call fcbcpy
  1719.     mov di,offset fcb+1    ; Copy filename    from DTA to FCB.
  1720.     mov bx,offset buff+1
  1721.     mov cl,11
  1722.     call fcbcpy                    ; [7 end]
  1723. send16: call init               ; Clear the line and initialize the buffers.
  1724.     call serini        ; Initialize serial port. [14]
  1725.         mov pktnum,0            ; Set the packet number to zero.
  1726.         mov numtry,0            ; Set the number of tries to zero.
  1727.         mov numpkt,0            ; Set the number of packets to zero.
  1728.         mov numrtr,0            ; Set the number of retries to zero.
  1729.         call rtpos              ; Position cursor.
  1730.         mov ax,0
  1731.         call nout               ; Write the number of retries.
  1732.         mov state,'S'           ; Set the state to receive initiate.
  1733. send2:  
  1734. IF ibmpc OR L610
  1735.     mov ah,2                ; Position cursor.
  1736.     mov bh,0
  1737.     mov dx,scrst
  1738.     int bios
  1739. ENDIF
  1740. IF Z100
  1741.     mov ah,prstr        ; Get print string function
  1742.     mov dx,offset scrst    ; and string to move cursor
  1743.     int dos            ; Print the string
  1744. ENDIF
  1745.         mov ah,prstr            ; Be informative.
  1746.         mov dx,offset infms2
  1747.         int dos
  1748. IF ibmpc OR L610
  1749.     mov ah,2
  1750.     mov dx,scrnp
  1751.     mov bh,0
  1752.     int bios
  1753. ENDIF
  1754. IF Z100
  1755.     mov ah,prstr        ; Get print string function
  1756.     mov dx,offset scrnp    ; and string to move cursor
  1757.     int dos            ; Print the string
  1758. ENDIF
  1759.         mov ax,numpkt
  1760.         call nout               ; Write the packet number.
  1761.         cmp state,'D'           ; Are we in the data send state?
  1762.         jne send3
  1763.         call sdata
  1764.         jmp send2
  1765. send3:  cmp state,'F'           ; Are we in the file send state?
  1766.         jne send4
  1767.         call sfile              ; Call send file.
  1768.         jmp send2
  1769. send4:  cmp state,'Z'           ; Are we in the EOF state?
  1770.         jne send5
  1771.         call seof
  1772.         jmp send2
  1773. send5:  cmp state,'S'           ; Are we in the send initiate state?
  1774.         jne send6
  1775.         call sinit
  1776.         jmp send2
  1777. send6:  cmp state,'B'           ; Are we in the eot state?
  1778.         jne send7
  1779.         call seot
  1780.         jmp send2
  1781. send7:  cmp state,'C'           ; Are we in the send complete state?
  1782.         jne send8
  1783.     call serrst        ; Reset serial port.  [14]
  1784. IF ibmpc OR L610
  1785.     mov ah,2                ; Position cursor.
  1786.     mov dx,scrst
  1787.     mov bh,0
  1788.     int bios
  1789. ENDIF
  1790. IF Z100
  1791.     mov ah,prstr        ; Get print string function
  1792.     mov dx,offset scrst    ; and string to move cursor
  1793.     int dos            ; Print the string
  1794. ENDIF
  1795.         mov ah,prstr
  1796.         mov dx,offset infms3    ; Plus a little cuteness.
  1797.     cmp cxzflg,0        ; Completed or interrupted? [20b]
  1798.     je snd71        ; Ended normally. [20b]
  1799.     mov dx,offset infms6    ; Say was interrupted. [20b]
  1800. snd71:  int dos            ; New label. [20b] 
  1801.     cmp belflg,0        ; Bell desired? [17a]
  1802.     je sendnb        ; [17a]
  1803.     mov dx,offset ender    ; Ring them bells.   [4]
  1804.     int dos            ;  [4]
  1805. sendnb:                ; [17a -- new label] 
  1806. IF ibmpc OR L610
  1807.     mov ah,2
  1808.     mov dx,scrrpr
  1809.     mov bh,0
  1810.     int bios
  1811. ENDIF
  1812. IF Z100
  1813.     mov ah,prstr        ; Get print string function
  1814.     mov dx,offset scrrpr    ; and string to move cursor
  1815.     int dos            ; Print the string
  1816. ENDIF
  1817.         jmp rskp
  1818. send8:     call serrst        ; Reset serial port.  [14]
  1819. IF ibmpc OR L610
  1820.     mov ah,2                ; Position cursor.
  1821.     mov dx,scrst
  1822.     mov bh,0
  1823.     int bios
  1824. ENDIF
  1825. IF Z100
  1826.     mov ah,prstr        ; Get print string function
  1827.     mov dx,offset scrst    ; and string to move cursor
  1828.     int dos            ; Print the string
  1829. ENDIF
  1830.         mov ah,prstr
  1831.         mov dx,offset infms4    ; Plus a little cuteness.
  1832.         int dos
  1833.     cmp belflg,0        ; Bell desired?  [17a]
  1834.     je send9        ; No.  [17a]
  1835.     mov dx,offset ender    ; Ring them bells.   [4]
  1836.     int dos            ;  [4]
  1837. send9:
  1838. IF ibmpc OR L610
  1839.     mov ah,2
  1840.     mov dx,scrrpr
  1841.     mov bh,0
  1842.     int bios
  1843. ENDIF
  1844. IF Z100
  1845.     mov ah,prstr        ; Get print string function
  1846.     mov dx,offset scrrpr    ; and string to move cursor
  1847.     int dos            ; Print the string
  1848. ENDIF
  1849.         jmp rskp
  1850. SEND    ENDP
  1851.  
  1852.  
  1853. ;       Send routines
  1854.  
  1855. ;       Send initiate
  1856.  
  1857.  
  1858. SINIT   PROC    NEAR
  1859.         cmp numtry,imxtry       ; Have we reached the maximum number of tries?
  1860.         jl sinit2
  1861.     call erpos
  1862.         mov dx,offset erms14
  1863.         mov ah,prstr
  1864.         int dos                 ; Print an error message.
  1865.         jmp abort               ; Change the state to abort.
  1866. sinit2: inc numtry              ; Save the updated number of tries.
  1867.         mov bx,offset data      ; Get a pointer to our data block.
  1868.         call rpar               ; Set up the parameter information.
  1869.     xchg ah,al
  1870.     mov ah,0
  1871.         mov argbk1,ax           ; Save the number of arguments.
  1872.         mov ax,numpkt           ; Get the packet number.
  1873.         mov argblk,ax
  1874.         mov ah,'S'              ; Send initiate packet.
  1875.         call spack              ; Send the packet.
  1876.      jmp abort
  1877.         call rpack              ; Get a packet.
  1878.          jmp r                  ;  Trashed packet don't change state, retry.
  1879.         cmp ah,'Y'              ; ACK?
  1880.         jne sinit3              ; If not try next.
  1881.         mov ax,pktnum           ; Get the packet number.
  1882.         cmp ax,argblk           ; Is it the right packet number?
  1883.         je sini22
  1884.         ret                     ; If not try again.
  1885. sini22: inc ax                  ; Increment the packet number.
  1886.         and ax,3FH              ; Turn off the two high order bits.
  1887.         mov pktnum,ax           ; Save modulo 64 of the number.
  1888.         inc numpkt              ; Increment the number of packets.
  1889.         mov ax,argbk1           ; Get the number of pieces of data.
  1890.         mov bx,offset data      ; Pointer to the data.
  1891.         call spar               ; Read in the data.
  1892.         mov ah,numtry           ; Get the number of tries.
  1893.         mov oldtry,ah           ; Save it.
  1894.         mov numtry,0            ; Reset the number of tries.
  1895.         mov state,'F'           ; Set the state to file send.
  1896.         call getfil             ; Open the file.
  1897.          jmp abort              ;  Something is wrong, die.
  1898.         ret
  1899. sinit3: cmp ah,'N'              ; NAK?
  1900.         jne sinit4              ; If not see if its an error.
  1901.         call rtpos              ; Position cursor.
  1902.         inc numrtr              ; Increment the number of retries
  1903.         mov ax,numrtr
  1904.         call nout               ; Write the number of retries.
  1905. ;        mov ax,pktnum           ; Get the present packet number. [18 start]
  1906. ;        inc ax                  ; Increment.
  1907. ;        cmp ax,argblk           ; Get the packet's number.
  1908. ;        je sini32
  1909. ;        ret                     ; If not assume its for this packet, go again.
  1910. ;sini32: mov numtry,0            ; Reset number of tries.
  1911. ;        mov state,'F'           ; Set the state to file send. [18 end]
  1912.         ret
  1913. sinit4: cmp ah,'E'              ; Is it an error packet.
  1914.         jne sinit5
  1915.         call error
  1916. sinit5: jmp abort
  1917. SINIT   ENDP
  1918.  
  1919.  
  1920.  
  1921. ;       Send file header
  1922.  
  1923. SFILE   PROC    NEAR
  1924.         cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  1925.         jl sfile1
  1926.     call erpos
  1927.         mov dx,offset erms14
  1928.         mov ah,prstr
  1929.         int dos                 ; Print an error message.
  1930.         jmp abort               ; Change the state to abort.
  1931. sfile1: inc numtry              ; Increment it.
  1932.     mov cxzflg,0        ; Clear ^X,^Z flag.  [20b]
  1933.         mov datptr,offset data  ; Get a pointer to our data block.
  1934.     mov bx,offset fcb+1        ; Pointer to file name in FCB.
  1935.     mov fcbptr,bx        ; Save position in FCB.
  1936.     mov cl,0        ; Counter for chars in file name.
  1937.     mov ch,0        ; Counter for number of chars in FCB.
  1938. sfil11:    cmp ch,8H        ; Ninth char?
  1939.     jne sfil12
  1940.     mov ah,'.'
  1941.     mov bx,datptr
  1942.     mov [bx],ah        ; Put dot in data packet.    
  1943.     inc bx
  1944.     mov datptr,bx        ; Save new position in data packet.
  1945.     inc cl
  1946. sfil12:    inc ch
  1947.     cmp ch,0CH        ; Twelve?
  1948.     jns sfil13
  1949.     mov bx,fcbptr
  1950.     mov ah,[bx]        ; Get char of filename.
  1951.     inc bx
  1952.     mov fcbptr,bx        ; Save position in FCB.
  1953.     cmp ah,'!'        ; Is it a good char?
  1954.     jl sfil11        ; If not, get the next.
  1955.     mov bx,datptr
  1956.     mov [bx],ah        ; Put char in data buffer.
  1957.     inc cl            ; Increment counter.
  1958.     inc bx
  1959.     mov datptr,bx        ; Save new position. 
  1960.     jmp sfil11        ; Get another char.
  1961. sfil13: mov ch,0
  1962.     mov argbk1,cx        ; Save number of char in filename.
  1963.     mov bx,datptr
  1964.     mov ah,'$'
  1965.     mov [bx],ah        ; Put dollar sign for printing.
  1966.     call clrfln
  1967.     mov ah,prstr
  1968.     mov dx,offset data    ; Print file name.
  1969.     int dos
  1970.  
  1971.         mov ax,pktnum           ; Get the packet number.
  1972.         mov argblk,ax
  1973.         mov ah,'F'              ; File header packet.
  1974.         call spack              ; Send the packet.
  1975.      jmp abort
  1976.         call rpack              ; Get a packet.
  1977.          jmp r                  ;  Trashed packet don't change state, retry.
  1978.         cmp ah,'Y'              ; ACK?
  1979.         jne sfile2              ; If not try next.
  1980.         mov ax,pktnum           ; Get the packet number.
  1981.         cmp ax,argblk
  1982.         je sfil14
  1983.         ret                     ; If not hold out for the right one.
  1984. sfil14: inc ax                  ; Increment the packet number.
  1985.         and ax,3FH              ; Turn off the two high order bits.
  1986.         mov pktnum,ax           ; Save modulo 64 of the number.
  1987.         inc numpkt              ; Increment the number of packets.
  1988.         mov ah,numtry           ; Get the number of tries.
  1989.         mov oldtry,ah           ; Save it.
  1990.         mov numtry,0            ; Reset the number of tries.
  1991.  
  1992. sfil15: mov ah,0                ; Get a zero.
  1993.         mov bx,offset fcb
  1994.         add bx,20H
  1995.         mov [bx],ah             ; Set the record number to zero.
  1996.         mov eoflag,ah           ; Indicate not EOF.
  1997.         mov ah,0FFH
  1998.         mov filflg,ah           ; Indicate file buffer empty.
  1999.         call gtchr
  2000.          jmp sfil16             ; Error go see if its EOF.
  2001.         jmp sfil17              ; Got the chars, proceed.
  2002. sfil16: cmp ah,0FFH             ; Is it EOF?
  2003.         je sfl161
  2004.         jmp abort               ; If not give up.
  2005. sfl161: mov ah,'Z'              ; Set the state to EOF.
  2006.         mov state,ah
  2007.         ret
  2008. sfil17: mov siz,ax
  2009.  
  2010.         mov state,'D'           ; Set the state to data send.
  2011.         ret
  2012. sfile2: cmp ah,'N'              ; NAK?
  2013.         jne sfile3              ; Try if error packet.
  2014.         call rtpos              ; Position cursor.
  2015.         inc numrtr              ; Increment the number of retries
  2016.         mov ax,numrtr
  2017.         call nout               ; Write the number of retries.
  2018.         mov ax,pktnum           ; Get the present packet number.
  2019.         inc ax                  ; Increment.
  2020.     and ax,03FH        ; Account for wraparound.  [18]
  2021.     cmp ax,argblk           ; Is the packet's number one more than now?
  2022.         jz sfil14               ; Just as good as a ACK; go to the ACK code.
  2023.         ret                     ; If not go try again.
  2024. sfile3: cmp ah,'E'              ; Is it an error packet.
  2025.         jne sfile4
  2026.         call error
  2027. sfile4: jmp abort
  2028. SFILE   ENDP
  2029.  
  2030.  
  2031. ;       Send data
  2032.  
  2033. SDATA   PROC    NEAR
  2034.     cmp cxzflg,0        ; Have we seen ^X or ^Z? [20b]
  2035.     je sdata0        ; Nope, just continue. [20b]
  2036.     mov state,'Z'        ; Else, abort sending the file. [20b]
  2037.     ret
  2038. sdata0: cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  2039.         jl sdata1
  2040.     call erpos
  2041.         mov dx,offset erms14
  2042.         mov ah,prstr
  2043.         int dos                 ; Print an error message.
  2044.         jmp abort               ; Change the state to abort.
  2045. sdata1: inc numtry              ; Increment it.
  2046.         mov datptr,offset data  ; Get a pointer to our data block.
  2047.         mov cbfptr,offset filbuf ; Pointer to chars to be sent.
  2048.         mov cx,1                ; First char.
  2049. sdat11: mov bx,cbfptr
  2050.         mov ah,[bx]
  2051.         inc cbfptr
  2052.         mov bx,datptr
  2053.         mov [bx],ah             ; Put the char in the data packet.
  2054.         inc datptr              ; Save position in data packet.
  2055.         inc cx                  ; Increment the count.
  2056.         cmp cx,siz              ; Have we transfered that many?
  2057.         jle sdat11              ; If not get another.
  2058.         mov ax,siz              ; Number of char in char buffer.
  2059.         mov argbk1,ax
  2060.         mov ax,pktnum           ; Get the packet number.
  2061.         mov argblk,ax
  2062.         mov ah,'D'              ; Data packet.
  2063.         call spack              ; Send the packet.
  2064.      jmp abort
  2065.         call rpack              ; Get a packet.
  2066.          jmp r                  ;  Trashed packet don't change state, retry.
  2067.         cmp ah,'Y'              ; ACK?
  2068.         jne sdata2              ; If not try next.
  2069.         mov ax,pktnum           ; Get the packet number.
  2070.         cmp ax,argblk           ; Is it the right packet number?
  2071.         jz sdat12
  2072.         ret                     ; If not hold out for the right one.
  2073. sdat12: inc ax                  ; Increment the packet number.
  2074.         and ax,3FH              ; Turn off the two high order bits.
  2075.         mov pktnum,ax           ; Save modulo 64 of the number.
  2076.         inc numpkt              ; Increment the number of packets.
  2077.         mov ah,numtry           ; Get the number of tries.
  2078.         mov oldtry,ah           ; Save it.
  2079.         mov numtry,0            ; Reset the number of tries.
  2080.     cmp argbk1,1        ; Does the ACK contain data? [20b]
  2081.     jne sdt12x        ; Nope, so continue. [20b]
  2082.     mov bx,offset data    ; If yes, check the data field. [20b]
  2083.     mov ah,[bx]        ; Pick it up. [20b]
  2084.     cmp ah,'X'        ; Other side requests ^X? [20b]
  2085.     jne sdt12y        ; Nope. [20b]
  2086.     jmp sdt12z        ; And leave. [20b]
  2087. sdt12y: cmp ah,'Z'        ; Other side requests ^Z? [20b]
  2088.     jne sdt12x        ; Nope. [20b]
  2089. sdt12z:    mov cxzflg,ah        ; Yes remember it. [20b]
  2090.     mov state,'Z'        ; Abort sending file(s). [20b]
  2091.     ret
  2092. sdt12x: call gtchr
  2093.          jmp sdat13             ; Error go see if its EOF.
  2094.         mov siz,ax              ; Save the size of the data gotten.
  2095.         ret
  2096.  
  2097. sdat13: cmp ah,0FFH             ; Is it EOF?
  2098.         je sdt131
  2099.         jmp abort               ; If not give up.
  2100.  
  2101. sdt131: mov state,'Z'           ; Set the state to EOF.
  2102.         ret
  2103. sdata2: cmp ah,'N'              ; NAK?
  2104.         jne sdata3              ; See if is an error packet.
  2105.         call rtpos            ; Position cursor.
  2106.         inc numrtr              ; Increment the number of retries
  2107.         mov ax,numrtr
  2108.         call nout               ; Write the number of retries.
  2109.         mov ax,pktnum           ; Get the present packet number.
  2110.         inc ax                  ; Increment.
  2111.     and ax,03FH        ; Account for wraparound.  [18]
  2112.         cmp ax,argblk           ; Is the packet's number one more than now?
  2113.         jz sdat12               ; Just as good as ACK; goto ACK code.
  2114.         ret                     ; If not go try again.
  2115. sdata3: cmp ah,'E'              ; Is it an error packet.
  2116.         jne sdata4
  2117.         call error
  2118. sdata4: jmp abort
  2119. SDATA   ENDP
  2120.  
  2121.  
  2122. ;       Send EOF
  2123.  
  2124. SEOF    PROC    NEAR
  2125.         cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  2126.         jl seof1
  2127.         call erpos              ; Position cursor.
  2128.         mov dx,offset erms14
  2129.         mov ah,prstr
  2130.         int dos                 ; Print an error message.
  2131.         jmp abort               ; Change the state to abort.
  2132. seof1:  inc numtry              ; Increment it.
  2133.         mov ax,pktnum           ; Get the packet number.
  2134.         mov argblk,ax
  2135.         mov argbk1,0            ; No data.
  2136.     cmp cxzflg,0        ; Seen a ^X or ^Z? [20b]
  2137.     je seof11        ; Nope, send normal EOF packet. [20b]
  2138.     mov bx,offset data    ; Get data area of packet.
  2139.     mov ah,'D'        ; Use "D" for discard. [20b]
  2140.     mov [bx],ah        ; And add it to the packet. [20b]
  2141.     mov argbk1,1        ; Set data size to 1. [20b]
  2142. seof11: mov ah,'Z'              ; EOF packet.
  2143.         call spack              ; Send the packet.
  2144.      jmp abort
  2145.         call rpack              ; Get a packet.
  2146.          jmp r                  ;  Trashed packet don't change state, retry.
  2147.         cmp ah,'Y'              ; ACK?
  2148.         jne seof2               ; If not try next.
  2149.         mov ax,pktnum           ; Get the packet number.
  2150.         cmp ax,argblk           ; Is it the right packet number?
  2151.         jz seof12
  2152.         ret                     ; If not hold out for the right one.
  2153. seof12: inc ax                  ; Increment the packet number.
  2154.         and ax,3FH              ; Turn off the two high order bits.
  2155.         mov pktnum,ax           ; Save modulo 64 of the number.
  2156.         inc numpkt              ; Increment the number of packets.
  2157.         mov ah,numtry           ; Get the number of tries.
  2158.         mov oldtry,ah           ; Save it.
  2159.         mov numtry,0            ; Reset the number of tries.
  2160.         mov ah,closf            ; Close the file.
  2161.         mov dx,offset fcb
  2162.         int dos
  2163.         call gtnfil             ; Get the next file.
  2164.          jmp seof13             ;  No more.
  2165.         mov state,'F'           ; Set the state to file send.
  2166.     cmp cxzflg,'X'        ; Control-X seen? [20b]
  2167.     jne seof14
  2168.     call cxmsg        ; Clear out the interrupt msg. [20b]
  2169. seof14:    mov cxzflg,0        ; Reset the flag. [20b]
  2170.         ret
  2171. seof13: mov state,'B'           ; Set the state to EOT.
  2172.         ret
  2173. seof2:  cmp ah,'N'              ; NAK?
  2174.         jne seof3               ; Try and see if its an error packet.
  2175.         call rtpos              ; Position cursor.
  2176.         inc numrtr              ; Increment the number of retries
  2177.         mov ax,numrtr
  2178.         call nout               ; Write the number of retries.
  2179.         mov ax,pktnum           ; Get the present packet number.
  2180.         inc ax                  ; Increment.
  2181.     and ax,03FH        ; Account for wraparound.  [18]
  2182.         cmp ax,argblk           ; Is the packet's number one more than now?
  2183.         jz seof12               ; Just as good as a ACK; go to the ACK code.
  2184.         ret                     ; If not go try again.
  2185. seof3:  cmp ah,'E'              ; Is it an error packet?
  2186.         jne seof4
  2187.         call error
  2188. seof4:  jmp abort
  2189. SEOF    ENDP
  2190.  
  2191.  
  2192. ;       Send EOT
  2193.  
  2194. SEOT    PROC    NEAR
  2195.         cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  2196.         jl seot1
  2197.         call erpos             ; Position cursor.
  2198.         mov dx,offset erms14
  2199.         mov ah,prstr
  2200.         int dos                 ; Print an error message.
  2201.         jmp abort               ; Change the state to abort.
  2202. seot1:  inc numtry              ; Increment it.
  2203.         mov ax,pktnum           ; Get the packet number.
  2204.         mov argblk,ax
  2205.         mov argbk1,0            ; No data.
  2206.         mov ah,'B'              ; EOF packet.
  2207.         call spack              ; Send the packet.
  2208.      jmp abort
  2209.         call rpack              ; Get a packet.
  2210.          jmp r                  ; Trashed packet don't change state, retry.
  2211.         cmp ah,'Y'              ; ACK?
  2212.         jne seot2               ; If not try next.
  2213.         mov ax,pktnum           ; Get the packet number.
  2214.         cmp ax,argblk           ; Is it the right packet number?
  2215.         jz seot12
  2216.         ret                     ; If not hold out for the right one.
  2217. seot12: inc ax                  ; Increment the packet number.
  2218.         and ax,3FH              ; Turn off the two high order bits.
  2219.         mov pktnum,ax           ; Save modulo 64 of the number.
  2220.         inc numpkt              ; Increment the number of packets.
  2221.         mov ah,numtry           ; Get the number of tries.
  2222.         mov oldtry,ah           ; Save it.
  2223.         mov numtry,0            ; Reset the number of tries.
  2224.         mov state,'C'           ; Set the state to file send.
  2225.         ret
  2226. seot2:  cmp ah,'N'              ; NAK?
  2227.         jne seot3               ; Is it error.
  2228.         call rtpos              ; Position cursor.
  2229.         inc numrtr              ; Increment the number of retries
  2230.         mov ax,numrtr
  2231.         call nout               ; Write the number of retries.
  2232.         mov ax,pktnum           ; Get the present packet number.
  2233.         inc ax                  ; Increment.
  2234.     and ax,03FH        ; Account for wraparound.  [18]
  2235.         cmp ax,argblk           ; Is the packet's number one more than now?
  2236.         jz seot12               ; Just as good as a ACK; go to the ACK code.
  2237.         ret                     ; If not go try again.
  2238. seot3:  cmp ah,'E'              ; Is it an error packet.
  2239.         jne seot4
  2240.         call error
  2241. seot4:  jmp abort
  2242. SEOT    ENDP
  2243.  
  2244.  
  2245. ; Here is the bulk of the file I/O.  Good luck.
  2246. ;       File routines
  2247.  
  2248. ;       Output the chars in a packet.
  2249.  
  2250. FILEIO    PROC    NEAR     
  2251.  
  2252. ptchr:  mov temp1,ax            ; Save the size.
  2253.         mov bx,offset data      ; Beginning of received packet data.
  2254.         mov outpnt,bx           ; Remember where we are.
  2255.         mov ch,rquote        ; Quote char.
  2256. ptchr1: dec temp1               ; Decrement # of chars in packet.
  2257.     jnl pt1
  2258.         jmp rskp                ; Return successfully if done.
  2259. pt1:    dec chrcnt              ; Decrement number of chars in dta.
  2260.         jns ptchr2              ; Continue if space left.
  2261.         call outbuf             ; Output it if full.
  2262.          jmp r                  ;  Error return if disk is full.
  2263. ptchr2: mov bx,outpnt           ; Get position in output buffer.
  2264.         mov ah,[bx]                     ; Grab a char.
  2265.         inc bx
  2266.         mov outpnt,bx           ; and bump pointer.
  2267.         cmp ah,ch               ; Is it the quote char?
  2268.         jne ptchr4              ; If not proceed.
  2269.         mov ah,[bx]                     ; Get the quoted character
  2270.         inc bx
  2271.         mov outpnt,bx           ; and bump pointer.
  2272.         dec temp1               ; Decrement # of chars in packet.
  2273.         mov dh,ah               ; Save the char.
  2274.         and ah,80H                      ; Turn off all but the parity bit.
  2275.         mov dl,ah               ; Save the parity bit.
  2276.         mov ah,dh                       ; Get the char.
  2277.         and ah,7FH                      ; Turn off the parity bit.
  2278.         cmp ah,ch               ; Is it the quote char?
  2279.         jz ptchr3               ; If so just go write it out.
  2280.         mov ah,dh                       ; Get the char.
  2281.         add ah,40H                      ; Make it a control char again.
  2282.         and ah,7FH                      ; Modulo 128.
  2283. ptchr3: or ah,dl                ; Or in the parity bit.
  2284. ptchr4: mov bx,bufpnt           ; Destination buffer.
  2285.         mov [bx],ah                     ; Store it.
  2286.         inc bx
  2287.         mov bufpnt,bx           ; Update the pointer
  2288.         jmp ptchr1              ; and loop to next char.
  2289.  
  2290.  
  2291.         ; output the buffer, reset bufpnt and chrcnt
  2292.  
  2293. outbuf: push bx
  2294.         mov ah,writef           ; The write code.
  2295.         mov dx,offset fcb
  2296.         int dos                ; Write the record.
  2297.         pop bx
  2298.         cmp al,0                ; Successful.
  2299.         jz outbf1
  2300.     push ax            ; Remember the return code. [20d]
  2301.     call abfil        ; Fix things up before aborting. [20d]
  2302.     pop ax            ; Retrive return code. [20d]
  2303.     cmp al,01
  2304.     jz outbf0
  2305.     call erpos
  2306.     mov ah,prstr
  2307.     mov dx,offset erms17    ; Record length exceeds dta.
  2308.     int dos
  2309.     ret
  2310. outbf0: call erpos
  2311.     mov ah,prstr            ; Tell about it.
  2312.         mov dx,offset erms11    ; Disk full error.
  2313.         int dos
  2314.         ret
  2315. outbf1: mov bx,offset buff      ; Addr for beginning.
  2316.         mov bufpnt,bx           ; Store addr for beginning.
  2317.         mov ax,bufsiz-1         ; Buffer size.
  2318.         mov chrcnt,ax           ; Number of chars left.
  2319.         jmp rskp
  2320.  
  2321. ;  Tidy up before aborting.    [20d]
  2322. ABFIL    PROC    NEAR
  2323.     mov ah,closf        ; Close the file.
  2324.     mov dx,offset fcb
  2325.     int dos
  2326.     cmp abfflg,1        ; Delete what got across or keep it?
  2327.     jne abfil0        ; Nope, keep it.
  2328.     mov ah,delf        ; Delete it.
  2329.     mov dx,offset fcb
  2330.     int dos
  2331. abfil0:    mov bx,offset erms10    ; Text of message to send.
  2332.     call errpack        ; Send an error packet.
  2333.     ret
  2334. ABFIL    ENDP
  2335.  
  2336. ; General routine for sending an error packet.  Register BX should
  2337. ; point to the text of the message being sent in the packet. [20f]
  2338.  
  2339. ERRPACK    PROC    NEAR
  2340.     mov di,offset data    ; Where to put the message.
  2341.     mov al,0
  2342. errp1:    mov ah,[bx]
  2343.     cmp ah,'$'        ; At end of message?
  2344.     je errp2
  2345.     inc al            ; Remember number of chars in msg.
  2346.     mov [di],ah
  2347.     inc bx
  2348.     inc di
  2349.     jmp errp1
  2350. errp2:    mov ah,0
  2351.     mov argbk1,ax
  2352.     mov ah,'E'        ; And send an error packet.
  2353.     call spack
  2354.      ret            ; Return if succeed or fail.
  2355.     nop
  2356.     nop
  2357.     ret
  2358. ERRPACK    ENDP
  2359.  
  2360. ;       Get the chars from the file.
  2361.  
  2362. gtchr:  mov ch,squote           ; Keep quote char in c.
  2363.         mov ah,filflg           ; Get the file flag.
  2364.         cmp ah,0                        ; Is there anything in the DMA?
  2365.         jz gtchr0               ; Yup, proceed.
  2366.         mov cl,0                ; No chars yet.
  2367.         call inbuf
  2368.          jmp gtceof             ; No more chars, go return EOF.
  2369. gtchr0: mov al,spsiz            ; Get the maximum packet size.
  2370.         sub al,5                ; Subtract the overhead.
  2371.         mov ah,0
  2372.         mov temp1,ax            ; Number of chars we're to get.
  2373.         mov bx,offset filbuf            ; Where to put the data.
  2374.         mov cbfptr,bx           ; Remember where we are.
  2375.         mov cl,0                ; No chars.
  2376. gtchr1: dec temp1               ; Decrement the number of chars left.
  2377.         jns gtchr2              ; Go on if there is more than one left.
  2378.         mov al,cl                       ; Return the count in A.
  2379.     mov ah,0
  2380.         jmp rskp
  2381. gtchr2: mov ax,chrcnt
  2382.         dec ax
  2383.         jl gtchr3
  2384.         mov chrcnt,ax
  2385.         jmp gtchr4
  2386. gtchr3: call inbuf              ; Get another buffer full.
  2387.          jmp gtceof
  2388.     cmp chrcnt,0
  2389.     jne gtchr4
  2390.     sub cl,2        ; Don't count controllified Z.
  2391.     mov al,cl
  2392.     mov ah,0
  2393.     jmp rskp
  2394. gtchr4: mov bx,bufpnt           ; Position in DMA.
  2395.         mov ah,[bx]                     ; Get a char from the file.
  2396.         inc bx
  2397.         mov bufpnt,bx
  2398.         mov dh,ah               ; Save the char.
  2399.         and ah,80H                      ; Turn off all but parity.
  2400.         mov dl,ah               ; Save the parity bit.
  2401.         mov ah,dh                       ; Restore the char.
  2402.         and ah,7FH                      ; Turn off the parity.
  2403.         cmp ah,' '                      ; Compare to a space.
  2404.         jl gtchr5               ; If less then its a control char, handle it.
  2405.         cmp ah,del                      ; Is the char a delete?
  2406.         jz gtchr5               ; Go quote it.
  2407.         cmp ah,ch               ; Is it the quote char?
  2408.         jne gtchr8              ; If not proceed.
  2409.         dec temp1               ; Decrement the char total remaining.
  2410.         mov bx,cbfptr           ; Position in character buffer.
  2411.         mov [bx],ah                     ; Put the char in the buffer.
  2412.         inc bx
  2413.         mov cbfptr,bx
  2414.         inc cl                  ; Increment the char count.
  2415.         jmp gtchr8
  2416. gtchr5: or ah,dl                ; Turn on the parity bit.
  2417.         cmp ah,('Z'-100O)               ; Is it a ^Z?
  2418.         jne gtchr7              ; If not just proceed.
  2419.         mov ah,eoflag           ; EOF flag set?
  2420.         cmp ah,0
  2421.         jz gtchr6               ; If not just go on.
  2422.         mov bx,bufpnt
  2423.         mov ax,chrcnt
  2424.         mov dh,al               ; Get number of chars left in DMA.
  2425. gtch51: dec dh
  2426.         mov ah,dh
  2427.         jns gtch52              ; Any chars left?
  2428.         mov chrcnt,0            ; If not, say so.
  2429.         mov al,cl                       ; Return the count in A.
  2430.     mov ah,0
  2431.         jmp rskp
  2432. gtch52: mov ah,[bx]                     ; Get the next char.
  2433.         inc bx                  ; Move the pointer.
  2434.         cmp ah,('Z'-100O)               ; Is it a ^Z?
  2435.         jz gtch51               ; If so see if they rest are.
  2436.  
  2437. gtchr6: mov ah,('Z'-100O)       ; Restore the ^Z.
  2438. gtchr7: xchg ah,al
  2439.         mov ah,0
  2440.         mov temp2,ax            ; Save the char.
  2441.         dec temp1               ; Decrement char counter.
  2442.         mov bx,cbfptr           ; Position in character buffer.
  2443.         mov [bx],ch                     ; Put the quote in the buffer.
  2444.         inc bx
  2445.         mov cbfptr,bx
  2446.         inc cl                  ; Increment the char count.
  2447.         mov ax,temp2            ; Get the control char back.
  2448.         xchg al,ah
  2449.         add ah,40H                      ; Make the non-control.
  2450.         and ah,7fH                      ; Modulo 200 octal.
  2451. gtchr8: mov bx,cbfptr           ; Position in character buffer.
  2452.         or ah,dl                ; Or in the parity bit.
  2453.         mov [bx],ah                     ; Put the char in the buffer.
  2454.         inc bx
  2455.         mov cbfptr,bx
  2456.         inc cl                  ; Increment the char count.
  2457.         jmp gtchr1              ; Go around again.
  2458.  
  2459. gtceof: cmp cl,0        ; Had we gotten any data?
  2460.     je gteof0        ; Nope.
  2461.     mov al,cl
  2462.     mov ah,0
  2463.     jmp rskp
  2464. gteof0: mov ah,0FFH             ; Get a minus one.
  2465.         ret
  2466.  
  2467.  
  2468. inbuf:  mov ah,eoflag           ; Have we reached the end?
  2469.         cmp ah,0
  2470.         jz inbuf0
  2471.         ret                     ; Return if set.
  2472. inbuf0: push bx                 
  2473.     push cx
  2474.     mov bx,offset buff      ; Set the r/w buffer pointer.
  2475.         mov bufpnt,bx
  2476.         mov ah,readf            ; Read a record.
  2477.         mov dx,offset fcb
  2478.         int dos
  2479.     mov cx,filsiz
  2480.     cmp cx,0        ; Check for 128 chars or less left.
  2481.     jne inbuf1        ; Still have data left.
  2482.     mov ax,ds
  2483.     mov es,ax
  2484.     mov si,offset filsiz+2
  2485.     mov di,offset bufhex
  2486.     cmps filsiz+2,es:bufhex
  2487.     ja inbuf1        ; More than 128 chars.
  2488.     mov eoflag,0FFH        ; Set End-of-file.
  2489.     mov cx,filsiz+2
  2490.     mov chrcnt,cx        ; Return proper number of chars.
  2491.         mov filflg,0        ; Buffer not empty.
  2492.     pop cx
  2493.     pop bx
  2494.     jmp rskp
  2495. inbuf1:    sub filsiz+2,80H    ; Sent another 128 chars.
  2496.     sbb filsiz,0        ; Account for the doubleword.
  2497.     mov al,80H        ; Use as counter for number of chars read.
  2498.     pop cx
  2499.     pop bx
  2500.     cmp filflg,0        ; Ever used DMS?
  2501.     jnz inbf21        ; Nope, then don't change count.
  2502.     dec al            ; Fix boundary error.
  2503. inbf21: mov ah,0                ; Zero the flag (buffer not empty).
  2504.     mov chrcnt,ax        ; Number of chars read from file.
  2505.         mov filflg,0        ; Buffer not empty.
  2506.     jmp rskp
  2507.  
  2508. getfil: mov ah,0FFH
  2509.         mov filflg,ah           ; Nothing in the DMA.
  2510.         mov ax,0
  2511.         mov eoflag,ah           ; Not the end of file.
  2512.         mov bx,offset fcb+0CH
  2513.         mov [bx],ax             ; Zero the current block number.
  2514.         mov bx,offset fcb+0EH
  2515.         mov [bx],ax             ; Ditto for Lrecl.
  2516.         mov bx,offset fcb+20H
  2517.         mov [bx],ah             ; Zero the current record (of block).
  2518.     inc bx
  2519.     mov [bx],ax        ; Same for record (of file). 
  2520.     mov bx,offset fcb+23H
  2521.     mov [bx],ax
  2522.         mov ah,openf            ; Open the file.
  2523.         mov dx,offset fcb
  2524.         int dos
  2525.     mov bx,offset fcb+18    ; File size in bytes (hi order word).
  2526.     mov di,offset filsiz    ; Where to put the info. 
  2527.     mov ax,[bx]
  2528.     mov [di],ax
  2529.     mov bx,offset fcb+16    ; Lo order word.
  2530.     mov ax,[bx]
  2531.     mov 2[di],ax
  2532.     sub filsiz+2,1        ; Don't count the ^Z.
  2533.     sbb filsiz,0
  2534.         jmp rskp
  2535.  
  2536.  
  2537. gtnfil: cmp cxzflg,'Z'        ; Did we have a ^Z? [20b]
  2538.     je gtn5            ; If yes, we're done sending files. [20b]
  2539.     cmp wldflg,0        ; Was there a "*"?        [7 start]
  2540.     je gtn5            ; Nope.
  2541.     mov bx,offset cpfcb    ; Get FCB from last check for file.  
  2542.     mov di,offset fcb    ; Copy to FCB.
  2543.     mov cl,37        ; Size of FCB.
  2544.     call fcbcpy
  2545. gtn2:    mov ah,snext
  2546.     mov dx,offset fcb    ; More files?
  2547.     int dos
  2548.     cmp al,0FFH
  2549.     je gtn5
  2550.     mov bx,offset fcb
  2551.     mov di,offset cpfcb
  2552.     mov cl,37
  2553.     call fcbcpy        ; Copy from FCB.
  2554.     mov di,offset fcb+1    ; Get name of next file to send.
  2555.     mov bx,offset buff+1
  2556.     mov cl,11
  2557.     call fcbcpy
  2558.     call getfil        ; Initialize
  2559.      jmp r
  2560.     jmp rskp            
  2561. gtn5:    mov wldflg,0        ; Reset wild card flag.
  2562.     ret                         ;  [7 end]
  2563.  
  2564.  
  2565. ;       Get the file name (including host to micro translation)
  2566.  
  2567. gofil:  mov bx,offset data      ; Get the address of the file name.
  2568.         mov datptr,bx           ; Store the address.
  2569.         mov bx,offset fcb+1            ; Address of the FCB.
  2570.         mov fcbptr,bx           ; Save it.
  2571.         mov ax,0
  2572.         mov temp1,ax            ; Initialize the char count.
  2573.         mov temp2,ax
  2574.     mov si,offset fcb
  2575.         mov [si],ah             ; Set the drive to default to current.
  2576.         mov ch,' '
  2577. gofil1: mov [bx],ch                     ; Blank the FCB.
  2578.         inc bx
  2579.         inc ah
  2580.         cmp ah,0BH                      ; Twelve?
  2581.         jl gofil1
  2582. gofil2: mov bx,datptr           ; Get the NAME field.
  2583.         mov ah,[bx]
  2584.         inc bx
  2585.         mov datptr,bx
  2586.         cmp ah,'.'                      ; Seperator?
  2587.         jne gofil3
  2588.         mov bx,offset fcb+9H
  2589.         mov fcbptr,bx
  2590.         mov ax,temp1
  2591.         mov temp2,ax
  2592.         mov temp1,9H
  2593.         jmp gofil6
  2594. gofil3: cmp ah,0                        ; Trailing null?
  2595.         jz gofil7               ; Then we're done.
  2596.         mov bx,fcbptr
  2597.         mov [bx],ah
  2598.         inc bx
  2599.         mov fcbptr,bx
  2600.         mov ax,temp1            ; Get the char count.
  2601.         inc ax
  2602.         mov temp1,ax
  2603.         cmp ax,8H                       ; Are we finished with this field?
  2604.         jl gofil2
  2605. gofil4: mov temp2,ax
  2606.         mov bx,datptr
  2607.         mov ah,[bx]
  2608.         inc bx
  2609.         mov datptr,bx
  2610.         cmp ah,0
  2611.         jz gofil7
  2612.         cmp ah,'.'                      ; Is this the terminator?
  2613.         jne gofil4              ; Go until we find it.
  2614. gofil6: mov bx,datptr           ; Get the TYPE field.
  2615.         mov ah,[bx]
  2616.         inc bx
  2617.         mov datptr,bx
  2618.         cmp ah,0                        ; Trailing null?
  2619.         jz gofil7               ; Then we're done.
  2620.         mov bx,fcbptr
  2621.         mov [bx],ah
  2622.         inc bx
  2623.         mov fcbptr,bx
  2624.         inc temp1               ; Increment char count.
  2625.         cmp temp1,0CH                   ; Are we finished with this field?
  2626.         jl gofil6
  2627. gofil7: mov bx,datptr
  2628.     mov ah,'$'
  2629.         mov [bx],ah             ; Put in a dollar sign for printing.
  2630.     call clrfln
  2631.         mov ah,prstr            ; Print the file name.
  2632.         mov dx,offset data
  2633.         int dos
  2634.         mov ah,flwflg           ; Is file warning on?
  2635.         cmp ah,0
  2636.     jnz gf7x
  2637.         jmp gofil9              ; If not, just proceed.
  2638. gf7x:   mov ah,openf            ; See if the file exists.
  2639.         mov dx,offset fcb
  2640.         int dos
  2641.         cmp al,0FFH             ; Does it exist?
  2642.     jnz gf8x
  2643.         jmp gofil9               ; If not create it.
  2644. gf8x:    
  2645. IF ibmpc OR L610
  2646.     mov ah,2        ; Position cursor.
  2647.     mov dx,scrfr
  2648.     mov bh,0
  2649.     int bios
  2650. ENDIF
  2651. IF Z100
  2652.     mov ah,prstr        ; Get print string function
  2653.     mov dx,offset scrfr    ; and string to move cursor
  2654.     int dos            ; Print the string
  2655. ENDIF
  2656.         mov ah,prstr            ; Inform the user we are renaming the file.
  2657.         mov dx,offset infms5
  2658.         int dos
  2659.         mov ax,temp2            ; Get the number of chars in the file name.
  2660.         cmp ax,0
  2661.         jne gofil8
  2662.         mov ax,temp1
  2663.         mov temp2,ax
  2664. gofil8: mov ch,0
  2665.         mov cl,al
  2666.     mov al,0            ; Says if first field is full.
  2667.         cmp cl,9H                       ; Is the first field full?
  2668.         jne gofl81
  2669.         mov al,0FFH             ; Set a flag saying so.
  2670.         dec cl
  2671. gofl81: mov bx,offset fcb              ; Get the FCB.
  2672.         add bx,cx               ; Add in the character number.
  2673.     mov ah,'&'
  2674.         mov [bx],ah             ; Replace the char with an ampersand.
  2675.     push ax
  2676.         push bx
  2677.         mov ah,openf            ; See if the file exists.
  2678.         mov dx,offset fcb
  2679.         int dos
  2680.         pop bx
  2681.         cmp al,0FFH             ; Does it exist?
  2682.     pop ax
  2683.         jz gofl89               ; If not create it.
  2684.         cmp al,0                      ; Get the flag.
  2685.         jz gofl83
  2686.         dec cl                  ; Decrement the number of chars.
  2687.         cmp cl,0
  2688.         jz gofl88               ; If no more, die.
  2689.         jmp gofl81
  2690. gofl83: inc cl                  ; Increment the number of chars.
  2691.         cmp cl,9H                       ; Are we to the end?
  2692.         jl gofl81               ; If not try again ; else fail. 
  2693.  
  2694. gofl88: call erpos        ; Position cursor.
  2695.     mov ah,prstr            ; Tell the user that we can't rename it.
  2696.         mov dx,offset ermes4
  2697.         int dos
  2698.     mov bx,dx        ; Tell host can't rename.  [20f]
  2699.     call errpack        ; Send error packet before abort. [20f]
  2700.         ret
  2701.  
  2702. gofl89: mov bx,offset fcb+0CH          ; Point past the end of the file name.
  2703.         mov dh,[bx]                     ; Save the present contents.
  2704.     mov ah,'$'
  2705.         mov [bx],ah             ; Put in a dollar sign.
  2706.         push dx
  2707.         mov ah,prstr            ; Print the file name.
  2708.         mov dx,offset fcb+1
  2709.         int dos
  2710.         pop dx
  2711.         mov bx,offset fcb+0CH          ; Restore over the dollar sign.
  2712.         mov [bx],dh
  2713. gofil9: mov ah,delf             ; Delete the file if it exists.
  2714.         mov dx,offset fcb
  2715.         int dos
  2716.         mov ax,0
  2717.         mov si,offset fcb+0CH
  2718.         mov [si],ax             ; Zero current block.
  2719.         mov si,offset fcb+0EH
  2720.         mov [si],ax             ; Same for Lrecl.
  2721.         mov si,offset fcb+20H
  2722.         mov [si],ah             ; Zero the current record (within block).
  2723.     inc si
  2724.     mov [si],ax        ; Zero record (within file).
  2725.     mov si,offset fcb+23H
  2726.     mov [si],ax
  2727.         mov ah,makef            ; Now create it.
  2728.         mov dx,offset fcb
  2729.         int dos
  2730.         cmp al,0FFH             ; Is the disk full?
  2731.     je gf9x
  2732.         jmp rskp
  2733. gf9x:   call erpos        ; Position cursor.
  2734.     mov ah,prstr            ; If so tell the user.
  2735.         mov dx,offset erms11
  2736.         int dos
  2737.         ret
  2738.  
  2739. FILEIO    ENDP
  2740.  
  2741.  
  2742. ;       Packet routines
  2743.  
  2744. ; Send_Packet
  2745. ; This routine assembles a packet from the arguments given and sends it
  2746. ; to the host.
  2747. ;
  2748. ; Expects the following:
  2749. ;       AH     - Type of packet (D,Y,N,S,R,E,F,Z,T)
  2750. ;       ARGBLK - Packet sequence number
  2751. ;       ARGBK1 - Number of data characters
  2752. ; Returns: +1 always
  2753.  
  2754. SPKT    PROC    NEAR
  2755.  
  2756. spack:     push ax                 ; Save the packet type.
  2757. IF ibmpc
  2758.     call clrbuf        ; Clear the input buffer. [20e]
  2759. ENDIF
  2760.         mov bx,offset packet    ; Get address of the send packet.
  2761.         mov ah,soh              ; Get the start of header char.
  2762.         mov [bx],ah             ; Put in the packet.
  2763.         inc bx                  ; Point to next char.
  2764.         mov ax,argbk1           ; Get the number of data chars.
  2765.     xchg ah,al
  2766.         add ah,' '+3            ; Real packet character count made printable.
  2767.         mov [bx],ah             ; Put in the packet.
  2768.         inc bx                  ; Point to next char.
  2769.         mov cl,ah               ; Start the checksum.
  2770.         mov ax,argblk           ; Get the packet number.
  2771.     xchg ah,al
  2772.         add ah,' '              ; Add a space so the number is printable.
  2773.         mov [bx],ah             ; Put in the packet.
  2774.         inc bx                  ; Point to next char.
  2775.         add cl,ah               ; Add the packet number to the checksum.
  2776.         pop ax                  ; Get the packet type.
  2777.         mov [bx],ah             ; Put in the packet.
  2778.         inc bx                  ; Point to next char.
  2779.         add cl,ah               ; Add the type to the checksum.
  2780.         mov dx,argbk1           ; Get the packet size.
  2781. spack2: cmp dx,0                ; Are there any chars of data?
  2782.          jz spack3              ;  No, finish up.
  2783.         dec dx                  ; Decrement the char count.
  2784.         mov ah,[bx]             ; Get the next char.
  2785.         inc bx                  ; Point to next char.
  2786.         add cl,ah               ; Add the char to the checksum.
  2787.     cmp ah,0
  2788.     jns spack2
  2789.     mov hierr,0FFH        ; set err flag. 
  2790.         jmp spack2              ; Go try again.
  2791. spack3: cmp hierr,0
  2792.     je sp3x            ; Nothing special to do.
  2793.     call biterr
  2794.     mov hierr,0        ; Reset.
  2795. sp3x:    mov ah,cl               ; Get the character total.
  2796.     mov ch,cl        ; Save here too (need 'cl' for shift).
  2797.         and ah,0C0H             ; Turn off all but the two high order bits.
  2798.     mov cl,6
  2799.         shr ah,cl               ; Shift them into the low order position.
  2800.     mov cl,ch
  2801.         add ah,cl               ; Add it to the old bits.
  2802.         and ah,3FH              ; Turn off the two high order bits.  (MOD 64)
  2803.         add ah,' '              ; Add a space so the number is printable.
  2804.         mov [bx],ah             ; Put in the packet.
  2805.         inc bx                  ; Point to next char.
  2806.         mov ah,seol             ; Get the EOL the other host wants.
  2807.         mov [bx],ah             ; Put in the packet.
  2808.         inc bx                  ; Point to next char.
  2809.         mov ah,0                ; Get a null.
  2810.         mov [bx],ah             ; Put in the packet.
  2811.     cmp debug,0        ; debug mode.
  2812.     je spack4
  2813.     inc bx
  2814.     mov ah,'$'
  2815.     mov [bx],ah
  2816. IF ibmpc OR L610    
  2817.     mov ah,2
  2818.     mov dx,scrsp
  2819.     mov bh,0
  2820.     int bios
  2821. ENDIF
  2822. IF Z100
  2823.     mov ah,prstr        ; Get print string function
  2824.     mov dx,offset scrsp    ; and string to move cursor
  2825.     int dos            ; Print the string
  2826. ENDIF
  2827.     mov ah,prstr
  2828.     mov dx,offset spmes
  2829.     int dos
  2830.     mov dx,offset packet
  2831.     mov ah,prstr
  2832.     int dos            ; debug end.
  2833. spack4: call outpkt             ; Call the system dependent routine.
  2834.      jmp r
  2835.     jmp rskp
  2836.  
  2837. SPKT    ENDP 
  2838. ;       Write out a packet.
  2839.  
  2840. OUTPKT  PROC    NEAR
  2841.         mov dh,spad             ; Get the number of padding chars.
  2842. outpk2: dec dh
  2843.         cmp dh,0
  2844.         jl outpk3               ; If none left proceed.
  2845.         mov ah,spadch           ; Get the padding char.
  2846.         call outchr             ; Output it.
  2847.         jmp outpk2
  2848. outpk3: mov bx,offset packet    ; Point to the packet.
  2849. outlup: mov ah,[bx]             ; Get the next character.
  2850.         cmp ah,0                ; Is it a null?
  2851.         jnz outlp2
  2852.         jmp rskp
  2853. outlp2: call outchr             ; Output the character.
  2854.      jmp r
  2855.       cmp    l6flg,0            ; going to a L6
  2856.      jz    outlp3            ; no
  2857.      mov    ah,[bx]            ; get char back
  2858.      cmp    ah,'\'            ; L6 eats \ unless gets 2
  2859.      jnz    outlp3
  2860.      call outchr            ; send 2nd one
  2861.       jmp  r             ; incase of failure
  2862. outlp3:
  2863.      inc bx                  ; Increment the char pointer.
  2864.       jmp outlup
  2865. OUTPKT  ENDP
  2866.  
  2867.  
  2868. ;************************System Dependent****************************
  2869. ;       Put a char in AH to the port.
  2870. PORT    PROC  NEAR 
  2871. IF ibmpc
  2872. outchr:    sub cx,cx        ; [14 start]
  2873.     mov al,ah        ; Parity routine works on AL. [16]
  2874.     call dopar        ; Set parity appropriately.     [10]
  2875.     mov ah,al        ; Don't overwrite character with status. [16]
  2876.     mov dx,mdstat        ; Get port status. [19b]
  2877. outch1:    in al,dx
  2878.     test al,20H        ; Transmitter ready?
  2879.     jnz outch2        ; Yes
  2880.     loop outch1
  2881.      jmp r            ; Timeout
  2882. outch2:    mov al,ah        ; Now send it out
  2883.     mov dx,mddat        ; [19b]
  2884.     out dx,al
  2885.     jmp rskp        ; [14 end]
  2886. ENDIF
  2887. IF Z100
  2888. outchr:    mov al,ah        ; Yes, get the character into al
  2889.     mov cx,0
  2890.     call dopar        ; Set parity appropriately.   [10]
  2891. outch1:    call bios_auxout    ; Send the character
  2892.     jmp rskp
  2893. ENDIF
  2894. IF L610                        ;[21]
  2895. outchr:    sub    cx,cx
  2896.         mov    al,ah    ; Get into al
  2897.         call    dopar    ; Set parity of your choice
  2898. outch1:    mov    ah,SEND_BYTE
  2899.         mov    dx,AUXPORT
  2900.         int    COMM
  2901.         and    ah,80H    ; Transmit ok?
  2902.         jz    outch2    ; Yep
  2903.         loop    outch1
  2904.          jmp    r        ; Timeout
  2905. outch2:    
  2906.         jmp    rskp    
  2907. ENDIF
  2908.  
  2909. ;************************System Dependent****************************
  2910. ;
  2911. ;       Get a char from the port and return in AH.
  2912.  
  2913. inchr:  
  2914. IF ibmpc
  2915.     call prtchr        ; Get character if ready.  [14]
  2916.      jmp inchr3        ; Got it in AL.  [14]
  2917. ENDIF
  2918. IF Z100
  2919.      push    bx        ; Save BX
  2920.     mov ah,chr_status    ; Get the function
  2921.     mov al,chr_sfgs        ; And the subfunction
  2922.     call bios_auxfunc    ; Determine if anything to input
  2923.     cmp bl,0        ; Is there?
  2924.     jnz inchr3        ; Yes, go get it
  2925.     pop bx            ; And restore BX
  2926. ENDIF
  2927. IF L610                    ; [21]
  2928.     mov    ah,PORT_STAT        ; is one here
  2929.     mov    dx,AUXPORT
  2930.     int    COMM
  2931.     and    ah,01H
  2932.     jnz    inchr3            ; Yes go get it
  2933. ENDIF
  2934.  
  2935.         mov ah,constat          ; Is a char on the console?
  2936.         int dos
  2937.         cmp al,0
  2938.         jz inchr                ; If not go look for another char.
  2939.         mov ah,conin            ; Get the char.
  2940.         int dos
  2941.     mov ah,al 
  2942.         cmp ah,cr                       ; Is it a carriage return?
  2943.         je inchr4               ; If yes, then leave.
  2944.     cmp ah,'Z'-100O        ; Control-Z? [20b]
  2945.     je inchr2        ; Yes - flag it. [20b]
  2946.     cmp ah,'X'-100O        ; Control-X? [20b]
  2947.     je inchr2        ; Yes - flag it. [20b]
  2948.     jmp inchr        ; Wait for some kind of input.
  2949. inchr2: add ah,100O        ; Make it printable. [20b]
  2950.     mov cxzflg,ah        ; Remember what we saw. [20b]
  2951.     jmp inchr        ; Continue getting input. [20b]
  2952. inchr4:    ret
  2953. inchr3: 
  2954. IF Z100
  2955.     mov ah,chr_read        ; Get the function to read
  2956.     call bios_auxfunc    ; Get a character
  2957.     pop bx            ; Restore BX
  2958. ENDIF
  2959. IF L610                ;[21]
  2960.     mov    ah,READ_BYTE
  2961.     mov    dx,AUXPORT
  2962.     int    COMM
  2963. ENDIF
  2964.     mov ah,al
  2965.     cmp parflg,parnon    ; Is the parity none?   [10]
  2966.     je inchr5        ; We're done.        [10]
  2967.     and ah,7FH                      ; Turn off the parity bit.
  2968. inchr5: jmp rskp
  2969.  
  2970. ; Set parity for character in Register AL.
  2971.  
  2972. dopar:
  2973. IF L610
  2974.     ret                ; L610 will set parity 
  2975. ENDIF
  2976.     cmp parflg,parnon    ; No parity?            [10 start]
  2977.     je parret        ; Just return
  2978.     cmp parflg,parevn    ; Even parity?
  2979.     jne dopar0
  2980.     and al,07FH        ; Strip parity.
  2981.     jpe parret        ; Already even, leave it.
  2982.     or al,080H        ; Make it even parity.
  2983.     jmp parret
  2984. dopar0:    cmp parflg,parmrk    ; Mark parity?
  2985.     jne dopar1
  2986.     or al,080H        ; Turn on the parity bit.
  2987.     jmp parret
  2988. dopar1:    cmp parflg,parodd    ; Odd parity?    
  2989.     jne dopar2
  2990.     and al,07FH        ; Strip parity.
  2991.     jpo parret        ; Already odd, leave it.
  2992.     or al,080H        ; Make it odd parity.
  2993.     jmp parret
  2994. dopar2: and al,07FH        ; Space parity - turn off parity bit.
  2995. parret: ret                            ; [10 end]
  2996. PORT    ENDP
  2997.  
  2998. ; Clear the input buffer before sending a packet. [20e]
  2999. IF ibmpc
  3000. CLRBUF    PROC    NEAR
  3001.     lea ax,cs:source    ; Initialize the pointers
  3002.     mov cs:srcpnt,ax
  3003.     mov cs:savesi,ax
  3004.     mov cs:count,0
  3005.     mov di,cs:srcpnt    ; Where to store bytes
  3006.     mov ax,cs        ; Ready ES for string operations
  3007.     mov es,ax
  3008.     mov si,0        ; Where to fetch bytes
  3009.     ret
  3010. CLRBUF    ENDP
  3011. ENDIF
  3012.  
  3013. ; Receive_Packet
  3014. ; This routine waits for a packet arrive from the host.  It reads
  3015. ; chars until it finds a SOH.
  3016.  
  3017. RPACK    PROC    NEAR
  3018. IF ibmpc OR L610
  3019.     mov ah,2
  3020.     mov dx,scrst        ; Position cursor.
  3021.     mov bh,0
  3022.     int bios
  3023. ENDIF
  3024. IF Z100
  3025.     mov ah,prstr        ; Get the function to print string
  3026.     mov dx,offset scrst    ; Get the string address
  3027.     int dos            ; Position the cursor
  3028. ENDIF
  3029.     mov ah,prstr
  3030.     mov dx,offset infms0
  3031.         int dos
  3032. rpack5: call inpkt              ; Read up to a carriage return.
  3033.          jmp r                  ;  Return bad.
  3034. rpack0: call getchr             ; Get a character.
  3035.          jmp r                  ;  Hit the carriage return, return bad.
  3036.         cmp ah,soh              ; Is the char the start of header char?
  3037.          jne rpack0             ;  No, go until it is.
  3038. rpack1: call getchr             ; Get a character.
  3039.          jmp r                  ;  Hit the carriage return, return bad.
  3040.         cmp ah,soh              ; Is the char the start of header char?
  3041.          jz rpack1              ;  Yes, then go start over.
  3042.         mov cl,ah               ; Start the checksum.
  3043.         sub ah,' '+3            ; Get the real data count.
  3044.         mov dh,ah               ; Save it for later.
  3045.         mov al,ah               ; Swap halves.
  3046.         mov ah,0
  3047.         mov argbk1,ax           ; Save the data count.
  3048.         call getchr             ; Get a character.
  3049.          jmp r                  ;  Hit the carriage return, return bad.
  3050.         cmp ah,soh              ; Is the char the start of header char?
  3051.          jz rpack1              ;  Yes, then go start over.
  3052.         add cl,ah               ; Add it to the checksum.
  3053.         sub ah,' '              ; Get the real packet number.
  3054.         mov al,ah               ; Swap halves.
  3055.         mov ah,0
  3056.         mov argblk,ax           ; Save the packet number.
  3057.         call getchr             ; Get a character.
  3058.          jmp r                  ;  Hit the carriage return, return bad.
  3059.         cmp ah,soh              ; Is the char the start of header char?
  3060.          jz rpack1              ;  Yes, then go start over.
  3061.         mov temp,ax             ; Save the message type. [11]
  3062.         add cl,ah               ; Add it to the checksum.
  3063.         mov bx,offset data      ; Point to the data buffer.
  3064. rpack2: dec dh                  ; Any data characters?
  3065.          js rpack3              ;  If not go get the checksum.
  3066.         call getchr             ; Get a character.
  3067.          jmp r                  ;  Hit the carriage return, return bad.
  3068.         cmp ah,soh              ; Is the char the start of header char?
  3069.          jz rpack1              ;  Yes, then go start over.
  3070.         mov [bx],ah             ; Put the char into the packet.
  3071.         inc bx                  ; Point to the next character.
  3072.         add cl,ah               ; Add it to the checksum.
  3073.         jmp rpack2              ; Go get another.
  3074. rpack3: call getchr             ; Get a character.
  3075.          jmp r                  ;  Hit the carriage return, return bad.
  3076.         cmp ah,soh              ; Is the char the start of header char?
  3077.          jz rpack1              ;  Yes, then go start over.
  3078.         sub ah,' '              ; Turn the char back into a number.
  3079.         mov dh,cl               ; Get the character total.
  3080.         and dh,0C0H             ; Turn off all but the two high order bits.
  3081.     mov ch,cl
  3082.     mov cl,6
  3083.         shr dh,cl               ; Shift them into the low order position.
  3084.     mov cl,ch
  3085.         add dh,cl               ; Add it to the old bits.
  3086.         and dh,3FH              ; Turn off the two high order bits.  (MOD 64)
  3087.         cmp dh,ah               ; Are they equal?
  3088.          jz rpack4              ;  If so finish up.
  3089.         ret
  3090. rpack4: mov ah,0
  3091.         mov [bx],ah             ; Put a null at the end of the data.
  3092.         mov ax,temp             ; Get the type.   [11]
  3093.         jmp rskp
  3094. RPACK   ENDP
  3095.  
  3096.  
  3097. INPKT   PROC    NEAR
  3098.     mov bl,cxzflg        ; Remember original value. [20b]
  3099.     mov tmp,bl        ; Store it here. [20b]
  3100.         mov bx,offset recpkt    ; Point to the beginning of the packet.
  3101.     mov incnt,0
  3102. inpkt2: call inchr              ; Get a character.
  3103.          jmp inpkt0            ;  Return failure. [20b]
  3104.      nop            ;  Make it three bytes long. [20b] 
  3105.         mov [bx],ah             ; Put the char in the packet.
  3106.         inc bx
  3107.     inc incnt
  3108.         cmp ah,reol             ; Is it the EOL char?
  3109.         jne inpkt2              ; If not loop for another.
  3110.     cmp incnt,1        ; Ignore bare CR.   [2 start]
  3111.     jne inpkt6
  3112.     mov incnt,0
  3113.     mov bx,offset recpkt
  3114.     jmp inpkt2        ;                   [2 end]
  3115. inpkt6:    cmp ibmflg,0            ; Is this the (dumb) IBM mainframe?
  3116.         jz inpkt4               ; If not then proceed.
  3117. inpkt5: cmp state,'S'           ; Check if this is the Send-Init packet.
  3118.         jz inpkt4               ; If so don't wait for the XON.
  3119. inpkt3: call inchr              ; Wait for the turn around char.
  3120.          jmp inpkt0            ;  Return failure. [20b]
  3121.      nop            ;  Make it three bytes long.  [20b]
  3122.         cmp ah,xon              ; Is it the IBM turn around character?
  3123.         jne inpkt3              ; If not, go until it is.
  3124. inpkt4: mov bx,offset recpkt
  3125.         mov pktptr,bx           ; Save the packet pointer.
  3126.     mov bl,tmp        ; Get the original value. [20b]
  3127.     cmp bl,cxzflg        ; Did ^X/^Z flag change? [20b]
  3128.     je inpkx        ; If not, just return.  [20b]
  3129.     call intmsg         ; Else, say we saw the interrupt. [20b]
  3130. inpkx:  jmp rskp                ; If so we are done.
  3131. inpkt0:    mov bl,tmp        ; Get the original value. [20b]
  3132.     cmp bl,cxzflg        ; Did ^X/^Z flag change? [20b]
  3133.     je inpky        ; If not, just return failure.  [20b]
  3134.     call intmsg         ; Else, say we saw the interrupt. [20b]
  3135. inpky:    jmp r
  3136. INPKT   ENDP
  3137.  
  3138. GETCHR  PROC    NEAR
  3139.         push bx
  3140.         mov bx,pktptr           ; Get the packet pointer.
  3141.         mov ah,[bx]             ; Get the char.
  3142.         inc bx
  3143.         mov pktptr,bx
  3144.         pop bx                  ; Restore BX.
  3145.         cmp ah,reol             ; Is it the EOL char?
  3146.         jne getcr2              ; If not return retskp.
  3147.         ret                     ; If so return failure.
  3148. getcr2: jmp rskp
  3149. GETCHR  ENDP
  3150.  
  3151.  
  3152. ; This is where we go if we get an error packet.  A call to ERROR 
  3153. ; positions the cursor and prints the message.  A call to ERROR1
  3154. ; just prints a CRLF and then the message.  [8]
  3155.  
  3156. ERROR   PROC    NEAR
  3157.         mov state,'A'           ; Set the state to abort.
  3158.         call erpos            ; Position the cursor.
  3159.     jmp error2
  3160. error1:    mov ah,prstr
  3161.     mov dx,offset crlf
  3162.     int dos
  3163. error2: mov bx,argbk1           ; Get the length of the data.
  3164.         add bx,offset data      ; Get to the end of the string.
  3165.         mov ah,'$'              ; Put a dollar sign at the end.
  3166.         mov [bx],ah
  3167.         mov ah,prstr            ; Print the error message.
  3168.         mov dx,offset data
  3169.         int dos
  3170.         ret
  3171. ERROR   ENDP
  3172.  
  3173. ; LOGOUT - tell remote KERSRV to logout.
  3174.  
  3175. LOGOUT    PROC    NEAR                        ; [8 start]
  3176.     mov ah,cmcfm
  3177.     call comnd        ; Get a confirm.
  3178.      jmp r
  3179.     call logo
  3180.      jmp rskp        ; Go get another command whether we ....
  3181.     jmp rskp        ; .... succeed or fail.
  3182. LOGOUT    ENDP
  3183.  
  3184. LOGO    PROC    NEAR
  3185.     mov numtry,0        ; Initialize count.
  3186.     call serini        ; Initialize port.  [14]
  3187. logo1:    mov ah,numtry
  3188.     cmp ah,maxtry        ; Too many times?
  3189.     js logo3        ; No, try it.
  3190. logo2:    mov ah,prstr
  3191.     mov dx,offset erms19
  3192.     int dos
  3193.     call serrst        ; Reset port.  [14]
  3194.     ret
  3195. logo3:    inc numtry        ; Increment number of tries.
  3196.     mov argblk,0        ; Packet number zero.
  3197.     mov argbk1,1        ; One piece of data.
  3198.     mov bx,offset data
  3199.     mov ah,'L'
  3200.     mov [bx],ah        ; Logout the remote host.
  3201.     mov ah,'G'        ; Generic command packet.
  3202.     call spack
  3203.      jmp logo2        ; Tell user and die.
  3204.      nop
  3205.     call rpack5        ; Get ACK (w/o screen msgs.)
  3206.      jmp logo1        ; Go try again.
  3207.      nop
  3208.     cmp ah,'Y'        ; ACK?
  3209.     jne logo4
  3210.     call serrst        ; Reset port.  [14]
  3211.     jmp rskp
  3212. logo4:    cmp ah,'E'        ; Error packet?    
  3213.     jnz logo1        ; Try sending the packet again.
  3214.     call error1
  3215.     call serrst        ; Reset port.  [14]
  3216.     ret
  3217. LOGO    ENDP
  3218.  
  3219. ; FINISH - tell remote KERSRV to exit.
  3220.  
  3221. FINISH    PROC    NEAR
  3222.     mov ah,cmcfm        ; Parse a confirm.
  3223.     call comnd
  3224.      jmp r
  3225.     mov numtry,0        ; Initialize count.
  3226.     call serini        ; Initialize port.  [14]
  3227. fin1:    mov ah,numtry
  3228.     cmp ah,maxtry        ; Too many times?
  3229.     js fin3            ; Nope, try it.
  3230. fin2:    mov ah,prstr
  3231.     mov dx,offset erms18
  3232.     int dos
  3233.     call serrst        ; Reset port.  [14]
  3234.     jmp rskp        ; Go home.
  3235. fin3:    inc numtry        ; Increment number of tries.
  3236.     mov argblk,0        ; Packet number zero.
  3237.     mov argbk1,1        ; One piece of data.
  3238.     mov bx,offset data
  3239.     mov ah,'F'
  3240.     mov [bx],ah        ; Finish running Kermit.
  3241.     mov ah,'G'        ; Generic command packet.
  3242.     call spack
  3243.      jmp fin2        ; Tell user and die.
  3244.      nop
  3245.     call rpack5        ; Get ACK (w/o screen stuff).
  3246.      jmp fin1        ; Go try again.
  3247.      nop
  3248.     cmp ah,'Y'        ; Got an ACK?
  3249.     jnz fin4
  3250.     call serrst        ; Reset port. [14]
  3251.     jmp rskp        ; Yes, then we're done.
  3252. fin4:    cmp ah,'E'        ; Error packet?
  3253.     jnz fin1        ; Try sending it again.
  3254.     call error1
  3255.     call serrst        ; Reset port.  [14]
  3256.     jmp rskp
  3257. FINISH    ENDP
  3258.  
  3259. ; BYE command - tell remote KERSRV to logout & exits to DOS.  
  3260.  
  3261. BYE    PROC    NEAR
  3262.     mov ah,cmcfm        ; Parse a confirm.
  3263.     call comnd
  3264.      jmp r
  3265.     call logo        ; Tell the mainframe to logout.
  3266.       jmp rskp        ; Failed - don't exit.
  3267.     mov extflg,1        ; Set exit flag.
  3268.     jmp rskp                    ; [8 end]
  3269. BYE    ENDP
  3270.  
  3271. ; This is the 'exit' command.  It leaves KERMIT and returns to DOS.
  3272.  
  3273. EXIT    PROC    NEAR
  3274.         mov ah,cmcfm
  3275.         call comnd              ; Get a confirm.
  3276.          jmp r
  3277.         mov extflg,1            ;  Set the exit flag.
  3278.         jmp rskp                ; Then return to system.
  3279. EXIT    ENDP
  3280.  
  3281.  
  3282. ; This is the 'help' command.  It gives a list of the commands.
  3283.  
  3284. HELP    PROC    NEAR
  3285.         mov ah,cmcfm
  3286.         call comnd              ; Get a confirm.
  3287.          jmp r
  3288.         mov ah,prstr            ; Print a string to the console.
  3289.         mov dx,offset tophlp    ; The address of the help message.
  3290.         int dos
  3291.         jmp rskp
  3292. HELP    ENDP
  3293.  
  3294. IF ibmpc
  3295. source    db    2048 DUP(?)    ; Buffer for data from port.
  3296. srcpnt    dw    0        ; Pointer in buffer (DI).
  3297. count    dw    0        ; Number of chars in int buffer.
  3298. savesi    dw    0        ; Save SI register here.    
  3299. telflg    db    0        ; Are we acting as a terminal. [16] [17c]
  3300. mst    dw    0        ; Modem status address. [19b]
  3301. mdat    dw    0        ; Modem data address. [19b]
  3302. mdeoi    db    0        ; End-of-Interrupt value. [19b]
  3303. ENDIF
  3304. IF L610                    ; [21]
  3305. telflg    db    0            ; are we acting as a terminal
  3306. ENDIF
  3307. ;       This is the CONNECT command.
  3308.  
  3309. TELNET  PROC    NEAR
  3310.         mov ah,cmcfm
  3311.         call comnd              ; Get a confirm.
  3312.          jmp r                  ;  Didn't get a confirm.
  3313.         mov ah,prstr            ; Output
  3314.         mov dx,offset crlf      ; a crlf.
  3315.         int dos
  3316.     call dobaud        ; Set baud rate. [19a]
  3317.     call domsg        ; Reassure user. [19b]
  3318. IF L610                ; [21]
  3319.     call    serini        ; init serial port
  3320.     mov    cs:telflg,0FFH    ; Turn on Telnet flag
  3321. ENDIF
  3322. IF ibmpc
  3323.     mov ah,3        ; Get cursor position.  [17b start, 20g]
  3324.     mov bh,0
  3325.     int bios
  3326.     cmp dh,24        ; Are we on row 25? [19d]
  3327.     jne nobump        ; Nope, then leave where it is. [19d]
  3328.     dec dh            ; Decrement ROW attribute. (DT)
  3329.     mov ah,2
  3330.     int bios        ; [17b end]
  3331. nobump:    mov cs:telflg,0FFH    ; Turn on Telnet flag.  [16] [17c] [20g]
  3332.     call serini        ; Initialize serial port. [14]
  3333.     xor ax,ax
  3334.     mov cx,ds        ; Save DS in CX.
  3335.     mov ds,ax        ; Use low core.
  3336.     mov bx,6CH        ; "break" interrupt vector.
  3337.     push [bx]
  3338.     mov bx,6EH
  3339.     push [bx]
  3340.     mov bx,6CH
  3341.     mov ax,offset intret
  3342.     mov es,ax
  3343.     mov [bx],es        ; ignore break int's (pt to "iret").
  3344.     mov bx,6EH
  3345.     mov [bx],cs
  3346.     mov ds,cx
  3347.     mov ssp,sp        ; Save SP to make an easy return.
  3348. ENDIF
  3349. IF Z100 OR L610
  3350.     mov ssp,sp        ; Save current stack pointer.
  3351. ENDIF
  3352. telnoe: call plup        ; Char at port (type to console) ?
  3353. IF ibmpc
  3354.     cmp al,ESC
  3355.     jne telx
  3356.     jmp telesc
  3357. ENDIF
  3358. telx:    cmp al,DEL        ; Don't bother with deletes.
  3359.     je telnoe
  3360.     cmp al,XOFF        ; Skip all the following too.
  3361.     je telnoe
  3362.     cmp al,XON    
  3363.     je telnoe
  3364.     cmp al,00H        ; Null.
  3365.     je telnoe
  3366. IF ibmpc
  3367.     cmp al,BELL
  3368.     jne nobell
  3369.     call beep
  3370.     jmp telnoe
  3371. nobell:    cmp al,TAB        ; Tab ? [15]
  3372.     jne notab        ; No, skip the jump [15]
  3373.     call dotab        ; Yes, handle the tab [15]
  3374.     jmp telnoe        ; And get the next character [15]
  3375. notab:    call dotty        ; Use our own TTY I/O.  [17b]
  3376.     jmp telnoe
  3377. ENDIF
  3378. IF Z100 OR L610
  3379.     mov dl,al        ; Get the character
  3380.     mov ah,dconio        ; and the function
  3381.     int dos            ; type the character
  3382.     jmp telnoe        ; Get next character
  3383. ENDIF
  3384. TELNET  ENDP
  3385.  
  3386. ; Reassure user about connection to the host.  Tell him what escape
  3387. ; sequence to use to return and the communications port and baud
  3388. ; rate being used.   [19b] 
  3389.  
  3390. DOMSG    PROC    NEAR
  3391.     mov ah,prstr
  3392.     mov dx,offset tmsg1
  3393.     int dos
  3394.     call escprt
  3395.     mov ah,prstr
  3396.     mov dx,offset tmsg3
  3397.     int dos
  3398.     call baudprt        ; Say what baud rate we're using. [19a]
  3399. IF ibmpc
  3400.     mov ah,prstr
  3401.     mov dx,offset tmsg4
  3402.     int dos
  3403.     mov tmp,'1'        ; Assume COM1.
  3404.     cmp comflg,1
  3405.     je domsg0
  3406.     mov tmp,'2'        ; Nope, we're using COM2.
  3407. domsg0:    mov dx,offset tmp
  3408.     int dos
  3409. ENDIF
  3410.     mov ah,prstr
  3411.     mov tmp,']'
  3412.     mov dx,offset tmp
  3413.     int dos
  3414.     mov dx,offset crlf    ; Output 3 CRLF's.
  3415.     int dos
  3416.     int dos
  3417.     int dos
  3418.     ret
  3419. DOMSG    ENDP
  3420.  
  3421. ; Put character in AL to the screen.  [17b start]
  3422. IF ibmpc 
  3423. DOTTY    PROC NEAR
  3424.     push ax
  3425.     mov ah,3        ;Get cursor
  3426.     mov bh,0
  3427.     int bios
  3428.     pop ax
  3429.     cmp al,8        ;Backspace?
  3430.     je dotty3
  3431.     cmp al,0DH        ;CR?
  3432.     je dotty4
  3433.     cmp al,0AH        ;LF?
  3434.     je dotty5
  3435.     cmp incmod,0        ;I/C?
  3436.     jne dotty7
  3437.     mov ah,9        ;Ordinary character
  3438.     mov bx,curatt
  3439.     mov cx,1
  3440.     int bios
  3441.     mov ah,2
  3442.     mov bh,0
  3443.     inc dl            ;Step cursor
  3444.     cmp dl,80        ;Overflow?
  3445.     jne dotty2
  3446.     ret
  3447. dotty1:    inc dh
  3448. dotty6:    mov ah,2
  3449. dotty2:    int bios
  3450.     ret
  3451. dotty3:    dec dl            ;BS
  3452.     jge dotty6
  3453.     ret
  3454. dotty4:    mov dl,0        ;CR
  3455.     jmp dotty6
  3456. dotty5:    cmp dh,23        ;LF
  3457.     jl dotty1
  3458.     mov ah,8        ;Get attribute of last line
  3459.     int bios
  3460.     mov bh,ah
  3461.     mov ax,0601H        ;Scroll
  3462.     sub cx,cx
  3463.     mov dx,174FH
  3464.     jmp dotty2
  3465. dotty7:    mov temp,ax        ;DK6 Save the character
  3466.     mov temp1,dx        ;Save the cursor
  3467.     mov dl,78        ;Start shift at end of line
  3468.     mov temp2,dx
  3469.     mov ah,1        ;Turn off cursor
  3470.     mov ch,20H
  3471.     int bios
  3472. dotty8:    mov ah,2        ;Position to col M
  3473.     mov bh,0
  3474.     mov dx,temp2
  3475.     int bios
  3476.     mov ah,8        ;Read char/attr
  3477.     int bios
  3478.     mov cx,ax        ;Save it
  3479.     mov ah,2        ;Position to col M+1
  3480.     inc dx
  3481.     int bios
  3482.     mov ah,9        ;Write char/attr
  3483.     mov al,cl
  3484.     mov bl,ch
  3485.     mov cx,1
  3486.     int bios
  3487.     dec dx
  3488.     dec temp2
  3489.     cmp dx,temp1
  3490.     jne dotty8
  3491.     mov ah,2        ;Position
  3492.     mov bh,0
  3493.     int bios
  3494.     mov ax,temp        ;Write the char
  3495.     mov ah,9
  3496.     mov bx,curatt        ;In the current video mode
  3497.     mov cx,1
  3498.     int bios
  3499.     mov ah,2        ;Step to next column
  3500.     inc dl
  3501.     int bios
  3502.     mov ah,1        ;Turn on cursor
  3503.     mov cx,0B0CH
  3504.     int bios
  3505.     ret            ; [17b end]
  3506. DOTTY    ENDP
  3507. ENDIF
  3508.  
  3509. EXTLN    PROC    NEAR
  3510. IF ibmpc
  3511.     call serrst        ; Reset serial port. [14]
  3512.     mov sp,ssp
  3513.     xor bx,bx
  3514.     mov cx,ds        ; Save DS register.
  3515.     mov ds,bx        ; Address low memory.
  3516.     mov bx,6EH
  3517.     pop [bx]
  3518.     mov bx,6CH
  3519.     pop [bx]
  3520. ;    mov bx,mdmintv+2        ; Restore old interrupt vectors.
  3521. ;    pop [bx]
  3522. ;    mov bx,mdmintv
  3523. ;    pop [bx]
  3524.     mov ds,cx        ; Restore DS.
  3525.     xor bx,bx
  3526.     mov cs:telflg,0      ; Not acting as terminal anymore. [16] [17c] [20g]
  3527. ;    sti
  3528. ENDIF
  3529. IF Z100 OR L610
  3530.     mov sp,ssp    
  3531. ENDIF
  3532.     mov ah,prstr
  3533.     mov dx,offset tmsg2
  3534.     int dos
  3535.     jmp rskp
  3536. EXTLN    ENDP
  3537.  
  3538. ;[14 start]       Common initialization for using serial port.
  3539.  
  3540. SERINI    PROC    NEAR
  3541. IF ibmpc
  3542.     cli            ; Disable interrupts
  3543.     cld            ; Do increments in string operations
  3544.     xor ax,ax        ; Address low memory
  3545.     mov es,ax
  3546.     mov bx,mdintv        ; Save serial card interrupt vector. [19b]
  3547.     mov ax,es:[bx]
  3548.     mov savsci,ax
  3549.     mov ax,offset serint    ; And point it to my routine
  3550.     mov es:[bx],ax
  3551.     add bx,2        ; Save CS register too. [19b]
  3552.     mov ax,es:[bx]
  3553.     mov savscs,ax
  3554.     mov es:[bx],cs
  3555.     call clrbuf        ; Clear input buffer. [20e]
  3556.     mov ax,mdstat        ; [19b]
  3557.     mov cs:mst,ax        ; Use this address for status. [19b]
  3558.     mov ax,mddat        ; [19b]
  3559.     mov cs:mdat,ax        ; Use this address for data. [19b]
  3560.     mov al,mdmeoi        ; [19b]
  3561.     mov cs:mdeoi,al        ; Use to signify end-of-interrupt. [19b]
  3562.     in al,21H        ; Set up 8259 interrupt controller
  3563.     and al,mden        ; Enable INT3 or INT4. [19b]
  3564.     out 21H,al
  3565.     mov dx,mdcom        ; Set up the serial card. [19b]
  3566.     mov al,3
  3567.     out dx,al
  3568.     mov dl,0F9H        ; [19b]
  3569.     mov al,1        ; Set up interrupt enable register
  3570.     out dx,al
  3571.     mov dl,0FCH        ; Enable interrupts from serial card
  3572.     mov al,0BH
  3573.     out dx,al
  3574.     sti            ; Allow interrupts
  3575.     mov dl,0F8H
  3576.     in al,dx
  3577. ENDIF
  3578. IF L610                    ; [21]
  3579.     mov    al,parflg        ; get parity flag
  3580.     cmp    al,PAREVN        ; Is even?
  3581.     jnz    serin1        ; nope
  3582.     mov    al,EVENP+BIT7+STOP1 ; even parity , 7 bit char, 1 stop bit
  3583.     jmp    serinc        ; go set comm port
  3584. serin1:
  3585.     cmp    al,PARODD        ; Odd?
  3586.     jnz    serin2
  3587.     mov    al,ODDP+BIT7+STOP1
  3588.     jmp    serinc
  3589. serin2:
  3590.     mov    al,NONEP+BIT8+STOP1
  3591. serinc:
  3592.     or    al,baud    ; put in baud
  3593.     mov    ah,INIT_PORT        ; Initialize comm port
  3594.     mov    dl,AUXPORT
  3595.     int    COMM
  3596. ENDIF
  3597.     ret
  3598. SERINI    ENDP
  3599.  
  3600. SERRST    PROC    NEAR
  3601. IF ibmpc
  3602.     cli            ; Disable interrupts
  3603.     mov dx,03FCH        ; Disable modem interrupts
  3604.     cmp comflg,1        ; Using port 1 ? [19b]
  3605.     je srst0        ; Yes - continue. [19b]
  3606.     mov dh,02        ; Set for port 2. [19b]
  3607. srst0:    mov al,3        ; [new label - 19b]
  3608.     out dx,al
  3609.     in al,21H        ; Interrupt controller
  3610.     or al,mddis        ; Inhibit IRQ3 or IRQ4. [19b]
  3611.     out 21H,al
  3612.     xor bx,bx        ; Address low memory
  3613.     mov es,bx
  3614.     mov bx,mdintv        ; Restore the serial card int vector [19b]
  3615.     mov ax,savsci
  3616.     mov es:[bx],ax
  3617.     add bx,2        ; Restore CS too. [19b]
  3618.     mov ax,savscs
  3619.     mov es:[bx],ax
  3620.     sti
  3621. ENDIF
  3622.     ret
  3623. SERRST    ENDP                    ; [14 end]
  3624.  
  3625. ; *********** serial port interrupt routine ********
  3626.  
  3627. IF ibmpc
  3628. SERINT  PROC  NEAR
  3629.     push dx
  3630.     push ax
  3631.     push es
  3632.     push di
  3633.     cld
  3634.     mov di,cs:srcpnt    ; Registers for storing data.
  3635.     mov ax,cs
  3636.     mov es,ax
  3637.     mov dx,cs:mst        ; Asynch status port. [19b]
  3638.     in al,dx
  3639.     test al,mdminp        ; Data available?
  3640.     jz retint        ; Nope.
  3641.     mov dx,cs:mdat        ; [19b]
  3642.     in al,dx
  3643.     mov ah,0FFH        ; Assume X-fer mode. [16 start]
  3644.     cmp cs:telflg,0        ; File transfer or terminal mode? [17c]
  3645.     jz srint0
  3646.     mov ah,7FH        ; Terminal mode (7 bits only). 
  3647. srint0:    and al,ah        ; Fiddle with input. [16 end]
  3648.     jz retint        ; Ignore nulls.
  3649.     cmp al,7FH        ; Ignore rubouts, too.
  3650.     jz retint
  3651.     stosb            ; Store char in buffer.
  3652.     lea ax,cs:source
  3653.     sub di,ax
  3654.     and di,7FFH        ; Truncate buffer here.
  3655.     add di,ax
  3656.     inc cs:count
  3657. retint:    mov cs:srcpnt,di
  3658.     sti
  3659.     mov al,mdeoi        ; [19b]
  3660.     out intcon1,al        ; Send End-of-Interrupt to 8259.
  3661.     pop di
  3662.     pop es
  3663.     pop ax
  3664.     pop dx
  3665. intret:    iret
  3666. SERINT    ENDP
  3667. ENDIF
  3668.  
  3669. PLUP    PROC    NEAR
  3670.     call conchr        ; Check keyboard.   [15 begin]
  3671.      jmp extln        ; Exit from Telnet
  3672.      nop            ;
  3673.      nop            ; In case it is a short jump (Z100)
  3674.     call prtchr        ; Check serial port
  3675.      ret            ; Got a character
  3676.      nop            ; Use up three bytes.  [15 end] 
  3677.      nop
  3678.     jmp plup
  3679. PLUP    ENDP
  3680.  
  3681. ;************************System Dependent****************************
  3682.  
  3683. ; These I/O routines are similar to those just above.
  3684.  
  3685. PRTCHR  PROC    NEAR
  3686. IF ibmpc
  3687.     cmp cs:count,0
  3688.     jnz prtch2
  3689.     jmp rskp        ; No data - check console.
  3690. prtch2: cli            ; Disable int's.
  3691.     mov cx,ds
  3692.     mov ax,cs
  3693.     mov ds,ax
  3694.     mov si,cs:savesi
  3695.     lodsb            ; Get char from buffer.
  3696.     lea dx,cs:source
  3697.     sub si,dx
  3698.     and si,7FFH        ; Truncate buffer after here.
  3699.     add si,dx
  3700.     dec cs:count
  3701.     mov cs:savesi,si 
  3702.     mov ds,cx
  3703.     sti            ; Renable int's.
  3704.     ret
  3705. ENDIF
  3706. IF Z100
  3707.     push bx            ; Save BX
  3708.     mov ah,chr_status    ; Get the function we want
  3709.     mov al,chr_sfgs        ; Get the subfunction to get status
  3710.     call bios_auxfunc    ; Perform the function
  3711.     cmp bl,0        ; Anything in queue?
  3712.     jne prtch1        ; Yes, go get it
  3713.     pop bx            ; Restore BX
  3714.     jmp rskp        ; No, give skip return
  3715. prtch1:    mov ah,chr_read        ; Want to read character
  3716.     call bios_auxfunc    ; Do it
  3717.     and al,07FH        ; Strip off parity bit
  3718.     pop bx            ; And restore BX
  3719.     ret
  3720. ENDIF
  3721. IF L610                            ;[21]
  3722.     push    bx
  3723.     mov    ah,PORT_STAT    ; Is char there
  3724.     mov    dx,AUXPORT
  3725.     int    COMM
  3726.     and    ah,01H        ; Data there?
  3727.     jnz    prtch1        ; Yep
  3728.     pop    bx
  3729.     jmp    rskp            ; No just give skip return
  3730. prtch1:
  3731.     mov    ah,READ_BYTE    ; Get it
  3732.     mov    dx,AUXPORT    ; From AUX:
  3733.     int    COMM
  3734.     mov    ah,0FFh
  3735.     cmp    cs:telflg,0    ; File transfer or terminal mode
  3736.     jz    prtch2
  3737.     mov    ah,7FH        ; Terminal only 7 bits
  3738. prtch2:
  3739.     and    al,ah        ; Diddle with input
  3740.     pop    bx
  3741.     ret
  3742. ENDIF
  3743.  
  3744. PRTCHR  ENDP
  3745.  
  3746.  
  3747. ; Generate a short beep.
  3748.  
  3749. IF ibmpc
  3750. BEEP    PROC    NEAR
  3751.     mov al,10110110B    ; Gen a short beep (long one losses data.)
  3752.     out timer+3,al        ; Code snarfed from Technical Reference.
  3753.     mov ax,533H
  3754.     out timer+2,al
  3755.     mov al,ah
  3756.     out timer+2,al
  3757.     in al,port_b
  3758.     mov ah,al
  3759.     or al,03
  3760.     out port_b,al
  3761.     sub cx,cx
  3762.     mov bl,1
  3763. beep0:  loop beep0
  3764.     dec bl        
  3765.     jnz beep0
  3766.     mov al,ah
  3767.     out port_b,al
  3768.     ret
  3769. BEEP    ENDP 
  3770. ENDIF
  3771.  
  3772. CONCHR  PROC    NEAR
  3773. IF ibmpc
  3774.     mov ah,1        ; Get keyboard status.
  3775.     int keyb
  3776.     jnz cnc0x    
  3777.     jmp rskp
  3778. cnc0x:    mov ah,0        ; Read a char.
  3779.     int keyb
  3780.     cmp al,0        ; Special char (cntrl-break)?
  3781.     jnz nobrk        ; Nope.
  3782.     cmp ah,3        ; 3 in ah means nul code.
  3783.     jz nobrk        ; Pass nulls.  [14]
  3784.     cmp ah,83        ; Del Key?  [14]
  3785.     je cnc1r        ; Yes - send a rubout. [14]
  3786.     cmp ah,0        ; Cntrl-Break?
  3787.     jne cnc1y
  3788.     call sendbr        ; Send a break. [20g]
  3789. cnc1y:    jmp rskp    
  3790. ENDIF
  3791. IF Z100 OR L610        ; [21]
  3792.     mov ah,dconio        ; Determine if character present
  3793.     mov dl,0ffH        ; Want input
  3794.     int dos            ; Get status
  3795.     cmp al,00H        ; Any characters there?
  3796.     jne nobrk        ; if not, forget it
  3797.     jmp rskp        ; Give skip return
  3798. ENDIF
  3799.  
  3800. cnc1r:    cmp delflg,0        ; Translate BS to DEL? [19c]
  3801.     je dobs            ; Nope, BS=BS [19c]    
  3802.     mov al,BS        ; BS (will be converted to DEL) [15]
  3803.     jmp nobrk
  3804. dobs:    mov al,07FH        ; ASCII rubout.  [14]
  3805. nobrk:  mov dl,al        ; Store char here.
  3806.     mov ah,escchr           ; Get the escape char.
  3807.         cmp ah,dl               ; Is it an escape char?
  3808.         jz intchr               ; If so go process it.
  3809.     cmp delflg,0        ; Translate BS to DEL?  [19c]
  3810.     je dobs1        ; Nope, BS=BS  [19c]
  3811.     cmp dl,BS        ; Is it a backspace ? [15 begin]
  3812.     jnz cch0        ; No, check for delete
  3813.     mov dl,DEL        ; Yes, get a delete
  3814.     jmp cch1        ; And send that instead
  3815. cch0:    cmp dl,DEL        ; Is it a delete ?
  3816.     jnz cch1        ; No, done checking then
  3817.     mov dl,BS        ; Yes, use a backspace
  3818. cch1:    mov ax,dx        ; Copy character back to AX  [15 end]
  3819. dobs1:    call dopar        ; Set parity (if any).   [10]
  3820.     mov dx,ax
  3821.     push dx
  3822.         call prtout             ; Output the char to the port.
  3823.     pop dx
  3824.         mov ah,ecoflg           ; Get the echo flag.
  3825.         cmp ah,0                        ; Is it turned on?
  3826.     jnz cnc1x
  3827.         jmp rskp                 ; If not we're done here.
  3828. cnc1x:  and dl,7FH
  3829.     cmp dl,BS        ; Backspace?
  3830.     je cnc2x
  3831.     cmp dl,CR        ; Carriage return?
  3832.     je cnc2x
  3833. IF ibmpc
  3834.     cmp dl,BELL
  3835.     jne cnc2y
  3836.     call beep
  3837.     jmp rskp
  3838. ENDIF
  3839. cnc2y:    cmp dl,20H        ; Is it a control char?
  3840.     jge cnc2x    
  3841.     jmp rskp
  3842. cnc2x:    mov ah,dconio           ; Direct console output.
  3843.         int dos                 ; Echo the char.
  3844.         jmp rskp
  3845. CONCHR  ENDP
  3846.  
  3847. ; One routine to send a break for the IBM-PC and Z100. [20g]
  3848. SENDBR    PROC    NEAR
  3849.     push cx
  3850.     push dx
  3851.     push ax
  3852. IF L610            ; [21]
  3853.     mov    ah,7H    ; send a break out aux port
  3854.     mov    al,01H
  3855.     mov    dh,0
  3856.     mov    dl,AUXPORT
  3857.     int COMM
  3858.     mov    ah,7H    ; flush buffer also
  3859.     mov    al,02H
  3860.     mov    dh,0
  3861.     mov    dl,AUXPORT
  3862.     int    COMM
  3863. ELSE
  3864.     xor cx,cx        ; Clear loop counter.
  3865.     mov dx,mdcom        ; Port address.  [19b]
  3866.     in al,dx        ; Get current setting.
  3867.     or al,BRKBIT        ; Set send-break bit(s).
  3868.     out dx,al        ; Start the break.
  3869. pause:    loop pause        ; Wait a while.
  3870.     xor al,BRKBIT        ; Clear send-break bit(s).
  3871.     out dx,al        ; Stop the break.
  3872. ENDIF
  3873.     pop ax
  3874.     pop dx
  3875.     pop cx
  3876.     ret
  3877.             ; And return.
  3878. SENDBR    ENDP
  3879.  
  3880. CONN    PROC    NEAR     
  3881. intchr: mov ah,dconio           ; Direct console I/O.
  3882.         mov dl,0FFH             ; Input.
  3883.         int dos                 ; Get a char.
  3884.     mov ah,al
  3885.     cmp ah,0                        ; Is the char a null?
  3886.         jz intchr               ; If so, go until we get a char.
  3887.         mov bh,ah               ; Save the actual char.
  3888.         and ah,137O             ; Convert to upper case.
  3889.         cmp ah,'C'                      ; Is it close?
  3890.         jne intch0
  3891.         ret
  3892. intch0: cmp ah,'S'                      ; Is it status?
  3893.     jnz inc0x
  3894.         jmp stat01              ; If so, jump to stat01 (it will return).
  3895. inc0x:  cmp ah,'B'        ; Send a break? [20g]
  3896.     jne inc1x        ; No. [20g]
  3897.     call sendbr        ; Yes, so send a break. [20g]
  3898.     jmp rskp        ; And return.  [20g]
  3899. inc1x:    mov ah,bh                       ; Get the char.
  3900.         cmp ah,'?'                      ; Is it help?
  3901.         jne intch1              ; If not, go to the next check.
  3902.         mov dx,offset inthlp    ; If so, get the address of the help message.
  3903.         mov ah,prstr            ; Print it.
  3904.         int dos
  3905.         jmp intchr              ; Get another char.
  3906. intch1: mov ch,ah               ; Put the char into another reg.
  3907.         mov ah,escchr           ; Get the escape char.
  3908.         cmp ah,ch               ; Is it the escape char?
  3909.         jne intch2              ; If not, go send a beep to the user.
  3910.     mov al,ch
  3911.     call dopar        ; Set parity.     [10] 
  3912. intc11: mov dl,al
  3913.     call prtout             ; Output it.
  3914.         jmp rskp                ; Return, we are done here.
  3915. intch2: mov dl,'G'-100O         ; Otherwise send a beep.
  3916.         mov ah,dconio
  3917.         int dos
  3918.         jmp rskp
  3919.  
  3920. ; Another similar I/O routine.
  3921.  
  3922. ;************************System Dependent****************************
  3923.  
  3924. prtout:
  3925.     mov al,dl               ; Char must be in al.
  3926. IF ibmpc
  3927.     mov dx,mddat        ; [19b]
  3928.     out dx,al
  3929. ENDIF
  3930. IF Z100
  3931.     call bios_auxout    ; Send the character
  3932. ENDIF
  3933.  
  3934. IF L610            ; [21]
  3935.     sub    cx,cx
  3936. prtot1:
  3937.     mov    ah,SEND_BYTE
  3938.     mov    dx,AUXPORT
  3939.     int    COMM
  3940.     and    ah,80H    ; is ok?
  3941.     jz    prtot2
  3942.     loop    prtot1
  3943. prtot2:
  3944. ENDIF
  3945.         ret
  3946. CONN    ENDP
  3947.  
  3948. ; [15 begin]
  3949. IF ibmpc            ; Only for IBM-PC's. [20g]
  3950. DOTAB    PROC NEAR
  3951.     mov ah,3        ; Read current cursor position.
  3952.     mov bh,0        ; This screen
  3953.     int bios        ; From bios
  3954.     cmp dl,72        ; Are we at the last tab stop ?
  3955.     jl dotab0        ; No, move to the next
  3956.     cmp dl,79        ; Are we at the end ?
  3957.     je dotab2        ; Yes, just return
  3958.     add dl,1        ; No, move forward one position
  3959.     jmp dotab1        ; Set the cursor position
  3960. dotab0:    mov al,dl        ; Get the column into al
  3961.     push dx            ; Save the current cursor position
  3962.     xor ah,ah        ; Zero the high end of ax
  3963.     mov bl,8        ; Get an eight
  3964.     xor bh,bh        ; Zero high byte
  3965.     div bl            ; Divide by 8
  3966.     mov al,ah        ; Put the remainder in the low end
  3967.     xor ah,ah        ; Zero the high end
  3968.     mov cl,8        ; Get an 8 into cl
  3969.     xor ch,ch        ; Zero high byte
  3970.     sub cl,al        ; Subtract al from cl
  3971.     xor ch,ch        ; Zero high end
  3972.     pop dx            ; Restore the current cursor position
  3973.     add dl,cl        ; And subtract column mod 8
  3974. dotab1:    mov ah,2        ; Set cursor position
  3975.     mov bh,0        ; This screen
  3976.     int bios        ; Bios call
  3977. dotab2:    ret            ; Return
  3978. DOTAB    ENDP
  3979. ENDIF                ; [20g]
  3980. ; [15 end]
  3981.  
  3982.  
  3983. IF ibmpc            ; [20g]
  3984. TELESC    PROC    NEAR
  3985.     cmp vtflg,0        ; Is vt52 flag on?
  3986.     jne vt0
  3987.     jmp telnoe        ; Don't do escape stuff if it's off.
  3988. vt0:    call plup
  3989.         mov ah,al                       ; Get the char.
  3990.     cmp ah,'Z'        ; Tell host our terminal type. [20a]
  3991.     je vtiden        ; [20a]
  3992.     cmp ah,'Y'        ; Special char - move cursor.
  3993.     jne vt1
  3994.     jmp movcur
  3995. vt1:    cmp ah,'<'        ; Start-ANSI?  [17b start] 
  3996.     je vtexit        ; Yes, ignore
  3997.     cmp ah,'['        ; An ANSI command?
  3998.     je vtansi        ; Yes, do it
  3999.     cmp ah,'@'        ; Insert characters?
  4000.     jne vtnins
  4001.     mov incmod,1
  4002.     jmp telnoe
  4003. vtnins:    cmp ah,'p'        ; Inverse?
  4004.     jne vtninv
  4005.     jmp vtinvi
  4006. vtninv:    cmp ah,'q'        ; Normal?
  4007.     jne vtnino
  4008.     jmp vtinvo        ; [17b end]
  4009. vtnino:    cmp ah,'A'        ; Less than an 'A'?
  4010.         jl vtig                 ; Yes - ignore.
  4011.         cmp ah,'O'+1            ; Greater than 'O'?   [17b]
  4012.         jns vtig                ; Yes - ignore.
  4013.         mov al,'A'
  4014.         sub ah,al               ; Else make into index.
  4015.         shl ah,1
  4016.         mov bx,offset ttab      ; Load base addr of table.
  4017.     mov cl,ah               ; Move a into cx.
  4018.         mov ch,00H              ; Zero out high byte.
  4019.         add bx,cx               ; Double add index+offset.
  4020.     mov bx,[bx]        ; Get address of routine to call.
  4021.     jmp bx
  4022. vtig:                           ; Ignore escape sequence.
  4023.         push ax                 ; Push the char to be output.
  4024.         mov dl,esc              ; Load an escape.
  4025.         mov ah,conout           ; The function code
  4026.         int dos                 ; and the syscal.
  4027.         pop ax                  ; Restore the character
  4028.         mov dl,ah               ; and move to output register.
  4029.         mov ah,conout           ; The function
  4030.         int dos                 ; and the syscall.
  4031. ENDIF
  4032. vtexit:    jmp telnoe        ; Return home. [17b]
  4033.  
  4034. ; Used for terminal-type querying programs.  [20a]
  4035. IF ibmpc
  4036. vtiden:    mov ah,ESC        ; Respond with "ESC / K".
  4037.     call outchr
  4038.      jmp telnoe        ; If failed, just forget the rest.
  4039.     mov ah,"/"
  4040.     call outchr
  4041.      jmp telnoe
  4042.     mov ah,"K"
  4043.     call outchr
  4044.      jmp telnoe        ; And return even if failed.
  4045.     jmp telnoe
  4046. ENDIF
  4047.  
  4048. ; ANSI Insert/Delete Line.  [17b start, 20g] 
  4049. IF ibmpc
  4050. vtansi:    call plup
  4051.     cmp al,'?'
  4052.     je vtanso
  4053.     sub al,30H
  4054.     mov temp,ax
  4055.     call plup
  4056.     cmp al,"9"
  4057.     jg vtans1
  4058.     sub al,30H
  4059.     mov temp2,ax
  4060.     mov ax,temp
  4061.     mov dl,10
  4062.     mul dl
  4063.     add ax,temp2
  4064.     mov temp,ax
  4065.     call plup
  4066. vtans1:    cmp al,'L'
  4067.     jne vtans2
  4068.     mov ah,3        ; Get cursor position
  4069.     mov bh,0
  4070.     int bios
  4071.     mov temp1,dx
  4072.     mov cx,dx        ; Do a N-line scroll
  4073.     mov cl,0
  4074.     mov dx,184FH
  4075.     mov ax,temp
  4076.     mov ah,7
  4077.     mov bh,7
  4078.     int bios
  4079.     jmp vtans3
  4080. vtans2: cmp al,'M'
  4081.     jne vtans4
  4082.     mov ah,3
  4083.     mov bh,0
  4084.     int bios
  4085.     mov temp1,dx
  4086.     mov ax,temp
  4087.     mov ah,6
  4088.     mov cx,dx
  4089.     mov dx,184FH
  4090.     mov bh,7
  4091.     int bios
  4092. vtans3: mov dx,temp1        ; Restore cursor position
  4093.     mov dl,0
  4094.     mov ah,2
  4095.     mov bh,0
  4096.     int bios
  4097. vtans4:    jmp telnoe
  4098. vtanso: call plup
  4099.     call plup
  4100.     jmp telnoe
  4101.  
  4102. vtinvi: mov curatt,0070H    ; Reverse video
  4103.     jmp telnoe
  4104. vtinvo: mov curatt,0007H    ; Normal video
  4105.     jmp telnoe        ;  [17b end]
  4106. TELESC    ENDP
  4107. ENDIF
  4108.  
  4109. IF ibmpc
  4110. TEL    PROC    NEAR
  4111. movcur:    call plup
  4112.     sub al,32
  4113.     mov dh,al
  4114.     mov temp,dx        ; Save row position here.
  4115.     call plup
  4116.     mov dx,temp        ; Restore
  4117.     sub al,32        ; Comes with 37Q added on (& starts at 1).
  4118.     mov dl,al
  4119.     mov bh,0
  4120.     mov ah,2
  4121.     int bios
  4122.     jmp telnoe
  4123.  
  4124. curup:    mov ah,3        ; Cursor up function.
  4125.     mov bh,0
  4126.     int bios
  4127.     cmp dh,0
  4128.     je cup0
  4129.     sub dh,1
  4130.     mov ah,2
  4131.     int bios
  4132. cup0:    jmp telnoe
  4133.  
  4134. curdwn:    mov ah,3        ; Cursor down.
  4135.     mov bh,0
  4136.     int bios
  4137.     cmp dh,24
  4138.     je cdn0
  4139.     add dh,1
  4140.     mov ah,2
  4141.     int bios
  4142. cdn0:    jmp telnoe
  4143.  
  4144. currt:    mov ah,3        ; Cursor right.
  4145.     mov bh,0
  4146.     int bios
  4147.     cmp dl,79
  4148.     je crt0
  4149.     add dl,1
  4150.     mov ah,2
  4151.     int bios
  4152. crt0:    jmp telnoe
  4153.  
  4154. curlft:    mov ah,3        ; Cursor left.
  4155.     mov bh,0
  4156.     int bios
  4157.     cmp dl,0
  4158.     je clt0
  4159.     sub dl,1
  4160.     mov ah,2
  4161.     int bios
  4162. clt0:    jmp telnoe
  4163.  
  4164. curskp:    jmp vtig        ; Ignore for now.
  4165.  
  4166. curclr:    call locate        ; Home the cursor [15]
  4167.     jmp curscr        ; And clear the screen [15]
  4168.  
  4169. curhm:    call locate
  4170.     jmp telnoe
  4171.  
  4172. curscr:    mov ah,3        ; Clear to end of screen.
  4173.     mov bh,0
  4174.     int bios
  4175.     cmp dx,0
  4176.     jne csr0
  4177.     call cmblnk
  4178.     jmp telnoe
  4179. csr0:    cmp dl,0
  4180.     je csr1
  4181.     push dx
  4182.     call clreol
  4183.     pop dx
  4184.     add dh,1
  4185.     mov dl,0
  4186. csr1:    mov cx,dx
  4187.     mov dx,184FH
  4188.     mov bh,7
  4189. ;    mov al,25
  4190. ;    sub al,ch
  4191.     mov al,0
  4192.     mov ah,7
  4193.     int bios
  4194.     jmp telnoe
  4195.  
  4196. curln:    call clreol        ; One routine to clear to EOL. [19a]
  4197.     jmp telnoe
  4198.  
  4199. inslin:    mov ah,3        ; Get cursor position.
  4200.     mov bh,0
  4201.     int bios
  4202.     mov temp,dx        ; Save here.
  4203.     mov cx,dx
  4204.     mov cl,0        ; Start at beginning of row.
  4205.     mov dx,184FH        ; End at lower corner of screen.
  4206.     mov ax,0701H
  4207.     mov bh,7
  4208.     int bios        ; Scroll down one line.
  4209.     mov dx,temp        ; Get back where we were.
  4210.     mov dl,0
  4211.     mov ah,2
  4212.     mov bh,0
  4213.     int bios
  4214.     jmp telnoe
  4215.  
  4216. dellin: mov ah,3
  4217.     mov bh,0
  4218.     int bios        ; Get current cursor position. 
  4219.     mov temp,dx        ; Remember the place.
  4220.     mov ax,0601H        ; Scroll up one line.
  4221.     mov cx,dx
  4222.     mov cl,0        ; Start at beginning of row.
  4223.     mov dx,184FH
  4224.     mov bh,7
  4225.     int bios
  4226.     mov dx,temp
  4227.     mov dl,0
  4228.     mov ah,2
  4229.     mov bh,0
  4230.     int bios
  4231.     jmp telnoe
  4232.  
  4233. ; Delete character.  [17b start] 
  4234. delchr:    mov ah,3        ; Get cursor position
  4235.     mov bh,0
  4236.     int bios
  4237.     mov temp,dx
  4238.     mov ah,1        ; Turn off cursor
  4239.     mov ch,20H
  4240.     int bios
  4241. delch1:    mov ah,2        ; Position to col M+1
  4242.     inc dl
  4243.     int bios
  4244.     mov ah,8        ; Get char/attr
  4245.     int bios
  4246.     mov cx,ax        ; Save it
  4247.     dec dl            ; Position to col M
  4248.     mov ah,2
  4249.     int bios
  4250.     mov ah,9        ; Write char/attr
  4251.     mov al,cl
  4252.     mov bl,ch
  4253.     mov cx,1
  4254.     int bios
  4255.     inc dl            ; Next column
  4256.     cmp dl,79        ; About to write to col 80?
  4257.     jne delch1        ; No
  4258.     mov ah,2        ; Position to col 80
  4259.     int bios
  4260.     mov ah,9        ; Write char/attr
  4261.     mov al,' '
  4262.     int bios
  4263.     mov ah,2        ; Reset cursor
  4264.     mov dx,temp
  4265.     int bios
  4266.     mov ah,1
  4267.     mov cx,0B0CH
  4268.     int bios
  4269.     jmp telnoe
  4270.  
  4271. ; Cancel Insert Character mode
  4272. insmox:    mov incmod,0
  4273.     jmp telnoe        ; [17b end]
  4274. TEL    ENDP
  4275. ENDIF
  4276. ; Common routine to clear to end-of-line. [19a]
  4277. IF ibmpc OR L610        ; [21]
  4278. CLREOL    PROC    NEAR
  4279.     mov ah,3        ; Clear to end of line.
  4280.     mov bh,0
  4281.     int bios        ; Get current cursor position
  4282.     mov cx,dx
  4283.     mov dl,79
  4284.     mov ah,7
  4285.     mov al,0
  4286.     mov bh,7
  4287.     int bios
  4288.     ret
  4289. CLREOL    ENDP
  4290. ENDIF    
  4291.  
  4292.  
  4293. ; This is the SET command.
  4294.  
  4295. SETCOM  PROC    NEAR
  4296.         mov dx,offset settab    ; Parse a keyword from the set table.
  4297.         mov bx,offset sethlp
  4298.         mov ah,cmkey
  4299.         call comnd
  4300.          jmp r
  4301.         call bx
  4302.         jmp rskp
  4303. SETCOM  ENDP
  4304.  
  4305.  
  4306. ;       This is the ESCAPE character SET subcommand.     [6 start]
  4307.  
  4308. ESCAPE  PROC    NEAR
  4309.     call cmgtch        ; Get a char.
  4310.     cmp ah,0
  4311.     jns es1            ; Terminator or no?
  4312.     and ah,7FH        ; Turn off minus bit.
  4313.     cmp ah,'?'
  4314.     jne es0
  4315.     mov dx,offset eschlp
  4316.     mov ah,prstr
  4317.     int dos
  4318.     mov dx,offset crlf
  4319.     int dos
  4320.     mov dx,offset kerm
  4321.     int dos
  4322.     mov bx,cmdptr
  4323.     mov al,'$'
  4324.     mov [bx],al
  4325.     mov dx,offset cmdbuf
  4326.     int dos
  4327.     dec cmcptr        ; Ignore dollar sign.
  4328.     dec cmccnt
  4329.     mov cmaflg,0
  4330.     jmp repars
  4331. es0:    mov ah,prstr
  4332.     mov dx,offset ermes3
  4333.     int dos
  4334.     ret
  4335. es1:      mov temp,ax
  4336.     call cmcfrm
  4337.      jmp es0
  4338.      nop            ; Take up 3 bytes.
  4339.     mov ax,temp
  4340.     mov escchr,ah        ; Save new value.
  4341.     ret
  4342. ESCAPE  ENDP            ; [6 end]
  4343.  
  4344. ;     This is the End-of-line character SET subcommand.       [5 start]
  4345.  
  4346. EOLSET    PROC    NEAR
  4347.     call cmgtch        ; Get the first char into AH.
  4348.     cmp ah,0
  4349.     jns eol1
  4350.     cmp ah,0BFH        ; Question mark?
  4351.     je eol4
  4352.     jmp eol3
  4353. eol1:    sub ah,030H        ; Digit --> real number.
  4354.     mov temp,ax        ; Save the input.
  4355.     call cmcfrm
  4356.      jmp eol0        ; Got a char.
  4357.     mov ax,0
  4358.     mov bx,temp
  4359.     jmp eol2
  4360. eol0:    sub ah,030H        ; Digit --> real number.
  4361.     mov temp1,ax
  4362.     call cmcfrm
  4363.      jmp eol3        ; Too many chars.
  4364.     mov bx,temp1
  4365.     mov ax,temp
  4366.     xchg al,ah
  4367.     mov ah,0
  4368. eol2:    mov temp,ax        ; Save our registers.
  4369.     mov temp1,bx
  4370.     call cmcfrm
  4371.      jmp eol3
  4372.     mov bx,temp1
  4373.     mov ax,temp
  4374.     mov temp2,10        ; Get numerical value of char.
  4375.     mul temp2
  4376.     add al,bh
  4377.     mov ah,0
  4378.     cmp al,0
  4379.     jl eol3
  4380.     cmp al,1FH
  4381.     jg eol3
  4382.     mov seol,al        ; Use new eol char.
  4383.     ret
  4384. eol3:    mov ah,prstr
  4385.     mov dx,offset eolerr    ; Bad end-of-line char
  4386.     int dos
  4387.     jmp prserr
  4388. eol4:    mov ah,prstr
  4389.     mov dx,offset eolhlp
  4390.     int dos
  4391.     mov dx,offset crlf
  4392.     int dos
  4393.     mov dx,offset kerm
  4394.     int dos
  4395.     mov bx,cmdptr
  4396.     mov al,'$'
  4397.     mov [bx],al
  4398.     mov dx,offset cmdbuf
  4399.     int dos
  4400.     dec cmcptr            ; Don't count the dollar sign.
  4401.     dec cmccnt            ; Or the question mark.
  4402.     mov cmaflg,0            ; Check for more input.
  4403.     jmp repars
  4404. EOLSET    ENDP                             ;    [5 end]
  4405.  
  4406. ;       This is the LOCAL echo SET subcommand.
  4407.  
  4408. LCAL    PROC    NEAR
  4409.         mov dx,offset ontab
  4410.         mov bx,offset onhlp
  4411.         mov ah,cmkey
  4412.         call comnd
  4413.          jmp r
  4414.         push bx                 ; Save the parsed value.
  4415.         mov ah,cmcfm
  4416.         call comnd              ; Get a confirm.
  4417.          jmp r                  ;  Didn't get a confirm.
  4418.         pop bx
  4419.         mov ecoflg,bl           ; Set the local echo flag.
  4420.     ret
  4421. LCAL    ENDP
  4422.  
  4423. ;       This is the VT52 emulation SET subcommand.
  4424.  
  4425. IF ibmpc
  4426. VT52EM  PROC    NEAR
  4427.         mov dx,offset ontab
  4428.         mov bx,offset onhlp
  4429.         mov ah,cmkey
  4430.         call comnd
  4431.          jmp r
  4432.         push bx
  4433.         mov ah,cmcfm
  4434.         call comnd              ; Get a confirm.
  4435.          jmp r                  ;  Didn't get a confirm.
  4436.         pop bx
  4437.         mov vtflg,bl            ; Set the VT52 emulation flag.
  4438.     ret
  4439. VT52EM  ENDP
  4440. ENDIF
  4441.  
  4442. ; This is the SET subcommand to choose between COM1 and COM2. [19b]
  4443.   
  4444. IF ibmpc
  4445. COMSET  PROC    NEAR
  4446.         mov dx,offset comptab
  4447.         mov bx,offset comphlp
  4448.         mov ah,cmkey
  4449.         call comnd
  4450.          jmp r
  4451.         push bx
  4452.         mov ah,cmcfm
  4453.         call comnd              ; Get a confirm.
  4454.          jmp r                  ;  Didn't get a confirm.
  4455.         pop bx
  4456.         mov comflg,bl           ; Set the comm port flag.
  4457.     call dobaud        ; Set the baud rate for the port. [19a]
  4458.     cmp comflg,1        ; Using Com 1?
  4459.     jne coms0        ; Nope.
  4460.     mov mddat,MDMDAT1    ; Set COM1 defaults.
  4461.     mov mdstat,MDMSTS1
  4462.     mov mdcom,MDMCOM1
  4463.     mov mddis,MDMINTC
  4464.     mov mden,MDMINTO
  4465.     mov mdmeoi,EOICOM
  4466.     mov mdintv,MDMINTV
  4467.     ret
  4468. coms0:    mov mddat,MDMDAT2    ; Set COM2 defaults.
  4469.     mov mdstat,MDMSTS2
  4470.     mov mdcom,MDMCOM2
  4471.     mov mddis,MDINTC2
  4472.     mov mden,MDINTO2
  4473.     mov mdmeoi,EOICOM2
  4474.     mov mdintv,MDINTV2
  4475.     ret
  4476. COMSET  ENDP
  4477. ENDIF
  4478.  
  4479. ;       This is the SET IBM command.
  4480.  
  4481. IBMSET  PROC    NEAR
  4482.         mov dx,offset ontab
  4483.         mov bx,offset onhlp
  4484.         mov ah,cmkey
  4485.         call comnd
  4486.          jmp r
  4487.         push bx
  4488.         mov ah,cmcfm
  4489.         call comnd              ; Get a confirm.
  4490.          jmp r                  ;  Didn't get a confirm.
  4491.         pop bx
  4492.         mov ibmflg,bl           ; Set the IBM flag.
  4493.     cmp bl,0        ; Turning on or off?    [12 start]
  4494.     je ibmst1        ; If off, set parity & local echo to defaults.
  4495.     mov ah,ibmpar        ; Set IBM parity.
  4496.     mov al,1        ; Set local echo on.
  4497.     jmp ibmst2
  4498. ibmst1:    mov ah,defpar        ; Reset parity to default.
  4499.     mov al,0        ; Turn off local echo.
  4500. ibmst2:    mov parflg,ah        ; Set parity.
  4501.     mov ecoflg,al        ; And local echo.    [12 end]    
  4502.     xor al,01H        ; 01 -> 00, 00 -> 01. [19c]  
  4503.     mov delflg,al        ; BS -> DEL or BS -> BS. [19c]
  4504.     ret
  4505. IBMSET  ENDP
  4506.  
  4507. ;       This is the SET L6 command.
  4508.  
  4509. L6SET  PROC    NEAR
  4510.     mov dx,offset ontab
  4511.     mov bx,offset onhlp
  4512.     mov ah,cmkey
  4513.     call comnd
  4514.       jmp r
  4515.     push bx
  4516.     mov ah,cmcfm
  4517.     call comnd              ; Get a confirm.
  4518.       jmp r                  ;  Didn't get a confirm.
  4519.     pop bx
  4520.     mov l6flg,bl           ; Set the L6 flag.
  4521.     cmp bl,0        ; Turning on or off?    [12 start]
  4522.     je l6st1        ; If off, set parity & local echo to defaults.
  4523.     mov ah,parevn        ; Set L6 parity.
  4524.     mov al,0        ; Set local echo off.
  4525.     jmp l6st2
  4526. l6st1:
  4527.     mov ah,defpar        ; Reset parity to default.
  4528.     mov al,1            ; Turn off local echo.
  4529. l6st2:
  4530.     mov parflg,ah        ; Set parity.
  4531.     mov ecoflg,al        ; And local echo.    [12 end]    
  4532.     mov delflg,0        ; Only use BS for delete
  4533.     ret
  4534. L6SET  ENDP
  4535.  
  4536. ;       This is the SET File-Warning command.
  4537.  
  4538. FILWAR  PROC    NEAR
  4539.         mov dx,offset ontab
  4540.         mov bx,offset onhlp
  4541.         mov ah,cmkey
  4542.         call comnd
  4543.          jmp r
  4544.         push bx
  4545.         mov ah,cmcfm
  4546.         call comnd              ; Get a confirm.
  4547.          jmp r                  ;  Didn't get a confirm.
  4548.         pop bx
  4549.         mov flwflg,bl           ; Set the IBM flag.
  4550.     ret
  4551. FILWAR  ENDP
  4552.  
  4553. ;       This is the SET aborted-file command.  [20d]
  4554.  
  4555. ABFSET  PROC    NEAR
  4556.         mov dx,offset abftab
  4557.         mov bx,offset abfhlp
  4558.         mov ah,cmkey
  4559.         call comnd
  4560.          jmp r
  4561.         push bx
  4562.         mov ah,cmcfm
  4563.         call comnd              ; Get a confirm.
  4564.          jmp r                  ;  Didn't get a confirm.
  4565.         pop bx
  4566.         mov abfflg,bl           ; Set the aborted file flag.
  4567.     ret
  4568. ABFSET  ENDP
  4569.  
  4570. ;       This is the SET Parity command.                [10 start]
  4571.  
  4572. SETPAR  PROC    NEAR
  4573.         mov dx,offset partab
  4574.         mov bx,offset parhlp
  4575.         mov ah,cmkey
  4576.         call comnd
  4577.          jmp r
  4578.         push bx
  4579.         mov ah,cmcfm
  4580.         call comnd              ; Get a confirm.
  4581.          jmp r                  ;  Didn't get a confirm.
  4582.         pop bx
  4583.         mov parflg,bl           ; Set the parity flag.
  4584.     ret
  4585. SETPAR  ENDP                            ; [10 end]
  4586.  
  4587. ; Sets debugging mode on and off.
  4588.  
  4589. DEBST    PROC    NEAR
  4590.         mov dx,offset ontab
  4591.         mov bx,offset onhlp
  4592.         mov ah,cmkey
  4593.         call comnd
  4594.          jmp r
  4595.         push bx
  4596.         mov ah,cmcfm
  4597.         call comnd              ; Get a confirm.
  4598.          jmp r                  ;  Didn't get a confirm.
  4599.         pop bx
  4600.         mov debug,bl           ; Set the IBM flag.
  4601.     ret
  4602. DEBST   ENDP
  4603.  
  4604. ; Turn bell on or off.    [17a start]
  4605.  
  4606. BELLST    PROC    NEAR
  4607.     mov dx,offset ontab
  4608.     mov bx,offset onhlp
  4609.     mov ah,cmkey
  4610.     call comnd
  4611.      jmp r
  4612.     push bx
  4613.     mov ah,cmcfm
  4614.     call comnd
  4615.      jmp r
  4616.     pop bx
  4617.     mov belflg,bl
  4618.     ret
  4619. BELLST    ENDP                      ;  [17a end]
  4620.  
  4621. ; Function to set BS -> BS or BS -> DEL.  [19c]
  4622.  
  4623. BSSET    PROC    NEAR
  4624.         mov dx,offset BStab
  4625.         mov bx,offset BShlp
  4626.         mov ah,cmkey
  4627.         call comnd
  4628.          jmp r
  4629.         push bx
  4630.         mov ah,cmcfm
  4631.         call comnd              ; Get a confirm.
  4632.          jmp r                  ;  Didn't get a confirm.
  4633.         pop bx
  4634.         mov delflg,bl           ; Set backspace/delete flag.
  4635.     ret
  4636. BSSET   ENDP
  4637.  
  4638. ;  This function sets the baud rate.
  4639.  
  4640. BAUDST  PROC    NEAR
  4641.         mov dx,offset bdtab
  4642.         mov bx,offset bdhlp
  4643.         mov ah,cmkey
  4644.         call comnd
  4645.          jmp r
  4646.     push bx
  4647.     mov ah,cmcfm
  4648.     call comnd        ; Get a confirm.
  4649.      jmp r            ; Didn't get one.
  4650.     pop bx
  4651. IF ibmpc
  4652.         mov baud,bx             ; Set the IBM flag.
  4653.     call dobaud        ; Use common code. [19a] 
  4654. ENDIF
  4655. IF L610
  4656.     mov baud,bl
  4657.     call dobaud
  4658. ENDIF
  4659. IF Z100 
  4660.     mov baud,bl        ; Remember baud rate. [20g]
  4661.     mov bx,ds        ; Set up pointer to config info
  4662.     mov es,bx        ;  .  .  .
  4663.     mov bx,offset auxcnf    ;  .  .  .
  4664.     mov ah,chr_control    ; Function is control
  4665.     mov al,chr_cfsu        ; Subfunction is set new config
  4666.     call bios_auxfunc    ; Set the configuration
  4667. ENDIF
  4668.     ret
  4669. BAUDST  ENDP
  4670.  
  4671. ; Only keep one copy of the code that sets the baud rate. [19a]
  4672.  
  4673. DOBAUD    PROC    NEAR
  4674. IF ibmpc
  4675.     mov dx,mdcom        ; LCR -- Initialize baud rate. [19b]
  4676.     in al,dx
  4677.     mov bl,al
  4678.     or ax,80H
  4679.     out dx,al
  4680.     mov dx,mddat        ; [19b]
  4681.     mov ax,baud
  4682.     out dx,al
  4683.     inc dx
  4684.     mov al,ah
  4685.     out dx,al
  4686.     mov dx,mdcom        ; [19b]
  4687.     mov al,bl
  4688.     out dx,al
  4689. ENDIF
  4690. IF Z100
  4691.     mov bx,ds        ; Set up pointer to config info
  4692.     mov es,bx        ;  .  .  .
  4693.     mov bx,offset auxcnf    ;  .  .  .
  4694.     mov ah,chr_status    ; Get the function code
  4695.     mov al,chr_sfgc        ; And the subfunction to get config
  4696.     call bios_auxfunc    ; Get the block
  4697. ENDIF
  4698. IF L610            ; [21]
  4699.     mov    al,baud
  4700.     mov    ah,INIT_PORT
  4701.     mov    dl,AUXPORT
  4702.     int    COMM
  4703. ENDIF
  4704.  
  4705.     ret
  4706. DOBAUD    ENDP
  4707.  
  4708. ;       This is the STATUS command.
  4709.  
  4710. STATUS  PROC    NEAR
  4711.         call stat0
  4712.          jmp r
  4713.         jmp rskp
  4714. STATUS  ENDP
  4715.  
  4716. STAT0   PROC    NEAR
  4717.         mov ah,cmcfm
  4718.         call comnd              ; Get a confirm.
  4719.          jmp r                  ;  Didn't get a confirm.
  4720. stat01: mov dx,offset locst     ; Assume local echo on.
  4721.     cmp ecoflg,0            ; Is the local echo flag on?
  4722.         jnz stat1               
  4723.         mov dx,offset remst     ; If not say so.
  4724. stat1:  mov ah,prstr            ; Print it.
  4725.         int dos
  4726. IF ibmpc
  4727.         mov dx,offset vtemst    ; Get address of the VT52 emulation string.
  4728.         cmp vtflg,0             ; Is the VT52 emulation flag on?
  4729.         jnz stat2
  4730.         mov dx,offset novtst    ; If not say so.
  4731. stat2:  mov ah,prstr            ; Print it.
  4732.         int dos
  4733.     mov dx,offset cm1st    ; Assume we're using COM1. [19b start]
  4734.     cmp comflg,1        ; Are we?
  4735.     je stat2a        ; Yup.
  4736.     mov dx,offset cm2st    ; We're using COM2.
  4737. stat2a:    mov ah,prstr
  4738.     int dos            ; [19b end]
  4739. ENDIF
  4740.     mov dx,offset ibmst    ; Is IBM flag on?
  4741.     cmp ibmflg,0
  4742.     jnz stat3
  4743.     mov dx,offset noibm     ; Say it's not.
  4744. stat3:  mov ah,prstr
  4745.     int dos
  4746.     mov    dx,offset l6st        ; Assume L6 flag on
  4747.     cmp    l6flg,0
  4748.     jnz    stat3a
  4749.     mov    dx,offset nol6
  4750. stat3a:
  4751.     mov    ah,prstr
  4752.     int    dos
  4753.     mov dx,offset deboff    ; Assume debug mode is off.
  4754.     cmp debug,0
  4755.     je stat4
  4756.     mov dx,offset debon
  4757. stat4:    mov ah,prstr
  4758.     int dos
  4759.     mov dx,offset flwon    ; Assume file-warning on.
  4760.     cmp flwflg,0
  4761.     jne stat5
  4762.     mov dx,offset flwoff
  4763. stat5:    mov ah,prstr
  4764.     int dos
  4765.     mov dx,offset pnonst    ; Assume no parity.        [10 start]
  4766.     cmp parflg,parnon
  4767.     je stat6
  4768.     mov dx,offset pmrkst    ; Mark parity?
  4769.     cmp parflg,parmrk
  4770.     je stat6
  4771.     mov dx,offset pevnst    ; Maybe it's even parity.
  4772.     cmp parflg,parevn
  4773.     je stat6
  4774.     mov dx,offset poddst    ; Odd parity?
  4775.     cmp parflg,parodd
  4776.     je stat6
  4777.     mov dx,offset pspcst
  4778. stat6:    mov ah,prstr
  4779.     int dos                            ;[10 end]
  4780.     mov dx,offset belon    ; Tell if bells ring at end.  [17a start - DT]
  4781.     cmp belflg,0
  4782.     jne stat7
  4783.     mov dx,offset beloff    ; No bells. 
  4784. stat7:    mov ah,prstr
  4785.     int dos            ; That's it.  [17a end - DT]
  4786.     mov dx,offset abfdst    ; Do we discard file if abort? [20d start]
  4787.     cmp abfflg,1
  4788.     je stat8
  4789.     mov dx,offset abfkst    ; Keep what we received so far.
  4790. stat8:    int dos            ; [20d end]
  4791.     mov dx,offset bkdel    ; Is backarrow BS or DEL...  [19c start]
  4792.     cmp delflg,1        ; Is it delete?
  4793.     je stat9        ; Yup.
  4794.     mov dx,offset bkbs    ; It's a backspace.
  4795. stat9:    int dos            ; Tell the user.  [19c end]
  4796.     mov dx,offset eolst    ; Tell the end-of-line char used.  [5 start]
  4797.     mov ah,prstr
  4798.     int dos
  4799.     mov ah,conout
  4800.     mov dl,seol
  4801.     add dl,40H
  4802.     int dos                             ; [5 end]
  4803.     mov ah,prstr
  4804.     mov dx,offset escmes            ; Print escape character.  [6]
  4805.     int dos    
  4806.     call escprt
  4807.     call baudprt            ; Print the baud rate. [19a]
  4808.         mov dx,offset cmcrlf    ; Get the address of a crlf.
  4809.         mov ah,prstr            ; Print it.
  4810.         int dos
  4811.         jmp rskp
  4812. STAT0   ENDP
  4813.  
  4814. ; Print information on the baud rate. [19a]
  4815.  
  4816. BAUDPRT    PROC     NEAR
  4817.     mov dx,offset b48st    ; Assume 4800 baud.
  4818.     cmp baud,B4800
  4819.     jnz bdprt0
  4820.     jmp bdprt2
  4821. bdprt0:    mov dx,offset b12st
  4822.     cmp baud,B1200
  4823.     jnz bdprt1
  4824.     jmp bdprt2
  4825. bdprt1:    mov dx,offset b18st
  4826.     cmp baud,B1800
  4827.     jz bdprt2
  4828.     mov dx,offset b24st
  4829.     cmp baud,B2400
  4830.     jz bdprt2
  4831.     mov dx,offset b96st
  4832.     cmp baud,B9600
  4833.     jz bdprt2
  4834.     mov dx,offset b03st
  4835. IF ibmpc OR L610
  4836.     jmp bdprt2
  4837. ENDIF
  4838. IF Z100
  4839.     cmp baud,B0300
  4840.     jz bdprt2
  4841.     mov dx,offset b04st
  4842.     cmp baud,B00455
  4843.     jz bdprt2
  4844.     mov dx,offset b05st
  4845.     cmp baud,B0050
  4846.     jz bdprt2
  4847.     mov dx,offset b07st
  4848.     cmp baud,b0075
  4849.     jz bdprt2
  4850.     mov dx,offset b11st
  4851.     cmp baud,B0110
  4852.     jz bdprt2
  4853.     mov dx,offset b13st
  4854.     cmp baud,B01345
  4855.     jz bdprt2
  4856.     mov dx,offset b15st
  4857.     cmp baud,B0150
  4858.     jz bdprt2
  4859.     mov dx,offset b06st
  4860.     cmp baud,B0600
  4861.     je bdprt2
  4862.     mov dx,offset b20st
  4863.     cmp baud,B2000
  4864.     jz bdprt2
  4865.     mov dx,offset b19st
  4866.     cmp baud,B19200
  4867.     jz bdprt2
  4868.     mov dx,offset b38st
  4869. ENDIF
  4870. bdprt2:    mov ah,prstr
  4871.     int dos
  4872.     ret
  4873. BAUDPRT    ENDP
  4874.  
  4875. ;       Utility routines
  4876.  
  4877. ; Jumping to this location is like retskp.  It assumes the instruction
  4878. ;   after the call is a jmp addr.
  4879.  
  4880. RSKP    PROC    NEAR
  4881.     pop bp
  4882.     add bp,3
  4883.     push bp
  4884.         ret
  4885. RSKP    ENDP
  4886.  
  4887. ; Jumping here is the same as a ret.
  4888.  
  4889. R       PROC    NEAR
  4890.         ret
  4891. R       ENDP
  4892.  
  4893. ; This routine prints the number in AX on the screen.  (Thanks to Jeff
  4894. ; Damens).  No longer used but keep around just in case.
  4895.  
  4896. ;NOUT    PROC    NEAR
  4897. ;        push bx                 ; Save some stuff.
  4898. ;        push cx
  4899. ;        push dx
  4900. ;        push ax
  4901. ;        mov bh,0                ; Don't print leading zeros.
  4902. ;        and ah,0F0H             ; Only want high order nibble.
  4903. ;        mov cl,4
  4904. ;    shr ah,cl
  4905. ;        call pdig               ; Print the digit.
  4906. ;        pop ax                  ; Restore argument.
  4907. ;        and ah,0FH              ; Just the low order nibble.
  4908. ;        call pdig
  4909. ;        mov ah,al
  4910. ;        and ah,0F0H             ; Only want high order nibble.
  4911. ;    mov cl,4
  4912. ;        shr ah,cl
  4913. ;        call pdig               ; Print the digit.
  4914. ;        mov ah,al
  4915. ;        and ah,0FH              ; Just the low order nibble.
  4916. ;        mov bh,0FFH             ; Make sure at least one zero is printed.
  4917. ;        call pdig
  4918. ;        pop dx                  ; Restore some stuff.
  4919. ;        pop cx
  4920. ;        pop bx
  4921. ;        ret
  4922. ;NOUT    ENDP
  4923.  
  4924.  ; Print the number in AX on the screen in decimal rather that hex. [19a]
  4925.  
  4926. NOUT     PROC    NEAR
  4927.     push ax
  4928.     push dx
  4929.     mov temp,10        ; Divide quotient by 10.
  4930.     cwd            ; Convert word to doubleword.
  4931.     div temp        ; AX <-- Quo, DX <-- Rem.
  4932.     cmp ax,0        ; Are we done?    
  4933.     jz nout0        ; Yes.
  4934.     call nout        ; If not, then recurse.
  4935. nout0:    add dl,'0'        ; Make it printable.
  4936.     mov temp,ax
  4937.     mov ah,conout
  4938.     int dos    
  4939.     mov ax,temp
  4940.     pop dx
  4941.     pop ax
  4942.     ret
  4943. NOUT    ENDP
  4944.  
  4945.        ; print the digit in register AH
  4946.  
  4947. PDIG    PROC    NEAR
  4948.         push ax                 ; Save it.
  4949.         cmp ah,0
  4950.         jne pdig2
  4951.         cmp bh,0
  4952.         jne pdig2
  4953.         pop ax
  4954.         ret
  4955. pdig2:  mov bh,0FFH             ; Set the print zero flag.
  4956.         cmp ah,10               ; Do we use digits or a-f?
  4957.         jl usedig               ; Digit.
  4958.         add ah,'A'-10           ; Compute digit
  4959.         jmp havdig              ; and proceed.
  4960. usedig: add ah,'0'              ; Convert to digit
  4961. havdig: mov dl,ah
  4962.         mov ah,conout
  4963.         int dos
  4964.         pop ax
  4965.         ret
  4966. PDIG    ENDP
  4967.  
  4968.  
  4969. ;       This set of routines provides a user oriented way of parsing
  4970. ;       commands.  It is similar to that of the COMND JSYS in TOPS-20.
  4971.  
  4972.  
  4973. ;       This routine prints the prompt in DE and specifies the reparse
  4974. ;       address.
  4975.  
  4976. PROMPT    PROC  NEAR
  4977.     pop bx                  ; Get the return address.
  4978.         push bx                 ; Put it on the stack again.
  4979.         mov cmrprs,bx           ; Save as addr to go to on reparse.
  4980.         mov bx,0                        ; Clear out register.
  4981.         add bx,sp               ; Get the present stack pointer.
  4982.         mov cmostp,bx           ; Save for later restoral.
  4983.         mov cmprmp,dx           ; Save pointer to the prompt.
  4984.         mov bx,offset cmdbuf
  4985.         mov cmcptr,bx           ; Initialize the command pointer.
  4986.         mov cmdptr,bx
  4987.         mov ah,0
  4988.         mov cmaflg,ah           ; Zero the flags.
  4989.         mov cmccnt,ah
  4990.         mov cmsflg,0FFH
  4991.         mov ah,prstr
  4992.         mov dx,offset cmcrlf
  4993.         int dos
  4994.         mov ah,prstr            ; Print the prompt.
  4995.         mov dx,cmprmp
  4996.         int dos
  4997.         ret
  4998. PROMPT    ENDP
  4999.  
  5000. ;       This address is jumped to on reparse.
  5001.  
  5002. PARSE    PROC NEAR 
  5003. repars: mov sp,cmostp           ; new sp <-- old sp
  5004.         mov bx,offset cmdbuf
  5005.         mov cmdptr,bx
  5006.         mov ah,0FFH
  5007.         mov cmsflg,ah
  5008.         mov bx,cmrprs           ; Get the reparse address.
  5009.         call bx                 ; Go there.
  5010.  
  5011. ;       This address can be jumped to on a parsing error.
  5012.  
  5013. prserr: mov sp,cmostp           ; Set new sp to old one.
  5014.         mov bx,offset cmdbuf
  5015.         mov cmcptr,bx           ; Initialize the command pointer.
  5016.         mov cmdptr,bx
  5017.         mov ah,0
  5018.         mov cmaflg,ah           ; Zero the flags.
  5019.         mov cmccnt,ah
  5020.         mov cmsflg,0FFH
  5021.         mov ah,prstr
  5022.         mov dx,offset cmcrlf
  5023.         int dos
  5024.         mov ah,prstr            ; Print the prompt.
  5025.         mov dx,cmprmp           ; Get the prompt.
  5026.         int dos
  5027. ; Instead return to before the prompt call.
  5028.         mov bx,cmrprs
  5029.         call bx
  5030. PARSE    ENDP
  5031.  
  5032. ;       This routine parses the specified function in AH. Any additional
  5033. ;       information is in DX and BX.
  5034. ;       Returns +1 on success
  5035. ;               +4 on failure (assumes a JMP follows the call)
  5036.  
  5037. CMND    PROC NEAR
  5038. comnd:  mov cmstat,ah           ; Save what we are presently parsing.
  5039.         call cminbf             ; Get chars until an action or a erase char.
  5040.     mov ah,cmstat        ; Restore 'ah' for upcoming checks.
  5041.         cmp ah,cmcfm            ; Parse a confirm?
  5042.         jz cmcfrm               ; Go get one.
  5043.         cmp ah,cmkey            ; Parse a keyword?
  5044.     jnz cm1
  5045.         jmp cmkeyw               ; Try and get one.
  5046. cm1:    cmp ah,cmifi        ; Parse an input file spec?
  5047.     jnz cm2
  5048.     jmp cmifil        ; Go get one.
  5049. cm2:    cmp ah,cmofi        ; Output file spec?
  5050.     jnz cm3
  5051.     jmp cmofil        ; Go get one.
  5052. cm3:    cmp ah,cmtxt        ; Parse arbitrary text.   [8]
  5053.     jnz cm4
  5054.     jmp cmtext
  5055. cm4:    mov ah,prstr        ; Else give error.
  5056.     mov dx,offset cmer00    ; "?Unrecognized COMND call"
  5057.     int dos
  5058.     ret
  5059.  
  5060. ; This routine gets a confirm.
  5061.  
  5062. cmcfrm: call cmgtch        ; Get a char.
  5063.     cmp ah,0        ; Is it negative (a terminator; a space or
  5064.                 ; a tab will not be returned here as they
  5065.                 ; will be seen as leading white space.)
  5066.         js cmcfr0
  5067.         ret                     ; If not, return failure.
  5068. cmcfr0: and ah,7FH                      ; Turn off the minus bit.
  5069.         cmp ah,esc                      ; Is it an escape?
  5070.         jne cmcfr2
  5071.         mov ah,conout
  5072.         mov dl,bell             ; Get a bell.
  5073.         int dos
  5074.         mov ah,0
  5075.         mov cmaflg,ah           ; Turn off the action flag.
  5076.         mov bx,cmcptr           ; Move the pointer to before thee scape.
  5077.         dec bx
  5078.         mov cmcptr,bx
  5079.         mov cmdptr,bx
  5080.         dec cmccnt              ; Decremrnt the char count.
  5081.         jmp cmcfrm              ; Try again.
  5082. cmcfr2: cmp ah,'?'                      ; Curious?
  5083.         jne cmcfr3
  5084.         mov ah,prstr            ; Print something useful.
  5085.         mov dx,offset cmin00
  5086.         int dos
  5087.         mov ah,prstr
  5088.         mov dx,offset cmcrlf            ; Print a crlf.
  5089.         int dos
  5090.         mov ah,prstr
  5091.         mov dx,cmprmp           ; Reprint the prompt.
  5092.         int dos
  5093.         mov bx,cmdptr           ; Get the pointer into the buffer.
  5094.         mov ah,'$'              ; Put a $ there for printing.
  5095.         mov [bx],ah
  5096.         mov bx,cmcptr
  5097.         dec bx                  ; Decrement & save the buffer pointer.
  5098.         mov  cmcptr,bx
  5099.         mov ah,prstr
  5100.         mov dx,offset cmdbuf
  5101.         int dos
  5102.         mov ah,0                        ; Turn off the action flag.
  5103.         mov cmaflg,ah
  5104.         jmp repars              ; Reparse everything.
  5105.  
  5106. cmcfr3: cmp ah,ff                       ; Is it a form feed?
  5107.         jne cmcfr4
  5108.         call cmblnk             ; If so blank the screen.
  5109. cmcfr4: jmp rskp
  5110.  
  5111. ;       This routine parses a keyword from the table pointed
  5112. ;       to in DX.  The format of the table is as follows:
  5113. ;
  5114. ;       addr:   db      n       ; Where n is the # of entries in the table.
  5115. ;               db      m       ; M is the size of the keyword.
  5116. ;               db      'string$' ; Where string is the keyword.
  5117. ;               dw      ab      ; Where ab is data to be returned.
  5118. ;
  5119. ;       The keywords must be in alphabetical order.
  5120.  
  5121.  
  5122. cmkeyw: mov cmhlp,bx            ; Save the help.
  5123.         mov cmptab,dx           ; Save the beginning of keyword table.
  5124.         mov bx,dx
  5125.         mov ch,[bx]                     ; Get number of entries in table.
  5126.         inc bx
  5127.     mov dx,cmdptr        ; Save command pointer.
  5128.     mov cmsptr,dx        ; Save pointer's here.
  5129. cmky1:  cmp ch,0                ; Any commands left to check?
  5130.         jne cmky2
  5131. ;    mov ah,prstr        ; [19e]
  5132. ;    mov dx,offset cmer04    ; Complain.   [1] [19e]
  5133. ;    int dos            ; [19e]
  5134.         ret                     ; Fail if not.
  5135. cmky2:  dec ch
  5136.     mov cl,0        ; Keep track of how many chars read in so far.
  5137.         call cmgtch             ; Get a char.
  5138.         cmp ah,0                ; Do we have a terminator?
  5139.         jns cmky2x 
  5140.     jmp cmky4               ; Negative number means we do.
  5141. cmky2x: inc bx                  ; Point to first letter of keyword.
  5142.     inc cl            ; Read in another char.
  5143.         mov al,[bx]                   
  5144.         cmp ah,'a'              ; Less than a?
  5145.         jl cmky21               ; If so, don't capitalize.
  5146.         cmp ah,'z'+1            ; More than z?
  5147.         jns cmky21
  5148.         and ah,137O             ; Capitalize the letter.
  5149. cmky21: cmp ah,al
  5150.     je cmky3
  5151.     jg cmky2y
  5152.         jmp cmky41              ; Fail if ah preceeds al alphabetically.
  5153. cmky2y: jmp cmky6               ; Not this keyword - try the next.
  5154. cmky3:  inc bx                  ; We match here, how 'bout next char?
  5155.         mov al,[bx]
  5156.         cmp al,'$'               ; End of keyword?
  5157.     jne cmky3x
  5158.         jmp cmky7                ; Succeed.
  5159. cmky3x:    mov dl,al        ; Save al's char here.
  5160.         call cmgtch
  5161.     inc cl            ; Read in another char.
  5162.     mov al,dl
  5163.     cmp ah,'a'
  5164.     jl cmky31
  5165.     cmp ah,'z'+1
  5166.     jns cmky31
  5167.     and ah,137O
  5168. cmky31: cmp ah,9BH        ; Escape Recognition (escape w/minus bit on)?
  5169.     je cmky3y
  5170.     cmp ah,0BFH        ; A question mark?    [3]
  5171.     je cmky3y
  5172.     cmp ah,0A0H        ; A space?
  5173.     je cmky3y
  5174.     cmp ah,8DH        ; Carriage return?
  5175.     je cmky3y
  5176.     jmp cmky38
  5177. cmky3y:    mov cmkptr,bx        ; Save bx here.
  5178.     mov cmsiz,cx        ; Save size info.
  5179.     mov cmchr,ah        ; Save char for latter.
  5180.     call cmambg        ; See if input is ambiguous or not.
  5181.      jmp cmky32        ; Succeeded (not ambiguous).
  5182.     mov ah,cmchr
  5183.     cmp ah,9BH        ; Escape?
  5184.     je cmky3z
  5185.     jmp cmky41        ; Fail.
  5186. cmky3z:    mov ah,conout        ; Else, ring a bell.
  5187.     mov dl,bell
  5188.     int dos
  5189.     mov bx,cmcptr        ; Move pointer to before the escape.
  5190.     dec bx
  5191.     mov cmcptr,bx
  5192.     mov cmdptr,bx
  5193.     dec cmccnt        ; Decrement char count.
  5194.     mov bx,cmkptr        ; Failed - pretend user never typed ....
  5195.     mov cx,cmsiz        ; ... in a char.
  5196.     dec cl            ; Don't count the escape.
  5197.     dec bx
  5198.     mov cmaflg,0        ; Reset the action flag.
  5199.     jmp cmky3        ; Keep checking.
  5200. cmky32: mov cx,cmsiz        ; Restore info.
  5201.     mov bx,cmkptr        ; Our place in the keyword table.
  5202.     cmp cmchr,0A0H        ; Space?
  5203.     je cmky35
  5204.     cmp cmchr,0BFH        ; Question mark?     [3]
  5205.     je cmky35
  5206.     cmp cmchr,8DH        ; Carriage return?
  5207.     je cmky35
  5208.     dec cmcptr        ; Pointer into buffer of input.
  5209.     mov dx,cmcptr
  5210. cmky33:    mov ah,[bx]        ; Get next char in keyword.
  5211.     cmp ah,'$'        ; Are we done yet?
  5212.     jz cmky34
  5213.     mov di,dx
  5214.     mov [di],ah
  5215.     inc bx
  5216.     inc dx
  5217.     inc cmccnt
  5218.     jmp cmky33
  5219. cmky34:    mov ah,' '
  5220.     mov di,dx
  5221.     mov [di],ah        ; Put a blank in the buffer.
  5222.     inc dx
  5223.     mov cx,cmcptr        ; Remember where we were (for printing below).
  5224.     mov cmcptr,dx        ; Update our pointers.
  5225.     mov cmdptr,dx
  5226.     mov ah,'$'
  5227.     mov di,dx
  5228.     mov [di],ah        ; Add '$' for printing.
  5229.     mov ah,prstr
  5230.     mov dx,cx        ; Point to beginning of filled in data.
  5231.     int dos
  5232.     inc bx            ; Point to address we'll need.
  5233.     mov bx,[bx]
  5234.     mov cmaflg,0         ; Turn off action flag.
  5235.     jmp rskp
  5236.  
  5237. cmky35:    inc bx
  5238.     mov ah,[bx]        ; Find end of keyword. 
  5239.     cmp ah,'$'
  5240.     jne cmky35    
  5241.     inc bx
  5242.     mov bx,[bx]        ; Address of next routine to call.
  5243. ;    mov cmaflg,0        ; Zero the action flag.
  5244.     jmp rskp
  5245.  
  5246. cmky38:    cmp ah,al
  5247.         jne cmky6               ; Go to end of keyword and try next.
  5248.         jmp cmky3
  5249.            
  5250. cmky4:  and ah,7FH              ; Turn off minus bit.
  5251.         cmp ah,'?'              ; Need help?
  5252.         je cmky5
  5253.     cmp ah,' '        ; Just a space - no error.
  5254.     je cmky51
  5255.     cmp ah,cr
  5256.     je cmky51
  5257.     cmp ah,tab
  5258.     je cmky51 
  5259.     cmp ah,esc        ; Ignore escape?
  5260.     je cmky43
  5261. cmky41: mov ah,prstr
  5262.         mov dx,offset cmer03
  5263.         int dos
  5264.         jmp prserr              ; Parse error - give up.
  5265.  
  5266. cmky43:    mov ah,conout        ; Ring a bell.
  5267.     mov dl,bell
  5268.     int dos
  5269.     mov bx,cmcptr
  5270.     dec bx
  5271.     mov cmcptr,bx
  5272.     mov cmdptr,bx
  5273.     dec cmccnt        ; Don't count the escape.
  5274.     mov cmaflg,0        ; Reset action flag.
  5275.     inc ch            ; Account for a previous 'dec'.
  5276.     jmp cmky1        ; Start over.
  5277.  
  5278. cmky5:  mov ah,prstr
  5279.         mov dx,cmhlp            ; Print the help text.
  5280.         int dos
  5281.     mov dx,offset crlf
  5282.     int dos
  5283.     mov dx,offset kerm
  5284.     int dos
  5285.     mov bx,cmdptr        ; Get pointer into buffer.
  5286.     mov al,'$'
  5287.     mov [bx],al        ; Add dollar sign for printing.
  5288.     mov dx,offset cmdbuf
  5289.     int dos
  5290.     dec cmcptr        ; Don't keep it in the buffer.
  5291.     dec cmccnt        ; Don't conut it.
  5292.     mov cmaflg,0            ; Turn off the action flag.
  5293.         jmp repars
  5294.  
  5295. cmky51:    jmp prserr
  5296.  
  5297. cmky6:  inc bx                  ; Find end of keyword.
  5298.         mov al,[bx]
  5299.         cmp al,'$'
  5300.         jne cmky6             
  5301.         inc bx                  ; Beginning of next command.
  5302.         inc bx
  5303.         inc bx
  5304.     mov dx,cmsptr        ; Get old cmdptr.
  5305.     mov cmdptr,dx        ; Restore.
  5306.     mov cmsflg,0FFH
  5307.         jmp cmky1               ; Keep trying.
  5308.  
  5309. cmky7:  call cmgtch             ; Get char.
  5310.     cmp ah,0
  5311.     js cmky71        ; Ok if a terminator.
  5312.         dec bx
  5313.         jmp cmky6               ; No match - try next keyword.
  5314. cmky71: inc bx                  ; Get necessary data.
  5315.         mov bx,[bx]
  5316.     cmp ah,9BH        ; An escape?
  5317.     jne cmky72
  5318.     mov ah,prstr
  5319.     mov dx,offset prsp      ; Print a space.
  5320.     int dos
  5321.     mov di,cmcptr
  5322.     dec di
  5323.     mov ah,20H
  5324.     mov [di],ah        ; Replace escape char with space.
  5325.     mov cmaflg,0
  5326.     mov cmsflg,0FFH        ; Pretend they typed a space.
  5327. cmky72: jmp rskp
  5328.  
  5329. ; See if keyword is unambiguous or not from what the user has typed in.
  5330.  
  5331. cmambg:    cmp ch,0        ; Any keywords left to check?
  5332.     jne cmamb0
  5333.     ret            ; If not then not ambiguous.
  5334. cmamb0:    inc bx            ; Go to end of keyword ...
  5335.     mov al,[bx]        ; So we can check the next one.
  5336.     cmp al,'$'
  5337.     jne cmamb0
  5338.     add bx,4        ; Point to start of next keyword.
  5339.     dec cl            ; Don't count escape.
  5340.     mov dx,cmsptr        ; Buffer with input typed by user.
  5341. cmamb1:    mov ah,[bx]        ; Keyword char.    
  5342.     mov di,dx
  5343.     mov al,[di]        ; Input char.
  5344.     cmp al,'a'        ; Do capitalizing.
  5345.     jl cmam11
  5346.     cmp al,'z'+1
  5347.     jns cmam11
  5348.     and al,137O
  5349. cmam11:    cmp ah,al        ; Keyword bigger than input (alphabetically)?
  5350.     jle cmamb2        ; No - keep checking.
  5351.     ret            ; Yes - not ambiguous.
  5352. cmamb2:    inc bx            ; Advance one char.
  5353.     inc dx
  5354.     dec cl
  5355.     jnz cmamb1
  5356.     jmp rskp        ; Fail - it's ambiguous.
  5357.  
  5358. cmifil: mov bx,dx               ; Get the fcb address in bx.
  5359.         mov cmfcb,bx            ; Save it.
  5360.         mov ch,0                ; Initialize char count.
  5361.         mov ah,0
  5362.         mov [bx],ah                     ; Set the drive to default to current.
  5363.     inc bx
  5364.         mov cmfcb2,bx
  5365.         mov cl,' '
  5366. cmifi0: mov [bx],cl                     ; Blank the FCB.
  5367.         inc bx
  5368.         inc ah
  5369.         cmp ah,0BH                      ; Twelve?
  5370.         jl cmifi0
  5371. cmifi1: call cmgtch             ; Get another char.
  5372.         cmp ah,0                        ; Is it an action character.
  5373.         jns cmifi2
  5374.         and ah,7FH                      ; Turn off the action bit.
  5375.         cmp ah,'?'                      ; A question mark?
  5376.         jne cmif12
  5377.         mov al,0
  5378.         mov cmaflg,al           ; Blank the action flag.
  5379.         dec cmcptr           ; Decrement the buffer pointer.
  5380.     dec cmccnt        ; Decrement count.
  5381. ;        jmp cmifi8              ; Treat like any other character.
  5382.     mov ah,prstr
  5383.     mov dx,offset filhlp    ; Help  message.
  5384.     int dos
  5385.     mov dx,offset crlf
  5386.     int dos
  5387.     mov dx,offset kerm
  5388.     int dos
  5389.     mov bx,cmdptr
  5390.     mov al,'$'
  5391.     mov [bx],al        ; Put in dollar sign for printing.
  5392.     mov dx,offset cmdbuf
  5393.     int dos
  5394.     jmp repars
  5395. cmif12: cmp ah,esc                      ; An escape?
  5396.         jne cmif13
  5397.         mov ah,0
  5398.         mov cmaflg,ah           ; Turn off the action flag.
  5399.         mov ah,conout
  5400.         mov dl,bell
  5401.         int dos         ; Ring the bell.
  5402.         mov bx,cmcptr           ; Move the pointer to before the escape.
  5403.         dec bx
  5404.         mov cmcptr,bx
  5405.         mov cmdptr,bx
  5406.         dec cmccnt              ; Decrement char count.
  5407.         jmp repars
  5408. cmif13: mov ah,ch                       ; It must be a terminator.
  5409.         cmp ah,0                        ; Test the length of the file name.
  5410.     jnz cmf3x
  5411.         jmp cmifi9               ; If zero complain.
  5412. cmf3x:  cmp ah,0DH
  5413.         js cmf3y
  5414.     jmp cmifi9              ; If too long complain.
  5415. cmf3y:  jmp rskp                ; Otherwise we have succeeded.
  5416. cmifi2: cmp ah,'.'
  5417.         jne cmifi3
  5418.         inc ch
  5419.         mov ah,ch
  5420.         cmp ah,1H                       ; Any chars yet?
  5421.           jnz cmf2x
  5422.     jmp cmifi9               ; No, give error.
  5423. cmf2x:  cmp ah,0AH                      ; Tenth char?
  5424.           js cmf2y
  5425.     jmp cmifi9              ; Past it, give an error.
  5426. cmf2y:  mov dl,9H
  5427.         mov dh,0
  5428.         mov bx,cmfcb
  5429.         add bx,dx               ; Point to file type field.
  5430.         mov cmfcb2,bx
  5431.         mov ch,9H               ; Say we've gotten nine.
  5432.         jmp cmifi1              ; Get the next char.
  5433. cmifi3: cmp ah,':'
  5434.         jne cmifi4
  5435.         inc ch
  5436.         cmp ch,2H                       ; Is it in right place for a drive?
  5437.     je cmif3x
  5438.         jmp cmifi9              ; If not, complain.
  5439. cmif3x: mov ch,0        ; Reset char count.
  5440.     mov bx,cmfcb2
  5441.     sub bx,1
  5442.         mov ah,[bx]                     ; Get the drive name.
  5443.         sub ah,'@'              ; Get the drive number.
  5444.     mov cmfcb2,bx
  5445.      mov bx,cmfcb
  5446.         mov [bx],ah                     ; Put it in the fcb.
  5447.         jmp cmifi1
  5448. cmifi4: cmp ah,'*'
  5449.         jne cmifi7
  5450.         mov ah,ch
  5451.         cmp ah,8H                       ; Is this in the name or type field?
  5452.         jz cmifi9               ; If its where the dot should be give up.
  5453.         jns cmifi5              ; Type.
  5454.         mov cl,8H               ; Eight chars.
  5455.         jmp cmifi6
  5456. cmifi5: mov cl,0CH              ; Three chars.
  5457. cmifi6: mov wldflg,0FFH        ; Remember we had a wildcard.
  5458.     mov bx,cmfcb2           ; Get a pointer into the FCB.
  5459.         mov ah,'?'
  5460.         mov [bx],ah                     ; Put a question mark in.
  5461.         inc bx
  5462.         mov cmfcb2,bx
  5463.         inc ch
  5464.         mov ah,ch
  5465.         cmp ah,cl
  5466.         jl cmifi6               ; Go fill in another.
  5467.         jmp cmifi1              ; Get the next char.
  5468. cmifi7: cmp ah,03DH        ; Equals sign (wildcard)?
  5469.     jne cmif7x
  5470.     mov ah,'?'
  5471.     mov wldflg,0FFH        ; Say we have a wildcard.
  5472.     jmp cmifi8        ; Put into FCB.
  5473. cmif7x:    cmp ah,'0'
  5474.         jl cmif8x
  5475.         cmp ah,'z'+1
  5476.         jns cmif8x
  5477.         cmp ah,'A'                      ; Don't capitalize non-alphabetics.
  5478.         jl cmifi8
  5479.         and ah,137O             ; Capitalize.
  5480. cmifi8: mov bx,cmfcb2           ; Get the pointer into the FCB.
  5481.         mov [bx],ah                     ; Put the char there.
  5482.         inc bx
  5483.         mov cmfcb2,bx
  5484.         inc ch
  5485.         jmp cmifi1
  5486.  
  5487. cmif8x:    push es
  5488.     mov cx,ds
  5489.     mov es,cx        ; Scan uses ES register.
  5490.     mov di,offset spchar    ; Special chars.
  5491.     mov cx,20        ; Twenty of them.
  5492.     mov al,ah        ; Char is in al.
  5493.     repnz scasb        ; Search string for input char.
  5494.     cmp cx,0        ; Was it there?
  5495.     pop es
  5496.     jnz cmifi8
  5497.  
  5498. cmifi9: mov ah,prstr
  5499.         mov dx,offset cmer02
  5500.         int dos
  5501.         ret
  5502.  
  5503. cmofil: jmp cmifil              ; For now, the same as CMIFI.
  5504.  
  5505. ; Parse arbitrary text up to a CR.  Put chars into data buffer sent to
  5506. ; the host (pointed to by BX).   Return updated pointer in BX and 
  5507. ; input size in AH.
  5508.  
  5509. cmtext:    mov cmptab,bx        ; Save pointer to data buffer.   [8 start]
  5510.     mov cl,0        ; Init the char count.
  5511. cmtxt1:    call cmgtch        ; Get a char.
  5512.     cmp ah,0        ; Terminator?
  5513.     jns cmtxt5        ; Nope, put into the buffer.
  5514.     and ah,07FH
  5515.     cmp ah,esc        ; An escape?
  5516.     jne cmtxt2
  5517.     mov ah,conout
  5518.     mov dl,bell        ; Ring a bell.
  5519.     int dos
  5520.     mov cmaflg,0        ; Reset action flag.
  5521.     dec cmcptr        ; Move pointer to before the escape.
  5522.     dec cmdptr
  5523.     dec cmccnt        ; Decrement count.
  5524.     jmp cmtxt1        ; Try again.
  5525. cmtxt2:    cmp ah,'?'        ; Asking a question?
  5526.     jz cmtxt3
  5527.     cmp ah,ff        ; Formfeed?
  5528.     jne cmtx2x
  5529.     call cmblnk
  5530. cmtx2x: mov ah,cl        ; Return count in AH.
  5531.     mov bx,cmptab        ; Return updated pointer.
  5532.     jmp rskp
  5533. cmtxt3:    mov cmaflg,0        ; Reset action flag to zero.
  5534. cmtxt5: inc cl            ; Increment the count.
  5535.     mov bx,cmptab        ; Pointer into destination array.
  5536.     mov [bx],ah        ; Put char into the buffer.
  5537.     inc bx
  5538.     mov cmptab,bx
  5539.     jmp cmtxt1                    ; [8 end]
  5540.  
  5541. cminbf: push dx
  5542.         push bx
  5543.         mov cx,dx               ; Save value here too.
  5544.         mov ah,cmaflg           ; Is the action char flag set?
  5545.         cmp ah,0
  5546.     je cminb1
  5547.         jmp cminb9              ; If so get no more chars.
  5548. cminb1: inc cmccnt              ; Increment the char count.
  5549.         mov ah,conin            ; Get a char.
  5550.         int dos
  5551.     mov ah,al        ; Keep char in 'ah'.
  5552.         mov bx,cmcptr           ; Get the pointer into the buffer.
  5553.         mov [bx],ah                     ; Put it in the buffer.
  5554.         inc bx
  5555.         mov cmcptr,bx
  5556.         cmp ah,25O                      ; Is it a ^U?
  5557.         jne cminb2
  5558. cmnb12: mov ah,prstr
  5559.     mov dx,offset clrlin
  5560.     int dos
  5561. IF ibmpc OR L610
  5562.     mov ax,0920H               ; Write spaces.
  5563.         mov bx,7                ; Clear the line.
  5564.     mov cx,80
  5565.         int bios
  5566. ENDIF
  5567.         mov ah,prstr
  5568.         mov dx,cmprmp           ; Print the prompt.
  5569.         int dos
  5570.         mov bx,offset cmdbuf
  5571.         mov cmcptr,bx           ; Reset the point to the start.
  5572.     mov cmccnt,0               ; Zero the count.
  5573.         mov dx,cx               ; Preserve original value of dx.
  5574.         jmp repars              ; Go start over.
  5575. cminb2: cmp ah,10O                      ; Or backspace?
  5576.         jz cminb3
  5577.         cmp ah,del                      ; Delete?
  5578.         jne cminb4
  5579.         mov ah,prstr            ; Print the delete string.
  5580.         mov dx,offset delstr
  5581.         int dos
  5582. cminb3: mov ah,cmccnt           ; Decrement the char count by two.
  5583.         dec ah
  5584.         dec ah
  5585.         cmp ah,0                        ; Have we gone too far?
  5586.         jns cmnb32              ; If not proceed.
  5587.         mov ah,conout           ; Ring the bell.
  5588.         mov dl,bell
  5589.         int dos
  5590.         jmp cmnb12              ; Go reprint prompt and reparse.
  5591. cmnb32: mov cmccnt,ah           ; Save the new char count.
  5592.         mov ah,prstr            ; Erase the character.
  5593.         mov dx,offset clrspc
  5594.         int dos
  5595.         mov bx,cmcptr           ; Get the pointer into the buffer.
  5596.         dec bx                  ; Back up in the buffer.
  5597.         dec bx
  5598.         mov cmcptr,bx
  5599.         jmp repars              ; Go reparse everything.
  5600. cminb4: cmp ah,'?'                      ; Is it a question mark.
  5601.         jz cminb6
  5602.         cmp ah,esc                      ; Is it an escape?
  5603.         jz cminb8
  5604.         cmp ah,cr                       ; Is it a carriage return?
  5605.         jz cminb5
  5606.         cmp ah,lf                       ; Is it a line feed?
  5607.         jz cminb5
  5608.         cmp ah,ff                       ; Is it a formfeed?
  5609.         jne cminb7
  5610.         call cmblnk
  5611.     call locate
  5612. cminb5: mov ah,cmccnt           ; Have we parsed any chars yet?
  5613.         cmp ah,1
  5614.     jnz cminb6
  5615.         jmp prserr               ; If not, just start over.
  5616. cminb6: mov ah,0FFH             ; Set the action flag.
  5617.         mov cmaflg,ah
  5618.         jmp cminb9
  5619. cminb7: jmp cminb1        ; Get another char.
  5620.  
  5621. cminb8: mov ah,prstr        ; Don't print the escape char.
  5622.     mov dx,offset escspc
  5623.     int dos
  5624.     jmp cminb6
  5625.  
  5626. cminb9: pop bx
  5627.         pop dx
  5628.         ret
  5629.  
  5630. cmgtch: push cx
  5631.     push bx
  5632.         push dx
  5633. cmgtc1: mov ah,cmaflg
  5634.         cmp ah,0                        ; Is it set.
  5635.         jne cmgt10
  5636.         call cminbf             ; If the action char flag is not set get more.
  5637. cmgt10: mov bx,cmdptr           ; Get a pointer into the buffer.
  5638.         mov ah,[bx]                     ; Get the next char.
  5639.         inc bx
  5640.         mov cmdptr,bx
  5641.         cmp ah,' '                      ; Is it a space?
  5642.         jz cmgtc2
  5643.         cmp ah,tab                      ; Or a tab?
  5644.         jne cmgtc3
  5645. cmgtc2: mov ah,cmsflg           ; Get the space flag.
  5646.         cmp ah,0                        ; Was the last char a space?
  5647.         jne cmgtc1              ; Yes, get another char.
  5648.         mov ah,0FFH             ; Set the space flag.
  5649.         mov cmsflg,ah
  5650.         mov ah,' '
  5651.         pop dx
  5652.         pop bx
  5653.         jmp cmgtc5
  5654. cmgtc3: mov al,0
  5655.         mov cmsflg,al           ; Zero the space flag.
  5656.         pop dx
  5657.         pop bx
  5658.         cmp ah,esc
  5659.         jz cmgtc5
  5660.         cmp ah,'?'                      ; Is the user curious?
  5661.         jz cmgtc4
  5662.         cmp ah,cr
  5663.         jz cmgtc4
  5664.         cmp ah,lf
  5665.         jz cmgtc4
  5666.     cmp ah,ff
  5667.     je cmgtc4
  5668.     pop cx
  5669.     ret            ; Not an action char, just return.
  5670. cmgtc4: dec cmdptr
  5671. cmgtc5: or ah,80H        ; Make the char negative to indicate
  5672.     pop cx
  5673.     ret            ; it is a terminator.
  5674. CMND    ENDP
  5675.  
  5676. ; This routine blanks the screen.
  5677.  
  5678. CMBLNK    PROC    NEAR        ; This is stolen from the IBM example.
  5679. IF ibmpc OR L610
  5680.     mov cx,0
  5681.     mov dx,184FH
  5682.     mov bh,7
  5683.     mov ax,600H
  5684.     int bios
  5685. ENDIF
  5686. IF Z100
  5687.     mov ah,prstr        ; Get the function code
  5688.     mov dx,offset clrscr    ; Want to clear the screen
  5689.     int dos            ; Do it
  5690. ENDIF
  5691.     ret
  5692. CMBLNK  ENDP
  5693.  
  5694. ; Cursor control.
  5695.  
  5696. LOCATE  PROC    NEAR
  5697. IF ibmpc OR L610
  5698.     mov dx,0        ; Go to top left corner of screen.
  5699.     mov bh,0
  5700.     mov ah,2
  5701.     int bios
  5702. ENDIF
  5703. IF Z100
  5704.     mov ah,prstr        ; Function is print string
  5705.     mov dx,offset homcur    ; Home cursor
  5706.     int dos            ; do it
  5707. ENDIF
  5708.     ret
  5709. LOCATE  ENDP
  5710.  
  5711.  
  5712. MAIN     ENDS            ; End of code section.
  5713. ;
  5714. ;
  5715. ;
  5716. ;
  5717. ;
  5718. ;
  5719. ;
  5720.     %OUT * End Of Phase *
  5721.     END   START  
  5722. ; This here code is here to test a problem with end of file
  5723.