home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / ASYNLIB2.ZIP / ASYNC.ASM next >
Assembly Source File  |  1980-03-19  |  12KB  |  551 lines

  1. ;  Async Module.
  2.  
  3.     IDEAL
  4.     MODEL    compact
  5.  
  6. EOI            equ    020h                ; 8259 end-of-interupt
  7. Ctrl8259_0    equ    020h                ; 8259 port
  8. Ctrl8259_1    equ    021h                ; 8259 port (Masks)
  9. BufSize        equ    8196                ; Buffer Size
  10.  
  11.  
  12.  
  13.  
  14.     DATASEG
  15.  
  16. ; Various things to be set upon AsyncInit()
  17. VectorNum        db    ?                ; Vector Number
  18. EnableIRQ        db    ?                ; Mask to enable 8259 IRQ
  19. DisableIRQ    db    ?                ; Mask to disable 8259 IRQ
  20. VectorSeg        dw    ?                ; Old Vector Segment
  21. VectorOfs        dw    ?                ; Old Vector Offset
  22.  
  23. ; Register Addresses for the 8250 UART
  24. Port            dw    ?                ; Port Base Address
  25. LABEL RegStart word
  26. THR            dw    ?                ; Transmitter Holding Register
  27. RDR            dw    ?                ; Reciever Data Register
  28. BRDL            dw    ?                ; Baud Rate Divisor, Low byte
  29. BRDH            dw    ?                ; Baud Rate Divisor, High Byte
  30. IER            dw    ?                ; Interupt Enable Register
  31. IIR            dw    ?                ; Interupt Identification Register
  32. LCR            dw    ?                ; Line Control Register
  33. MCR            dw    ?                ; Modem Control Register
  34. LSR            dw    ?                ; Line Status Register
  35. MSR            dw    ?                ; Modem Status Register
  36.  
  37. ; Buffer Data
  38. RecBuffer        db    BufSize DUP (?)    ; Recieve Buffer
  39. RecHead        dw    ?                ; Buffer Head Pointer
  40. RecTail        dw    ?                ; Buffer Tail Pointer
  41. TransBuffer    db    BufSize DUP (?)    ; Transmit Buffer
  42. TransHead        dw    ?                ; Buffer Head Pointer
  43. TransTail        dw    ?                ; Buffer Tail Pointer
  44.  
  45. ; Register Offsets for the UART
  46. RegOffsets    dw    0, 0, 0, 1, 1, 2, 3, 4, 5, 6
  47.  
  48.  
  49.     CODESEG
  50.  
  51.     PUBLIC    _AsyncInit,    _AsyncClear,     _AsyncStop
  52.     PUBLIC    _AsyncIn,        _AsyncOut,     _AsyncSet
  53.     PUBLIC    _AsyncHand,    _AsyncStat,    _AsyncInStat
  54.     PUBLIC    _AsyncOutStat
  55.  
  56.  
  57. ;-----------------------------------------------------------------------------
  58. ; AsyncClear                        Empty the recieve buffer
  59. ;-----------------------------------------------------------------------------
  60. ; void    AsyncClear( void);
  61. ;
  62. ;
  63. ;-----------------------------------------------------------------------------
  64. PROC    _AsyncClear
  65.     cli
  66.     push    ax
  67.     mov    ax, offset RecBuffer
  68.     mov    [RecHead], ax
  69.     mov    [RecTail], ax
  70.     mov    ax, offset TransBuffer
  71.     mov    [TransHead], ax
  72.     mov    [TransTail], ax
  73.     pop    ax
  74.     sti
  75.     ret
  76. ENDP    _AsyncClear
  77.  
  78.  
  79.  
  80. ;-----------------------------------------------------------------------------
  81. ; AsyncInit                    Initalize Serial Port and install ISR
  82. ;-----------------------------------------------------------------------------
  83. ;    void    AsyncInit( int port)
  84. ;
  85. ;    Where Port is
  86. ;        0  =  COM1
  87. ;        1  =  COM2
  88. ;        2  =  COM3
  89. ;        3  =  COM4
  90. ;
  91. ;-----------------------------------------------------------------------------
  92. PROC    _AsyncInit
  93.     ARG    CommPort:word
  94.  
  95.     push    bp
  96.     mov    bp, sp
  97.  
  98. ;---- Set various things according to com port number
  99.     mov    ax, [CommPort]
  100.  
  101. ;----- COM1
  102.     cmp    ax, 0
  103.     jne    @@1
  104.     mov    [Port], 03F8h
  105.     mov    [VectorNum], 0Ch
  106.     mov    [EnableIRQ], 0EFh
  107.     mov    [DisableIRQ], 10h
  108.     jmp    @@Done
  109. @@1:
  110. ;----- COM2
  111.     cmp    ax, 1
  112.     jne    @@2
  113.     mov    [Port], 02F8h
  114.     mov    [VectorNum], 0Bh
  115.     mov    [EnableIRQ], 0F7h
  116.     mov    [DisableIRQ], 08h
  117.     jmp    @@Done
  118. @@2:
  119. ;----- COM3
  120.     cmp    ax, 2                ; 2
  121.     jne    @@3
  122.     mov    [Port], 03E8h            ; 03E8
  123.     mov    [VectorNum], 0Ch        ; 0C
  124.     mov    [EnableIRQ], 0EFh        ; EF
  125.     mov    [DisableIRQ], 10h        ; 10
  126.     jmp    @@Done
  127. @@3:
  128. ;----- COM4
  129.     mov    [Port], 02E8h            ; 02E8
  130.     mov    [VectorNum], 0Bh        ; 0B
  131.     mov    [EnableIRQ], 0F7h        ; F7
  132.     mov    [DisableIRQ], 08h        ; 08
  133. @@Done:
  134.  
  135. ;---- Compute Register locations
  136.     mov    cx, 10
  137.     mov    bx, offset RegOffsets
  138.     push    di
  139.     mov    di, offset RegStart
  140. @@4:
  141.     mov    ax, [bx]
  142.     add    ax, [Port]
  143.     mov    [di], ax
  144.     add    bx, 2
  145.     add    di, 2
  146.     loop    @@4
  147.  
  148.     pop    di
  149.  
  150.  
  151. ;----- Initalize Buffer
  152.     call    _AsyncClear
  153.  
  154. ;--- Save and reassign interrupt vector
  155.     push    ds                        ; Save Old Vector
  156.     mov    al,[VectorNum]
  157.     mov    ah,35h
  158.     int    21h
  159.     mov    [VectorSeg], es
  160.     mov    [VectorOfs], bx
  161.  
  162.     mov    al, [VectorNum]
  163.     push    cs                        ; Set New Vector
  164.     pop    ds
  165.     mov    dx, offset AsyncISR
  166.     mov    ah, 25h
  167.     int    21h
  168.     pop    ds
  169.  
  170. ;----- Enable 8259 interrupt (IRQ) line for this async adapter
  171.     in    al, Ctrl8259_1
  172.     and    al, [EnableIRQ]
  173.     out    Ctrl8259_1, al
  174.  
  175. ;----- Enable 8250 Interrupt-on-data-ready
  176.     mov    dx, [LCR]                ; Read Line control register and clear
  177.     in    al, dx                ; bit 7, the Divisor Latch Address
  178.     and    al, 07Fh
  179.     out    dx, al
  180.     mov    dx, [IER]
  181.  
  182.         mov al, 0           ;we're gonna test the UART first
  183.         out dx, al
  184.         in al, dx           ;if this isn't 0, there's no UART
  185.         cmp al, 0
  186.         jnz @@222
  187.  
  188.     mov    al, 3
  189.     out    dx, al
  190.  
  191. ;----- Clear 8250 Status and data registers
  192. @@10:
  193.     mov    dx, [RDR]        ; Clear RDR by reading port
  194.     in    al, dx
  195.     mov    dx, [LSR]        ; Clear LSR
  196.     in    al, dx
  197.     mov    dx, [MSR]        ; Clear MSR
  198.     in    al, dx
  199.     mov    dx, [IIR]        ; Clear IIR
  200.     in    al, dx
  201.     test    al, 1
  202.     jz    @@10
  203.  
  204. ;----- Set Bit 3 of MCR -- Enable interupts
  205.     mov    dx, [MCR]
  206.     in    al, dx
  207.     or    al, 08h
  208.     out    dx, al
  209.  
  210. ;----- Clear Buffer Just in case
  211.     call    _AsyncClear
  212.  
  213. ;----- Return
  214.     xor    ax, ax
  215. @@222:
  216.     pop    bp
  217.     ret
  218. ENDP    _AsyncInit
  219.  
  220.  
  221.  
  222. ;-----------------------------------------------------------------------------
  223. ;  AsyncStop                        Uninstall ISR
  224. ;-----------------------------------------------------------------------------
  225. ;    void  AsyncStop( void)
  226. ;-----------------------------------------------------------------------------
  227. PROC    _AsyncStop
  228.     push    bp
  229.     mov    bp, sp
  230.  
  231. ;----- Mask (disable) 8259 IRQ Interrupt
  232.     in    al, Ctrl8259_1
  233.     or    al, [DisableIRQ]
  234.     out    Ctrl8259_1, al
  235.  
  236. ;----- Disable 8250 interrupt
  237.     mov    dx, [LCR]
  238.     in    al, dx
  239.     and    al, 07Fh
  240.     out    dx, al
  241.     mov    dx, [IER]
  242.     xor    al, al
  243.     out    dx, al
  244.  
  245. ;----- Set bit 3 in MCR to 0
  246.     mov    dx, [MCR]
  247.     in    al, dx
  248.     and    al, 0F7h
  249.     out    dx, al
  250.  
  251. ;----- Interrupts are disables.  Restore saved interrupt vector.
  252.     push    ds
  253.     mov    al, [VectorNum]
  254.     mov    ah, 25h
  255.     mov    dx, [VectorOfs]
  256.     mov    ds, [VectorSeg]
  257.     int    21h
  258.     pop    ds
  259.  
  260. ;----- Return
  261.     pop    bp
  262.     ret
  263. ENDP    _AsyncStop
  264.  
  265.  
  266.  
  267. ;-----------------------------------------------------------------------------
  268. ; AsyncISR                    Async Interrupt Service Routine
  269. ;-----------------------------------------------------------------------------
  270. ;    To be called only as an interrupt.
  271. ;-----------------------------------------------------------------------------
  272. PROC    AsyncISR
  273.     push    ax                    ; Save Registers
  274.     push    bx
  275.     push    ds
  276.     push    dx
  277.  
  278.     mov    ax, @data                ; Address local data with ds
  279.     mov    ds, ax
  280.  
  281.     mov    dx, [IIR]                ; Check if data actually recieved
  282.     in    al, dx
  283.     and    al, 06h
  284.     cmp    al, 04h
  285.     je    @@recieve
  286.     cmp    al, 02h
  287.     jne    @@end
  288.  
  289. ;----- Transmit A byte
  290. @@transmit:
  291.     mov    bx, [TransTail]
  292.     cmp    bx, [TransHead]
  293.     jne    @@1
  294.  
  295.     mov    dx, [IER]                ; Buffer empty
  296.     mov    al, 1
  297.     out    dx, al                ; Disable THR empty interrupt
  298.     jmp    @@end
  299.  
  300. @@1:
  301.     mov    al, [byte ptr bx]        ; Get Byte
  302.     inc    [TransTail]            ; Update buffer pointer
  303.     cmp    [word ptr TransTail], offset TransBuffer + BufSize
  304.     jb    @@2
  305.     mov    [TransTail], offset TransBuffer
  306. @@2:
  307.     mov    dx, [THR]
  308.     out    dx, al
  309.     jmp    @@end
  310.  
  311. ;----- Recieve a byte
  312. @@recieve:
  313.     mov    dx, [RDR]                ; Get Byte
  314.     in    al, dx
  315.     mov    bx, [RecHead]            ; Store Byte in buffer
  316.     mov    [byte ptr bx], al
  317.     inc    bx                    ; Update RecHead
  318.     cmp    bx, offset RecBuffer + BufSize
  319.     jb    @@10
  320.     mov    bx, offset RecBuffer
  321. @@10:
  322.     cmp    bx, [RecTail]
  323.     jne    @@20
  324.     mov    bx, [RecHead]            ; Cancel Pointer advance on overflow
  325. @@20:
  326.     mov    [RecHead], bx            ; Store new pointer
  327.  
  328. @@end:
  329.     mov    al, EOI                ; Signal end ot interrupt
  330.     out    Ctrl8259_0, al
  331.  
  332.         ; Disable and re-enable interrupts so that there
  333.         ; is an interrupt edge.
  334.  
  335.         mov     dx,[IER]                ; Point to Interrupt Enable Register.
  336.         in      al,dx                   ; Read the current value.
  337.         push    ax                      ; Save it.
  338.         mov     al,0                    ; Disable the interrupts.
  339.         out     dx,al
  340.         pop     ax                      ; Restore original mask.
  341.         out     dx,al                   ; Re-enable interrupts.
  342.  
  343.         pop     dx                      ; Restore saved registers.
  344.         pop     ds
  345.         pop     bx
  346.         pop     ax
  347.  
  348.     iret
  349.  
  350. ENDP    AsyncISR
  351.  
  352.  
  353.  
  354. ;-----------------------------------------------------------------------------
  355. ;    AsyncIn                    Gets a byte from the input buffer
  356. ;-----------------------------------------------------------------------------
  357. ;    int    AsyncIn( void)
  358. ;-----------------------------------------------------------------------------
  359. PROC    _AsyncIn
  360.     push    bp
  361.     mov    bp, sp
  362.  
  363.     xor    ax, ax                ; Pre-Set result to 0
  364.     mov    bx, [RecTail]
  365.     cmp    bx, [RecHead]
  366.     je    @@return
  367.     mov    al, [byte ptr bx]
  368.     inc    [RecTail]
  369.     cmp    [word ptr RecTail], offset RecBuffer + BufSize
  370.     jb    @@return
  371.     mov    [RecTail], offset RecBuffer
  372.  
  373. @@return:
  374.     pop    bp
  375.     ret
  376. ENDP    _AsyncIn
  377.  
  378.  
  379.  
  380. ;-----------------------------------------------------------------------------
  381. ;    AsyncOut                Output a byte
  382. ;-----------------------------------------------------------------------------
  383. ;    void    AsyncOut( int c)
  384. ;-----------------------------------------------------------------------------
  385. PROC    _AsyncOut
  386.     ARG    CharOut:word
  387.  
  388.     push    bp
  389.     mov    bp, sp
  390.  
  391.     mov    ax, [CharOut]
  392.  
  393.     mov    bx, [TransHead]
  394.     mov    cx, bx
  395.     inc    cx                        ; Compute NEW buffer position
  396.     cmp    cx, offset TransBuffer + BufSize
  397.     jb    @@1
  398.     mov    cx, offset TransBuffer
  399. @@1:
  400.     cmp    cx, [TransTail]            ; Wait for space in buffer
  401.     je    @@1
  402.  
  403.     mov    [byte ptr bx], al            ; Add byte to buffer
  404.     mov    [TransHead], cx            ; Update pointer
  405.  
  406.     mov    dx, [IER]                    ; Enable THR empty interrupt
  407.     mov    al, 3
  408.     out    dx, al
  409.  
  410.     pop    bp
  411.     ret
  412. ENDP    _AsyncOut
  413.  
  414.  
  415.  
  416. ;-----------------------------------------------------------------------------
  417. ;    AsyncSet                    Set communication paramaters
  418. ;-----------------------------------------------------------------------------
  419. ;    void    AsyncSet( int Baud, int Control)
  420. ;
  421. ;    Baud = 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 28800, 38400, 57600
  422. ;    Control = The valure to place in the LCR
  423. ;-----------------------------------------------------------------------------
  424. PROC    _AsyncSet
  425.     ARG    Baud:word, Control:word
  426.  
  427.     push    bp
  428.     mov    bp, sp
  429.  
  430.     mov    bx, [Baud]
  431.     cmp    bx, 0
  432.     je    @@abort
  433.  
  434.     mov    ax, 0C200h        ; Baud rate divisor = 115200 / Baud
  435.     mov    dx, 0001h            ; 115200 = 0001C200h
  436.     div    bx
  437.     mov    cx, ax
  438.  
  439.     cli
  440.     mov    dx, [LCR]            ; Set Port Toggle to BRDL/BRDH registers
  441.     mov    al, 0ffh
  442.     out    dx, al
  443.  
  444.     mov    dx, [BRDL]        ; Set Baud Rate
  445.     mov    al, cl
  446.     out    dx, al
  447.     mov    dx, [BRDH]
  448.     mov    al, ch
  449.     out    dx, al
  450.  
  451.     mov    dx, [LCR]            ; Set LCR and Port Toggle
  452.     mov    ax, [Control]
  453.     and    al, 07Fh
  454.     out    dx, al
  455.  
  456.     sti
  457. @@abort:
  458.     pop    bp
  459.     ret
  460. ENDP    _AsyncSet
  461.  
  462.  
  463.  
  464. ;-----------------------------------------------------------------------------
  465. ;    AsyncInStat                Returns the # of characters in buffer
  466. ;-----------------------------------------------------------------------------
  467. ;    int    AsyncInStat( void)
  468. ;-----------------------------------------------------------------------------
  469. PROC    _AsyncInStat
  470.     push    bp
  471.     mov    bp, sp
  472.  
  473.     mov    ax,[RecHead]
  474.     sub    ax, [RecTail]
  475.     jge    @@10
  476.     add    ax, BufSize
  477. @@10:
  478.  
  479.     pop    bp
  480.     ret
  481. ENDP    _AsyncInStat
  482.  
  483.  
  484.  
  485. ;-----------------------------------------------------------------------------
  486. ;    AsyncOutStat                Returns the # of characters in buffer
  487. ;-----------------------------------------------------------------------------
  488. ;    int    AsyncOutStat( void)
  489. ;-----------------------------------------------------------------------------
  490. PROC    _AsyncOutStat
  491.     push    bp
  492.     mov    bp, sp
  493.  
  494.     mov    ax,[TransHead]
  495.     sub    ax, [TransTail]
  496.     jge    @@10
  497.     add    ax, BufSize
  498. @@10:
  499.  
  500.     pop    bp
  501.     ret
  502. ENDP    _AsyncOutStat
  503.  
  504.  
  505.  
  506. ;-----------------------------------------------------------------------------
  507. ;    AsyncHand                    Sets various handshaking lines
  508. ;-----------------------------------------------------------------------------
  509. ;    void    AsyncHand( int Hand)
  510. ;-----------------------------------------------------------------------------
  511. PROC    _AsyncHand
  512.     ARG    Hand:word
  513.     push    bp
  514.     mov    bp, sp
  515.  
  516.     mov    dx, [MCR]
  517.     mov    ax, [Hand]
  518.     or    al, 08h                ; Keep interrupt enable ON
  519.     out    dx, al
  520.  
  521.     pop    bp
  522.     ret
  523. ENDP    _AsyncHand
  524.  
  525.  
  526.  
  527. ;-----------------------------------------------------------------------------
  528. ;    AsyncStat                    Returns Async/Modem status
  529. ;-----------------------------------------------------------------------------
  530. ;    unsigned    AsyncStat( void)
  531. ;
  532. ;    MSR is returned in the high byte, LSR in the low byte
  533. ;-----------------------------------------------------------------------------
  534. PROC    _AsyncStat
  535.     push    bp
  536.     mov    bp, sp
  537.  
  538.     mov    dx, [MSR]
  539.     in    al, dx
  540.     mov    cl, al
  541.     mov    dx, [LSR]
  542.     in    al, dx            ; LSR in low byte
  543.     mov    ah, cl            ; MSR in high byte
  544.  
  545.     pop    bp
  546.     ret
  547. ENDP    _AsyncStat
  548.  
  549.  
  550.     END
  551.