home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / sampler0 / onekey.asm < prev    next >
Assembly Source File  |  1986-02-05  |  10KB  |  203 lines

  1. VECTORS SEGMENT AT 0H           ;Set up segment to intercept Interrupts
  2.         ORG     9H*4            ;The keyboard Interrupt
  3. KEYBOARD_INT_VECTOR     LABEL   DWORD
  4.         ORG     1CH*4           ;Timer Interrupt
  5. TIMER_VECTOR      LABEL   DWORD
  6. VECTORS ENDS
  7.  
  8. ROM_BIOS_DATA   SEGMENT AT 40H  ;The ROM BIOS data area in low memory
  9.         ORG     1AH             ;This is where the keyboard buffer is.
  10. ROM_BUFFER_HEAD DW      ?       ;The position of the buffer's head
  11. ROM_BUFFER_TAIL DW      ?       ;And tail.
  12. KB_BUFFER       DW      16 DUP (?)      ;Reserve space for the buffer itself
  13. KB_BUFFER_END   LABEL   WORD    ;Buffer's end is stored here.        
  14. ROM_BIOS_DATA   ENDS             
  15.  
  16. CODE_SEG        SEGMENT         ;Begin the Code segment holding the programs
  17.         ASSUME  CS:CODE_SEG
  18.         ORG     100H            ;Com files start at ORG 100H
  19. BEGIN:  JMP     INIT_VECTORS    ;Skip over data area
  20.  
  21. COPY_RIGHT              DB      '(C) 1984 S. Holzner'   ;The Author's signature
  22. KEYS                    DW      30 DUP(0)       ;The keys we replace
  23. FINISHED_FLAG           DB      1     ;If not finished, timer will stuff buffer 
  24. COMMANDS                DW      1530 DUP(0)    ;Scan and ASCII codes of commands
  25. COMMAND_INDEX           DW      1       ;Stores position in command (for timer)
  26. ROM_KEYBOARD_INT        DD      1       ;Called to interpret keyboard signals
  27. ROM_TIMER               DD      1       ;The Timer interrupt's address
  28.  
  29. INTERCEPT_KEYBOARD_INT  PROC    NEAR    ;Here it is.             
  30.         ASSUME  DS:NOTHING      ;Free DS
  31.         PUSH    DS              ;Save all used registers
  32.         PUSH    SI
  33.         PUSH    DI
  34.         PUSH    DX
  35.         PUSH    CX
  36.         PUSH    BX
  37.         PUSH    AX
  38.         PUSHF                   ;Pushf for Keyboard Int's IRET
  39.         CALL    ROM_KEYBOARD_INT   ;Have new key put into keyboard buffer
  40.         ASSUME  DS:ROM_BIOS_DATA        ;Set up to point at keyboard buffer.
  41.         MOV     AX,ROM_BIOS_DATA
  42.         MOV     DS,AX
  43.                   
  44.         MOV     BX,ROM_BUFFER_TAIL      ;Was there a character? If Tail equals
  45.         CMP     BX,ROM_BUFFER_HEAD      ; Head then no real character typed.
  46.         JNE     NEWCHAR
  47.         JMP     NO_NEW_CHARACTERS       ;Jump out, no new characters.
  48. NEWCHAR:SUB     BX,2                    ;Move back two bytes from tail;
  49.         CMP     BX,OFFSET KB_BUFFER     ;Do we have to wrap?
  50.         JAE     NO_WRAP                 ;No
  51.         MOV     BX,OFFSET KB_BUFFER_END         ;Wrap by moving two bytes 
  52.         SUB     BX,2                            ; before buffer end.
  53. NO_WRAP:MOV     AX,[BX]                 ;Get the character into AX
  54.  
  55.         CMP     FINISHED_FLAG,1  ;Done stuffing the buffer with last command?
  56.         JE      FIN                     ;Yes, proceed
  57.         JMP     NO_NEW_CHARACTERS       ;No, leave.
  58.  
  59. FIN:    MOV     FINISHED_FLAG,1         ;Assume we'll finish
  60.  
  61.         LEA     SI,KEYS                 ;Point source index at keys to replace
  62.         MOV     CX,30                   ;Loop over all of them
  63. LOOPER: CMP     AX,CS:[SI]              ;Match to given key (in AX)?
  64.         JE      FOUND                   ;Yes, key found, continue on.
  65.         ADD     SI,2                    ;Point to next key to check it.
  66.         LOOP    LOOPER                  ;Go back for next one.
  67.         JMP     NO_NEW_CHARACTERS       ;Loop finished without match - leave.
  68.  
  69. FOUND:  CLI                     ;Turn off hardware (timer, keyboard) Interrupts
  70.         LEA     SI,COMMANDS     ;Set up to read command
  71.         NEG     CX              ;Find the location of first word of command
  72.         ADD     CX,30
  73.         MOV     AX,CX
  74.         MOV     CX,102
  75.         MUL     CL
  76.         ADD     SI,AX
  77.         MOV     COMMAND_INDEX,SI ;And move it into Command_Index
  78.  
  79. STUFF:  MOV     AX,CS:[SI]  ;Here we go - get ready to stuff word in buffer.
  80.         ADD     SI,2                    ;Point to the command's next character
  81.         CMP     AX,0                    ;Is it a zero? (End of command)
  82.         JE      NO_NEW_CHARACTERS       ;Yes, leave with Finished_Flag=1
  83.         MOV     DX,BX                   ;Find position in buffer from BX
  84.         ADD     DX,2                    ;Move to next position for this word
  85.         CMP     DX,OFFSET KB_BUFFER_END ;Are we past the end?
  86.         JL      NO_WRAP2                ;No, don't wrap
  87.         MOV     DX,OFFSET KB_BUFFER     ;Wrap
  88. NO_WRAP2:
  89.         CMP     DX,ROM_BUFFER_HEAD      ;Buffer full but not yet done?
  90.         JE      BUFFER_FULL             ;Time to leave, set Finished_Flag=0.
  91.         ADD     COMMAND_INDEX,2         ;Move to next word in command
  92.         MOV     [BX],AX                 ;Put it into the buffer right here.
  93.         ADD     BX,2                    ;Point to next space in buffer
  94.         CMP     BX,OFFSET KB_BUFFER_END ;Wrap here?
  95.         JL      NO_WRAP3                ;No, readjust buffer tail
  96.         MOV     BX,OFFSET KB_BUFFER     ;Yes, wrap
  97. NO_WRAP3: 
  98.         MOV     ROM_BUFFER_TAIL,BX      ;Reset buffer tail
  99.         JMP     STUFF                   ;Back to stuff in another character.
  100. BUFFER_FULL:                            ;If buffer is full, let timer take over
  101.         MOV     FINISHED_FLAG,0         ; by setting Finished_Flag to 0.
  102. NO_NEW_CHARACTERS:
  103.         POP     AX                      ;Restore everything before departure.
  104.         POP     BX
  105.         POP     CX
  106.         POP     DX
  107.         POP     DI
  108.         POP     SI
  109.         POP     DS
  110.         STI
  111.         IRET                            ;An interrupt deserves an IRET
  112. INTERCEPT_KEYBOARD_INT  ENDP
  113.         ASSUME  DS:CODE_SEG
  114. INTERCEPT_TIMER   PROC    NEAR          ;This completes filling the buffer
  115.         PUSHF                           ;Store used flags
  116.         PUSH    DS                      ;Save DS since we'll change it
  117.         PUSH    CS                      ;Put current value of CS into DS
  118.         POP     DS
  119.         CALL    ROM_TIMER               ;Make obligatory call
  120.         PUSHF
  121.         CMP     FINISHED_FLAG,1         ;Do we have to do anything?
  122.         JE      OUT                     ;No, leave
  123.         CLI                             ;Yes, start by clearing interrupts
  124.         PUSH    DS                      ;Save these.
  125.         PUSH    SI
  126.         PUSH    DX
  127.         PUSH    BX
  128.         PUSH    AX
  129.         ASSUME  DS:ROM_BIOS_DATA        ;Point to the keyboard buffer again.
  130.         MOV     AX,ROM_BIOS_DATA
  131.         MOV     DS,AX
  132.         MOV     BX,ROM_BUFFER_TAIL      ;Prepare to put charaters in at tail
  133.         MOV     FINISHED_FLAG,1         ;Assume we'll finish
  134.         MOV     SI,COMMAND_INDEX        ;Find where we left ourselves
  135.  
  136. STUFF2: MOV     AX,CS:[SI]              ;The same stuff loop as above.
  137.         ADD     SI,2                    ;Point to next command character.
  138.         CMP     AX,0                    ;Is it zero? (end of command)
  139.         JNE     OVER                    ;No, continue.
  140.         JMP     NO_NEW_CHARACTERS2      ;Yes, leave with Finished_Flag=1
  141. OVER:   MOV     DX,BX                   ;Find position in buffer from BX
  142.         ADD     DX,2                    ;Move to next position for this word
  143.         CMP     DX,OFFSET KB_BUFFER_END ;Are we past the end?
  144.         JL      NO_WRAP4                ;No, don't wrap
  145.         MOV     DX,OFFSET KB_BUFFER     ;Do the Wrap rap.
  146. NO_WRAP4:                               
  147.         CMP     DX,ROM_BUFFER_HEAD      ;Buffer full but not yet done?
  148.         JE      BUFFER_FULL2            ;Time to leave, come back later.
  149.         ADD     COMMAND_INDEX,2         ;Point to next word of command.
  150.         MOV     [BX],AX                 ;Put into buffer
  151.         ADD     BX,2                    ;Point to next space in buffer
  152.         CMP     BX,OFFSET KB_BUFFER_END ;Wrap here?
  153.         JL      NO_WRAP5                ;No, readjust buffer tail
  154.         MOV     BX,OFFSET KB_BUFFER     ;Yes, wrap
  155. NO_WRAP5:                               
  156.         MOV     ROM_BUFFER_TAIL,BX      ;Reset buffer tail
  157.         JMP     STUFF2                  ;Back to stuff in another character
  158. BUFFER_FULL2:
  159.         MOV     FINISHED_FLAG,0         ;Set flag to not-done-yet.
  160. NO_NEW_CHARACTERS2:
  161.         POP     AX                      ;Restore these.
  162.         POP     BX
  163.         POP     DX
  164.         POP     SI
  165.         POP     DS
  166. OUT:    POPF                            ;And Exit.
  167.         POP     DS
  168.         IRET                            ;With customary IRET
  169. INTERCEPT_TIMER   ENDP
  170.  
  171. INIT_VECTORS    PROC    NEAR    ;Rest Interrupt vectors here
  172.         ASSUME  DS:VECTORS
  173.         PUSH    DS
  174.         MOV     AX,VECTORS
  175.         MOV     DS,AX
  176.         CLI                     ;Don't allow interrupts
  177.         MOV     AX,KEYBOARD_INT_VECTOR  ;Get and store old interrupt address
  178.         MOV     ROM_KEYBOARD_INT,AX
  179.         MOV     AX,KEYBOARD_INT_VECTOR[2]
  180.         MOV     ROM_KEYBOARD_INT[2],AX
  181.  
  182.         MOV     KEYBOARD_INT_VECTOR,OFFSET INTERCEPT_KEYBOARD_INT
  183.         MOV     KEYBOARD_INT_VECTOR[2],CS  ;And put ours in place.
  184.         MOV     AX,TIMER_VECTOR         ;Now same for timer
  185.         MOV     ROM_TIMER,AX
  186.         MOV     AX,TIMER_VECTOR[2]
  187.         MOV     ROM_TIMER[2],AX
  188.  
  189.         MOV     TIMER_VECTOR,OFFSET INTERCEPT_TIMER
  190.         MOV     TIMER_VECTOR[2],CS      ;And intercept that too.
  191.         STI
  192.         ASSUME  DS:ROM_BIOS_DATA
  193.         MOV     AX,ROM_BIOS_DATA
  194.         MOV     DS,AX
  195.         MOV     BX,OFFSET KB_BUFFER     ;Clear the keyboard buffer.
  196.         MOV     ROM_BUFFER_HEAD,BX
  197.         MOV     ROM_BUFFER_TAIL,BX
  198.         MOV     DX,OFFSET INIT_VECTORS  ;Prepare to attach in memory
  199.         INT     27H                     ;And do so.
  200. INIT_VECTORS    ENDP
  201. CODE_SEG        ENDS
  202.         END     BEGIN   ;End Begin so that we jump there first.
  203.