home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / msysjour / vol05 / 03 / keyboard / kbbuffer.asm < prev    next >
Assembly Source File  |  1990-05-01  |  9KB  |  302 lines

  1. ;---------------------------------------------------------------;
  2. ;  KBBUFFER.CTL * Michael J. Mefford                            ;
  3. ;  Is loaded as a device driver just to get within offset       ;
  4. ;  range of the BIOS data area and the keyboard buffer so       ;
  5. ;  it can replace the default 15 key buffer with a larger one.  ;
  6. ;---------------------------------------------------------------;
  7.  
  8. BIOS_DATA      SEGMENT AT 40H
  9.                ORG     1AH
  10. BUFFER_HEAD    DW      ?
  11. BUFFER_TAIL    DW      ?
  12.                ORG     80H
  13. BUFFER_START   DW      ?
  14. BUFFER_END     DW      ?
  15. BIOS_DATA      ENDS
  16.  
  17.  
  18. _TEXT          SEGMENT PUBLIC 'CODE'
  19.                ASSUME  CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
  20.  
  21.                ORG     0H
  22.  
  23. ;COPYRIGHT      DB     "KBBUFFER.CTL 1.0 (c) 1990 ",CR,LF
  24. ;PROGRAMMER     DB     "Michael J. Mefford",CR,LF,CTRL_Z
  25.  
  26. ;************* DEVICE_HEADER *************;
  27.  
  28. POINTER        DD      -1
  29. ATTRIBUTE      DW      1000000000000000B
  30. DEVICE_STRAG   DW      STRATEGY
  31. DEVICE_INT     DW      INTERRUPT
  32. DEVICE_NAME    DB      "BUFFERCTL"
  33.  
  34.  
  35. CR             EQU     13
  36. LF             EQU     10
  37. CTRL_Z         EQU     26
  38. SPACE          EQU     32
  39. BOX            EQU     254
  40.  
  41. ;-------------------------;
  42.  
  43. REQUEST_HEADER STRUC
  44.  
  45. HEADER_LENGTH  DB      ?
  46. UNIT_CODE      DB      ?
  47. COMMAND_CODE   DB      ?
  48. STATUS         DW      ?
  49. RESERVED       DQ      ?
  50.  
  51. REQUEST_HEADER ENDS
  52.  
  53. DONE           EQU     0000000100000000B       ;Status codes.
  54. UNKNOWN        EQU     1000000000000011B
  55.  
  56. ;-------------------------;
  57.  
  58. INIT           STRUC
  59.  
  60. HEADER         DB      (TYPE REQUEST_HEADER) DUP(?)
  61. UNITS          DB      ?
  62. ENDING_OFFSET  DW      ?
  63. ENDING_SEGMENT DW      ?
  64. ARGUMENTS_OFF  DW      ?
  65. ARGUMENTS_SEG  DW      ?
  66.  
  67. INIT           ENDS
  68.  
  69. REQUEST_OFFSET DW      ?
  70. REQUEST_SEG    DW      ?
  71.  
  72. ;              CODE AREA
  73. ;              ---------
  74.  
  75. ;---------------------------------------------;
  76. ; The only task of the strategy routine is to ;
  77. ; save the pointer to the request header.     ;
  78. ;---------------------------------------------;
  79.  
  80. STRATEGY       PROC    FAR
  81.  
  82.   MOV     CS:REQUEST_OFFSET,BX    ;Request header address is
  83.   MOV     CS:REQUEST_SEG,ES       ; passed in ES:BX.
  84.   RET
  85.  
  86. STRATEGY       ENDP
  87.  
  88. ;----------------------------------------;
  89. ; The interrupt procedure will be called ;
  90. ; immediately after the strategy.        ;
  91. ;----------------------------------------;
  92.  
  93. INTERRUPT      PROC    FAR
  94.  
  95.   PUSH    AX                      ;Responsible for all registers.
  96.   PUSH    BX
  97.   PUSH    CX
  98.   PUSH    DX
  99.   PUSH    DS
  100.   PUSHF
  101.  
  102.   MOV     DS,CS:REQUEST_SEG       ;Retrieve request header pointer.
  103.   MOV     BX,CS:REQUEST_OFFSET
  104.  
  105.   OR      STATUS[BX],DONE         ;Tell DOS we are done.
  106.   CMP     COMMAND_CODE[BX],0      ;Is it INIT command?
  107.   JZ      MAKE_STACK              ;If yes, do our stuff.
  108.   OR      STATUS[BX],UNKNOWN      ;Else, exit with confused
  109.   JMP     SHORT UNKNOWN_EXIT      ; message to DOS.
  110.  
  111. MAKE_STACK:  
  112.   MOV     CX,SS                   ;Save DOS stack.
  113.   MOV     DX,SP
  114.   MOV     AX,CS
  115.   CLI
  116.   MOV     SS,AX                   ;Make new stack.
  117.   MOV     SP,0FFFEH
  118.   STI
  119.   PUSH    CX                      ;Save old stack pointers on new.
  120.   PUSH    DX
  121.  
  122.   PUSH    ES                      ;Save rest of registers.
  123.   PUSH    SI
  124.   PUSH    BP
  125.  
  126.   CALL    INITIALIZE              ;Go do our stuff.
  127.  
  128.   POP     BP                      ;Restore registers.
  129.   POP     SI
  130.   POP     ES
  131.  
  132.   POP     DX                      ;Restore old DOS stack.
  133.   POP     CX
  134.   CLI
  135.   MOV     SS,CX
  136.   MOV     SP,DX
  137.   STI
  138.  
  139. UNKNOWN_EXIT:
  140.   POPF                            ;Restore rest of registers.
  141.   POP     DS
  142.   POP     DX
  143.   POP     CX
  144.   POP     BX
  145.   POP     AX
  146.   RET                             ;Far return back to DOS.
  147.  
  148. INTERRUPT      ENDP
  149.  
  150. KBBUFFER_CTL_END LABEL   WORD
  151.  
  152. ;************* END OF RESIDENT PORTION *************;
  153.  
  154. BUFFER_DEFAULT EQU     80
  155. BUFFER_MIN     EQU     16
  156. BUFFER_MAX     EQU     200
  157.  
  158. HEADING        LABEL   BYTE
  159.  
  160. DB "KBBUFFER.CTL 1.0 (c) 1990 "
  161. DB "Michael J. Mefford",CR,LF,LF,"$"
  162.  
  163. INSTALLED_MSG  LABEL   BYTE
  164.  
  165. DB "Installed",CR,LF,LF
  166.  
  167. DB "Syntax:  DEVICE = KBBUFFER.CTL [buffer size]",CR,LF
  168. DB "buffer size = 16 - 200",CR,LF
  169. DB "default = 80",CR,LF,LF,"$"
  170.  
  171. OUT_OF_RANGE_MSG  LABEL BYTE
  172.  
  173. DB "KBBUFFER.CTL is loaded greater than "
  174. DB "64K from BIOS data area",CR,LF
  175. DB "KBBUFFER is inactive",CR,LF
  176. DB "Make sure KBBUFFER.CTL is first in CONFIG.SYS",CR,LF,LF,"$"
  177.  
  178. ;              ***************
  179. ;              * SUBROUTINES *
  180. ;              ***************
  181.  
  182. ;------------------------------------------;
  183. ; INPUT                                    ;
  184. ;   DS:BX points to request header.        ;
  185. ;                                          ;
  186. ;   All registers destroyed.               ;
  187. ;------------------------------------------;
  188.  
  189. INITIALIZE     PROC    NEAR
  190.  
  191.   PUSH    DS                      ;Point to request segment.
  192.   POP     ES
  193.   MOV     ENDING_OFFSET[BX],OFFSET KBBUFFER_CTL_END
  194.   MOV     ENDING_SEGMENT[BX],CS   ;Resident portion setup.
  195.  
  196.   MOV     CX,ARGUMENTS_SEG[BX]    ;Retrieve CONFIG.SYS buffer
  197.   MOV     SI,ARGUMENTS_OFF[BX]    ; pointers from INIT table.
  198.  
  199.   PUSH    CS                      ;Point to our data.
  200.   POP     DS
  201.   MOV     DX,OFFSET HEADING       ;Display signature.
  202.   CALL    PRINT_STRING
  203.  
  204.   MOV     DS,CX                   ;Point to argument segment.
  205.   CLD
  206.  
  207. ;------------------------------------;
  208. ; Parse CONFIG.CTL second parameter. ;
  209. ;------------------------------------;
  210.  
  211. FIND_PARA:   
  212.   LODSB                           ;Get a byte.
  213.   CMP     AL,SPACE                ;Leading white space?
  214.   JA      FIND_PARA               ;If yes, parse it off.
  215.  
  216.   DEC     SI                      ;Point to start of argument.
  217.   XOR     BP,BP                   ;Use BP to store seconds.
  218. NEXT_NUMBER: 
  219.   LODSB                           ;Retrieve a byte.
  220.   CMP     AL,CR                   ;If carriage return or linefeed,
  221.   JZ      CK_PARA                 ; found end of parameter.
  222.   CMP     AL,LF
  223.   JZ      CK_PARA
  224.   SUB     AL,"0"                  ;ASCII to binary.
  225.   JC      NEXT_NUMBER             ;If not between 0 and 9, skip.
  226.   CMP     AL,9
  227.   JA      NEXT_NUMBER
  228.   CBW                             ;Convert to word.
  229.   XCHG    AX,BP                   ;Swap old and new number.
  230.   MOV     CX,10                   ;Shift to left by multiplying
  231.   MUL     CX                      ; last entry by ten.
  232.   ADD     BP,AX                   ;Add new number and store in BP.
  233.   JMP     SHORT NEXT_NUMBER
  234.  
  235. ;---------------------------------------------;
  236. ; Check minimum, maximum parameter boundaries ;
  237. ;---------------------------------------------;
  238.  
  239. CK_PARA:     
  240.   CMP     BP,BUFFER_MIN           ;Is it below 16?
  241.   JA      CK_MAX
  242.   MOV     BP,BUFFER_DEFAULT       ;If yes, use default 80.
  243. CK_MAX:      
  244.   CMP     BP,BUFFER_MAX           ;Is it above 200?
  245.   JBE     CK_SEGMENT
  246.   MOV     BP,BUFFER_MAX           ;If yes, use default 80.
  247.  
  248. ;----------------------------------------------------------------;
  249. ; Check to see if KBBUFFER.CTL is within 64K range.  If it is,   ;
  250. ; change keyboard buffer to point to us, else exit with message. ;
  251. ;----------------------------------------------------------------;
  252.  
  253. CK_SEGMENT:  
  254.   INC     BP                          ;Adjust.
  255.   SHL     BP,1                        ;Convert byte count to word.
  256.   MOV     DX,OFFSET OUT_OF_RANGE_MSG  ;Point to out of range msg.
  257.   MOV     AX,CS                       ;Retrieve our segment.
  258.   SUB     AX,SEG BIOS_DATA            ;Subtract BIOS data segment.
  259.   MOV     CX,4                        ;AX = distance in paragraphs;
  260. PARA_TO_BYTES:
  261.   SHL     AX,1                        ; convert to bytes.
  262.   JC      INIT_END                    ;If > 64K, exit.
  263.   LOOP    PARA_TO_BYTES
  264.   ADD     AX,OFFSET KBBUFFER_CTL_END  ;Add resident portion offset.
  265.   JC      INIT_END                    ;If > 64K, exit.
  266.   MOV     CX,AX
  267.   ADD     CX,BP                       ;Add requested buffer size.
  268.   JC      INIT_END                    ;If > 64K, exit.
  269.  
  270. IN_RANGE:    
  271.   ADD     ES:ENDING_OFFSET[BX],BP     ;Point to end of resident.
  272.   ASSUME  DS:BIOS_DATA                ;Point to BIOS data area.
  273.   MOV     DX,SEG BIOS_DATA
  274.   MOV     DS,DX
  275.  
  276.   CLI                                 ;No interrupts.
  277.   MOV     BUFFER_HEAD,AX              ;Change keyboard buffer
  278.   MOV     BUFFER_TAIL,AX              ; pointers to point to us.
  279.   MOV     BUFFER_START,AX
  280.   MOV     BUFFER_END,CX
  281.   STI                                 ;Interrupts back on.
  282.  
  283.   MOV     DX,OFFSET INSTALLED_MSG     ;Display install msg.
  284.  
  285. INIT_END:    
  286.   PUSH    CS                          ;Point to our data.
  287.   POP     DS
  288.   CALL    PRINT_STRING                ;Display message.
  289.   RET                                 ;Exit.
  290.  
  291. INITIALIZE     ENDP
  292.  
  293. ;------------------------------;
  294.  
  295. PRINT_STRING:
  296.   MOV     AH,9                    ;Print string via DOS.
  297.   INT     21H
  298.   RET
  299.  
  300. _TEXT          ENDS
  301.                END
  302.