Annotation of coherent/b/kernel/FWB2/talkbios.asm, revision 1.1.1.1

1.1       root        1: ;------------------------------------------------------------------------------
                      2: ;      Talking BIOS device driver for the AT&T PC6300.
                      3: ;      Copyright (C) Karl Dahlke 1987
                      4: ;      This software may be freely used and distributed
                      5: ;      for any non-profit purpose.
                      6: ;------------------------------------------------------------------------------
                      7: 
                      8: ;      talkbios.asm: assembly base and support for talking BIOS routines
                      9: 
                     10: 
                     11: WDFIXLEN       equ     4096 ; length of word correction table
                     12: KBSIZ  equ 120 ; length  of type ahead keyboard buffer
                     13: ADDR   equ offset DGROUP
                     14: 
                     15: ;      These routines are bundled into a pseudo device driver,
                     16: ;      which is installed at init time.
                     17: ;      The device cannot be meaningfully read or written.
                     18: 
                     19: ;      Compatible with ansi.sys, ctrm, and most other applications.
                     20: 
                     21: ;      Device Driver skeleton taken from public domain,
                     22: ;      written by Frank Whaley.
                     23: 
                     24: ;      The real time interrupt switches stacks,
                     25: ;      since there are a lot of function calls in it,
                     26: ;      and it holds the CPU for quite a while.
                     27: ;      The other interrupts and the device driver
                     28: ;      use the existing stacks.  In general, there is very little
                     29: ;      documentation regarding stacks.  How much room is required
                     30: ;      for DOS interrupts, worst case?  How much room is available on system
                     31: ;      stacks (e.g. when device drivers get control)?
                     32: ;      It makes it difficult to write robust programs.
                     33: ;      Well, MS-DOS drivers seem quite unconcerned about these things,  so,
                     34: ;      For now, we just press on.
                     35: ;      The real time interrupt stack tromps right over the
                     36: ;      initialization code, saving memory.
                     37: 
                     38: ;      here come the segments
                     39: ;      segment structure is compatible with microsoft C, small memory model
                     40: _TEXT  segment  byte public 'CODE'
                     41: _TEXT  ends
                     42: ;      empty segments, but C uses them, so declare them
                     43: CONST  segment  word public 'CONST'
                     44: CONST  ends
                     45: _BSS   segment  word public 'BSS'
                     46: _BSS   ends
                     47: _DATA  segment  word public 'DATA'
                     48: _DATA  ends
                     49: _EDATA segment  para public 'EDATA'
                     50: _EDATA ends
                     51: 
                     52: DGROUP group CONST, _BSS, _DATA, _EDATA
                     53:        assume  cs: _TEXT, ds: DGROUP
                     54: 
                     55: 
                     56: ;      make microsoft C/link phase happy (see crt0.asm)
                     57:        public  __acrtused      
                     58:        __acrtused = 9876h      ; funny value not easily matched in SYMDEB
                     59: 
                     60: 
                     61: _TEXT  segment
                     62: 
                     63:        extrn _sdoutchar:near, _sdinkey:near, _sdioctl:near
                     64:        extrn   _sdload:near, _sdtime:near, _dosline:near
                     65:        public myds
                     66: 
                     67:        org     0 ; Device drivers start at 0
                     68: 
                     69: HDR     proc    far
                     70: ;      Device Header
                     71:        dd      -1 ; -> next device
                     72:        dw      0c000h ; attributes: character, ioctl
                     73:        DW      strategy ; -> device strategy
                     74:        DW      interrupt ; -> device interrupt
                     75:        db  "SPEAK$  " ; talking BIOS routines
                     76: 
                     77: ;      the following variables are  accessed through cs.
                     78: rh1ptr label word ; to access by words
                     79: rhptr   dd      0 ; -> Request Header
                     80: orig_rti dw 0,0 ; original real time interrupt vector
                     81: orig_kbi dw 0,0 ; original keyboard interrupt vector
                     82: orig_bkb dw 0,0 ; original bios keyboard interrupt vector
                     83: orig_bsc dw 0,0 ; original bios screen interrupt vector
                     84: ;      save ss and sp when switching to real time interrupt stack
                     85: save_ss        dw 0
                     86: save_sp        dw 0
                     87: myds   dw 0 ;  ds segment when running this system
                     88: nestrti        db 1 ; check for nested real time interrupts
                     89: 
                     90: ;      functions for device driver commands
                     91: functab        label word
                     92:        DW  init
                     93:        dw badf
                     94:        dw badf
                     95:        DW  ioctl
                     96:        dw nulf, nulf, nulf, nulf, nulf, nulf, nulf, nulf
                     97: 
                     98: 
                     99: 
                    100: strategy:
                    101: ;      squirrel away pointer to the msdos request
                    102: ;      I don't understand why dos doesn't just call the interrupt routine directly,
                    103: ;      and bypass this intermediate, seemingly unnecessary strategy routine.
                    104:        mov    rh1ptr,BX ; save request header ptr
                    105:        mov    rh1ptr + 2,ES
                    106:        ret
                    107: 
                    108: interrupt:
                    109: ;      device driver interrupt routine,  *not* a true interrupt routine.
                    110: ;      Perform the action requested by dos,
                    111: ;      request structure is pointed to by rhptr.
                    112: ;      We save all registers, gather relevant information
                    113: ;      from the request header,
                    114: ;      call the appropriate routine,
                    115: ;      restore registers, and return.
                    116: 
                    117:        pushf
                    118:        push ds
                    119:        push es
                    120:        push ax
                    121:        push bx
                    122:        push cx
                    123:        push dx
                    124:        push si
                    125:        push di
                    126:        cld
                    127:        sti
                    128:        mov ds,myds
                    129: 
                    130: ;      get relevant information from request header,
                    131: ;      for the functions to use
                    132:        les di,rhptr
                    133:        mov al,es:[di+2] ; ax = Command Code
                    134:        cbw
                    135: ;      set default status = DONE
                    136:        mov es:[di+3],100h
                    137:        mov cx,es:[di+18]
                    138:        les di,es:[di+14]
                    139: 
                    140:        ; call our functions
                    141:        cmp al,12
                    142:        jb cmdok
                    143: ;      command out of range
                    144:        mov al,2 ; replace with an illegal command
                    145: cmdok: mov si,offset _TEXT:functab
                    146:        add si,ax
                    147:        add si,ax
                    148:        call cs:[si]
                    149: 
                    150:        pop di
                    151:        pop si
                    152:        pop dx
                    153:        pop cx
                    154:        pop bx
                    155:        pop ax
                    156:        pop es
                    157:        pop ds
                    158:        popf
                    159:        ret
                    160: 
                    161: HDR     endp
                    162: 
                    163: 
                    164: ;      coherent kernel functions
                    165: cohker proc near
                    166:        public _sphi, _spl, _inb, _outb, _isin, _kalloc
                    167:        public _memcpy, _setivec, _read_t0
                    168: 
                    169: _read_t0:      pushf
                    170:        cli
                    171:        mov al,0
                    172: out 43h,al
                    173:        out  0e0h,al
                    174:        in al,40h
                    175:        mov ah,al
                    176:        out 0e0h,al
                    177:        in al,40h
                    178:        out 0e0h,al
                    179:        xchg al,ah
                    180:        popf
                    181:        ret
                    182: 
                    183: ;      a simplistic emulation of setivec(), clrivec() is not provided.
                    184: ;      may only be called once, with either 2 or 3.
                    185: _setivec:
                    186:        push bp
                    187:        mov bp,sp
                    188: ;      change parameters if on com2
                    189:        cmp word ptr [bp+4],4
                    190:        jz oncom1
                    191:        mov intofs,2ch
                    192:        mov irm,0f7h
                    193:        dec eoi
                    194: oncom1:
                    195:        mov ax,[bp+6]
                    196:        mov ivec_fn,ax
                    197: 
                    198: ;      set interrupt vector
                    199:        xor ax,ax
                    200:        mov es,ax
                    201:        mov bx,intofs
                    202:        mov word ptr es:[bx],offset _TEXT: ih_com
                    203:        mov es:[bx+2],cs
                    204: 
                    205:        in al,21h                     ;set enable bit on 8259
                    206:        and al,irm
                    207:        nop ; timing
                    208:        nop
                    209:        out 21h,al
                    210: 
                    211:        pop bp
                    212:        ret
                    213: 
                    214:        _sphi:  pushf
                    215:        cli
                    216:        pop ax
                    217:        ret
                    218: 
                    219: _spl:  push bp
                    220:        mov bp,sp
                    221:        mov ax,[bp+4]
                    222:        push ax
                    223:        popf
                    224:        pop bp
                    225:        ret
                    226: 
                    227: _inb:  push bp
                    228:        mov bp,sp
                    229:        mov dx,[bp+4]
                    230:        mov ah,0
                    231:        in al,dx
                    232:        pop bp
                    233:        ret
                    234: 
                    235: _outb: push bp
                    236:        mov bp,sp
                    237:        mov ax,[bp+6]
                    238:        mov dx,[bp+4]
                    239:        out dx,al
                    240:        pop bp
                    241:        ret
                    242: 
                    243: _memcpy:       push bp
                    244:        mov bp,sp
                    245:        push ds
                    246:        pop es
                    247:        push si
                    248:        push di
                    249:        mov si,[bp+6]
                    250:        mov di,[bp+4]
                    251:        mov cx,[bp+8]
                    252:        repz movsb
                    253:        pop di
                    254:        pop si
                    255:        pop bp
                    256:        ret
                    257: 
                    258: ;      store character in our internal BIOS-like keyboard buffer
                    259: _isin: push bp
                    260:        mov bp,sp
                    261:        pushf
                    262:        cli
                    263:        mov ax,[bp+4]
                    264: ;      -1 means flush the buffer
                    265:        cmp ax,-1
                    266:        jnz isinflush
                    267:        mov bx,ADDR: kbbuf
                    268:        mov kbhead,bx
                    269:        mov kbtail,bx
                    270:        mov ax, 0
                    271:        jmp short endisin
                    272: isinflush:
                    273: ;      work around an MSDOS bug, control C goes right to the top
                    274: ;      of the input queue, so you can blow away a running program,
                    275: ;      even if you have accidentally typed another character.
                    276:        cmp al,3
                    277:        jnz normchar
                    278:        mov bx,ADDR: kbbuf
                    279:        mov kbhead,bx
                    280:        mov kbtail,bx
                    281: normchar:      mov bx,kbhead
                    282:        mov [bx],ax
                    283:        inc bx
                    284:        inc bx
                    285:        cmp bx,ADDR: kbbuf+KBSIZ*2
                    286:        jnz wrap3
                    287:        mov bx,ADDR: kbbuf
                    288: wrap3: cmp bx,kbtail
                    289:        mov ax,-1
                    290:        jz endisin
                    291:        mov ax,0
                    292:        mov kbhead,bx
                    293: endisin:       popf
                    294:        pop bp
                    295:        ret
                    296: 
                    297: _kalloc:       push bp
                    298:        mov bp,sp
                    299:        test byte ptr inload,0ffh
                    300:        jz kalerr
                    301:        mov cx,[bp+4]
                    302:        mov ax,endbound
                    303:        add ax,cx
                    304:        jc kalerr
                    305:        xchg ax,endbound
                    306:        jmp short kalend
                    307: kalerr:        mov ax,0
                    308: kalend:        pop bp
                    309:        ret
                    310: cohker endp
                    311: 
                    312: ;      null function, for irrelevant comands
                    313: badf   proc near
                    314:        les di,rhptr
                    315:        mov es:[di+3],8103h ; unknown function for this device driver
                    316: nulf:  ret
                    317: badf   endp
                    318: 
                    319: ;      init function, set buffer, set interrupt vectors, set memory usage
                    320: init   proc near
                    321: ;      set up our own ds
                    322:        mov ax,offset _TEXT: DGROUP
                    323:        mov cl,4
                    324:        shr ax,cl
                    325:        mov bx,cs
                    326:        add ax,bx
                    327:        mov ds,ax
                    328:        mov myds,ax
                    329: 
                    330: ;      zero .bss area
                    331:        mov es,ax
                    332:        xor ax,ax
                    333:        mov cx,ADDR:databeg
                    334:        mov di,ADDR:bssbeg
                    335:        sub cx,di
                    336:        shr cx,1
                    337:        rep stosw
                    338: 
                    339: ;      get buffer size from config.sys line
                    340: ;      size specified in 1024 byte blocks, consistent with ramdisk.dev
                    341:        les di,rhptr
                    342:        les di,es:[di+18] ; es:di = config.sys command line
                    343:        push es
                    344:        push di
                    345:        call _dosline
                    346:        add sp,4
                    347: 
                    348: ;      C initialization routine
                    349:        call _sdload
                    350: 
                    351:        les si,rhptr
                    352:        mov ax,endbound
                    353:        mov es:[si+14],ax
                    354:        mov es:[si+16],ds
                    355:        mov inload,0
                    356: 
                    357: ;      set interrupt vectors
                    358: ;      should be done using dos calls 25h and 35h,
                    359: ;      but only calls 00h through 0ch and 30h are supported
                    360: ;      during device driver init phase.
                    361: ;      Disk Operating System Technical Reference Programming Manual
                    362: ;      [IBM inc.] chapter 3.
                    363: ;      Therefore, we disable interrupts,
                    364: ;      and write the lowmem vectors directly
                    365:        xor bx,bx
                    366:        mov ds,bx
                    367:        cli ; rest of init procedure has interrupts disabled
                    368:        mov ax,[bx+20h] ; save original real time interrupt vector
                    369:        mov orig_rti,ax
                    370:        mov ax,[bx+22h]
                    371:        mov orig_rti+2,ax
                    372:        mov word ptr [bx+20h],offset _TEXT: ih_rti  ;  real time interrupt
                    373:        mov [bx+22h],cs
                    374:        mov ax,[bx+24h] ; save original keyboard interrupt vector
                    375:        mov orig_kbi,ax
                    376:        mov ax,[bx+26h]
                    377:        mov orig_kbi+2,ax
                    378:        mov word ptr [bx+24h], offset _TEXT: ih_kbi
                    379:        mov [bx+26h],cs
                    380: 
                    381: ;      take over BIOS keyboard interrupt,
                    382: ;      to accommodate our internal type ahead buffer (long).
                    383:        mov ax,[bx+58h] ; save original bios keyboard interrupt vector
                    384:        mov orig_bkb,ax
                    385:        mov ax,[bx+5ah]
                    386:        mov orig_bkb+2,ax
                    387:        mov word ptr [bx+58h],offset _TEXT: ih_bkb ; BIOS keyboard interrupt
                    388:        mov [bx+5ah],cs
                    389: 
                    390: ;      same for screen BIOS routine
                    391:        mov ax,[bx+40h] ; save original bios screen interrupt vector
                    392:        mov orig_bsc,ax
                    393:        mov ax,[bx+42h]
                    394:        mov orig_bsc+2,ax
                    395:        mov word ptr [bx+40h],offset _TEXT: ih_bsc ; BIOS screen interrupt
                    396:        mov [bx+42h],cs
                    397: 
                    398: ;      empty our own keyboard buffer
                    399:        mov ds,myds
                    400:        mov kbhead,ADDR: kbbuf
                    401:        mov kbtail,ADDR: kbbuf
                    402:        sti
                    403: 
                    404: ;      call original bios routine to clear any accumulated MS-DOS characters
                    405: drain: mov ah,1
                    406:        pushf
                    407: ;      call far ptr cs:[orig_bkb], I can't figure out the masm syntax for this
                    408:        db 2eh, 0ffh, 01eh
                    409:        dw orig_bkb
                    410:        jz endinit
                    411:        mov ah,0 ; remove character
                    412:        pushf
                    413: ;      call far ptr cs:[orig_bkb]
                    414:        db 2eh, 0ffh, 01eh
                    415:        dw orig_bkb
                    416:        jmp short drain
                    417: 
                    418: endinit:       ret
                    419: init   endp
                    420: 
                    421: ;      read ioctl values
                    422: ;      used by a calling process to copy the text buffer to a file
                    423: ioctl  proc near
                    424: ;      returns pointers to the start and end of the internal text buffer
                    425: ;      plus the head and tail pointers.
                    426: ;      thus only 16-byte ioctl reads are allowed
                    427: ;      calling process must understand this driver implicitly.
                    428:        cmp cx,16
                    429:        jnz badioctl
                    430: ;      call C routine
                    431:        push es
                    432:        push di
                    433:        mov ax, 0
                    434:        push ax
                    435:        call _sdioctl
                    436:        add sp,6
                    437:        or ax,ax
                    438:        jz ioctlok
                    439: badioctl:
                    440:        les di,rhptr
                    441:        mov word ptr es:[di+18],0 ; 0 bytes transfered
                    442:        mov es:[di+3],810bh ; read fault, cannot return that many bytes
                    443: ioctlok:
                    444:        ret
                    445: ioctl  endp
                    446: 
                    447: ;      screen BIOS routine
                    448: ;      save characters written to screen, and pass all other commands through
                    449: ih_bsc proc far
                    450:        cmp ah,14
                    451:        jnz go10
                    452:        cmp bx,7
                    453:        jz scrchar
                    454: 
                    455: ;      jmp far ptr cs:[orig_bsc]
                    456: go10:  db 2eh, 0ffh, 02eh
                    457:        dw orig_bsc
                    458: 
                    459: scrchar:
                    460:        push ds
                    461:        push ax
                    462:        push bx
                    463:        push cx
                    464:        push dx
                    465:        mov ds,myds
                    466:        pushf
                    467:        sti
                    468: 
                    469:        push ax
                    470: ;      console is owner
                    471:        mov ax,0
                    472:        push ax
                    473:        call _sdoutchar
                    474:        add sp,4
                    475:        popf
                    476: 
                    477:        test al,2
                    478:        jz noesc
                    479:        pop dx
                    480:        pop cx
                    481:        push cx
                    482:        push dx
                    483:        push ax
                    484:        mov ax,0e1bh
                    485:        mov bx,7
                    486:        pushf
                    487: ;      call far ptr cs:[orig_bsc]
                    488:        db 2eh, 0ffh, 01eh
                    489:        dw orig_bsc
                    490:        pop ax
                    491: noesc: test al,1
                    492:        pop dx
                    493:        pop cx
                    494:        pop bx
                    495:        pop ax
                    496:        pop ds
                    497:        jz noscreen
                    498:        jmp short go10
                    499: 
                    500: noscreen: iret
                    501: ih_bsc endp
                    502: 
                    503: ;      interrupt routines
                    504: 
                    505: ;      read the virtual screen, in real time
                    506: ;      called at real time interrupt level
                    507: ;      Since this mess could easily take more than 50ms,
                    508: ;      and I don't feel like counting instructions for all possible paths,
                    509: ;      we call the original real time interrupt right away,
                    510: ;      then we interpret keyboard commands, read text, etc.
                    511: ih_rti proc far ; user real time interrupt handler
                    512: 
                    513:        pushf ; call the original interrupt routine
                    514: ;      call far ptr cs:[orig_rti]
                    515:        db 2eh, 0ffh, 01eh
                    516:        dw orig_rti
                    517: 
                    518: ;      simulate Coherent lbolt
                    519:        push ds
                    520:        mov ds,myds
                    521:        add word ptr _lbolt,5
                    522:        adc word ptr _lbolt+2,0
                    523:        pop ds
                    524: 
                    525: ;      check for nested real time interrupts
                    526:        dec nestrti
                    527:        jz go_rti
                    528:        inc nestrti
                    529:        iret ; previous routine still reading, or whatever
                    530: go_rti:
                    531: 
                    532: ;      switch stacks
                    533:        mov save_ss,ss
                    534:        mov save_sp,sp
                    535: ;      New stack overlays initialization code, about 200 bytes.
                    536:        push cs
                    537:        pop ss
                    538:        mov sp,offset _TEXT: drain
                    539: 
                    540:        cld
                    541:        push ds
                    542:        push ax
                    543:        push bx
                    544:        push cx
                    545:        push dx
                    546:        push es
                    547: 
                    548:        mov ds,myds
                    549:        sti
                    550: 
                    551: call _sdtime
                    552: 
                    553:        cli
                    554:        pop es
                    555:        pop dx
                    556:        pop cx
                    557:        pop bx
                    558:        pop ax
                    559:        pop ds
                    560:        mov ss,save_ss ; restore old stack
                    561:        mov sp,save_sp
                    562:        inc nestrti
                    563:        iret
                    564: ih_rti endp
                    565: 
                    566: 
                    567: ih_com proc far
                    568:        cld
                    569:        push ds
                    570:        push ax
                    571:        push bx
                    572:        push cx
                    573:        push dx
                    574: 
                    575:        mov ds,myds
                    576:        cld
                    577: 
                    578:        mov bx,ivec_fn
                    579:        call bx
                    580: 
                    581:        mov al,eoi
                    582:        out 20h,al
                    583:        pop dx
                    584:        pop cx
                    585:        pop bx
                    586:        pop ax
                    587:        pop ds
                    588:        iret
                    589: ih_com endp
                    590: 
                    591: 
                    592: ih_kbi proc far ; keyboard interrupt handler
                    593:        pushf ; call the original hardware interrupt routine
                    594: ;      call far ptr cs:[orig_kbi]
                    595:        db 2eh, 0ffh, 01eh
                    596:        dw orig_kbi
                    597: ;      if a key was entered into the MS-DOS buffer,
                    598: ;      and the key represents a reading command,
                    599: ;      remove it from the buffer, and place the corresponding
                    600: ;      command into the talkcmd location
                    601: ;      we assume no real time (or other) interrupt routine will
                    602: ;      grab the key from the buffer before this routine can snag it.
                    603:        cld
                    604:        push ax
                    605:        push bx
                    606:        push cx
                    607:        push dx
                    608:        push ds
                    609: ;      C routines preserve si, di, and bp
                    610: 
                    611: ;      call original bios routine to get the entered character
                    612:        mov ah,1
                    613:        pushf
                    614: ;      call far ptr cs:[orig_bkb]
                    615:        db 2eh, 0ffh, 01eh
                    616:        dw orig_bkb
                    617:        jz nokey ; no new characters typed
                    618: ;      now get the character
                    619:        mov ah,0
                    620:        pushf
                    621: ;      call far ptr cs:[orig_bkb]
                    622:        db 2eh, 0ffh, 01eh
                    623:        dw orig_bkb
                    624: 
                    625:        mov ds,myds
                    626:        push ax
                    627:        cmp word ptr _sdcontrol,0
                    628:        jz notactive
                    629: ;      console is owner
                    630:        mov ax,0
                    631:        push ax
                    632:        call _sdinkey ; turn key into command code
                    633:        add sp,4
                    634:        jmp short nokey
                    635: notactive:
                    636:        call _isin
                    637:        add sp,2
                    638: 
                    639: nokey: pop ds
                    640:        pop dx
                    641:        pop cx
                    642:        pop bx
                    643:        pop ax
                    644:        iret
                    645: ih_kbi endp
                    646: 
                    647: ;      new BIOS keyboarde routine, to accommodate new type ahead buffer.
                    648: ;
                    649: ;      the original bios routine enables interrupts,
                    650: ;      and when ah = 1, leaves them that way,
                    651: ;      regardless of the initial conditions.
                    652: ;      don't know if this is a feature or a bug, but I emulate it.
                    653: ;
                    654: ;      For some bizarre reason, dos4.0 calls this BIOS routine
                    655: ;      with ah = 10h, 11h, or 12h, instead of 0, 1, or 2.
                    656: ;      I have no idea what the extra bit means.
                    657: ;      I simply clear it out, and things seem to work.
                    658: ;      Thus this bios routine works under all versions of dos,
                    659: ;      as of this writing.
                    660: ih_bkb proc far
                    661:        sti
                    662:        and ah,0efh
                    663:        cmp ah,1
                    664:        jb getc
                    665:        jz nbget
                    666: ;      jmp far ptr cs:[orig_bkb]
                    667:        db 2eh, 0ffh, 02eh
                    668:        dw orig_bkb
                    669: 
                    670: nbget: ;       non blocking getchar
                    671:        push ds
                    672:        push bx
                    673:        mov ds,myds
                    674:        mov bx,kbtail
                    675:        cmp bx,kbhead
                    676:        mov ax,[bx]
                    677:        pop bx
                    678:        pop ds
                    679:        ret 2
                    680: 
                    681: getc:  ;       blocking getchar
                    682:        push ds
                    683:        push bx
                    684:        mov ds,myds
                    685:        mov bx,kbtail
                    686:        cmp bx,kbhead
                    687:        mov ax,[bx]
                    688:        jz getc
                    689:        inc bx
                    690:        inc bx
                    691:        cmp bx,ADDR: kbbuf+KBSIZ*2
                    692:        jnz wrap6
                    693:        mov bx,ADDR: kbbuf
                    694: wrap6: mov kbtail,bx
                    695:        pop bx
                    696:        pop ds
                    697:        iret
                    698: ih_bkb endp
                    699: 
                    700: _TEXT    ends
                    701: 
                    702: 
                    703: _BSS   segment
                    704: bssbeg dw ?
                    705: _BSS   ends
                    706: 
                    707: 
                    708: _DATA  segment
                    709: 
                    710:        extrn _lbolt:word, _sdcontrol:word
                    711: 
                    712: databeg        label word
                    713: 
                    714: ;      we implement our own interrupt level keyboard buffer
                    715: ;      the ms-dos buffer (15 characters) is frustratingly small
                    716: kbbuf  dw KBSIZ dup(?)
                    717: kbhead dw  kbbuf
                    718: kbtail dw  kbbuf
                    719: 
                    720: ivec_fn        dw 0 ; setivec function
                    721: 
                    722: endbound dw ADDR: boundary
                    723: inload db 1 ; are we in load phase?
                    724: 
                    725: intofs dw 30h ; offset for interrupt vector
                    726: irm    db 0efh ; interrupt register mask
                    727: eoi    db 64h ; end of interrupt code
                    728: 
                    729: _DATA    ends
                    730: 
                    731: 
                    732: ;      to find the end of DGROUP, and the start of word table and buffer
                    733: _EDATA segment
                    734: boundary       label word
                    735: _EDATA ends
                    736: 
                    737:        end HDR

unix.superglobalmegacorp.com

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