]> 4ch.mooo.com Git - 16.git/blobdiff - 16/scrasm/KEYB.INC
refresh wwww
[16.git] / 16 / scrasm / KEYB.INC
diff --git a/16/scrasm/KEYB.INC b/16/scrasm/KEYB.INC
new file mode 100755 (executable)
index 0000000..ef730cf
--- /dev/null
@@ -0,0 +1,237 @@
+;; ====================================================================\r
+;; Macros\r
+;; ====================================================================\r
+;; Jump if key pressed\r
+JKEYP           MACRO   key,label\r
+                cmp     byte ptr cs:_keyFlags[key+1],1\r
+                je      label\r
+                ENDM\r
+;; Jump if key not pressed\r
+JKEYNP          MACRO   key,label\r
+                cmp     byte ptr cs:_keyFlags[key+1],1\r
+                jne     label\r
+                ENDM\r
+\r
+;; Note that JNKEY and JKEY both modify _flKeyChanged, so you cannot\r
+;; use one after the other!  In other words,\r
+;;  JKEYNP no_key\r
+;;  JKEYP  yes_key      ;<-- this will fail\r
+;; will not work like you'd think it would.  The second call (JKEYP)\r
+;; will not know that a key has been pressed!\r
+;; Jump if no key pressed:\r
+JNKEY           MACRO   label\r
+                cmp     cs:_flKeyChanged,0\r
+                je      label\r
+                mov     cs:_flKeyChanged,0      ; <--- important!\r
+                ENDM\r
+;; Jump if key pressed:\r
+JKEY            MACRO   label\r
+                cmp     cs:_flKeyChanged,0\r
+                mov     cs:_flKeyChanged,0\r
+                jne     label\r
+                ENDM\r
+\r
+;; Start keyboard interrupts\r
+KEYB_START      MACRO\r
+                call    SwapInt9\r
+                mov     cs:_flKeyChanged,0\r
+                ENDM\r
+\r
+;; Clear keyboard interrupts\r
+KEYB_END        MACRO\r
+                call    SwapInt9\r
+                ENDM\r
+\r
+;; Credit for these routines:  Steve Dollins, Brown Computer Group.\r
+;; I didn't write any of the code below -- just heisted it from some\r
+;; stuff that he wrote and released!  Very useful keyboard routines.\r
+;; Any comments prefixed SDE were added by me.\r
+_keyFlags       dw      256 dup (0)     ; SDE: since they only use 2 bits\r
+                                        ; per word, this is a tradeoff,\r
+                                        ; space for time\r
+\r
+oldint9_offset  dw      offset newint9\r
+oldint9_segment dw      seg newint9\r
+\r
+_flKeyChanged   dw      0\r
+\r
+;-----------------------------------------------------------------------\r
+; void SwapInt9( void )\r
+;\r
+;       SwapInt9() exchanges the vector in oldint9_segment:oldint9_offset\r
+;       with the vector in the interrupt table for INT 9h.\r
+;-----------------------------------------------------------------------\r
+\r
+SwapInt9        PROC    far\r
+                mov     ax,cs\r
+                mov     ds,ax\r
+\r
+                mov     ax,03509h       ; Get interrupt 09h\r
+                int     21h             ;   return in ES:BX\r
+\r
+                mov     ax,oldint9_segment\r
+                mov     dx,oldint9_offset\r
+                push    ds\r
+                mov     ds,ax\r
+                mov     ax,02509h       ; Set new interrupt\r
+                int     21h             ;  to address in DS:DX\r
+                pop     ds\r
+\r
+                mov     oldint9_segment,es    ; Save the old interrupt\r
+                mov     oldint9_offset,bx\r
+                ret\r
+SwapInt9        ENDP\r
+\r
+\r
+;-----------------------------------------------------------------------\r
+; newint9 is the new keyboard interrupt (INT 9h).\r
+;\r
+;       Reads the scan code from the keyboard and modifies the key\r
+;       flags table.  The high byte is set to the position of the key,\r
+;       pressed=1, release=0.  The low byte is set to 1 when the key\r
+;       is pressed and left unmodified when the key is released.\r
+;-----------------------------------------------------------------------\r
+newint9         PROC    far\r
+                push    ax\r
+                push    bx\r
+                push    ds\r
+\r
+                mov     ax,cs\r
+                mov     ds,ax\r
+\r
+                JKEYNP  kCTRL,not_ctrlaltdel    ; SDE code\r
+                JKEYNP  kALT,not_ctrlaltdel     ; To still allow ctrl-\r
+                JKEYNP  kDELETE,not_ctrlaltdel  ; alt-delete.  Nothing\r
+                jmp     ctrlaltdel      ; worse than a total lockup!\r
+not_ctrlaltdel:\r
+\r
+                in      ax,60h          ; get scan code in AL, control byte in AH\r
+                mov     bx,ax           ; save a copy in BX\r
+                xchg    ah,al           ; swap to get control byte in AL\r
+                or      al,80h          ; clear keyboard\r
+                out     61h,al          ;   of interrupt\r
+                and     al,7Fh\r
+                out     61h,al\r
+                mov     al,20h          ; send generic EOI to\r
+                out     20h,al          ;   PIC\r
+\r
+                and     bx,0007fh       ; strip all but the scan code\r
+                shl     bx,1            ; multiply by two to get our offset\r
+\r
+                ; if the key was released, the high bit is set in the scan code\r
+                bt      ax,15           ; move this high bit into the carry flag\r
+                setnc   byte ptr [_keyFlags+bx+1] ; set "Is being pressed" flag\r
+                jc      short int09done ; if the key was released, we're done\r
+                mov     byte ptr [_keyFlags+bx],1 ; set "Has been pressed" flag\r
+                mov     _flKeyChanged,1         ; state of keyboard has changed\r
+int09done:\r
+                mov     _flKeyChanged,1         ; state of keyboard has changed\r
+                pop     ds\r
+                pop     bx\r
+                pop     ax\r
+                iret\r
+ctrlaltdel:     int     19h                     ; SDE -- added this.\r
+                                                ;  Allows a reboot.\r
+newint9         ENDP\r
+\r
+;; Defines the current key procedure (used as a jump-through)\r
+kprocCur        dw      KprocDirect\r
+\r
+;; This is a keyboard procedure.  Normally, this would control some\r
+;; sprite, or something, and the screen would follow the sprite.  For\r
+;; the purposes of this code, though (namely, sprite-less scrolling)\r
+;; it just directly affects ScrollDX and ScrollDY.\r
+;; This keyproc is inertialess, use + and - to increase speed and\r
+;; the up/down/left/right keys to move directions.\r
+;; Pressing K will switch to the other keyprocedure on the fly.\r
+;; P pauses the screen -- note that this is just for completely\r
+;; freezing the screen... it doesn't return until you let go!\r
+\r
+EVEN\r
+scroll_speed_x  dw      SCROLL_SPEED                    ; (defaults)\r
+scroll_speed_y  dw      SCROLL_SPEED * VIRTUAL_WIDTH    ; (defaults)\r
+KprocDirect     PROC    near\r
+chk_leftright:  mov     ax,0\r
+                JKEYNP  kRIGHT,not_right\r
+                mov     ax,scroll_speed_x\r
+                mov     ScrollDX,ax\r
+                jmp     chk_updown\r
+not_right:      JKEYNP  kLEFT,not_left\r
+                sub     ax,scroll_speed_x\r
+                mov     ScrollDX,ax\r
+                jmp     chk_updown\r
+not_left:       mov     ScrollDX,ax\r
+\r
+chk_updown:     mov     ax,0\r
+                JKEYNP  kUP,not_up\r
+                sub     ax,scroll_speed_y\r
+                mov     ScrollDY,ax\r
+                jmp     chk_other\r
+not_up:         JKEYNP  kDOWN,not_down\r
+                mov     ax,scroll_speed_y\r
+                mov     ScrollDY,ax\r
+                jmp     chk_other\r
+not_down:       mov     ScrollDY,ax\r
+\r
+chk_other:      JKEYNP  kK,not_k\r
+                mov     kprocCur,KprocInertia\r
+not_k:          JKEYNP  kM,not_m\r
+                mov     bDoTransition,1\r
+not_m:          JKEYNP  kGREY_MINUS,not_minus\r
+                cmp     scroll_speed_x,1\r
+                jle     not_minus\r
+                dec     scroll_speed_x\r
+                sub     scroll_speed_y,VIRTUAL_WIDTH\r
+not_minus:      JKEYNP  kGREY_PLUS,not_plus\r
+                cmp     scroll_speed_x,16\r
+                jge     not_plus\r
+                inc     scroll_speed_x\r
+                add     scroll_speed_y,VIRTUAL_WIDTH\r
+not_plus:\r
+\r
+pause_key:      JKEYP   kP,pause_key\r
+\r
+                ret\r
+KprocDirect     ENDP\r
+\r
+;; This keyproc has inertia, so + and - don't work.\r
+;; Use up/down/left/right keys to increase speed in those directions.\r
+;; Pressing K will switch to the other keyprocedure on the fly.\r
+;; P pauses the screen -- note that this is just for completely\r
+;; freezing the screen... it doesn't return until you let go!\r
+KprocInertia    PROC    near\r
+chk2_leftright: JKEYNP  kRIGHT,not2_right\r
+                cmp     ScrollDX,16\r
+                je      not2_right\r
+                inc     ScrollDX\r
+                jmp     chk2_updown\r
+not2_right:     JKEYNP  kLEFT,not2_left\r
+                cmp     ScrollDX,-16\r
+                je      not2_left\r
+                dec     ScrollDX\r
+                jmp     chk2_updown\r
+not2_left:\r
+\r
+chk2_updown:    JKEYNP  kUP,not2_up\r
+                cmp     ScrollDY,-VIRTUAL_WIDTH * 16\r
+                je      not2_up\r
+                add     ScrollDY,-VIRTUAL_WIDTH\r
+                jmp     chk2_other\r
+not2_up:        JKEYNP  kDOWN,not2_down\r
+                cmp     ScrollDY,VIRTUAL_WIDTH * 16\r
+                je      not2_down\r
+                add     ScrollDY,VIRTUAL_WIDTH\r
+                jmp     chk2_other\r
+not2_down:\r
+\r
+chk2_other:     JKEYNP  kK,not2_k\r
+                mov     kprocCur,KprocDirect\r
+not2_k:         JKEYNP  kM,not2_m\r
+                mov     bDoTransition,1\r
+not2_m:\r
+\r
+pause2_key:     JKEYP   kP,pause2_key\r
+\r
+                ret\r
+KprocInertia    ENDP\r
+\1a
\ No newline at end of file