home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / Dloads / PROGRAMM / SERIAL.ZIP / SERASM.ASM < prev    next >
Assembly Source File  |  1992-01-29  |  11KB  |  347 lines

  1. ;
  2. ; serasm.asm - Low Level Communcations Routines
  3. ;              Copyright (c) 1992 by Mark Goodwin
  4. ;
  5.  
  6. ;
  7. ; UART register constants
  8. ;
  9. IIR                    equ        2
  10. MCR                    equ        4
  11. LSR                    equ        5
  12. MSR                    equ        6
  13.  
  14. ;
  15. ; UART bit mask constants
  16. ;
  17. RX_RDY                equ        1
  18. TX_RDY                equ        20H
  19. INT_MASK            equ        7
  20. RX_ID                equ        4
  21. MC_INT                equ        8
  22. DTR                    equ        1
  23. RTS                    equ        2
  24. CTS                    equ        10H
  25. DSR                    equ        20H
  26. DCD                    equ        80H
  27. ICR                    equ        20H
  28. EOI                    equ        20H
  29.  
  30. ;
  31. ; XON/XOFF constants
  32. ;
  33. XON                    equ        11H
  34. XOFF                equ        13H
  35.  
  36. ;
  37. ; system clock location
  38. ;
  39. CLOCK                equ        46cH
  40.  
  41. ;
  42. ; boolean values
  43. ;
  44. TRUE                equ        1
  45. FALSE                equ        0
  46.  
  47. ;
  48. ; data segment
  49. ;
  50. DGROUP                group    _DATA
  51. _DATA                segment    word public 'DATA'
  52.                     assume  ds:DGROUP
  53.  
  54. ;
  55. ; declare all variables as public
  56. ;
  57.                     public  _sibuff,_eibuff,_ilen,_inbuff
  58.                     public  _rx_flow,_rx_rts,_rx_dtr,_rx_xon
  59.                     public  _tx_rts,_tx_dtr,_tx_xon,_tx_xonoff
  60.                     public  _fon,_foff
  61.                     public  _base
  62.  
  63. ;
  64. ; varibles
  65. ;
  66. _sibuff             dw      ?                ;start of input buffer ptr
  67. _eibuff             dw      ?                ;end of input buffer ptr
  68. _ilen               dw      ?                ;input buffer length
  69. _inbuff             dd      ?                ;input buffer ptr
  70. _rx_flow            dw      ?                ;input buffer full flag
  71. _rx_rts             dw      ?                ;receive RTS/CTS flag
  72. _rx_dtr             dw      ?                ;receive DTR/DSR flag
  73. _rx_xon             dw      ?                ;receive XON/XOFF flag
  74. _tx_rts             dw      ?                ;xmit RTS/CTS flag
  75. _tx_dtr             dw      ?                ;xmit DTR/DSR flag
  76. _tx_xon             dw      ?                ;xmit XON/XOFF flag
  77. _tx_xonoff          dw      ?                ;xmit XOFF flag
  78. _fon                dw      ?                ;point to turn receive flow on
  79. _foff               dw      ?                ;point to turn receive flow off
  80. _base               dw      ?                ;UART base ptr
  81.  
  82. _DATA                ends
  83.  
  84. ;
  85. ; code segment
  86. ;
  87. SERASM_TEXT            segment    para public 'CODE'
  88.                     assume     cs:SERASM_TEXT
  89.  
  90. ;
  91. ; declare procedures public
  92. ;
  93.                     public  _get_serial,_put_serial,_handler,_mpeek
  94.  
  95. ;
  96. ; get character from the serial port
  97. ;
  98. _get_serial            proc    far
  99.                     push    di              ;save di
  100.                     push    es                ;save es
  101.                     mov        ax,-1            ;ax=character not available
  102.                     push    ax                ;save it on stack
  103.                     mov        bx,_sibuff        ;bx=next character ptr
  104.                     cmp        bx,_eibuff        ;buffer empty?
  105.                     je        gs4                ;jump if it is
  106.                     pop        ax                ;remove dummy return value
  107.                     les        di,_inbuff        ;es:di=input buffer ptr
  108.                     mov        al,es:[di][bx]     ;al=next character
  109.                     xor        ah,ah            ;ax=next character
  110.                     push    ax                ;save it on stack
  111.                     inc        bx                ;bump the next character ptr
  112.                     cmp        bx,_ilen        ;wrap ptr?
  113.                     jne        gs1                ;jump if not
  114.                     xor        bx,bx            ;point it to start of buffer
  115. gs1:                mov        _sibuff,bx        ;save the new ptr
  116.                     cmp        _rx_flow,TRUE     ;receive flow?
  117.                     jne        gs4                ;jump if not
  118.                     call    chars_in_buff     ;ax=number of chars in buffer
  119.                     cmp        ax,_fon            ;turn back on?
  120.                     jg        gs4                ;jump if not
  121.                     mov        _rx_flow,FALSE    ;flag receive flow off
  122.                     cmp        _rx_rts,TRUE    ;RTS/CTS?
  123.                     jne        gs2                ;jump if not
  124.                     mov        dx,_base        ;dx=base ptr
  125.                     add        dx,MCR            ;dx=modem control register
  126.                     in        al,dx            ;get current value
  127.                     or        al,RTS            ;assert RTS
  128.                     out        dx,al            ;send new value to UART
  129. gs2:                cmp        _rx_dtr,TRUE    ;DTR/DSR?
  130.                     jne        gs3                ;jump if not
  131.                     mov        dx,_base        ;dx=base ptr
  132.                     add        dx,MCR            ;dx=modem control register
  133.                     in        al,dx            ;get current value
  134.                     or        al,DTR            ;assert DTR
  135.                     out        dx,al            ;send new value to UART
  136. gs3:                cmp        _rx_xon,TRUE    ;XON/XOFF?
  137.                     jne        gs4                ;Jump if not
  138.                     cli                        ;disable the interrupts
  139.                     mov        dx,_base        ;dx=xmit register
  140.                     mov        al,XON            ;al=XON value
  141.                     out        dx,al            ;send it to remote
  142.                     sti                        ;enable the interrupts
  143. gs4:                pop        ax                ;get the character
  144.                     pop        es                ;restore es
  145.                     pop        di                ;restore di
  146.                     ret                        ;return
  147. _get_serial            endp
  148.  
  149. ;
  150. ; send a byte out through the serial port
  151. ;
  152. _put_serial            proc    far
  153. char                equ        <[bp + 6]>        ;char parameter
  154.                     push    bp                ;save bp
  155.                     mov        bp,sp            ;bp=stack frame ptr
  156.                     push    di                ;save di
  157.                     push    es                ;save es
  158.                     xor        ax,ax            ;ax=segment 0000h
  159.                     mov        es,ax            ;es=segment 0000h ptr
  160.                     mov        di,CLOCK        ;es:di=system clock ptr
  161.                     mov        bx,es:[di]        ;bx=current value
  162.                     mov        cx,18            ;cx=1 second timeout value
  163.                     mov        dx,_base        ;dx=base register
  164.                     mov        dx,MCR            ;dx=modem control register
  165.                     in        al,dx            ;al=current value
  166.                     or        al,MC_INT or DTR or RTS ;assert GPO2, DTR, RTS
  167.                     out        dx,al            ;send it to UART
  168.                     cmp        _tx_rts,TRUE    ;RTS/CTS?
  169.                     jne        ps2                ;Jump if not
  170.                     mov        dx,_base        ;dx=base register
  171.                     add        dx,MSR            ;dx=modem status register
  172. ps1:                in        al,dx            ;al=current value
  173.                     and        al,CTS            ;CTS asserted?
  174.                     jnz        ps2                ;jump if it is
  175.                     cmp        bx,es:[di]        ;system clock changed?
  176.                     je        ps1                ;loop if not
  177.                     mov        bx,es:[di]        ;bx=new system clock value
  178.                     loop    ps1                ;loop till time out
  179.                     jmp        ps9                ;jump for time out
  180. ps2:                cmp        _tx_dtr,TRUE    ;DTR/DSR?
  181.                     jne        ps4                ;jump if not
  182.                     mov        dx,_base        ;dx=base register
  183.                     add        dx,MSR            ;dx=modem status register
  184. ps3:                in        al,dx            ;al=current value
  185.                     and        al,DSR            ;DSR asserted?
  186.                     jnz        ps4                ;jump if it is
  187.                     cmp        bx,es:[di]        ;system clock changed?
  188.                     je        ps3                ;loop if not
  189.                     mov        bx,es:[di]        ;bx=new system clock value
  190.                     loop    ps3                ;loop till time out
  191.                     jmp        ps9                ;jump for time out
  192. ps4:                cmp        _tx_xon,TRUE    ;XON/XOFF?
  193.                     jne        ps6                ;jump if not
  194. ps5:                cmp        _tx_xonoff,TRUE    ;XOFF?
  195.                     jne        ps6                ;jump if not
  196.                     mov        dx,_base        ;dx=base register
  197.                     add        dx,MSR            ;dx=modem status register
  198.                     in        al,dx            ;al=current value
  199.                     and        al,DCD            ;carrier?
  200.                     jnz        ps5                ;loop if it is
  201. ps6:                mov        dx,_base        ;dx=base register
  202.                     add        dx,LSR            ;dx=line status register
  203. ps7:                in        al,dx            ;al=current value
  204.                     and        al,TX_RDY        ;xmitter ready?
  205.                     jnz        ps8                ;jump if it is
  206.                     cmp        bx,es:[di]        ;system clock changed?
  207.                     je        ps3                ;loop if not
  208.                     mov        bx,es:[di]        ;bx=new system clock value
  209.                     loop    ps7                ;loop till time out
  210.                     jmp        ps9                ;jump for time out
  211. ps8:                cli                        ;disable the interrupts
  212.                     mov        dx,_base        ;dx=xmitter register
  213.                     mov        ax,char            ;al=character to send
  214.                     out        dx,al            ;send it
  215.                     sti                        ;enable the interrupts
  216. ps9:                pop        es                ;restore es
  217.                     pop        di                ;restore di
  218.                     mov        sp,bp            ;restore the stack ptr
  219.                     pop        bp                ;restore bp
  220.                     ret                        ;return
  221. _put_serial            endp
  222.  
  223. ;
  224. ; calculate number of character in input buffer
  225. ;
  226. chars_in_buff        proc    near
  227.                     mov        ax,_eibuff        ;ax=end of buffer ptr
  228.                     sub        ax,_sibuff        ;figure number of chars
  229.                     jae        cib1            ;jump if ptrs haven't crossed
  230.                     mov        ax,_ilen        ;ax=buffer size
  231.                     sub        ax,_sibuff        ;ax=number chars to end of buffer
  232.                     add        ax,_eibuff        ;ax=number chars in buffer
  233. cib1:                ret                        ;return
  234. chars_in_buff        endp
  235.  
  236. ;
  237. ; interrupt handler
  238. ;
  239. _handler            proc    far
  240.                     push    ax                ;save ax
  241.                     push    bx                ;save bx
  242.                     push    cx                ;save cx
  243.                     push    dx                ;save dx
  244.                     push    si                ;save si
  245.                     push    di                ;save di
  246.                     push    bp                ;save bp
  247.                     push    es                ;save es
  248.                     push    ds                ;save ds
  249.                     mov        ax,seg _base    ;ax=segment address
  250.                     mov        ds,ax            ;ds=segment address
  251.                     mov        dx,_base        ;dx=base register
  252.                     add        dx,IIR            ;dx=interrupt id register
  253.                     in        al,dx            ;al=current value
  254.                     and        al,INT_MASK        ;mask it
  255.                     cmp        al,RX_ID        ;receive interrupt?
  256.                     je        h1                ;jump if it is
  257.                     jmp        h8                ;jump if not
  258. h1:                    mov        dx,_base        ;dx=receive register
  259.                     in        al,dx            ;al=new character
  260.                     cmp        _tx_xon,TRUE    ;XON/XOFF?
  261.                     jne        h3                ;jump if not
  262.                     cmp        al,XOFF            ;XOFF?
  263.                     jne        h2                ;jump if not
  264.                     mov        _tx_xonoff,TRUE    ;flag XOFF
  265.                     jmp     h5                ;jump
  266. h2:                 cmp        al,XON            ;XON?
  267.                     jne        h3                ;jump if not
  268.                     mov        _tx_xonoff,FALSE ;flag not XOFF
  269.                     jmp     h5                ;jump
  270. h3:                 mov        _tx_xonoff,FALSE ;flag not XOFF
  271.                     mov        bx,_eibuff        ;bx=next char ptr
  272.                     les        di,_inbuff        ;es:di=input buffer ptr
  273.                     mov        es:[di][bx],al    ;save the char
  274.                     inc        bx                ;bump the buffer ptr
  275.                     cmp        bx,_ilen        ;wrap it?
  276.                     jne        h4                ;jump if not
  277.                     xor        bx,bx            ;point to start of buffer
  278. h4:                    mov        _eibuff,bx        ;save new ptr
  279. h5:                    mov        dx,_base        ;dx=base register
  280.                     add        dx,LSR            ;dx=line status register
  281.                     in        al,dx            ;al=current value
  282.                     and        al,RX_RDY        ;another character available
  283.                     jnz        h1                ;loop if it is
  284.                     cmp        _rx_flow,TRUE    ;receive flow on?
  285.                     je        h8                ;jump if it is
  286.                     call    chars_in_buff    ;ax=no chars in buffer
  287.                     cmp        ax,_foff        ;turn receive off?
  288.                     jb        h8                ;jump if not
  289.                     mov        _rx_flow,TRUE    ;flag receive flow on
  290.                     cmp        _rx_rts,TRUE    ;RTS/CTS?
  291.                     jne        h6                ;jump if not
  292.                     mov        dx,_base        ;dx=base register
  293.                     add        dx,MCR            ;dx=modem control register
  294.                     in        al,dx            ;al=current value
  295.                     and        al,not RTS        ;unassert RTS
  296.                     out        dx,al            ;send it to UART
  297. h6:                    cmp        _rx_dtr,TRUE    ;DTR/DSR?
  298.                     jne        h7                ;jump if not
  299.                     mov        dx,_base        ;dx=base register
  300.                     add        dx,MCR            ;dx=modem control register
  301.                     in        al,dx            ;al=current value
  302.                     and        al,not DTR        ;unassert DTR
  303.                     out        dx,al            ;send it to UART
  304. h7:                    cmp        _rx_xon,TRUE    ;XON/XOFF?
  305.                     jne        h8                ;jump if not
  306.                     mov        dx,_base        ;dx=xmit register
  307.                     mov        al,XOFF            ;al=XOFF
  308.                     out        dx,al            ;send it
  309. h8:                    mov        dx,ICR            ;dx=interrupt control register
  310.                     mov        al,EOI            ;al=end of interrupt command
  311.                     out        dx,al            ;send it
  312.                     pop        ds                ;restore ds
  313.                     pop        es                ;restore es
  314.                     pop        bp                ;restore bp
  315.                     pop        di                ;restore di
  316.                     pop        si                ;restore si
  317.                     pop        dx                ;restore dx
  318.                     pop        cx                ;restore cx
  319.                     pop        bx                ;restore bx
  320.                     pop        ax                ;restore ax
  321.                     iret                    ;return
  322. _handler            endp
  323.  
  324. ;
  325. ; get word of memory routine
  326. ;
  327. _mpeek              proc    far
  328. srcseg              equ     <[bp + 6]>      ;segment parameter
  329. srcoff              equ     <[bp + 8]>      ;offset parameter
  330.                     push    bp              ;save bp
  331.                     mov     bp,sp           ;bp=stack frame ptr
  332.                     push    di              ;save di
  333.                     push    es              ;save es
  334.                     mov     es,srcseg       ;es=segment address
  335.                     mov     di,srcoff       ;di=offset address
  336.                     mov     ax,es:[di]      ;ax=memory word
  337.                     pop     es              ;restore es
  338.                     pop     di              ;restore di
  339.                     pop     bp              ;restore bp
  340.                     ret                     ;return;
  341. _mpeek              endp
  342.  
  343.  
  344. SERASM_TEXT            ends
  345.  
  346.                     end
  347.