home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / victor9000cpm / viccpm.a86 next >
Text File  |  1988-08-23  |  165KB  |  4,987 lines

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