home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / msxtip.asm < prev    next >
Assembly Source File  |  2020-01-01  |  41KB  |  932 lines

  1.         name msxtip
  2. ; File MSXTIP.ASM
  3. ; Last modification: 20 April 1986
  4.  
  5. revlvl  equ     6                       ; Rev level 6, 13 April 1986
  6. ;;;REVLVL  EQU 5                           ;Revision level 6-25-85
  7.  
  8. ;==============================================================================
  9. ;
  10. ; MSXTIPRO.ASM  This file contains system dependent routines for the
  11. ;               TI-Professional computer running MS-DOS version 2.10. This
  12. ;               version features interrupt driven I/O and H19/Tektronix 4010
  13. ;               emulation. This version has been tested at 9600 baud with
  14. ;               no loss of data.
  15. ;
  16. ; Credits:      Dan Smith       Computing Center        (303) 273-3396
  17. ;                               Colorado School of Mines
  18. ;                               Golden, Colorado 80241
  19. ;               Joe Smith (now at TYMSHARE, 39100 Liberty St, Fremont CA 94538)
  20. ;
  21. ;==============================================================================
  22. ; Add global entry point vtstat for use by Status in mssset.
  23. ; Clear terminal emulation flag, flags.vtflg, in procedure lclini.
  24. ; Add register save/restore in procedure getbaud.
  25. ; Bump rev level to 6. Joe R. Doupnik 12 March 1986
  26. ; Add global procedures ihosts and ihostr to handle host initialization
  27. ; when packets are to be sent or received by us,resp. 24 March 1986
  28. ; Add global procedure dtrlow (without worker serhng) to force DTR & RTS low
  29. ; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd]
  30. ; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
  31. ;  to a file. Just does a beep for now. 13 April 1986 [jrd]
  32. ; In proc Outchr add override of xon from chkxon sending routine.
  33. ;  This makes a hand typed Xoff supress the xon flow control character sent
  34. ;  automatically as the receiver buffer empties. 20 April 1986 [jrd]
  35.  
  36.         include mssdef.h
  37.  
  38.         public  xofsnt, machnam, setktab, setkhlp, count
  39.  
  40.         public  serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel
  41.         public  ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl
  42.         public  dodisk, getbaud, beep, puthlp, poscur, putmod, clrmod
  43.         public  sendbr, showkey
  44.         public  ihosts, ihostr, dtrlow, dumpscr                 ; [jrd]
  45.  
  46. ;=========================================================================
  47. ; Data Segment variables for Ti-Pro
  48. ;
  49. ; external variables used:
  50. ; drives - # of disk drives on system
  51. ; flags - global flags as per flginfo structure defined in pcdefs
  52. ; portval - pointer to current portinfo structure (currently either port1
  53. ;    or port2)
  54. ; port1, port2 - portinfo structures for the corresponding ports
  55. ;
  56. ; global variables defined in this module:
  57. ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
  58. ;=========================================================================
  59.  
  60. datas   segment public 'datas'
  61.  
  62.         extrn   drives:byte,flags:byte, dmpname:byte            ; [jrd]
  63.         extrn   portval:word,port1:byte,port2:byte,port3:byte,port4:byte
  64.  
  65. false   equ     0
  66. true    equ     1
  67. mntrgh  equ     bufsiz*3/4              ;High trigger point for XOFF
  68.  
  69. machnam db      'TI-PRO (Revision ',REVLVL+'0',')$'
  70. badbd   db      cr,lf,'Unimplemented baud rate$'
  71. hngmsg  db      cr,lf,' The phone should have hungup.',cr,lf,'$' ; [jrd]
  72. hnghlp  db      cr,lf,' The modem control lines DTR and RTS for the current'
  73.         db      ' port are forced low (off)'
  74.         db      cr,lf,' to hangup the phone. Normally, Kermit leaves them'
  75.         db      ' high (on) when it exits.'
  76.         db      cr,lf,'$'                                       ; [jrd]
  77. rdbuf   db      80 dup (?)      ; temp buf [jrd]
  78. noimp   db      cr,lf,'?Not implemented.$'                      ; [jrd]
  79. shkmsg  db      'Not implemented.'
  80. shklen  equ     $-shkmsg
  81. setktab db      0               ;Must be defined. Used in Set Key command
  82. setkhlp db      0               ;Must be defined. Used in Set Key ?
  83. crlf    db      cr,lf,'$'
  84. delstr  db      bs,bs,' ',bs,'$';Delete string.
  85. clrlin  db      cr              ;Must be at clreol-1
  86. clreol  db      esc,'[K$'       ;Clear line.
  87. homeras db      esc,'[H',esc,'[J$' ;Home and erase
  88. savint  dw      0,0             ;Place to save interrupt vector
  89. invvid  db      esc,'[0;7m$'    ;Inverse video
  90. norvid  db      esc,'[0;1m$'    ;Normal video (WHITE=BOLD, as opposed to GREEN)
  91. xofsnt  db      0               ;Say if we sent an XOFF.
  92. xofrcv  db      0               ;Say if we received an XOFF.
  93. portin  db      0               ;Non-zero if port is initialized
  94.  
  95. source  db      bufsiz dup(?)   ;Circular buffer for data from port
  96. savedi  dw      0               ;Input pointer for circular buffer
  97. savesi  dw      0               ;Output pointer for circular buffer
  98. count   dw      0               ;Number of characters in buffer
  99.  
  100. porttab db      04h             ;4 entries
  101.         db      01h,'1$'
  102.         dw      01h
  103.         db      01h,'2$'
  104.         dw      02h             ;*** NOTE: This is 2, not 0 ****
  105.         db      01h,'3$'
  106.         dw      03h
  107.         db      01h,'4$'
  108.         dw      04h
  109.  
  110. ontab   db      2               ;Number of entries
  111.         db      03h,'OFF$'
  112.         dw      0
  113.         db      02h,'ON$'
  114.         dw      1
  115.  
  116. modem   mdminfo <0e7h,0e6h,0e4h,0feh,001h,000h,40h*4>   ;Init to Port 1 parms
  117.  
  118. ; Data to init Serial Controller
  119. ; Channel A parameters
  120.  
  121. parmta  db      09h             ;Select WR9
  122.         db      0c0h            ;Reset 8530
  123.         db      0bh             ;Select WR11
  124.         db      50h             ;No XTAL, RxC=BRG=TxC, TRxC pin is an input
  125.         db      0eh             ;Select WR14
  126.         db      03h             ;BRG source is PCLK pin, enable BRG
  127.         db      0fh             ;Select WR15
  128.         db      0               ;Disable external status interrupts
  129.         db      04h             ;Select WR4
  130.         db      44h             ;x16 clock, 1 stop bit, no parity
  131.         db      05h             ;Select WR5
  132.         db      11101010b       ;Raise DTR+RTS, 8 bits, Tx enable
  133.         db      03h             ;Select WR3
  134.         db      0c1h            ;8 bits, enable receiver
  135.         db      01h             ;Select WR1
  136.         db      10h             ;Interrupt on all receive chars or spec. cond.
  137.         db      9               ;Select WR9
  138.         db      8               ;Master interrupt enable
  139. parmas  equ     $-parmta
  140.  
  141. ; Channel B parameters
  142.  
  143. parmtb  db      0fh             ;Select WR15
  144.         db      00h             ;Disable external status interrupts
  145.         db      01h             ;Select WR1
  146.         db      00h             ;Disable all other interrupts
  147.         db      05h             ;Select WR5
  148.         db      02h             ;Raise RTSB (RCNTL) for internal modem
  149. parmbs  equ     $-parmtb
  150.  
  151. baudat  label   word            ;Divisors for Z-8530 with 4.9152-MHz oscillator
  152.         dw      0696h           ; 0   45.5 baud
  153.         dw      05FEh           ; 1   50 baud
  154.         dw      03FEh           ; 2   75 baud
  155.         dw      02B8h           ; 3  110 baud (+0.03%)
  156.         dw      0239h           ; 4  134.5 baud (Selectric)
  157.         dw      01FEh           ; 5  150 baud
  158.         dw      00FEh           ; 6  300 baud
  159.         dw      007Eh           ; 7  600 baud
  160.         dw      003Eh           ; 8 1200 baud
  161.         dw      0029h           ; 9 1800 baud (-0.78%)
  162.         dw      0024h           ;10 2000 baud (+1.05%)
  163.         dw      001Eh           ;11 2400 baud
  164.         dw      000Eh           ;12 4800 baud
  165.         dw      0006h           ;13 9600 baud
  166.         dw      0002h           ;14 19.2 kbaud
  167.         dw      0000h           ;15 38.4 kbaud - not supported
  168. baudlen equ     $-baudat        ;Size of table in bytes
  169.  
  170. datas   ends
  171.  
  172.  
  173. ; Serial port routines -- Initialize
  174.  
  175. code    segment public 'code'
  176.         assume  cs:code,ds:datas
  177.         extrn   sleep:near                              ; [jrd]
  178.         extrn   comnd:near,dopar:near
  179.  
  180. ;==============================================================================
  181. ; Initialization for using serial port.  Returns normally.
  182. ; This is called for by SEND, RECEIVE, and CONNECT commands.
  183. ;==============================================================================
  184.         db      'serini'
  185. serini  proc    near
  186.         cmp     portin,2                ;Is it initialized already?
  187.         jz      serinc                  ;Yes, skip all this
  188.         cli                             ;Disable interrupts
  189.         cld                             ;Do increments in string operations
  190.         push    es                      ;Set interrupt vector
  191.         xor     ax,ax
  192.         mov     es,ax                   ;Point to vector segment
  193.         push    bx                      ; save reg. [jrd]
  194.         mov     bx,modem.mdintv         ;Get vector address for this com port
  195.         mov     ax,es:[bx]
  196.         mov     savint,ax               ;Save old vector offset
  197.         mov     ax,offset serint
  198.         mov     es:[bx],ax              ;Replace with my offset
  199.         mov     ax,es:[bx+2]
  200.         mov     savint+2,ax             ;Save old vector segment
  201.         mov     es:[bx+2],cs            ;Replace with my segment
  202.         pop     bx                      ; [jrd]
  203.         pop     es
  204.         call    clrbuf                  ;Clear 8530 and memory buffers
  205.  
  206.         mov     si,offset parmta        ;Addr of port A parameter table
  207.         cmp     portin,1                ;1 means reset but dont hang up modem
  208.         jnz     sini10
  209.         add     si,2                    ;Skip over hardware reset to avoid
  210.                                         ;hanging up TI internal modems
  211. sini10: mov     dx,modem.mdstat         ;Port A command/status addr
  212.         in      al,dx                   ;Make sure it's pointing to WR0
  213.         mov     cx,parmas               ;Table size
  214. serina: lodsb                           ;Get a byte
  215.         out     dx,al                   ;Send it to 8530
  216.         loop    serina                  ;Do all of port A
  217.  
  218.         mov     si,offset parmtb        ;Addr of port-B parameter table
  219.         mov     dx,modem.mdcom          ;Port B command/status addr
  220.         in      al,dx                   ;Make sure it's pointing to WR0
  221.         mov     cx,parmbs
  222. serinb: lodsb                           ;Get a byte
  223.         out     dx,al                   ;Send it to 8530
  224.         loop    serinb
  225.  
  226.         in      al,19h                  ;Set up 8259a interrupt controller
  227.         and     al,modem.mden           ;Enable IR0, IR1, IR2, or IR4
  228.         out     19h,al
  229.  
  230.         sti                             ;Allow interrupts
  231. serinc: mov     portin,2                ;Flag that port is set up
  232.         ret
  233. serini  endp
  234.  
  235. ;==============================================================================
  236. ; Serial port interrupt handler. This routine gets all serial port interrupts
  237. ; and stores any data in a circular buffer.
  238. ;==============================================================================
  239.         db      'serint'
  240. serint  proc    near
  241.         sti                             ;Enable interrupts
  242.         push    ax                      ;Save registers used
  243.         push    bx
  244.         push    dx
  245.         push    di
  246.         push    ds
  247.         push    es
  248.         cld                             ;Auto increment
  249.         mov     ax,seg datas
  250.         mov     ds,ax                   ;Set segment registers
  251.         mov     es,ax
  252.         mov     dx,modem.mdstat         ;Get status register
  253.         in      al,dx                   ;Read RR0 contents
  254.         and     al,1                    ;See if any characters in receive FIFO
  255.         jz      sint50                  ;Jump if not
  256.         mov     dx,modem.mddat          ;Point to data register
  257.         in      al,dx                   ;Get received character
  258.         mov     bx,portval              ;Point to port data structure
  259.         cmp     [bx].parflg,parnon      ;Is parity off?
  260.         jz      sint5                   ;Jump if it is
  261.         and     al,7fh                  ;Strip off parity
  262. sint5:  or      al,al                   ;Throw away nulls
  263.         jz      sint50
  264.         cmp     [bx].floflg,0           ;Doing flow control?
  265.         je      sint20                  ;No
  266.         mov     dx,[bx].flowc           ;Flow control char, dh=XON, dl=XOFF
  267.         cmp     al,dl                   ;Is it an XOFF?
  268.         jne     sint10                  ;No, go on
  269.         mov     xofrcv,1                ;Set flag
  270.         jmp     short sint50
  271. sint10: cmp     al,dh                   ;Did we get an XON?
  272.         jne     sint20                  ;No, go on
  273.         mov     xofrcv,0                ;Clear XOFF flag
  274.         jmp     short sint50
  275. sint20: mov     di,savedi               ;Point to buffer location
  276.         stosb                           ;Store new char in circular buffer
  277.         cmp     di,offset source+bufsiz ;Is buffer pointer at end?
  278.         jb      sint30                  ;No, carry on
  279.         mov     di,offset source        ;Wrap buffer pointer to start of buffer
  280. sint30: inc     count                   ;Increment number of chars in buffer
  281.         cmp     [bx].floflg,0           ;Doing flow control?
  282.         je      sint40                  ;No, just leave
  283.         cmp     xofsnt,1                ;Have we sent an XOFF already?
  284.         je      sint40                  ;Yes, don't send another
  285.         cmp     count,mntrgh            ;Past the high trigger point?
  286.         jbe     sint40                  ;No, the buffer still has room
  287.         mov     ah,dl                   ;Get the XOFF character
  288.         call    outchr                  ;Send it
  289.         nop                             ;Waste 3 bytes for skip returns
  290.         nop                             ;  and ignore failures
  291.         nop
  292.         mov     xofsnt,1                ;Remember we sent it
  293. sint40: mov     savedi,di               ;Update buffer pointer
  294. sint50: cli
  295.         mov     al,20h                  ;Get end of interrupt code
  296.         out     18h,al                  ;Send End-of-Interrupt to 8259
  297.         pop     es                      ;Restore registers
  298.         pop     ds
  299.         pop     di
  300.         pop     dx
  301.         pop     bx
  302.         pop     ax
  303.         iret
  304. serint  endp
  305.  
  306. ;==============================================================================
  307. ; Reset the serial port.  This is the opposite of SERINI.  Calling
  308. ; this twice without intervening calls to SERINI should be harmless.
  309. ; Returns normally.
  310. ;==============================================================================
  311. serrst  proc    near
  312.         mov     portin,1                ;1 means reset all but don't hangup
  313.         cli                             ;  internal modem
  314.         mov     dx,modem.mdstat         ;Point to channel A WR0
  315.         mov     al,9
  316.         out     dx,al                   ;Register 9 write
  317.         xor     al,al
  318.         nop
  319.         out     dx,al                   ;disable 8530 interrupts
  320.         in      al,19h                  ;Disable 8259a IR line
  321.         or      al,modem.mddis
  322.         out     19h,al
  323.         push    es                      ;Reset interrupt vector
  324.         push    bx                      ; save reg. [jrd]
  325.         xor     bx,bx
  326.         mov     es,bx
  327.         mov     bx,modem.mdintv         ;Get vector address
  328.         mov     ax,savint
  329.         mov     es:[bx],ax              ;Restore saved vector
  330.         mov     ax,savint+2
  331.         mov     es:[bx+2],ax
  332.         pop     bx                      ; [jrd]
  333.         pop     es
  334.         sti
  335.         ret                             ;All done.
  336. serrst  endp
  337.  
  338. ;==============================================================================
  339. ; Clear the input buffer. This throws away all the characters in the
  340. ; serial interrupt buffer.  This is particularly important when
  341. ; talking to servers, since NAKs can accumulate in the buffer.
  342. ;==============================================================================
  343. clrbuf  proc    near
  344.         push    ax                      ; save regs. [jrd]
  345.         push    cx
  346.         push    dx
  347.         mov     ax,offset source
  348.         mov     savedi,ax               ;Place to put next character received
  349.         mov     savesi,ax               ;Place to get next character from
  350.         mov     cx,8
  351.         mov     dx,modem.mddat          ;Address channel-A data register
  352. clrbf1: in      al,dx                   ;Clear out anything in the receive FIFO
  353.         loop    clrbf1
  354.         mov     count,cx                ;Set count to zero
  355.         pop     dx
  356.         pop     cx
  357.         pop     ax
  358.         ret
  359. clrbuf  endp
  360.  
  361. ;==============================================================================
  362. ; Put the char in AH to the serial port.  This assumes the
  363. ; port has been initialized.  Should honor xon/xoff.  Skip returns on
  364. ; success, returns normally if the character cannot be written.
  365. ;==============================================================================
  366.         db      'outchr'
  367. outchr  proc    near
  368.         push    bx
  369.         push    cx
  370.         push    dx
  371.         mov     bx,portval
  372.         cmp     [bx].floflg,0           ;Are we doing flow control.
  373.         je      outch2                  ;No, just continue.
  374.         xor     cx,cx                   ;clear counter
  375.         cmp ah,byte ptr [bp].flowc      ; sending xoff? [jrd]
  376.         jne outch1              ; ne = no
  377.         mov xofsnt,false        ; supress xon from chkxon buffer routine
  378. outch1: cmp     xofrcv,1                ;Are we being held?
  379.         jne     outch2                  ;No - it's OK to go on.
  380.         loop    outch1                  ;held, try for a while
  381.         mov     xofrcv,0                ;timed out, force it off and fall thru.
  382. outch2: mov     al,ah                   ;Parity routine works on AL.
  383.         call    dopar                   ;Set parity appropriately.
  384.  
  385.         mov     ah,al                   ;Preserve character for a bit
  386.         xor     cx,cx                   ;Set loop counter to max
  387.         mov     dx,modem.mdstat         ;Port 1 channel A command/status address
  388. outch3: in      al,dx                   ;Get RR0 contents
  389.         and     al,04h                  ;Transmit buffer empty?
  390.         jnz     outch4                  ;Yes, output char
  391.         loop    outch3                  ;No, try again
  392.         jmp     outch5                  ;Loop counter expired, give up
  393. outch4: mov     dx,modem.mddat          ;Get port 1 channel A data address
  394.         mov     al,ah                   ;Get the character
  395.         out     dx,al                   ;Send it
  396.         pop     dx
  397.         pop     cx
  398.         pop     bx
  399.         jmp     rskp                    ;Skip return for OK
  400.  
  401. outch5: pop     dx
  402.         pop     cx
  403.         pop     bx
  404.         ret                             ;Non-skip return due to timeout
  405. outchr  endp
  406.  
  407. ;==============================================================================
  408. ; Set the current port.  Called from SET PORT command
  409. ;==============================================================================
  410. coms    proc    near
  411.         mov     dx,offset porttab       ;Point to list of port number keywords
  412.         mov     bx,0                    ;No help
  413.         mov     ah,cmkey                ;Parse a keyword
  414.         call    comnd
  415.         jmp r                           ;Return for errors
  416.         push    bx                      ;Save port number
  417.         mov     ah,cmcfm
  418.         call    comnd                   ;Get a confirm.
  419.         jmp     comx                    ;Didn't get a confirm. error
  420.         nop                             ;Need 3 bytes in here
  421.         call    serrst                  ;Reset previous serial port
  422.         pop     bx                      ;Restore desired comm port
  423.         mov     flags.comflg,bl         ;Set the comm port flag.
  424.  
  425.         cmp     flags.comflg,1          ;Port 1?
  426.         jne     coms2                   ;No, try another
  427.         mov     portval,offset port1
  428.         mov     modem.mddat,0e7h        ;Data reg
  429.         mov     modem.mdstat,0e6h       ;Channel A command/status
  430.         mov     modem.mdcom,0e4h        ;Channel B command/status
  431.         mov     modem.mddis,01h         ;Mask to disable IR0
  432.         mov     modem.mden,0feh         ;Mask to enable IR0
  433.         mov     modem.mdintv,40h*4      ;Vector for IR0
  434.         call    serini
  435.         ret
  436.  
  437. coms2:  cmp     flags.comflg,2          ;Port 2?
  438.         jne     coms3                   ;No, try another
  439.         mov     portval,offset port2
  440.         mov     modem.mddat,0efh        ;Data reg
  441.         mov     modem.mdstat,0eeh       ;Channel A command/status
  442.         mov     modem.mdcom,0ech        ;Channel B command/status
  443.         mov     modem.mddis,02h         ;Mask to disable IR1
  444.         mov     modem.mden,0fdh         ;Mask to enable IR1
  445.         mov     modem.mdintv,41h*4      ;Vector for IR1
  446.         call    serini
  447.         ret
  448.  
  449. coms3:  cmp     flags.comflg,3          ;Port 3?
  450.         jne     coms4                   ;No, try another
  451.         mov     portval,offset port3
  452.         mov     modem.mddat,0f7h        ;Data reg
  453.         mov     modem.mdstat,0f6h       ;Channel A command/status
  454.         mov     modem.mdcom,0f4h        ;Channel B command/status
  455.         mov     modem.mddis,04h         ;Mask to disable IR2
  456.         mov     modem.mden,0fbh         ;Mask to enable IR2
  457.         mov     modem.mdintv,42h*4      ;Vector for IR2
  458.         call    serini
  459.         ret
  460.  
  461. coms4:  mov     portval,offset port4
  462.         mov     modem.mddat,0ffh        ;Data reg
  463.         mov     modem.mdstat,0feh       ;Channel A command/status
  464.         mov     modem.mdcom,0fch        ;Channel B command/status
  465.         mov     modem.mddis,10h         ;Mask to disable IR4
  466.         mov     modem.mden,0efh         ;Mask to enable IR4
  467.         mov     modem.mdintv,44h*4      ;Vector for IR4
  468.         call    serini
  469.         ret
  470.  
  471. comx:   pop bx
  472.         ret
  473. coms    endp
  474.  
  475. ;==============================================================================
  476. ; Set heath emulation on/off.  Called from SET TERMINAL-EMULATION command
  477. ;==============================================================================
  478. vts     proc    near
  479.         mov     dx,offset ontab         ;Table containing OFF ON keywords
  480.         mov     bx,0                    ;No help
  481.         mov     ah,cmkey                ;Means parse a keyword
  482.         call    comnd                   ;Parse for ON or OFF
  483.         jmp     r                       ;Jump for errors
  484.         push    bx                      ;Save returned code for ON or OFF
  485.         mov     ah,cmcfm                ;Means parse a confirm
  486.         call    comnd                   ;Wait for confirm
  487.         jmp     short vt0               ;Jump for error
  488.         nop                             ;Needs 3 bytes here
  489.         pop     bx                      ;Restore return status
  490.         mov     flags.vtflg,bl          ;Set H19 on/off global variable
  491.         ret
  492. vt0:    pop     bx
  493.         ret
  494. vts     endp
  495.  
  496. VTSTAT  PROC    NEAR    ; For Status display [jrd]
  497.         ret             ; no emulator status to display
  498. VTSTAT  ENDP
  499.  
  500. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  501. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  502. ; is determined by mssset and is passed as pointer dmpname.
  503.  
  504. DUMPSCR PROC    NEAR    ; Dumps screen contents to a file. Just Beeps here
  505.         call beep       ; [jrd]
  506.         ret
  507. DUMPSCR ENDP
  508.  
  509.  
  510. ;==============================================================================
  511. ; Delete a character from the terminal.  This works by printing
  512. ; backspaces and spaces.  Returns normally.
  513. ;==============================================================================
  514. dodel   proc    near
  515.         mov     ah,9
  516.         mov     dx,offset delstr        ;Backspace-space-backspace
  517.         int     21h
  518.         ret
  519. dodel   endp
  520.  
  521. ;==============================================================================
  522. ; Move the cursor to the left margin, then clear to end of line.
  523. ; Returns normally.
  524. ;==============================================================================
  525. ctlu    proc    near
  526.         mov     ah,9
  527.         mov     dx,offset clrlin        ;Output CR, then clear to end of line
  528.         int     21h
  529.         ret
  530. ctlu    endp
  531.  
  532. ;==============================================================================
  533. ; This routine blanks the screen.  Returns normally.
  534. ;==============================================================================
  535. cmblnk  proc    near
  536.         mov     ah,13h          ;Function 13h of INT 49h clears the screen
  537.         int     49h
  538.         ret
  539. cmblnk  endp
  540.  
  541. ;==============================================================================
  542. ; Homes the cursor.  Returns normally.
  543. ;==============================================================================
  544. locate  proc    near
  545.         xor     dx,dx                   ;Go to top left corner of screen.
  546.         jmp     poscur
  547. locate  endp
  548.  
  549. ;==============================================================================
  550. ; Local initialization
  551. ;==============================================================================
  552. lclini  proc    near
  553.         mov     flags.vtflg,0   ; no terminal emulation. [jrd]
  554.         call    beep1           ;In case BASIC left the speaker messed up
  555.         ret
  556. lclini  endp
  557.  
  558. ;==============================================================================
  559. ; Port read character.  Check the port status.  If no data, skip
  560. ; return.  Else, read in a char and return.
  561. ;==============================================================================
  562.         db      'prtchr'
  563. prtchr  proc    near
  564.         call    chkxon                  ;See if we need to XON first
  565.         cmp     count,0                 ;See if anything in buffer
  566.         jnz     pc10                    ;Jump if something there
  567.         jmp     rskp                    ;Skip return since nothing there
  568. pc10:   mov     si,savesi               ;Get buffer pointer
  569.         lodsb                           ;Get char from buffer
  570.         cmp     si,offset source+bufsiz ;See if past end of buffer
  571.         jb      pc20                    ;Jump if not
  572.         mov     si,offset source        ;Wrap pointer to start of buffer
  573. pc20:   dec     count                   ;1 less char in buffer
  574.         mov     savesi,si               ;Save buffer pointer
  575.         mov     dx,count                ;Return remaining count in DX
  576.         ret
  577. prtchr  endp
  578.  
  579. ;==============================================================================
  580. ; Local routine to see if we have to transmit an xon
  581. ;==============================================================================
  582. chkxon  proc    near
  583.         push    bx
  584.         mov     bx,portval
  585.         cmp     [bx].floflg,0           ;Doing flow control?
  586.         je      chkxo1                  ;No, skip all this
  587.         cmp     xofsnt,0                ;Have we sent an xoff?
  588.         je      chkxo1                  ;No, forget it
  589.         cmp     count,mntrgh            ;Below trigger?
  590.         jae     chkxo1                  ;No forget it
  591.         mov     ax,[bx].flowc           ;AH gets xon
  592.         call    outchr                  ;Send XON character
  593.         nop
  594.         nop
  595.         nop                             ;In case it skips
  596.         mov     xofsnt,0                ;Remember we've sent the XON.
  597. chkxo1: pop     bx                      ;Restore register
  598.         ret                             ;And return
  599. chkxon  endp
  600.  
  601. ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
  602. ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
  603. ; else repeat cycle. Requires that the port be initialized before hand.
  604. ; Ihosts is used by the local send-file routine just after initializing
  605. ; the serial port.
  606. ; 22 March 1986 [jrd]
  607.  
  608. IHOSTS  PROC    NEAR
  609.         push    ax              ; save the registers
  610.         push    bx
  611.         push    cx
  612.         push    dx
  613.         mov     bx,portval      ; port indicator
  614.         mov     ax,[bx].flowc   ; put Go-ahead flow control char in ah
  615.         call    outchr          ; send it (release Host's output queue)
  616.          nop                    ; outchr can do skip return
  617.          nop
  618.          nop
  619. ihosts1:call    clrbuf          ; clear out interrupt buffer
  620.         mov     ax,1            ; sleep for 1 second
  621.         call    sleep           ; procedure sleep is in msscom.asm
  622.         call    prtchr          ; check for char at port
  623.          jmp    ihosts1         ; have a char in al, repeat wait/read cycle
  624.          nop                    ; prtchr does skip return on empty buffer
  625.         pop     dx              ; empty buffer. we are done here.
  626.         pop     cx
  627.         pop     bx
  628.         pop     ax
  629.         ret
  630. IHOSTS  ENDP
  631.  
  632. ; IHOSTR - initialize the remote host for our reception of a file by
  633. ; sending the flow-on character (XON typically) to release any held
  634. ; data. Called by receive-file code just after initializing the serial
  635. ; port.         22 March 1986 [jrd]
  636. IHOSTR  PROC    NEAR
  637.         push    ax              ; save regs
  638.         push    bx
  639.         push    cx
  640.         mov     bx,portval      ; port indicator
  641.         mov     ax,[bx].flowc   ; put Go-ahead flow control char in ah
  642.         call    outchr          ; send it (release Host's output queue)
  643.          nop                    ; outchr can do skip return
  644.          nop
  645.          nop
  646.         pop     cx
  647.         pop     bx
  648.         pop     ax
  649.         ret
  650. IHOSTR  ENDP
  651.  
  652. DTRLOW  PROC    NEAR            ; Global proc to Hangup the Phone by making
  653.                                 ; DTR and RTS low.
  654.         mov ah,cmtxt            ; allow text to be able to display help
  655.         mov bx,offset rdbuf     ; dummy buffer
  656.         mov dx,offset hnghlp    ; help message
  657.         call comnd              ; get a confirm
  658.          jmp r
  659. ; not yet imp.  call serhng             ; drop DTR and RTS
  660.         mov ah,prstr            ; give a nice message
  661. ; not yet imp.  mov dx,offset hngmsg
  662.         mov dx,offset noimp     ; for now
  663.         int dos
  664.         jmp rskp
  665. DTRLOW  ENDP
  666.  
  667. ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
  668. ; to terminate the connection. 29 March 1986 [jrd]
  669. ; Calling this twice without intervening calls to serini should be harmless.
  670. ; Returns normally.
  671. ; SERHNG is Not Yet Implemented.
  672.  
  673.  
  674. ;==============================================================================
  675. ; Set the baud rate for the current port, based on the value
  676. ; in the portinfo structure.  Returns normally.
  677. ; Called from SET BAUD command with new index in PORT.BAUD, previous in AX
  678. ;==============================================================================
  679.         db      'dobaud'
  680. dobaud  proc    near
  681.         push    bx
  682.         mov     bx,portval              ;Get pointer
  683.         mov     bx,[bx].baud            ;Get new baud-rate index
  684.         shl     bx,1                    ;Multiply by 2
  685.         cmp     baudat[bx],0            ;Test for zero
  686.         jne     dobod1                  ;Nonzero is OK
  687.         mov     bx,portval              ;Error, get back to data structure
  688.         mov     [bx].baud,ax            ;Restore previous baud rate number
  689.         mov     ah,9
  690.         mov     dx,offset badbd         ;Bad baud rate
  691.         int     21h
  692.         pop     bx
  693.         ret
  694.  
  695. dobod1: mov     ax,baudat[bx]           ;Get BRG divisor
  696.         call    setbaud                 ;Send AX to baud-rate-divisor
  697.         pop     bx
  698.         ret
  699. dobaud  endp
  700.  
  701. ;==============================================================================
  702. ; Local routine to send AX to the Baud Rate Generator.  Preserves all regs
  703. ;==============================================================================
  704. setbaud proc    near
  705.         push    dx
  706.         push    ax                      ;Save rate
  707.         mov     dx,modem.mdstat         ;Address the channel-A command port
  708.         mov     al,13                   ;Point to register 13
  709.         out     dx,al
  710.         jmp     short $+2               ;Slight delay to let hardware respond
  711.         mov     al,ah                   ;High-order part of divisor
  712.         out     dx,al
  713.         jmp     short $+2
  714.         mov     al,12                   ;Point to register 12
  715.         out     dx,al
  716.         jmp     short $+2
  717.         pop     ax
  718.         out     dx,al                   ;Low-order part of divisor
  719.         pop     dx
  720.         ret
  721. setbaud endp
  722.  
  723. ;==============================================================================
  724. ; Clear to the end of the current line.  Returns normally.
  725. ;==============================================================================
  726. clearl  proc    near
  727.         mov     ah,9
  728.         mov     dx,offset clreol        ;Erase from cursor to end of line
  729.         int     21h
  730.         ret
  731. clearl  endp
  732.  
  733. ;==============================================================================
  734. ; this is called by Kermit initialization.  It checks the
  735. ; number of disks on the system, sets the drives variable
  736. ; appropriately.  Returns normally.
  737. ;==============================================================================
  738. dodisk  proc    near
  739.         mov ah,gcurdsk                  ;Current disk value to AL.
  740.         int 21h
  741.         mov dl,al                       ;Put current disk in DL.
  742.         mov ah,seldsk                   ;Select current disk.
  743.         int 21h                         ;Returns number of drives in AL.
  744.         mov drives,al                   ;Set global variable
  745.         ret
  746. dodisk  endp
  747.  
  748. ;==============================================================================
  749. ; Get the current baud rate from the serial card and set it
  750. ; in the portinfo structure for the current port.  Returns normally.
  751. ; This is used during initialization.
  752. ;==============================================================================
  753. getbaud proc    near
  754.         push    ax                      ; save some regs. [jrd]
  755.         push    bx                      ; [jrd]
  756.         push    dx                      ; [jrd]
  757.         mov     dx,modem.mdstat         ;Address channel-A command port
  758.         mov     al,13                   ;Point to register 13
  759.         out     dx,al
  760.         jmp     short $+2               ;Small delay
  761.         in      al,dx                   ;Read RR13
  762.         mov     ah,al                   ;Save high-order part
  763.         mov     al,12                   ;Point to register 12
  764.         out     dx,al
  765.         jmp     short $+2
  766.         in      al,dx                   ;Read RR12
  767. ;Baud rate = (300*256)/(AX+2)
  768.         mov     bx,0                    ;Index value
  769. getbd1: cmp     ax,baudat[bx]           ;See if known value
  770.         je      getbd2                  ;Found it
  771.         add     bx,2                    ;Point to next word
  772.         cmp     bl,baudlen              ;End of table?
  773.         jl      getbd1                  ;No, keep looking
  774.         mov     bx,B1200*2              ;Yes, force it to 1200 baud
  775.         mov     ax,baudat[bx]
  776.         call    setbaud
  777.  
  778. getbd2: mov     ax,bx                   ;Get the byte index
  779.         shr     ax,1                    ;Reduce to number from 0 to 15
  780.         mov     bx,portval              ;Point to structure
  781.         mov     [bx].baud,ax            ;Store where SHOW processor can see it
  782.         pop     dx                      ; restore regs. [jrd]
  783.         pop     bx                      ; [jrd]
  784.         pop     ax                      ; [jrd]
  785.         ret
  786. getbaud endp
  787.  
  788. ;==============================================================================
  789. ; Produce a short beep.  The PC DOS bell is long enough to cause a loss
  790. ; of data at the port.  Returns normally.
  791. ;==============================================================================
  792. beep1   proc    near
  793.         mov     ah,2                    ;Set speaker frequency
  794.         mov     cx,1000                 ;Approx 1.5 kHz
  795.         int     48h
  796.         ret
  797. beep1   endp
  798.  
  799. beep    proc    near
  800.         call    beep1                   ;Set the frequency
  801.         mov     ah,0                    ;Timed beep function
  802.         mov     al,5                    ;5/40 = 1/8 second
  803.         int     48h
  804.         ret
  805. beep    endp
  806.  
  807. ;==============================================================================
  808. ; Put a help message on the screen.
  809. ; Pass the message in ax, terminated by a null.  Returns normally.
  810. ;==============================================================================
  811. puthlp  proc    near
  812.         push    ax                      ;preserve this
  813.         mov     ah,9
  814.         mov     dx,offset crlf
  815.         int     21h
  816.         pop     si                      ;point to string again
  817. puthl3: lodsb                           ;get a byte
  818.         cmp     al,0                    ;end of string?
  819.         je      puthl4                  ;yes, stop
  820.         mov     dl,al
  821.         mov     ah,6
  822.         int     21h                     ;else write to screen
  823.         jmp     puthl3                  ;and keep going
  824. puthl4: mov     ah,9
  825.         mov     dx,offset crlf
  826.         int     21h
  827.         ret
  828. puthlp  endp
  829.  
  830. ;==============================================================================
  831. ; Write a line at the bottom of the screen...
  832. ; the line is passed in dx, terminated by a $.  Returns normally.
  833. ;==============================================================================
  834. putmod  proc    near
  835.         push    dx                      ;preserve message
  836.         mov     dx,24*100h              ;now address line 24
  837.         call    poscur
  838.         mov     dx,offset invvid
  839.         mov     ah,9
  840.         int     21h                     ;Set inverse video
  841.         pop     dx                      ;get message back
  842.         mov     ah,9
  843.         int     21h                     ;write it out
  844.         mov     dx,offset norvid
  845.         mov     ah,9
  846.         int     21h                     ;Normal video
  847.         ret                             ;and return
  848. putmod  endp
  849.  
  850. ;==============================================================================
  851. ; Clear the mode line written by PUTMOD.  Returns normally.
  852. ;==============================================================================
  853. clrmod  proc    near
  854.         mov     dx,1800h
  855.         call    poscur                  ;Go to bottom row.
  856.         call    clearl                  ;Clear to end of line.
  857.         ret
  858. clrmod  endp
  859.  
  860. ;==============================================================================
  861. ; Position the cursor according to contents of DX:
  862. ; DH contains row, DL contains column.  Returns normally.
  863. ;==============================================================================
  864. poscur  proc    near
  865.         xchg    dh,dl                   ;BIOS wants row in DL, Col in DH
  866.         mov     ah,2                    ;Locate cursor function
  867.         int     49h
  868.         ret
  869. poscur  endp
  870.  
  871. ;==============================================================================
  872. ; Send a break out the current serial port.  Returns normally.
  873. ;==============================================================================
  874. sendbr  proc    near
  875.         push    cx
  876.         push    dx
  877.         push    ax
  878.         xor     cx,cx                   ;Clear loop counter.
  879.         mov     dx,modem.mdstat         ;Address channel-A command port
  880.         mov     al,5                    ;Point to register 5
  881.         out     dx,al
  882.         jmp     short $+2
  883.         in      al,dx                   ;Get current setting.
  884.         mov     ah,al                   ;Copy the bits
  885.         mov     al,5                    ;Point back to register 5
  886.         out     dx,al
  887.         mov     al,ah                   ;Get old bits
  888.         or      al,10h                  ;Set send-break bit
  889.         out     dx,al                   ;Start the break
  890. pause:  loop    pause                   ;Wait a while.
  891.         mov     al,5                    ;Point to register 5
  892.         out     dx,al
  893.         jmp     short $+2
  894.         mov     al,ah                   ;Clear send-break bit
  895.         out     dx,al                   ;Stop the break
  896.         pop     ax
  897.         pop     dx
  898.         pop     cx
  899.         ret                             ;And return.
  900.         ret
  901. sendbr  endp
  902.  
  903. ;==============================================================================
  904. ; Called by the SHOW KEY command
  905. ;==============================================================================
  906. showkey proc    near
  907.         mov ax,offset shkmsg
  908.         mov cx,shklen
  909.         ret
  910. showkey endp
  911.  
  912. ;==============================================================================
  913. ; Jumping to this location is like retskp.  It assumes the instruction
  914. ; after the call is a jmp addr.
  915. ;==============================================================================
  916. rskp    proc    near
  917.         pop bp
  918.         add bp,3
  919.         push bp
  920.         ret
  921. rskp    endp
  922.  
  923. ;==============================================================================
  924. ; Jumping here is the same as a ret. The jump to here uses up the 3 bytes
  925. ;==============================================================================
  926. r       proc    near
  927.         ret
  928. r       endp
  929.  
  930. code    ends
  931.         end
  932.