]> 4ch.mooo.com Git - 16.git/blob - 16/scrasm/KEYB.INC
more
[16.git] / 16 / scrasm / KEYB.INC
1 ;; ====================================================================\r
2 ;; Macros\r
3 ;; ====================================================================\r
4 ;; Jump if key pressed\r
5 JKEYP           MACRO   key,label\r
6                 cmp     byte ptr cs:_keyFlags[key+1],1\r
7                 je      label\r
8                 ENDM\r
9 ;; Jump if key not pressed\r
10 JKEYNP          MACRO   key,label\r
11                 cmp     byte ptr cs:_keyFlags[key+1],1\r
12                 jne     label\r
13                 ENDM\r
14 \r
15 ;; Note that JNKEY and JKEY both modify _flKeyChanged, so you cannot\r
16 ;; use one after the other!  In other words,\r
17 ;;  JKEYNP no_key\r
18 ;;  JKEYP  yes_key      ;<-- this will fail\r
19 ;; will not work like you'd think it would.  The second call (JKEYP)\r
20 ;; will not know that a key has been pressed!\r
21 ;; Jump if no key pressed:\r
22 JNKEY           MACRO   label\r
23                 cmp     cs:_flKeyChanged,0\r
24                 je      label\r
25                 mov     cs:_flKeyChanged,0      ; <--- important!\r
26                 ENDM\r
27 ;; Jump if key pressed:\r
28 JKEY            MACRO   label\r
29                 cmp     cs:_flKeyChanged,0\r
30                 mov     cs:_flKeyChanged,0\r
31                 jne     label\r
32                 ENDM\r
33 \r
34 ;; Start keyboard interrupts\r
35 KEYB_START      MACRO\r
36                 call    SwapInt9\r
37                 mov     cs:_flKeyChanged,0\r
38                 ENDM\r
39 \r
40 ;; Clear keyboard interrupts\r
41 KEYB_END        MACRO\r
42                 call    SwapInt9\r
43                 ENDM\r
44 \r
45 ;; Credit for these routines:  Steve Dollins, Brown Computer Group.\r
46 ;; I didn't write any of the code below -- just heisted it from some\r
47 ;; stuff that he wrote and released!  Very useful keyboard routines.\r
48 ;; Any comments prefixed SDE were added by me.\r
49 _keyFlags       dw      256 dup (0)     ; SDE: since they only use 2 bits\r
50                                         ; per word, this is a tradeoff,\r
51                                         ; space for time\r
52 \r
53 oldint9_offset  dw      offset newint9\r
54 oldint9_segment dw      seg newint9\r
55 \r
56 _flKeyChanged   dw      0\r
57 \r
58 ;-----------------------------------------------------------------------\r
59 ; void SwapInt9( void )\r
60 ;\r
61 ;       SwapInt9() exchanges the vector in oldint9_segment:oldint9_offset\r
62 ;       with the vector in the interrupt table for INT 9h.\r
63 ;-----------------------------------------------------------------------\r
64 \r
65 SwapInt9        PROC    far\r
66                 mov     ax,cs\r
67                 mov     ds,ax\r
68 \r
69                 mov     ax,03509h       ; Get interrupt 09h\r
70                 int     21h             ;   return in ES:BX\r
71 \r
72                 mov     ax,oldint9_segment\r
73                 mov     dx,oldint9_offset\r
74                 push    ds\r
75                 mov     ds,ax\r
76                 mov     ax,02509h       ; Set new interrupt\r
77                 int     21h             ;  to address in DS:DX\r
78                 pop     ds\r
79 \r
80                 mov     oldint9_segment,es    ; Save the old interrupt\r
81                 mov     oldint9_offset,bx\r
82                 ret\r
83 SwapInt9        ENDP\r
84 \r
85 \r
86 ;-----------------------------------------------------------------------\r
87 ; newint9 is the new keyboard interrupt (INT 9h).\r
88 ;\r
89 ;       Reads the scan code from the keyboard and modifies the key\r
90 ;       flags table.  The high byte is set to the position of the key,\r
91 ;       pressed=1, release=0.  The low byte is set to 1 when the key\r
92 ;       is pressed and left unmodified when the key is released.\r
93 ;-----------------------------------------------------------------------\r
94 newint9         PROC    far\r
95                 push    ax\r
96                 push    bx\r
97                 push    ds\r
98 \r
99                 mov     ax,cs\r
100                 mov     ds,ax\r
101 \r
102                 JKEYNP  kCTRL,not_ctrlaltdel    ; SDE code\r
103                 JKEYNP  kALT,not_ctrlaltdel     ; To still allow ctrl-\r
104                 JKEYNP  kDELETE,not_ctrlaltdel  ; alt-delete.  Nothing\r
105                 jmp     ctrlaltdel      ; worse than a total lockup!\r
106 not_ctrlaltdel:\r
107 \r
108                 in      ax,60h          ; get scan code in AL, control byte in AH\r
109                 mov     bx,ax           ; save a copy in BX\r
110                 xchg    ah,al           ; swap to get control byte in AL\r
111                 or      al,80h          ; clear keyboard\r
112                 out     61h,al          ;   of interrupt\r
113                 and     al,7Fh\r
114                 out     61h,al\r
115                 mov     al,20h          ; send generic EOI to\r
116                 out     20h,al          ;   PIC\r
117 \r
118                 and     bx,0007fh       ; strip all but the scan code\r
119                 shl     bx,1            ; multiply by two to get our offset\r
120 \r
121                 ; if the key was released, the high bit is set in the scan code\r
122                 bt      ax,15           ; move this high bit into the carry flag\r
123                 setnc   byte ptr [_keyFlags+bx+1] ; set "Is being pressed" flag\r
124                 jc      short int09done ; if the key was released, we're done\r
125                 mov     byte ptr [_keyFlags+bx],1 ; set "Has been pressed" flag\r
126                 mov     _flKeyChanged,1         ; state of keyboard has changed\r
127 int09done:\r
128                 mov     _flKeyChanged,1         ; state of keyboard has changed\r
129                 pop     ds\r
130                 pop     bx\r
131                 pop     ax\r
132                 iret\r
133 ctrlaltdel:     int     19h                     ; SDE -- added this.\r
134                                                 ;  Allows a reboot.\r
135 newint9         ENDP\r
136 \r
137 ;; Defines the current key procedure (used as a jump-through)\r
138 kprocCur        dw      KprocDirect\r
139 \r
140 ;; This is a keyboard procedure.  Normally, this would control some\r
141 ;; sprite, or something, and the screen would follow the sprite.  For\r
142 ;; the purposes of this code, though (namely, sprite-less scrolling)\r
143 ;; it just directly affects ScrollDX and ScrollDY.\r
144 ;; This keyproc is inertialess, use + and - to increase speed and\r
145 ;; the up/down/left/right keys to move directions.\r
146 ;; Pressing K will switch to the other keyprocedure on the fly.\r
147 ;; P pauses the screen -- note that this is just for completely\r
148 ;; freezing the screen... it doesn't return until you let go!\r
149 \r
150 EVEN\r
151 scroll_speed_x  dw      SCROLL_SPEED                    ; (defaults)\r
152 scroll_speed_y  dw      SCROLL_SPEED * VIRTUAL_WIDTH    ; (defaults)\r
153 KprocDirect     PROC    near\r
154 chk_leftright:  mov     ax,0\r
155                 JKEYNP  kRIGHT,not_right\r
156                 mov     ax,scroll_speed_x\r
157                 mov     ScrollDX,ax\r
158                 jmp     chk_updown\r
159 not_right:      JKEYNP  kLEFT,not_left\r
160                 sub     ax,scroll_speed_x\r
161                 mov     ScrollDX,ax\r
162                 jmp     chk_updown\r
163 not_left:       mov     ScrollDX,ax\r
164 \r
165 chk_updown:     mov     ax,0\r
166                 JKEYNP  kUP,not_up\r
167                 sub     ax,scroll_speed_y\r
168                 mov     ScrollDY,ax\r
169                 jmp     chk_other\r
170 not_up:         JKEYNP  kDOWN,not_down\r
171                 mov     ax,scroll_speed_y\r
172                 mov     ScrollDY,ax\r
173                 jmp     chk_other\r
174 not_down:       mov     ScrollDY,ax\r
175 \r
176 chk_other:      JKEYNP  kK,not_k\r
177                 mov     kprocCur,KprocInertia\r
178 not_k:          JKEYNP  kM,not_m\r
179                 mov     bDoTransition,1\r
180 not_m:          JKEYNP  kGREY_MINUS,not_minus\r
181                 cmp     scroll_speed_x,1\r
182                 jle     not_minus\r
183                 dec     scroll_speed_x\r
184                 sub     scroll_speed_y,VIRTUAL_WIDTH\r
185 not_minus:      JKEYNP  kGREY_PLUS,not_plus\r
186                 cmp     scroll_speed_x,16\r
187                 jge     not_plus\r
188                 inc     scroll_speed_x\r
189                 add     scroll_speed_y,VIRTUAL_WIDTH\r
190 not_plus:\r
191 \r
192 pause_key:      JKEYP   kP,pause_key\r
193 \r
194                 ret\r
195 KprocDirect     ENDP\r
196 \r
197 ;; This keyproc has inertia, so + and - don't work.\r
198 ;; Use up/down/left/right keys to increase speed in those directions.\r
199 ;; Pressing K will switch to the other keyprocedure on the fly.\r
200 ;; P pauses the screen -- note that this is just for completely\r
201 ;; freezing the screen... it doesn't return until you let go!\r
202 KprocInertia    PROC    near\r
203 chk2_leftright: JKEYNP  kRIGHT,not2_right\r
204                 cmp     ScrollDX,16\r
205                 je      not2_right\r
206                 inc     ScrollDX\r
207                 jmp     chk2_updown\r
208 not2_right:     JKEYNP  kLEFT,not2_left\r
209                 cmp     ScrollDX,-16\r
210                 je      not2_left\r
211                 dec     ScrollDX\r
212                 jmp     chk2_updown\r
213 not2_left:\r
214 \r
215 chk2_updown:    JKEYNP  kUP,not2_up\r
216                 cmp     ScrollDY,-VIRTUAL_WIDTH * 16\r
217                 je      not2_up\r
218                 add     ScrollDY,-VIRTUAL_WIDTH\r
219                 jmp     chk2_other\r
220 not2_up:        JKEYNP  kDOWN,not2_down\r
221                 cmp     ScrollDY,VIRTUAL_WIDTH * 16\r
222                 je      not2_down\r
223                 add     ScrollDY,VIRTUAL_WIDTH\r
224                 jmp     chk2_other\r
225 not2_down:\r
226 \r
227 chk2_other:     JKEYNP  kK,not2_k\r
228                 mov     kprocCur,KprocDirect\r
229 not2_k:         JKEYNP  kM,not2_m\r
230                 mov     bDoTransition,1\r
231 not2_m:\r
232 \r
233 pause2_key:     JKEYP   kP,pause2_key\r
234 \r
235                 ret\r
236 KprocInertia    ENDP\r
237 \1a