-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathw65c265rom.asm
370 lines (309 loc) · 15.3 KB
/
w65c265rom.asm
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
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
;===============================================================================
; __ ____ ____ ____ ____ __ ____ ______ ______
; \ \ / / /_| ___| / ___|___ \ / /_| ___/ ___\ \/ / __ )
; \ \ /\ / / '_ \___ \| | __) | '_ \___ \___ \\ /| _ \
; \ V V /| (_) |__) | |___ / __/| (_) |__) |__) / \| |_) |
; \_/\_/ \___/____/ \____|_____|\___/____/____/_/\_\____/
;
; Power On Reset and Basic Vector Handling for the W65C265SXB Development Board
;-------------------------------------------------------------------------------
; Copyright (C)2015-2016 HandCoded Software Ltd.
; All rights reserved.
;
; This work is made available under the terms of the Creative Commons
; Attribution-NonCommercial-ShareAlike 4.0 International license. Open the
; following URL to see the details.
;
; http://creativecommons.org/licenses/by-nc-sa/4.0/
;
;===============================================================================
; Notes:
;
;
; This ROM takes control of the UART3 serial connection from the Mensch Monitor
; on startup.
;
;-------------------------------------------------------------------------------
pw 132
inclist on
chip 65816
include "w65c816.inc"
include "w65c265.inc"
include "w65c265sxb.inc"
;===============================================================================
; Configuration
;-------------------------------------------------------------------------------
; The BAUD_RATE constant defines the speed that W65C265 will configure UART3 at
; to communicate with the host PC. The Mensch Monitor works works at 9600 baud
; but if the ROM takes over complete control of the board it could be raised to
; a higher speed.
BAUD_RATE equ 9600 ; ACIA baud rate
BRG_VALUE equ OSC_FREQ/(16*BAUD_RATE)-1
if BRG_VALUE&$ffff0000
messg "BRG_VALUE does not fit in 16-bits"
endif
; The size of the UART RX and TX buffers. Currently a whole page is used for
; these.
BUFF_SIZE equ 126
;
TIMER0_HZ equ 1000
TIMER0_PR equ OSC_FREQ/TIMER0_HZ-1
if TIMER0_PR&$ffff0000
messg "TIMER0_PR does not fit in 16-bits"
endif
;===============================================================================
;-------------------------------------------------------------------------------
udata
TX_HEAD ds 1 ; Offsets to TX data
TX_TAIL ds 1
RX_HEAD ds 1 ; Offsets to RX data
RX_TAIL ds 1
TX_DATA ds BUFF_SIZE
RX_DATA ds BUFF_SIZE
;===============================================================================
; ROM Header
;-------------------------------------------------------------------------------
rom_header section offset $8000
db 'AJJ',0
jmp RESET
;===============================================================================
; Power On Reset
;-------------------------------------------------------------------------------
code
extern Start
longi off
longa off
RESET:
sei ; Disable interrupts
native ; Switch to native mode
long_i
ldx #$01ff ; Reset the stack
txs
lda #$80 ; Disable the WDC ROM
tsb BCR
stz TER ; Disable all interrupts
stz TIER
stz UIER
stz EIER
lda #<TIMER0_PR ; Initialise Timer 0
sta T0CL
lda #>TIMER0_PR
sta T0CH
lda #1<<0 ; Enable the timer
tsb TER
lda #1<<7 ; Set UART3 to use timer 3
trb TCR
lda #<BRG_VALUE ; And set baud rate
sta T3CL
lda #>BRG_VALUE
sta T3CH
lda #1<<3 ; Enable timer 3
tsb TER
lda #%00100101 ; Set UART3 for 8-N-1
sta ACSR3
lda #1<<6 ; Enable RX interrupt
tsb UIER
stz TX_HEAD ; Clear buffer offsets
stz TX_TAIL
stz RX_HEAD
stz RX_TAIL
; CTS/RTS pins
cli
jmp Start ; Jump to the application start
;===============================================================================
; UART Interface
;-------------------------------------------------------------------------------
; Appends the character in A to the transmit buffer. If the buffer is completely
; full then wait until a transmit interrupt has occurred before returning.
public UartTx
UartTx:
pha ; Save callers registers
phx
phy
php
short_ai
ldx TX_TAIL ; Append new data to buffer
sta TX_DATA,x
inx ; Bump and wrap the offset
cpx #BUFF_SIZE
bne $+4
ldx #0
TxLoop: cpx TX_HEAD ; Is the buffer completely full?
beq TxWait
stx TX_TAIL ; No, update the tail
lda #1<<7 ; Ensure TX interrupts enabled
tsb UIER
plp ; Restore callers registers
ply
plx
pla
rts ; Done
TxWait: wai ; Wait for an interrupt
bra TxLoop ; The check again
; Fetch the next character from the receive buffer waiting for some to arrive
; if the buffer is empty.
public UartRx
UartRx:
phx ; Save callers registers
phy
php
short_ai
RxLoop: ldx RX_HEAD ; Any data in the buffer?
cpx RX_TAIL
beq RxWait ; No, wait for some
lda RX_DATA,x ; Extract a byte
inx ; Bump and wrap offset
cpx #BUFF_SIZE
bne $+4
ldx #0
stx RX_HEAD ; Update the offset
plp ; Restore callers registers
ply
plx
rts ; Done
RxWait: wai ; Wait for an interrupt
bra RxLoop
; Check if the receive buffer contains any data and return C=1 if there is
; some.
public UartRxTest
UartRxTest:
pha ; Save callers registers
php
short_a
clc ; Assume buffer empty
lda RX_HEAD ; Compare offsets
eor RX_TAIL
beq $+3 ; Empty?
sec ; No, set C
rol a ; Save carry
plp
ror a ; Restore carry
pla ; Restore callers A
rts ; Done
;===============================================================================
; UART Interrupt Handlers
;-------------------------------------------------------------------------------
; Handle an RX interrupt for UART3. Append the recieved data to the tail of the
; buffer.
IRQAR3:
long_ai ; Save users registers
pha
phx
phy
short_ai
lda #1<<6 ; Clear the RX interrupt flag
trb UIFR
ldx RX_TAIL
lda ARTD3 ; Copy recieved byte to buffer
sta RX_DATA,X
inx ; Bump and wrap
cpx #BUFF_SIZE
bne $+4
ldx #0
cpx RX_HEAD ; Buffer already full?
beq $+5 ; Yes
stx RX_TAIL ; Update the tail
; RTS/CTS processing
long_ai ; Restore users registers
ply
plx
pla
rti ; Continue
; Handle a TX interrupt for UART3. If the buffer is empty then disable the
; interrupt until more data is added to the TX buffer.
IRQAT3:
long_ai ; Save users registers
pha
phx
phy
short_ai
ldx TX_HEAD ; Any data to transmit?
cpx TX_TAIL
bne IRQAT3Send ; Yes
lda #1<<7
trb UIER ; No, disable interrupt
bra IRQAT3Done
IRQAT3Send: lda TX_DATA,x ; Transmit the nex character
sta ARTD3
inx ; Bump and wrap offset
cpx #BUFF_SIZE
bne $+4
ldx #0
stx TX_HEAD ; Update the offset
IRQAT3Done: long_ai ; Restor users registers
ply
plx
pla
rti
;===============================================================================
; Vectors
;-------------------------------------------------------------------------------
UnusedVector: bra $
BadVector: bra $
native_vector section offset $ff80
dw UnusedVector ; Timer 0 Interrupt
dw UnusedVector ; Timer 1 Interrupt
dw UnusedVector ; Timer 2 Interrupt
dw UnusedVector ; Timer 3 Interrupt
dw UnusedVector ; Timer 4 Interrupt
dw UnusedVector ; Timer 5 Interrupt
dw UnusedVector ; Timer 6 Interrupt
dw UnusedVector ; Timer 7 Interrupt
dw UnusedVector ; Positive Edge Interrupt on P56
dw UnusedVector ; Negative Edge Interrupt on P57
dw UnusedVector ; Positive Edge Interrupt on P60
dw UnusedVector ; Positive Edge Interrupt on P62
dw UnusedVector ; Negative Edge Interrupt on P64
dw UnusedVector ; Negative Edge Interrupt on P66
dw UnusedVector ; Parallel Interface Bus (PIB) Interrupt
dw UnusedVector ; IRQ Level Interrupt
dw UnusedVector ; UART0 Receiver Interrupt
dw UnusedVector ; UART0 Transmitter Interrupt
dw UnusedVector ; UART1 Receiver Interrupt
dw UnusedVector ; UART1 Transmitter Interrupt
dw UnusedVector ; UART2 Receiver Interrupt
dw UnusedVector ; UART2 Transmitter Interrupt
dw IRQAR3 ; UART3 Receiver Interrupt
dw IRQAT3 ; UART3 Transmitter Interrupt
dw BadVector ; Reserved
dw BadVector ; Reserved
dw UnusedVector ; COP Software Interrupt
dw UnusedVector ; BRK Software Interrupt
dw UnusedVector ; ABORT Interrupt
dw UnusedVector ; Non-Maskable Interrupt
dw UnusedVector ; Reserved
dw UnusedVector ; Reserved
emulate_vectors section offset $ffc0
dw UnusedVector ; Timer 0 Interrupt
dw UnusedVector ; Timer 1 Interrupt
dw UnusedVector ; Timer 2 Interrupt
dw UnusedVector ; Timer 3 Interrupt
dw UnusedVector ; Timer 4 Interrupt
dw UnusedVector ; Timer 5 Interrupt
dw UnusedVector ; Timer 6 Interrupt
dw UnusedVector ; Timer 7 Interrupt
dw UnusedVector ; Positive Edge Interrupt on P56
dw UnusedVector ; Negative Edge Interrupt on P57
dw UnusedVector ; Positive Edge Interrupt on P60
dw UnusedVector ; Positive Edge Interrupt on P62
dw UnusedVector ; Negative Edge Interrupt on P64
dw UnusedVector ; Negative Edge Interrupt on P66
dw UnusedVector ; Parallel Interface Bus (PIB) Interrupt
dw UnusedVector ; IRQ Level Interrupt
dw UnusedVector ; UART0 Receiver Interrupt
dw UnusedVector ; UART0 Transmitter Interrupt
dw UnusedVector ; UART1 Receiver Interrupt
dw UnusedVector ; UART1 Transmitter Interrupt
dw UnusedVector ; UART2 Receiver Interrupt
dw UnusedVector ; UART2 Transmitter Interrupt
dw UnusedVector ; UART3 Receiver Interrupt
dw UnusedVector ; UART3 Transmitter Interrupt
dw BadVector ; Reserved
dw BadVector ; Reserved
dw UnusedVector ; COP Software Interrupt
dw BadVector ; Reserved
dw UnusedVector ; ABORT Interrupt
dw UnusedVector ; Non-Maskable Interrupt
dw RESET ; Reset
dw UnusedVector ; IRQ/BRK
end