|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.