home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / msxhpx.asm < prev    next >
Assembly Source File  |  2020-01-01  |  71KB  |  2,522 lines

  1.     name msxhpx
  2. ; File MSXHPX.ASM
  3.     include mssdef.h
  4. ;       Copyright (C) 1982,1991, Trustees of Columbia University in the
  5. ;       City of New York.  Permission is granted to any individual or
  6. ;       institution to use, copy, or redistribute this software as long as
  7. ;       it is not sold for profit and this copyright notice is retained.
  8. ; Edit history:
  9. ; 2 March 1991 version 3.10
  10. ; 2 Dec 2, 1990 Modify serhng so hangup works on serial port in connect mode.
  11. ; Nov. 24, 1990. Reemove reference to prserr to make link happy.
  12. ; Last edit Aug. 17, 1990
  13. ; August 9, 1990. Fix klogon and klogof.
  14. ; July 1990. Put in correct delay times for breaks. Thanks to Fred Lipschultz.
  15. ; June 1990. Install screen save for HP 110 and fixup dial command.[jan]
  16. ; February 1990. Major rewrite. Fix up for tektronix grapahics and 3.0.
  17. ; John Nyenhuis, Purdue EE 317-494-3524 nyenhuis@ecn.purdue.edu
  18. ; Binary works on both 110 and Plus.
  19. ; Change naming of ports to serial, modem, and 82164A
  20. ; Read keyboard less often and use BIOS screen write on plus for speed.
  21. ; 1 July 1988 Version 2.31
  22. ; 1 Jan 1988 version 2.30
  23. ; 25 May 1987 Add keyboard translator, input translation, cleanups. [jrd]
  24. ; 1 Oct 86 Version 2.29a
  25. ; 30 Sept 1986 Reject DEL char at serial port reception level to avoid
  26. ;  problems when DEL is used as a filler char (by Emacs). [jrd]
  27. ; 28 Sept 1986 Revise procedure Term to permit capturing, printer ready
  28. ;  testing, debug display. Revised other port procedures slightly too;
  29. ;  especially to set port into binary mode via ioctl. [jrd]
  30. ; 22 Sept 1986 Add modifications from Mike Mellinger: outchr, serhng.
  31. ;   Introduce COM3 as additional choice. Startup 8 bits, no parity. [jrd]
  32. ; 4 Sept 1986 Add Bob Goeke's change to move comms port table to a system
  33. ;   dependent module (typ msx---) to allow 3+ ports and localized idents. [jrd]
  34.  
  35. ; Date: 15 Oct 85
  36. ; HP Portable Kermit
  37. ;    for HP110 and HP Portable Plus
  38. ;    Port 1: Serial, Port 2: internal modem
  39. ;    Defaults: even parity, 1200 baud: serial, 1200 internal modem
  40. ;    Internal modem code only works on HP Portable Plus
  41. ;    15 Nov 85:
  42. ;       Added code to shut off serial port and modem when quitting Kermit
  43. ;    11 Jan 86;
  44. ;       change msdefs.h to mssdef.h for kermit 2.28 jrd
  45. ;
  46. ; Add global entry point vtstat for use by Status in mssset.
  47. ; Also trimmed off trailing commas in publics. Joe R. Doupnik 12 March 1986
  48. ; Add global procedures ihosts and ihostr to handle host initialization
  49. ; when packets are to be sent or received by us,resp. 24 March 1986
  50. ; Add global procedure dtrlow (without worker serhng) to force DTR & RTS low
  51. ; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd]
  52. ; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
  53. ;   to a file. Just does a beep for now. 13 April 1986 [jrd]
  54. ; In proc Outchr add override of xon from chkxon sending routine.
  55. ;   This makes a hand typed Xoff supress the xon flow control character sent
  56. ;   automatically as the receiver buffer empties. 20 April 1986 [jrd]
  57. ; Fix port selector table, comptab, (from original version) to properly
  58. ;   hold port name AUX. 23 April 1986 [jrd]
  59. ;
  60. ;    Fixed error in resetting the serial port, 25 April 1986
  61. ;
  62.         page    80,132
  63.  
  64.  
  65. ; mov a string     all registers preserved
  66.    movsmac macro xsource,  xdestination, xlength
  67.     push cx
  68.     push di
  69.     push si
  70.     mov       si,offset xsource
  71.     mov       di, offset xdestination
  72.     mov       cx,xlength
  73.     cld              ; move forward
  74.     rep movsb          ; do the move
  75.     pop      si
  76.     pop      di
  77.     pop      cx
  78. endm
  79. writechar   macro saying
  80.     push  dx
  81.     push  ax
  82.     mov      ah,2
  83.     mov      dl,saying
  84.     int      dos
  85.     pop      ax
  86.     pop      dx
  87. endm
  88.  
  89. writestring   macro saying
  90.     push ax
  91.     push dx
  92.     mov  ah,prstr
  93.     mov  dx,offset saying
  94.     int  dos
  95.     pop  dx
  96.     pop  ax
  97.  endm
  98.  
  99. saveregs macro
  100.       pushf
  101.       push  ax
  102.       push  bx
  103.       push  cx
  104.       push  dx
  105.       push  es
  106.       push  di
  107.       push  si
  108.       push  ds
  109.       push  bp
  110. endm
  111.  
  112. restoreregs  macro
  113.      pop   bp
  114.      pop   ds
  115.      pop   si
  116.      pop   di
  117.      pop   es
  118.      pop   dx
  119.      pop   cx
  120.      pop   bx
  121.      pop   ax
  122.      popf
  123. endm
  124.  
  125. mul10  macro register  ; multiply register other then ax by 10
  126.     push ax
  127.     mov ax,register
  128.     mov temp1,ax
  129.     shl ax,1
  130.     shl ax,1
  131.     shl ax,1
  132.     add ax,temp1
  133.     add ax,temp1
  134.       mov temp1,ax
  135.     pop ax
  136.       mov register,temp1
  137. endm
  138.     
  139.   delay macro number
  140.    push ax
  141.    push cx
  142.    mov ax,number
  143.    call pcwait
  144.    pop cx
  145.    pop ax
  146.    endm
  147.  
  148.  
  149. ; structure for status information table sttab.
  150. stent    struc
  151. sttyp    dw  ?       ; type (actually routine to call)
  152. msg    dw  ?       ; message to print
  153. val2    dw  ?       ; needed value: another message, or tbl addr
  154. tstcel    dw  ?       ; address of cell to test, in data segment
  155. basval    dw  0       ; base value, if non-zero
  156. stent    ends
  157.  
  158.  
  159.  
  160. ;; below 40 publics are the minimum necessary
  161.        public  baudst,ihostr,bdtab,getbaud,chrout
  162.        public  pcwait,putmod,serrst,trnprs,prtchr
  163.        public  poscur,outchr,dtrlow,vts,puthlp
  164.        public    vtstat,coms,cquery,ctlu,shomodem
  165.        public  portval,getmodem,term,dumpscr,cmblnk
  166.        public  cquit,locate,clearl,machnam,lclini
  167.        public  sendbl,comptab,sendbr,clrmod,cstatus
  168.        public  termtb,serhng,clrbuf,beep, serini
  169. ;;additional system dependent publics
  170.     public    klogon,kdos,snull,klogof
  171.     public bigscreen        ; bigscreen=1 if it's big [jan]
  172.     public    termtog            ; toggle terminal types [jan]
  173.     public    kclrscn, ourhelp, getflgs, dial_number, sethpkey, setaltkey
  174.     public    setkeyboard, vtstbl, setchtab
  175.  
  176. false    equ    0
  177. true    equ    1
  178. instat    equ    6
  179. print_out equ    05h            ; dos function to print to printer
  180. prtscr    equ    80h            ; print screen pressed
  181. hpkeynum    equ  11
  182. altkeynum    equ  12
  183. tekonnum    equ  13
  184. tekoffnum    equ  14
  185.  
  186. data   segment public 'data'
  187.     extrn    flags:byte, trans:byte
  188.     extrn    dmpname:byte
  189.     extrn    kbdflg:byte, rxtable:byte
  190.     extrn    lclexit:word       ; call when quitting kermit
  191.     extrn    lclsusp:word       ; call when pushing to dos
  192.     extrn    lclrest:word       ; call when exiting from dos
  193.     extrn    tekflg:byte,denyflg:word
  194.     extrn    dosnum:word
  195.     extrn    repflg:byte, diskio:byte  ; for replay feature
  196.     extrn    kbdflg:byte  ;    in telnet 
  197.  
  198. ; hp110/ portable plus specific
  199. machnam db    'Can Not Identify Terminal ','$'  ; should never see this
  200. hp110_name db       'HP_110$'
  201. lenhp110_name equ   $-hp110_name
  202. plus_name   db 'HP_Portable_Plus$'
  203. lenplus_name equ $-plus_name
  204.  
  205. ; num_rows and bigscreen must be set by lclini everything else is
  206. ; determined by the program
  207. ;; everybody defaults to 110
  208. num_rows    dw      16        ; default
  209. bigscreen    db      1        ; 1 for plus 0 for 110
  210. graph_bytes    dw      25*60*8    ; size of graphics screen
  211.  
  212. erms20    db    cr,lf,'?Warning: System has no disk drives$'
  213. erms40    db    cr,lf,'?Warning: Unrecognized baud rate$'
  214. erms41    db    cr,lf,'?Warning: Cannot open com port$'
  215. erms50    db    cr,lf,'Error reading from device$'
  216. serierr db    cr,lf,'Can not initialize port $'
  217. write2err db    cr,lf,'Can not write to com port $'
  218. badbd    db    cr,lf,'Unimplemented baud rate$'
  219. badpar    db    cr,lf,'Unimplemented parity$'
  220. noimp    db    cr,lf,'Command not implemented.$'
  221. hngmsg    db    cr,lf,' The phone should have hungup.',cr,lf,'$'
  222. hnghlp    db    cr,lf,' The modem control lines DTR and RTS for the current'
  223.     db    ' port are forced low (off)'
  224.     db    cr,lf,' to hangup the phone. Normally, Kermit leaves them'
  225.     db    ' high (on) when it exits.'
  226.     db    cr,lf,'$'
  227. msmsg1    db    cr,lf,' Communications port is not ready.$'
  228. msmsg2    db    cr,lf,' Communications port is ready.$'
  229. rdbuf    db    80 dup (?)        ; temp buf
  230. shkmsg    db    'Not implemented.'
  231. shklen    equ    $-shkmsg
  232. baudstr db    'SB'            ; string used in setting baud rate
  233. baudx    db    0,';' ,'$'
  234. flo_str db    'C'            ; string used to set flow
  235. flo_x    db    '0',';','$'        ; 0=no flow 2=xon/xoff
  236. brk_on    db    'B1;'            ; start sending breaks
  237. brk_off db    'B0;'            ; stop sending breaks
  238. chk_msg db    0BFH,';'        ; check serial buffer
  239. ask_cursor    db escape,'[6n','$'
  240. badcursor     db 'Unable to get cursor position ',cr,lf,'$'
  241. ask_modem_status db 'MS;'
  242. transmiton    db 'Transmit On ',cr,lf,'$'
  243. offhook          db 'Modem is off hook ',cr,lf,'$'
  244. modemenabled       db 'Modem is Enabled  ',cr,lf,'$'
  245. dial_msg db    'MR;'
  246. $m0    db    'M0;SW0;P4;SS0;LI1;'
  247. len_$m0     equ $-$m0
  248. $m1    db    'M1;SW0;P4;SS0;LI1;'
  249. len_$m1     equ $-$m1
  250. $off_m    db    'C2;P0;SS0;SW1;M3;M5;'    ; turn off portable plus
  251. off_len equ    $-$off_m
  252. $off_m110  db  'C2;P0;SS0;SW1;MH;'    ; string to turn off 110 modem
  253. len$off_m110  equ $-$off_m110
  254. need_to_set_baud db  true           ; only set baud when needed
  255. ;;need_to_set_flow db  true         ; need to update flow control
  256. ;
  257. setktab db    0
  258. setkhlp db    0
  259. crlf    db    cr,lf,'$'
  260. delstr    db    BS,escape,'P','$'
  261. clrlin    db    cr,ESCAPE,'K$'
  262. clreol    db    ESCAPE,'K$'
  263. hpkey    db    escape,'&k0\$'        ; hp keyboard
  264. altkey    db    escape,'&k1\$'        ; alternate keyboard
  265. tekstatustxt db 'Tek Auto Entry: $'
  266. tekbyte db tekonnum
  267. keystatustxt db 'Keyboard: $'
  268. keyflg    db   altkeynum
  269. ; escape sequences for turning on the alpha display
  270. ; on the 110, we also need to load the character set
  271. ; id_terminal will decide which one to use
  272.  
  273. alpha_disp  db     escape,'[=8h',escape,'[10m','$','xxxxxxxxxxx','$'  ; default
  274. alpha_110  db    escape,'[=8h',escape,'[10m','$'     ; for 110
  275. lenalpha_110 equ $-alpha_110               ; Its length
  276. alpha_plus   db escape,'[=8h',escape,'*dK','$'               ; for plus
  277. lenalpha_plus    equ $-alpha_plus          ; Its length
  278. cursav        db    escape,'[s','$'        ; save the cursor
  279. curres        db    escape,'[u','$'        ; restore cursor
  280. curon        db    escape,'*dQ','$'       ; turn on cursor
  281. curoff        db    escape,'*dR','$'       ; turn off the cursor
  282. old_cursor  dw    ?         ; store alpha cursor position
  283. transfcn    db    escape,'&s0A$'     ; transmit functions,
  284. dialcode    db    32  ;  16 for pulse 32 for tone
  285. termidfail  db escape,'Kermit can not identify terminal type ',cr,lf,'$'
  286. ask_id        db    escape,'*s^','$'   ; is it 110 or plus
  287. dial_saying db 'Enter Number to dial ,=delay ;=cancel P=pulse T=tone.',cr,lf,'$'
  288.  
  289. rdbuffstrt  dw     ?   ; start of rdbuff for dial_number
  290. canceldial  db    'Dial Cancelled ',cr,lf,'$'
  291. modem_saying db     'Set port to internal modem before dialing ',cr,lf,'$'
  292. onhook_saying db 'Modem is already connected  ',cr,lf,'$'
  293. w_ioctlerr   db cr,lf,'Error in writing to ioctl  ',7,'$'
  294. r_ioctlerr   db cr,lf,'Error in reading ioctl ',7,'$'
  295. io_notready  db cr,lf,'Not ready to write to ioctl ','$'
  296. helpini         db cr,lf,'Press Extended f1 for help in connect mode ',cr,lf,'$'
  297. ourhelptxt   db cr,lf ,'Some Special Keys in Connect Mode: '
  298.          db cr,lf,'Menu clears screen'
  299.    db cr,lf,'User System toggles between alpha and tektronix screens. '
  300.    db cr,lf,'Extended B sends a break ','$'
  301. helpplus  db cr,lf, 'Extended = also clears the screen '
  302.   db cr,lf,'Extended - also toggles between alpha and tektronix screens','$'
  303. help110      db cr,lf, 'Press Extended D to dial a number ','$'
  304. helpend      db  cr,lf,cr,lf,'Press any key to return to connect mode','$'
  305. telflg    db    0        ; non-zero if we're a terminal
  306. xofsnt    db    0        ; Say if we sent an XOFF
  307. xofrcv    db    0        ; Say if we received an XOFF
  308. invseq    db    ESCAPE,'&dB$'    ; Reverse video
  309. nrmseq    db    ESCAPE,'&d@$'    ; Normal video
  310. ivlseq    db    80 dup (' '),cr,'$'    ; make line inverse video
  311. prthnd    dw    0        ; Port handle
  312. argadr    dw    ?        ; address of arg blk from msster.asm
  313. parmsk    db    ?        ; 8/7 bit parity mask, for reception
  314. flowoff db    ?        ; flow-off char, Xoff or null (if no flow)
  315. flowon    db    ?        ; flow-on char, Xon or null
  316. captrtn dw    ?        ; routine to call for captured output
  317. tempbuf dw    10 dup(?)
  318. prttab    dw    com1,com2,com3
  319. com1    db    'COM1',0
  320. com2    db    'COM1',0    ; this gets changed on plus
  321. com3    db    'COM2',0
  322. blank    db    ESCAPE,'H',ESCAPE,'J$'
  323. movcur    db    ESCAPE,'&a'
  324. colno    db    20 dup(?)
  325. ten    db    10
  326. temp    dw    0
  327. temp1    dw    0        ; Temporary storage
  328. temp2    dw    0        ; Temporary storage
  329. tempbyte db    0
  330.  
  331. ;;new stuff to scan escape sequences from comm port  [jan]
  332. stringtab     dw    tekst1,tekst2     ; strings for matching
  333.          dw    badst1,badst2
  334. numstrings    equ   4            ; number of strings to match
  335. disptab        dw    toteknoplay,totekplay      ; dispatch table
  336.         dw    ignoreall, ignoreall
  337. tekst1        db    escape,'[?38h',0    ;1st string to get into tek mode [jan]
  338. tekst2        db    escape,FF,0    ;2nd string to get into tek mode [jan]
  339.  
  340. badst1 db   escape,'[=8h',0        ; ignore alpha on sequence
  341. badst2 db   escape,'[=10h',0        ; ignore graph on sequence
  342.  
  343. stringchekbuff       db     16 dup (0)
  344. stringchekcnt       dw     0           ;characters already in buffer
  345. matchsofar    dw    false        ; no match yet
  346. match        dw    0
  347. playem        db    false        ;don't play back switch characters
  348. ; end of data for string scannine
  349. prtrdy           db   true         ; if false, we get out of connect mode
  350.  
  351. keydelay    dw    0
  352.  
  353. scrsavseg    dw  ?             ; segment of screen memory
  354. line_len    dw  ?             ; words in a line
  355. line_ofs    dw  ?             ; ofset between adjacent lines
  356. num_lines    dw  ?             ; number of lines in screen memory
  357.  
  358. ints_set       db    false         ; interrupts vectors set?
  359. need_break     db    false
  360. brk_int        equ  58h         ; break key interrupt
  361. savbrko        dw   ?             ; save offset of break interrupt
  362. savbrks        dw   ?             ; save segment of break interrupt
  363.  
  364. vtstbl    stent <srchkw,keystatustxt,termtb,keyflg> ; tell keyboard for status
  365.     stent <srchkw,tekstatustxt,termtb,tekbyte> ; tell keyboard for status
  366.     dw    0                ; end of table
  367.  
  368. ; Entries for choosing communications port. [19b]
  369. comptab db    3        ; 7 entries. Rewritten by [jrd]
  370.     mkeyw    'Serial',1
  371.     mkeyw    'Modem',2
  372.     mkeyw    '82164A',3         ; 3 is hpil
  373.  
  374. setchtab  db 1      ; set file character-set table
  375.     mkeyw  'CP437',437
  376.  
  377. termtb    db    6
  378.     mkeyw    'HP2621',ttgenrc
  379.     mkeyw    'Tek4010',tttek
  380.     mkeyw    'HpKeyBoard',hpkeynum
  381.     mkeyw    'AltKeyBoard',altkeynum
  382.     mkeyw    'EnableTek', tekonnum
  383.     mkeyw    'DisableTek',tekoffnum
  384.  
  385. defbaud equ  7                ; default baud rate
  386. port1    prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
  387. port2    prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
  388. port3    prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
  389. portval dw    port2            ; Default is to use port 1
  390.  
  391. bdtab    db    15            ; Baud rate table
  392.  
  393.     mkeyw    '50',0
  394.     mkeyw    '75',1
  395.     mkeyw    '110',2
  396.     mkeyw    '134',3
  397.     mkeyw    '150',4
  398.     mkeyw    '300',5
  399.     mkeyw    '600',6
  400.     mkeyw    '1200',7
  401.     mkeyw    '1800',8
  402.     mkeyw    '2400',9
  403.     mkeyw    '3600',10
  404.     mkeyw    '4800',11
  405.     mkeyw    '7200',12
  406.     mkeyw    '9600',13
  407.     mkeyw    '19200',14
  408. ourbdtab db '1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
  409.  
  410. ;    variables for serial interupt handler
  411.  
  412. source    db    260  DUP(?)  ; buffer for data from port
  413. bufout    dw    0        ; buffer removal pointer
  414. count    dw    0        ; number of chars in int buffer
  415. bufin    dw    0        ; buffer insertion pointer
  416. ; variable for fast write on plus
  417. plus_char  db 'R',0
  418.  
  419. ourarg    termarg <>
  420. asciitab  db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
  421.  
  422.  
  423. data   ends
  424.  
  425. code    segment public 'code'
  426.     extrn    comnd:near, dopar:near, atoi:near, prompt:near
  427.     extrn    sleep:near
  428.     extrn    tekcls:near
  429.     extrn    msuinit:near, keybd:near    ; in msuhpx
  430.     extrn    tekemu:near,tekini:near
  431.     extrn    sbrk:near            ; memory allocator
  432.     extrn    statc:near, srchkw:near
  433.  
  434.     assume    cs:code,ds:data,es:data
  435.  
  436. ;check string to see if we need to do something special
  437.  
  438. stringchek  proc  near
  439.        cmp   stringchekcnt,0     ; nobody in yet?
  440.        jne   stringchek1     ; ne => already have characters
  441.        cmp   al,escape         ; is this escape?
  442.        je    stringchek1     ; it is escape, so go and process
  443.        cmp   al,escape+80h     ; in case parity is odd
  444.        je    stringchek1     ; process escape
  445.        stc             ; display the character
  446.        ret             ; return quickly if nothing to do
  447. stringchek1:             ; here is escape already in
  448.        saveregs
  449.        and     al,07fh         ;strip high bit
  450.        mov     bx,stringchekcnt
  451.        mov     stringchekbuff[bx],al  ;put character in buffer
  452.        inc     stringchekcnt          ;one more character in buffer
  453.        call    stringtest     ; does the string in stringchekbuff match?
  454.        cmp    match,0         ; 0 means no match
  455.        je      stringchek2
  456.        mov     si,match           ; here means we have a match
  457.        shl     si,1           ; multiply by 2
  458.        dec     si
  459.        dec     si           ; 1=0, 2=1 etc
  460.        call    disptab[si]       ; call appropriate function
  461.        call    stringbuffplay          ; play back the buffer
  462.        clc               ; don't display
  463.        jmp     stringchek3       ; return and don't display character
  464. stringchek2:
  465.      clc              ; don not display
  466.      cmp   matchsofar,true      ; do we have a match so far
  467.      je    stringchek3         ; e=true , get out
  468.      mov   playem,true
  469.      call  stringbuffplay           ; clean out the buffer
  470.      clc               ; don't display character
  471. stringchek3:
  472.      restoreregs
  473.      ret
  474. stringchek   endp
  475.  
  476. ;test to see if input string is a match to toggle terminal  [jan]
  477.  
  478.  
  479. ; stringtab gives addresses of 0 terminated strings
  480. ; teststring in stringchekbuff
  481. ;numstrings is the number to checked
  482. ; matchsofar will have be true if there is a possilbe match
  483. ; match will be non-zero 1, 2, 3 indicating number of match if a match
  484. ; if no match yet, match will be 0
  485. ; severaal registers get destroyed
  486. stringtest proc near
  487.     mov    matchsofar, false      ; assume no match
  488.     mov    match,0            ; no match
  489.     xor    si,si            ; pointer to string tab
  490.     dec    si
  491.     dec    si            ; step back 1 item
  492.     mov    cx,0            ; cx points to number of string
  493. strtst1:
  494.     inc    cx            ; strings number
  495.     cmp    cx,numstrings        ; done parsing table?
  496.     ja    strtst5            ; we're done, get out of here
  497.     mov    di, offset stringchekbuff
  498.     inc    si
  499.     inc    si            ; point to next item
  500.     mov    bx,stringtab[si]    ; offset of string
  501. strtst2:
  502.     mov    al,[di]            ; stringchekbuff in al
  503.     mov    ah,[bx]            ; string element to test in ah
  504.     cmp    al,0            ; end of stringchekbuff
  505.     jne    strtst2a        ; ne=> not at end of buffer
  506.     mov    matchsofar,true        ; we have a match so far
  507.     jmp    strtst5            ; return to caller
  508. strtst2a:
  509.     cmp    ah,0            ; at end of string?
  510.     je    strtst1            ; failure, go to next string
  511.     cmp    ah,al            ; match?
  512.     jne    strtst1            ; no match, on to next string
  513.                     ; here if match
  514.     mov    ah,[bx+1]        ; next byte from string
  515.     cmp    ah,0            ; are we done with string?
  516.     je    strtst3            ; e => yes, a match
  517.     inc    bx            ; next element in string
  518.     inc    di            ; next character in stringchekbuff
  519.     jmp    strtst2            ; check next item in string
  520. strtst3:                ; here if we have a match
  521.      mov    match,cx        ;
  522.      mov    matchsofar,true        ;
  523. strtst5:
  524.     ret
  525. stringtest endp
  526.  
  527.  
  528.  
  529. ;play back characters in string buffer ..called by stringchek
  530. stringbuffplay proc near
  531.       xor      bx,bx          ;bx=0
  532.       mov      cx,stringchekcnt
  533. stringbuffplay1:
  534.       mov      al,stringchekbuff[bx]
  535.       cmp      playem,true    ;playback characters?
  536.       jne      stringbuffplay2     ;ne = no don't play back
  537.       push     bx          ; save index
  538.       push     cx          ; save count
  539.       call     outtty          ; print the character
  540.       pop      cx          ; restore count
  541.       pop      bx          ; restore index
  542. stringbuffplay2:
  543.      mov      stringchekbuff[bx],0  ;set to 0
  544.      inc      bx          ;point to next character
  545.      loop     stringbuffplay1     ;repeat until buffer is empty
  546.      mov      stringchekcnt,0     ;now no characters in buffer
  547.      ret
  548. stringbuffplay endp
  549.  
  550. ignoretek proc near           ; ignore this escape sequence in tek mode
  551.     mov playem,false
  552.     cmp flags.vtflg,tttek      ; are in in tek emulation
  553.     je    ignoretek1           ; e=yes do not play back
  554.     mov playem,true
  555. ignoretek1:
  556.      ret
  557. ignoretek endp
  558.  
  559. ignoreall proc near   ; always ignore this escape sequence
  560.      mov playem,false
  561.      writechar bell
  562.      ret
  563. ignoreall endp
  564.  
  565. totekplay proc near           ; turn on tektronix
  566.       mov playem,true           ; play back characters
  567.       jmp totek
  568. totekplay endp
  569.  
  570. toteknoplay proc near
  571.      mov playem,false
  572.      jmp  totek
  573. toteknoplay endp
  574.  
  575.  
  576. totek proc near           ; turn on tektronix
  577.        test    denyflg,tekxflg     ;tek auto entry enabled?
  578.        jz     totek1
  579.        mov playem,true        ; play back characters
  580.        ret
  581. totek1:
  582.  
  583.    cmp    flags.vtflg,tttek    ; already doing tek
  584.    je    totek2
  585.    call termtog            ; toggle to tektronix
  586. totek2:
  587.     ret
  588. totek endp
  589.  
  590.  
  591. setkeyboard proc   near         ; set appropriate keyboard
  592.      cmp   keyflg,altkeynum    ; want alternate keyboard
  593.      je      setkbd1        ; e=> set altkeyboard
  594.      call  sethpkey
  595.      ret
  596. setkbd1:call setaltkey
  597.      ret
  598. setkeyboard endp
  599.  
  600. sethpkey  proc    near
  601.     writestring hpkey
  602.     ret
  603. sethpkey  endp
  604.  
  605. setaltkey proc near
  606.      writestring altkey
  607.      ret
  608. setaltkey endp
  609.  
  610. scrsavinit   proc  near         ; set up memory block to save screen memory [jan]
  611.     saveregs
  612.     mov         ax,num_rows
  613.  
  614.     mov         cl,9
  615.     shl         ax,cl
  616.     mov         bx,ax         ; bx=512*num_rows
  617.     mov         ax,num_rows
  618.     mov         cl,7
  619.     shl         ax,cl         ; ax=128*num_rows
  620.     add         ax, bx         ; ax=640*numrows
  621.     mov         cx,ax         ; save num bytes in cx
  622.     push     cx
  623.     call     sbrk         ; memory manager
  624.     pop         cx             ; recover number of bytes
  625.     shr         cx,1         ; cx has number of words
  626.     mov         scrsavseg,ax    ; save it
  627.     xor         ax,ax
  628.     mov         di,ax
  629.     mov         es,scrsavseg
  630.     rep         stosw
  631.     restoreregs
  632.     clc
  633.     ret
  634. scrsavinit endp
  635.  
  636. savescr         proc     near    ; save dislply memory
  637.      saveregs            ; save the registers
  638.      mov    di,0        ; tek page by default
  639.      mov    line_len,60        ; bytes in tek line
  640.      mov    line_ofs,64        ; bytes between adjacent tek lines
  641.      mov    ax, num_rows    ; number of rows
  642.      shl    ax,1          ; each row has 8 lines
  643.      shl    ax,1          ; so multipy by 8
  644.      shl    ax,1
  645.      mov    num_lines,ax
  646.      xor    si,si        ; tek display starts at 8000:0000
  647.      xor    dx,dx        ; dx points to offset of current line
  648.      cmp    flags.vtflg,tttek    ; doing tek emulation?
  649.  
  650.      je        savesc1        ; je means yes we are doing tek
  651.      cmp    bigscreen,0        ; don't save for 110
  652.      jne     savesca        ; ne=> we have a plus
  653. ;;    here if saving for hp110
  654.       mov di,graph_bytes   ; here if saving 110 screen
  655.       mov    line_len,128     ; each line is 128 bytes
  656.       mov    line_ofs, 128    ; lines offset by 128 bytes
  657.      call    askcursor        ; cursor location in dx
  658.      mov    old_cursor,dx     ; save old cursora
  659.      writestring  curoff    ; turn off the cursor
  660.      in        al,0e6h         ; get row number at display top
  661.       and     al,63        ; insurance
  662.      xor     ah,ah
  663.      mov     cl,7
  664.      shl     ax,cl
  665.      mov     dx,ax
  666.      mov     si,dx
  667.      mov     ax,num_rows
  668.      mov     num_lines,ax
  669.      jmp     savesc1        ; do the save
  670. savesca:
  671.      mov    di,graph_bytes      ; here if saving alpha screen
  672.      mov    line_len,160    ; bytes in alpha line
  673.      mov    line_ofs,256    ; bytes between adjacent alpha lines
  674.      call    askcursor        ; cursor location in dx
  675.      mov    old_cursor,dx     ; save old cursora
  676.      writestring  curoff    ; turn off the cursor
  677.      in        al,83h        ; get row number of display top
  678.      mov    ah,al        ; multiply by 256 to get byte number
  679.      xor    al,al
  680.      mov    dx,ax         ; offset of alpha display start in dx
  681.      mov    si,dx
  682.      mov    ax,num_rows
  683.      mov    num_lines,ax     ; each row is one line in alpha
  684. savesc1:
  685.      mov     ax,scrsavseg      ; screen save segment
  686.      mov     es,ax
  687.      mov     cx,num_lines
  688. savesc2:
  689.      push    cx             ; save number of lines
  690.      mov     cx,line_len
  691.      shr     cx,1         ; words = bytes/2
  692.      mov     ax,8000h         ; screen memory segment
  693.      push    ds
  694.      mov     ds,ax
  695.      cld
  696.      rep     movsw         ; move line
  697.      pop     ds             ; get back kermit's ds
  698.      pop     cx             ; get back line number
  699.      add     dx,line_ofs     ; point to beginning of next line
  700. ;  check for wrap on hp110
  701.      cmp     bigscreen,1     ; is it a plus?
  702.      je         savesc2a         ; = means yes, it is a plus
  703.      cmp     flags.vtflg,tttek     ; tek emulation?
  704.      je         savesc2a         ; e=> yes, don't worry about wrap
  705.      cmp     dx,128*48         ; ready to wrap around on hp110?
  706.      jb        savesc2a        ; ne=> not there yet
  707.      mov     dx,0         ; point to first line on hp110 display
  708. ;  end of wrap check on hp110
  709. savesc2a:
  710.      mov     si,dx
  711.      loop savesc2         ; do the next line
  712.      cmp    flags.vtflg,tttek     ; doing tek emulation
  713.      je        savesc3         ; yes, don't turn on cursor
  714.  
  715.      writestring  curon         ; turn on the cursor
  716. savesc3:
  717. savescrex:
  718.      restoreregs         ; restore the registers
  719.      clc             ; all ok
  720.      ret
  721. savescr     endp
  722.  
  723.  
  724. restscr         proc     near    ; move ds:si(memory)  to es:di (screen)
  725.      saveregs            ; save the registers
  726.      mov    si,0        ; tek page by default
  727.      mov    line_len,60        ; bytes in tek line
  728.      mov    line_ofs,64        ; bytes between adjacent tek lines
  729.      mov    ax, num_rows    ; number of rows
  730.      shl    ax,1          ; each row has 8 lines
  731.      shl    ax,1          ; so multipy by 8
  732.      shl    ax,1
  733.      mov    num_lines,ax
  734.      xor    di,di        ; tek starts at 8000:0000
  735.      xor    dx,dx        ; dx points to offset of current line
  736.      cmp    flags.vtflg,tttek    ; doing tek emulation?
  737.      je        restsc1        ; je means yes we are doing tek
  738.      writestring alpha_disp      ; reload the hp character set
  739.      cmp     bigscreen,0     ; using the 110  ?
  740.      jne     restsca         ; ne=> we have the plus
  741.      call    cmblnk        ; blank display     on 110
  742.      writestring  curoff    ; turn off the cursor
  743.  
  744.      mov    si,graph_bytes      ; here if restoring alpha screen
  745.      mov    line_len,128    ; bytes in alpha line
  746.      mov    line_ofs,128    ; bytes between adjacent alpha lines
  747.      in        al,0e6h         ; get row number of display top
  748.     and  al,63        ; insurance
  749.      mov    cl,7           ; multiply by 128 to get byte number
  750.      xor    ah,ah
  751.      shl    ax,cl
  752.      mov    dx,ax         ; dx points to start of line
  753.      mov    di,dx         ; offset of alpha display start
  754.      mov    ax,num_rows
  755.      mov    num_lines,ax
  756.      jmp    restsc1
  757.  
  758. restsca:
  759.      call    cmblnk        ; blank display
  760.      writestring  curoff    ; turn off the cursor
  761.  
  762.      mov    si,graph_bytes      ; here if restoring alpha screen
  763.      mov    line_len,160    ; bytes in alpha line
  764.      mov    line_ofs,256    ; bytes between adjacent alpha lines
  765.      in        al,83h        ; get row number of display top
  766.      mov    ah,al        ; multiply by 256 to get byte number
  767.      xor    al,al
  768.      mov    di,ax          ; offset of alpha display start
  769.      mov    dx,di         ; dx points to start of line
  770.      mov    ax,num_rows
  771.      mov    num_lines,ax
  772. restsc1:
  773.      mov     cx,num_lines
  774. restsc2:
  775.      push    cx             ; save number of lines
  776.      mov     cx,line_len
  777.      shr     cx,1         ; words = bytes/2
  778.      mov     ax,8000h         ; screen memory segment
  779.      mov     es,ax         ; es:di points to display memory
  780.      cld
  781.      mov     ax,scrsavseg     ;
  782.      push    ds             ; save kermit's ds
  783.      mov     ds,ax         ; ds points to screen save memory
  784.      rep     movsw         ; move line
  785.      pop     ds             ; get back kermit's ds
  786.      pop     cx             ; get back line number
  787.      add     dx,line_ofs     ; dx points to begin of next lien
  788.      mov     di,dx         ; point to next line in desplay
  789. ;  check for wrap around on hp110
  790.      cmp     bigscreen,1     ; using a plus
  791.      je         restsc2a         ;  e=> yes its a plus
  792.      cmp     flags.vtflg,tttek     ; doing tek
  793.      je         restsc2a         ; e=> yes, dont worry about 110 wrap
  794.      cmp     dx,48*128         ; need to wrap
  795.      jb        restsc2a        ; ne=> no
  796.      mov     dx,0
  797.      mov     di,dx
  798. ; end of wrap around check on hp110
  799. restsc2a:
  800.      loop restsc2         ; do the next line
  801.      cmp   flags.vtflg,tttek     ; doing tek emulation
  802.      je       restsc3         ; yes, skip the cursor stuff
  803.  
  804.       mov  dx,old_cursor
  805.       call  poscur
  806.      writestring  curon         ; turn on the cursor
  807. restsc3:
  808. restscrex:
  809.      restoreregs         ; restore the registers
  810.      clc             ; all ok
  811.      ret
  812. restscr     endp
  813.  
  814. ;  identify wether we have hp110 or portable plus
  815. ;  if plus then bigscreen = 1 else bigscreen =0
  816. id_terminal proc near
  817.       saveregs
  818.       call clear_key_buffer        ; clear the keyboard buffer if needed
  819.       writestring ask_id        ; ansi termial ask string
  820.       push     ds
  821.       pop      es            ; es=ds for string moves
  822.       call     getkey            ; first key in string is 1 or 4
  823.       cmp  al,'1'            ; 1 for hp110
  824.       jne  id_ter2            ; ne means its a plus
  825.       mov  bigscreen,0
  826.       mov  num_rows,16            ; it's a 110
  827.       mov  graph_bytes,16*60*8          ; bytes in graphics screen
  828.       movsmac hp110_name, machnam, lenhp110_name  ; move name
  829.       movsmac alpha_110, alpha_disp, lenalpha_110  ; mov alpha message
  830.       jmp id_ter4            ; normal exit
  831. id_ter2: mov bigscreen,1         ; its a plus
  832.     mov num_rows,25
  833.     mov graph_bytes,25*60*8        ; bytes in graphics screen
  834.     movsmac plus_name machnam lenplus_name ; move machine name
  835.     movsmac alpha_plus alpha_disp lenalpha_plus ; alpha message
  836.     mov   bx,offset com2
  837.     mov   al,'3'
  838.     mov   [bx+3],al         ; com2 is always modem
  839.       jmp id_ter4             ; normal exit
  840. id_tererr: writestring termidfail
  841. id_ter4: call clear_key_buffer
  842.     restoreregs
  843.     clc
  844.     ret
  845. id_terminal  endp
  846.  
  847. modem_status_byte proc     near  ; get status byte on 110
  848.     cmp    bigscreen,0         ; is this a 110
  849.     je     modembyte1         ; => yes it is
  850.     mov    al,0             ; no status on plus
  851.     ret
  852. modembyte1:
  853.     saveregs
  854.     mov    dx, offset ask_modem_status
  855.     mov    cx,3                ; 3 bytes
  856.     call   w_ioctl                ; ask the status
  857.     mov    cx,1                ; 1 byte to read
  858.     call   r_ioctl
  859.     restoreregs
  860.     mov    ax, tempbuf           ; retrive the status byte
  861.     clc
  862.     ret
  863. modem_status_byte  endp
  864.  
  865. modem_status proc near    ; get modem status
  866.        saveregs
  867.        call    modem_status_byte       ; al will contain status
  868.        test   al,2               ; transmit enabled
  869.        jz     modem_stat1
  870.        writestring transmiton
  871. modem_stat1:
  872.        test   al,8              ; is modem off hook?
  873.        jz  modem_stat2
  874.       writestring offhook
  875. modem_stat2:
  876.        test   al,128            ; is the modem enabled?
  877.        jz  modem_stat3
  878.        writestring  modemenabled
  879. modem_stat3:
  880.        restoreregs
  881.        clc
  882.        ret
  883. modem_status endp
  884.  
  885. dial_number proc near        ; dial a number
  886.     cmp     bigscreen,0          ; is this a 110?
  887.     je     dial_numa          ; e=> yes, do the dial
  888.  ;;   ret            ; don't do anything if its a plus
  889. dial_numa:              ; start code which runs only on 110
  890.     saveregs
  891.     call savescr
  892.     writestring alpha_disp
  893.  ;;   call cmblnk           ; give a nice screen to work with
  894.  
  895.     cmp     flags.comflg,2           ; using port 2?
  896.     je dial_num0          ; e => yes, we are
  897.  
  898.     writestring modem_saying   ;
  899.     mov      ax,500           ; wait a second
  900.     call  pcwait
  901.     jmp dial_ex              ; can't dial until port set right
  902. dial_num0:
  903.        call modem_status_byte
  904.        test    al,128           ; is the modem on?
  905.        jz      dial_num1       ; it's not on so ok to dial
  906.        writestring onhook_saying ; tell user he can't dial with modem on
  907.        mov    ax,500
  908.        call   pcwait
  909.        jmp    dial_ex
  910. dial_num1:
  911.       call modem_status
  912.       mov ax,offset rdbuf   ; rdbuf is work buffer
  913.       push ds
  914.       pop es             ; es points to data segment
  915.       mov di,ax               ; let rdbuf be our buffer
  916.       call clear_key_buffer
  917.       writestring dial_saying
  918.       mov    al,'M'
  919.       mov    [di],al
  920.       inc    di
  921.        mov    al,'D'
  922.        mov    [di],al
  923.        inc    di
  924.     mov   rdbuffstrt,di        ; the start location of new characters
  925.       mov    dl,16            ; tone dial is default
  926. dial_num2:
  927.       call getkey            ; get key from user
  928.       cmp   al,8            ; backspace?
  929.       je   dial_num2b            ;  backspace, so erase previous char.
  930.       cmp   al,127            ; delete is also legal backspace
  931.       jne   dial_num2c            ; ne => no backspace
  932. ;  here to handle backspace
  933. dial_num2b:
  934.       cmp   di,rdbuffstrt       ; any characters in the command buffer?
  935.       je    dial_num2           ; nobody in yet, so do nothing
  936.       call  dodel           ; write a backspace
  937.       dec   di               ; remove last character from buffer
  938.       jmp   dial_num2           ; get the next character
  939. ; end of backspace handler
  940. dial_num2c:
  941.   ;;    writechar al               ; display for user
  942.       cmp  al,cr            ; are we done
  943.       je dial_num8
  944.       cmp  al,';'            ; ':' cancels dial command
  945.       je   dial_num2c1
  946.        cmp al,3                ; control c cancels
  947.       je   dial_num2c1
  948.        cmp  al,escape            ; escape also cancels
  949.        je  dial_num2c1
  950.        jmp  dial_num2d            ; continue
  951. dial_num2c1:       jmp    dial_ex        ; cancel dial command
  952. dial_num2d:
  953.       cmp  al,','            ; pause command
  954.       jne  dial_num2e
  955.       writechar      al            ; write comma to screen
  956.       mov  al,2                ; 2 second delay
  957.       mov  [di],al
  958.       inc  di               ; point to next byte in rdbuf
  959.       jmp  dial_num2
  960. dial_num2e:
  961.       cmp  al,'p'            ; pulse?
  962.       jne  dial_num3
  963.       mov  dl,32
  964. dial_num3: cmp al,'P'           ; pulse ?
  965.      jne dial_num4
  966.       mov  dl,32
  967. dial_num4: cmp al,'t'            ; tone?
  968.        jne dial_num5
  969.      mov dl,16
  970. dial_num5: cmp al,'T'            ; again tone
  971.     jne dial_num6
  972.     mov dl,16
  973. dial_num6: cmp al,'0'
  974.     jb dial_num2          ; ignore this one
  975.      cmp al,'9'          ; is it too big
  976.      ja dial_num2          ; yes, too big, so ignore
  977.      writechar al          ; write it on screen
  978.      sub  al,'0'          ; convert ascii to binary
  979.      add   al,dl          ; add dial code
  980.      mov [di],al          ; put in the read buffer
  981.      inc di              ; next byte in readbuffer
  982.        jmp dial_num2          ; get next key from user
  983. dial_num8:
  984.       mov al,2          ; 2 second delay
  985.       mov  [di],al
  986.        inc    di
  987.        mov al,80          ; enable transmit tone
  988.        mov    [di],al
  989.        inc    di
  990.        mov al,64           ; enable originate mode
  991.        mov    [di],al
  992.         inc di
  993.        mov    al,255           ; terminate dial sequence
  994.         mov [di],al
  995.        inc di
  996.         mov al,';'          ; add semicolon
  997.        mov [di],al
  998.        inc di
  999.        mov al,' '           ; finish with a blank
  1000.        mov    [di],al
  1001.          inc di
  1002.          mov al,'$'
  1003.          mov [di],al
  1004.       ;;  writestring rdbuf
  1005.  
  1006. ;; now dial string is safely in rdbuf and size in dh
  1007.       mov cx,di
  1008.       mov  ax,offset rdbuf         ; start of string
  1009.       sub  cx,ax         ; cx has bytes in buffer
  1010.      push  cx        ; save the number to write
  1011.      mov   dx, offset dial_msg
  1012.      mov   cx,3
  1013.      call  w_ioctl     ; tell pc we want to dial a number
  1014.      mov ax,50     ; wait to let things settle
  1015.      call pcwait         ; wait 50 ms
  1016.      mov  dx,offset     rdbuf
  1017.      pop  cx         ; number of byres
  1018.      call  w_ioctl
  1019.       call modem_status    ; tell user the status
  1020.  
  1021.       jmp dial_ok        ; all ok
  1022. dial_ex: writestring canceldial
  1023. dial_ok:
  1024.  
  1025.      mov ax,1000        ; give user time to read message
  1026.      call pcwait        ; wait a short while
  1027.      cmp  flags.vtflg,tttek ; doing tek
  1028.      jne  dial_tog
  1029.      call tekini        ; need to reinitialize emulator
  1030. dial_tog:
  1031.      call restscr
  1032.      restoreregs
  1033.      clc              ; stay in connect
  1034.      ret
  1035. dial_number  endp
  1036.  
  1037.  
  1038.  
  1039.      askcursor proc near       ; return curor row in dh, column in dl
  1040.        mov dx,257           ; default
  1041.        saveregs
  1042.       call clear_key_buffer    ;
  1043.       writestring ask_cursor        ; ansi ask cursor message
  1044.        mov ax,50
  1045.        call pcwait            ; wait a whill
  1046.        xor cx,cx
  1047. askcur1:
  1048.        call getkey
  1049.        inc cx
  1050.        cmp cx,20
  1051.        ja askcurex
  1052.        cmp al,'['
  1053.        jne askcur1
  1054.       xor bx,bx             ; keep row number in bx
  1055.  
  1056. askcur2:
  1057.       call getkey
  1058.       cmp al,';'           ; this signifies start of column report
  1059.       je askcur3
  1060.       sub al,'0'           ; make binary
  1061.       mul10 bx               ; multiply by 10
  1062.       add bl,al
  1063.        inc cx
  1064.        cmp cx,20
  1065.        ja askcurex
  1066.       jmp askcur2           ; repeat until done
  1067.  
  1068. askcur3: mov dh,bl           ; row in dh
  1069.        xor bx,bx           ; now get column
  1070. askcur4:  call getkey
  1071.       cmp al,'R'           ; this signifies start of column report
  1072.       je askcur5
  1073.       sub al,'0'           ; make binary
  1074.       mul10 bx               ; multiply by 10
  1075.       add bl,al
  1076.     inc cx
  1077.     cmp cx,20
  1078.     ja askcurex
  1079.       jmp askcur4           ; repeat until done
  1080. askcur5: mov dl,bl            ; column in dl
  1081.       jmp askcur7
  1082. askcurex: writestring badcursor
  1083. askcur7: clc
  1084.      mov temp1,dx
  1085.      restoreregs
  1086.       mov dx,temp1
  1087.       dec  dh   ; map (1,1) to (0,0)
  1088.       dec  dl
  1089.      ret
  1090. askcursor endp
  1091.  
  1092.  
  1093.  getkey proc near    ; wait for a key to be typed
  1094.   mov ah,7
  1095.   int dos
  1096.   ret
  1097. getkey endp
  1098.  
  1099. clear_key_buffer  proc    near
  1100.        saveregs
  1101. clear_key1:
  1102.        mov ax,0600h
  1103.        mov dx,0ffffh
  1104.        int dos
  1105.        jnz clear_key1
  1106.        restoreregs
  1107.        clc
  1108.        ret
  1109. clear_key_buffer  endp
  1110.  
  1111. ourhelp proc near   ; give user some help
  1112.      saveregs
  1113.      call savescr     ; save current screen
  1114.      writestring alpha_disp; be sure alpha is on
  1115.      call cmblnk    ; blank the screen
  1116.      writestring  ourhelptxt
  1117.      cmp  bigscreen,1       ; do we have a plus ?
  1118.      je      ourhelp1
  1119.      writestring   help110
  1120.      jmp  ourhelp2
  1121. ourhelp1: writestring helpplus
  1122. ourhelp2: writestring  helpend
  1123.       call getkey     ; user types a key when done reading
  1124.       cmp   flags.vtflg,tttek  ; doing tek emulation
  1125.       jne   ourhelp3           ; ne => we're doing alpha screen
  1126.       call  tekini           ; need to reinitialize the emulator
  1127. ourhelp3:
  1128.       call restscr     ; give him back his previous screen
  1129.       restoreregs
  1130.       clc         ; stat in connect mode
  1131.       ret
  1132. ourhelp endp
  1133.  
  1134. getrepchr proc    near          ; get replay character for file
  1135.       mov    ah,readf2          ; read from replay file
  1136.       mov    bx,diskio.handle
  1137.       mov    cx,1          ; read 1 character
  1138.       mov    dx,offset rdbuf  ; to this buffer
  1139.       int    dos
  1140.       jc     getrepchr1          ; c => failure
  1141.       cmp    ax,cx          ; read the byte?
  1142.       jne    getrepchr1
  1143.       mov    al,rdbuf          ; al has character
  1144.       clc              ; character available in al
  1145.       ret
  1146.       
  1147.  
  1148. getrepchr1:
  1149.       call   beep         ; announce file is done
  1150.       call   beep
  1151.       call   getkey         ; wait for a key to be pressed
  1152.       mov    prtrdy,false    ; so we exit connect mode
  1153.       stc
  1154.       ret             ; no character available
  1155. getrepchr    endp
  1156.  
  1157. repchrout  proc     near        ; process key in al  while replaying
  1158.     and   al,7fh        ; strip parity
  1159. repchrout1:
  1160.     cmp   al,'C'-40h    ; Control C?(to exit playback mode)
  1161.     je    repchrout3    ; e=> yes, return failure
  1162.     cmp   al,XOFF        ; user wants to stop?
  1163.     jne   repchrout2    ; ne => ok to continue
  1164.     call  getkey        ; wait and get a key
  1165.     jmp   repchrout1    ; now process this key
  1166. repchrout2:
  1167.     clc            ; return success
  1168.     ret
  1169. repchrout3:
  1170.     mov   prtrdy,false    ; exit terminal
  1171.     stc            ; exit connect mode
  1172.     ret
  1173. repchrout  endp
  1174.  
  1175.  
  1176. ; Clear the input buffer. This throws away all the characters in the
  1177. ; serial interrupt buffer.    This is particularly important when
  1178. ; talking to servers, since NAKs can accumulate in the buffer.
  1179. ; Returns normally.
  1180.  
  1181. CLRBUF    PROC    NEAR
  1182.     cmp    repflg,0  ; don't clear if replaying
  1183.     je    clrbuf0
  1184.     ret
  1185. clrbuf0:
  1186.     push    ax      ; necessary for msghpx
  1187.     mov    bufin,offset source
  1188.     mov    bufout,offset source
  1189.     mov    count,0
  1190. clrbuf1: call prtchr    ; empty out firmware buffer
  1191.      jnc clrbuf1
  1192.      pop  ax
  1193.      ret
  1194. CLRBUF    ENDP
  1195.  
  1196. ; Clear to the end of the current line.     Returns normally.
  1197.  
  1198. CLEARL    PROC    NEAR
  1199.     push    ax            ; save regs
  1200.     push    dx
  1201.     mov    ah,prstr
  1202.     mov    dx,offset clreol
  1203.     int    dos
  1204.     pop    dx
  1205.     pop    ax
  1206.     ret
  1207. CLEARL    ENDP
  1208. ; Put the char in AH to the serial port.  This assumes the
  1209. ; port has been initialized.  Should honor xon/xoff.
  1210. ; clc upon success (for 3.00)
  1211. OUTCHR     PROC  NEAR
  1212.      push cx         ; save regs
  1213.     or ah,ah        ; sending a null?
  1214.     jz outch2        ; z = yes
  1215.     xor cx,cx        ; clear counter
  1216.     cmp ah,flowoff        ; sending xoff?
  1217.     jne outch1        ; ne = no
  1218.     mov xofsnt,false    ; supress xon from chkxon buffer routine
  1219. outch1: cmp xofrcv,true        ; Are we being held?
  1220.     jne outch2        ; No - it's OK to go on
  1221.     loop outch1        ; held, try for a while
  1222.     mov xofrcv,false    ; timed out, force it off and fall thru
  1223. outch2: push dx            ; Save register
  1224.     mov al,ah        ; Parity routine works on AL
  1225.     call dopar        ; Set parity appropriately
  1226.                 ; Begin revised output routine
  1227.       ;;  and al,07fh
  1228.     mov byte ptr temp,al    ; put data there
  1229.     cmp prthnd,0        ; Got a handle yet?
  1230.     jne outch3        ; Yup just go on
  1231.     call opnprt        ; Else 'open' the port
  1232. outch3: push    bx
  1233.     mov    bx,prthnd    ; port handle
  1234.     mov    cx,1        ; one byte to write
  1235.     mov    dx,offset temp    ; place where data will be found
  1236.     mov    ah,write2    ; dos 2 write to file/device
  1237.     int    dos
  1238.     pop    bx        ; end of revised routine
  1239.     pop dx
  1240.     pop cx
  1241.     jc   outch4        ; stc => failure
  1242.     clc            ; clc for success
  1243.     ret
  1244. outch4: writestring write2err
  1245.     stc
  1246.     ret
  1247. OUTCHR    ENDP
  1248. ; This routine blanks the screen.   Returns normally.
  1249.  
  1250. CMBLNK    PROC    NEAR
  1251.     push    ax        ; save regs
  1252.     push    dx
  1253.     mov    ah,prstr
  1254.     mov    dx,offset blank
  1255.     int    dos
  1256.     pop    dx
  1257.     pop    ax
  1258.     ret
  1259. CMBLNK    ENDP
  1260.  
  1261. ; Homes the cursor.    Returns normally.
  1262.  
  1263. LOCATE    PROC    NEAR
  1264.     mov    dx,0        ; Go to top left corner of screen
  1265.     jmp    poscur
  1266. LOCATE    ENDP
  1267.  
  1268. ; Write a line at the bottom of the screen...
  1269. ; the line is passed in dx, terminated by a $.    Returns normally.
  1270. putmod    proc    near
  1271.     push    dx        ; preserve message
  1272.     mov    dx,1800H    ; assume plus
  1273.      cmp    bigscreen,0    ; is it a 110?
  1274.      jne    putmod1        ; ne => its a plus
  1275.     mov    dx,0F00H    ; now address line 15
  1276. putmod1:
  1277.     call    poscur
  1278.     mov    dx,offset invseq    ; put into inverse video
  1279.     mov    ah,prstr
  1280.     int    dos
  1281.     pop    dx        ; get message back
  1282.     int    dos        ; print it
  1283.     mov    dx,offset nrmseq    ; normal video
  1284.     int    dos
  1285.     ret
  1286. putmod    endp
  1287.  
  1288. ; clear the mode line written by putmod.  Returns normally.
  1289. clrmod    proc    near
  1290.     mov    dx,1800H       ; plus by default
  1291.     cmp    bigscreen,0    ; is it a 110?
  1292.     jne    clrmod1           ; ne => it is a plus
  1293.     mov    dx,0F00H
  1294. clrmod1:
  1295.     call    poscur        ; Go to bottom row
  1296.     call    clearl        ; Clear to end of line
  1297.     ret
  1298. clrmod    endp
  1299.  
  1300. ; Put a help message on the screen.
  1301. ; Pass the message in ax, terminated by a null.     Returns normally.
  1302. puthlp    proc    near
  1303.     push    dx        ; save regs
  1304.     push    si
  1305.     push    ax        ; preserve this
  1306.     mov    ah,prstr
  1307.     mov    dx,offset crlf
  1308.     int    dos
  1309.     pop    si        ; point to string again
  1310. puth0:    mov    ah,prstr
  1311.     mov    dx,offset invseq    ; put into reverse video
  1312.     int    dos
  1313.     mov    ah,prstr
  1314.     mov    dx,offset ivlseq    ; make line inverse video
  1315.     int    dos
  1316.     cld
  1317. puth1:    lodsb            ; get a byte
  1318.     cmp    al,0        ; end of string?
  1319.     je    puth2
  1320.     mov    dl,al
  1321.     mov    ah,conout
  1322.     int    dos        ; else write to screen
  1323.     cmp    al,lf        ; line feed?
  1324.     je    puth0        ; yes, clear the next line
  1325.     jmp    puth1
  1326. puth2:    mov    ah,prstr
  1327.     mov    dx,offset crlf
  1328.     int    dos
  1329.     mov    dx,offset nrmseq    ; normal video
  1330.     int    dos
  1331.     pop    si
  1332.     pop    dx
  1333.     ret
  1334. puthlp    endp
  1335.  
  1336.  
  1337. ; Set the baud rate for the current port, based on the value
  1338. ; in the portinfo structure.  Returns carry clear.
  1339.  
  1340. BAUDST    PROC    NEAR
  1341.       saveregs
  1342.     mov    dx,offset bdtab        ; baud rate table, ascii
  1343.     xor    bx,bx            ; help is the table itself
  1344.     mov    ah,cmkey        ; get keyword
  1345.     call    comnd
  1346.     jc    baudst3            ; c = failure
  1347.     push    bx            ; save result
  1348.     mov    ah,cmeol        ; get confirmation
  1349.     call    comnd
  1350.     pop    bx
  1351.     jc    baudst3            ; c = failure
  1352.     mov    si,portval
  1353.     mov    ax, offset port2
  1354.     cmp    ax,si            ; using the modem?
  1355.     jne     baudst2         ; ne => no
  1356.     cmp    bigscreen,1        ; using plus?
  1357.     je    baudst1            ; e => yes
  1358.     mov    bx,5              ; only 300 baud legal on 110 modem
  1359.     jmp    baudst2
  1360. baudst1:cmp    bx,5              ; 300 baud
  1361.     je    baudst2            ; 300 baud is ok
  1362.     mov    bx,7              ; if not 300, then it's 1200
  1363. baudst2:
  1364.     mov    ax,[si].baud        ; remember original value
  1365.     mov    [si].baud,bx        ; set the baud rate
  1366.       ;;  call      dobaud          ; use common code
  1367.       ; we set baud rate in SERINI
  1368.     mov need_to_set_baud, true    ; we need to update the baud rate
  1369.  
  1370.     clc
  1371. baudst3: restoreregs
  1372.      ret
  1373. BAUDST    ENDP
  1374.  
  1375. ; Set the baud rate for the current port, based on the value
  1376. ; in the portinfo structure.      Returns normally.
  1377. ; it is assumed the port is open else w_ioctl returns error
  1378.  
  1379. DOBAUD    PROC    NEAR
  1380.     cmp  need_to_set_baud, true    ; do we need to update the baud ?
  1381.     je  dobaud1               ; e=> yes, update baud rate
  1382.     clc                   ; success
  1383.     ret                   ; return if not needed
  1384. dobaud1:saveregs
  1385.     mov    bx,portval
  1386.     mov    dx,[bx].baud
  1387.     mov    bx,offset ourbdtab
  1388.     add    bx,dx             ; point to character in baud tabble
  1389.     mov    dx,[bx]
  1390.     mov    baudx,dl        ; put into baud rate messge
  1391.     mov    cx,4
  1392.     mov    dx,offset baudstr    ; point to message
  1393.     call w_ioctl
  1394.     mov need_to_set_baud, false    ; don't need to reset baud rate
  1395.     restoreregs
  1396.     ret                ; Must be set before starting Kermit
  1397. DOBAUD    ENDP
  1398.  
  1399. ; USe hardware flow control [jan]... it is assumed the port is open
  1400. DOFLOW PROC   NEAR
  1401.     saveregs
  1402.     mov    bx,portval
  1403.     mov  dl,'0'               ; default is no flow control
  1404.     cmp  [bx].floflg,0           ; doing flow control ?
  1405.     je   doflow1               ; e => no flow control
  1406.     mov    dl,'2'
  1407. doflow1:mov   flo_x,dl
  1408.     mov    dx, offset flo_str    ; C is first character
  1409.     mov    cx,3            ; 3 lettters in string
  1410.        ;;  writestring flo_str
  1411.     call w_ioctl
  1412.     restoreregs
  1413.     clc                 ; success
  1414.     ret
  1415. doflow     endp
  1416.  
  1417. ; Get the current baud rate from the serial card and set it
  1418. ; in the portinfo structure for the current port.   Returns normally.
  1419. ; This is used during initialization.
  1420.  
  1421. GETBAUD PROC    NEAR
  1422.     ret            ; Can't do this
  1423. GETBAUD ENDP
  1424.  
  1425. ; SHOW MODEM - displays status of modem lines DSR, CD, CTS, in this case
  1426. ; it just says whether or not the port is ready for i/o.
  1427. shomodem proc    near
  1428.     mov    ah,CMEOL    ; get a confirm
  1429.     call    comnd
  1430.     jnc    shmod00        ; nc=> success
  1431.     ret            ; get out if failure
  1432. shmod00:
  1433.     cmp    prthnd,0    ; Got a handle yet?
  1434.     jne    shmod0        ; Yup just go on
  1435.     call    opnprt        ; Else 'open' the port
  1436. shmod0: mov    dx,offset msmsg1 ; say port is not ready
  1437.     mov    bx,prthnd
  1438.     mov    al,7        ; output status command
  1439.     mov    ah,ioctl    ; ask DOS to look for us
  1440.     int    dos
  1441.     jc    shmod1        ; c = call failed, device not ready
  1442.     or    al,al
  1443.     jz    shmod1        ; not ready
  1444.     mov    dx,offset msmsg2 ; say port is ready
  1445. shmod1: mov    ah,prstr
  1446.     int    dos
  1447.      stc
  1448.      ret              ; carry set upon failure
  1449. shomodem endp
  1450.  
  1451. getmodem proc    near
  1452.     mov    al,0        ; no modem status
  1453.     ret
  1454. getmodem endp
  1455.  
  1456.  
  1457. ; this is not used, but is left in to aid future debugging
  1458. printal proc near   ; print the value in al
  1459. push di
  1460. push ax
  1461. push bx
  1462. push dx
  1463. push ax
  1464. push ax
  1465. ; print a leading space
  1466. mov ah,2
  1467. mov dl,' '
  1468. int dos
  1469. ;
  1470. pop  ax
  1471. and  al, 0f0h    ; high nibble
  1472. shr al,1
  1473. shr al,1
  1474. shr al,1
  1475. shr al,1  ; high nibble to low nibble
  1476. mov di, offset asciitab
  1477. xor bx, bx   ; bx=0
  1478. mov bl, al
  1479. mov dl, [di+bx]
  1480. mov ah,2   ; print char
  1481. int dos               ; print high nibble
  1482. ; now the low nibble
  1483. pop ax     ; get back original char
  1484. and al, 0fh
  1485. mov bl,al
  1486. mov dl, [di+bx]
  1487. mov ah, 2
  1488. int dos           ; print low nibble
  1489. pop dx
  1490. pop bx
  1491. pop ax
  1492. pop di
  1493. ret
  1494. printal endp
  1495.  
  1496. ;;end of msxhpx.h include file
  1497. ;
  1498. ;    write cx bytes to ioctl of serial port
  1499. ;
  1500. W_IOCTL PROC    NEAR
  1501.     cmp    prthnd,0    ; port opened?
  1502.     jne    w_ioctl1b    ; ne => yes it is open
  1503.     writechar 'I'
  1504.     ret
  1505. w_ioctl1b:
  1506.     push    ax        ; save regs
  1507.     push    bx
  1508.     push    cx
  1509.     mov    cx,1000        ; knock at port until ready
  1510. w_ioctla:
  1511.  
  1512.        mov     ah,ioctl           ; first check
  1513.     mov    bx, prthnd
  1514.     mov    al,7        ; check status
  1515.     int    dos
  1516.     cmp    al,0ffh        ; ok?
  1517.     loopne     w_ioctla    ; try again
  1518.     cmp     al,0ffh
  1519.     jne    w_ioctl3    ;ne =>     error
  1520.     pop    cx        ; retrieve number to write
  1521.     mov    ah, ioctl    ; now do write
  1522.     mov       al,3
  1523.     mov    bx,prthnd
  1524.     int    dos
  1525.     jnc    w_ioctl2
  1526. w_ioctl1:
  1527.     writestring w_ioctlerr    ; failure
  1528.     stc            ; failure
  1529.     jmp   w_ioctl2
  1530. w_ioctl3:writestring io_notready
  1531.      pop  cx
  1532.      stc
  1533. w_ioctl2:
  1534.     pop    bx
  1535.     pop    ax
  1536.     ret
  1537. W_IOCTL ENDP
  1538. ;
  1539. ;    read cx bytes from ioctl of serial port to tempbuf
  1540. ;
  1541. R_IOCTL PROC    NEAR
  1542.     cmp    prthnd,0        ; port opened?
  1543.     jne    r_ioctl0        ; ne => it is open
  1544.     writechar 'R'
  1545.     ret
  1546. r_ioctl0:
  1547.     push    ax            ; save regs
  1548.     push    bx
  1549.     mov    ah,ioctl
  1550.     mov    al,2
  1551.     mov    bx,prthnd
  1552.     mov    dx,offset tempbuf
  1553.     int    dos
  1554.     jnc    r_ioctl1       ; all ok
  1555.     writestring r_ioctlerr
  1556. r_ioctl1:
  1557.     pop    bx
  1558.     pop    ax
  1559.     ret
  1560. R_IOCTL ENDP
  1561. ;
  1562. ;    check serial port for characters and return number in al
  1563. ;
  1564. CHK_BUFF PROC    NEAR
  1565.     push    cx
  1566.     push    dx
  1567.     mov    dx,offset chk_msg
  1568.     mov    cx,2
  1569.     call    w_ioctl
  1570.     jc    chk_buff1      ; failure
  1571.     mov    cx,1
  1572.     call    r_ioctl
  1573.     jc    chk_buff1    ; failure
  1574.     mov    ax,tempbuf
  1575.     pop    dx
  1576.     pop    cx
  1577.     ret
  1578. chk_buff1: pop    dx
  1579.        pop    cx
  1580.        xor    ax,ax        ; no characters upon failure
  1581.        ret
  1582. CHK_BUFF ENDP
  1583.  
  1584.  
  1585. ; Use for DOS 2.0 and above. Check the port status. If no data, skip
  1586. ; return.   Else, read in a char and return.
  1587. PRTCHR    PROC    NEAR
  1588.     cmp    repflg,0        ; doing replay?
  1589.     je    prtch0            ; e => not doing replay
  1590.     jmp    getrepchr        ; get replay character if in replay
  1591. prtch0:
  1592.     push    bx
  1593.     push    cx
  1594.     push    si
  1595.     cmp    prthnd,0        ; got a handle
  1596.     jne    prtch1            ; ne = yes
  1597.     call    opnprt            ; open port if not
  1598.     jc     prt3x            ; exit if error
  1599. prtch1: cmp    count,0            ; any chars in buffer?
  1600.     jne    prtch2            ; ...yes, get one
  1601.     call    chk_buff        ; any chars at port?
  1602.     or    al,al            ; ax has characters available
  1603.     jz    prtch4            ; no, go to skip return
  1604.     mov    ah,0
  1605.      mov    cx,ax            ; read as many as are available
  1606. ;     mov     cx,1             ; read one char
  1607.     mov    count,cx
  1608.     mov    bx,prthnd
  1609.     mov    ah,readf2        ; DOS read from file/device
  1610.     mov    dx,offset source
  1611.     int    dos
  1612.     jc    prt3x            ; c = failure
  1613.     mov    count,ax        ; number of bytes read
  1614.     mov    bufout,offset source
  1615. prtch2: dec    count
  1616.     mov    si,bufout
  1617.     cld
  1618.     lodsb
  1619.     mov    bufout,si
  1620. prtch3: ;;call printal     ; print character from port
  1621.     pop    si
  1622.     pop    cx
  1623.     pop    bx
  1624.     clc
  1625.     ret                ; return success
  1626. prt3x:    mov    ah,prstr
  1627.     mov    dx,offset erms50
  1628.     int    dos
  1629. prtch4: pop    si
  1630.     pop    cx
  1631.     pop    bx
  1632.     stc                     ; stc means no characters
  1633.     ret
  1634. PRTCHR    ENDP
  1635.  
  1636. tprn  proc near
  1637.      ret
  1638. tprn endp
  1639.  
  1640. breakkey proc near               ; handle pressing of break key
  1641.     push  ax
  1642.     push  ds
  1643.     mov  ax,data
  1644.     mov  ds,ax               ; get correct data segment
  1645.     mov  need_break,true           ; flag that break needs setting
  1646.     pop   ds
  1647.     pop   ax
  1648.     iret
  1649. breakkey endp
  1650.  
  1651. ; Send a break out the current serial port.    Returns normally.
  1652. ; sendbrw is worker routine time in milliseconds in ax
  1653. SENDBRW     PROC     NEAR
  1654.     push    cx
  1655.     push    dx
  1656.     push    ax         ; save time of break
  1657.     mov    dx,offset brk_on
  1658.     mov    cx,3
  1659.     call    w_ioctl
  1660.     pop    ax         ; restore time
  1661.     call    pcwait         ; delay the appropriate time
  1662.     mov    dx,offset brk_off
  1663.     mov    cx,3
  1664.     call    w_ioctl
  1665.     pop    dx
  1666.     pop    cx
  1667.     mov  need_break,false         ; don't need to do break
  1668. sendbrw1: clc                 ; clear carry to stay in Connect mode
  1669.     ret
  1670. SENDBRW     ENDP
  1671.  
  1672. SENDBR    PROC    NEAR            ; Send a Break
  1673.     mov    ax,275            ; 275 ms for normal break
  1674.     jmp    sendbrw            ; go to worker routine
  1675. SENDBR    ENDP
  1676.  
  1677. SENDBL    PROC    NEAR            ; Send a Long Break
  1678.     mov    ax,1800            ; 1800 ms for long break
  1679.     jmp    sendbrw            ; go to worker routine
  1680. SENDBL    ENDP
  1681.  
  1682. ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
  1683. ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
  1684. ; else repeat cycle. Requires that the port be initialized before hand.
  1685. ; Ihosts is used by the local send-file routine just after initializing
  1686. ; the serial port.
  1687. ; 22 March 1986 [jrd]
  1688.  
  1689. IHOSTS    PROC    NEAR
  1690.     push    ax        ; save the registers
  1691.     push    bx
  1692.     push    cx
  1693.     push    dx
  1694.     mov    bx,portval    ; port indicator
  1695.     mov    ax,[bx].flowc    ; put Go-ahead flow control char in ah
  1696.     or    ah,ah        ; don't send null if flow = none
  1697.     jz    ihosts1        ; z = null
  1698.     call    outchr        ; send it (release Host's output queue)
  1699.      nop            ; outchr can do skip return
  1700.      nop
  1701.      nop
  1702. ihosts1:call    clrbuf        ; clear out interrupt buffer
  1703.     pop    dx        ; empty buffer. we are done here
  1704.     pop    cx
  1705.     pop    bx
  1706.     pop    ax
  1707.     ret
  1708. IHOSTS    ENDP
  1709.  
  1710. ; IHOSTR - initialize the remote host for our reception of a file by
  1711. ; sending the flow-on character (XON typically) to release any held
  1712. ; data. Called by receive-file code just after initializing the serial
  1713. ; port.        22 March 1986 [jrd]
  1714. IHOSTR    PROC    NEAR
  1715.     push    ax        ; save regs
  1716.     push    bx
  1717.     push    cx
  1718.     mov    bx,portval    ; port indicator
  1719.     mov    ax,[bx].flowc    ; put Go-ahead flow control char in ah
  1720.     or    ah,ah        ; don't send null if flow = none
  1721.     jz    ihostr1        ; z = null
  1722.     call    outchr        ; send it (release Host's output queue)
  1723.      nop            ; outchr can do skip return
  1724.      nop
  1725.      nop
  1726. ihostr1:pop    cx
  1727.     pop    bx
  1728.     pop    ax
  1729.     ret
  1730. IHOSTR    ENDP
  1731.  
  1732. DTRLOW    PROC    NEAR        ; Global proc to Hangup the Phone by making
  1733.                 ; DTR and RTS low.
  1734.     mov ah,CMLINE        ; allow text to be able to display help
  1735.     mov bx,offset rdbuf    ; dummy buffer
  1736.     mov dx,offset hnghlp    ; help message
  1737.     call comnd        ; get a confirm
  1738.     jnc  dtrlow1        ; nc => success
  1739.     ret            ; get out if failure
  1740. dtrlow1:
  1741.     call serhng        ; drop DTR and RTS
  1742.     mov ah,prstr        ; give a nice message
  1743.     mov dx,offset hngmsg
  1744.     int dos
  1745.     clc               ; carry clear for success
  1746.     ret
  1747. DTRLOW    ENDP
  1748.  
  1749. ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
  1750. ; to terminate the connection. 29 March 1986 [jrd]
  1751. ; Calling this twice without intervening calls to serini should be harmless.
  1752. ; Returns normally.
  1753. ; Adapted from recommendation by Mike Mellinger. [jrd]
  1754. SERHNG    PROC    NEAR
  1755.     saveregs
  1756.     cmp    prthnd,0    ; is the port open
  1757.     je    serhn1        ; e => it is closed
  1758.       ;     mov     ax,offset port3
  1759.       ;     cmp     ax,portval
  1760.       ; je    serhn4        ; don't do anything for 82164A
  1761.     cmp    bigscreen,1    ; do we have the plus?
  1762.     je    serhn2        ; yes we do
  1763.     mov    dx,offset $off_m110  ; separate hangup for 110
  1764.     mov    cx,len$off_m110
  1765.     jmp    serhn3
  1766. serhn2:
  1767.     mov    dx,offset $off_m ; magic words to turn off DTR
  1768.     mov    cx,off_len    ; their length
  1769. serhn3:
  1770.      call w_ioctl         ; write them
  1771. serhn4:     mov     bx,prthnd      ; close port
  1772.      mov     ah,close2     ; close the device
  1773.     int    dos
  1774.     mov    prthnd,0    ; port no longer open
  1775.     mov    ax,1000
  1776.     call    pcwait         ; delay so hangup can work
  1777. serhn1:
  1778.     restoreregs
  1779.     ret
  1780. SERHNG    ENDP
  1781.  
  1782. ; Wait for the # of milliseconds in ax, for non-IBM compatibles.
  1783. ; Thanks to Bernie Eiben for this one.
  1784. pcwait    proc    near
  1785.     mov    cx,240        ; inner loop counter for 1 millisecond
  1786. pcwai1: sub    cx,1        ; inner loop takes 20 clock cycles
  1787.     jnz    pcwai1
  1788.     dec    ax        ; outer loop counter
  1789.     jnz    pcwait        ; wait another millisecond
  1790.     ret
  1791. pcwait    endp
  1792.  
  1793.  
  1794. ; Position the cursor according to contents of DX:
  1795. ; DH contains row, DL contains column.    Returns normally.
  1796. POSCUR    PROC    NEAR
  1797.     push    ax            ; save regs
  1798.     push    dx
  1799.     push    di
  1800.     mov    ax,ds
  1801.     mov    es,ax            ; address data segment!!
  1802.     cld
  1803.     mov    di,offset colno
  1804.     mov    al,dl            ; column
  1805.     call    nout
  1806.     mov    al,'x'
  1807.     stosb
  1808.     mov    al,dh            ; row
  1809.     call    nout
  1810.     mov    al,'Y'
  1811.     stosb
  1812.     mov    al,'$'
  1813.     stosb
  1814.     mov    dx,offset movcur
  1815.     mov    ah,prstr
  1816.     int    dos            ; print the sequence
  1817.     pop    di
  1818.     pop    dx
  1819.     pop    ax
  1820.     ret
  1821. POSCUR    ENDP
  1822.  
  1823. NOUT    PROC    NEAR
  1824.     cbw            ; extend the word
  1825.     div    byte ptr ten    ; divide by ten
  1826.     or    al,al        ; any quotient?
  1827.     jz    nout1        ; no, forget this
  1828.     push    ax        ; save current result
  1829.     call    nout        ; output high order
  1830.     pop    ax        ; restore
  1831. nout1:    mov    al,ah        ; get digit
  1832.     add    al,'0'        ; make printable
  1833.     stosb            ; put in buffer
  1834.     ret            ; and return
  1835. NOUT    ENDP
  1836.  
  1837. ; Delete a character from the terminal.     This works by printing
  1838. ; backspaces and spaces.  Returns normally.
  1839.  
  1840. DODEL    PROC    NEAR
  1841.     push    ax            ; save regs
  1842.     push    dx
  1843.     mov    ah,prstr
  1844.     mov    dx,offset delstr    ; Erase weird character
  1845.     int    dos
  1846.     pop    dx
  1847.     pop    ax
  1848.     ret
  1849. DODEL    ENDP
  1850.  
  1851. ; Move the cursor to the left margin, then clear to end of line.
  1852. ; Returns normally.
  1853.  
  1854. CTLU    PROC    NEAR
  1855.     push    ax            ; save regs
  1856.     push    dx
  1857.     mov    ah,prstr
  1858.     mov    dx,offset clrlin
  1859.     int    dos
  1860.     call    clearl
  1861.     pop    dx
  1862.     pop    ax
  1863.     ret
  1864. CTLU    ENDP
  1865.  
  1866. ; Set the current port.
  1867.  
  1868. COMS    PROC    NEAR
  1869.     mov    dx,offset comptab    ; table of comms ports
  1870.     mov    bx,0            ; use keywords as help
  1871.     mov    ah,cmkey        ; parse a keyword
  1872.     call    comnd
  1873.     jnc    coms1            ; nc => success
  1874.     ret                ; get out if failure
  1875. coms1:    push    bx
  1876.     mov    ah,CMEOL
  1877.     call    comnd            ; Get a confirm
  1878.     jc   comx               ; carry => failure
  1879.  
  1880.     call    serr_x            ; force close on serial port
  1881.  
  1882.     pop    bx
  1883.     mov    flags.comflg,bl        ; Set the comm port flag
  1884.     cmp    flags.comflg,1        ; Using Com 1?
  1885.     jne    coms2            ; ne = no
  1886.     mov    portval,offset port1
  1887.     clc                ; carry clear for success
  1888.     ret
  1889. coms2:    cmp    bl,2            ; using com2?
  1890.     jne    coms3            ; ne = no
  1891.     mov    portval,offset port2
  1892.     clc                ; success [jan]
  1893.     ret
  1894. coms3:
  1895.     mov    portval,offset port3
  1896.     clc                 ; success [jan]
  1897.     ret
  1898. comx:    pop    bx
  1899.     stc                 ; carry set for failure [jan]
  1900.     ret
  1901. COMS    ENDP
  1902.  
  1903. ; Set tektronix emulation on/off
  1904.  
  1905. VTS    PROC    NEAR
  1906.       mov     dx,offset termtb
  1907.       mov     bx,0
  1908.       mov     ah,cmkey
  1909.       call    comnd
  1910.       jnc    vts00          ; nc => success
  1911.       ret              ; return if failure
  1912. vts00: push    bx
  1913.       mov     ah,CMEOL
  1914.       call    comnd          ; Get a confirm
  1915.       jc      vtx          ; carry => didn't get a confirm
  1916.       pop     bx
  1917.       cmp     bl,hpkeynum      ; want hpkeyboard
  1918.       jne     vts0          ; ne => no
  1919.       mov     keyflg,hpkeynum
  1920.       call    setkeyboard
  1921.       clc
  1922.       ret
  1923. vts0: cmp     bl,altkeynum       ; want alt keyboard?
  1924.       jne     vts0a           ; ne=> no
  1925.       mov     keyflg,altkeynum       ; turn on altkeyboard
  1926.       call    setkeyboard
  1927.       clc
  1928.       ret
  1929. vts0a:    cmp   bl, tekonnum       ; enable tek ?
  1930.       jne   vts0b           ; ne => don't enable
  1931.       and   denyflg, not tekxflg   ; clear tekxflgbit
  1932.       mov tekbyte, bl           ; for status display
  1933.       clc
  1934.       ret
  1935. vts0b: cmp bl, tekoffnum       ; disable tek ?
  1936.     jne vts1           ; ne=> don't disable
  1937.     or  denyflg, tekxflg       ; set deny tek bit
  1938.     mov  tekbyte, bl       ; for status
  1939.     clc
  1940.     ret
  1941. vts1:
  1942.       mov     flags.vtflg,bl       ; Set the Tektronix emulation flag [jan]
  1943.       mov     tekflg,0           ;need to re-initialize tek emulator [jan]
  1944.       clc               ; success
  1945.       ret
  1946. vtx:  pop bx
  1947.       stc              ; carry set => failure
  1948.       ret
  1949. VTS    ENDP
  1950.  
  1951. VTSTAT    PROC    NEAR    ; For Status display [jrd]
  1952.        mov  bx,offset vtstbl  ; table of things to show
  1953.        jmp  statc          ; common status code
  1954.       ;;  ret          ; no emulator status to display
  1955. VTSTAT    ENDP
  1956.  
  1957. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  1958. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  1959. ; is determined by mssset and is passed as pointer dmpname.
  1960.  
  1961. DUMPSCR PROC    NEAR    ; Dumps screen contents to a file. Just Beeps here
  1962.     call    beep
  1963.     ret
  1964. DUMPSCR ENDP
  1965.  
  1966.  
  1967. ; Initialize variables to values used by the generic MS DOS version.
  1968. lclose    proc  near
  1969.      call sethpkey       ; turn on hp keyboard
  1970.      ret
  1971. lclose     endp
  1972.  
  1973. lpop     proc  near          ; executed when returing from dos
  1974.      call  setkeyboard    ; turn on the appropriate keyboard
  1975.      ret
  1976. lpop     endp
  1977.  
  1978. lpush    proc  near       ; call before pushing to dos
  1979.     call  sethpkey    ; turn on hp keyboard
  1980.     ret
  1981. lpush    endp
  1982.  
  1983. lclini     proc    near
  1984.     saveregs
  1985.     mov    dosnum,200h    ; force dosnum to 2.00 so replay proc works
  1986.     mov    prtrdy,true    ; port is ready
  1987.     call    msuinit        ; init keyboard translator
  1988.     mov    lclexit, offset lclose ; let mssker know that lclose exists
  1989.     mov    lclsusp, offset lpush  ; for mssker (optional)
  1990.     mov    lclrest, offset lpop
  1991.     mov    flags.vtflg,0    ; Don't do terminal emulation
  1992.  ;;    mov    prthnd,0      ; no port handle yet. [jrd]
  1993.  ;;    call    opnprt          ; Get file handle for comm port
  1994. ;;    mov portval, offset port2
  1995. ;;    mov flags.comflg,2    ; modem on at startup
  1996.     mov    portval, offset port1
  1997.     mov    flags.comflg, 1      ; serial port is default at startup
  1998.     call    setkeyboard    ; turn on keyboard
  1999.     call    id_terminal    ; do we have 110 or portable plus?
  2000.     cmp    bigscreen,1    ; using a plus
  2001.     je    lclini1           ; e=> yes we are
  2002.     mov    bx,offset port2
  2003.     mov    [bx].baud,5    ; modem on 110 = 300 baud
  2004.  
  2005. lclini1:
  2006.     call    scrsavinit       ; initialize memory for screen save
  2007.     writestring alpha_disp       ; turn on the alpha display
  2008.     call    savescr           ; save an alpha screen to initialize
  2009.     writestring helpini
  2010.     restoreregs
  2011.     clc
  2012.     ret
  2013.  
  2014. lclini     endp
  2015.  
  2016. ; Get a file handle for the communications port.  Use DOS call to get the
  2017. ; next available handle.  If it fails, ask user what value to use (there
  2018. ; should be a predefined handle for the port, generally 3).    The open
  2019. ; will fail if the system uses names other than "COM1", "COM2", "COM3","AUX".
  2020. opnprt proc near
  2021.     call serr_x        ; close port if already open
  2022.     mov    ax, portval
  2023.     cmp    ax, offset port1
  2024.     jne    opnprt0
  2025.     mov    flags.comflg,1
  2026.     jmp    opnprt0d      ; proceed with the open
  2027. opnprt0:
  2028.     mov    ax, portval
  2029.     cmp    ax, offset port2
  2030.     jne    opnprt0a
  2031.     mov    flags.comflg,2
  2032.     jmp    opnprt0d      ; proceed with the open
  2033. opnprt0a:
  2034.     mov    ax, portval
  2035.     cmp    ax, offset port3
  2036.     jne    opnprt0b
  2037.     mov    flags.comflg,3
  2038.     jmp    opnprt0d      ; proceed with the open
  2039. opnprt0b: mov portval, offset port1  ; if all else fails
  2040.       mov flags.comflg, 1
  2041.  
  2042. opnprt0d:
  2043.     mov    al,flags.comflg
  2044.  
  2045.  
  2046.     dec    al        ; flags.comflg = 1 for com1, 2 com2, 3 com3
  2047.     mov    ah,0
  2048.     mov    si,ax
  2049.     shl    si,1            ; double index
  2050.     mov    dx,prttab[si]
  2051.     mov    ah,open2
  2052.     mov    al,2
  2053.     int    dos
  2054.     jnc    opnpr1
  2055.     mov    ah,prstr        ; It didn't like the string
  2056.     mov    dx,offset erms41
  2057.     int    dos
  2058.     mov    prthnd,0        ; clear port file handle
  2059.     stc                ; carry set for failure
  2060.     ret
  2061. opnpr1: mov    prthnd,ax        ; Call succeeded
  2062.     mov    ah,ioctl
  2063.     mov    al,00h            ; get device info
  2064.     xor    dx,dx
  2065.     xor    cx,cx            ; 0 bytes to read/write
  2066.     mov    bx,prthnd        ; port's handle
  2067.     int    dos
  2068.     or    dl,20h            ; set binary mode in device info
  2069.     xor    cx,cx            ; 0 bytes to read/write
  2070.     mov    dh,0
  2071.     mov    ah,ioctl
  2072.     mov    al,01h            ; set device info
  2073.     int    dos
  2074.     mov    ax,portval
  2075.     cmp    ax,offset port3        ; using 82164A
  2076.     jne     opnpr2
  2077.     clc             ; don't need to write to 82164a
  2078.     ret
  2079. opnpr2:
  2080.     cmp    ax,offset port1        ; using port1 (serial) ?
  2081.     jne     opnpr3              ; ne => no, not using port 1
  2082.     mov    dx,offset $m1
  2083.     mov    cx,len_$m1
  2084.     call     w_ioctl
  2085.     clc
  2086.     ret
  2087. opnpr3: cmp ax, offset port2          ; using modem
  2088.     jne   opnpr4              ; ne => not using modem
  2089.      mov     dx,offset $m0
  2090.     mov    cx,len_$m0
  2091.     call    w_ioctl
  2092.     clc
  2093.     ret
  2094.  
  2095. opnpr4: clc
  2096.     ret                ; carry clear for success
  2097. opnprt     endp
  2098.  
  2099.   ; set the interrupt vectors
  2100.  
  2101. setints       proc     near
  2102. ;    save break vector and set to breakkey
  2103. ;    first save the break existing interrupt
  2104.     cmp    ints_set,true           ; interrupt vectors set?
  2105.     je    setints1           ; je=>yes, don't reset!
  2106.     push    ax
  2107.     push    bx
  2108.     push    dx
  2109.     push    es
  2110.     mov    al, brk_int
  2111.     mov    ah,35h               ; get interrupt vector
  2112.     int    dos               ; es:bx has long pointer
  2113.     mov    savbrko,bx           ; offset of routine
  2114.     mov    savbrks,es           ; segment
  2115.     pop    es
  2116. ; now set the break interrupt
  2117.     push    ds
  2118.     mov    dx,offset breakkey     ; address of interrupt routine
  2119.     push    cs               ; segment of breakkey is code
  2120.     pop    ds               ; ds=cs
  2121.     mov    ah,25h               ; set vector call
  2122.     mov    al,brk_int           ; break key interrupt
  2123.     int    21h               ; set the vector
  2124.     pop    ds               ; restore data segment
  2125. ; end of setting break vector
  2126. setints1:
  2127.        mov  ints_set,true         ; we have set the interrupts
  2128.        pop     dx
  2129.        pop     bx
  2130.        pop     ax
  2131.        clc
  2132.        ret
  2133. setints     endp
  2134.  
  2135. restoreints  proc near            ; restore interrupts
  2136.        cmp   ints_set,false        ; have we set interrupts?
  2137.        je     restoreints1        ; don't restore if not set!
  2138.  
  2139. ;     resotore break key interrupt
  2140.        push   ds
  2141.        mov    dx,savbrko          ; original offset
  2142.        mov    ax,savbrks          ; original segment
  2143.        mov    ds,ax              ; original segment to ds
  2144.        mov     ah,25h              ;
  2145.        mov    al,brk_int
  2146.        int    dos              ; restore original interrupt
  2147.        pop    ds
  2148. ;;end of restore
  2149.  
  2150.  
  2151. restoreints1: mov ints_set,false
  2152.           clc
  2153.           ret
  2154. restoreints   endp
  2155.  
  2156.  
  2157.  
  2158. ; Initialization for using serial port.     Returns normally.
  2159. SERINI    PROC    NEAR
  2160.     cld                ; Do increments in string operations
  2161.     cmp    prthnd,0        ; Got Handle already?
  2162.     jne    ser_x            ; ne = yes, skip open
  2163.     ;;    call    setints            ; set interrupt vectors
  2164.     call    opnprt            ; open handle
  2165.     jc    serin2            ; carry set = failure
  2166.  
  2167. ser_x:
  2168.     call    dobaud            ; set baud rate
  2169.     jc    serin2
  2170.     call    doflow             ; set hardware flow control
  2171.     jc    serin2
  2172.     push    bx
  2173.     mov    bx,portval        ; get port
  2174.     mov    parmsk,0ffh        ; parity mask, assume parity is None
  2175.     cmp    [bx].parflg,parnon    ; is it None?
  2176.     je    serin1            ; e = yes
  2177.     mov    parmsk,07fh        ; no, pass lower 7 bits as data
  2178. serin1: mov    bx,[bx].flowc        ; get flow control chars
  2179.     mov    flowoff,bl        ; xoff or null
  2180.     mov    flowon,bh        ; xon or null
  2181.     pop    bx
  2182.  
  2183.     clc                   ; carry clear for success
  2184.     ret
  2185. serin2: writestring serierr           ; error message
  2186.  
  2187.     call serr_x               ; force close on bad port
  2188.     stc
  2189.     ret
  2190. SERINI    ENDP
  2191.  
  2192.  
  2193. ; Reset the serial port.  This is the opposite of serini.   Calling
  2194. ; this twice without intervening calls to serini should be harmless.
  2195. ; Returns normally.
  2196.  
  2197. SERRST    PROC    NEAR
  2198.     cmp    flags.extflg,0
  2199.     jne    serr_x
  2200.     ret
  2201. serr_x: call serhng        ; close files and hangup
  2202.     ;;      mov  need_to_set_flow, true ; need to update flow control
  2203.     mov  need_to_set_baud, true ; need to update baud rate
  2204.     ret
  2205. SERRST    ENDP
  2206.  
  2207. ; Produce a short beep.     The PC DOS bell is long enough to cause a loss
  2208. ; of data at the port.    Returns normally.
  2209.  
  2210. BEEP    PROC    NEAR
  2211.     mov    dl,bell
  2212.     mov    ah,dconio
  2213.     int    dos
  2214.     ret
  2215. BEEP    ENDP
  2216.  
  2217. ; Dumb terminal emulator.  Doesn't work too well above 1200 baud (and
  2218. ; even at 1200 baud you sometimes lose the first one or two characters
  2219. ; on a line). Does capture (logging), local echo, debug display, tests
  2220. ; for printer/logging device not ready. 27 Sept 86 [jrd].
  2221. term    proc    near
  2222.     saveregs
  2223.  
  2224.     mov    argadr,ax        ; save argument ptr
  2225.     mov    si,ax            ; this is source
  2226.     mov    di,offset ourarg    ; place to store arguments
  2227.     push    es            ; save register
  2228.     push    ds
  2229.     pop    es            ; set es to data segment
  2230.     mov    cx,size termarg
  2231.     cld
  2232.     rep    movsb            ; copy into our arg blk
  2233.     pop    es            ; restore reg
  2234.     and    ourarg.flgs,not (prtscr) ; no screen printing at startup
  2235.     mov    ax,ourarg.captr
  2236.     mov    captrtn,ax        ; buffer capture routine
  2237.     call    setints            ; set interrupts for connect mode
  2238. term0a:
  2239.     cmp    flags.vtflg,tttek      ; tek emulation on?
  2240.     jne    term0
  2241.      call tekini
  2242. term0:
  2243.     call    restscr            ; restore the screen
  2244.     mov    parmsk,0ffh        ; parity mask, assume parity = None
  2245.     cmp    ourarg.parity,parnon    ; is parity None?
  2246.     je    term1            ; e = yes, keep all 8 bits
  2247.     mov    parmsk,07fh        ; else keep lower 7 bits
  2248.  
  2249. term1:
  2250.     cmp prtrdy,false         ; ready to read port?
  2251.     je  term5            ; get out
  2252.     call    portchr            ; read char from serial port
  2253.     jnc    short term3        ; nc = no char, go on
  2254.     cmp    flags.vtflg,tttek    ; doing tek emulation?
  2255.     je    term1a               ;e=yes, already doing tek
  2256.     call stringchek            ; check for special escape strings
  2257.     jnc   short term3        ; nc => don't display
  2258. term1a: call    outtty         ; display and capture char [jrd]
  2259. term3:
  2260.     inc keydelay               ;just check keyboard once
  2261.     mov ax,keydelay               ;each eight reads of the port
  2262.     and ax,7               ;should speed things up
  2263.     jnz term1              ;at higher baud rates [jan]
  2264.     cmp    need_break,false      ; do we need to send a break?
  2265.     je     term3a              ;e=> no, get next key
  2266.     call sendbr              ; do the required break
  2267. term3a:
  2268.     call    keybd            ; call keyboard xlator, send results
  2269.     jnc    term1            ; nc = stay in Connect mode
  2270. term5:                    ; [gaw@prc]
  2271.     call    savescr            ; save screen [gaw@prc]
  2272.     cmp   flags.vtflg,tttek
  2273.     jne   term6               ; skip string write if not in tek
  2274.     writestring  alpha_disp        ; turn on alpha display for kermit
  2275. term6:
  2276.     cmp   prtrdy, true        ; need to set kbdflg if wierd exit
  2277.     je    term7
  2278.     mov  kbdflg,'C'               ; so we exit connect mode
  2279.     mov  prtrdy,true
  2280. term7:
  2281.     call  restoreints        ; restore connect mode interrupts
  2282.     restoreregs
  2283.     ret                ; and return to caller
  2284. term    endp
  2285.  
  2286.  
  2287. termtog proc  near        ; toggle terminal type [jan]
  2288.     call    savescr        ; save present screen
  2289.     cmp    flags.vtflg,tttek ; doing tek emulation ?
  2290.     jne    termtog1      ; ne means  doing tek
  2291.     writestring  alpha_disp
  2292.     mov    flags.vtflg,ttgenrc ; turn on alpha display
  2293.     call    restscr           ; restore previous alpha display
  2294.     clc
  2295.     ret
  2296. termtog1:
  2297.     mov    flags.vtflg,tttek  ; turn on tek display
  2298.     call tekini
  2299.     call    restscr        ; restore the previous screen
  2300.     clc            ; do not exit Connect mode [jrd]
  2301.     ret            ; stay in connect mode
  2302. termtog endp
  2303.  
  2304. kclrscn proc    near        ; clear screen in text or Tek mode [jrd]
  2305.     cmp    flags.vtflg,tttek ; doing Tek emulation?
  2306.     jne    kclrsc1        ; ne = no
  2307.     call    tekcls        ; blank and some more
  2308.     clc            ; stay in Connect mode
  2309.     ret
  2310. kclrsc1:call    cmblnk        ; blank screen
  2311.     clc            ; stay in Connect mode
  2312.     ret
  2313. kclrscn endp
  2314.  
  2315. getflgs     proc  near
  2316.      mov al,ourarg.flgs           ;supply flags for msggri [jan]
  2317.      ret
  2318. getflgs     endp
  2319.  
  2320. ; put the character in al to the screen, do capture and printing,
  2321. ; does translation for Set Input command.
  2322. ; Adapted from msyibm.asm [jrd]
  2323. outtty    proc    near
  2324.     cmp    flags.vtflg,tttek    ; doing tektronix emulation?
  2325.     jne    outtty1            ; ne= not doing tek emulation
  2326.     jmp    tekemu            ; do tekemu and return
  2327. outtty1:
  2328.    ;;      call printal              ; debug
  2329.     test    flags.remflg,d8bit    ; keep 8 bits for displays?
  2330.     jnz    outnp8            ; nz = yes, 8 bits if possible
  2331.     and    al,7fh            ; remove high bit
  2332. outnp8: cmp    rxtable+256,0        ; is translation off?
  2333.     je    outnp7            ; e = yes, off
  2334.     push    bx            ; Translate incoming char [jrd]
  2335.     mov    bx,offset rxtable    ; address of translate table [jrd]
  2336.     xlatb                ; new char is in al
  2337.     pop    bx
  2338. outnp7:
  2339.     test    ourarg.flgs,capt    ; capturing output? Can be shut off
  2340.     jz    outnoc            ; no, forget this part
  2341.     push    ax            ; save char
  2342.     call    captrtn            ; give it captured character
  2343.     pop    ax            ; restore character and keep going
  2344. outnoc: test    ourarg.flgs,prtscr    ; should we be printing?
  2345.     jz    outnop            ; no, keep going
  2346.     push    ax
  2347.     mov    ah,print_out        ; write to system printer device
  2348.     mov    dl,al
  2349.     int    dos
  2350.     pop    ax
  2351.     jnc    outnop            ; nc = successful print
  2352.     push    ax
  2353.     call    beep            ; else make a noise and
  2354.     call    trnprs            ;  turn off printing
  2355.     pop    ax
  2356. outnop: cmp    flags.vtflg,0        ; emulating a terminal?
  2357.     jnz    outnop1            ; nz = yup, go do something smart
  2358.     test    ourarg.flgs,trnctl    ; debug? if so use dos tty mode
  2359.     jz    outnp5            ; z = no
  2360.     mov    ah,conout
  2361.     cmp    al,7fh            ; Ascii Del char or greater?
  2362.     jb    outnp1            ; b = no
  2363.     je    outnp0            ; e = Del char
  2364.     push    ax            ; save the char
  2365.     mov    dl,7eh            ; output a tilde for 8th bit
  2366.     int    dos
  2367.     pop    ax            ; restore char
  2368.     and    al,7fh            ; strip high bit
  2369. outnp0: cmp    al,7fh            ; is char now a DEL?
  2370.     jne    outnp1            ; ne = no
  2371.     and    al,3fH            ; strip next highest bit (Del --> '?')
  2372.     jmp    outnp2            ; send, preceded by caret
  2373. outnp1: cmp    al,' '            ; control char?
  2374.     jae    outnp3            ; ae = no
  2375.     add    al,'A'-1        ; make visible
  2376. outnp2: push    ax            ; save char
  2377.     mov    dl,5eh            ; caret
  2378.     int    dos            ; display it
  2379.     pop    ax            ; recover the non-printable char
  2380. outnp3: mov    dl,al
  2381.     int    dos
  2382.     ret
  2383. ;outnp4: ;cmp      al,bell          ; bell (Control G)? [jrd]
  2384.     ;jne     outnp5             ; ne = no
  2385.        ; jmp     beep             ; use short beep, avoid char loss.
  2386. outnop1:
  2387. outnp5:
  2388.     cmp    bigscreen, 1        ; do we have the plus
  2389.     jne    outnp5a            ; ne => we just have a 110
  2390.     cmp    al,14            ; is the character CTRL N?
  2391.     je    outnp6            ; e=> yes, do not print CTRL N
  2392.                     ; (CTRL N on Plus messes up character
  2393.                     ; set)
  2394.     push     si            ; print character on plus
  2395.     mov    plus_char,al        ; where si expects it
  2396.     mov    bx,6            ; don't know why
  2397.     mov    si,offset plus_char    ; write the character
  2398.     int    50h            ; special interrupt
  2399.     pop    si
  2400.     ret
  2401.  
  2402. outnp5a:
  2403.     mov    ah,conout        ; dostty screen mode
  2404.     mov    dl,al            ; write without intervention.
  2405.     int    dos            ; else let dos display char
  2406. outnp6: ret                ; and return
  2407. outtty    endp
  2408.  
  2409.  
  2410.  
  2411. ; send the character in al out to the serial port; handle echoing.
  2412. ; Can send an 8 bit char while displaying only 7 bits locally.
  2413. outprt    proc    near
  2414.     test    ourarg.flgs,lclecho    ; echoing?
  2415.     jz    outpr1            ; z = no, forget it
  2416.     push    ax            ; save char
  2417.     call    outtty            ; print it
  2418.     pop    ax            ; restore
  2419. outpr1: mov    ah,al            ; this is where outchr expects it
  2420.     call    outchr            ; output to the port
  2421.     ret
  2422. outprt    endp
  2423.  
  2424. ; Get a char from the serial port manager
  2425. ; returns with carry on if a character is available
  2426. portchr proc    near
  2427.     call    prtchr            ; character at port?
  2428.     jnc   portc1
  2429. portc0: clc                ; no carry -> no character
  2430.     ret                ; and return
  2431. portc1: and    al,parmsk        ; apply 8/7 bit parity mask
  2432. ; don't catch anybody [jan]
  2433.        ; or     al,al             ; catch nulls
  2434.        ; jz     portc0             ; z = null, ignore it
  2435.        ; cmp     al,del             ; catch dels
  2436.        ; je     portc0             ; e = del, ignore it
  2437.     stc                ; have a character
  2438.     ret                ; and return
  2439. portchr endp
  2440.  
  2441. ;; keyboard translator action routines, system dependent, called from msugen.
  2442. ; These are invoked by a jump instruction. Return carry clear for normal
  2443. ; processing, return carry set to exit Connect mode (kbdflg has transfer char)
  2444.  
  2445. ;  msu calls this to send keystroke out the port
  2446. chrout    proc  near
  2447.     cmp    repflg,0        ; in replay mode?
  2448.     je    chrout1            ; e=> not doing replay
  2449.     jmp    repchrout          ; display the replay character
  2450. chrout1:call    outprt               ; put char in al to serial port
  2451.     clc                ; stay in Connect mode
  2452.     ret
  2453. chrout    endp
  2454.  
  2455. trnprs: push    ax            ; toggle Copy screen to printer
  2456.     test    ourarg.flgs,prtscr    ; are we currently printing?
  2457.     jnz    trnpr2            ; nz = yes, its on and going off
  2458.     mov    ah,ioctl
  2459.     mov    al,7            ; get output status of printer
  2460.     push    bx
  2461.     mov    bx,4            ; file handle for system printer
  2462.     int    dos
  2463.     pop    bx
  2464.     jc    trnpr1            ; c = printer not ready
  2465.     cmp    al,0ffh            ; Ready status?
  2466.     je    trnpr2            ; e = Ready
  2467. trnpr1: call    beep            ; Not Ready, complain
  2468.     jmp    trnpr3            ; and ignore request
  2469. trnpr2: xor    ourarg.flgs,prtscr    ; flip the flag
  2470. trnpr3: pop    ax
  2471.     clc
  2472.     ret
  2473.  
  2474. klogon    proc    near            ; resume logging (if any)
  2475.     test    flags.capflg,logses    ; session logging enabled?
  2476.     jz    klogn            ; z = no, forget it
  2477.     or    ourarg.flgs,capt    ; turn on capture flag
  2478.     push    bx
  2479.     mov    bx, argadr        ; update kermits capture flag
  2480.     or    [bx].flgs, capt
  2481.     pop    bx
  2482. klogn:    clc
  2483.     ret
  2484. klogon    endp
  2485.  
  2486. klogof    proc    near            ; suspend logging (if any)
  2487.     and    ourarg.flgs,not capt    ; stop capturing
  2488.     push    bx
  2489.     mov    bx, argadr
  2490.     and    [bx].flgs, not capt     ; update kermits capture flag
  2491.     pop    bx
  2492.  
  2493. klogo:    clc
  2494.     ret
  2495. klogof    endp
  2496.  
  2497. snull:    mov    ah,0            ; send a null
  2498.     call    outchr            ; send without echo or logging
  2499.     clc
  2500.     ret
  2501.  
  2502. kdos:    mov    al,'P'            ; Push to DOS
  2503.     jmp    short cmdcom
  2504. cstatus:mov    al,'S'            ; these commands exit Connect mode
  2505.     jmp    short cmdcom
  2506. cquit:    mov    al,'C'
  2507.     jmp    short cmdcom
  2508. cquery: mov    al,'?'
  2509.     jmp    short cmdcom
  2510. cmdcom: mov    kbdflg,al        ; pass char to msster.asm via kbdflg
  2511.     stc                ; say exit Connect mode
  2512.     ret
  2513.  
  2514. ; Jumping here is the same as a ret.
  2515.  
  2516. R    PROC    NEAR
  2517.     ret
  2518. R    ENDP
  2519.  
  2520. code    ends
  2521.     end
  2522.