home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / asm / MSKERMIT.ZIP / MSXIBM.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-05-17  |  21.4 KB  |  829 lines

  1. ; Kermit system dependent module for IBM-PC
  2.  
  3.     public    serini, serrst, clrbuf, outchr, coms, vts, dodel,
  4.     public    ctlu, cmblnk, locate, prtchr, dobaud, clearl,
  5.     public    dodisk, getbaud, beep,
  6.     public    count, xofsnt, puthlp, putmod, clrmod, poscur
  7.     public    sendbr, machnam, setktab, setkhlp, lclini, showkey
  8.     include msdefs.h
  9.  
  10. false    equ    0
  11. true    equ    1
  12. mntrgh    equ    bufsiz*3/4    ; High point = 3/4 of buffer full.
  13.  
  14. ; constants used by serial port handler
  15.  
  16. BRKBIT    EQU    040H        ; Send-break bit. 
  17. TIMER    EQU    40H        ; Use to issue short beep.
  18. PORT_B    EQU    61H        ; Port B address.
  19. MCONF    EQU    11H        ; Machine configuration. 
  20. KEYB    EQU    16H
  21. BIOS    EQU    10H
  22.  
  23. MDMDAT1    EQU    03F8H        ; Address of modem port (data). [19b]
  24. MDMSTS1    EQU    03FDH        ; Address of modem port    status. [19b]
  25. MDMCOM1    EQU    03FBH        ; Address of modem port command. [19b]
  26. MDMDAT2    EQU    02F8H        ; Port 2 address. [19b]
  27. MDMSTS2    EQU    02FDH        ; Port 2 status. [19b]
  28. MDMCOM2    EQU    02FBH        ; Port 2 command. [19b]
  29. MDMINP    EQU    1        ; Input ready bit.
  30.  
  31. MDMINTV    EQU    0030H        ; Address of modem port interrupt vector.
  32. MDINTV2 EQU    002CH        ; Address for port 2. [19b] 
  33. MDMINTO    EQU    0EFH        ; Mask to enable interrupt for modem port.
  34. MDINTO2 EQU    0F7H        ; Enable interrupt level 3. [19b]
  35. MDMINTC    EQU    010H        ; Bit to set to disable interrupts for modem.
  36. MDINTC2 EQU    008H        ; Disable IRQ3. [19b]
  37.  
  38. INTCONT    EQU    0021H        ; Address of 8259 interrupt controller ICW2-3.
  39. INTCON1    EQU    0020H        ; Address of 8259 ICW1.
  40. EOICOM    EQU    0064H        ; End of interrupt.
  41. EOICOM2    EQU    0063H        ; End of interrupt for COM2. [19b]
  42.  
  43. ; external variables used:
  44. ; drives - # of disk drives on system
  45. ; flags - global flags as per flginfo structure defined in pcdefs
  46. ; trans - global transmission parameters, trinfo struct defined in pcdefs
  47. ; portval - pointer to current portinfo structure (currently either port1
  48. ;    or port2)
  49. ; port1, port2 - portinfo structures for the corresponding ports
  50.  
  51. ; global variables defined in this module:
  52. ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
  53. ; setktab - keyword table for redefining keys (should contain a 0 if
  54. ;    not implemented)
  55. ; setkhlp - help for setktab.
  56.  
  57. datas     segment    public 'datas'
  58.     extrn    drives:byte,flags:byte, trans:byte
  59.     extrn    portval:word, port1:byte, port2:byte
  60.  
  61. setktab    db    12
  62.     mkeyw    'BACKSPACE',0eh
  63.     mkeyw    'F1',3bh
  64.     mkeyw    'F2',3ch
  65.     mkeyw    'F3',3dh
  66.     mkeyw    'F4',3eh
  67.     mkeyw    'F5',3fh
  68.     mkeyw    'F6',40h
  69.     mkeyw    'F7',41h
  70.     mkeyw    'F8',42h
  71.     mkeyw    'F9',43h
  72.     mkeyw    'F10',44h
  73.     mkeyw    'SCAN',-1
  74.  
  75. setkhlp    db    cr,lf,'Keyname: backspace, f1, ... f10, or "SCAN" follwed by '
  76.     db    'decimal scan code$'
  77. brkval    db    0        ; What to send for a break.
  78. brkadr    dw    0        ; Where to send it.
  79. modem    mdminfo    <MDMDAT1,MDMSTS1,MDMCOM1,MDMINTO,MDMINTC,EOICOM,MDMINTV>
  80. erms20    db    cr,lf,'?Warning: System has no disk drives$' ; [21a]
  81. erms40    db    cr,lf,'?Warning: Unrecognized baud rate$'
  82. badbd    db    cr,lf,'Unimplemented baud rate$'
  83. machnam    db    'IBM-PC$'
  84. crlf    db    cr,lf,'$'
  85. delstr  db    BS,' ',BS,'$'     ; Delete string. [21d]
  86. clrlin  db    cr,'$'            ; Clear line (just the cr part).
  87. savsci    dw    ?        ; Save for serial port interrupt vector. [14]
  88. savscs    dw    ?        ; Ditto.  [14]  
  89. savbr1    dw    ?        ; "Break" interrupt vector. [25]
  90. savbr2    dw    ?        ; Ditto. [25]
  91. portin    db    0        ; Has comm port been initialized. [21c]
  92. xofsnt    db    0        ; Say if we sent an XOFF.
  93. xofrcv    db    0        ; Say if we received an XOFF.
  94. tmp    db    ?,'$'
  95. temp    dw    0
  96. temp1    dw    ?        ; Temporary storage.
  97. temp2    dw    ?        ; Temporary storage.
  98.  
  99. ontab    db    02H        ; Two entries.
  100.     db    03H,'OFF$'    ; Should be alphabetized.  [19a]
  101.     dw    00H
  102.     db    02H,'ON$'
  103.     dw    01H
  104.  
  105. comptab    db    04H
  106.     db    01H,'1$'
  107.     dw    01H
  108.     db    01H,'2$'
  109.     dw    00H
  110.     db    04H,'COM1$'
  111.     dw    01H
  112.      db    04H,'COM2$'
  113.     dw    00H
  114.  
  115. ; this table is indexed by the baud rate definitions given in
  116. ; pcdefs.  Unsupported baud rates should contain FF.
  117. bddat    label    word
  118.     dw    0FFH        ; 45.5 baud  -- Not supported.
  119.     dw    900H        ; 50 baud
  120.     dw    600H        ; 75 baud
  121.     dw    417H        ; 110 baud
  122.     dw    359H        ; 134.5 baud
  123.     dw    300H        ; 150 baud
  124.     dw    180H        ; 300 baud
  125.     dw    0C0H        ; 600 baud
  126.     dw    60H        ; 1200 baud
  127.     dw    40H        ; 1800 baud
  128.     dw    3AH        ; 2000 baud
  129.     dw    30H        ; 2400 baud
  130.     dw    18H        ; 4800 baud
  131.     dw    0CH        ; 9600 baud
  132.     dw    0FFH        ; 19200 baud -- Not supported.
  133.     dw    0FFH        ; 38400 baud -- Not supported.
  134.  
  135. ; variables for serial interrupt handler
  136.  
  137. source    db    bufsiz DUP(?)    ; Buffer for data from port.
  138. srcpnt    dw    0        ; Pointer in buffer (DI).
  139. count    dw    0        ; Number of chars in int buffer.
  140. savesi    dw    0        ; Save SI register here.    
  141. telflg    db    0        ; Are we acting as a terminal.
  142. mst    dw    0        ; Modem status address.
  143. mdat    dw    0        ; Modem data address.
  144. mdeoi    db    0        ; End-of-Interrupt value.
  145.  
  146. rbtrn    db    7fH        ; rubout
  147.  
  148. shkbuf    db    300 dup (?)    ; room for definition
  149. shkmsg    db    '  Scan code: '
  150. shkmln    equ    $-shkmsg
  151. shkms1    db    cr,lf,'  Definition: '
  152. shkm1ln    equ    $-shkms1
  153. datas    ends
  154.  
  155. code    segment    public
  156.     extrn    comnd:near, dopar:near, defkey:near, gss:near
  157.     assume    cs:code,ds:datas
  158.  
  159. ; local initialization
  160.  
  161. lclini    proc    near
  162.     mov    ax,0eH        ; scan code for arrow key
  163.     mov    si,offset rbtrn    ; translate to rubout
  164.     mov    cx,1        ; one char translation
  165.     call    defkey
  166.     mov brkval,BRKBIT    ; What to send for a break.
  167.     mov ax,modem.mdcom    ; Where to send it.
  168.     mov brkadr,ax
  169.     ret
  170. lclini    endp
  171.  
  172. ; this is called by Kermit initialization.  It checks the
  173. ; number of disks on the system, sets the drives variable
  174. ; appropriately.  Returns normally.  
  175.  
  176. DODISK    PROC    NEAR
  177.     int mconf            ; Get equipment configuration.
  178.     mov ah,al            ; Store AL value for a bit.
  179.     and al,01H            ; First, look at bit 0.
  180.     jz dodsk0            ; No disk drives -- forget it.
  181.     mov al,ah            ; Get back original value.
  182.     mov cl,6            ; Shift over bits 6 and 7.
  183.     shr al,cl            ; To positions 0 and 1.
  184.     inc al                ; Want 1 thru 4 (not 0 thru 3).
  185.     mov drives,al            ; Remember how many. 
  186.     ret
  187. dodsk0:    mov ah,prstr            ; Print a warning message.
  188.     mov dx,offset erms20        ; I'm not sure if things will
  189.     int dos                ; work with only a cassette.
  190.     mov drives,0            ; Say there aren't any drives.
  191.     ret
  192. DODISK    ENDP
  193.  
  194. ; show the definition of a key.  The terminal argument block (which contains
  195. ; the address and length of the definition tables) is passed in ax.
  196. ; Returns a string to print in AX, length of same in CX.
  197. ; Returns normally.
  198. showkey    proc    near
  199.     push    es
  200.     push    ax        ; save the ptr
  201.     mov    bx,ds
  202.     mov    es,bx        ; address data segment
  203.     cld
  204. showk1:    xor    ah,ah
  205.     int    keyb        ; read a char
  206.     push    ax        ; save the character
  207.     call    gss        ; get shift state
  208.     pop    bx
  209.     mov    ah,al        ; shift state to ah
  210.     mov    al,bh        ; scan code to al
  211.     push    ax        ; remember scan code
  212.     mov    di,offset shkbuf
  213.     mov    si,offset shkmsg
  214.     mov    cx,shkmln
  215.     rep    movsb        ; copy in initial message
  216.     call    nout        ; write out scan code
  217.     mov    si,offset shkms1
  218.     mov    cx,shkm1ln    ; second message
  219.     rep    movsb
  220.     pop    ax        ; get scan code back
  221.     pop    bx        ; and terminal arg block
  222.     mov    cx,[bx].klen    ; and length
  223.     jcxz    showk2        ; no table, not defined
  224.     push    di        ; remember output ptr
  225.     mov    di,[bx].ktab    ; get key table
  226.     repne    scasw        ; search for a definition for this
  227.     mov    si,di        ; remember result ptr
  228.     pop    di        ; get output ptr back
  229.     jne    showk2        ; not defined, forget it
  230.     sub    si,[bx].ktab    ; compute offset from beginning
  231.     sub    si,2        ; minus 2 for pre-increment
  232.     add    si,[bx].krpl    ; get index into replacement table
  233.     mov    si,[si]        ; pick up replacement
  234.     mov    cl,[si]        ; get length
  235.     mov    ch,0
  236.     inc    si
  237.     rep    movsb        ; copy into buffer
  238. showk2:    mov    ax,offset shkbuf ; this is buffer
  239.     mov    cx,di
  240.     sub    cx,ax        ; length
  241.     pop    es
  242.     ret            ; and return
  243. showkey    endp
  244.  
  245. ; Clear the input buffer. This throws away all the characters in the
  246. ; serial interrupt buffer.  This is particularly important when
  247. ; talking to servers, since NAKs can accumulate in the buffer.
  248. ; Returns normally.
  249.  
  250. CLRBUF    PROC    NEAR
  251.     cli
  252.     mov ax,offset source
  253.     mov srcpnt,ax
  254.     mov savesi,ax
  255.     mov count,0
  256.     sti
  257.     ret
  258. CLRBUF    ENDP
  259.  
  260. ; Clear to the end of the current line.  Returns normally.
  261.  
  262. CLEARL    PROC    NEAR
  263.     mov ah,3        ; Clear to end of line.
  264.     mov bh,0
  265.     int bios        ; Get current cursor position
  266.     mov cx,dx
  267.     mov dl,79
  268.     mov ah,7
  269.     mov al,0
  270.     mov bh,7
  271.     int bios
  272.     ret
  273. CLEARL    ENDP
  274.  
  275. ; Put the char in AH to the serial port.  This assumes the
  276. ; port has been initialized.  Should honor xon/xoff.  Skip returns on
  277. ; success, returns normally if the character cannot be written.
  278.  
  279. outchr:    mov bp,portval
  280.     cmp ds:[bp].floflg,0    ; Are we doing flow control.
  281.     je outch2        ; No, just continue.
  282.     xor cx,cx        ; clear counter
  283. outch1:    cmp xofrcv,true        ; Are we being held?
  284.     jne outch2        ; No - it's OK to go on.
  285.     loop outch1        ; held, try for a while
  286.     mov xofrcv,false    ; timed out, force it off and fall thru.
  287. outch2:    push dx            ; Save register.
  288.     sub cx,cx
  289.     mov al,ah        ; Parity routine works on AL.
  290.     call dopar        ; Set parity appropriately.
  291.     mov ah,al        ; Don't overwrite character with status.
  292.     mov dx,modem.mdstat    ; Get port status.
  293. outch3:    in al,dx
  294.     test al,20H        ; Transmitter ready?
  295.     jnz outch4        ; Yes
  296.     loop outch3
  297.      jmp outch5        ; Timeout
  298. outch4:    mov al,ah        ; Now send it out
  299.     mov dx,modem.mddat
  300.     out dx,al
  301.     pop dx
  302.     jmp rskp
  303. outch5:    pop dx
  304.     ret
  305.  
  306. ; This routine blanks the screen.  Returns normally.
  307.  
  308. CMBLNK    PROC    NEAR        ; This is stolen from the IBM example.
  309.     mov cx,0
  310.     mov dx,184FH
  311.     mov bh,7
  312.     mov ax,600H
  313.     int bios
  314.     ret
  315. CMBLNK  ENDP
  316.  
  317. ; Locate: homes the cursor.  Returns normally.
  318.  
  319. LOCATE  PROC    NEAR
  320.     mov dx,0        ; Go to top left corner of screen.
  321.     jmp poscur
  322. LOCATE  ENDP
  323.  
  324. ; write a line in inverse video at the bottom of the screen...
  325. ; the line is passed in dx, terminated by a $.  Returns normally.
  326. putmod    proc    near
  327.     push    dx        ; preserve message
  328.     mov    cx,1800h
  329.     mov    dx,184fh
  330.     mov    ax,600h        ; scroll to clear the line
  331.     mov    bh,70h        ; inverse video
  332.     int    bios
  333.     mov    dx,1800h    ; now address line 24
  334.     call    poscur
  335.     pop    dx        ; get message back
  336.     mov    ah,prstr
  337.     int    dos        ; write it out
  338.     ret            ; and return
  339. putmod    endp
  340.  
  341. ; clear the mode line written by putmod.  Returns normally.
  342. clrmod    proc    near
  343.     mov    cx,1800h
  344.     mov    dx,184fh
  345.     mov    ax,600h
  346.     mov    bh,7h
  347.     int    bios
  348.     ret
  349. clrmod    endp
  350.  
  351. ; put a help message on the screen.  This one uses reverse video...
  352. ; pass the message in ax, terminated by a null.  Returns normally.
  353. puthlp    proc    near
  354.     push    ax        ; preserve this
  355.     mov    si,ax        ; point to it
  356.     mov    dh,1        ; init counter
  357. puthl1:    lodsb            ; get a byte
  358.     cmp    al,lf        ; linefeed?
  359.     jne    puthl2        ; no, keep going
  360.     inc    dh        ; count it
  361.     jmp    puthl1        ; and keep looping
  362. puthl2:    cmp    al,0        ; end of string?
  363.     jne    puthl1        ; no, keep going
  364.     mov    ax,600h        ; scroll to clear window
  365.     xor    cx,cx        ; from top left
  366.     mov    dl,4fh        ; to bottom right of needed piece
  367.     mov    bh,70h        ; inverse video
  368.     int    bios
  369.     call    locate        ; home cursor
  370.     pop    si        ; point to string again
  371. puthl3:    lodsb            ; get a byte
  372.     cmp    al,0        ; end of string?
  373.     je    puthl4        ; yes, stop
  374.     mov    ah,14
  375.     int    bios        ; else write to screen
  376.     jmp    puthl3        ; and keep going
  377. puthl4:    mov    dx,24 * 100H    ; go to last line
  378.     jmp    poscur        ; position and return
  379. puthlp    endp
  380.  
  381. ; Set the baud rate for the current port, based on the value
  382. ; in the portinfo structure.  Returns normally.
  383.  
  384. DOBAUD    PROC    NEAR
  385.     mov bp,portval
  386.     mov temp1,ax        ; Don't overwrite previous rate. [25]
  387.     mov ax,ds:[bp].baud    ; Check if new rate is valid. [25]
  388.     mov tmp,2
  389.     mul tmp            ; Get index into baud table.
  390.     mov bx,offset bddat    ; Start of table.
  391.     add bx,ax
  392.     mov ax,[bx]        ; The data to output to port.
  393.     cmp ax,0FFH        ; Unimplemented baud rate.
  394.     jne dobd0
  395.     mov ax,temp1        ; Get back orginal value.
  396.     mov ds:[bp].baud,ax    ; Leave baud rate as is.
  397.     mov ah,prstr
  398.     mov dx,offset badbd    ; Give an error message.
  399.     int dos
  400.     ret
  401. dobd0:    mov temp1,ax        ; Remember value to output. [25]
  402.     mov dx,modem.mdcom    ; LCR -- Initialize baud rate. [19b]
  403.     in al,dx
  404.     mov bl,al
  405.     or ax,80H
  406.     out dx,al
  407.     mov dx,modem.mddat    ; [19b]
  408.     mov ax,temp1
  409.     out dx,al
  410.     inc dx
  411.     mov al,ah
  412.     out dx,al
  413.     mov dx,modem.mdcom    ; [19b]
  414.     mov al,bl
  415.     out dx,al
  416.     ret
  417. DOBAUD    ENDP
  418.  
  419. ; Get the current baud rate from the serial card and set it
  420. ; in the portinfo structure for the current port.  Returns normally.
  421. ; This is used during initialization.
  422.  
  423. GETBAUD    PROC    NEAR
  424.     mov dx,modem.mdcom    ; Get current Line Control Register value.
  425.     in al,dx
  426.     mov bl,al        ; Save it.
  427.     or ax,80H        ; Turn on to access baud rate generator.
  428.     out dx,al
  429.     mov dx,modem.mddat    ; Divisor latch.
  430.     inc dx
  431.     in al,dx        ; Get hi order byte.
  432.     mov ah,al        ; Save here.
  433.     dec dx
  434.     in al,dx        ; Get lo order byte.
  435.     push ax    
  436.     mov dx,modem.mdcom
  437.     mov al,bl        ; Restore old value.
  438.     out dx,al
  439.     pop ax
  440.     cmp ax,0FFFFH        ; Who knows what this is.
  441.     je getb2
  442.     mov bx,offset bddat    ; Find rate's offset into table.
  443.     mov cl,0        ; Keep track of index.
  444. getb0:    cmp ax,[bx]
  445.     je getb1
  446.     inc cl
  447.     cmp cl,baudsiz        ; At the end of the list.
  448.     jge getb2
  449.     add bx,2
  450.     jmp getb0
  451. getb1:    mov ch,0
  452.     mov bp,portval
  453.     mov ds:[bp].baud,cx    ; Set baud rate.
  454.     ret
  455. getb2:    mov ah,prstr
  456.     mov dx,offset erms40
  457.     int dos
  458.     ret
  459. GETBAUD    ENDP
  460.  
  461. ; skip returns if no character available at port,
  462. ; otherwise returns with char in al, # of chars in buffer in dx.
  463. PRTCHR  PROC    NEAR
  464.     call chkxon        ; see if we need to xon
  465.     cmp count,0
  466.     jnz prtch2
  467.     jmp rskp        ; No data - check console.
  468. prtch2:    mov si,savesi
  469.     lodsb            ; get a byte
  470.     cmp si,offset source + bufsiz    ; bigger than buffer?
  471.     jb prtch1        ; no, keep going
  472.     mov si,offset source    ; yes, wrap around
  473. prtch1:    dec count
  474.     mov savesi,si 
  475.     mov dx,count        ; return # of chars in buffer
  476.     ret
  477. PRTCHR  ENDP
  478.  
  479. ; local routine to see if we have to transmit an xon
  480. chkxon    proc    near
  481.     push    bx
  482.     mov    bx,portval
  483.     cmp    [bx].floflg,0    ; doing flow control?
  484.     je    chkxo1        ; no, skip all this
  485.     cmp    xofsnt,false    ; have we sent an xoff?
  486.     je    chkxo1        ; no, forget it
  487.     cmp    count,mntrgh    ; below trigger?
  488.     jae    chkxo1        ; no, forget it
  489.     mov    ax,[bx].flowc    ; ah gets xon
  490.     call    outchr        ; send it
  491.     nop
  492.     nop
  493.     nop            ; in case it skips
  494.     mov    xofsnt,false    ; remember we've sent the xon.
  495. chkxo1:    pop    bx        ; restore register
  496.     ret            ; and return
  497. chkxon    endp
  498.  
  499. ; Send a break out the current serial port.  Returns normally.
  500. SENDBR    PROC    NEAR
  501.     push cx
  502.     push dx
  503.     push ax
  504.     xor cx,cx        ; Clear loop counter.
  505.     mov dx,brkadr        ; Port address.  [19b]
  506.     in al,dx        ; Get current setting.
  507.     or al,brkval        ; Set send-break bit(s).
  508.     out dx,al        ; Start the break.
  509. pause:    loop pause        ; Wait a while.
  510.     xor al,brkval        ; Clear send-break bit(s).
  511.     out dx,al        ; Stop the break.
  512.     pop ax
  513.     pop dx
  514.     pop cx
  515.     ret            ; And return.
  516. SENDBR    ENDP
  517.  
  518. ; Position the cursor according to contents of DX:
  519. ; DH contains row, DL contains column.  Returns normally.
  520.  
  521. POSCUR    PROC    NEAR
  522.     mov ah,2        ; Position cursor.
  523.     mov bh,0
  524.     int bios
  525.     ret
  526. POSCUR    ENDP
  527.  
  528. ; Delete a character from the terminal.  This works by printing
  529. ; backspaces and spaces.  Returns normally.
  530.  
  531. DODEL    PROC    NEAR
  532.     mov ah,prstr
  533.     mov dx,offset delstr    ; Erase weird character.
  534.     int dos            
  535.     ret
  536. DODEL    ENDP
  537.  
  538. ; Move the cursor to the left margin, then clear to end of line.
  539. ; Returns normally.
  540.  
  541. CTLU    PROC    NEAR
  542.     mov ah,prstr
  543.     mov dx,offset clrlin
  544.     int dos
  545.     call clearl
  546.     ret
  547. CTLU    ENDP
  548.  
  549. ; set the current port.  
  550.  
  551. COMS    PROC    NEAR
  552.     mov dx,offset comptab
  553.     mov bx,0
  554.     mov ah,cmkey
  555.     call comnd
  556.      jmp r
  557.     push bx
  558.     mov ah,cmcfm
  559.     call comnd        ; Get a confirm.
  560.      jmp comx        ;  Didn't get a confirm.
  561.      nop
  562.     pop bx
  563.     mov flags.comflg,bl    ; Set the comm port flag.
  564.     cmp flags.comflg,1    ; Using Com 1?
  565.     jne coms0        ; Nope.
  566.     mov ax,offset port1
  567.     mov portval,ax
  568.     mov modem.mddat,MDMDAT1    ; Set COM1 defaults.
  569.     mov modem.mdstat,MDMSTS1
  570.     mov modem.mdcom,MDMCOM1
  571.     mov modem.mddis,MDMINTC
  572.     mov modem.mden,MDMINTO
  573.     mov modem.mdmeoi,EOICOM
  574.     mov modem.mdintv,MDMINTV
  575.     mov brkadr,MDMCOM1
  576.     ret
  577. coms0:    mov ax,offset port2
  578.     mov portval,ax
  579.     mov modem.mddat,MDMDAT2    ; Set COM2 defaults.
  580.     mov modem.mdstat,MDMSTS2
  581.     mov modem.mdcom,MDMCOM2
  582.     mov modem.mddis,MDINTC2
  583.     mov modem.mden,MDINTO2
  584.     mov modem.mdmeoi,EOICOM2
  585.     mov modem.mdintv,MDINTV2
  586.     mov brkadr,MDMCOM2
  587.     ret
  588. comx:    pop bx
  589.     ret
  590. COMS    ENDP
  591.  
  592. ; Set heath emulation on/off.
  593.  
  594. VTS    PROC    NEAR
  595.     mov dx,offset ontab
  596.     mov bx,0
  597.     mov ah,cmkey
  598.     call comnd
  599.      jmp r
  600.     push bx
  601.     mov ah,cmcfm
  602.     call comnd        ; Get a confirm.
  603.      jmp vt0        ;  Didn't get a confirm.
  604.      nop
  605.     pop bx
  606.     mov flags.vtflg,bl    ; Set the VT52 emulation flag.
  607.     ret
  608. vt0:    pop bx
  609.     ret
  610. VTS    ENDP
  611.  
  612. ; initialization for using serial port.  This routine performs
  613. ; any initialization necessary for using the serial port, including
  614. ; setting up interrupt routines, setting buffer pointers, etc.
  615. ; Doing this twice in a row should be harmless (this version checks
  616. ; a flag and returns if initialization has already been done).
  617. ; SERRST below should restore any interrupt vectors that this changes.
  618. ; Returns normally.
  619.  
  620. SERINI    PROC    NEAR
  621.     push es
  622.     cmp portin,0        ; Did we initialize port already? [21c]
  623.     jne serin0        ; Yes, so just leave. [21c]
  624.     cli            ; Disable interrupts
  625.     cld            ; Do increments in string operations
  626.     xor ax,ax        ; Address low memory
  627.     mov es,ax
  628.     mov bx,modem.mdintv    ; Save serial card interrupt vector. [19b]
  629.     mov ax,es:[bx]
  630.     mov savsci,ax
  631.     mov ax,offset serint    ; And point it to my routine
  632.     mov es:[bx],ax
  633.     add bx,2        ; Save CS register too. [19b]
  634.     mov ax,es:[bx]
  635.     mov savscs,ax
  636.     mov es:[bx],cs
  637.     mov portin,1        ; Remember port has been initialize. 
  638.     call clrbuf        ; Clear input buffer. 
  639.     mov ax,modem.mdstat
  640.     mov mst,ax        ; Use this address for status. 
  641.     mov ax,modem.mddat
  642.     mov mdat,ax        ; Use this address for data. 
  643.     mov al,modem.mdmeoi
  644.     mov mdeoi,al        ; Use to signify end-of-interrupt. 
  645.     in al,21H        ; Set up 8259 interrupt controller
  646.     and al,modem.mden    ; Enable INT3 or INT4. 
  647.     out 21H,al
  648.     mov dx,modem.mdcom    ; Set up the serial card. 
  649.     mov al,3
  650.     out dx,al
  651.     mov dl,0F9H
  652.     mov al,1        ; Set up interrupt enable register
  653.     out dx,al
  654.     mov dl,0FCH        ; Enable interrupts from serial card
  655.     mov al,0BH
  656.     out dx,al
  657.     sti            ; Allow interrupts
  658.     mov dl,0F8H
  659.     in al,dx
  660. serin0:    pop es
  661.     ret            ; We're done.
  662. SERINI    ENDP
  663.  
  664. ; Reset the serial port.  This is the opposite of serini.  Calling
  665. ; this twice without intervening calls to serini should be harmless.
  666. ; Returns normally.
  667.  
  668. SERRST    PROC    NEAR
  669.     push es            ; preserve this
  670.     cmp portin,0        ; Reset already? 
  671.     je srst1        ; Yes, just leave. 
  672.     cli            ; Disable interrupts
  673.     mov dx,03FCH        ; Disable modem interrupts
  674.     cmp flags.comflg,1    ; Using port 1 ? 
  675.     je srst0        ; Yes - continue. 
  676.     mov dh,02        ; Set for port 2. 
  677. srst0:    mov al,3
  678.     out dx,al
  679.     in al,21H        ; Interrupt controller
  680.     or al,modem.mddis    ; Inhibit IRQ3 or IRQ4. 
  681.     out 21H,al
  682.     xor bx,bx        ; Address low memory
  683.     mov es,bx
  684.     mov bx,modem.mdintv    ; Restore the serial card int vector 
  685.     mov ax,savsci
  686.     mov es:[bx],ax
  687.     add bx,2        ; Restore CS too. 
  688.     mov ax,savscs
  689.     mov es:[bx],ax
  690.     mov portin,0        ; Reset flag.
  691.     sti
  692. srst1:    pop es
  693.     ret            ; All done.
  694. SERRST    ENDP
  695.  
  696. ; serial port interrupt routine.  This is not accessible outside this
  697. ; module, handles serial port receiver interrupts.
  698.  
  699. SERINT  PROC  NEAR
  700.     push bx
  701.     push dx
  702.     push ax
  703.     push es
  704.     push di
  705.     push ds
  706.     push bp
  707.     push cx
  708.     cld
  709.     mov ax,seg datas
  710.     mov ds,ax        ; address data segment
  711.     mov es,ax
  712.     mov di,srcpnt        ; Registers for storing data.
  713.     mov dx,mst        ; Asynch status port. [19b]
  714.     in al,dx
  715.     test al,mdminp        ; Data available?
  716.     jz retint        ; Nope.
  717.     mov dx,mdat        ; [19b]
  718.     in al,dx
  719.     cmp telflg,0        ; File transfer or terminal mode? [17c]
  720.     jz srint0
  721.     and al,7FH        ; Terminal mode (7 bits only). 
  722. srint0: or al,al
  723.     jz retint        ; Ignore nulls.
  724.     mov ah,al
  725.     and ah,7fH        ; strip parity temporarily
  726.     cmp ah,7FH        ; Ignore rubouts, too.
  727.     jz retint
  728.     mov bp,portval
  729.     cmp ds:[bp].floflg,0    ; Doing flow control?
  730.     je srint2        ; Nope.
  731.     mov bx,ds:[bp].flowc    ; Flow control char (BH = XON, BL = XOFF).
  732.     cmp al,bl        ; Is it an XOFF?
  733.     jne srint1        ; Nope, go on.
  734.     mov xofrcv,true        ; Set the flag.
  735.     jmp retint
  736. srint1:    cmp al,bh        ; Get an XON?
  737.     jne srint2        ; No, go on.
  738.     mov xofrcv,false    ; Clear our flag.
  739.     jmp retint
  740. srint2:    stosb
  741.     cmp di,offset source + bufsiz
  742.     jb srint3        ; not past end...
  743.     mov di,offset source    ; wrap buffer around
  744. srint3:    inc count
  745.     cmp ds:[bp].floflg,0    ; Doing flow control?
  746.     je retint        ; No, just leave.
  747.     cmp xofsnt,true        ; Have we sent an XOFF?
  748.     je retint        ; Yes.
  749.     cmp count,mntrgh    ; Past the high trigger point?
  750.     jbe retint        ; No, we're within our limit.
  751.     mov ah,bl        ; Get the XOFF.
  752.     call outchr        ; Send it.
  753.     nop
  754.     nop
  755.     nop            ; ignore failure.
  756.     mov xofsnt,true        ; Remember we sent it.
  757. retint:    mov srcpnt,di
  758.     sti
  759.     mov al,mdeoi        ; [19b]
  760.     out intcon1,al        ; Send End-of-Interrupt to 8259.
  761.     pop cx
  762.     pop bp
  763.     pop ds
  764.     pop di
  765.     pop es
  766.     pop ax
  767.     pop dx
  768.     pop bx
  769. intret:    iret
  770. SERINT    ENDP
  771.  
  772. ; Produce a short beep.  The PC DOS bell is long enough to cause a loss
  773. ; of data at the port.  Returns normally.
  774.  
  775. BEEP    PROC    NEAR
  776.     mov al,10110110B    ; Gen a short beep (long one losses data.)
  777.     out timer+3,al        ; Code snarfed from Technical Reference.
  778.     mov ax,533H
  779.     out timer+2,al
  780.     mov al,ah
  781.     out timer+2,al
  782.     in al,port_b
  783.     mov ah,al
  784.     or al,03
  785.     out port_b,al
  786.     sub cx,cx
  787.     mov bl,1
  788. beep0:  loop beep0
  789.     dec bl        
  790.     jnz beep0
  791.     mov al,ah
  792.     out port_b,al
  793.     ret
  794. BEEP    ENDP 
  795.  
  796. ; put the number in ax into the buffer pointed to by di.  Di is updated
  797. nout    proc    near
  798.     mov    dx,0        ; high order is always 0.
  799.     mov    bx,10
  800.     div    bx        ; divide to get digit
  801.     push    dx        ; save remainder digit
  802.     or    ax,ax        ; test quotient
  803.     jz    nout1        ; zero, no more of number
  804.     call    nout        ; else call for rest of number
  805. nout1:    pop    ax        ; get digit back
  806.     add    al,'0'        ; make printable
  807.     stosb            ; drop it off
  808.     ret            ; and return
  809. nout    endp
  810.  
  811. ; Jumping to this location is like retskp.  It assumes the instruction
  812. ;   after the call is a jmp addr.
  813.  
  814. RSKP    PROC    NEAR
  815.     pop bp
  816.     add bp,3
  817.     push bp
  818.     ret
  819. RSKP    ENDP
  820.  
  821. ; Jumping here is the same as a ret.
  822.  
  823. R    PROC    NEAR
  824.     ret
  825. R    ENDP
  826.  
  827. code    ends 
  828.     end
  829.