home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1999 January / Simtel-MSDOS-Jan1999-CD2.iso / io_utils / serial.aqm / SERIAL.ASM
Assembly Source File  |  1998-12-10  |  5KB  |  230 lines

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