Annotation of coherent/b/kernel/FWB2/talkbios.asm, revision 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.