home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / io_util / tandy232.asm < prev    next >
Assembly Source File  |  1994-03-04  |  9KB  |  363 lines

  1. ;----------------------------------------------------------------------------
  2. ;
  3. ;    Replacement for the Tandy 2000 RS232 handler
  4. ;
  5. ;    Copyright 1985 by John McNamee.
  6. ;
  7. ;    This software is made available for non-commercial use. If I find
  8. ;    you selling it, my lawyers will teach you a lesson in the copyright
  9. ;    laws that you will never forget.
  10. ;
  11. ;----------------------------------------------------------------------------
  12. ;
  13. ;    There are some differences between these routines and the BIOS.
  14. ;    I do not check Data Set Ready, or any other modem status, before
  15. ;    sending characters. If the UART is ready, I send the character.
  16. ;    This makes it easier to do machine-to-machine hardwire connections.
  17. ;    I do not fully implement the XON/XOFF processing. Only "HOST" type
  18. ;    processing is done: if the other side sends an XOFF to the 2000, I
  19. ;    stop transmitting until I get an XON. Nothing is done if the 2000
  20. ;    input buffer fills up; no XOFF is sent, and excess characters are
  21. ;    just ignored. This was the easiest way to implement things, and
  22. ;    should be OK for most people. It should be noted that the IBM PC
  23. ;    doesn't do either type, so many programs handle all their own
  24. ;    XON/XOFF processing already.
  25. ;
  26. ;----------------------------------------------------------------------------
  27.  
  28. bufsiz    equ    256            ;Size of input buffer
  29.  
  30. code    segment    public 'code'
  31.     assume    cs:code, ds:code
  32.  
  33.     org    100h
  34. entry:    jmp    setup
  35.  
  36. ;----------------------------------------------------------------------------
  37. ;    Runtime data area
  38. ;----------------------------------------------------------------------------
  39. port12:    db    ?            ;Copy of last byte sent to port 12
  40. hold:    db    ?            ;XON/XOFF status flags
  41. inptr:    dw    ?            ;Buffer input pointer
  42. outptr:    dw    ?            ;Buffer output pointer
  43. inbuf:    db    bufsiz dup (?)
  44.  
  45. ;----------------------------------------------------------------------------
  46. ;    INT 14 handler
  47. ;----------------------------------------------------------------------------
  48. int14    proc    near
  49.     push    bx
  50.     push    cx
  51.     push    dx
  52.     push    ds
  53.     push    cs
  54.     pop    ds            ;DS=CS
  55.  
  56.     cmp    ah,00            ;Reset Comm Port
  57.     jnz    not_0
  58.     and    ah,3            ;We only want bits 0 and 1
  59.     mov    byte ptr hold,dh    ;Set XON/XOFF flags
  60.     pushf
  61.     db    9Ah            ;Opcode for long jump
  62. oldint:    dw    ?,?
  63.     call    flush            ;Flush the buffer
  64.     mov    al,36h            ;Disable transmitter
  65.     call    outctl            ;Output to control port
  66.     call    stat
  67.     jmp    exit14
  68.  
  69. not_0:    cmp    ah,01            ;Transmit Character
  70.     jnz    not_1
  71.     call    send
  72.     jmp    exit14
  73.  
  74. not_1:    cmp    ah,02            ;Receive Character
  75.     jnz    not_2
  76.     call    recv
  77.     jmp    exit14
  78.  
  79. not_2:    cmp    ah,03            ;Get Current Comm Status
  80.     jnz    not_3
  81.     call    stat
  82.     jmp    exit14
  83.  
  84. not_3:    cmp    ah,04            ;Flush Comm Buffer
  85.     jnz    exit14
  86.     call    flush
  87.  
  88. exit14:    pop    ds
  89.     pop    dx
  90.     pop    cx
  91.     pop    bx
  92.     iret
  93. int14    endp
  94.  
  95. ;----------------------------------------------------------------------------
  96. ;    Send a character
  97. ;----------------------------------------------------------------------------
  98. send    proc    near
  99.     push    ax
  100.     mov    al,37h            ;Enable transmitter
  101.     call    outctl
  102.     mov    cx,0000            ;Timeout counter
  103.     mov    dl,2
  104. wait1:    in    al,12h            ;Get UART status
  105.     test    al,01            ;UART ready?
  106.     jz    wait2
  107.     test    byte ptr hold,10h    ;Is "stop transmitting" flag set?
  108.     jz    send1
  109. wait2:    loop    wait1
  110.     dec    dl            ;Bump counter
  111.     jnz    wait1
  112.     pop    ax
  113.     call    stat            ;Get status
  114.     or    ah,80h            ;Set timeout error
  115.     ret
  116. send1:    pop    ax
  117.     out    10h,al            ;Send character
  118.     call    stat            ;Return status
  119.     ret
  120. send    endp
  121.  
  122. ;----------------------------------------------------------------------------
  123. ;    Receive a character
  124. ;----------------------------------------------------------------------------
  125. recv    proc    near
  126.     cli
  127.     mov    bx,outptr
  128.     cmp    bx,inptr        ;Is buffer empty?
  129.     jnz    recv1
  130.     sti                ;Allow interrupt to happen
  131.     nop
  132.     nop
  133.     jmp    recv            ;Go back and try again
  134. recv1:    mov    al,cs:[bx]        ;Get character
  135.     inc    bx
  136.     cmp    bx,offset inbuf+bufsiz    ;At end of buffer?
  137.     jnz    recv2
  138.     mov    bx,offset inbuf        ;Wrap around
  139. recv2:    mov    outptr,bx
  140.     mov    ah,00h            ;No errors returned
  141.     sti
  142.     ret
  143. recv    endp
  144.  
  145. ;----------------------------------------------------------------------------
  146. ;    Flush input buffer
  147. ;----------------------------------------------------------------------------
  148. flush    proc    near
  149.     cli
  150.     and    dh,3
  151.     mov    byte ptr hold,dh
  152.     mov    ax,offset inbuf
  153.     mov    outptr,ax
  154.     mov    inptr,ax
  155.     sti
  156.     ret
  157. flush    endp
  158.  
  159. ;----------------------------------------------------------------------------
  160. ;    Get status
  161. ;----------------------------------------------------------------------------
  162. stat    proc    near
  163.     xor    ah,ah
  164.     push    bx
  165.     cli
  166.     mov    bx,inptr
  167.     cmp    bx,outptr
  168.     sti
  169.     pop    bx
  170.     jz    stat1
  171.     or    ah,01h            ;There is data in the buffer
  172. stat1:    in    al,12h            ;Get UART status
  173.     push    ax
  174.     mov    al,byte ptr port12    ;Get last value sent to UART
  175.     call    outctl            ;Send it again to clear error status
  176.     pop    ax
  177.     test    al,10h            ;Overrun error?
  178.     jz    stat2
  179.     or    ah,02h
  180. stat2:    test    al,08h            ;Parity error?
  181.     jz    stat3
  182.     or    ah,04h
  183. stat3:    test    al,20h            ;Framing error?
  184.     jz    stat4
  185.     or    ah,08h
  186. stat4:    test    al,08h            ;Break detected?
  187.     jz    stat5
  188.     or    ah,10h
  189. stat5:    test    al,01h            ;TxRDY?
  190.     jz    stat6
  191.     or    ah,60h
  192. stat6:    mov    al,20h            ;Fake modem status (CTS and DSR set)
  193.     ret
  194. stat    endp
  195.  
  196. ;----------------------------------------------------------------------------
  197. ;    INT 72 handler
  198. ;----------------------------------------------------------------------------
  199. int72    proc    near
  200.     cli
  201.     push    ax
  202.     push    bx
  203.     push    cx
  204.     push    dx
  205.     push    ds
  206.     push    cs
  207.     pop    ds            ;DS = CS
  208.  
  209. ;    Get UART status. Check if a received character is ready.
  210.     in    al,12h
  211.     test    al,02h
  212.     jz    exit72
  213.  
  214. ;    Get character from UART and stuff in buffer
  215.     in    al,10h
  216.     push    ax
  217.     and    al,7Fh            ;Strip parity
  218.     test    byte ptr hold,02    ;Should we do XON/XOFF processing?
  219.     jz    int72b
  220.     cmp    al,'S'-40h        ;Did we get an XOFF?
  221.     jne    int72a
  222.     or    byte ptr hold,10h    ;Set "stop transmitting" flag
  223.     pop    ax
  224.     jmp    exit72
  225. int72a:    cmp    al,'Q'-40h        ;Did we get an XON?
  226.     jne    int72b
  227.     and    byte ptr hold,0EFh    ;Clear "stop transmitting" flag
  228.     pop    ax
  229.     jmp    exit72
  230. int72b:    pop    ax
  231.     mov    bx,inptr        ;Get buffer input pointer
  232.     mov    [bx],al            ;Store character in buffer
  233.     inc    bx
  234.     cmp    bx,offset inbuf+bufsiz    ;At end of buffer
  235.     jnz    ckfull
  236.     mov    bx,offset inbuf        ;Wrap around
  237. ckfull:    cmp    bx,outptr        ;Buffer full?
  238.     jz    exit72
  239.     mov    inptr,bx
  240.  
  241. ;    Clear interrupt and return
  242. exit72:    mov    al,36h            ;Leave transmitter disabled
  243.     call    outctl
  244.     mov    dx,0060h
  245.     mov    al,20h
  246.     out    dx,al
  247.     mov    al,0Bh
  248.     out    dx,al            ;Clear 8259 interrupt controler
  249.     sti
  250.     nop
  251.     nop
  252.     in    al,dx
  253.     or    al,al
  254.     jnz    not186
  255.     cli
  256.     mov    dx,0FF22h
  257.     mov    ax,8000h
  258.     out    dx,ax            ;Clear 186 interrupt controler
  259. not186:    sti
  260.     pop    ds
  261.     pop    dx
  262.     pop    cx
  263.     pop    bx
  264.     pop    ax
  265.     iret
  266. int72    endp
  267.  
  268. ;----------------------------------------------------------------------------
  269. ;    Output byte to UART control port
  270. ;----------------------------------------------------------------------------
  271. outctl    proc    near
  272.     out    12h,al
  273.     mov    byte ptr port12,al
  274.     ret
  275. outctl    endp
  276.  
  277. ;----------------------------------------------------------------------------
  278. ;    Initialize everything
  279. ;----------------------------------------------------------------------------
  280. setup    proc    near
  281.     push    cs
  282.     pop    ds            ;DS=CS
  283.  
  284. ;    Test version number
  285.     mov    ah,30h
  286.     int    21h            ;GetVersion
  287.     cmp    ax,0B02h        ;Is it 02.11.xx?
  288.     jz    ver_ok
  289.     mov    dx,offset badver
  290.     call    prtmsg            ;Print bad version message
  291.     mov    ax,4C01h
  292.     int    21h            ;Exit
  293. ver_ok:
  294.  
  295. ;    Get old vector
  296.     mov    ax,3514h        ;Get vector for INT 14h
  297.     int    21h
  298.     mov    oldint+2,es        ;Save old interrupt segment
  299.     mov    oldint,bx        ;Save old interrupt offset
  300.     mov    ax,es
  301.     cmp    ax,0060h        ;Already installed
  302.     jz    not_in
  303.     mov    dx,offset inserr
  304.     call    prtmsg            ;Print already installed message
  305.     mov    ax,4C01h
  306.     int    21h            ;Exit
  307. not_in:
  308.  
  309. ;    Setup pointers
  310.     cli                ;We need silence for this next trick
  311.     xor    al,al
  312.     mov    byte ptr hold,al
  313.     mov    ax,offset inbuf
  314.     mov    inptr,ax        ;Set input pointer
  315.     mov    outptr,ax        ;Set output pointer
  316.  
  317. ;    Install new vectors
  318.     mov    ax,2514h        ;Set vector for INT 14h
  319.     mov    dx,offset int14
  320.     int    21h
  321.     mov    ax,2553h        ;Set vector for INT 53h
  322.     int    21h
  323.     mov    ax,2572h        ;Set vector for INT 72h
  324.     mov    dx,offset int72
  325.     int    21h
  326.     sti
  327.  
  328. ;    Initialize RS232 port to 300 baud, 8 bits, No parity, 1 stop bit
  329.     mov    ah,00h
  330.     mov    al,43h
  331.     mov    dx,0000h
  332.     int    14h
  333.  
  334. ;    Let the user know everything is OK and exit
  335.     mov    dx,offset insmsg
  336.     call    prtmsg            ;Print installed message
  337.     mov    ax,offset setup        ;First byte after resident code
  338.     mov    cl,4
  339.     shr    ax,cl            ;Turn into paragraph count
  340.     inc    ax            ;Keep one extra paragraph
  341.     mov    dx,ax            ;DX=final paragraph count
  342.     mov    ax,3100h        ;Keep process
  343.     int    21h
  344. setup    endp
  345.  
  346. ;----------------------------------------------------------------------------
  347. ;    Print message
  348. ;----------------------------------------------------------------------------
  349. prtmsg    proc    near
  350.     mov    ah,09
  351.     int    21h
  352.     ret
  353. prtmsg    endp
  354.  
  355.     db    'Copyright 1985 by John McNamee.'
  356. insmsg:    db    13,10,'RS232 fix for Tandy 2000 BIOS installed.',13,10,'$'
  357. badver:    db    13,10,'This fix is only needed on MSDOS 02.11.02!',13,10,'$'
  358. inserr:    db    13,10,'RS232 fix already installed!',13,10,'$'
  359.  
  360. code    ends
  361.  
  362.     end    entry
  363.