-
Notifications
You must be signed in to change notification settings - Fork 0
/
1541.VIA1.asm
315 lines (302 loc) · 24.8 KB
/
1541.VIA1.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
; ------------------------------------------------------------------------------------------------------------- ;
; VIC 1541 - 6522 VIA1 chip register definitions
; ------------------------------------------------------------------------------------------------------------- ;
; VIA #1 Registers - $1800-$180F - Serial Bus Controller Port
; ------------------------------------------------------------------------------------------------------------- ;
VIA1 = $1800 ; Base address
; ------------------------------------------------------------------------------------------------------------- ;
; Two 8-bit bidirectional I/O ports (Port A and Port B)
; ------------------------------------------------------------------------------------------------------------- ;
SERCNT = VIA1 + $00 ; Serial Bus Controller
VIA1PB = SERCNT ; Data Port B (Serial Data I/O, ATN, CLOCK, Device #)
VIA1PB_DATIN = %00000001 ; DATA input from serial bus (inverted input line)
VIA1PB_DATOUT = %00000010 ; DATA output to serial bus (inverted output line)
VIA1PB_CLKIN = %00000100 ; CLOCK input from serial bus (inverted input line)
VIA1PB_CLKOUT = %00001000 ; CLOCK output to serial bus (inverted output line)
VIA1PB_ATNA = %00010000 ; ATTENTION Acknowledge output (attention acknowledge line)
; 1=enable device presence detection by
; automatically ACK each SERCNT_ATN signal on SERCNT_DATOUT
VIA1PB_ADR = %01100000 ; Device Address Preset DIP Switches (hardware device number)
VIA1PB_ADR_08 = %00000000 ; 00 = #8
VIA1PB_ADR_09 = %00100000 ; 01 = #9
VIA1PB_ADR_10 = %01000000 ; 10 = #10
VIA1PB_ADR_11 = %01100000 ; 11 = #11
VIA1PB_ATN = %10000000 ; ATTENTION input from serial bus
VIA1ORB = SERCNT ; output register B
VIA1ORB_PB0 = %00000000 ;
VIA1ORB_PB1 = %00000010 ;
VIA1ORB_PB2 = %00000100 ;
VIA1ORB_PB3 = %00001000 ;
VIA1ORB_PB4 = %00010000 ;
VIA1ORB_PB5 = %00100000 ;
VIA1ORB_PB6 = %01000000 ;
VIA1ORB_PB7 = %10000000 ;
VIA1IRB = SERCNT ; input register B
VIA1IRB_PB0 = %00000000 ;
VIA1IRB_PB1 = %00000010 ;
VIA1IRB_PB2 = %00000100 ;
VIA1IRB_PB3 = %00001000 ;
VIA1IRB_PB4 = %00010000 ;
VIA1IRB_PB5 = %00100000 ;
VIA1IRB_PB6 = %01000000 ;
VIA1IRB_PB7 = %10000000 ;
; ------------------------------------------------------------------------------------------------------------- ;
VIA1PA = VIA1 + $01 ; Data Port A - read to acknowledge interrupt generated by ATN IN going high
VIA1DATA = VIA1PA ;
VIA1ORA = VIA1PA ; output register A
VIA1ORA_PA0 = %00000001 ;
VIA1ORA_PA1 = %00000010 ;
VIA1ORA_PA2 = %00000100 ;
VIA1ORA_PA3 = %00001000 ;
VIA1ORA_PA4 = %00010000 ;
VIA1ORA_PA5 = %00100000 ;
VIA1ORA_PA6 = %01000000 ;
VIA1ORA_PA7 = %10000000 ;
VIA1IRA = VIA1PA ; input register A
VIA1IRA_PA0 = %00000001 ;
VIA1IRA_PA1 = %00000010 ;
VIA1IRA_PA2 = %00000100 ;
VIA1IRA_PA3 = %00001000 ;
VIA1IRA_PA4 = %00010000 ;
VIA1IRA_PA5 = %00100000 ;
VIA1IRA_PA6 = %01000000 ;
VIA1IRA_PA7 = %10000000 ;
; ------------------------------------------------------------------------------------------------------------- ;
; DDRB specify which pins within the port bus are to be designated as inputs or outputs
; Bit 0…7 = 0 - corresponding pin in PB acts as INPUT
; Bit 0…7 = 1 - corresponding pin in PB acts as OUTPUT
; ------------------------------------------------------------------------------------------------------------- ;
VIA1DDRB = VIA1 + $02 ; Data Direction Register Port B
VIA1DDRB_DATIN_OUT = %00000001 ; DATA input from serial bus (inverted input line)
VIA1DDRB_DATIN_IN = %11111110 ;
VIA1DDRB_DATOUT_OUT = %00000010 ; DATA output to serial bus (inverted output line)
VIA1DDRB_DATOUT_IN = %11111101 ;
VIA1DDRB_CLKIN_OUT = %00000100 ; CLOCK input from serial bus (inverted input line)
VIA1DDRB_CLKIN_IN = %11111011 ;
VIA1DDRB_CLKOUT_OUT = %00001000 ; CLOCK output to serial bus (inverted output line)
VIA1DDRB_CLKOUT_IN = %11110111 ;
VIA1DDRB_ATNA_OUT = %00010000 ; ATTENTION Acknowledge output (attention acknowledge line)
VIA1DDRB_ATNA_IN = %11101111 ;
VIA1DDRB_ADR_OUT = %01100000 ; Device Address Preset DIP Switches (hardware device number)
VIA1DDRB_ADR_IN = %10011111 ;
VIA1DDRB_ATN_OUT = %10000000 ; ATTENTION input from serial bus
VIA1DDRB_ATN_IN = %01111111 ;
VIA1DDRB_PB0 = %00000001 ; 0=Input 1=output
VIA1DDRB_PB1 = %00000010 ; 0=Input 1=output
VIA1DDRB_PB2 = %00000100 ; 0=Input 1=output
VIA1DDRB_PB3 = %00001000 ; 0=Input 1=output
VIA1DDRB_PB4 = %00010000 ; 0=Input 1=output
VIA1DDRB_PB5 = %00100000 ; 0=Input 1=output
VIA1DDRB_PB6 = %01000000 ; 0=Input 1=output
VIA1DDRB_PB7 = %10000000 ; 0=Input 1=output
VIA1DDRB_INI = VIA1DDRB_ATNA_OUT | VIA1DDRB_CLKOUT_OUT | VIA1DDRB_DATOUT_OUT ; ...##.#. ATN_IN / ADR_IN / CLK_IN / DAT_IN
; ------------------------------------------------------------------------------------------------------------- ;
; DDRA specifies which pins within the port bus are to be designated as inputs or outputs
; Bit 0…7 = 0 - corresponding pin in PA acts as INPUT
; Bit 0…7 = 1 - corresponding pin in PA acts as OUTPUT
; ------------------------------------------------------------------------------------------------------------- ;
VIA1DDRA = VIA1 + $03 ; Data Direction Register Port A
VIA1DDRA_PA0 = %00000001 ; 0=Input 1=output
VIA1DDRA_PA1 = %00000010 ; 0=Input 1=output
VIA1DDRA_PA2 = %00000100 ; 0=Input 1=output
VIA1DDRA_PA3 = %00001000 ; 0=Input 1=output
VIA1DDRA_PA4 = %00010000 ; 0=Input 1=output
VIA1DDRA_PA5 = %00100000 ; 0=Input 1=output
VIA1DDRA_PA6 = %01000000 ; 0=Input 1=output
VIA1DDRA_PA7 = %10000000 ; 0=Input 1=output
VIA1DDRA_INI = %11111111 ; $ff
; ------------------------------------------------------------------------------------------------------------- ;
; Interval Timer 1 (T1) consists of two 8-bit latches and a 16-bit counter
; the latches store data to be loaded into the counter
; the counter decrements at Phase 2 clock rate
; if reaching zero VIA1IFR_TI1 causing an Interrupt Request if VIA1IER_TI1 is set
; ------------------------------------------------------------------------------------------------------------- ;
VIA1T1CL = VIA1 + $04 ; Timer 1 Counter LO
; read low byte to (re)start timer upon underflow
VIA1T1CL_T1CL0 = %00000001 ; write=latches LO read=counter LO
VIA1T1CL_T1CL1 = %00000010 ; write=latches LO read=counter LO
VIA1T1CL_T1CL2 = %00000100 ; write=latches LO read=counter LO
VIA1T1CL_T1CL3 = %00001000 ; write=latches LO read=counter LO
VIA1T1CL_T1CL4 = %00010000 ; write=latches LO read=counter LO
VIA1T1CL_T1CL5 = %00100000 ; write=latches LO read=counter LO
VIA1T1CL_T1CL6 = %01000000 ; write=latches LO read=counter LO
VIA1T1CL_T1CL7 = %10000000 ; write=latches LO read=counter LO
; ------------------------------------------------------------------------------------------------------------- ;
VIA1T1CH = VIA1 + $05 ; Timer 1 Counter HI
; write high byte to (re)start timer upon underflow
VIA1T1CH_T1CH0 = %00000001 ; read/write=counter HI
VIA1T1CH_T1CH1 = %00000010 ; read/write=counter HI
VIA1T1CH_T1CH2 = %00000100 ; read/write=counter HI
VIA1T1CH_T1CH3 = %00001000 ; read/write=counter HI
VIA1T1CH_T1CH4 = %00010000 ; read/write=counter HI
VIA1T1CH_T1CH5 = %00100000 ; read/write=counter HI
VIA1T1CH_T1CH6 = %01000000 ; read/write=counter HI
VIA1T1CH_T1CH7 = %10000000 ; read/write=counter HI
; ------------------------------------------------------------------------------------------------------------- ;
VIA1T1LL = VIA1 + $06 ; Timer 1 Latches LO - read/write starting value of timer from/to here
VIA1T1LL_T1LL0 = %00000001 ; read/write=latch LO
VIA1T1LL_T1LL1 = %00000010 ; read/write=latch LO
VIA1T1LL_T1LL2 = %00000100 ; read/write=latch LO
VIA1T1LL_T1LL3 = %00001000 ; read/write=latch LO
VIA1T1LL_T1LL4 = %00010000 ; read/write=latch LO
VIA1T1LL_T1LL5 = %00100000 ; read/write=latch LO
VIA1T1LL_T1LL6 = %01000000 ; read/write=latch LO
VIA1T1LL_T1LL7 = %10000000 ; read/write=latch LO
; ------------------------------------------------------------------------------------------------------------- ;
VIA1T1LH = VIA1 + $07 ; Timer 1 Latches HI - read/write starting value of timer from/to here
VIA1T1LH_T1HL0 = %00000001 ; read/write=latch HI
VIA1T1LH_T1HL1 = %00000010 ; read/write=latch HI
VIA1T1LH_T1HL2 = %00000100 ; read/write=latch HI
VIA1T1LH_T1HL3 = %00001000 ; read/write=latch HI
VIA1T1LH_T1HL4 = %00010000 ; read/write=latch HI
VIA1T1LH_T1HL5 = %00100000 ; read/write=latch HI
VIA1T1LH_T1HL6 = %01000000 ; read/write=latch HI
VIA1T1LH_T1HL7 = %10000000 ; read/write=latch HI
; ------------------------------------------------------------------------------------------------------------- ;
; Timer 2 (T2) operates in One-Shot Mode only (as an interval timer) or as a pulse counter for counting negative pulses on PB6
; ------------------------------------------------------------------------------------------------------------- ;
VIA1T2CL = VIA1 + $08 ; Timer 2 Counter LO (unused)
VIA1T2CL_T2CL0 = %00000001 ; write=latches LO read=counter LO
VIA1T2CL_T2CL1 = %00000010 ; write=latches LO read=counter LO
VIA1T2CL_T2CL2 = %00000100 ; write=latches LO read=counter LO
VIA1T2CL_T2CL3 = %00001000 ; write=latches LO read=counter LO
VIA1T2CL_T2CL4 = %00010000 ; write=latches LO read=counter LO
VIA1T2CL_T2CL5 = %00100000 ; write=latches LO read=counter LO
VIA1T2CL_T2CL6 = %01000000 ; write=latches LO read=counter LO
VIA1T2CL_T2CL7 = %10000000 ; write=latches LO read=counter LO
; ------------------------------------------------------------------------------------------------------------- ;
VIA1T2CH = VIA1 + $09 ; Timer 2 Counter HI (unused)
VIA1T2CH_T2CH0 = %00000001 ; read/write=counter LO
VIA1T2CH_T2CH1 = %00000010 ; read/write=counter LO
VIA1T2CH_T2CH2 = %00000100 ; read/write=counter LO
VIA1T2CH_T2CH3 = %00001000 ; read/write=counter LO
VIA1T2CH_T2CH4 = %00010000 ; read/write=counter LO
VIA1T2CH_T2CH5 = %00100000 ; read/write=counter LO
VIA1T2CH_T2CH6 = %01000000 ; read/write=counter LO
VIA1T2CH_T2CH7 = %10000000 ; read/write=counter LO
; ------------------------------------------------------------------------------------------------------------- ;
VIA1SR = VIA1 + $0a ; Shift Register (unused)
; ------------------------------------------------------------------------------------------------------------- ;
VIA1ACR = VIA1 + $0b ; Auxiliary Control Register
VIA1ACR_LATCH = %00000011 ; LATCH enable/disable
VIA1ACR_LATCH_PA = %00000001 ; Control latching PA
VIA1ACR_LATCH_PA_ENA = %00000001 ; 1=enable latching PA
VIA1ACR_LATCH_PA_DISA = %11111110 ; 0=disable latching PA
VIA1ACR_LATCH_PB = %00000010 ; Control latching PB
VIA1ACR_LATCH_PB_ENA = %00000010 ; 1=enable latching PB
VIA1ACR_LATCH_PB_DISA = %11111101 ; 0=disable latching PB
VIA1ACR_SHFT = %00011100 ; Shift Register Control
VIA1ACR_SHFT_I_DISA = %00000000 ; 000 - SR Mode 0: Shift register disabled
VIA1ACR_SHFT_I_TI2 = %00000100 ; 001 - SR Mode 1: Shift in under TI2 control
VIA1ACR_SHFT_I_PHI2 = %00001000 ; 010 - SR Mode 2: Shift in under Phi2 control
VIA1ACR_SHFT_I_CB1 = %00001100 ; 011 - SR Mode 3: Shift in under CB1 control (external clock)
VIA1ACR_SHFT_O_FRE = %00010000 ; 100 - SR Mode 4: Shift out under TI2 control (free-running at TI2 rate)
VIA1ACR_SHFT_O_TI2 = %00010100 ; 101 - SR Mode 5: Shift out under TI2 control
VIA1ACR_SHFT_O_PHI2 = %00011000 ; 110 - SR Mode 6: Shift out under Phi2 control
VIA1ACR_SHFT_O_CB1 = %00011100 ; 111 - SR Mode 7: Shift out under CB1 control (external clock)
VIA1ACR_T2 = %00100000 ; Timer 2 Control
VIA1ACR_T2_PULSE = %00100000 ; 1=Count Down with incoming Pulses on PB6
VIA1ACR_T2_TIMED = %11011111 ; 0=Timed Interrupt - single interval timing
VIA1ACR_T1 = %11000000 ; Timer 1 Control
VIA1ACR_T1_OS = %00000000 ; 00=Timed Interrupt each time Timer 1 is loaded - one-shot - no PB7 output pulses
VIA1ACR_T1_FRE = %01000000 ; 01=Continuous Interrupts - free run - no PB7 output pulses
VIA1ACR_T1_OSPB7 = %10000000 ; 10=Timed Interrupt each time Timer 1 is loaded - one-shot on PB7 (negative pulses)
VIA1ACR_T1_FREPB7 = %11000000 ; 11=Continuous Interrupts - free run on PB7 (square-wave: invert last pulse)
; ------------------------------------------------------------------------------------------------------------- ;
VIA1PCR = VIA1 + $0c ; Peripheral Control Register
VIA1PCR_CA1_INT = %00000001 ; Bit 0: CA1 Line Control - Interrupt Control
VIA1PCR_CA1_INT_NEG = %11111110 ; 0=CA1 input on falling edge (Negative active edge)
; VIA1IFR_CA1 is set on a high to low transition of CA1
VIA1PCR_CA1_INT_POS = %00000001 ; 1=CA1 input on rising edge (Positive active edge)
; VIA1IFR_CA1 is set on a low to high transition of CA1
; ------------------------------------------------------------------------------ ;
VIA1PCR_CA2 = %00001110 ; Bit 1…3: CA2 Control
VIA1PCR_CA2_NEG = %00000000 ; Input - Negative active edge
VIA1PCR_CA2_NEGI = %00000010 ; Input - Negative edge Independent Interrupt
VIA1PCR_CA2_POS = %00000100 ; Input - Positive active edge
VIA1PCR_CA2_POSI = %00000110 ; Input - Positive edge Independent Interrupt
VIA1PCR_CA2_HDS = %00001000 ; Output - Handshake
VIA1PCR_CA2_PULS = %00001010 ; Output - Pulse
VIA1PCR_CA2_LO = %00001100 ; Output - Low
VIA1PCR_CA2_HI = %00001110 ; Output - High
; ------------------------------------------------------------------------------ ;
VIA1PCR_CB1_INT = %00010000 ; Bit 4: CB1 Line Control - Interrupt Control
; used to accept an interrupt for received data
VIA1PCR_CB1_INT_NEG = %11101111 ; 0=CA2 input on falling edge (Negative active edge)
; VIA1IFR_CB1 is set on a high to low transition of CB1
VIA1PCR_CB1_INT_POS = %00010000 ; 1=CA2 input on rising edge (Positive active edge)
; VIA1IFR_CB1 is set on a low to high transition of CB1
; ------------------------------------------------------------------------------ ;
VIA1PCR_CB2 = %11100000 ; Bits 5…7: CB2 Line Control
VIA1PCR_CB2_NEG = %00000000 ; Input - Negative active edge
VIA1PCR_CB2_NEGI = %00100000 ; Input - Negative edge Independent Interrupt
VIA1PCR_CB2_POS = %01000000 ; Input - Positive active edge
VIA1PCR_CB2_POSI = %01100000 ; Input - Positive edge Independent Interrupt
VIA1PCR_CB2_HDS = %10000000 ; Output - Handshake
VIA1PCR_CB2_PULS = %10100000 ; Output - Pulse
VIA1PCR_CB2_LO = %11000000 ; Output - Low
VIA1PCR_CB2_HI = %11100000 ; Output - High
; ------------------------------------------------------------------------------------------------------------- ;
VIA1IFR1 = VIA1 + $0d ; Interrupt Flag Register
; indicate which IFR flags should cause a VIA IRQ to the 6502 IRQ line
VIA1IFR_CA2 = %00000001 ; Set by: CA2 active edge Cleared by: Read or Write PA
VIA1IFR_CA1 = %00000010 ; Set by: CA1 active edge Cleared by: Read or Write PA
VIA1IFR_SHIFT = %00000100 ; Set by: 8 Shifts completed Cleared by: Read or Write Shift register
VIA1IFR_CB2 = %00001000 ; Set by: CB2 active edge Cleared by: Read or Write PB
VIA1IFR_CB1 = %00010000 ; Set by: CB1 active edge Cleared by: Read or Write PB
VIA1IFR_TI2 = %00100000 ; Set by: Time-Out (underflow) Timer 2 Cleared by: Read TI2 Low or Write TI2 High
VIA1IFR_TI1 = %01000000 ; Set by: Time-Out (underflow) Timer 1 Cleared by: Read TI1 Low or Write TI1 High
VIA1IFR_INT = %10000000 ; Set by: Any Enabled Interrupt occurred Cleared by: Set IFR1_INT to 0
; Clear all interrupt flags in IFR
; ------------------------------------------------------------------------------------------------------------- ;
VIA1IER = VIA1 + $0e ; Interrupt Enable Register
; Indicate which IFR flags should cause a VIA IRQ to the 6502 IRQ line
; Note: The whole byte must be set at once
; changing a particular bit individually with AND/OR will have no effect
VIA1IER_CA2 = %00000001 ; CA2
VIA1IER_CA1 = %00000010 ; CA1
VIA1IER_SHIFT = %00000100 ; Shift Register
VIA1IER_CB2 = %00001000 ; CB2
VIA1IER_CB1 = %00010000 ; CB1
VIA1IER_TI2 = %00100000 ; Timer 2
VIA1IER_TI1 = %01000000 ; Timer 1
VIA1IER_ENAB = %10000000 ; write: 1=Set Interrupt Flags
; bits 0…6: each 1 enables the corresponding interrupt
; bits 0…6: each 0 leaves the corresponding interrupt bit unaffected
VIA1IER_CLR = %01111111 ; 0=Clear Interrupt Flags
; bits 0…6: each 1 disables the corresponding interrupt
; bits 0…6: each 0 leaves the corresponding interrupt bit unaffected
; read: bit 7: will allways be 1 but can in fact be a 0
; it takes an explicit write to to insure its state
; bits 0…6: reflect their ENABLE/DISABLE start
; ------------------------------------------------------------------------------------------------------------- ;
VIA1PAN = VIA1 + $0f ; Data Port A - same as PA except no handshake will be initiated
; i.e. the CAl and CA2 control lines are not affected (unused)
VIA1ORAN = VIA1PAN ; Output Register A
VIA1ORAN_PA0 = %00000001 ;
VIA1ORAN_PA1 = %00000010 ;
VIA1ORAN_PA2 = %00000100 ;
VIA1ORAN_PA3 = %00001000 ;
VIA1ORAN_PA4 = %00010000 ;
VIA1ORAN_PA5 = %00100000 ;
VIA1ORAN_PA6 = %01000000 ;
VIA1ORAN_PA7 = %10000000 ;
VIA1POTA = VIA1PAN ; Output Register A
VIA1POTA_PA0 = %00000001 ;
VIA1POTA_PA1 = %00000010 ;
VIA1POTA_PA2 = %00000100 ;
VIA1POTA_PA3 = %00001000 ;
VIA1POTA_PA4 = %00010000 ;
VIA1POTA_PA5 = %00100000 ;
VIA1POTA_PA6 = %01000000 ;
VIA1POTA_PA7 = %10000000 ;
VIA1IRAN = VIA1PAN ; Input Register A
VIA1IRNA_PA0 = %00000001 ;
VIA1IRNA_PA1 = %00000010 ;
VIA1IRNA_PA2 = %00000100 ;
VIA1IRNA_PA3 = %00001000 ;
VIA1IRNA_PA4 = %00010000 ;
VIA1IRNA_PA5 = %00100000 ;
VIA1IRNA_PA6 = %01000000 ;
VIA1IRNA_PA7 = %10000000 ;
; ------------------------------------------------------------------------------------------------------------- ;