Annotation of sbbs/steve/rciolx.asm, revision 1.1.1.1

1.1       root        1:        .xlist
                      2:        include mdef
                      3:        .ilist
                      4: ;************************************************************************
                      5: ;*                                                                     *
                      6: ;*         rciol: direct 8250 communications interface for C           *
                      7: ;*                                                                     *
                      8: ;*    prototypes: int   rioini(int,int);     initialize com,irq                *
                      9: ;*               int   setbaud(int);        set baud rate              *
                     10: ;*     *n/a      int   rioctl(int);         remote i/o control         *
                     11: ;*               void  dtr(char);           set/reset dtr              *
                     12: ;*               int   outcom(int);         send character             *
                     13: ;*               int   incom(void);         receive character          *
                     14: ;*     *n/a      int   rioifc(int);         local i/o redirection      *
                     15: ;*                                                                     *
                     16: ;************************************************************************
                     17: 
                     18: ; this source file is lacking _rioctl and _rioifc
                     19: 
                     20: biosda segment at 40h          ;bios data area
                     21: biosda ends
                     22: 
                     23:        setmod  %mm
                     24: 
                     25: ; 8259 interrupt controller register equates
                     26: 
                     27: icr1   equ     20h             ;interrupt command register (master)
                     28: imr1   equ     21h             ;interrupt mask register (master)
                     29: ivb1   equ     8               ;vector base 0-7: cannot be read, assumed
                     30: icr2   equ     0a0h            ;interrupt command register (slave)
                     31: imr2   equ     0a1h            ;interrupt mask register (slave)
                     32: ivb2   equ     70h             ;vector base 8-f: cannot be read, assumed
                     33: 
                     34: ; 8250 uart register equates
                     35: 
                     36: iir    equ     2               ;interrupt identification register
                     37: ier    equ     1               ;interrupt enable register
                     38: ierd   equ     0bh             ;enable: rxd, thre, msr
                     39: 
                     40: msr    equ     6               ;modem status register
                     41: mcr    equ     4               ;modem control register
                     42: mcrd   equ     0bh             ;irq enable, rts on, dtr on
                     43: 
                     44: lsr    equ     5               ;line status register
                     45: lcr    equ     3               ;line control register
                     46: lcrd   equ     3               ;N,8,1 mode
                     47: 
                     48: ; buffer pointer structure
                     49: 
                     50: dstruc bufp,0
                     51:        dss     2,bcnt          ;character count
                     52:        dss     2,bput          ;next character to buffer
                     53:        dss     2,bget          ;next character from buffer
                     54:        dss     1,ovfl          ;overflow flag
                     55:        dss     1
                     56:        dss     2,bofst         ;buffer offset
                     57:        dss     2,bsize         ;buffer size
                     58: dstruc bufp
                     59:        .xlist
                     60:        .eopg
                     61:        .data
                     62:        public  _plst
                     63: 
                     64:        align 2
                     65: 
                     66: brdd   dd      115200          ;baud rate dividend
                     67: 
                     68: iv16h  dd      0               ;saved interrupt vector for int 16h
                     69: iv29h  dd      0               ;saved interrupt vector for int 29h
                     70: ivsio  dd      0               ;saved serial i/o vector
                     71: 
                     72: buart  dw      0               ;uart base address
                     73: lsrad  dw      0               ;line status register port address
                     74: irqn   db      0               ;interrupt request line
                     75: ircr   db      0               ;saved interrupt controller mask
                     76: siovn  db      0               ;serial i/o vector number
                     77: 
                     78: ic29h  equ     1               ;int 29h is being intercepted
                     79: ic29d  equ     3               ;int 29h is being diverted
                     80: ic16h  equ     10h             ;int 16h is being intercepted
                     81: intcp  db      0               ;intercepted interrupt code
                     82: 
                     83: opera  db      0               ;operational (port defined, baud set)
                     84: 
                     85: mode   db      0               ;function enable (incl pause/abort cycles)
                     86: state  db      0               ;operational state (must follow mode)
                     87: hold   equ     2               ;stop transmission
                     88: abort  equ     4               ;aborting
                     89: ctsck  equ     10h             ;check clear to send signal (mode only, fixed)
                     90: 
                     91: txintp db      0               ;transmit interrupt pending
                     92: status db      0               ;communications status
                     93: rxlost equ     1               ;received characters lost
                     94: 
                     95:        align   2
                     96: txbmx  equ     1024            ;receive buffer maximum size
                     97: rxbmx  equ     1024            ;transmit buffer maximum size
                     98: 
                     99: _plst  label   word
                    100: 
                    101: dv     rxbp    bufp,0          ;receive buffer pointers
                    102: dv     txbp    bufp,0          ;transmit buffer pointers
                    103: 
                    104: dv     rxb     rxbmx,0a8h      ;receive buffer
                    105: dv     txb     txbmx,0a8h      ;transmit buffer
                    106: 
                    107: tst    db      0
                    108:        .xlist
                    109:        .eopg
                    110:        .code
                    111:        public  _rioini,_outcom,_incom,_dtr,_setbaud
                    112: 
                    113: riods: dw      -1              ;remote i/o routine data segment value
                    114: 
                    115: ; initialize communications
                    116: 
                    117: ; clear buffers, data, program uart, enable interrupts
                    118: 
                    119: _rioini        proc
                    120:        push    bp
                    121:        mov     bp,sp
                    122:        push    si
                    123:        push    di
                    124: 
                    125:        mov     ax,pb[bp]       ;com port or uart address
                    126:        or      ax,ax
                    127:        mov     ax,buart
                    128:        jnz     @f              ;initialize
                    129:        or      ax,ax
                    130:        jz      cierr           ;error, not initialized
                    131:        jmp     finis           ;terminate
                    132: 
                    133: @@:    or      ax,ax
                    134:        jz      cinit           ;continue, not yet initialized
                    135: cierr: mov     ax,-1
                    136:        jmp     ciex            ;return error
                    137: 
                    138: cinit: mov     ax,ds
                    139:        mov     cs:riods,ax             ;save data segment
                    140: 
                    141:        call    ibfls                   ;clear input buffer
                    142:        mov     bofst[si],os rxb        ;set receive buffer address
                    143:        call    obfls                   ;clear output buffer
                    144:        mov     bofst[si],os txb        ;set transmit buffer address
                    145: 
                    146:        xor     ax,ax
                    147:        mov     mode,ax         ;clear mode and state
                    148:        mov     txintp,al       ;clear int pending
                    149: 
                    150:        mov     ax,seg biosda
                    151:        mov     es,ax
                    152:        mov     bx,pb[bp]       ;com port or uart address
                    153:        mov     dx,bx
                    154:        dec     bx
                    155:        cmp     bx,4
                    156:        jnc     scport          ;com port address specified
                    157: 
                    158:        and     bx,3            ;com 0-3 for 1-4
                    159:        add     bx,bx           ;offset (x 2)
                    160:        mov     dx,es:[bx]
                    161:        or      dx,dx
                    162:        jnz     scport          ;port exists
                    163:        jmp     ciabt           ;no such com port
                    164: 
                    165: scport:        mov     buart,dx        ;uart base address
                    166:        add     dx,lsr
                    167:        mov     lsrad,dx        ;line status register
                    168: 
                    169: ;      mov     al,pb[bp+4]     ;hardware flow control
                    170: ;      and     al,1
                    171: ;      jz      girq
                    172: ;      or      mode,ctsck      ;check cts
                    173: 
                    174: girq:  mov     al,pb[bp+2]     ;irq line
                    175:        and     al,7
                    176:        jnz     irqv            ;valid
                    177:        and     al,1
                    178:        add     al,3            ;assume 4 for 1, 3 for 2
                    179: irqv:  mov     irqn,al
                    180:        mov     cl,al
                    181:        mov     al,1
                    182:        shl     al,cl           ;mask for current irq line
                    183: ;      mov     irqm,al
                    184:        mov     ah,al
                    185:        push    ax              ;save irq mask
                    186:        in      al,imr1
                    187:        mov     ircr,al         ;save prior enable mask
                    188:        or      al,ah
                    189:        out     imr1,al         ;inhibit interrupts
                    190:        mov     al,cl           ;irq number
                    191:        add     al,ivb1         ;add vector base
                    192:        mov     siovn,al        ;save sio vector
                    193:        call    gvect           ;get prior vector in dx:bx
                    194:        mov     ivsio,bx
                    195:        mov     ivsio+2,dx      ;save prior vector
                    196:        push    cs
                    197:        pop     dx
                    198:        mov     bx,os sioisr
                    199:        call    svect           ;set service routine vector in dx:bx
                    200: 
                    201:        mov     dx,buart
                    202:        in      ax,dx           ;clear%
                    203:        add     dx,mcr
                    204:        mov     al,mcrd
                    205:        out     dx,al           ;modem control register
                    206:        dec     dx
                    207:        mov     al,lcrd
                    208:        out     dx,al           ;line control register
                    209:        dec     dx
                    210:        dec     dx
                    211:        mov     al,ierd
                    212:        out     dx,al           ;interrupt enable register
                    213: 
                    214:        pop     ax              ;irq mask
                    215:        in      al,imr1
                    216:        not     ah
                    217:        and     al,ah
                    218:        out     imr1,al         ;enable interrupts
                    219: 
                    220: ;      mov     mw cs:mv2,1234h
                    221: ;      xor     ax,ax
                    222: ;      mov     si,os inims
                    223: ;      call    msout
                    224: 
                    225:        xor     ax,ax           ;return 0
                    226:        jmp     ciex            ;exit
                    227: 
                    228: ; terminate serial i/o operation
                    229: 
                    230: finis: mov     dx,buart
                    231:        add     dx,mcr
                    232:        xor     al,al
                    233:        out     dx,al           ;dtr off, release irq line
                    234: 
                    235:        mov     al,siovn        ;serial i/o vector
                    236:        mov     bx,ivsio        ;prior offset
                    237:        mov     dx,ivsio+2      ;prior segment
                    238:        call    svect           ;replace original vector
                    239: 
                    240:        mov     al,ircr
                    241:        out     imr1,al         ;replace prior interrupt controller mask
                    242:        xor     bx,bx
                    243:        jmp     cterm           ;return 0
                    244: 
                    245: ciabt: mov     bx,-1
                    246: cterm: xor     ax,ax
                    247:        mov     buart,ax        ;not initialized
                    248:        mov     opera,al        ;not operational
                    249:        mov     ax,bx           ;return code
                    250: ciex:  pop     di
                    251:        pop     si
                    252:        pop     bp
                    253:        ret
                    254: 
                    255: _rioini        endp
                    256: 
                    257: 
                    258: ; get interrupt vector al in dx:bx
                    259: 
                    260: gvect: push    es
                    261:        mov     ah,35h
                    262:        int     21h             ;returns vector in es:bx
                    263:        push    es
                    264:        pop     dx              ;segment
                    265:        pop     es
                    266:        ret
                    267: 
                    268: ; set interrupt vector al in dx:bx
                    269: 
                    270: svect: push    ds
                    271:        push    dx
                    272:        mov     ds,dx           ;segment
                    273:        mov     dx,bx           ;offset
                    274:        mov     ah,25h
                    275:        int     21h             ;takes vector in ds:dx
                    276:        pop     dx
                    277:        pop     ds
                    278:        ret
                    279: 
                    280: 
                    281: ; flush buffers
                    282: 
                    283: ibfls: mov     si,os rxbp      ;address input buffer pointers
                    284:        mov     bx,rxbmx        ;set maximum size
                    285:        jmp     s xbfls
                    286: obfls: mov     si,os txbp      ;address output buffer pointers
                    287:        mov     bx,txbmx        ;set maximum size
                    288: 
                    289: ; si -> bufp structure, bx = maximum size
                    290: 
                    291: xbfls: mov     cx,os bofst/2   ;pointer list length
                    292:        pushf
                    293:        cli
                    294:        push    si
                    295:        xor     ax,ax
                    296:        rep     stosw           ;clear pointers
                    297:        pop     si
                    298:        mov     bsize[si],bx
                    299:        popf
                    300:        ret
                    301: 
                    302: 
                    303: ; get character from buffer, ds:si -> pointers, saves cx, dx
                    304: 
                    305: bgetc: mov     ax,bcnt[si]
                    306:        or      ax,ax
                    307:        jz      bgnc            ;buffer empty
                    308: 
                    309:        pushf
                    310:        cli
                    311:        mov     bx,bofst[si]    ;buffer offset from segment
                    312:        mov     di,bget[si]     ;character offset from buffer
                    313:        mov     al,mb [bx+di]   ;get character
                    314:        inc     di              ;advance pointer
                    315:        cmp     di,bsize[si]
                    316:        jc      bggp            ;pointer not past end of buffer
                    317:        xor     di,di           ;reset to start
                    318: bggp:  mov     bget[si],di
                    319:        dec     bcnt[si]        ;character count
                    320:        popf                    ;re-enable interrupts if disabled
                    321:        or      al,al           ;character in al, clear carry
                    322:        ret
                    323: 
                    324: bgnc:  stc
                    325:        ret
                    326: 
                    327: 
                    328: ; put character to buffer, ds:si -> pointers, al = char, saves ax, cx, dx
                    329: 
                    330: bputc: mov     bx,bcnt[si]
                    331: bputco:        cmp     bx,bsize[si]
                    332:        jnc     bgnc            ;buffer full
                    333: 
                    334:        pushf
                    335:        cli
                    336:        mov     bx,bofst[si]    ;buffer offset from segment
                    337:        mov     di,bput[si]     ;character offset from buffer
                    338:        mov     mb [bx+di],al   ;put character
                    339:        inc     di              ;advance pointer
                    340:        cmp     di,bsize[si]
                    341:        jc      bpgp            ;pointer not past end of buffer
                    342:        xor     di,di           ;reset to start
                    343: bpgp:  mov     bput[si],di
                    344:        inc     bcnt[si]        ;character count
                    345:        popf                    ;re-enable interrupts if disabled
                    346:        clc                     ;character in al, clear carry
                    347:        ret
                    348: 
                    349: 
                    350: ; sio input character
                    351: 
                    352: _incom proc
                    353:        push    si
                    354:        push    di
                    355: 
                    356:        mov     si,os rxbp      ;address receive buffer pointers
                    357:        call    bgetc           ;get character from receive buffer
                    358:        mov     ah,state
                    359:        jnc     icgc            ;received character in al
                    360:        or      ah,1            ;no character available
                    361:        xor     al,al
                    362: 
                    363: icgc:  pop     di
                    364:        pop     si
                    365:        ret
                    366: _incom endp
                    367: 
                    368: 
                    369: ; sio output character
                    370: 
                    371: _outcom        proc
                    372:        xor     al,al
                    373:        mov     ah,state
                    374:        test    ah,abort
                    375:        jnz     ocabt           ;aborting
                    376: 
                    377:        push    bp
                    378:        mov     bp,sp
                    379:        push    si
                    380:        push    di
                    381: 
                    382:        mov     al,pb[bp]
                    383:        mov     si,os txbp      ;address transmit buffer pointers
                    384: 
                    385: ocrep: mov     bx,bcnt[si]
                    386:        or      bx,bx
                    387:        jnz     ocbuf           ;buffer not empty
                    388: 
                    389:        test    ah,hold
                    390:        jnz     ocbuf           ;paused
                    391: 
                    392:        mov     dx,lsrad        ;address line status register
                    393:        mov     cl,al
                    394:        in      al,dx
                    395:        and     al,20h          ;transmit hold register empty
                    396:        mov     al,cl
                    397:        jz      ocbuf           ;interrupt pending
                    398: 
                    399:        mov     dx,buart        ;uart base (r/w data port)
                    400:        out     dx,al           ;transmit character
                    401:        jmp     s ocex          ;exit
                    402: 
                    403: ocbuf: call    bputco          ;put character to transmit buffer
                    404:        jnc     ocex            ;done
                    405: 
                    406:        ;check timer, exit if 2 min.
                    407: 
                    408:        jmp     ocrep           ;retry
                    409: 
                    410: ocex:  pop     di
                    411:        pop     si
                    412:        pop     bp
                    413: ocabt: ret                     ;state in ah
                    414: _outcom        endp
                    415: 
                    416: 
                    417: ; sio interrupt service routine
                    418: 
                    419: sioisr proc
                    420:        cli
                    421:        push    ax
                    422:        push    bx
                    423:        push    cx
                    424:        push    dx
                    425:        push    si
                    426:        push    di
                    427:        push    ds
                    428: 
                    429:        mov     ax,cs:riods
                    430:        mov     ds,ax           ;i/o data segment
                    431: 
                    432: isrep: mov     dx,lsrad        ;line status register
                    433:        in      ax,dx           ;lsr in al, msr in ah
                    434:        mov     mw cs:mv2,ax    ;%
                    435:        mov     cx,ax           ;save line status
                    436:        sub     dx,lsr          ;address r/w data port
                    437:        test    al,1            ;received data available
                    438:        jz      txchk           ;no character received
                    439: 
                    440:        test    al,0ch          ;overrun/parity/framing error
                    441:        in      al,dx           ;read data
                    442:        jnz     txchk           ;receive error, discard data
                    443: 
                    444:        mov     bx,mode         ;mode in bl, state in bh
                    445:        test    bh,abort
                    446:        jnz     intex           ;aborting
                    447:        test    bl,abort
                    448:        jz      rcpau           ;not checking for abort
                    449:        cmp     al,3            ;^C
                    450:        jnz     rcpau           ;not abort character
                    451: 
                    452:        call    ibfls           ;flush input buffer
                    453:        call    obfls           ;flush output buffer
                    454:        mov     state,abort     ;aborting
                    455:        jmp     intex
                    456: 
                    457: rxccs: mov     state,hold      ;set pause flag
                    458:        jmp     s txchk
                    459: rxccq: and     state,not hold  ;clear pause flag
                    460:        jmp     s txchk
                    461: 
                    462: rcpau: test    bl,hold
                    463:        jz      rxpch           ;not checking pause
                    464:        cmp     al,13h          ;^s
                    465:        jz      rxccs           ;pause
                    466:        cmp     al,10h          ;^q
                    467:        jz      rxccq           ;resume
                    468: 
                    469: rxpch: mov     si,os rxbp      ;address receive buffer
                    470:        call    bputc           ;put character in buffer
                    471:        jnc     txchk           ;done
                    472:        or      status,rxlost   ;set receive characters lost flag
                    473: 
                    474: txchk: test    cl,20h          ;transmit hold register empty
                    475:        jz      intex           ;not ready to transmit
                    476: 
                    477:        mov     si,os txbp      ;address transmit buffer
                    478:        call    bgetc
                    479:        jc      intex           ;buffer empty
                    480: 
                    481:        mov     bx,mode         ;mode in bl, state in bh
                    482:        not     ch
                    483:        and     ch,bl           ;mode and not msr
                    484:        test    ch,ctsck        ;cts checking and cts off
                    485:        jnz     intex           ;hardware flow off, interrupt will resume
                    486: 
                    487:        test    bh,hold
                    488:        jnz     intex           ;paused
                    489: 
                    490:        out     dx,al           ;transmit character
                    491: 
                    492: intex: mov     dx,buart
                    493:        add     dx,iir
                    494:        in      al,dx           ;reset int?
                    495:        in      al,dx
                    496: ;      and     al,1
                    497: ;      jnz     isrex           ;more?
                    498: ;      jmp     isrep
                    499: 
                    500:        inc     mw cs:mv1
                    501:        mov     ax,rxbp.bcnt
                    502:        mov     mw cs:mv3,ax
                    503:        mov     ax,txbp.bcnt
                    504:        mov     mw cs:mv4,ax
                    505:        mov     ax,800
                    506:        mov     si,os intmsg
                    507:        call    msout
                    508: 
                    509: isrex: pop     ds
                    510:        pop     di
                    511:        pop     si
                    512:        pop     dx
                    513:        pop     cx
                    514:        pop     bx
                    515:        mov     al,20h
                    516:        out     icr1,al         ;non-specific eoi
                    517:        pop     ax
                    518:        iret
                    519: 
                    520: intmsg:        db      'Interrupt �5, msr/lsr �4, rxbc �4, txbc �4    ',0
                    521: 
                    522: sioisr endp
                    523: 
                    524: 
                    525: ; set baud rate
                    526: 
                    527: _setbaud proc
                    528:        mov     dx,buart        ;base port address
                    529:        or      dx,dx
                    530:        jnz     sbinit          ;initialized
                    531:        xor     ax,ax
                    532:        dec     ax              ;-1
                    533:        ret                     ;return error
                    534: 
                    535: sbinit:        push    bp
                    536:        mov     bp,sp
                    537:        push    si
                    538:        mov     cx,dx   ;%
                    539:        mov     si,os brdd      ;address baud rate dividend
                    540:        mov     dx,2[si]
                    541:        mov     ax,[si]         ;dividend in dx:ax
                    542:        div     mw pb[bp]       ;divide by parameter 1
                    543:        mov     dx,cx   ;%
                    544:        push    ax              ;actual rate divisor for uart
                    545:        mov     si,dx
                    546:        add     dx,lcr          ;address line control register
                    547:        in      al,dx
                    548:        or      al,80h
                    549:        out     dx,al           ;address baud rate divisor
                    550:        xchg    si,dx
                    551:        pop     ax
                    552:        out     dx,ax           ;write baud rate divisor
                    553:        xchg    si,dx
                    554:        in      al,dx
                    555:        and     al,7fh
                    556:        out     dx,al           ;address rx/tx registers, ier
                    557:        xchg    si,dx
                    558:        in      ax,dx           ;clear%
                    559: 
                    560:        xor     ax,ax           ;no error
                    561:        pop     si
                    562:        pop     bp
                    563:        ret
                    564: _setbaud endp
                    565:        .xlist
                    566:        .eopg
                    567: ; drop dtr
                    568: 
                    569: ; n=0 (off), n=1 (on), or n>1 (off, wait n seconds for dcd off)
                    570: 
                    571: _dtr   proc
                    572: 
                    573:        push    bp
                    574:        mov     bp,sp
                    575:        mov     ax,seg biosda
                    576:        mov     es,ax
                    577: 
                    578:        mov     dx,buart        ;uart base port
                    579:        or      dx,dx
                    580:        jz      dtrer           ;not initialized
                    581: 
                    582:        add     dx,4            ;address mcr
                    583:        in      al,dx
                    584:        and     al,0feh         ;clear dtr bit
                    585:        mov     ah,pb[bp]       ;parameter
                    586:        and     ah,0fh
                    587:        cmp     ah,2            ;0 off, 1 on
                    588:        jnc     wtdcd           ;off, wait for dcd
                    589:        or      al,ah
                    590:        out     dx,al           ;set as specified
                    591:        xor     al,al
                    592:        jmp     s dtrck
                    593: 
                    594: wtdcd: out     dx,al           ;dtr off
                    595:        inc     dx
                    596:        inc     dx              ;address msr
                    597: 
                    598: twn:   mov     cx,18           ;55ms/s
                    599: tws:   mov     bl,es:[6ch]     ;55ms counter
                    600: twt:   in      al,dx
                    601:        and     al,80h          ;dcd
                    602:        jz      dtrck           ;done
                    603:        cmp     bl,es:[6ch]     ;55ms counter
                    604:        jz      twt             ;wait 55ms
                    605:        loop    tws             ;wait 990ms
                    606:        dec     ah
                    607:        jnz     twn             ;wait 2-x seconds
                    608: dtrer: mov     al,-1           ;timeout
                    609: 
                    610: dtrck: mov     ah,al
                    611:        cmp     mb pb[bp],1
                    612:        jz      dtrex           ;dtr was set
                    613: 
                    614:        push    ax              ;dtr was reset, clear state and buffers
                    615:        call    ibfls
                    616:        call    obfls
                    617:        xor     al,al
                    618:        mov     state,al
                    619:        mov     status,al
                    620:        pop     ax
                    621: 
                    622: dtrex: pop     bp
                    623:        ret
                    624: _dtr   endp
                    625: 
                    626:        include mviow
                    627:        end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.