home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / tandy2000.zip / ta2000.asm next >
Assembly Source File  |  1984-02-16  |  214KB  |  5,995 lines

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