-
Notifications
You must be signed in to change notification settings - Fork 4
/
keyboard.dasm16
317 lines (298 loc) · 7.65 KB
/
keyboard.dasm16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
; keyboard constants
.DEFINE DCPU_BACKSPACE 0x10
.DEFINE DCPU_RETURN 0x11
.DEFINE DCPU_INSERT 0x12
.DEFINE DCPU_DELETE 0x13
.DEFINE DCPU_UP 0x80
.DEFINE DCPU_DOWN 0x81
.DEFINE DCPU_LEFT 0x82
.DEFINE DCPU_RIGHT 0x83
.DEFINE DCPU_SHIFT 0x90
.DEFINE DCPU_CTRL 0x91
.DEFINE DCPU_STOP 0x1B
:RAM91 ; stop key flag
:STKEY DAT 0
:RAMC5 ; Code of last key pressed
:LSTX DAT 0
:RAMC6 ; Number of Characters in Keyboard Queue
:NDX DAT 0
; Handle keyboard interrupts by storing keystrokes in
; special RAM locations, where they'll be picked up by
; the clock interrupt.
:KEYASCII .DAT 0
; 0x01: shift
; 0x05: control
; this doesn't work on any known implementation yet
:KEYSHIFT .DAT 0
:RAM028A
:RPTFLAG DAT 0
:RAM028B
:KOUNT DAT REPEAT_FRAMES_B
:RAM028C
:DELAY DAT REPEAT_FRAMES_A
:RAM028D
:SHFLAG DAT 0
:RAM028E
:LSTSHF DAT 0
:RAM028F
:KEYLOG DAT 0 ; ROM?
;------------------------------------------------------
:LP2 ; get a character from the keyboard buffer
:ROME5B4 SET A, [KEYD]
SET X, 0
:ROME5B9 SET [KEYD+X], [KEYD+1+X]
ADD X, 1
IFN X, [NDX]
JMP ROME5B9
SUB [NDX], 1
IAQ 0
SET C, 0 ; no error
RTS
;-----------------------------------------------------------
; KEYBOARD INTERRUPT ROUTINE - triggered by keyboard events
; keeps a steady state of which keys are being held down.
; does not affect the keyboard buffer at all.
;-----------------------------------------------------------
:KEYINT
SET PUSH, B
SET PUSH, C
SET A, 2 ; check key
SET B, DCPU_CTRL
HWI [KEYBOARD]
SHL C, 2
SET [KEYSHIFT], C
SET A, 2 ; check key
SET B, DCPU_SHIFT
HWI [KEYBOARD]
BOR [KEYSHIFT], C
SET A, 1 ; get from queue
HWI [KEYBOARD]
IFG C, 0x9F ; strange high ascii in 0x10co.de
JSR HIGHASCII
IFL C, 0x90
SET [KEYASCII], C ; for scanning during clock interrupt
SET B, -1
IFE C, DCPU_STOP
SET B, 0x7F
SET [RAM91], B
;SET A, 2 ; check key
;SET B, [KEYASCII] ; original key
;; check for key-up event here
;HWI [KEYBOARD]
;IFE C, 0
; SET [KEYASCII], 0
SET C, POP
SET B, POP
RFI
; 0x10co.de + chrome gives us strange keystrokes
; where it adds 0x80 to them. this fixes most of them
; I hesitate to do anything else due to the probability
; that it won't work on non-US keyboards.
:HIGHASCII
SET A, C
SUB A, 0x80
IFB [KEYSHIFT], 1
JMP HIGHASCII_SHIFT
; translations without SHIFT
IFE A, 0x40
SET A, 0x5F ; underscore (leftarrow)
IFL A, 0x40
XOR A, 0x10 ; change ,-./ to <=>?
IFE A, 0x2B ; was a plus w/o shift key
ADD A, 18 ; equals sign
IFE A, 0x2A ; was a colon w/o shift key
ADD A, 17 ; semicolon
IFE A, 0x5E
SET A, 0x27 ; apostrophe
SET C, A
RTS
:HIGHASCII_SEMICOLON
ADD A, 1
:HIGHASCII_SHIFT
IFE A, 0x3B ; semicolon with shift key
SUB A, 0x10 ; is really a plus sign
IFE A, 0x5E
SET A, 0x22 ; double quote
IFE A, 0x40
SET A, 0x7E ; tilde (pi)
:HIGHASCII_END
SET C, A
RTS
:SCANSHIFT
; allow typing ( in 0x10co.de
IFE [KEYASCII], 0x81
SET [KEYASCII], 0x28
; allow typing & in 0x10co.de
IFE [KEYASCII], 0x80
SET [KEYASCII], 0x26
:SCANREG
SET Y, [KEYASCII]
IFL Y, 0x20
JMP SCANSPECIAL
IFB Y, 0x80
JMP SCANARROWS
IFE Y, 0x7E ; TILDE
JMP SCAN_PI
SET [SFDX], Y
; handle letter shifting
IFG Y, 0x60 ; lowercase letters
SUB [SFDX], 0x20 ; are "unshifted"
IFG Y, 0x40
IFL Y, 0x5B
ADD [SFDX], 0x80
RTS
:SCAN_PI
SET [SFDX], 0xFF
RTS
:SCANSPECIAL
SET [SFDX], CBM_RETURN
IFE Y, DCPU_INSERT
SET [SFDX], CBM_INSERT
IFE Y, DCPU_BACKSPACE
JMP SCAN_DELETE
IFN Y, DCPU_DELETE
JMP SCAN_NOT_DELETE
:SCAN_DELETE
IFC [SHFLAG], 1 ; unshifted
SET [SFDX], CBM_DELETE
IFB [SHFLAG], 1 ; shifted
SET [SFDX], CBM_INSERT
:SCAN_NOT_DELETE
RTS
:CTRL_COLORS
DAT 0x92, 0x90, 0x05, 0x1c, 0x9f, 0x9c, 0x1E, 0x1F, 0x9E, 0x12
:CBMKEY_COLORS
DAT 0x92, 0x81, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x12
:SCANCTRL
SET [SFDX], CBM_RETURN
SET Y, [KEYASCII]
SET A, CTRL_COLORS-0x30
ADD A, Y
IFG Y, 0x2F
IFL Y, 0x3A
SET [SFDX], [A]
; ctrl-letter
SET A, Y
AND A, 63
IFG A, 0
IFL A, 30
SET [SFDX], A
; lowercase mode with ctrl-n or ctrl-.
; uppercase mode with ctrl-,
IFE A, CBM_COMMA
SET [SFDX], 142
IFE A, 0x2E ; .
SET [SFDX], 14
IFE A, 0x3D ; =
SET [SFDX], 0x13 ; HOME
IFE A, 0x2D ; +
SET [SFDX], 0x93 ; CLR
RTS
; TODO: CBM-graphics characters
:SCANCBM
SET Y, [KEYASCII]
SET A, CBMKEY_COLORS-0x30
ADD A, Y
IFG Y, 0x2F
IFL Y, 0x39
SET [SFDX], [A]
SET A, Y
IFE A, 0x3D ; =
SET [SFDX], 0x93 ; CLR
IFE A, 0x2D ; +
SET [SFDX], 0x93 ; CLR
RTS
:SCANARROWS
IFE Y, DCPU_RIGHT
SET [SFDX], CBM_RIGHT
IFE Y, DCPU_DOWN
SET [SFDX], CBM_DOWN
IFE Y, DCPU_LEFT
SET [SFDX], CBM_LEFT
IFE Y, DCPU_UP
SET [SFDX], CBM_UP
RTS
;-----------------------------------------------------------
; KEYBOARD SCAN ROUTINE -- called every 1/60 of a second
;-----------------------------------------------------------
:ROMEA87
SET [SHFLAG], [KEYSHIFT]
SET [SFDX], 0x407F ; code for NO KEY PRESSED
IFE [KEYASCII], 0
JMP ROMEAE0
IFC [KEYSHIFT], 0x07 ; no shift-ctrl
JSR SCANREG
IFE [KEYSHIFT], 0x01 ; SHIFT only
JSR SCANSHIFT
IFE [KEYSHIFT], 0x04 ; CTRL only
JSR SCANCTRL
IFE [KEYSHIFT], 0x05 ; CBM (shift+ctrl)
JSR SCANCBM
:ROMEAE0
SET Y, [SFDX] ; key being pressed
SET A, Y ; [SFDX] contains the actual value, not scan code
SET X, A ; because EAE4 said so
IFE [SFDX], [LSTX]
JMP ROMEAF0
SET [RAM028C], REPEAT_FRAMES_A ; key repeat speed
; SET [RAM028B], REPEAT_FRAMES_B ; key repeat speed
JMP ROMEB26
:ROMEAF0
; clear shift bit so that we can test for
; a character and its shifted equivalent
; at the same tims.
SET Y, A
AND Y, 0x407F
:ROMEAF2
; handle key repeat logic
IFB [RAM028A], 0x80
JMP ROMEB0D ; repeat all characters
IFB [RAM028A], 0x40
RTS ; repeat no characters
IFB Y, 0x4000 ; no key pressed
JMP ROMEB26
; repeat only these characters
IFE Y, CBM_DELETE ;and insert
JMP ROMEB0D
; software-repeating space gets stuck in dtemu.
;IFE Y, 0x20 ; SPACE
; JMP ROMEB0D
IFE Y, CBM_RIGHT ; cursor right/left
JMP ROMEB0D
IFN Y, CBM_DOWN ; cursor up/down
RTS
:ROMEB0D ; repeat this key
IFE [RAM028C], 0
JMP ROMEB17
SUB [RAM028C], 1
IFN [RAM028C], 0
RTS
:ROMEB17
SUB [RAM028B], 1
IFN [RAM028B], 0
RTS
:ROMEB1C SET [RAM028B], REPEAT_FRAMES_B ; repeat speed
:ROMEB21
SET X, [NDX]
SUB X, 1
IFA X, -1 ; BPL
RTS
:ROMEB26 ; no key pressed
SET [LSTX], [SFDX]
IFN [LSTSHF], [0x01]
JMP SKIPSHIFTCBM
IFE SHFLAG, 0x05
JSR TOGGLEFONT ; why doesn't this work
:SKIPSHIFTCBM
SET [LSTSHF], [SHFLAG]
IFB A, 0x4000 ; no key pressed
RTS
:ROMEB35
SET X, [NDX]
IFG X, KEYBOARD_BUFFER_SIZE ; keyboard buffer overflow
RTS
:ROMEB3C ; Add A to keybuard queue
SET [KEYD+X], A
ADD [NDX], 1
:ROMEB47
RTS