home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / RGASM.RAR / ASMCODE.EXE / CHAPT7 / KBDBUF.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-08-27  |  9.0 KB  |  262 lines

  1. ;
  2. ;       Program KbdBuf ( Chapter 7 )
  3. ;
  4.         page    55,132
  5. ;
  6. ;               Device request header
  7. ;
  8. ReqHeader       segment at 0
  9. HeaderLen       db      ?
  10. UnitCode        db      ?
  11. CommandCode     db      ?
  12. Status          dw      ?
  13. Reserved        db      8 dup (?)
  14. Units           db      ?                       ; Number of units
  15. EndOffset       dw      ?                       ; Segment:Offset address of
  16. EndSegment      dw      ?                       ;   the end of resident part
  17. ArgOffset       dw      ?                       ; Segment:Offset address of
  18. ArgSegment      dw      ?                       ;   the parameter string
  19. ReqHeader       ends
  20. ;
  21. ;               BIOS data segment
  22. ;
  23. BiosData        segment at 40h
  24.         org     1Ah
  25. BufHead         dw      ?                       ; Buffer head ptr
  26. BufTail         dw      ?                       ; Buffer tail ptr
  27.         org     80h
  28. BufStart        dw      ?                       ; Points to the buffer start
  29. BufEnd          dw      ?                       ; Points to the buffer end
  30. BiosData        ends
  31.  
  32. CR              equ     0Dh                     ; Carriage return code
  33. LF              equ     0Ah                     ; Line feed code
  34. EndMsg          equ     24h                     ; Dollar sign code
  35. Space           equ     20h                     ; Blank code
  36. InitCommand     equ     0                       ; Command "INIT driver"
  37. DoneRep equ     0100h                   ; Code "Device ready'
  38. FailRep         equ     8003h                   ; Code "Error-unknown command"
  39. BufferDef       equ     80                      ; Buffer default length
  40. BufferMin       equ     16                      ; Buffer minimal length
  41. BufferMax       equ     512                     ; Buffer maximal length
  42.  
  43. _TEXT           segment public 'CODE'
  44.         assume  cs:_TEXT,ds:_TEXT,es:ReqHeader,ss:_TEXT
  45.         org     0
  46. ;
  47. ;               Header
  48. ;
  49. NextDev         dd      0FFFFFFFFh              ; Pointer to the next driver
  50. DevAttr         dw      8000h                   ; Character device
  51. Dev_Strat       dw      Strategy                ; Offset of STRATEGY proc
  52. Dev_int         dw      Interrupt               ; Offset of INTERRUPT proc
  53. Dev_name        db      'KbdBuf  '              ; Driver name ( 8 characters)
  54.  
  55. ReqOffset       dw      ?
  56. ReqSegment      dw      ?
  57. StackSeg        dw      ?
  58. StackPtr        dw      ?
  59. ThisSeg         dw      ?
  60. ThisOff         dw      ?
  61. ParamVal        dw      0
  62. Ten             db      10
  63. Sixteen         dw      16
  64. BufLen          dw      0
  65. StatusWord      dw      DoneRep
  66.  
  67. Strategy        proc    far
  68. ;
  69. ;               The procedure STRATEGY is called while installing the driver.
  70. ;               This procedure is a dummy procedure because the driver
  71. ;               doesn't control any real device.
  72. ;
  73.         mov     ThisSeg,cs              ; Save the current segment
  74.         mov     ThisOff,offset NextDev  ; Save the offset of beginning
  75.         mov     ReqSegment,es           ; Save the segment of REQUEST
  76.         mov     ReqOffset,bx            ; Save the offset of REQUEST
  77.         push    ax
  78.         push    dx
  79.         push    ds
  80.         mov     ah,09
  81.         mov     ds,ThisSeg
  82.         mov     dx,offset HeadMsg
  83.         int     21h
  84.         pop     ds
  85.         pop     dx
  86.         pop     ax
  87.         ret
  88. HeadMsg         db      'Keyboard buffer extender ',EndMsg
  89. Strategy        endp
  90.  
  91. Interrupt       proc    far
  92.         push    ax
  93.         push    bx
  94.         push    cx
  95.         push    dx
  96.         push    ds
  97.         pushf
  98.         mov     al,CommandCode[bx]      ; Get the command code
  99.         mov     MsgAddr,offset InstMsg
  100.         cmp     al,INITcommand          ; Is it the INIT command?
  101.         je      ProcessCommand          ; If so, continue the work
  102.         mov     StatusWord,FailRep      ; If not, report the error
  103.         mov     MsgAddr,offset FailMsg
  104.         jmp     ReturnToDOS             ;    and exit the driver
  105.  
  106. ProcessCommand:
  107.  
  108.         mov     StatusWord,DoneRep      ; Report "DONE" to DOS
  109.         mov     EndSegment[bx],cs       ; Return address of the end
  110.         mov     EndOffset[bx],offset DriverEnd
  111.  
  112.         mov     cs:StackSeg,ss          ; Save the stack segment
  113.         mov     cs:StackPtr,sp          ; Save the stack pointer
  114.         mov     ax,cs                   ; Get the current segment
  115.  
  116.         cli                             ; No interrupts allowed while
  117.                         ;    changing stack registers
  118.         mov     ss,ax                   ; Stack is in current segment
  119.         mov     sp,0FFFEh               ; Stack is at the top of seg
  120.         sti                             ; Interrupts are now allowed
  121.  
  122.         push    es                      ;
  123.         push    si                      ;
  124.         push    bp                      ;
  125.  
  126.         call    ReadParm                ; Read parameter string
  127.  
  128.         call    CountEnding             ; Address of buffer end
  129.  
  130.         jc      NotInstall              ; If Carry Flag is set driver
  131.                         ; is not located in first 64K 
  132.  
  133. ;               Following two lines put SEGMENT:OFFSET address of the driver's
  134. ;               resident part into the DATA field for INIT command
  135.  
  136.         mov     es,ReqSegment
  137.         mov     bx,ReqOffset
  138.         mov     ax,ParamVal             ; Buffer length into AX
  139.         add     EndOffset[bx],ax        ; Offset addres of buffer end
  140.  
  141.         push    es
  142.         mov     ax,EndSegment[bx]       ; Segment address of buffer end
  143.         mul     Sixteen                 ; Right shift by 1 hex digit
  144.         add     ax,EndOffset[bx]        ; Effective address
  145.         sub     ax,400h                 ; Subtract start addres of
  146.                         ;   BIOS data area 
  147.         assume  es:BiosData
  148.         mov     dx,BIOSdata
  149.         mov     es,dx                   ; ES points to the BIOS data seg
  150.         cli                             ; No interrupts allowed!
  151.         mov     es:BufEnd,ax            ; New BUFFER END PTR
  152.         sub     ax,ParamVal             ; Subtract length of buffer 
  153.         mov     es:BufStart,ax          ; New BUFFER START PTR
  154.         mov     es:BufHead,ax           ; New BUFFER HEAD PTR
  155.         mov     es:BufTail,ax           ; NEW BUFFER TAIL PTR
  156.         sti                             ; Pointers are set - allow INT
  157.         pop     es
  158.         assume  es:ReqHeader
  159. NotInstall:
  160.         pop     bp
  161.         pop     si
  162.         pop     es
  163.  
  164.         cli
  165.         mov     ss,cs:StackSeg          ; Restore the stack segment
  166.         mov     sp,cs:StackPtr          ; Restore the stack pointer
  167.         sti
  168.  
  169. ReturnToDOS:
  170.         push    cs
  171.         pop     ds
  172.         mov     ah,09                   ; Function 09 - output string
  173.         mov     dx,MsgAddr              ; DX- Address of initial message
  174.         int     21h                     ; DOS service call
  175.         mov     es,ReqSegment           ; ES:BX point to the request
  176.         mov     bx,ReqOffset            ;   header area
  177.         mov     ax,StatusWord           ; Remember the status word
  178.         mov     Status[bx],ax           ; and return it to the DOS
  179.  
  180.         popf
  181.         pop     ds
  182.         pop     dx
  183.         pop     cx
  184.         pop     bx
  185.         pop     ax
  186.  
  187.         ret
  188. InstMsg         db      'is successfilly installed',Cr,LF,EndMsg
  189. FailMsg         db      'failed - not in the first 64K of memory',CR,LF,EndMsg
  190. MsgAddr         dw      ?
  191. Interrupt       endp
  192.  
  193. DriverEnd       label   dword                   ; This marks the END of driver
  194.  
  195. ReadParm        proc    near
  196.         mov     es,ReqSegment           ; ES:BX point to the request
  197.         mov     bx,ReqOffset            ;    data field
  198.         mov     si,es:ArgOffset[bx]     ; ES:SI - offset of arguments
  199.         mov     es,es:ArgSegment[bx]
  200.         mov     BlankId,0
  201.         mov     bx,0
  202. CopyParm:       mov     al,es:[si+bx]
  203.         cmp     al,CR
  204.         je      EndParm
  205.         cmp     al,LF
  206.         je      EndParm
  207.         cmp     al,0
  208.         je      EndParm
  209.         cmp     al,'0'
  210.         jl      NonDigit
  211.         cmp     al,'9'
  212.         ja      NonDigit
  213.         push    ax
  214.         sub     al,'0'                  ; Character to number
  215.         mov     ah,0                    ; Clear high part of AX
  216.         mov     CurNum,ax               ; Store current value
  217.         mov     ax,ParamVal
  218.         mul     Ten
  219.         add     ax,CurNum
  220.         mov     ParamVal,ax             
  221.         pop     ax
  222. NonDigit:       inc     bx
  223.         cmp     BlankId,0
  224.         jne     EndParm
  225.         jmp     CopyParm
  226. EndParm:        cmp     ParamVal,0              ; Is parameter set?
  227.         jne     PresentParm             ; If so, process its value
  228.         mov     ParamVal,BufferDef      ; Else set the defualt value
  229. PresentParm:    cmp     ParamVal,BufferMin      ; Compare to minimal value
  230.         ja      GreaterMin              ; Continue if it is bigger
  231.         mov     ParamVal,BufferMin      ; Else set the minimal value
  232. GreaterMin:     cmp     ParamVal,BufferMax      ; Compare to maximal value
  233.         jb      EndAccParm              ; If less - accept the value
  234. TooBig:         mov     ParamVal,BufferMax      ; Else set the maximal value
  235. EndAccParm:
  236.         ret
  237. BlankId         db      ?
  238. CurNum          dw      ?               
  239. ReadParm        endp
  240.  
  241. CountEnding     proc    near
  242.         push    es
  243.         push    bx
  244.         mov     es,ReqSegment
  245.         mov     bx,ReqOffset
  246.         mov     ax,EndSegment[bx]
  247.         mul     Sixteen
  248.         jc      EscapeProc
  249.         add     ax,EndOffset[bx]
  250.         jc      EscapeProc
  251.         add     ax,ParamVal
  252. EscapeProc:     pop     bx
  253.         pop     es
  254.         ret                             ; AX now contains the effective
  255.                         ;   address of buffer end
  256. CountEnding     endp
  257.  
  258. TxtParm         db      (64) ('$') , CR, LF, EndMsg
  259.  
  260. _TEXT           ends
  261.         end
  262.