home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / io_util / serint.aqm / SERINT.ASM
Assembly Source File  |  1994-03-04  |  4KB  |  216 lines

  1.     title    SERINT
  2. ;Interupt driven RS232 serial port routines.
  3. ; these routines replace the BIOS rs232 calls with a version that has
  4. ; interupt driven character receive, and can thus operate at considerably
  5. ;  higher speeds than the standard bios calls (int 14h).
  6. ;
  7. ;  Copyright 1983 by William E. Westfield.  All rights reserved.
  8. ;   This software may be freely distributed, but it may not under
  9. ;   any circumstances be sold by anyone other than the author.
  10. ;
  11.  
  12. BUFSiz= 1024
  13.  
  14. XON=    17
  15. XOFF=    19
  16.  
  17. STOPED=    1
  18.  
  19.  
  20. Everything Segment public
  21. assume cs:everything,es:everything,ss:everything
  22. assume    ds: everything
  23.  
  24. org    14h*4
  25. RS232vector    dd 0
  26.  
  27. org    30h
  28. SerialCardVector    dd 0
  29.  
  30. tflags    db    0
  31. bufseg    dw    0
  32. bufHead dw    0
  33. BufTail dw    0
  34. COUNT    dw    0
  35. sav1    dw    0
  36. sav2    dw    0
  37.  
  38. othvec    dd    0
  39. biosint dd    0
  40.  
  41. org    100h
  42.  
  43. start:
  44.     mov    bp,ds
  45.     xor    ax,ax
  46.     mov    ds,ax
  47.     les    ax,SerialCardVector
  48.     mov    cs:OthVec,ax
  49.     mov    cs:OthVec+2,es
  50.     les    ax,rs232vector
  51.     mov    cs:biosint,ax
  52.     mov    cs:biosint+2,es
  53.     mov    word ptr SerialCardVector,OFFSET serint
  54.     mov    word ptr SerialCardVector+2,cs
  55.     mov    word ptr rs232vector,OFFSET rsint
  56.     mov    word ptr rs232vector+2,cs
  57.  
  58.     mov    bx,cs
  59.     mov    ds,bx
  60.     xor    ax,ax
  61.     mov    BUFTail,ax    ; load place for interupt routine to put chars
  62.     mov    BUFHead,ax    ; load place for main routine to get chars
  63.  
  64.     mov    ax,offset BUFFER    ;computer segment containing the buffer
  65.     mov    cl,4        ;by taking address, multiplying by 16 to get
  66.     shr    ax,cl        ;segment value.
  67.     add    ax,bx        ; and then add current segment
  68.     inc    ax        ; and round up.
  69.     mov    BUFSeg,ax
  70.  
  71. init3:    cli
  72. init6:    in    al,021H        ; Set up 8259 interupt controller
  73.     and    al,0EFH        ;  enabling INT4
  74.     out    021H,al
  75.     mov    dx,03F9H    ; Interupt Enable register
  76.     mov    al,1        ; enable 'data available' serial interupt
  77.     out    dx,al
  78.     mov    dl,0FCH
  79.     mov    al,0BH        ; enable interupts from serial card
  80.     out    dx,al
  81.     sti            ; enable CPU to receive interupts
  82.     mov    dl,0F8H    ;
  83.     in    al,dx
  84.     mov    dx,offset Buffer+BUFSiz+65    ;note some slack...
  85.     int    27h        ;terminate but stay resident
  86.  
  87.  
  88. subttl     ********** serial port interupt routine **********
  89.  
  90. rsint:    sti
  91.     cmp    dx,0
  92.     jne    notus
  93.     cmp    ah,1
  94.     je    sndchr
  95.     jge    wedoit
  96. notus:    jmp    cs:dword ptr BIOSint
  97.  
  98. wedoit:    cmp    ah,2            ; receive a character ?
  99.      je    GETCHR
  100. status:    pushf                ;simulate interupt
  101.     call    cs:dword ptr BIOSint
  102.     cmp    cs:count,0
  103.     je    nochars
  104.     or    ah,1            ;indicate data ready
  105. nochars: iret
  106.  
  107. SNDCHR:    push    dx
  108.     mov    dx,3FDh
  109.     mov    ah,al
  110. sndlp:    in    al,dx
  111.     test    al,20h
  112.     jz    sndlp
  113.     mov    dl,0F8h
  114.     xchg    al,ah
  115.     out    dx,al
  116.     pop    dx
  117.     iret
  118.     
  119.  
  120. GETCHR:
  121. TSTLP:    cmp    cs:COUNT,0
  122.     jz    TSTLP
  123.     mov    cs:sav1,si
  124.     mov    cs:sav2,ds
  125.     mov    si,cs:BUFHead
  126.     mov    ds,cs:BUFSeg
  127.     cli
  128.     lodsb
  129.     cmp    si,BUFSiz
  130.     jb    GETCH2
  131.     xor    si,si
  132. GETCH2:    dec    cs:COUNT
  133.     test    cs:tflags,STOPED
  134.     je    GETCH3
  135.     cmp    cs:COUNT,100
  136.     ja    GETCH3
  137.      mov    dx,3F8h
  138.      push    ax
  139.      mov    al,xon
  140.      out    dx,al
  141.      and    cs:tflags,255-STOPED
  142.     pop    AX
  143. GETCH3:
  144.     mov    cs:BUFHead,si
  145.     sti
  146.     mov    si,cs:SAV1
  147.     mov    ds,cs:sav2
  148.     mov    ah,0
  149.     iret
  150.  
  151.  
  152. serint:    push    dx
  153.     push    ax
  154.     push    es
  155.     push    ds
  156.     push    di
  157.     cld
  158.     mov    es,cs:BUFSeg
  159.     mov    di,cs:BUFTail    ;get registers we need
  160. intlp:    mov    dx,03fdH    ; asynch status port
  161.     in    al,dx
  162.     test    al,1        ; see if data available
  163.     jz    retint
  164.     jz    othint        ;  no.
  165.     mov    dl,0f8H    ; yes, get it
  166.     in    al,dx
  167.     and    al,07fH    ; take 7 bits
  168.     jz    retint        ; ignore nulls
  169.     cmp    al,07fH    ; rubout ?
  170.     jz    retint        ; yes, ignore it.
  171. serin2:    stosb
  172.     mov    ax,cs
  173.     mov    ds,ax        ; deal with global variables now...
  174.     inc    COUNT        ; increment count of characters in buffer
  175.     cmp    di,BUFSiz    ; does it loop around past end of the buffer ?
  176.     jb    serin3
  177.      xor    di,di        ; yes, reset to beginning.
  178. serin3:    mov    BUFTail,di
  179.     mov    ax,BUFSiz
  180.     sub    ax,COUNT    ; how much space is left ?
  181.     cmp    ax,BUFSiz/10    ; less than a tenth left ?
  182.     jae    serin5
  183.     test    tflags,STOPED
  184.     jne    serin4
  185.     mov    dx,03F8H
  186.     mov    al,xoff    ; send character to stop output    
  187.     out    dx,al
  188.     or    tflags,STOPED
  189. serin4:
  190. serin5:
  191. retint:    mov    al,064H
  192.     out    020H,al        ; send  End-Of-Interupt to 8259
  193.     pop    di
  194.     pop    ds
  195.     pop    es
  196.     pop    ax
  197.     pop    dx
  198. intret:    iret
  199.  
  200. othint:    ;something we werent waiting for caused the interupt,
  201.     ; so pass it on to previous interupt vector
  202.     cmp    cs:OTHVEC+2,0
  203.     jz    retint
  204.     pop    di
  205.     pop    ds
  206.     pop    es
  207.     pop    ax
  208.     pop    dx
  209.     jmp    cs:dword ptr OTHVEC
  210.  
  211. BUFFER    db BufSiz dup(?)
  212.  
  213. everything ends
  214.  
  215.     end start
  216.