forked from caseywdunn/eater_6502
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvid15_keyboard.s
295 lines (251 loc) · 5.22 KB
/
vid15_keyboard.s
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
; Define port addresses
PORTB = 0x6000 ; Port B address
PORTA = 0x6001 ; Port A address
DDRB = 0x6002 ; Data Direction Register for Port B
DDRA = 0x6003 ; Data Direction Register for Port A
PCR = 0x600c ; Peripheral Control Register
IFR = 0x600d ; Interrupt Flag Register
IER = 0x600e ; Interrupt Enable Register
kb_wptr = 0x0000
kb_rptr = 0x0001
kb_flags = 0x0002
RELEASE = 0b00000001
SHIFT = 0b00000010
kb_buffer = 0x0200 ;256 byte kb buffer 0200-02ff
E = 0b10000000 ; Enable bit for LCD
RW = 0b01000000 ; Read/Write (0 = write)
RS = 0b00100000 ; Register Select for LCD
; Reset
.org 0x8000 ; Set reset vector starting location
reset:
; Initialize stack pointer
ldx #0xff
txs
cli ; Clear interrupt disable flag
lda #01
sta PCR ; Enable Peripheral Control Register
lda #0x82
sta IER ; Set interrupt enable
; Configure Port B pins as output
lda #0b11111111
sta DDRB
; Configure Port A pins as input
lda #0b00000000
sta DDRA
jsr lcd_init
; LCD Display configuration
lda #0b00101000 ; 4-bit mode, 2 lines, 5x8 font
jsr lcd_instruction
lda #0b00001111 ; Display ON, cursor OFF
jsr lcd_instruction
lda #0b00000110 ; Set entry mode
jsr lcd_instruction
lda #0b00000001 ; Clear display
jsr lcd_instruction
lda #0x00
sta kb_rptr
sta kb_wptr
sta kb_flags
loop:
sei
lda kb_rptr
cmp kb_wptr
cli
bne key_pressed
jmp loop
key_pressed
ldx kb_rptr
lda kb_buffer, x
jsr print_char
inc kb_rptr
jmp loop
lcd_wait:
pha
lda #0b11110000 ; Set Port B to output mode for control signals
sta DDRB
lcd_busy:
lda #RW ; Set RW for read mode
sta PORTB
lda #(RW | E) ; Set RW and Enable bits
sta PORTB
lda PORTB
pha
lda #RW
sta PORTB
lda #(RW | E)
sta PORTB
lda PORTB
pla
and #0b00001000 ; Check busy flag
bne lcd_busy ; Wait if busy flag is set
lda #RW
sta PORTB ; Clear control bits
lda #0b11111111 ; Set Port B to output mode
sta DDRB
pla
rts
lcd_init:
lda #%00000011 ; Set 8-bit mode (first initialization)
sta PORTB
ora #E
sta PORTB
and #%00001111
sta PORTB
lda #%00000011 ; Set 8-bit mode (second initialization)
sta PORTB
ora #E
sta PORTB
and #%00001111
sta PORTB
lda #%00000011 ; Set 8-bit mode (third initialization)
sta PORTB
ora #E
sta PORTB
and #%00001111
sta PORTB
lda #%00000010 ; Set 4-bit mode
sta PORTB
ora #E
sta PORTB
and #%00001111
sta PORTB
rts
lcd_instruction:
jsr lcd_wait
pha
lsr
lsr
lsr
lsr
sta PORTB
ora #E
sta PORTB
eor #E
sta PORTB
pla
and #%00001111
sta PORTB
ora #E
sta PORTB
eor #E
sta PORTB
rts
print_char:
jsr lcd_wait
pha
lsr
lsr
lsr
lsr
ora #RS
sta PORTB
ora #E
sta PORTB
eor #E
sta PORTB
pla
and #%00001111
ora #RS
sta PORTB
ora #E
sta PORTB
eor #E
sta PORTB
rts
keyboard_interrupt:
pha
txa
pha
lda kb_flags
and #RELEASE
beq read_key
lda kb_flags ; can skip loading again
eor #RELEASE
sta kb_flags
lda PORTA
cmp #0x12
beq shift_up
cmp #0x59
beq shift_up
jmp exit
shift_up
lda kb_flags
eor #SHIFT
sta kb_flags
jmp exit
read_key:
lda PORTA
cmp #0xf0
beq key_release
cmp #0x12
beq shift_down
cmp #059
beq shift_down
tax
lda kb_flags
and #SHIFT
bne shifted_key
lda keymap, x
jmp push_key
shifted_key:
lda keymap_shifted, x
push_key:
ldx kb_wptr
sta kb_buffer, x
inc kb_wptr
jmp exit
shift_down
lda kb_flags
ora #SHIFT
sta kb_flags
jmp exit
key_release:
lda kb_flags
ora #RELEASE
sta kb_flags
exit:
pla
tax
pla
rti
nmi:
rti
.org 0xfd00
keymap:
.byte "????????????? `?" ; 00-0F
.byte "?????q1???zsaw2?" ; 10-1F
.byte "?cxde43?? vftr5?" ; 20-2F
.byte "?nbhgy6???mju78?" ; 30-3F
.byte "?,kio09??./l;p-?" ; 40-4F
.byte "??'?[=?????]?\??" ; 50-5F
.byte "?????????1?47???" ; 60-6F
.byte "0.2568???+3-*9??" ; 70-7F
.byte "????????????????" ; 80-8F
.byte "????????????????" ; 90-9F
.byte "????????????????" ; A0-AF
.byte "????????????????" ; B0-BF
.byte "????????????????" ; C0-CF
.byte "????????????????" ; D0-DF
.byte "????????????????" ; E0-EF
.byte "????????????????" ; F0-FF
keymap_shifted:
.byte "????????????? ~?" ; 00-0F
.byte "?????Q!???ZSAW@?" ; 10-1F
.byte "?CXDE#$?? VFTR%?" ; 20-2F
.byte "?NBHGY^???MJU&*?" ; 30-3F
.byte "?<KIO)(??>?L:P_?" ; 40-4F
.byte '??"?{+?????}?|??' ; 50-5F
.byte "?????????1?47???" ; 60-6F
.byte "0.2568???+3-*9??" ; 70-7F
.byte "????????????????" ; 80-8F
.byte "????????????????" ; 90-9F
.byte "????????????????" ; A0-AF
.byte "????????????????" ; B0-BF
.byte "????????????????" ; C0-CF
.byte "????????????????" ; D0-DF
.byte "????????????????" ; E0-EF
.byte "????????????????" ; F0-FF
.org 0xfffa
.word nmi
.word reset
.word keyboard_interrupt