home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / extra / nyenhuis2.arc / MSXGRI.ASM < prev    next >
Assembly Source File  |  1988-07-01  |  34KB  |  1,268 lines

  1.     name msxgri
  2. ; File MSXGRI.ASM
  3. ; Grid Compass II dependent file for MS-DOS Kermit
  4. ;  Use with msugri.asm keyboard translator file.
  5. ;
  6. ; Last edit: 12 June 1988
  7. ; 1 July 1988 Version 2.31
  8. ; 12 June 1988 Add error recovery if serial port fails to initialize, reduce
  9. ;  serial port buffer to 1000 bytes. [jrd]
  10. ; 11 Jan 1988 Add 2.30 features. [jrd]
  11. ; 1 Jan 1988 version 2.30
  12. ;
  13. ; Jim Noble
  14. ; Planning Research Corporation
  15. ; 1500 Planning Research Drive
  16. ; Mail Stop 5S3
  17. ; McLean, VA  22102
  18. ; May, 1985
  19. ; Add global entry point vtstat for use by Status in mssset.
  20. ; Added register save/restore in procedure getbaud.
  21. ; Joe R. Doupnik 12 March 1986
  22. ; Add global procedures ihosts and ihostr to handle host initialization
  23. ; when packets are to be sent or received by us,resp. 24 March 1986
  24. ; Add global procedure dtrlow (without worker serhng) to force DTR & RTS low
  25. ; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd]
  26. ; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
  27. ;  to a file. Just does a beep for now. 13 April 1986 [jrd]
  28. ; In proc Outchr add override of xon from chkxon sending routine.
  29. ;  This makes a hand typed Xoff supress the xon flow control character sent
  30. ;  automatically as the receiver buffer empties. 20 April 1986 [jrd] 
  31.  
  32.     public    serini,    serrst,    clrbuf,    outchr,    coms, vts, vtstat, dodel, ctlu
  33.     public    cmblnk,    locate,    prtchr,    dobaud,    clearl,    lclini, getmodem
  34.     public    dodisk,    getbaud, beep, setkhlp,    setktab, pcwait, trnprs
  35.     public    machnam, xofsnt, count,    term, poscur, serhng
  36.     public    clrmod,    putmod,    puthlp,    sendbr,    sendbl, showkey, shomodem
  37.     public    ihosts, ihostr, dtrlow, dumpscr, comptab, termtb   ; [jrd]
  38.     public    chrout, cstatus, cquit, cquery        ; kbd action verbs
  39.     public    snull, kdos, klogof, klogon
  40.  
  41.     include    mssdef.h
  42.  
  43. false    equ    0
  44. true    equ    1
  45. print_out equ    05h            ; dos function to print to printer
  46. prtscr    equ    80h            ; print screen pressed
  47.  
  48. gbuflen    equ    1000        ; max bytes grid internal buffer holds
  49. mntrgh    equ    gbuflen/2    ; High point = 1/2 of buffer full.
  50. mntrgl    equ    bufsiz/4    ; Low point = 1/4 buffer full. [jrd]
  51.  
  52. gserial    equ    81h        ; grid serial port interrupt
  53. gmodem    equ    82h        ; grid modem port interrupt
  54. ginit    equ    0        ; function 0 - initialize port
  55. gread    equ    1        ; function 1 - read data
  56. gwrite    equ    2        ; function 2 - write data
  57. gwcmd    equ    4        ; function 4 - write command
  58. grstat    equ    5        ; function 5 - read status
  59. gflush    equ    6        ; function 6 - buffer flush
  60. ggbaud    equ    7        ; function 7 - get baud
  61. gsbaud    equ    8        ; function 8 - set baud
  62. gspar    equ    9        ; function 9 - set parity
  63. gsdata    equ    10        ; function 10 - set data bits
  64. gssbit    equ    11        ; function 11 - set stop bits
  65. gbufass    equ    12        ; function 12 - buffer assign
  66. gcharto    equ    13        ; function 13 - set character timeout
  67. gbrk    equ    14        ; function 14 - break control
  68. gcts    equ    19        ; function 19 - clear to send timeout
  69. gbrkon    equ    gbrk*100H+00H    ; function 14 -    set break on
  70. gbrkoff    equ    gbrk*100H+0ffH    ; function 14 -    set break off
  71. scnstrt    equ    400h        ; starting address of screen area (page 0)
  72. scnwrds    equ    4800        ; number of words in screen memory area
  73.  
  74. datas    segment    public 'datas'
  75.     extrn    drives:byte, flags:byte, trans:byte
  76.     extrn    portval:word, port1:byte, port2:byte, dmpname:byte
  77.     extrn    kbdflg:byte, rxtable:byte
  78.  
  79. machnam    db    'GRID COMPASS II version A'
  80.  
  81. curini    db    0            ; [gaw@prc]
  82. cursav    db    ESCAPE,'[s','$'        ; [gaw@prc]
  83. curres    db    ESCAPE,'[u','$'        ; [gaw@prc]
  84. curon    db    ESCAPE,'[3;3z','$'    ; [gaw@prc]
  85. curoff    db    ESCAPE,'[3;4z','$'    ; [gaw@prc]
  86. scrsav    dw    scnwrds DUP(?)
  87.  
  88. erms20    db    cr,lf,'?Warning: System    has no disk drives$'
  89. erms40    db    cr,lf,'?Warning: Unrecognized baud rate$'
  90. badbd    db    cr,lf,'Unimplemented baud rate$'
  91. crlf    db    cr,lf,'$'
  92. comphlp    db    cr,lf,'1 (SERIAL)  2 (MODEM)$'        ; [19b] [gaw@prc]
  93. hngmsg    db    cr,lf,' The phone should have hungup.',cr,lf,'$'
  94. hnghlp    db    cr,lf,' The modem control lines DTR and RTS for the current'
  95.     db    ' port are forced low (off)'
  96.     db    cr,lf,' to hangup the phone. Normally, Kermit leaves them'
  97.     db    ' high (on) when it exits.'
  98.     db    cr,lf,'$'
  99. rdbuf    db    80 dup (?)    ; temp buf
  100. noimp    db    cr,lf,'?Not implemented.$'
  101. delstr    db    BS,' ',BS,'$'    ; Delete string
  102. clrlin    db    cr,ESCAPE,'[0K','$'
  103. portin    db    0        ; has clock int vector been initialized?
  104. xofsnt    db    0        ; Say if we sent an XOFF.
  105. xofrcv    db    0        ; Say if we received an    XOFF.
  106. insrvc    db    0        ; Say if in service on XON/XOFF interrupt
  107. parmsk    db    ?        ; parity mask, 0ffh for no parity, 07fh with.
  108. flowoff    db    ?        ; flow-off char, Xoff or null (if no flow)
  109. flowon    db    ?        ; flow-on char, Xon or null
  110. captrtn    dw    ?        ; routine to call for captured output
  111. invseq    db    ESCAPE,'[7m$'    ; Reverse video.
  112. nrmseq    db    ESCAPE,'[0m$'    ; Normal mode.
  113. ivlseq    db    79 dup (' '),cr,'$'    ; Make a line inverse video
  114. tmp    db    ?,'$'
  115. temp    dw    0
  116. temp1    dw    ?        ; Temporary storage.
  117. temp2    dw    ?        ; Temporary storage.
  118. fncerr    db    cr,lf,'Error on function '
  119. fnctype    db    'X with a status return of '
  120. fncstat    db     'Y$'
  121. argadr    dw    ?        ; address of arg blk
  122.  
  123. ; key redefinitions
  124. setktab    db    0
  125.  
  126. setkhlp    db    0
  127.  
  128. ontab    db    2        ; Two entries.
  129.     mkeyw    'Off',0
  130.     mkeyw    'On',1
  131.  
  132. ; Entries for choosing communications port.
  133.  
  134. comptab    db    4        ; number of entries
  135.     mkeyw    '1',1        ; com1
  136.     mkeyw    '2',2        ; com2
  137.     mkeyw    'COM1',1
  138.     mkeyw    'COM2',2
  139.  
  140. termtb    db    2
  141.     mkeyw    'none',ttgenrc
  142.     mkeyw    'VT52',ttvt52
  143.  
  144. ; this table is indexed by the baud rate definitions given in
  145. ; pcdefs.  Unsupported baud rates should contain -1.
  146. ; (*) - only two supported on modem
  147. bddat    label    word
  148.     dw    -1        ; 45.5 baud  -- Not supported.
  149.     dw    0        ; 50 baud
  150.     dw    1        ; 75 baud
  151.     dw    2        ; 110 baud
  152.     dw    3        ; 134.5 baud
  153.     dw    4        ; 150 baud
  154.     dw    5        ; 300 baud - (*) 
  155.     dw    6        ; 600 baud
  156.     dw    7        ; 1200 baud - (*)
  157.     dw    8        ; 1800 baud
  158.     dw    9        ; 2000 baud
  159.     dw    10        ; 2400 baud
  160.     dw    12        ; 4800 baud
  161.     dw    14        ; 9600 baud
  162.     dw    15        ; 19200 baud
  163.     dw    -1        ; 38400 baud -- Not supported.
  164.  
  165. ; variables for    serial interrupt handler
  166.  
  167. gbuffer    db    gbuflen DUP(?)    ; large internal buffer for grid [gaw@prc]
  168.  
  169. source    db    bufsiz DUP(?)    ; Buffer for data from port
  170. bufout    dw    0        ; buffer removal ptr
  171. count    dw    0        ; Number of chars in int buffer
  172. bufin    dw    0        ; buffer insertion ptr
  173. telflg    db    0        ; Are we acting    as a terminal
  174. clreol    db    ESCAPE,'[0K$'
  175. blank    db    ESCAPE,'[2J$'
  176. movcur    db    ESCAPE,'['
  177. colno    db    20 dup (?)
  178. ten    db    10
  179. ourarg    termarg    <>
  180. datas    ends
  181.  
  182. code    segment    public 'code'
  183.     extrn    comnd:near, dopar:near,    prserr:near, defkey:near
  184.     extrn    sleep:near, msuinit:near, keybd:near
  185.     assume    cs:code,ds:datas
  186.  
  187. ; local initialization
  188.  
  189. lclini    proc    near
  190.     mov    portin,0    ; serial port not yet initialized
  191.     mov    flags.vtflg,0    ; turn off terminal emulation [gaw@prc]
  192.     call    msuinit        ; init keyboard translator
  193.     ret
  194. lclini    endp
  195.  
  196. ; See how many disk drives we have.
  197. DODISK    PROC    NEAR
  198.     mov ah,gcurdsk            ; Current disk value to    AL
  199.     int dos
  200.     mov dl,al            ; Put current disk in DL
  201.     mov ah,seldsk            ; Select current disk
  202.     int dos                ; Get number of    drives in AL
  203.     mov drives,al
  204.     ret
  205. DODISK    ENDP
  206.  
  207. ; Clear    the input buffer before    sending    a packet.
  208.  
  209. CLRBUF    PROC    NEAR
  210.     cli
  211.     mov ax,offset source
  212.     mov bufin,ax
  213.     mov bufout,ax
  214.     mov count,0
  215.     sti
  216. clrb1:    call prtchr            ; get a    character
  217.      jmp clrb1            ; until    there aren't any more
  218.      nop
  219.     ret
  220. CLRBUF    ENDP
  221.  
  222. ; Common routine to clear to end-of-line
  223.  
  224. CLEARL    PROC    NEAR
  225.     mov dx,offset clreol
  226.     mov ah,prstr
  227.     int dos
  228.     ret
  229. CLEARL    ENDP
  230.  
  231. SHOMODEM PROC    NEAR        ; display CD, CTS, DSR. Not implemented here
  232.     mov    ah,prstr
  233.     mov    dx,offset noimp
  234.     int    dos
  235.     jmp    rskp
  236. SHOMODEM ENDP
  237. getmodem proc    near
  238.     mov    al,0        ; modem status, none
  239.     ret
  240. getmodem endp
  241.  
  242. ; Do a grid function call to the correct com port and return
  243.  
  244. GRDFNC    PROC    NEAR
  245.     push    es        ; save es reg
  246.     push    ds        ; then mov ds to es
  247.     pop    es
  248.     push    ax        ; save function call and value in al
  249.     add    ah,"0"        ; make function code printable
  250.     mov    fnctype,ah    ; and save in error message
  251.     pop    ax        ; restore ax
  252.     cmp    flags.comflg,1    ; serial port or modem?    [gaw@prc]
  253.     jne    grdfnc1        ; if modem, do other int [gaw@prc]
  254.     int    gserial        ; else do serial port function call [gaw@prc]
  255.     jmp    grdfnc2        ; skip other int [gaw@prc]
  256. grdfnc1:
  257.     int    gmodem        ; do modem port function call [gaw@prc]
  258. grdfnc2:
  259.     jnc    grdfnc3        ; skip error msg if carry not set
  260.     add    al,"0"        ; make error code printable
  261.     mov    fncstat,al    ; and put in error message
  262.     mov    ah,prstr
  263.     push    dx
  264.     mov    dx,offset fncerr ; Give an error message
  265.     int    dos
  266.     pop    dx
  267. grdfnc3:
  268.     pop    es        ; restore es
  269.     ret
  270. GRDFNC    ENDP
  271.  
  272. ; Set the baud rate for the current port, based on the value
  273. ; in the portinfo structure.  Returns normally.
  274.  
  275. DOBAUD    PROC    NEAR
  276.     push    ax        ; save regs
  277.     push    bx
  278.     mov    bx,portval
  279.     mov    temp1,ax    ; Don't overwrite previous rate
  280.     mov    ax,[bx].baud    ; Check if new rate is valid
  281.     shl    ax,1        ; index words
  282.     mov    bx,offset bddat    ; Start of table
  283.     add    bx,ax
  284.     mov    ax,[bx]        ; The data to output to port
  285.     cmp    ax,0FFH        ; Unimplemented baud rate
  286.     jne    dobd0
  287. dobd01:
  288.     mov    ax,temp1    ; Get back original value
  289.     mov    bx,portval
  290.     mov    [bx].baud,ax    ; Leave baud rate as is
  291.     mov    ah,prstr
  292.     mov    dx,offset badbd    ; Give an error message
  293.     int    dos
  294.     pop    bx
  295.     pop    ax
  296.     ret
  297. dobd0:
  298.     mov    temp1,ax    ; Remember value to output
  299.     cmp    flags.comflg,1    ; is it com1?
  300.     je    dobd1        ; yep, skip test for 300/1200
  301.     cmp    ax,7        ; is it 1200 on com2?
  302.     je    dobd1        ; yep, go do it
  303.     cmp    ax,5        ; is it 300 on com2?
  304.     je    dobd1        ; yep, go do it
  305.     jmp    short dobd01    ; go give unimplemented msg
  306. dobd1: 
  307.     mov    ah,gsbaud    ; set up to set the port baudrate
  308.     call    grdfnc        ; do a grid function call to a com port
  309.     pop    bx
  310.     pop    ax
  311.     ret
  312. DOBAUD    ENDP
  313.  
  314. ; Send a break out the current serial port.  Returns normally.
  315. sendbr    proc    near
  316.     push    cx
  317.     push    ax
  318.     xor    cx,cx        ; Clear    loop counter
  319.     mov    ax,gbrkon    ; setup    to do break on [gaw@prc]
  320.     call    grdfnc        ; do break on
  321. pause:    loop    pause        ; Wait a while
  322.     mov    ax,gbrkoff    ; setup    to do break off    [gaw@prc]
  323.     call    grdfnc        ; do break off
  324.     pop    ax
  325.     pop    cx
  326.     clc
  327.     ret            ; And return
  328. sendbr    endp
  329.  
  330. SENDBL    PROC     NEAR        ; send a long break
  331.     call    sendbr        ; do several of these
  332.     call    sendbr
  333.     call    sendbr
  334.     call    sendbr
  335.     ret
  336. SENDBL    ENDP 
  337.  
  338. ; Send char in al out the serial port. Checks flow control.
  339. ; Return rskp if success, return rskp even if failure. 
  340. OUTCHR    PROC    NEAR
  341.     push    bx
  342.     push    cx
  343.     mov    bx,portval
  344.     cmp    [bx].floflg,0    ; Are we doing flow control
  345.     pop    bx
  346.     je    outch2        ; No, just continue
  347.     xor    cx,cx        ; clear    counter
  348.     cmp    ah,flowoff     ; sending xoff?
  349.     jne    outch1        ; ne = no
  350.     mov    xofsnt,false    ; supress xon from chkxon buffer routine
  351. outch1:    cmp    xofrcv,true    ; Are we being held?
  352.     jne    outch2        ; No - it's OK to go on
  353.     loop    outch1        ; held,    try for    a while
  354.     mov    xofrcv,false    ; timed    out, force it off and fall thru
  355. outch2:
  356.     mov    byte ptr temp,ah ; put character in buffer
  357.     push    di        ; Save register
  358.     mov    cx,1        ; set up to write one char to a    grid port
  359.     mov    di,offset temp
  360.     mov    ah,gwrite
  361.     call    grdfnc        ; go write a character
  362.     pop    di        ; restore saved    registers
  363.     pop    cx
  364.     jmp    rskp
  365. OUTCHR    ENDP 
  366.  
  367. ; This routine blanks the screen.
  368.  
  369. CMBLNK    PROC    NEAR
  370.     push    ax
  371.     push    dx
  372.     mov    ah,prstr
  373.     mov    dx,offset blank
  374.     int    dos
  375.     pop    dx
  376.     pop    ax
  377.     ret
  378. CMBLNK    ENDP
  379.  
  380. LOCATE    PROC    NEAR
  381.     mov    dx,0        ; Go to    top left corner    of screen.
  382.     jmp    poscur        ; callret...
  383. LOCATE    ENDP
  384.  
  385.  
  386. ; Get the current baud rate from the serial card and set it
  387. ; in the portinfo structure for the current port.  Returns normally.
  388. ; This is used during initialization.
  389.  
  390. GETBAUD    PROC    NEAR
  391.     push    ax        ; save some regs
  392.     push    bx
  393.     push    cx
  394.     push    dx
  395.     mov    ah,ggbaud    ; set up to get port baud rate
  396.     call    grdfnc        ; and go get it
  397.     mov    al,ah        ; mov baudrate into al
  398.     mov    ah,0        ; and zero upper part of ax
  399.  
  400.     mov    bx,offset bddat    ; Find rate's offset into table
  401.     mov    cl,0        ; Keep track of index
  402. getb0:    cmp    ax,[bx]
  403.     je    getb1
  404.     inc    cl
  405.     cmp    cl,baudsiz    ; At the end of the list
  406.     jge    getb2
  407.     add    bx,2
  408.     jmp    getb0
  409. getb1:    mov    ch,0
  410.     mov    bx,portval
  411.     mov    [bx].baud,cx    ; Set baud rate
  412.     jmp    short getb3
  413. getb2:    mov    ah,prstr
  414.     mov    dx,offset erms40
  415.     int    dos
  416. getb3:    pop    dx        ; restore regs
  417.     pop    cx
  418.     pop    bx
  419.     pop    ax
  420.     ret
  421. GETBAUD    ENDP
  422.  
  423.  
  424.  
  425. ; skip returns if no character available at port,
  426. ; otherwise returns with char in al, # of chars    in buffer in dx.
  427. PRTCHR    PROC    NEAR
  428.     push    si
  429.     cmp    count,0        ; any characters?
  430.     jne    prtch2        ; ne = yes, get from buffer
  431. prtch1:
  432.     push    di
  433.     push    bx
  434.     push    cx
  435.     mov    cx,bufsiz    ; set up to read from grid port    buffer
  436.     mov    di,offset source
  437.     mov    ah,gread
  438.     call    grdfnc
  439.     pop    cx        ; restore saved    registers
  440.     pop    bx
  441.     pop    di
  442.  
  443.     mov    count,ax    ; reset    count
  444.     or    ax,ax
  445.     jz    prtch4        ; still    no chars
  446.     mov    bufout,offset source ; this is output ptr
  447. prtch2:
  448.     dec    count
  449.     mov    dx,count    ; return count in dx
  450.     mov    si,bufout
  451.     cld
  452.     lodsb            ; get character
  453.     mov    bufout,si    ; update ptr
  454.     pop    si
  455.     ret
  456. prtch4:
  457.     pop    si
  458.     jmp    rskp        ; no chars
  459. PRTCHR    ENDP
  460.  
  461. ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
  462. ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
  463. ; else repeat cycle. Requires that the port be initialized before hand.
  464. ; Ihosts is used by the local send-file routine just after initializing
  465. ; the serial port.
  466. ; 22 March 1986 [jrd]
  467.  
  468. IHOSTS    PROC    NEAR
  469.     push    ax        ; save the registers
  470.     push    bx
  471.     push    cx
  472.     push    dx
  473.     mov    bx,portval    ; port indicator
  474.     mov    ax,[bx].flowc    ; put Go-ahead flow control char in ah
  475.     or    ah,ah        ; don't send null if flow = none
  476.     jz    ihosts1        ; z = null
  477.     call    outchr        ; send it (release Host's output queue)
  478.      nop            ; outchr can do skip return
  479.      nop
  480.      nop
  481. ihosts1:call    clrbuf        ; clear out interrupt buffer
  482.     pop    dx            ; empty buffer. we are done here
  483.     pop    cx
  484.     pop    bx
  485.     pop    ax
  486.     ret
  487. IHOSTS    ENDP
  488.  
  489. ; IHOSTR - initialize the remote host for our reception of a file by
  490. ; sending the flow-on character (XON typically) to release any held
  491. ; data. Called by receive-file code just after initializing the serial
  492. ; port.        22 March 1986 [jrd]
  493. IHOSTR    PROC    NEAR
  494.     push    ax        ; save regs
  495.     push    bx
  496.     push    cx
  497.     mov    bx,portval    ; port indicator
  498.     mov    ax,[bx].flowc    ; put Go-ahead flow control char in ah
  499.     or    ah,ah        ; don't send null if flow = none
  500.     jz    ihostr1        ; z = null
  501.     call    outchr        ; send it (release Host's output queue)
  502.      nop            ; outchr can do skip return
  503.      nop
  504.      nop
  505. ihostr1:pop    cx
  506.     pop    bx
  507.     pop    ax
  508.     ret
  509. IHOSTR    ENDP
  510.  
  511. DTRLOW    PROC    NEAR        ; Global proc to Hangup the Phone by making
  512.                 ; DTR and RTS low.
  513.     mov    ah,cmtxt    ; allow text to be able to display help
  514.     mov    bx,offset rdbuf    ; dummy buffer
  515.     mov    dx,offset hnghlp ; help message
  516.     call    comnd        ; get a confirm
  517.      jmp r
  518. ; not yet imp.    call serhng    ; drop DTR and RTS
  519.     mov    ah,prstr    ; give a nice message
  520. ; not yet imp.    mov dx,offset hngmsg
  521.     mov    dx,offset noimp    ; for now
  522.     int    dos
  523.     clc
  524.     jmp    rskp
  525. DTRLOW    ENDP
  526.  
  527. ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
  528. ; to terminate the connection. 29 March 1986 [jrd]
  529. ; Calling this twice without intervening calls to serini should be harmless.
  530. ; Returns normally.
  531. ; SERHNG is Not Yet Implemented.
  532. SERHNG    PROC    NEAR
  533.     ret
  534. SERHNG    ENDP
  535.  
  536. ; Wait for the # of milliseconds in ax, for non-IBM compatibles.
  537. ; Based on 4.77 Mhz 8088 processor speeds.
  538. ; Thanks to Bernie Eiben for this one.
  539. pcwait    proc    near
  540.     mov    cx,240        ; inner loop counter for 1 millisecond
  541. pcwai1:    sub    cx,1        ; inner loop takes 20 clock cycles
  542.     jnz    pcwai1
  543.     dec    ax        ; outer loop counter
  544.     jnz    pcwait        ; wait another millisecond
  545.     ret
  546. pcwait    endp
  547.  
  548.  
  549. ; Position the cursor according    to contents of DX.
  550.  
  551. POSCUR    PROC    NEAR
  552.     push    ax            ; save regs
  553.     push    dx
  554.     push    es
  555.     push    di
  556.     mov    ax,ds
  557.     mov    es,ax            ; address data segment!!!
  558.     cld
  559.     mov    di,offset colno
  560.     mov    al,dh            ; row
  561.     inc    al            ; adjust offset from 1 instead of 0
  562.     mov    ah,0            ; zero up half of reg containing number
  563.     call    nout
  564.     mov    al,';'
  565.     stosb
  566.     mov    al,dl            ; column
  567.     inc    al            ; adjust offset from 1 instead of 0
  568.     mov    ah,0            ; zero up half of reg containing number
  569.     call    nout
  570.     mov    al,'H'
  571.     stosb
  572.     mov    al,'$'
  573.     stosb
  574.     mov    dx,offset movcur
  575.     mov    ah,prstr
  576.     int    dos            ; print    the sequence
  577.     pop    di
  578.     pop    es
  579.     pop    dx
  580.     pop    ax
  581.     ret
  582. POSCUR    ENDP
  583.  
  584. ; put the number in ax into the buffer pointed to by di.  Di is updated
  585. nout    proc    near
  586.     push    dx            ; save registers
  587.     push    bx
  588.     push    ax
  589.     cld 
  590.     mov    dx,0            ; high order is always 0
  591.     mov    bx,10
  592.     div    bx            ; divide to get digit
  593.     push    dx            ; save remainder digit
  594.     or    ax,ax            ; test quotient
  595.     jz    nout1            ; zero, no more of number
  596.     call    nout            ; else call for rest of number
  597. nout1:    pop    ax            ; get digit back
  598.     add    al,'0'            ; make printable
  599.     stosb                ; drop it off
  600.     pop    ax            ; restore all registers
  601.     pop    bx
  602.     pop    dx
  603.     ret
  604. nout    endp
  605.  
  606.  
  607. ; Write    a line in inverse video    at the bottom of the screen...
  608. ; the line is passed in    dx, terminated by a $.    Returns    normally.
  609. putmod    proc    near
  610.     push    dx        ; preserve message
  611.     mov    dx,26 *    100H    ; line 26
  612.     call    poscur
  613.     mov    dx,offset invseq ; put into inverse video
  614.     mov    ah,prstr
  615.     int    dos
  616.     pop    dx
  617.     int    dos
  618.     mov    dx,offset nrmseq ; normal videw
  619.     int    dos
  620.     ret            ; and return
  621. putmod    endp
  622.  
  623. ; Clear    the mode line written by putmod.  Returns normally.
  624. clrmod    proc    near
  625.     mov    dx,26 *    100H
  626.     call    poscur
  627.     call    clearl
  628.     ret
  629. clrmod    endp
  630.  
  631. ; Put a    help message one the screen in reverse video.  Pass
  632. ; the message in AX, terminated    by a null.  Returns normally.
  633. ; The message is put wherever the cursor currently is located.
  634. puthlp    proc    near
  635.     push ax
  636.     mov ah,prstr        ; Leave    some room before the message
  637.     mov dx,offset crlf
  638.     int dos
  639.     pop si            ; Put message address here
  640. puth0:    mov ah,prstr
  641.     mov dx,offset invseq    ; Put into reverse video
  642.     int dos
  643.     mov ah,prstr
  644.     mov dx,offset ivlseq    ; Make line inverse video
  645.     int dos
  646.     cld
  647. puth1:    lodsb
  648.     cmp al,0        ; Terminated with a null
  649.     je puth2
  650.     mov dl,al
  651.     mov ah,conout
  652.     int dos    
  653.     cmp al,lf        ; Line feed?
  654.     je puth0        ; Yes, clear the next line
  655.     jmp puth1        ; Else,    just keep on writing
  656. puth2:    mov dx,offset crlf
  657.     mov ah,prstr
  658.     int dos
  659.     mov dx,offset nrmseq    ; Normal video
  660.     int dos
  661.     clc
  662.     ret
  663. puthlp    endp
  664.  
  665. ; Perform a delete.
  666.  
  667. DODEL    PROC    NEAR
  668.     push    ax
  669.     push    dx
  670.     mov    ah,prstr
  671.     mov    dx,offset delstr    ; Erase character
  672.     int    dos    
  673.     pop    dx
  674.     pop    ax        
  675.     ret
  676. DODEL    ENDP
  677.  
  678. ; Perform a Control-U.
  679.  
  680. CTLU    PROC    NEAR
  681.     push    ax
  682.     push    dx
  683.     mov    ah,prstr
  684.     mov    dx,offset clrlin
  685.     int    dos
  686.     pop    dx
  687.     pop    ax
  688.     ret
  689. CTLU    ENDP
  690.  
  691. COMS    PROC    NEAR
  692.     mov dx,offset comptab
  693.     mov bx,offset comphlp
  694.     mov ah,cmkey
  695.     call comnd
  696.      jmp r
  697.      nop
  698.     push bx
  699.     mov ah,cmcfm
  700.     call comnd        ; Get a    confirm.
  701.      jmp comx        ;  Didn't get a    confirm
  702.      nop
  703.     pop bx
  704.     mov flags.comflg,bl    ; Set the comm port flag
  705.     cmp flags.comflg,1    ; Using    Com 1?
  706.     jne coms0        ; Nope
  707.     mov ax,offset port1
  708.     mov portval,ax
  709.     clc            ; carry clear for success
  710.     ret
  711. coms0:    mov ax,offset port2
  712.     mov portval,ax
  713.     clc            ; carry clear for success
  714.     ret
  715. comx:    pop bx
  716.     stc            ; carry set for failure
  717.     ret
  718. COMS    ENDP
  719.  
  720. ; Set heath emulation on/off.
  721.  
  722. VTS    PROC    NEAR
  723.     mov dx,offset termtb
  724.     mov bx,0
  725.     mov ah,cmkey
  726.     call comnd
  727.      jmp r
  728.      nop
  729.     push bx
  730.     mov ah,cmcfm
  731.     call comnd        ; Get a confirm
  732.      jmp vt0        ;  Didn't get a confirm
  733.      nop
  734.     pop bx
  735.     mov flags.vtflg,bl    ; Set the VT52 emulation flag
  736.     ret
  737. vt0:    pop bx
  738.     ret
  739. VTS    ENDP
  740.  
  741. VTSTAT    PROC    NEAR    ; For Status display [jrd]
  742.     ret        ; no emulator status to display
  743. VTSTAT    ENDP 
  744.  
  745. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  746. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  747. ; is determined by mssset and is passed as pointer dmpname.
  748.  
  749. DUMPSCR    PROC    NEAR    ; Dumps screen contents to a file. Just Beeps here
  750.     call beep    ; [jrd]
  751.     clc
  752.     ret
  753. DUMPSCR    ENDP
  754.  
  755.  
  756.  
  757. ; show the definition of a key.  The terminal argument block (which contains
  758. ; the address and length of the definition tables) is passed in ax.
  759. ; Returns a string to print in AX, length of same in CX.
  760. ; Returns normally.
  761. showkey    proc    near
  762.     ret            ; and return
  763. showkey    endp
  764.  
  765.  
  766. ;  Common initialization for using serial port.
  767.  
  768. SERINI    PROC    NEAR
  769.     push    es
  770.     cmp    portin,0    ; Did we initialize interrupt already?
  771.     je    serin0        ; No, skip exit
  772.     jmp    serin1        ; Yes, so just leave
  773. serin0:    cli            ; Disable interrupts
  774.     cld            ; Do increments in string operations
  775.     xor    ax,ax        ; get vector of clock tick int at 1CH
  776.     mov    es,ax
  777.     mov    bx,1Ch*4
  778.     mov    ax,es:[bx]
  779.     mov    cs:savclko,ax
  780.     add    bx,2
  781.     mov    ax,es:[bx]
  782.     mov    cs:savclks,ax
  783.  
  784. ;-> all because cli doesn't disable clock tick interrupt!
  785.     push    es        ; save pointer to segment part of vector
  786.     push    bx
  787.     mov    es,ax        ; point to location with offset replaced
  788.     mov    bx,offset serint
  789.     mov    cl,es:[bx]    ; save value in cl
  790.     mov    al,0CFh        ; load al with IRET instruction
  791.     mov    es:[bx],al    ; put at location with offset replace
  792.     pop    bx
  793.     pop    es
  794.     sub    bx,2        ; now point to offset part of vector
  795.     mov    ax,offset serint
  796.     mov    es:[bx],ax    ; and load with offset of serint
  797.     add    bx,2        ; now point to segment part of vector
  798.     mov    ax,cs
  799.     mov    es:[bx],ax    ; and load with code segement address
  800.     mov    ax,cs:savclks    ; now restore byte at offset of serint
  801.     mov    es,ax
  802.     mov    bx,offset serint
  803.     mov    es:[bx],cl
  804. ;<-
  805.  
  806.     mov    portin,1    ; Remember interrupt has been initialized
  807.     sti            ; turn interrupts back on
  808.     call    dobaud        ; reset baud just incase modem hung up
  809.     xor    ax,ax
  810.     mov    ah,gspar    ; parity = none
  811.     call    grdfnc
  812.     mov    al,1        ; stopbit = 1
  813.     mov    ah,gssbit
  814.     call    grdfnc
  815.     mov    al,8        ; data bits = 8
  816.     mov    ah,gsdata
  817.     call    grdfnc
  818.     mov    dx,1        ; timeout on char read wait = 1ms
  819.     mov    ah,gcharto
  820.     call    grdfnc
  821.     cmp    flags.comflg,1    ; Using    Com 1?
  822.     jne    skipcts        ; Nope.
  823.      mov    dx,0        ; timeout on cts = 0
  824.     mov    ah,gcts
  825.     call    grdfnc
  826. skipcts:mov    ax,ds        ; point to large buffer
  827.     mov    es,ax
  828.     mov    di,offset gbuffer
  829.     mov    cx,gbuflen
  830.     mov    ah,gbufass
  831.     call    grdfnc
  832.     mov    ah,gflush    ; flush grid input buffer
  833.     call    grdfnc
  834.     push    bx
  835.     mov    bx,portval        ; get port
  836.     mov    parmsk,0ffh        ; parity mask, assume parity is None
  837.     cmp    [bx].parflg,parnon    ; is it None?
  838.     je    serin2            ; e = yes
  839.     mov    parmsk,07fh        ; no, pass lower 7 bits as data
  840. serin2:    mov    bx,[bx].flowc        ; get flow control chars
  841.     mov    flowoff,bl        ; xoff or null
  842.     mov    flowon,bh        ; xon or null
  843.     pop    bx
  844.     call    clrbuf            ; Clear    input buffer
  845. serin1:    pop    es
  846.     clc                ; carry clear for success
  847.     ret
  848. SERINI    ENDP
  849.  
  850. SERRST    PROC    NEAR
  851.     cmp    portin,0    ; Did we initialize interrupt already?
  852.     je    serrst0        ; No, skip resetting clock vector
  853.     cli            ; Disable interrupts
  854.  
  855. ;-> all because cli doesn't disable clock tick interrupt!
  856.     push    es        ; restore vector of clock tick int at 1CH
  857.     mov    ax,cs:savclks    ; get pointer to location when segment replaced
  858.     mov    es,ax
  859.     mov    bx,offset serint
  860.     mov    cl,es:[bx]    ; save value from there in cl
  861.     mov    al,0CFh        ; load location with IRET
  862.     mov    es:[bx],al
  863.     push    es        ; save segment pointer for later
  864.     push    bx
  865.     xor    ax,ax        ; point to segment part of vector
  866.     mov    es,ax
  867.     mov    bx,(1Ch*4)+2
  868.     mov    ax,cs:savclks    ; replace with original value
  869.     mov    es:[bx],ax
  870.     sub    bx,2        ; now replace offset with original value
  871.     mov    ax,cs:savclko
  872.     mov    es:[bx],ax
  873.     pop    bx        ; now restore location holding temporary IRET
  874.     pop    es
  875.     mov    es:[bx],cl
  876.     pop    es        ; and clean up stack
  877. ;<-
  878.     mov    portin,0    ; Remember interrupt has been reset. 
  879.     sti            ; turn interrupts back on
  880.  
  881. serrst0:
  882.     ret            ; All done
  883. SERRST    ENDP
  884.  
  885. ; Comm port interrupt service routine to prevent grid buffer overflow
  886. ; sends Xoff if necessary if activated
  887. ;
  888. SERINT    PROC    NEAR
  889.     push ax
  890.     push bx
  891.     push cx
  892.     push dx
  893.     push ds
  894.     push es
  895.     push si
  896.     push di
  897.     push bp
  898.     pushf
  899.     cld
  900.     mov    ax,seg datas
  901.     mov    ds,ax        ; address data segment
  902.     mov    es,ax
  903.  
  904.     mov    bx,portval
  905.     cmp    [bx].floflg,0    ; Doing flow control?
  906.     je    retint        ; No, just leave.
  907.  
  908.     jmp    retint    ; <<===<< temporary stub until grid problem resolved
  909.  
  910.     cmp    insrvc,true    ; are we already doing interrupt service?
  911.     je    retint        ; yes, then skip service until this one done
  912.     mov    insrvc,true    ; nope, set in service flag
  913.     sti            ; flag set enable interrupts
  914.  
  915.     mov    ah,grstat    ; get the buffer count
  916.     call    grdfnc
  917.  
  918.     cmp    xofsnt,true    ; Have we sent an XOFF?
  919.     je    serint1        ; Yes.
  920.  
  921.     cmp    cx,mntrgh    ; Past the high trigger point?
  922.     jbe    intdone        ; No, we're within our limit
  923.     mov    ah,flowoff    ; Get the XOFF
  924.     or    ah,ah        ; null (no flow control)?
  925.     jz    intdone        ; z = yes, do nothing 
  926.     mov    byte ptr temp,ah ; put character in buffer
  927.     mov    cx,1        ; set up to write one char to a    grid port
  928.     mov    di,offset temp
  929.     mov    ah,gwrite
  930.     call    grdfnc        ; go write a character
  931.     mov    xofsnt,true    ; Remember we sent it
  932.     jmp    intdone
  933.  
  934. serint1:
  935.     cmp    cx,mntrgl    ; below the low trigger point?
  936.     ja    intdone        ; no, don't send XON
  937.     mov    ah,flowon    ; get the XON
  938.     or    ah,ah        ; null?
  939.     jz    intdone        ; z = yes, do nothing
  940.     mov    byte ptr temp,ah ; put character in buffer
  941.     mov    cx,1        ; set up to write one char to a    grid port
  942.     mov    di,offset temp
  943.     mov    ah,gwrite
  944.     call    grdfnc        ; go write a character
  945.     mov    xofsnt,false    ; remember we sent it
  946. intdone:
  947.     mov    insrvc,false    ; set in service flag to false
  948. retint:
  949.     sti
  950.     popf
  951.     pop bp
  952.     pop di
  953.     pop si
  954.     pop es
  955.     pop ds
  956.     pop dx
  957.     pop cx
  958.     pop bx
  959.     pop ax
  960.     jmp    dword ptr cs:savclko
  961.     
  962. savclko    dw    ?        ; save clock tick interrupt vector offset
  963. savclks    dw    ?        ; save clock tick interrupt vector segment 
  964.  
  965.  
  966. SERINT    ENDP
  967.  
  968.  
  969. ; Generate a short beep.
  970.  
  971. BEEP    PROC    NEAR
  972.     mov dl,bell
  973.     mov ah,conout
  974.     int dos    
  975.     ret
  976. BEEP    ENDP
  977.  
  978. ; put the character in al to the screen, do capture and printing,
  979. ; does translation for Set Input command.
  980. ; Adapted from msyibm.asm [jrd]
  981. outtty    proc    near
  982.     test    flags.remflg,d8bit    ; keep 8 bits for displays?
  983.     jnz    outnp8            ; nz = yes, 8 bits if possible
  984.     and    al,7fh            ; remove high bit
  985. outnp8:    cmp    rxtable+256,0        ; is translation off?
  986.     je    outnp7            ; e = yes, off
  987.     push    bx            ; Translate incoming char [jrd]
  988.     mov    bx,offset rxtable    ; address of translate table [jrd]
  989.     xlatb                ; new char is in al
  990.     pop    bx
  991. outnp7:
  992.     push    bx
  993.     mov    bx,argadr        ; args from msster directly
  994.     test    [bx].flgs,capt        ; capturing output? Can be shut off
  995.     pop    bx            ;  if out dev becomes not ready
  996.     jz    outnoc            ; no, forget this part
  997.     push    ax            ; save char
  998.     call    captrtn            ; give it captured character
  999.     pop    ax            ; restore character and keep going
  1000. outnoc:    test    ourarg.flgs,prtscr    ; should we be printing?
  1001.     jz    outnop            ; no, keep going
  1002.     push    ax
  1003.     mov    ah,print_out        ; write to system printer device
  1004.     mov    dl,al
  1005.     int    dos
  1006.     pop    ax
  1007.     jnc    outnop            ; nc = successful print
  1008.     push    ax
  1009.     call    beep            ; else make a noise and
  1010.     call    trnprs            ;  turn off printing
  1011.     pop    ax
  1012. outnop:    cmp    flags.vtflg,0        ; emulating a terminal?
  1013.     jnz    outnop1            ; nz = yup, go do something smart
  1014.     test    ourarg.flgs,trnctl    ; debug? if so use dos tty mode
  1015.     jz    outnp4            ; z = no
  1016.     mov    ah,conout
  1017.     cmp    al,7fh            ; Ascii Del char or greater?
  1018.     jb    outnp1            ; b = no
  1019.     je    outnp0            ; e = Del char
  1020.     push    ax            ; save the char
  1021.     mov    dl,7eh            ; output a tilde for 8th bit
  1022.     int    dos
  1023.     pop    ax            ; restore char
  1024.     and    al,7fh            ; strip high bit
  1025. outnp0:    cmp    al,7fh            ; is char now a DEL?
  1026.     jne    outnp1            ; ne = no
  1027.     and    al,3fH            ; strip next highest bit (Del --> '?')
  1028.     jmp    outnp2            ; send, preceded by caret
  1029. outnp1:    cmp    al,' '            ; control char?
  1030.     jae    outnp3            ; ae = no
  1031.     add    al,'A'-1        ; make visible
  1032. outnp2:    push    ax            ; save char
  1033.     mov    dl,5eh            ; caret
  1034.     int    dos            ; display it
  1035.     pop    ax            ; recover the non-printable char
  1036. outnp3:    mov    dl,al
  1037.     int    dos
  1038.     ret
  1039. outnp4:    cmp    al,bell            ; bell (Control G)? [jrd]
  1040.     jne    outnp5            ; ne = no
  1041.     jmp    beep            ; use short beep, avoid char loss.
  1042. outnop1:
  1043. outnp5:    mov    ah,conout        ; dostty screen mode
  1044.     mov    dl,al            ; write without intervention.
  1045.     int    dos            ; else let dos display char
  1046.     ret                ; and return
  1047. outtty    endp
  1048.  
  1049. ; send the character in al out to the serial port
  1050. ; handle echoing also...
  1051. outprt    proc    near
  1052.     test    flags,lclecho        ; echoing?
  1053.     jz    outpr1            ; no, forget it
  1054.     push    ax            ; save char
  1055.     call    outtty            ; print it
  1056.     pop    ax            ; restore
  1057. outpr1:    mov    ah,al            ; this is where outchr expects it
  1058.     call    outchr            ; output to the port
  1059.      nop
  1060.      nop
  1061.      nop                ; skip returns
  1062.     ret
  1063. outprt    endp
  1064.  
  1065. ; Get a char from the serial port manager
  1066. ; returns with carry on if a character is available
  1067. portchr    proc    near
  1068.     call    prtchr            ; character at port?
  1069.      jmp    short portc1        ; yes, go handle
  1070.      nop
  1071. portc0:    clc                ; no carry -> no character
  1072.     ret                ; and return
  1073. portc1:    and    al,parmsk        ; apply 8/7 bit parity mask
  1074.     or    al,al            ; null?
  1075.     jz    portc0            ; z = yes, ignore
  1076.     cmp    al,DEL            ; ascii DEL code?
  1077.     je    portc0            ; e = yes, ignore
  1078.     stc                ; have a character
  1079.     ret                ; and return
  1080. portchr    endp
  1081.  
  1082.  
  1083. argini    proc    near            ; read passed arguments
  1084.     mov    bx,argadr        ; base of argument block
  1085.     mov    al,[bx].flgs        ; get flags
  1086.     and    al,capt+emheath+havtt+trnctl+lclecho
  1087.     mov    flags,al        ; mask for allowable and save
  1088. ;    and    flags1,not (prtscr)    ; these are allowable
  1089.                     ; (others remain).
  1090.     mov    ax,[bx].captr
  1091.     mov    captrtn,ax        ; buffer capture routine
  1092.     mov    parmsk,0ffh        ; parity mask, assume parity = None
  1093.     cmp    [bx].parity,parnon    ; is parity None?
  1094.     je    argin2            ; e = yes, keep all 8 bits
  1095.     mov    parmsk,07fh        ; else keep lower 7 bits
  1096. argin2:    ret                ; that's it
  1097. argini    endp
  1098.  
  1099. term    proc    near
  1100.     mov    argadr,ax        ; save argument ptr
  1101.     push    es
  1102.     mov    si,ax            ; this is source
  1103.     mov    di,offset ourarg    ; place    to store arguments
  1104.     push    ds
  1105.     pop    es            ; address destination segment
  1106.     mov    cx,size termarg
  1107.     cld
  1108.     rep    movsb            ; copy into our    arg blk
  1109.     pop    es
  1110.     call    argini            ; init options from arg address
  1111.     cmp    curini,0        ; have we been in here before[gaw@prc]
  1112.     je    term1            ; if not skip restoring cursor[gaw@prc]
  1113.     call    restscr            ; restore screen
  1114.     cmp    flags.vtflg,0        ; are we in emulation mode[gaw@prc]
  1115.     jne    term1            ; to skip restoring cursor[gaw@prc]
  1116.     mov    ah,prstr        ; send '<esc>[u' to ansi.sys[gaw@prc]
  1117.     mov    dx,offset curres    ; [gaw@prc]
  1118.     int    dos            ; [gaw@prc]
  1119.  
  1120. term1:    call    portchr            ; read char from serial port
  1121.     jnc    short term3        ; nc = no char, go on
  1122.     call    outtty            ; display and capture char [jrd]
  1123. term3:    call    keybd            ; call keyboard xlator, send results
  1124.     jnc    term1            ; nc = stay in Connect mode
  1125.     cmp    flags.vtflg,0        ; are we in emulation mode[gaw@prc]
  1126.     jne    term5            ; if we are skip saving cursor[gaw@prc]
  1127.     mov    ah,prstr        ; send '<esc>[s' to ansi.sys[gaw@prc]
  1128.     mov    dx,offset cursav    ; [gaw@prc]
  1129.     int    dos            ; [gaw@prc]
  1130.     mov    byte ptr curini,1    ; now we've saved the cursor[gaw@prc]
  1131. term5:                    ; [gaw@prc]
  1132.     call    savescr            ; save screen [gaw@prc]
  1133.     mov    al,flags
  1134.     mov    bx,argadr
  1135.     mov    [bx].flgs,al        ; update flags in arg block
  1136.     ret                ; and return to caller
  1137. term    endp
  1138.  
  1139. savescr    proc near
  1140.     push    es            ; move ds base address to es
  1141.     push    ds
  1142.     pop    es
  1143.     mov    di,offset scrsav    ; point to start of screen save area
  1144.     mov    si,scnstrt        ; point to screen memory area
  1145.     mov    cx,scnwrds        ; setup word count
  1146.     push    ds
  1147.     xor    ax,ax            ; point to base page with ds
  1148.     mov    ds,ax
  1149.     cld
  1150.     rep    movsw            ; transfer image to save area
  1151.     pop    ds            ; restore registers and return
  1152.     pop    es
  1153.     ret
  1154. savescr    endp
  1155.  
  1156. restscr    proc near
  1157.     mov    dx,offset curoff    ; turn off cursor
  1158.     mov    ah,prstr
  1159.     int    dos
  1160.     mov    dx,offset blank        ; clear screen to get rid of cursor
  1161.     mov    ah,prstr
  1162.     int    dos
  1163.     push    es            ; point to base page with es
  1164.     xor    ax,ax            ; restore screen
  1165.     mov    es,ax
  1166.     mov    di,scnstrt        ; point to screen memory area
  1167.     mov    si,offset scrsav    ; point to start of screen save area
  1168.     mov    cx,scnwrds        ; setup word count
  1169.     cld
  1170.     rep    movsw            ; transfer image to screen
  1171.     pop    es 
  1172.     mov    dx,offset curon        ; turn on cursor
  1173.     mov    ah,prstr
  1174.     int    dos
  1175.     ret
  1176. restscr    endp
  1177.  
  1178. ;; keyboard translator action routines, system dependent, called from msugen.
  1179. ; These are invoked by a jump instruction. Return carry clear for normal
  1180. ; processing, return carry set for invoking Quit (kbdflg has transfer char).
  1181.  
  1182. ;trnmod:    test    flags,modoff        ; mode line already off?
  1183. ;    jnz    trnm1            ; yes, go turn on
  1184. ;    call    clrmod            ; no, clear mode line here
  1185. ;    or    flags,modoff        ; turn on flag
  1186. ;    ret                ; and return
  1187. ;trnm1:    call    modlin            ; turn on mode line
  1188. ;    and    flags,not modoff    ; clear flag
  1189. ;    ret                ; and return
  1190. ;
  1191.  
  1192. chrout: call    outprt            ; put char in al to serial port
  1193.     clc                ; stay in Connect mode
  1194.     ret
  1195.  
  1196. trnprs:    push    ax            ; toggle Copy screen to printer
  1197.     test    ourarg.flgs,prtscr    ; are we currently printing?
  1198.     jnz    trnpr2            ; nz = yes, its on and going off
  1199.     mov    ah,ioctl
  1200.     mov    al,7            ; get output status of printer
  1201.     push    bx
  1202.     mov    bx,4            ; file handle for system printer
  1203.     int    dos
  1204.     pop    bx
  1205.     jc    trnpr1            ; c = printer not ready
  1206.     cmp    al,0ffh            ; Ready status?
  1207.     je    trnpr2            ; e = Ready    
  1208. trnpr1:    call    beep            ; Not Ready, complain
  1209.     jmp    trnpr3            ; and ignore request
  1210. trnpr2:    xor    ourarg.flgs,prtscr    ; flip the flag
  1211. trnpr3:    pop    ax
  1212.     clc
  1213.     ret
  1214.  
  1215.  
  1216. klogon    proc    near            ; resume logging (if any)
  1217.     test    flags.capflg,logses    ; session logging enabled?
  1218.     jz    klogn            ; z = no, forget it
  1219.     or    ourarg.flgs,capt    ; turn on capture flag
  1220. klogn:    clc
  1221.     ret
  1222. klogon    endp
  1223.  
  1224. klogof    proc    near            ; suspend logging (if any)
  1225.     and    argadr.flgs,not capt    ; stop capturing
  1226. klogo:    clc
  1227.     ret
  1228. klogof    endp
  1229.  
  1230. snull:    mov    ah,0            ; send a null
  1231.     call    outchr            ; send without echo or logging
  1232.      nop
  1233.      nop
  1234.      nop
  1235.     clc
  1236.     ret
  1237.  
  1238. kdos:    mov    al,'P'            ; Push to DOS
  1239.     jmp    short cmdcom
  1240. cstatus:mov    al,'S'            ; these commands exit Connect mode
  1241.     jmp    short cmdcom
  1242. cquit:    mov    al,'C'
  1243.     jmp    short cmdcom
  1244. cquery:    mov    al,'?'
  1245.     jmp    short cmdcom
  1246. cmdcom:    mov    kbdflg,al        ; pass char to msster.asm via kbdflg
  1247.     stc                ; say exit Connect mode
  1248.     ret
  1249.  
  1250. ; Jumping to this location is like retskp.  It assumes the instruction
  1251. ;   after the call is a    jmp addr.
  1252.  
  1253. RSKP    PROC    NEAR
  1254.     pop bp
  1255.     add bp,3
  1256.     push bp
  1257.     ret
  1258. RSKP    ENDP
  1259.  
  1260. ; Jumping here is the same as a    ret.
  1261.  
  1262. R    PROC    NEAR
  1263.     ret
  1264. R    ENDP
  1265. code    ends 
  1266.     end
  1267.  
  1268.