home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / msxgri.asm < prev    next >
Assembly Source File  |  2020-01-01  |  54KB  |  1,918 lines

  1.        name msxgri
  2. ; File MSXGRI.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. ; Grid Compass dependent file for MS-DOS Kermit
  9. ;  Use with msugri.asm keyboard translator file.
  10. ; Edit history
  11. ; 2 March 1991 version 3.10
  12. ; Last edit:
  13. ; 2 March 1991
  14. ; Dec.    7, 1990. Put modem in verbose mode at startup.
  15. ;  Change machnm from GRID to GRiD. 
  16. ; Nov. 27, 1990. Add call to getbaud in serini.
  17. ; Nov. 24, 1990. Remove reference to prserr to make link happy.
  18. ; Nov. 21, 1990. Fix so both serial and modem drivers need not be loaded 
  19. ;  if they are not used. [jan]
  20. ; October 1990. Cosmetic fixes.
  21. ; August 1990. Select tek enable/ disable in termtb
  22. ; 22 february 1990 Fix up baud setting and and string parsing
  23. ; procedurs [jan]
  24. ; 23 January 1990. Version 3. Fix up comnd calls. Chance PRTCHR so
  25. ; clc for character, stc for no character. clc in OUTPRT. Include
  26. ; baud table and portval. Add BAUDST from MSXIBM.ASM. Zap DODISK. [jan]
  27. ; 3 February 1989.
  28. ; Call "call cmblnk" call call to tekcls so tek screen is cleared
  29. ;  even if it's not initialized
  30. ;  Take out II in machnm since this also works on 1101 [jan]
  31. ; 5 January 1989. Fix up SERINT, SERINI, SERRST, and SENDBR.
  32. ; Implement GETMODEM and SERHNG.  Send 'ATE1' to modem in LCLINI. [jan]
  33. ; 13 Dec 1988 Move screen clear and terminal type toggling to this file.
  34. ;  Do other small cleanups. [jrd]
  35. ;
  36. ; John Nyenhuis      Purdue University  School of Electrical Engineering
  37. ; West Lafayette IN 47907   (317)494-3524     nyenhuis@ecn.purdue.edu
  38. ; November 1988
  39. ; Fix up for Tektronix emulation
  40. ; User can specify screen size by set term 112x or set term 113x
  41. ; Call sbrk to get memory for Tektronix and ascii screen saves
  42. ; enable automatic entry into Tektronix emulator
  43. ; Most characters are now written to screen through bios rather than with DOS
  44. ; keyboard is checked once each 8 read of serial port for added speed
  45. ; Xon/Xoff flow control enabled
  46. ; vt52 terminal emulation taken out (all it did was to not restore the cursor)
  47. ;
  48. ; 1 July 1988 Version 2.31
  49. ; 12 June 1988 Add error recovery if serial port fails to initialize, reduce
  50. ;  serial port buffer to 1000 bytes. [jrd]
  51. ; 11 Jan 1988 Add 2.30 features. [jrd]
  52. ; 1 Jan 1988 version 2.30
  53. ;
  54. ; Jim Noble
  55. ; Planning Research Corporation
  56. ; 1500 Planning Research Drive
  57. ; Mail Stop 5S3
  58. ; McLean, VA  22102
  59. ; May, 1985
  60. ; Add global entry point vtstat for use by Status in mssset.
  61. ; Added register save/restore in procedure getbaud.
  62. ; Joe R. Doupnik 12 March 1986
  63. ; Add global procedures ihosts and ihostr to handle host initialization
  64. ; when packets are to be sent or received by us,resp. 24 March 1986
  65. ; Add global procedure dtrlow (without worker serhng) to force DTR & RTS low
  66. ; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd]
  67. ; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
  68. ;  to a file. Just does a beep for now. 13 April 1986 [jrd]
  69. ; In proc Outchr add override of xon from chkxon sending routine.
  70. ;  This makes a hand typed Xoff supress the xon flow control character sent
  71. ;  automatically as the receiver buffer empties. 20 April 1986 [jrd]
  72.  
  73.  
  74. saveregs macro
  75.       push  ax
  76.       push  bx
  77.       push  cx
  78.       push  dx
  79.       push  es
  80.       push  di
  81.       push  si
  82.       push  ds
  83.       pushf
  84. endm
  85.  
  86. restoreregs  macro
  87.      popf
  88.      pop   ds
  89.      pop   si
  90.      pop   di
  91.      pop   es
  92.      pop   dx
  93.      pop   cx
  94.      pop   bx
  95.      pop   ax
  96. endm
  97.  
  98. ;; below 40 publics are the minimum necessary
  99.        public  baudst,ihostr,bdtab,getbaud,chrout
  100.        public  pcwait,putmod,serrst,trnprs,prtchr
  101.        public  poscur,outchr,dtrlow,vts,puthlp
  102.        public    vtstat,coms,cquery,ctlu,shomodem
  103.        public  portval,getmodem,term,dumpscr,cmblnk
  104.        public  cquit,locate,clearl,machnam,lclini
  105.        public  sendbl,comptab,sendbr,clrmod,cstatus
  106.        public  termtb,serhng,clrbuf,beep, serini
  107. ;;additional system dependent publics
  108.     public    klogon,kdos,snull,klogof
  109.     public bigscreen        ; bigscreen=1 if it's big [jan]
  110.     public    termtog            ; toggle terminal types [jan]
  111.     public    kclrscn, getflgs, setchtab
  112.  
  113. cmcfm    equ    cmeol           ; equates to account for 3.0
  114. cmtxt    equ    cmline           ; names changes in
  115. cmfile    equ    cmword           ; mssdef.h
  116.  
  117. baudsiz equ    18            ; entries in baud table
  118. false    equ    0
  119. true    equ    1
  120. print_out equ    05h            ; dos function to print to printer
  121. prtscr    equ    80h            ; print screen pressed
  122.  
  123. gbuflen equ    1000        ; max bytes grid internal buffer holds
  124. mntrgh    equ    gbuflen/2    ; High point = 1/2 of buffer full.
  125. mntrgl    equ    gbuflen/4     ; Low point = 1/4 buffer full. [jrd]
  126.  
  127. CLK_INT equ    1ch*4        ; clock interrupt
  128. gserial equ    81h        ; grid serial port interrupt
  129. gmodem    equ    82h        ; grid modem port interrupt
  130. ginit    equ    0        ; function 0 - initialize port
  131. gread    equ    1        ; function 1 - read data
  132. gwrite    equ    2        ; function 2 - write data
  133. gwcmd    equ    4        ; function 4 - write command
  134. grstat    equ    5        ; function 5 - read status
  135. gflush    equ    6        ; function 6 - buffer flush
  136. ggbaud    equ    7        ; function 7 - get baud
  137. gsbaud    equ    8        ; function 8 - set baud
  138. gspar    equ    9        ; function 9 - set parity
  139. gsdata    equ    10        ; function 10 - set data bits
  140. gssbit    equ    11        ; function 11 - set stop bits
  141. gbufass equ    12        ; function 12 - buffer assign
  142. gcharto equ    13        ; function 13 - set character timeout
  143. gcts    equ    19        ; function 19 - clear to send timeout
  144. gbrkon    equ    0effH        ; function 14 - set break on
  145. gbrkoff equ    0e00H        ; function 14 - set break off
  146. scnstrt equ    400h        ; starting address of screen area (page 0)
  147. maxscnwrds equ       256*32    ; max number of words in screen memory area
  148. tekonnum equ 18            ; enable tek auto entry
  149. tekoffnum  equ 19
  150. ttbig    equ    12        ;big screen
  151. ttsmall equ    23        ;small screen
  152.  
  153. data   segment public 'data'
  154.     extrn    flags:byte, trans:byte
  155.  
  156.     extrn dmpname:byte
  157.     extrn    kbdflg:byte, rxtable:byte
  158.     extrn    tekflg:byte        ; used in msggri  [jan]
  159.     extrn    denyflg:word        ; controls tek autoentry etc
  160.     extrn    dosnum:word
  161.     extrn    repflg:byte, diskio:byte  ; for replay feature
  162.     extrn    kbdflg:byte  ;    in telnet
  163.  
  164.  
  165. ; structure for status information table sttab.
  166. stent    struc
  167. sttyp    dw  ?       ; type (actually routine to call)
  168. msg    dw  ?       ; message to print
  169. val2    dw  ?       ; needed value: another message, or tbl addr
  170. tstcel    dw  ?       ; address of cell to test, in data segment
  171. basval    dw  0       ; base value, if non-zero
  172. stent    ends
  173.  
  174.    ; table with datacomm status for the status command
  175. vtstbl stent <srchkw,tekstatustxt,termtb,tekbyte> ; tell tek able/disable
  176.        stent <srchkw,screenstatustxt,termtb,screenbyte> ; tell screen size
  177.    dw 0       ; end of table
  178.  
  179.  
  180.  
  181. tekstatustxt db 'Tek Auto Entry: $'
  182. tekbyte db tekonnum        ; tek auto entry code
  183. screenstatustxt db 'Screen Size: $'
  184. screenbyte db ttsmall
  185. prtrdy    db    true          ; when false, exit connect mode
  186. machnam db    'GRiD_COMPASS$'
  187. msmsg1    db    cr,lf,'  Modem is not ready: DSR is off$'
  188. msmsg2    db    cr,lf,'  Modem is ready:     DSR is on$'
  189. msmsg3    db    cr,lf,'  no Carrier Detect:  CD  is off$'
  190. msmsg4    db    cr,lf,'  Carrier Detect:     CD  is on$'
  191. msmsg5    db    cr,lf,'  no Clear To Send:   CTS is off$'
  192. msmsg6    db    cr,lf,'  Clear To Send:      CTS is on$'
  193. msmsg7    db    cr,lf,'  Modem is not used by the Network$'
  194.  
  195.  
  196. mdmhand        db    0        ;used by showmodem
  197. mdmstr        db   'ATE1Q0V1S7=25,',cr,lf     ;init modem string
  198. mdmstrlen    equ   $-mdmstr        ;length of modem string
  199.  
  200. ;;new stuff to scan escape sequences from comm port  [jan]
  201. stringtab    dw    tekst1,tekst2    ; strings for matching
  202. numstrings    equ   2            ; number of strings to match
  203. disptab        dw    toteknoplay,totekplay      ; dispatch table
  204. tekst1        db    escape,'[?38h',0    ;1st string to get into tek mode [jan]
  205. tekst2        db    escape,FF,0    ;2nd string to get into tek mode [jan]
  206.  
  207. stringchekbuff       db     16 dup (0)
  208. stringchekcnt       dw     0           ;characters already in buffer
  209. matchsofar    dw    false        ; no match yet
  210. match        dw    0
  211. playem        db    false        ;don't play back switch characters
  212. ; end of data for string scanning
  213.  
  214.  
  215. scnwrds        dw    240*20        ;words in small screen [jan]
  216. scrsavseg    dw    ?            ;segment for screen save [jan]
  217. bigscreen    db    0            ;=1 for big [jan]
  218. prevport    db    86        ;port number on previous connect
  219. portbusy    db    0            ;serial port not yet busy
  220. save_ax        dw    ?            ;temp location to save ax
  221. save_ds        dw    ?            ;temp location to save ds
  222. curini    db    0            ; [gaw@prc]
  223. cursav    db    ESCAPE,'[s','$'        ; [gaw@prc]
  224. curres    db    ESCAPE,'[u','$'        ; [gaw@prc]
  225. curon    db    ESCAPE,'[3;3z','$'    ; [gaw@prc]
  226. curoff    db    ESCAPE,'[3;4z','$'    ; [gaw@prc]
  227.  
  228. erms20    db    cr,lf,'?Warning: System has no disk drives$'
  229. erms40    db    cr,lf,'?Warning: Unrecognized baud rate$'
  230. badbd    db    cr,lf,'Unimplemented baud rate$'
  231. crlf    db    cr,lf,'$'
  232. comphlp db    cr,lf,'1 (SERIAL)  2 (MODEM)$'        ; [19b] [gaw@prc]
  233. hngmsg    db    cr,lf,' The phone should have hungup.',cr,lf,'$'
  234. hnghlp    db    cr,lf,' The modem control lines DTR and RTS for the current'
  235.     db    ' port are forced low (off)'
  236.     db    cr,lf,' to hangup the phone. Normally, Kermit leaves them'
  237.     db    ' high (on) when it exits.'
  238.     db    cr,lf,'$'
  239. rdbuf    db    80 dup (?)    ; temp buf
  240. noimp    db    cr,lf,'?Not implemented.$'
  241. delstr    db    BS,' ',BS,'$'    ; Delete string
  242. clrlin    db    cr,ESCAPE,'[0K','$'
  243. portin    db    0        ; has clock int vector been initialized?
  244. xofsnt    db    0        ; Say if we sent an XOFF.
  245. xofrcv    db    0        ; Say if we received an XOFF.
  246. insrvc    db    false            ; Say if in service on XON/XOFF interrupt
  247. parmsk    db    ?        ; parity mask, 0ffh for no parity, 07f with.
  248. flowoff db    ?        ; flow-off char, Xoff or null (if no flow)
  249. flowon    db    ?        ; flow-on char, Xon or null
  250. captrtn dw    ?        ; routine to call for captured output
  251. invseq    db    ESCAPE,'[7m$'    ; Reverse video.
  252. nrmseq    db    ESCAPE,'[0m$'    ; Normal mode.
  253. ivlseq    db    79 dup (' '),cr,'$'    ; Make a line inverse video
  254. tmp    db    ?,'$'
  255. temp    dw    0
  256. temp1    dw    ?        ; Temporary storage.
  257. temp2    dw    ?        ; Temporary storage.
  258. fncerr    db    cr,lf,'Error on function '
  259. fnctype db    'X with a status return of '
  260. fncstat db    'Y$'
  261. argadr    dw    ?        ; address of arg blk
  262.  
  263. ; key redefinitions
  264. setktab db    0
  265.  
  266. setkhlp db    0
  267.  
  268. ; Entries for choosing communications port.
  269.  
  270. comptab db    2        ; number of entries
  271.     mkeyw    'Serial',1
  272.     mkeyw    'Modem',2
  273.  
  274.  
  275.  
  276. setchtab  db   1; set file character-set table
  277.   mkeyw      'CP437',437
  278.  
  279.  
  280. termtb    db    6
  281.     mkeyw    '112x',ttsmall
  282.     mkeyw    '113x',ttbig
  283.     mkeyw    'ANSI',ttgenrc
  284.     mkeyw    'Tek4010',tttek
  285.     mkeyw    'EnableTek',tekonnum
  286.     mkeyw    'DisableTek', tekoffnum
  287. defbaud     equ 7         ; defauld baud rate is 1200
  288.  
  289.  
  290. port1    prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
  291. port2    prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
  292.  
  293.  
  294. portval dw    port1            ; Default is to use port 1
  295.  
  296. bdtab    db    16            ; Baud rate table
  297.  
  298.     mkeyw    '50',0
  299.     mkeyw    '75',1
  300.     mkeyw    '110',2
  301.     mkeyw    '134',3
  302.     mkeyw    '150',4
  303.     mkeyw    '300',5
  304.     mkeyw    '600',6
  305.     mkeyw    '1200',7
  306.     mkeyw    '1800',8
  307.     mkeyw    '2000',9
  308.     mkeyw    '2400',10
  309.     mkeyw    '3600',11
  310.     mkeyw    '4800',12
  311.     mkeyw    '7200',13
  312.     mkeyw    '9600',14
  313.     mkeyw    '19200',15
  314.  
  315. modbdtab  db  2             ; baud entries legal for modem
  316.        mkeyw   '300',5
  317.        mkeyw   '1200',7
  318.  
  319.  
  320.  
  321. ; variables for serial interrupt handler
  322.  
  323. gbuffer db    gbuflen DUP(?)    ; large internal buffer for grid [gaw@prc]
  324.  
  325. source    db    bufsiz DUP(?)    ; Buffer for data from port
  326. bufout    dw    0        ; buffer removal ptr
  327. count    dw    0        ; Number of chars in int buffer
  328. bufin    dw    0        ; buffer insertion ptr
  329. telflg    db    0        ; Are we acting as a terminal
  330. clreol    db    ESCAPE,'[0K$'
  331. blank    db    ESCAPE,'[2J$'
  332. movcur    db    ESCAPE,'['
  333. colno    db    20 dup (?)
  334. ten    db    10
  335. ourarg    termarg <>
  336. keydelay dw    0        ;for periodically checking the keyboard
  337. clkdelay dw    0        ;check flow control every 4th tick
  338. serclk     db    false        ;clock interrupt resets-for xon/xoff
  339. charout dd    ?        ; pointer to direct screen write [jan]
  340.  
  341. savclko dw    ?        ; save clock tick interrupt vector offset
  342. savclks dw    ?        ; save clock tick interrupt vector segment
  343.  
  344.  
  345. data   ends
  346.  
  347. code    segment public 'code'
  348.     extrn    comnd:near, dopar:near, defkey:near
  349.     extrn    sleep:near, msuinit:near, keybd:near
  350.     extrn    tekcls:near
  351.     extrn    tekemu:near     ; entry point to msggri [jan]
  352.     extrn    sbrk:near        ; memory allocator in mssker [jan]
  353.     extrn    srchkw:near, statc:near
  354.     assume    cs:code,ds:data
  355.  
  356. ; local initialization
  357. lclini    proc    near
  358.     mov    dosnum,200h      ; force dosnum to 2.00 so replay proc works
  359.     mov    prtrdy,true    ; port is ready
  360.     push    es         ;first set up for direct screen writing [jan]
  361.     push    bx        ; See page A1 of the GRiD DOS Manual
  362.     mov    ax,0
  363.     mov    es,ax
  364.     les    bx,es:[200h]    ; look in Bios for address of charout
  365.     mov    ax,es:[bx+20h]    ; offset of charout in ax
  366.     mov    bx,es:[bx+22h]    ; seg of charout routine in bx
  367.                 ; now store addr in a pointer that is used
  368.                 ; for indirect calls to charout
  369.     mov    word ptr charout,ax
  370.     mov    word ptr charout+2,bx
  371.     pop    bx        ; restore the registers
  372.     pop    es
  373.              ;we're all set up for direct screen write [jan]
  374.     mov    tekflg,0    ;tek emulator not initialized [jan]
  375.     mov    portin,0    ; serial port not yet initialized
  376.     mov    flags.vtflg,0    ; turn off terminal emulation [gaw@prc]
  377.     call    msuinit        ; init keyboard translator
  378.     call    scrsavinit    ;set up screen memory
  379. ;     call     serini         ; initialize serial port
  380.     ret
  381. lclini    endp
  382.  
  383. ;scrsavinit sets up memory block for saving tektronix and
  384. ; alpha screens two pages of screen memory are requested
  385. ; first page is for alpha, second is for tektronix
  386.  
  387. scrsavinit   proc   near       ;set up memory block to save     [jan]
  388.     push    ax
  389.     push    cx
  390.     push    es
  391.     push    di
  392.     mov    ax,maxscnwrds*4+100    ; want 4*maxscnwrds bytes
  393.     call    sbrk            ; ax will have the segment
  394.     mov    scrsavseg,ax        ; put it in our data segment
  395.     xor    ax,ax            ; ax=0--clear screen buffer
  396.     mov    di,ax            ; di=0
  397.     mov    cx,2*maxscnwrds+6    ; number of words to be 0
  398.     mov    es,scrsavseg        ; es points to memory segment
  399.     rep    stosw            ; zero memory location [jrd]
  400.     pop    di
  401.     pop    es
  402.     pop    cx
  403.     pop    ax
  404.     ret
  405. scrsavinit endp
  406.  
  407.  
  408. ; Clear the input buffer before sending a packet.
  409.  
  410. CLRBUF    PROC    NEAR
  411.     cmp     repflg,0     ; doing replay?
  412.     je     clrb0         ; e => no replay
  413.     ret            ; don't clear if replaying
  414. clrb0:
  415.     push     ax         ;need to save for CROSHAIR in msggri
  416.     cli
  417.     mov    ax,offset source
  418.     mov    bufin,ax
  419.     mov    bufout,ax
  420.     mov    count,0
  421.     sti
  422. clrb1:    call    prtchr            ; get a character
  423.     jnc    clrb1            ; until there aren't any more
  424.     pop    ax
  425.     clc
  426.     ret
  427. CLRBUF    ENDP
  428.  
  429. ; Common routine to clear to end-of-line
  430.  
  431. CLEARL    PROC    NEAR
  432.     mov dx,offset clreol
  433.     mov ah,prstr
  434.     int dos
  435.     ret
  436. CLEARL    ENDP
  437.  
  438.  
  439. ; SHOW MODEM, displays current status of lines DSR, CD, and CTS.
  440. ; Uses byte mdmhand, the modem line status register. [jrd]
  441. shomodem proc    near
  442.     mov    ah,cmcfm        ; get a confirm
  443.     call    comnd
  444.     jnc    shomod0
  445.     ret                 ; get out if error
  446. shomod0:
  447.     mov    dx,offset msmsg7    ; no modem status for network
  448.     call    getmodem        ; get modem status
  449.     mov    mdmhand,al
  450.     mov    ah,prstr
  451.     mov    dx,offset msmsg1    ; modem ready msg
  452.     test    mdmhand,20h        ; is DSR asserted?
  453.     jz    shomd1            ; z = no
  454.     mov    dx,offset msmsg2    ; say not asserted
  455. shomd1: int    dos
  456.     mov    dx,offset msmsg3    ; CD asserted msg
  457.     test    mdmhand,80h        ; CD asserted?
  458.     jz    shomd2            ; z = no
  459.     mov    dx,offset msmsg4    ; say not asserted
  460. shomd2: int    dos
  461.     mov    dx,offset msmsg5    ; CTS asserted msg
  462.     test    mdmhand,40h        ; CTS asserted?
  463.     jz    shomd3            ; z = no
  464.     mov    dx,offset msmsg6    ; say not asserted
  465. shomd3: mov    ah,prstr
  466.     int    dos
  467.     stc
  468.     ret               ; carry set upon failure
  469. shomodem endp
  470.  
  471. ; Get modem status and set global byte mdmhand. Preserve all registers.
  472. ; status in al ; ax not preserved   [jan]
  473.  
  474. getmodem proc near
  475.     push     bx            ;need to save everybody
  476.     push     cx
  477.     push     dx
  478.     pushf
  479.     mov     ah,5            ;grid status call
  480.     call     grdfnc
  481.     mov     al,ah           ;ah contains status if no error
  482.     popf
  483.     pop     dx
  484.     pop     cx
  485.     pop     bx
  486.     clc               ; carry clear upon success
  487.     ret
  488. getmodem endp
  489.  
  490.  
  491. ; Do a grid function call to the correct com port and return
  492.  
  493. GRDFNC    PROC    NEAR
  494.     or    portbusy,1     ;so we know port is busy
  495.     push    es        ; save es reg
  496.     push    ds        ; then mov ds to es
  497.     pop    es
  498.     push    ax        ; save function call and value in al
  499.     add    ah,"0"        ; make function code printable
  500.     mov    fnctype,ah    ; and save in error message
  501.     pop    ax        ; restore ax
  502.     cmp    flags.comflg,1    ; serial port or modem? [gaw@prc]
  503.     jne    grdfnc1        ; if modem, do other int [gaw@prc]
  504.     int    gserial        ; else do serial port function call [gaw@prc]
  505.     jmp    short grdfnc2    ; skip other int [gaw@prc]
  506. grdfnc1:int    gmodem        ; do modem port function call [gaw@prc]
  507. grdfnc2:jnc    grdfnc3        ; skip error msg if carry not set
  508.     add    al,"0"        ; make error code printable
  509.     mov    fncstat,al    ; and put in error message
  510.     mov    ah,prstr
  511.     push    dx
  512.     mov    dx,offset fncerr ; Give an error message
  513.     int    dos
  514.     pop    dx
  515. grdfnc3:pop    es        ; restore es
  516.     and    portbusy,0feH    ; clear bit 0
  517.     ret
  518. GRDFNC    ENDP
  519.  
  520.  
  521.  
  522. ; Set the baud rate for the current port, based on the value
  523. ; in the portinfo structure.  Returns carry clear.
  524.  
  525. BAUDST    PROC    NEAR
  526.     saveregs
  527.     mov    dx,offset bdtab        ; baud rate table for serial
  528.     mov    si,portval
  529.     mov    ax, offset port2    ; structure for modem
  530.     cmp    ax,si            ; using the modem
  531.     jne    baudst1            ; ne= > yes, using modem
  532.     mov    dx, offset modbdtab
  533. baudst1:xor    bx,bx            ; help is the table itself
  534.     mov    ah,cmkey        ; get keyword
  535.     call    comnd
  536.     jc    baudst2            ; c = failure
  537.     push    bx            ; save result
  538.     mov    ah,cmeol        ; get confirmation
  539.     call    comnd
  540.     pop    bx
  541.     jc    baudst2            ; c = failure
  542.     mov    si,portval        ; get address of baud structure
  543.     mov    ax,[si].baud        ; remember original value
  544.     mov    [si].baud,bx        ; set the baud rate
  545.     call    dobaud            ; use common code
  546.     clc
  547. baudst2:restoreregs 
  548.     ret
  549. BAUDST    ENDP
  550.  
  551. ; Set the baud rate for the current port, based on the value
  552. ; in the portinfo structure.  Returns normally.
  553. ; illegal rate not checked; baudst does this
  554.  
  555. DOBAUD    PROC    NEAR
  556.     saveregs
  557.     mov    bx,portval
  558.     mov    ax,[bx].baud    ; ax has baud rate from bdtab
  559.     mov    ah,gsbaud    ; set up to set the port baudrate
  560.     call    grdfnc        ; do a grid function call to a com port
  561.     restoreregs
  562.     ret
  563. DOBAUD    ENDP
  564.  
  565. ; Send a break out the current serial port.  Returns normally.
  566. sendbr    proc    near
  567.     push    ax
  568.     mov    ax,250        ;250 milliseconds long
  569.     call    sendbrt        ;do a timed break
  570.     pop    ax        ;restore ax
  571.     ret
  572. sendbr    endp
  573.  
  574. ; Send a long break out the current serial port.  Returns normally.
  575. sendbl    proc    near
  576.     push    ax
  577.     mov    ax,1400        ;1400 milliseconds long
  578.     call    sendbrt        ;do a timed break
  579.     pop    ax        ;restore ax
  580.     ret
  581. sendbl    endp
  582.  
  583. ;send timed break.  ax has length in milliseconds.
  584. sendbrt proc    near
  585.     mov    portbusy,2    ; port is occupied
  586.     push    cx        ; save cx
  587.     push    ax        ; save length of break
  588.     mov    ax,gbrkon    ; setup to do break on [gaw@prc]
  589.     call    grdfnc        ; do break on
  590.     pop    ax        ; get time to delay
  591.     call    pcwait        ; wait awhile
  592.     mov    ax,gbrkoff    ; setup to do break off [gaw@prc]
  593.     call    grdfnc        ; do break off
  594.     mov    ax,50
  595.     call    pcwait        ; wait awhile
  596.     pop    cx        ; restore
  597.     mov    portbusy,0    ; port no longer busy
  598.     clc
  599.     ret            ; And return
  600. sendbrt     endp
  601.  
  602.  
  603. ; Send char in ah out the serial port. Checks flow control.
  604. ; clc if success
  605. OUTCHR    PROC    NEAR
  606.     push    cx
  607.     push    bx
  608.     cmp    portin,0    ; port initialized?
  609.     jne    outchr0        ; ne=> not initialized
  610.     call    serini        ; initialize port
  611. outchr0:
  612.     mov    bx,portval
  613.     cmp    [bx].floflg,0    ; Are we doing flow control
  614.     pop    bx
  615.     je    outch2        ; No, just continue
  616.     xor    cx,cx        ; clear counter
  617.     cmp    ah,flowoff    ; sending xoff?
  618.     jne    outch1        ; ne = no
  619.     mov    xofsnt,false    ; supress xon from chkxon buffer routine
  620. outch1: cmp    xofrcv,true    ; Are we being held?
  621.     jne    outch2        ; No - it's OK to go on
  622.     loop    outch1        ; held, try for a while
  623.     mov    xofrcv,false    ; timed out, force it off and fall thru
  624. outch2:
  625.     mov    al,ah          ; parity routine expects character in al
  626.     call    dopar          ; do the parity [jan ]
  627.     mov    byte ptr temp,al ; put character in buffer
  628.     push    di        ; Save register
  629.     mov    cx,1        ; set up to write one char to a grid port
  630.     mov    di,offset temp
  631.     mov    ah,gwrite
  632.     call    grdfnc        ; go write a character
  633.     pop    di        ; restore saved registers
  634.     pop    cx
  635.      clc
  636.      ret             ; clc means success
  637. OUTCHR    ENDP
  638.  
  639. ; This routine blanks the screen.
  640.  
  641. CMBLNK    PROC    NEAR
  642.     push    ax
  643.     push    dx
  644.     mov    ah,prstr
  645.     mov    dx,offset blank
  646.     int    dos
  647.     pop    dx
  648.     pop    ax
  649.     clc             ; stay in connect mode
  650.     ret
  651. CMBLNK    ENDP
  652.  
  653. LOCATE    PROC    NEAR
  654.     mov    dx,0        ; Go to top left corner of screen.
  655.     jmp    poscur        ; callret...
  656. LOCATE    ENDP
  657.  
  658.  
  659. ; Get the current baud rate from the serial card and set it
  660. ; in the portinfo structure for the current port.  Returns normally.
  661. ; This is used during initialization.
  662.  
  663. GETBAUD PROC    NEAR
  664.     push    ax        ; save some regs
  665.     push    bx
  666.     push    cx
  667.     push    dx
  668.     mov    ah,ggbaud    ; set up to get port baud rate
  669.     call    grdfnc        ; and go get it
  670.     mov    al,ah        ; mov baudrate into al
  671.     mov    ah,0        ; and zero upper part of ax
  672.     mov    bx,portval
  673.     mov    [bx].baud,ax    ; Set baud rate
  674.     pop    dx        ; restore regs
  675.     pop    cx
  676.     pop    bx
  677.     pop    ax
  678.     clc                ; msxibm does this
  679.     ret
  680. GETBAUD ENDP
  681.  
  682. ; Returns with char in al, # of chars in buffer in dx and carry clear.
  683. ; Carry set means no character available.
  684. PRTCHR    PROC    NEAR
  685.     cmp    repflg,0        ; doing replay?
  686.     je    prtch0a            ; e => not doing replay
  687.     jmp    getrepchr        ; get replay character if in replay
  688. prtch0a: cmp    portin,0        ; port not initialized
  689.      jne     prtch0b        ; 0=> not initialized
  690.      call    serini
  691. prtch0b:
  692.     cmp    serclk,true    ; should we check flow control? [jan][jrd]
  693.     jne    prtch0        ;ne = no
  694.     call    flowchek    ;checkout flow control
  695. prtch0: push    si
  696.     cmp    count,0        ; any characters?
  697.     jne    prtch2        ; ne = yes, get from buffer
  698. prtch1:
  699.     push    di
  700.     push    bx
  701.     push    cx
  702.     mov    cx,bufsiz    ; set up to read from grid port buffer
  703.     mov    di,offset source
  704.     mov    ah,gread
  705.     call    grdfnc
  706.     pop    cx        ; restore saved registers
  707.     pop    bx
  708.     pop    di
  709.  
  710.     mov    count,ax    ; reset count
  711.     or    ax,ax
  712.     jz    prtch4        ; still no chars
  713.     mov    bufout,offset source ; this is output ptr
  714. prtch2:
  715.     dec    count
  716.     mov    dx,count    ; return count in dx
  717.     mov    si,bufout
  718.     cld
  719.     lodsb            ; get character
  720.     mov    bufout,si    ; update ptr
  721.     pop    si
  722.     clc            ; clc means a character
  723.     ret
  724. prtch4:    pop    si
  725.     stc              ; stc means no characters
  726.     ret
  727. PRTCHR    ENDP
  728.  
  729. ;FLOWCHEK --Check to see if we need to do flow control
  730. ;this gets called in connect mode each 4 ticks of the clock
  731. ;both SERINT and PRTCHR call this. SERINT will not call FLOWCHEK
  732. ;if the port is busy
  733. ;
  734. ;
  735. FLOWCHEK   PROC      NEAR
  736.        or      portbusy,2          ;bit 1 set if in flowchek
  737.  
  738. ;    code below largely taken from old SERINT
  739.        push    ax
  740.        push    bx
  741.        push    cx
  742.        push    dx
  743.        push    di
  744.        cld
  745.        mov     bx,portval
  746.        cmp     [bx].floflg,0   ; Doing flow control?
  747.        je      intdone        ; No, just leave.
  748.        mov     ah,grstat       ; get the buffer count
  749.        call    grdfnc
  750.        cmp     xofsnt,true     ; Have we sent an XOFF?
  751.        je      flowchek1    ; Yes.
  752.        cmp     cx,mntrgh       ; Past the high trigger point?
  753.        jbe     intdone           ; No, we're within our limit
  754.        mov     ah,flowoff      ; Get the XOFF
  755.        or      ah,ah           ; null (no flow control)?
  756.        jz      intdone           ; z = yes, do nothing
  757.        mov     byte ptr temp,ah ; put character in buffer
  758.        mov     cx,1           ; set up to write one char to a grid port
  759.        mov     di,offset temp
  760.        mov     ah,gwrite
  761.        call    grdfnc           ; go write a character
  762.        mov     xofsnt,true     ; Remember we sent it
  763.        jmp     intdone
  764.  
  765. flowchek1:
  766.        cmp     cx,mntrgl       ; below the low trigger point?
  767.        ja      intdone           ; no, don't send XON
  768.        mov     ah,flowon       ; get the XON
  769.        or      ah,ah           ; null?
  770.        jz      intdone           ; z = yes, do nothing
  771.        mov     byte ptr temp,ah ; put character in buffer
  772.        mov     cx,1           ; set up to write one char to a grid port
  773.        mov     di,offset temp
  774.        mov     ah,gwrite
  775.        call    grdfnc           ; go write a character
  776.        mov     xofsnt,false    ; remember we sent it
  777. intdone:pop    di
  778.     pop    dx
  779.     pop    cx
  780.     pop    bx
  781.     pop    ax
  782.     mov    serclk,false
  783.     mov    portbusy,0    ;port no longer busy
  784.     ret
  785. FLOWCHEK ENDP
  786.  
  787. ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
  788. ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
  789. ; else repeat cycle. Requires that the port be initialized before hand.
  790. ; Ihosts is used by the local send-file routine just after initializing
  791. ; the serial port.
  792. ; 22 March 1986 [jrd]
  793.  
  794. IHOSTS    PROC    NEAR
  795.     push    ax        ; save the registers
  796.     push    bx
  797.     push    cx
  798.     push    dx
  799.     mov    bx,portval    ; port indicator
  800.     mov    ax,[bx].flowc    ; put Go-ahead flow control char in ah
  801.     or    ah,ah        ; don't send null if flow = none
  802.     jz    ihosts1        ; z = null
  803.     call    outchr        ; send it (release Host's output queue)
  804.      nop            ; outchr can do skip return
  805.      nop
  806.      nop
  807. ihosts1:call    clrbuf        ; clear out interrupt buffer
  808.     pop    dx        ; empty buffer. we are done here
  809.     pop    cx
  810.     pop    bx
  811.     pop    ax
  812.     ret
  813. IHOSTS    ENDP
  814.  
  815. ; IHOSTR - initialize the remote host for our reception of a file by
  816. ; sending the flow-on character (XON typically) to release any held
  817. ; data. Called by receive-file code just after initializing the serial
  818. ; port.        22 March 1986 [jrd]
  819. IHOSTR    PROC    NEAR
  820.     push    ax        ; save regs
  821.     push    bx
  822.     push    cx
  823.     mov    bx,portval    ; port indicator
  824.     mov    ax,[bx].flowc    ; put Go-ahead flow control char in ah
  825.     or    ah,ah        ; don't send null if flow = none
  826.     jz    ihostr1        ; z = null
  827.     call    outchr        ; send it (release Host's output queue)
  828.      nop            ; outchr can do skip return
  829.      nop
  830.      nop
  831. ihostr1:pop    cx
  832.     pop    bx
  833.     pop    ax
  834.     ret
  835. IHOSTR    ENDP
  836.  
  837. DTRLOW    PROC    NEAR        ; Global proc to Hangup the Phone by making
  838.                 ; DTR and RTS low.
  839.     mov    ah,cmtxt    ; allow text to be able to display help
  840.     mov    bx,offset rdbuf ; dummy buffer
  841.     mov    dx,offset hnghlp ; help message
  842.     call    comnd        ; get a confirm
  843.     jnc    dtrlow1          
  844.     ret            ; get out if error
  845. dtrlow1:
  846.     call    serhng        ; drop DTR and RTS
  847.     mov    ah,prstr    ; give a nice message
  848.     mov    dx,offset hngmsg
  849.     int    dos
  850.     clc
  851.     ret            ; clear carry for success
  852. DTRLOW    ENDP
  853.  
  854. ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
  855. ; to terminate the connection. 29 March 1986 [jrd]
  856. ; Calling this twice without intervening calls to serini should be harmless.
  857. ; Returns normally.
  858.  
  859. SERHNG    PROC    NEAR             ;[jan]
  860.     or      portbusy,2         ;port is occupied
  861.     mov      ax,150
  862.     call      pcwait         ;wait for next tick of clock
  863.     cmp      flags.comflg,1     ;serial(1) or modem(<>1)
  864.     jne      serhngm         ;jne means we are using modem
  865.     mov      ax,01000H         ;turn off rts with function 16
  866.     call      grdfnc
  867.     mov      ax,100
  868.     call      pcwait         ;wait 100 mx
  869.     mov      ax,01100H         ;turn off dtr with function 17
  870.     call      grdfnc
  871.     mov      ax,500         ;wait 1/2 second
  872.     call      pcwait
  873.     mov      ax,010ffH         ;turn on rts with function 16
  874.     call      grdfnc
  875.     mov      ax,100
  876.     call      pcwait
  877.     mov      ax,011ffH         ;turn on dtr with function 17
  878.     call      grdfnc
  879.     jmp      serhng1
  880. serhngm:                 ;hang up modem
  881.     mov      ah,ginit
  882.     call      grdfnc         ;hangup and initialize modem
  883.     mov      ax,500
  884.     call      pcwait         ;let relay settle down
  885.     mov      prevport,86         ;fake so serini will initialize
  886.     call      serini         ;this reinitialzes modem
  887. serhng1:mov      ax,300         ;wait to let things settle
  888.     call      pcwait
  889.     mov      portbusy,0         ;port is no longer occupied
  890.     clc                 ; success
  891.     ret
  892. SERHNG    ENDP
  893.  
  894. MODEMSTR    PROC   NEAR          ;send initializing string to modem [jan]
  895.       cmp       flags.comflg,2    ; using modem
  896.       je       modemstr0a         ; yes
  897.       ret                 ; get out if serial
  898. modemstr0a:
  899.       push       ax             ;save ax
  900.       mov       ax,200
  901.       call       pcwait         ;delay 200 ms before doing something
  902.       push       es             ;save es and di
  903.       push       di
  904.       push       ds
  905.       pop       es             ;es now points to our data segment
  906.       mov       di,offset mdmstr  ;string to send to modem
  907.       mov       cx,mdmstrlen         ;length of the string
  908. modemstr0: push        cx              ;save cx
  909.       cmp       byte ptr es:[di],','          ;delay 0.5 second on comma
  910.       jne       modemstr2
  911.       mov       ax,500         ;delay for the comma
  912.       call       pcwait
  913.       jmp       modemstr3         ;onto next character
  914. modemstr2:
  915.       mov       ax,50         ;send out port
  916.       call       pcwait         ;50 ms between characters
  917.       mov        cx,1         ;1 byte at a time
  918.       mov        ah,2         ;grid write call
  919.       call        grdfnc         ;write it to modem
  920. modemstr3: inc         di             ;point to next byte
  921.       pop        cx             ;get the count
  922.       loop        modemstr0         ;do the next byte if cx<>0
  923.       pop      di             ;restore di and es
  924.       pop      es
  925.       pop      ax
  926.       ret
  927. MODEMSTR   ENDP
  928.  
  929. ; Wait for the # of milliseconds in ax, for non-IBM compatibles.
  930. ; Based on 4.77 Mhz 8088 processor speeds.
  931. ; Thanks to Bernie Eiben for this one.
  932. pcwait    proc    near
  933.     mov    cx,240        ; inner loop counter for 1 millisecond
  934. pcwai1: sub    cx,1        ; inner loop takes 20 clock cycles
  935.     jnz    pcwai1
  936.     dec    ax        ; outer loop counter
  937.     jnz    pcwait        ; wait another millisecond
  938.     ret
  939. pcwait    endp
  940.  
  941.  
  942. ; Position the cursor according to contents of DX.
  943.  
  944. POSCUR    PROC    NEAR
  945.     push    ax            ; save regs
  946.     push    dx
  947.     push    es
  948.     push    di
  949.     mov    ax,ds
  950.     mov    es,ax            ; address data segment!!!
  951.     cld
  952.     mov    di,offset colno
  953.     mov    al,dh            ; row
  954.     inc    al            ; adjust offset from 1 instead of 0
  955.     mov    ah,0            ; zero up half of reg containing number
  956.     call    nout
  957.     mov    al,';'
  958.     stosb
  959.     mov    al,dl            ; column
  960.     inc    al            ; adjust offset from 1 instead of 0
  961.     mov    ah,0            ; zero up half of reg containing number
  962.     call    nout
  963.     mov    al,'H'
  964.     stosb
  965.     mov    al,'$'
  966.     stosb
  967.     mov    dx,offset movcur
  968.     mov    ah,prstr
  969.     int    dos            ; print the sequence
  970.     pop    di
  971.     pop    es
  972.     pop    dx
  973.     pop    ax
  974.     ret
  975. POSCUR    ENDP
  976.  
  977. ; put the number in ax into the buffer pointed to by di.  Di is updated
  978. nout    proc    near
  979.     push    dx            ; save registers
  980.     push    bx
  981.     push    ax
  982.     cld
  983.     mov    dx,0            ; high order is always 0
  984.     mov    bx,10
  985.     div    bx            ; divide to get digit
  986.     push    dx            ; save remainder digit
  987.     or    ax,ax            ; test quotient
  988.     jz    nout1            ; zero, no more of number
  989.     call    nout            ; else call for rest of number
  990. nout1:    pop    ax            ; get digit back
  991.     add    al,'0'            ; make printable
  992.     stosb                ; drop it off
  993.     pop    ax            ; restore all registers
  994.     pop    bx
  995.     pop    dx
  996.     ret
  997. nout    endp
  998.  
  999.  
  1000. ; Write a line in inverse video at the bottom of the screen...
  1001. ; the line is passed in dx, terminated by a $.    Returns normally.
  1002. putmod    proc    near
  1003.     push    dx        ; preserve message
  1004.     mov    dx,26 * 100H    ; line 26
  1005.     call    poscur
  1006.     mov    dx,offset invseq ; put into inverse video
  1007.     mov    ah,prstr
  1008.     int    dos
  1009.     pop    dx
  1010.     int    dos
  1011.     mov    dx,offset nrmseq ; normal videw
  1012.     int    dos
  1013.     ret            ; and return
  1014. putmod    endp
  1015.  
  1016. ; Clear the mode line written by putmod.  Returns normally.
  1017. clrmod    proc    near
  1018.     mov    dx,26 * 100H
  1019.     call    poscur
  1020.     call    clearl
  1021.     ret
  1022. clrmod    endp
  1023.  
  1024. ; Put a help message one the screen in reverse video.  Pass
  1025. ; the message in AX, terminated by a null.  Returns normally.
  1026. ; The message is put wherever the cursor currently is located.
  1027. puthlp    proc    near
  1028.     push ax
  1029.     mov ah,prstr        ; Leave some room before the message
  1030.     mov dx,offset crlf
  1031.     int dos
  1032.     pop si            ; Put message address here
  1033. puth0:    mov ah,prstr
  1034.     mov dx,offset invseq    ; Put into reverse video
  1035.     int dos
  1036.     mov ah,prstr
  1037.     mov dx,offset ivlseq    ; Make line inverse video
  1038.     int dos
  1039.     cld
  1040. puth1:    lodsb
  1041.     cmp al,0        ; Terminated with a null
  1042.     je puth2
  1043.     mov dl,al
  1044.     mov ah,conout
  1045.     int dos
  1046.     cmp al,lf        ; Line feed?
  1047.     je puth0        ; Yes, clear the next line
  1048.     jmp puth1        ; Else, just keep on writing
  1049. puth2:    mov dx,offset crlf
  1050.     mov ah,prstr
  1051.     int dos
  1052.     mov dx,offset nrmseq    ; Normal video
  1053.     int dos
  1054.     clc
  1055.     ret
  1056. puthlp    endp
  1057.  
  1058. ; Perform a delete.
  1059.  
  1060. DODEL    PROC    NEAR
  1061.     push    ax
  1062.     push    dx
  1063.     mov    ah,prstr
  1064.     mov    dx,offset delstr    ; Erase character
  1065.     int    dos
  1066.     pop    dx
  1067.     pop    ax
  1068.     ret
  1069. DODEL    ENDP
  1070.  
  1071. ; Perform a Control-U.
  1072.  
  1073. CTLU    PROC    NEAR
  1074.     push    ax
  1075.     push    dx
  1076.     mov    ah,prstr
  1077.     mov    dx,offset clrlin
  1078.     int    dos
  1079.     pop    dx
  1080.     pop    ax
  1081.     ret
  1082. CTLU    ENDP
  1083.  ;;      set the current port
  1084. COMS    PROC    NEAR
  1085.     mov    dx,offset comptab
  1086.     xor    bx,bx        ; help is the table itself
  1087.     mov    ah,cmkey
  1088.     call    comnd
  1089.     jnc    coms00
  1090.     ret            ; get out if error
  1091. coms00:    push    bx
  1092.     mov    ah,cmcfm
  1093.     call    comnd        ; Get a confirm.
  1094.     jc    comx        ; carry set = failure
  1095.     pop    bx
  1096.     mov    flags.comflg,bl    ; Set the comm port flag
  1097.     cmp    flags.comflg,1    ; Using Com 1?
  1098.     jne    coms0        ; ne = no
  1099.     mov    portval,offset port1
  1100.     clc            ; carry clear for success
  1101.     ret
  1102. coms0:    mov    portval,offset port2
  1103.     clc            ; carry clear for success
  1104.     ret
  1105. comx:    pop bx
  1106.     stc            ; carry set for failure
  1107.     ret
  1108. COMS    ENDP
  1109.  
  1110. ; Set heath emulation on/off.
  1111.  
  1112. VTS    PROC    NEAR
  1113.       mov     dx,offset termtb
  1114.       mov     bx,0
  1115.       mov     ah,cmkey
  1116.       call    comnd
  1117.       jnc     vts0
  1118.       ret           ; get out if error
  1119. vts0:
  1120.       push    bx
  1121.       mov     ah,cmcfm
  1122.       call    comnd        ; Get a confirm
  1123.        jc      vt0         ; carry => didn't get a confirm
  1124.       pop     bx
  1125.       cmp     bl,ttbig           ; using big screen?
  1126.       jne     vt1          ;ne means its not big
  1127.       mov     bigscreen,1     ; so we know screen is big
  1128.       mov     screenbyte, bl  ; for status
  1129.       mov     scnwrds, 256*32  ; words in big screen
  1130.       mov     tekflg,0           ; tek needs reinitialization
  1131.       clc
  1132.       ret
  1133. vt1:  cmp     bl,ttsmall       ;ne means its not small
  1134.       jne     vt1a
  1135.       mov     tekflg,0           ; tek needs reinitialization
  1136.       mov     scnwrds, 240*20      ;words in small screen
  1137.       mov     bigscreen,0    ;screen is not big, i.e. it's small
  1138.       mov    screenbyte, bl    ; for status
  1139.       clc
  1140.       ret
  1141. vt1a: cmp    bl,tekonnum    ; enable tek?
  1142.       jne    vt1b        ; ne = no, don't enable
  1143.       and    denyflg,not tekxflg ; clear tekx bit
  1144.       mov    tekbyte,bl    ; for status display
  1145.     clc
  1146.     ret
  1147. vt1b:    cmp    bl,tekoffnum    ; disable tek
  1148.     jne    vt2        ; ne => don't disable
  1149.     or    denyflg,tekxflg    ; set tek deny bit
  1150.     mov    tekbyte,bl    ; for status display
  1151.     clc
  1152.     ret
  1153.  
  1154.  
  1155. vt2:    mov    flags.vtflg,bl    ; Set the Tektronix emulation flag [jan]
  1156.     mov    tekflg,0    ; need to re-initialize tek emulator [jan]
  1157.     clc            ; carry clear for success
  1158. vt3:    ret
  1159. vt0:    pop    bx
  1160.     stc            ; carry set for failure
  1161.     ret
  1162. VTS    ENDP
  1163.  
  1164.  
  1165.  
  1166. VTSTAT    PROC    NEAR    ; For Status display [jrd]
  1167.     mov bx, offset vtstbl    ; table of things to show
  1168.     jmp statc             ; common status code
  1169. ;;;  ret         ; no emulator status to display
  1170. VTSTAT    ENDP
  1171.  
  1172. termtog proc  near        ; toggle terminal type [jan]
  1173.     call    savescr        ; save present screen
  1174.     xor    flags.vtflg,tttek ;toggle terminal type
  1175.     mov    tekflg,0    ; we need to re-initialize tek emulator
  1176.     call    restscr        ; restore the previous screen
  1177.     clc            ; do not exit Connect mode [jrd]
  1178.     ret
  1179. termtog endp
  1180.  
  1181. kclrscn proc    near        ; clear screen in text or Tek mode [jrd]
  1182.     cmp    flags.vtflg,tttek ; doing Tek emulation?
  1183.     jne    kclrsc1        ; ne = no
  1184.     call    cmblnk        ; blank for good measure [jan]
  1185.     call    tekcls        ; blank and some more
  1186.     clc            ; stay in Connect mode
  1187.     ret
  1188. kclrsc1:call    cmblnk        ; blank screen
  1189.     clc            ; stay in Connect mode
  1190.     ret
  1191. kclrscn endp
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  1198. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  1199. ; is determined by mssset and is passed as pointer dmpname.
  1200.  
  1201. DUMPSCR PROC    NEAR    ; Dumps screen contents to a file. Just Beeps here
  1202.     call beep    ; [jrd]
  1203.     clc
  1204.     ret
  1205. DUMPSCR ENDP
  1206.  
  1207.  
  1208.  
  1209. ; show the definition of a key.     The terminal argument block (which contains
  1210. ; the address and length of the definition tables) is passed in ax.
  1211. ; Returns a string to print in AX, length of same in CX.
  1212. ; Returns normally.
  1213. showkey proc    near
  1214.     ret            ; and return
  1215. showkey endp
  1216.  
  1217.  
  1218. ;  Common initialization for using serial port.
  1219.  
  1220. SERINI    PROC    NEAR
  1221.  
  1222.     mov    portbusy,2    ;port is occupied-don't check flow
  1223.     mov    clkdelay,0    ; restart flow check clock
  1224.     push    es
  1225.     cmp    portin,0    ; Did we initialize interrupt already?
  1226.     je    serin0        ; No, skip exit
  1227.     jmp    serin1        ; Yes, so just leave
  1228. serin0:
  1229.     cli            ; Disable interrupts
  1230.     cld            ; Do increments in string operations
  1231.      xor    ax,ax        ;ax=0
  1232.      mov    es,ax        ;es=0
  1233.      mov    bx,CLK_INT    ;clock vector
  1234.      mov    ax,es:[bx]    ;get offset
  1235.      mov    savclko,ax    ;save clock int offset
  1236.      mov    ax,es:[bx+2]    ;get segment
  1237.      mov    savclks,ax    ;save clock int segment
  1238.  
  1239.     mov    ax,offset serint
  1240.     mov    es:[bx],ax    ; and load with offset of serint
  1241.     mov    ax,cs
  1242.     mov    es:[bx+2],ax    ; and load with code segement address
  1243.                 ;clk vector now reset
  1244.     mov    portin,1    ; Remember interrupt has been initialized
  1245.     sti            ; turn interrupts back on
  1246. serin1: call    getbaud        ; get existing baud rate
  1247.     call    dobaud        ; and reset it
  1248.  
  1249.     push    bx
  1250.     mov    bx,portval        ; get port
  1251.     mov    parmsk,0ffh        ; parity mask, assume parity is None
  1252.     cmp    [bx].parflg,parnon    ; is it None?
  1253.     je    serin2            ; e = yes
  1254.     mov    parmsk,07fh        ; no, pass lower 7 bits as data
  1255. serin2: mov    bx,[bx].flowc        ; get flow control chars
  1256.     mov    flowoff,bl        ; xoff or null
  1257.     mov    flowon,bh        ; xon or null
  1258.     pop    bx
  1259.  
  1260.  
  1261.     mov    ah,flags.comflg       ;get new com port
  1262.     cmp    ah,prevport       ;port changed?
  1263.     je    serin3           ;no change so don't reinitialize
  1264.     mov    prevport,ah       ;remember we have changed
  1265.     xor    ax,ax
  1266.     mov    ah,gspar    ; parity = none
  1267.     call    grdfnc
  1268.     mov    al,1        ; stopbit = 1
  1269.     mov    ah,gssbit
  1270.     call    grdfnc
  1271.     mov    al,8        ; data bits = 8
  1272.     mov    ah,gsdata
  1273.     call    grdfnc
  1274.     mov    dx,1        ; timeout on char read wait = 1ms
  1275.     mov    ah,gcharto
  1276.     call    grdfnc
  1277.     call    modemstr    ; init modem if on
  1278.     cmp    flags.comflg,1    ; Using Com 1?
  1279.     jne    skipcts        ; Nope.
  1280.     mov    dx,0        ; timeout on cts = 0
  1281.     mov    ah,gcts
  1282.     call    grdfnc
  1283. skipcts:mov    ax,ds        ; point to large buffer
  1284.     mov    es,ax
  1285.     mov    di,offset gbuffer
  1286.     mov    cx,gbuflen
  1287.     mov    ah,gbufass
  1288.     call    grdfnc
  1289.     mov    ah,gflush    ; flush grid input buffer
  1290.     call    grdfnc
  1291. ;;      call      clrbuf          ; Clear input buffer
  1292. serin3: pop    es
  1293.     mov    portbusy,0        ;now able to do flow checking
  1294.     clc                ; carry clear for success
  1295.     ret
  1296. SERINI    ENDP
  1297.  
  1298.  
  1299. SERRST    PROC    NEAR        ; reset the clock interrupt vector
  1300.     cmp    portin,0    ; Did we initialize interrupt already?
  1301.     je    serrst0        ; No, skip resetting clock vector
  1302.     cli            ; Disable interrupts
  1303.  
  1304.     push    es        ; restore vector of clock tick int at 1CH
  1305.     xor    ax,ax        ; point to segment part of vector
  1306.     mov    es,ax        ; es=0
  1307.     mov    bx,CLK_INT    ; clock interrupt =1ch*4
  1308.     mov    ax,savclko    ; replace with original value
  1309.     mov    es:[bx],ax    ; restore offset
  1310.     mov    ax,savclks
  1311.     mov    es:[bx+2],ax    ; restore segment
  1312.     pop    es        ; and clean up stack
  1313.     mov    portin,0    ; Remember interrupt has been reset.
  1314.     sti            ; turn interrupts back on
  1315.  
  1316. serrst0:
  1317.     ret            ; All done
  1318. SERRST    ENDP
  1319.  
  1320.  
  1321. ; Comm port interrupt service routine to prevent grid buffer overflow
  1322. ; Calls flowchek which sends Xoff if necessary if activated
  1323. ;flow control is checked every 4 clock ticks, about 80 ms
  1324. ; Modified by [jan] with helpful suggestions from [jrd]
  1325. SERINT    PROC    FAR
  1326.        push   ax        ;all registers must be saved by SERINT
  1327.        push   ds        ;here, we put some words on the stack
  1328.        mov    ax,data           ;first we let the clock interrupt get called
  1329.        mov    ds,ax        ;then (maybe) come back to check flow control
  1330.        pop    save_ds        ;save ds
  1331.        pop    save_ax        ;save ax
  1332.        pushf            ;save since they're changed by and instr.
  1333.        inc    clkdelay        ;just do flow control check
  1334.        mov    ax,clkdelay    ;once each 4 ticks of the clock
  1335.        and    ax,3        ;for improved performance
  1336.        jnz    serint0        ;nz means don't check this tick
  1337.        popf
  1338.        pushf            ;restore flags and return to stack
  1339.        mov    ax,cs        ;put segment of return address on stack
  1340.        push   ax        ;clock will return here
  1341.        mov    ax,offset serint1 ;offset of return address
  1342.        push   ax        ;is placed on stack
  1343.        pushf            ;this will come off
  1344. serint0:popf            ;remove extra flags from stack
  1345.  
  1346.        mov    ax,savclks    ;put address of clock routine
  1347.        push   ax        ;on top of stack
  1348.        mov    ax,savclko
  1349.        push   ax
  1350.        mov    ax,save_ax    ;restore ax and ds
  1351.        mov    ds,save_ds
  1352.        ret            ;go to the clock routine
  1353.                 ;we come back at serint1
  1354.                 ;once each 4 ticks
  1355. ;;Clock interrupt returns here if (clkdelay and 3)=0
  1356.  
  1357.  
  1358. serint1:            ;;  entry point after clock routine
  1359.        push ax
  1360.        push bx
  1361.        push cx
  1362.        push dx
  1363.        push ds
  1364.      mov     ax,data
  1365.      mov     ds,ax
  1366.      mov     serclk,true     ;check out flow control at least once/4 tick
  1367.     cmp    insrvc,true     ; are we already doing interrupt service?
  1368.     je    retint         ; yes, then skip service until this one done
  1369.     mov    insrvc,true     ; nope, set in service flag
  1370.     cmp    portbusy,0     ;is serial port available?
  1371.     jne    serint5          ;don't stack calls
  1372.                 ;grdfnc is non-reentrant
  1373.     sti            ; flag set enable interrupts
  1374.     call  flowchek        ;do flow control checking
  1375.       mov    serclk,false      ;don't check until next tick
  1376. serint5:  mov      insrvc,false      ; set in service flag to false
  1377. retint:    pop ds
  1378.        pop dx
  1379.        pop cx
  1380.        pop bx
  1381.        pop ax
  1382.        iret              ;iret since we have to remove flags
  1383. SERINT    ENDP
  1384. ; Generate a short beep.
  1385.  
  1386.  
  1387.  
  1388. BEEP    PROC    NEAR
  1389.     mov dl,bell
  1390.     mov ah,conout
  1391.     int dos
  1392.     ret
  1393. BEEP    ENDP
  1394.  
  1395.  
  1396. ;check string to see if we need to do something special
  1397.  
  1398. stringchek  proc  near
  1399.        cmp   stringchekcnt,0     ; nobody in yet?
  1400.        jne   stringchek1     ; ne => already have characters
  1401.        cmp   al,escape         ; is this escape?
  1402.        je    stringchek1     ; it is escape, so go and process
  1403.        cmp   al,escape+80h     ; in case parity is odd
  1404.        je    stringchek1     ; process the escape
  1405.        stc             ; display the character
  1406.        ret             ; return quickly if nothing to do
  1407. stringchek1:             ; here is escape already in
  1408.        saveregs
  1409.        and     al,07fh         ;strip high bit
  1410.        mov     bx,stringchekcnt
  1411.        mov     stringchekbuff[bx],al  ;put character in buffer
  1412.        inc     stringchekcnt          ;one more character in buffer
  1413.        call    stringtest     ; does the string in stringchekbuff match?
  1414.        cmp    match,0         ; 0 means no match
  1415.        je      stringchek2
  1416.        mov     si,match           ; here means we have a match
  1417.        shl     si,1           ; multiply by 2
  1418.        dec     si
  1419.        dec     si           ; 1=0, 2=1 etc
  1420.        call    disptab[si]       ; call appropriate function
  1421.        call    stringbuffplay          ; play back the buffer
  1422.        clc               ; don't display
  1423.        jmp     stringchek3       ; return and don't display character
  1424. stringchek2:
  1425.      clc              ; don not display
  1426.      cmp   matchsofar,true      ; do we have a match so far
  1427.      je    stringchek3         ; e=true , get out
  1428.      mov   playem,true
  1429.      call  stringbuffplay           ; clean out the buffer
  1430.      clc               ; don't display character
  1431. stringchek3:
  1432.      restoreregs
  1433.      ret
  1434. stringchek   endp
  1435.  
  1436. ;test to see if input string is a match to toggle terminal  [jan]
  1437.  
  1438.  
  1439. ; stringtab gives addresses of 0 terminated strings
  1440. ; teststring in stringchekbuff
  1441. ;numstrings is the number to checked
  1442. ; matchsofar will have be true if there is a possilbe match
  1443. ; match will be non-zero 1, 2, 3 indicating number of match if a match
  1444. ; if no match yet, match will be 0
  1445. ; severaal registers get destroyed
  1446. stringtest proc near
  1447.     mov    matchsofar, false      ; assume no match
  1448.     mov    match,0            ; no match
  1449.     xor    si,si            ; pointer to string tab
  1450.     dec    si
  1451.     dec    si            ; step back 1 item
  1452.     mov    cx,0            ; cx points to number of string
  1453. strtst1:
  1454.     inc    cx            ; strings number
  1455.     cmp    cx,numstrings        ; done parsing table?
  1456.     ja    strtst5            ; we're done, get out of here
  1457.     mov    di, offset stringchekbuff
  1458.     inc    si
  1459.     inc    si            ; point to next item
  1460.     mov    bx,stringtab[si]    ; offset of string
  1461. strtst2:
  1462.     mov    al,[di]            ; stringchekbuff in al
  1463.     mov    ah,[bx]            ; string element to test in ah
  1464.     cmp    al,0            ; end of stringchekbuff
  1465.     jne    strtst2a        ; ne=> not at end of buffer
  1466.     mov    matchsofar,true        ; we have a match so far
  1467.     jmp    strtst5            ; return to caller
  1468. strtst2a:
  1469.     cmp    ah,0            ; at end of string?
  1470.     je    strtst1            ; failure, go to next string
  1471.     cmp    ah,al            ; match?
  1472.     jne    strtst1            ; no match, on to next string
  1473.                     ; here if match
  1474.     mov    ah,[bx+1]        ; next byte from string
  1475.     cmp    ah,0            ; are we done with string?
  1476.     je    strtst3            ; e => yes, a match
  1477.     inc    bx            ; next element in string
  1478.     inc    di            ; next character in stringchekbuff
  1479.     jmp    strtst2            ; check next item in string
  1480. strtst3:                ; here if we have a match
  1481.      mov    match,cx        ;
  1482.      mov    matchsofar,true        ;
  1483. strtst5:
  1484.     ret
  1485. stringtest endp
  1486.  
  1487.  
  1488.  
  1489. ;play back characters in string buffer ..called by stringchek
  1490. stringbuffplay proc near
  1491.       xor      bx,bx          ;bx=0
  1492.       mov      cx,stringchekcnt
  1493. stringbuffplay1:
  1494.       mov      al,stringchekbuff[bx]
  1495.       cmp      playem,true    ;playback characters?
  1496.       jne      stringbuffplay2     ;ne = no don't play back
  1497.       push     bx          ; save index
  1498.       push     cx          ; save count
  1499.       call     outtty          ; print the character
  1500.       pop      cx          ; restore count
  1501.       pop      bx          ; restore index
  1502. stringbuffplay2:
  1503.      mov      stringchekbuff[bx],0  ;set to 0
  1504.      inc      bx          ;point to next character
  1505.      loop     stringbuffplay1     ;repeat until buffer is empty
  1506.      mov      stringchekcnt,0     ;now no characters in buffer
  1507.      ret
  1508. stringbuffplay endp
  1509.  
  1510. ignoretek proc near           ; ignore this escape sequence in tek mode
  1511.     mov playem,false
  1512.     cmp flags.vtflg,tttek      ; are in in tek emulation
  1513.     je    ignoretek1           ; e=yes do not play back
  1514.     mov playem,true
  1515. ignoretek1:
  1516.      ret
  1517. ignoretek endp
  1518.  
  1519. ignoreall proc near   ; always ignore this escape sequence
  1520.      mov playem,false
  1521.      call beep
  1522.      ret
  1523. ignoreall endp
  1524.  
  1525. totekplay proc near           ; turn on tektronix
  1526.       mov playem,true           ; play back characters
  1527.       jmp totek
  1528. totekplay endp
  1529.  
  1530. toteknoplay proc near
  1531.      mov playem,false
  1532.      jmp  totek
  1533. toteknoplay endp
  1534.  
  1535.  
  1536. totek proc near           ; turn on tektronix
  1537.        test    denyflg,tekxflg     ;tek auto entry enabled?
  1538.        jz     totek1
  1539.        mov playem,true        ; play back characters
  1540.        ret
  1541. totek1:
  1542.  
  1543.    cmp    flags.vtflg,tttek    ; already doing tek
  1544.    je    totek2
  1545.    call termtog            ; toggle to tektronix
  1546. totek2:
  1547.     ret
  1548. totek endp
  1549.  
  1550.  
  1551. ; put the character in al to the screen, do capture and printing,
  1552. ; does translation for Set Input command.
  1553. ; Adapted from msyibm.asm [jrd]
  1554. outtty    proc    near
  1555.     cmp    flags.vtflg,tttek    ; doing tektronix emulation?
  1556.     jne    outtty1            ; ne= not doing tek emulation
  1557.     jmp    tekemu            ; do tekemu and return
  1558. outtty1:cmp    repflg,0        ; replaying?
  1559.     je    outtty2            ; e=> no replay
  1560.   ;     mov     ah,conout         ; dostty screen mode
  1561.   ;     mov     dl,al             ; write without intervention.
  1562.   ;     int     dos             ; else let dos display char
  1563.   ;     ret                 ; get out
  1564. outtty2:
  1565.  
  1566.     test    flags.remflg,d8bit    ; keep 8 bits for displays?
  1567.     jnz    outnp8            ; nz = yes, 8 bits if possible
  1568.     and    al,7fh            ; remove high bit
  1569. outnp8: cmp    rxtable+256,0        ; is translation off?
  1570.     je    outnp7            ; e = yes, off
  1571.     push    bx            ; Translate incoming char [jrd]
  1572.     mov    bx,offset rxtable    ; address of translate table [jrd]
  1573.     xlatb                ; new char is in al
  1574.     pop    bx
  1575. outnp7:
  1576.        test ourarg.flgs, capt    ; capture flag on?
  1577.     jz    outnoc            ; no, forget this part
  1578.     push    ax            ; save char
  1579.     call    captrtn            ; give it captured character
  1580.     pop    ax            ; restore character and keep going
  1581. outnoc: test    ourarg.flgs,prtscr    ; should we be printing?
  1582.     jz    outnop            ; no, keep going
  1583.     push    ax
  1584.     mov    ah,print_out        ; write to system printer device
  1585.     mov    dl,al
  1586.     int    dos
  1587.     pop    ax
  1588.     jnc    outnop            ; nc = successful print
  1589.     push    ax
  1590.     call    beep            ; else make a noise and
  1591.     call    trnprs            ;  turn off printing
  1592.     pop    ax
  1593. outnop: cmp    flags.vtflg,0        ; emulating a terminal?
  1594.     jnz    outnop1            ; nz = yup, go do something smart
  1595.     test    ourarg.flgs,trnctl    ; debug? if so use dos tty mode
  1596.     jz    outnp5            ; z = no
  1597.     mov    ah,conout
  1598.     cmp    al,7fh            ; Ascii Del char or greater?
  1599.     jb    outnp1            ; b = no
  1600.     je    outnp0            ; e = Del char
  1601.     push    ax            ; save the char
  1602.     mov    dl,7eh            ; output a tilde for 8th bit
  1603.     int    dos
  1604.     pop    ax            ; restore char
  1605.     and    al,7fh            ; strip high bit
  1606. outnp0: cmp    al,7fh            ; is char now a DEL?
  1607.     jne    outnp1            ; ne = no
  1608.     and    al,3fH            ; strip next highest bit (Del --> '?')
  1609.     jmp    outnp2            ; send, preceded by caret
  1610. outnp1: cmp    al,' '            ; control char?
  1611.     jae    outnp3            ; ae = no
  1612.     add    al,'A'-1        ; make visible
  1613. outnp2: push    ax            ; save char
  1614.     mov    dl,5eh            ; caret
  1615.     int    dos            ; display it
  1616.     pop    ax            ; recover the non-printable char
  1617. outnp3: mov    dl,al
  1618.     int    dos
  1619.     ret
  1620. ;outnp4: ;cmp      al,bell          ; bell (Control G)? [jrd]
  1621.     ;jne     outnp5             ; ne = no
  1622.        ; jmp     beep             ; use short beep, avoid char loss.
  1623. outnop1:
  1624. outnp5:
  1625.     call    charout            ;tell grid bios to write character[jan]
  1626. ;     mov     ah,conout         ; dostty screen mode
  1627. ;     mov     dl,al             ; write without intervention.
  1628. ;     int     dos             ; else let dos display char
  1629. outnp6: ret                ; and return
  1630. outtty    endp
  1631.  
  1632. ; send the character in al out to the serial port
  1633. ; handle echoing also...
  1634. outprt    proc    near
  1635. ;     test     flags,lclecho         ; echoing?
  1636.      test  ourarg.flgs,lclecho    ; echoing?
  1637.     jz    outpr1            ; no, forget it
  1638.     push    ax            ; save char
  1639.     call    outtty            ; print it
  1640.     pop    ax            ; restore
  1641. outpr1: mov    ah,al            ; this is where outchr expects it
  1642.     call    outchr            ; output to the port
  1643.      nop
  1644.      nop
  1645.      nop                ; skip returns
  1646.     ret
  1647. outprt    endp
  1648.  
  1649. ; Get a char from the serial port manager
  1650. ; returns with carry on if a character is available
  1651. portchr proc    near
  1652.     call    prtchr            ; character at port?
  1653.         jnc      portc1         ; nc => character at port
  1654. portc0: clc                ; no carry -> no character
  1655.     ret                ; and return
  1656. portc1: and    al,parmsk        ; apply 8/7 bit parity mask
  1657.     stc                ; have a character
  1658.     ret                ; and return
  1659. portchr endp
  1660.  
  1661.  
  1662. argini    proc    near            ; read passed arguments
  1663.     mov    bx,argadr        ; base of argument block
  1664.     mov    ax,[bx].captr
  1665.     mov    captrtn,ax        ; buffer capture routine
  1666.     mov    parmsk,0ffh        ; parity mask, assume parity = None
  1667.     cmp    [bx].parity,parnon    ; is parity None?
  1668.     je    argin2            ; e = yes, keep all 8 bits
  1669.     mov    parmsk,07fh        ; else keep lower 7 bits
  1670. argin2: call    serini            ; initialize port if necessary
  1671.     ret                ; that's it
  1672. argini    endp
  1673.  
  1674. getflgs     proc  near
  1675.      mov al,ourarg.flgs           ;supply flags for msggri [jan]
  1676.      ret
  1677. getflgs     endp
  1678.  
  1679. term    proc    near
  1680.     mov    argadr,ax        ; save argument ptr
  1681.     push    es
  1682.     mov    si,ax            ; this is source
  1683.     mov    di,offset ourarg    ; place to store arguments
  1684.     push    ds
  1685.     pop    es            ; address destination segment
  1686.     mov    cx,size termarg
  1687.     cld
  1688.     rep    movsb            ; copy into our arg blk
  1689.     pop    es
  1690.     call    argini            ; init options from arg address
  1691.     cmp    curini,0        ; have we been in here before[gaw@prc]
  1692.     je    term1            ; if not skip restoring cursor[gaw@prc]
  1693.     call    restscr            ; restore screen
  1694.  
  1695. term1:    cmp    prtrdy,false        ; ready to read port
  1696.     je    term5            ; get out
  1697.     call    portchr            ; read char from serial port
  1698.     jnc    term3            ; nc = no char, go on
  1699.     cmp    flags.vtflg,tttek    ; doing tek emulation?
  1700.     je    term1a            ; e=yes, already doing tek
  1701.     call    stringchek        ; ESC FF will turn on tek [jan]
  1702.     jnc    term3
  1703. term1a: call    outtty            ; display and capture char [jrd]
  1704.  
  1705. term3:    inc    keydelay        ; just check keyboard once
  1706.     mov    ax,keydelay        ; each eight reads of the port
  1707.     and    ax,7            ; should speed things up
  1708.     jnz    term1            ; at higher baud rates [jan]
  1709.     call    keybd            ; call keyboard xlator, send results
  1710.     jnc    term1            ; nc = stay in Connect mode
  1711. term5:                    ; [gaw@prc]
  1712.     call    savescr            ; save screen [gaw@prc]
  1713.     cmp    prtrdy,true        ; need to set kbdflg if wierd exit
  1714.     je    term6
  1715.     mov    kbdflg,'C'        ; so we exit connect mode
  1716.     mov    prtrdy,true
  1717. term6:    ret
  1718. term    endp
  1719.  
  1720.  
  1721. getrepchr proc    near          ; get replay character for file
  1722.       mov    ah,readf2          ; read from replay file
  1723.       mov    bx,diskio.handle
  1724.       mov    cx,1          ; read 1 character
  1725.       mov    dx,offset rdbuf  ; to this buffer
  1726.       int    dos
  1727.       jc     getrepchr1          ; c => failure
  1728.       cmp    ax,cx          ; read the byte?
  1729.       jne    getrepchr1
  1730.       mov    al,rdbuf          ; al has character
  1731.       clc              ; character available in al
  1732.       clc
  1733.       ret
  1734.  
  1735.  
  1736. getrepchr1:
  1737.       call   beep         ; announce file is done
  1738.       call   beep
  1739.       call   getkey         ; wait for a key to be pressed
  1740.       mov    prtrdy,false    ; so we exit connect mode
  1741.       stc
  1742.       ret             ; no character available
  1743. getrepchr    endp
  1744.  
  1745. repchrout  proc     near        ; process key in al  while replaying
  1746.     and   al,7fh        ; strip parity
  1747. repchrout1:
  1748.     cmp   al,'C'-40h    ; Control C?(to exit playback mode)
  1749.     je    repchrout3    ; e=> yes, return failure
  1750.     cmp   al,XOFF        ; user wants to stop?
  1751.     jne   repchrout2    ; ne => ok to continue
  1752.     call  getkey        ; wait and get a key
  1753.     jmp   repchrout1    ; now process this key
  1754. repchrout2:
  1755.     clc            ; return success
  1756.     ret
  1757. repchrout3:
  1758.     mov   prtrdy,false    ; exit terminal
  1759.     stc            ; exit connect mode
  1760.     ret
  1761. repchrout  endp
  1762.  
  1763. getkey    proc   near          ; wait for a key to be typed
  1764.        mov    ah,7
  1765.        int    dos
  1766.        ret
  1767. getkey    endp
  1768.  
  1769. savescr proc near
  1770.     push    es            ; move ds base address to es
  1771.     push    di
  1772.     push    ax
  1773.     push    dx
  1774.     xor    ax,ax
  1775.     mov    di,maxscnwrds*2          ;tek page by default
  1776.     cmp    flags.vtflg,tttek
  1777.     je    savsc1
  1778.     mov    di,0             ;point to 1st page for text
  1779.     mov    ah,prstr        ; send '<esc>[s' to ansi.sys[gaw@prc]
  1780.     mov    dx,offset cursav    ; [gaw@prc]
  1781.     int    dos            ; [gaw@prc]
  1782.     mov    byte ptr curini,1    ; now we've saved the cursor[gaw@prc]
  1783.     mov    dx,offset curoff    ; turn off cursor
  1784.     mov    ah,prstr
  1785.     int    dos
  1786.  
  1787.  
  1788. savsc1: mov    ax,scrsavseg
  1789.     mov    es,ax            ;es points to screen save segment
  1790.     mov    si,scnstrt        ; point to screen memory area
  1791.     mov    cx,scnwrds        ; setup word count
  1792.     push    ds
  1793.     xor    ax,ax            ; point to base page with ds
  1794.     mov    ds,ax
  1795.     cld
  1796.     rep    movsw            ; transfer image to save area
  1797.     pop    ds            ; restore registers and return
  1798.     mov    dx,offset curon        ; turn on cursor
  1799.     mov    ah,prstr
  1800.     int    dos
  1801.     pop    dx
  1802.     pop    ax
  1803.     pop    di
  1804.     pop    es
  1805.     ret
  1806. savescr endp
  1807.  
  1808. restscr proc near
  1809.     mov    dx,offset curoff    ; turn off cursor
  1810.     mov    ah,prstr
  1811.     int    dos
  1812.     mov    dx,offset blank        ; clear screen to get rid of cursor
  1813.     mov    ah,prstr
  1814.     int    dos
  1815.     push    es            ; point to base page with es
  1816.     xor    ax,ax            ; restore screen
  1817.     mov    es,ax
  1818.     xor    ax,ax
  1819.     mov    si,ax               ;si=0 by default
  1820.     cmp    flags.vtflg,tttek
  1821.     jne    ressc1            ;ne means not tek
  1822.     mov    si,maxscnwrds*2         ;point to second page if tek
  1823.  
  1824.  
  1825. ressc1: mov    di,scnstrt        ; point to screen memory area
  1826.     mov    cx,scnwrds        ; setup word count
  1827.     mov    ax,scrsavseg
  1828.     push    ds
  1829.     mov    ds,ax             ;ds points to screen save area
  1830.     cld
  1831.     rep    movsw            ; transfer image to screen
  1832.     pop    ds
  1833.     pop    es
  1834.     cmp    flags.vtflg,0        ; are we in emulation mode[gaw@prc]
  1835.     jne    ressc2             ; to skip restoring cursor[gaw@prc]
  1836.     mov    ah,prstr        ; send '<esc>[u' to ansi.sys[gaw@prc]
  1837.     mov    dx,offset curres    ; [gaw@prc]
  1838.     int    dos            ; [gaw@prc]
  1839.     mov    dx,offset curon        ; turn on cursor
  1840.     mov    ah,prstr
  1841.     int    dos
  1842. ressc2: ret
  1843. restscr endp
  1844.  
  1845.  
  1846. ;  msu calls this to send keystroke in al out the port
  1847. chrout    proc  near
  1848.     cmp    repflg,0        ; in replay mode?
  1849.     je    chrout1            ; e=> not doing replay
  1850.     jmp    repchrout          ; display the replay character
  1851. chrout1:call    outprt               ; put char in al to serial port
  1852.     clc                ; stay in Connect mode
  1853.     ret
  1854. chrout    endp
  1855.  
  1856.  
  1857. trnprs: push    ax            ; toggle Copy screen to printer
  1858.     test    ourarg.flgs,prtscr    ; are we currently printing?
  1859.     jnz    trnpr2            ; nz = yes, its on and going off
  1860.     mov    ah,ioctl
  1861.     mov    al,7            ; get output status of printer
  1862.     push    bx
  1863.     mov    bx,4            ; file handle for system printer
  1864.     int    dos
  1865.     pop    bx
  1866.     jc    trnpr1            ; c = printer not ready
  1867.     cmp    al,0ffh            ; Ready status?
  1868.     je    trnpr2            ; e = Ready
  1869. trnpr1: call    beep            ; Not Ready, complain
  1870.     jmp    trnpr3            ; and ignore request
  1871. trnpr2: xor    ourarg.flgs,prtscr    ; flip the flag
  1872. trnpr3: pop    ax
  1873.     clc
  1874.     ret
  1875.  
  1876.  
  1877. klogon    proc    near            ; resume logging (if any)
  1878.     test    flags.capflg,logses    ; session logging enabled?
  1879.     jz    klogn            ; z = no, forget it
  1880.     or    ourarg.flgs,capt    ; turn on capture flag
  1881.     push    bx            ; tell kermit we resume logging
  1882.     mov    bx, offset argadr
  1883.     or    [bx].flgs, capt
  1884.     pop    bx
  1885. klogn:    clc
  1886.     ret
  1887. klogon    endp
  1888.  
  1889. klogof    proc    near            ; suspend logging (if any)
  1890.     and    ourarg.flgs, not capt
  1891.     push    bx
  1892.     mov    bx, offset argadr
  1893.     and    [bx].flgs, not capt    ; turn off kermit's capture flag
  1894.     pop    bx
  1895. klogo:    clc
  1896.     ret
  1897. klogof    endp
  1898.  
  1899. snull:    mov    ah,0            ; send a null
  1900.     call    outchr            ; send without echo or logging
  1901.     clc
  1902.     ret
  1903.  
  1904. kdos:    mov    al,'P'            ; Push to DOS
  1905.     jmp    short cmdcom
  1906. cstatus:mov    al,'S'            ; these commands exit Connect mode
  1907.     jmp    short cmdcom
  1908. cquit:    mov    al,'C'
  1909.     jmp    short cmdcom
  1910. cquery: mov    al,'?'
  1911.     jmp    short cmdcom
  1912. cmdcom: mov    kbdflg,al        ; pass char to msster.asm via kbdflg
  1913.     stc                ; say exit Connect mode
  1914.     ret
  1915.  
  1916. code    ends
  1917.     end
  1918.