/[projet1]/public/oric/routines/keyboard/keyboard.s
Defence Force logotype

Contents of /public/oric/routines/keyboard/keyboard.s

Parent Directory Parent Directory | Revision Log Revision Log


Revision 324 - (show annotations)
Wed Apr 28 17:11:15 2010 UTC (9 years, 7 months ago) by Chema
File size: 6548 byte(s)


1
2 ; Example program for reading the Oric's
3 ; keyboard. All keys are scanned and a
4 ; virtual matrix of 8 bytes is updated at
5 ; each IRQ.
6 ;
7 ; Idea: Dbug
8 ; Main code: Twiligthe
9 ; Adaptation & final implementation: Chema
10 ;
11 ; 2010
12
13
14 #define via_portb $0300
15 #define via_ddrb $0302
16 #define via_ddra $0303
17 #define via_t1cl $0304
18 #define via_t1ch $0305
19 #define via_t1ll $0306
20 #define via_t1lh $0307
21 #define via_t2ll $0308
22 #define via_t2ch $0309
23 #define via_sr $030A
24 #define via_acr $030b
25 #define via_pcr $030c
26 #define via_ifr $030D
27 #define via_ier $030E
28 #define via_porta $030f
29
30
31 .zero
32 irq_A .byt 0
33 irq_X .byt 0
34 irq_Y .byt 0
35 zpTemp01 .byt 0
36 zpTemp02 .byt 0
37 tmprow .byt 0
38
39 .text
40
41 #define ROM
42
43 #ifdef ROM
44 #define IRQ_ADDRLO $0245
45 #define IRQ_ADDRHI $0246
46 #else
47 #define IRQ_ADDRLO $fffe
48 #define IRQ_ADDRHI $ffff
49 #endif
50
51
52 _InitISR
53 .(
54 ;Since we are starting from when the standard irq has already been
55 ;setup, we need not worry about ensuring one irq event and/or right
56 ;timer period, only redirecting irq vector to our own irq handler.
57 sei
58 ; Setup DDRA, DDRB and ACR
59 lda #%11111111
60 sta via_ddra
61 lda #%11110111 ; PB0-2 outputs, PB3 input.
62 sta via_ddrb
63 lda #%1000000
64 sta via_acr
65
66 ; Since this is an slow process, we set the VIA timer to
67 ; issue interrupts at 25Hz, instead of 100 Hz. This is
68 ; not necessary -- it depends on your needs
69 lda #<40000
70 sta via_t1ll
71 lda #>40000
72 sta via_t1lh
73
74 ; Patch IRQ vector
75 lda #<irq_routine
76 sta IRQ_ADDRLO
77 lda #>irq_routine
78 sta IRQ_ADDRHI
79 cli
80 rts
81 .)
82
83
84 ; The virtual Key Matrix
85 _KeyBank .dsb 8
86
87 irq_routine
88 .(
89 ;Preserve registers
90 sta irq_A
91 stx irq_X
92 sty irq_Y
93
94 ;Clear IRQ event
95 lda via_t1cl
96
97 ;Process keyboard
98 jsr ReadKeyboard
99
100 ;Restore Registers
101 lda irq_A
102 ldx irq_X
103 ldy irq_Y
104
105 ;End of IRQ
106 rti
107 .)
108
109
110
111 ReadKeyboard
112 .(
113 ;Write Column Register Number to PortA
114 lda #$0E
115 sta via_porta
116
117 ;Tell AY this is Register Number
118 lda #$FF
119 sta via_pcr
120
121 ; Clear CB2, as keeping it high hangs on some orics.
122 ; Pitty, as all this code could be run only once, otherwise
123 ldy #$dd
124 sty via_pcr
125
126 ldx #7
127
128 loop2 ;Clear relevant bank
129 lda #00
130 sta _KeyBank,x
131
132 ;Write 0 to Column Register
133
134 sta via_porta
135 lda #$fd
136 sta via_pcr
137 lda #$dd
138 sta via_pcr
139
140
141 lda via_portb
142 and #%11111000
143 stx zpTemp02
144 ora zpTemp02
145 sta via_portb
146
147
148 ;Wait 10 cycles for circuit to settle on new row
149 ;Use time to load inner loop counter and load Bit
150
151 ; CHEMA: Fabrice Broche uses 4 cycles (lda #8:inx) plus
152 ; the four cycles of the and absolute. That is 8 cycles.
153 ; So I guess that I could do the same here (ldy,lda)
154
155 ldy #$80
156 lda #8
157
158 ;Sense Row activity
159 and via_portb
160 beq skip2
161
162 ;Store Column
163 tya
164 loop1
165 eor #$FF
166
167 sta via_porta
168 lda #$fd
169 sta via_pcr
170 lda #$dd
171 sta via_pcr
172
173 lda via_portb
174 and #%11111000
175 stx zpTemp02
176 ora zpTemp02
177 sta via_portb
178
179
180 ;Use delay(10 cycles) for setting up bit in _KeyBank and loading Bit
181 tya
182 ora _KeyBank,x
183 sta zpTemp01
184 lda #8
185
186 ;Sense key activity
187 and via_portb
188 beq skip1
189
190 ;Store key
191 lda zpTemp01
192 sta _KeyBank,x
193
194 skip1 ;Proceed to next column
195 tya
196 lsr
197 tay
198 bcc loop1
199
200 skip2 ;Proceed to next row
201 dex
202 bpl loop2
203
204 rts
205 .)
206
207
208 ; Some more routines, not actualy needed, but quite useful
209 ; for reading a single key (get the first active bit in
210 ; the virtual matrix) and returning his ASCII value.
211 ; Should serve as an example about how to handle the keymap.
212 ; Both _ReadKey and _ReadKeyNoBounce can be used directly from
213 ; C, declared as:
214 ; extern char ReadKey()
215 ; extern char ReadKeyNoBounce()
216
217
218 ; Usually it is a good idea to keep 0 all the unused
219 ; entries, as it speeds up things. Z=1 means no key
220 ; pressed and there is no need to look in tables later on.
221
222 ; This keys don't have an ASCII code assigned, so we will
223 ; use consecutive values outside the usual alphanumeric
224 ; space.
225
226 #define KEY_UP 1
227 #define KEY_LEFT 2
228 #define KEY_DOWN 3
229 #define KEY_RIGHT 4
230
231 #define KEY_LCTRL 5
232 #define KET_RCTRL 6
233 #define KEY_LSHIFT 7
234 #define KEY_RSHIFT 8
235 #define KEY_FUNCT 9
236
237
238 ; This keys do have ASCII values, let's use them
239
240 #define KEY_RETURN $0d
241 #define KEY_ESC $1b
242 #define KEY_DEL $7f
243
244
245 tab_ascii
246 .asc "7","N","5","V",KET_RCTRL,"1","X","3"
247 .asc "J","T","R","F",0,KEY_ESC,"Q","D"
248 .asc "M","6","B","4",KEY_LCTRL,"Z","2","C"
249 .asc "K","9",59,"-",0,0,92,39
250 .asc " ",",",".",KEY_UP,KEY_LSHIFT,KEY_LEFT,KEY_DOWN,KEY_RIGHT
251 .asc "U","I","O","P",KEY_FUNCT,KEY_DEL,"]","["
252 .asc "Y","H","G","E",0,"A","S","W"
253 .asc "8","L","0","/",KEY_RSHIFT,KEY_RETURN,0,"="
254
255
256 ; Reads a key (single press, but repeating) and returns his ASCII value in reg X.
257 ; Z=1 if no keypress detected.
258 _ReadKey
259 .(
260 ldx #7
261 loop
262 lda _KeyBank,x
263 beq skip
264
265 ldy #$ff
266 loop2
267 iny
268 lsr
269 bcc loop2
270 txa
271 asl
272 asl
273 asl
274 sty tmprow
275 clc
276 adc tmprow
277 tax
278 lda tab_ascii,x
279 tax
280 rts
281 skip
282 dex
283 bpl loop
284
285 ldx #0
286 rts
287 .)
288
289 ; Read a single key, same as before but no repeating.
290
291 oldKey .byt 0
292 _ReadKeyNoBounce
293 .(
294 jsr _ReadKey
295 cpx oldKey
296 beq retz
297 stx oldKey
298 rts
299 retz
300 ldx #0
301 rts
302 .)
303
304

  ViewVC Help
Powered by ViewVC 1.1.26