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

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

Parent Directory Parent Directory | Revision Log Revision Log


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


1 Chema 322
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