9120e874 Andy McCall 25 days ago
1
2
3
4
5
#include " via.h"
6
#include " i2c.h"
7
#include " memory.h"
8
#include " serial.h"
9
#include < stdio.h>
10
#include < stdlib.h>
11
#include < time.h>
12
#include < string.h>
13
14
#include " glue.h"
15
#include " joystick.h"
16
17
typedef struct {
18
unsigned timer_count[ 2 ] ;
19
unsigned pb6_pulse_counts;
20
uint8_t registers[ 15 ] ;
21
bool timer1_m1;
22
bool timer_running[ 2 ] ;
23
bool pb7_output;
24
} via_t ;
25
26
static via_t via[ 2 ] ;
27
28
29
30
31
static void
32
via_init ( via_t * via )
33
{
34
35
for ( int i = 0 ; i < 4 ; i+ + ) via-> registers[ i] = 0 ;
36
for ( int i = 11 ; i < 15 ; i+ + ) via-> registers[ i] = 0 ;
37
via-> timer_running[ 0 ] = false ;
38
via-> timer_running[ 1 ] = false ;
39
via-> timer1_m1 = false ;
40
via-> pb7_output = true ;
41
}
42
43
static void
44
via_clear_pra_irqs ( via_t * via )
45
{
46
via-> registers[ 13 ] &= ~ 0x02 ;
47
if ( ( via-> registers[ 12 ] & 0b00001010) != 0b00000010) {
48
via-> registers[ 13 ] &= ~ 0x01 ;
49
}
50
}
51
52
static void
53
via_clear_prb_irqs ( via_t * via )
54
{
55
via-> registers[ 13 ] &= ~ 0x10 ;
56
if ( ( via-> registers[ 12 ] & 0b10100000) != 0b00100000) {
57
via-> registers[ 13 ] &= ~ 0x08 ;
58
}
59
}
60
61
static uint8_t
62
via_read ( via_t * via , uint8_t reg , bool debug )
63
{
64
uint8_t ifr;
65
bool irq;
66
switch ( reg) {
67
case 0 :
68
if ( ! debug) via_clear_prb_irqs ( via ) ;
69
return via-> registers[ 0 ] ;
70
case 1 :
71
case 15 :
72
if ( ! debug) via_clear_pra_irqs ( via ) ;
73
return via-> registers[ 1 ] ;
74
case 4 :
75
if ( ! debug) via-> registers[ 13 ] &= ~ 0x40 ;
76
return ( uint8_t ) ( via-> timer_count[ 0 ] & 0xff ) ;
77
case 5 :
78
return ( uint8_t ) ( via-> timer_count[ 0 ] >> 8 ) ;
79
case 8 :
80
if ( ! debug) via-> registers[ 13 ] &= ~ 0x20 ;
81
return ( uint8_t ) ( via-> timer_count[ 1 ] & 0xff ) ;
82
case 9 :
83
return ( uint8_t ) ( via-> timer_count[ 1 ] >> 8 ) ;
84
case 10 :
85
if ( ! debug) via-> registers[ 13 ] &= ~ 0x04 ;
86
return via-> registers[ 10 ] ;
87
case 13 :
88
ifr = via-> registers[ 13 ] ;
89
irq = ( ifr & via-> registers[ 14 ] ) != 0 ;
90
return ( ( uint8_t ) irq << 7 ) | ifr;
91
case 14 :
92
return via-> registers[ 14 ] | 0x80 ;
93
default :
94
return via-> registers[ reg] ;
95
}
96
}
97
98
static void
99
via_write ( via_t * via , uint8_t reg , uint8_t value )
100
{
101
switch ( reg) {
102
case 0 :
103
via_clear_prb_irqs ( via ) ;
104
via-> registers[ 0 ] = value;
105
break ;
106
case 1 :
107
case 15 :
108
via_clear_pra_irqs ( via ) ;
109
via-> registers[ 1 ] = value;
110
break ;
111
case 4 :
112
via-> registers[ 6 ] = value;
113
break ;
114
case 5 :
115
case 7 :
116
via-> registers[ 13 ] &= ~ 0x40 ;
117
via-> registers[ 7 ] = value;
118
if ( reg == 5 ) {
119
via-> timer_count[ 0 ] = ( ( unsigned ) value << 8 ) | via-> registers[ 6 ] ;
120
via-> timer_running[ 0 ] = true ;
121
via-> pb7_output = false ;
122
}
123
break ;
124
case 9 :
125
via-> registers[ 13 ] &= ~ 0x20 ;
126
via-> timer_count[ 1 ] = ( ( unsigned ) value << 8 ) | via-> registers[ 8 ] ;
127
via-> timer_running[ 1 ] = true ;
128
break ;
129
case 10 :
130
via-> registers[ 13 ] &= ~ 0x04 ;
131
via-> registers[ 10 ] = value;
132
break ;
133
case 13 :
134
via-> registers[ 13 ] &= ~ ( value & 0x7f ) ;
135
break ;
136
case 14 :
137
if ( value & 0x80 ) {
138
via-> registers[ 14 ] |= value & 0x7f ;
139
} else {
140
via-> registers[ 14 ] &= ~ value & 0x7f ;
141
}
142
break ;
143
default :
144
via-> registers[ reg] = value;
145
}
146
}
147
148
static void
149
via_step ( via_t * via , unsigned clocks )
150
{
151
152
153
uint8_t acr = via-> registers[ 11 ] ;
154
uint8_t ifr = via-> registers[ 13 ] ;
155
156
unsigned cnt;
157
uint32_t tclk, tclk_s, reload;
158
159
cnt = via-> timer_count[ 0 ] ;
160
tclk = clocks;
161
while ( tclk > 0 ) {
162
if ( via-> timer1_m1) {
163
reload = ( ( ( uint32_t ) via-> registers[ 7 ] << 8 ) | via-> registers[ 6 ] ) ;
164
tclk_s = reload + 1 ;
165
if ( tclk < tclk_s) tclk_s = tclk;
166
cnt = reload - tclk_s + 1 ;
167
via-> timer1_m1 = false ;
168
} else if ( cnt < tclk) {
169
if ( via-> timer_running[ 0 ] ) {
170
ifr |= 0x40 ;
171
via-> pb7_output ^= true ;
172
if ( ! ( acr & 0x40 ) ) via-> timer_running[ 0 ] = false ;
173
}
174
if ( tclk - cnt == 1 ) {
175
176
cnt = 0xffff ;
177
via-> timer1_m1 = true ;
178
tclk_s = 1 ;
179
} else {
180
reload = ( ( ( uint32_t ) via-> registers[ 7 ] << 8 ) | via-> registers[ 6 ] ) ;
181
tclk_s = cnt + reload + 2 ;
182
if ( tclk < tclk_s) tclk_s = tclk;
183
cnt += reload - tclk_s + 2 ;
184
}
185
} else {
186
cnt -= tclk;
187
break ;
188
}
189
tclk -= tclk_s;
190
}
191
via-> timer_count[ 0 ] = ( unsigned ) cnt;
192
193
cnt = via-> timer_count[ 1 ] ;
194
tclk = ( acr & 0x20 ) ? via-> pb6_pulse_counts : clocks;
195
via-> pb6_pulse_counts = 0 ;
196
if ( cnt < tclk) {
197
if ( via-> timer_running[ 1 ] ) {
198
ifr |= 0x20 ;
199
via-> timer_running[ 1 ] = false ;
200
}
201
via-> timer_count[ 1 ] = 0x10000 + cnt - tclk;
202
} else {
203
via-> timer_count[ 1 ] -= tclk;
204
}
205
206
207
208
via-> registers[ 13 ] = ifr;
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
void
236
via1_init ( )
237
{
238
via_init ( & via[ 0 ] ) ;
239
i2c_port. clk_in = 1 ;
240
serial_port. in . atn = 0 ;
241
serial_port. in . clk = 0 ;
242
serial_port. in . data = 0 ;
243
serial_port. out . clk = 1 ;
244
serial_port. out . data = 1 ;
245
}
246
247
uint8_t
248
via1_read ( uint8_t reg , bool debug )
249
{
250
251
252
253
254
switch ( reg) {
255
case 0 :
256
if ( ! debug) via_clear_prb_irqs ( & via[ 0 ] ) ;
257
if ( via[ 0 ] . registers [ 11 ] & 2 ) {
258
259
return 0 ;
260
} else {
261
return
262
( ~ via[ 0 ] . registers [ 2 ] & (
263
( serial_port_read_clk ( ) << 6 ) |
264
( serial_port_read_data ( ) << 7 )
265
) ) |
266
( via[ 0 ] . registers [ 2 ] & (
267
( serial_port. in . atn << 3 ) |
268
( ( ! serial_port. in . clk ) << 4 ) |
269
( ( ! serial_port. in . data ) << 5 )
270
) ) ;
271
}
272
273
case 1 :
274
case 15 :
275
276
277
278
if ( ! debug) {
279
i2c_step ( ) ;
280
via_clear_pra_irqs ( & via[ 0 ] ) ;
281
}
282
if ( via[ 0 ] . registers [ 11 ] & 1 ) {
283
284
return 0 ;
285
} else {
286
return ( ~ via[ 0 ] . registers [ 3 ] & i2c_port. data_out ) |
287
( via[ 0 ] . registers [ 3 ] & i2c_port. data_in ) |
288
( ~ via[ 0 ] . registers [ 3 ] & I2C_CLK_MASK ) |
289
( via[ 0 ] . registers [ 3 ] & i2c_port. clk_in ) |
290
Joystick_data;
291
}
292
293
default :
294
return via_read ( & via[ 0 ] , reg, debug) ;
295
}
296
}
297
298
void
299
via1_write ( uint8_t reg , uint8_t value )
300
{
301
via_write ( & via[ 0 ] , reg, value) ;
302
if ( reg == 0 || reg == 2 ) {
303
304
const uint8_t pb = via[ 0 ] . registers [ 0 ] | ~ via[ 0 ] . registers [ 2 ] ;
305
serial_port. in . atn = ( pb & SERIAL_ATNIN_MASK) != 0 ;
306
serial_port. in . clk = ( pb & SERIAL_CLOCKIN_MASK) == 0 ;
307
serial_port. in . data = ( pb & SERIAL_DATAIN_MASK) == 0 ;
308
309
} else if ( reg == 1 || reg == 3 ) {
310
i2c_step ( ) ;
311
312
const uint8_t pa = via[ 0 ] . registers [ 1 ] | ~ via[ 0 ] . registers [ 3 ] ;
313
i2c_port. data_in = pa & I2C_DATA_MASK;
314
i2c_port. clk_in = ( pa & I2C_CLK_MASK) >> 1 ;
315
joystick_set_latch ( via[ 0 ] . registers [ 1 ] & JOY_LATCH_MASK ) ;
316
joystick_set_clock ( via[ 0 ] . registers [ 1 ] & JOY_CLK_MASK ) ;
317
}
318
}
319
320
void
321
via1_step ( unsigned clocks )
322
{
323
via_step ( & via[ 0 ] , clocks) ;
324
}
325
326
bool
327
via1_irq ( )
328
{
329
return ( via[ 0 ] . registers [ 13 ] & via[ 0 ] . registers [ 14 ] ) != 0 ;
330
}
331
332
333
334
335
336
337
338
339
void
340
via2_init ( )
341
{
342
via_init ( & via[ 1 ] ) ;
343
}
344
345
uint8_t
346
via2_read ( uint8_t reg , bool debug )
347
{
348
return via_read ( & via[ 1 ] , reg, debug) ;
349
}
350
351
void
352
via2_write ( uint8_t reg , uint8_t value )
353
{
354
via_write ( & via[ 1 ] , reg, value) ;
355
}
356
357
void
358
via2_step ( unsigned clocks )
359
{
360
via_step ( & via[ 1 ] , clocks) ;
361
}
362
363
bool
364
via2_irq ( )
365
{
366
return ( via[ 1 ] . registers [ 13 ] & via[ 1 ] . registers [ 14 ] ) != 0 ;
367
}
368
369
370
371
void
372
via_debug_get_state ( int which , via_debug_state_t * out )
373
{
374
if ( which < 0 || which > 1 ) {
375
return ;
376
}
377
const via_t * v = & via[ which] ;
378
for ( int i = 0 ; i < 15 ; i+ + ) {
379
out-> regs[ i] = v-> registers[ i] ;
380
}
381
out-> timer_count[ 0 ] = ( uint16_t ) v-> timer_count[ 0 ] ;
382
out-> timer_count[ 1 ] = ( uint16_t ) v-> timer_count[ 1 ] ;
383
out-> timer_latch[ 0 ] = ( ( uint16_t ) v-> registers[ 7 ] << 8 ) | v-> registers[ 6 ] ;
384
out-> timer_latch[ 1 ] = v-> registers[ 8 ] ;
385
out-> timer_running[ 0 ] = v-> timer_running[ 0 ] ;
386
out-> timer_running[ 1 ] = v-> timer_running[ 1 ] ;
387
out-> timer1_m1 = v-> timer1_m1;
388
out-> pb7_output = v-> pb7_output;
389
}