@@ -41,12 +41,9 @@ public class IOController
41
41
protected UnsignedByte samDisplayOffsetRegister ;
42
42
43
43
/* PIA1 */
44
- protected UnsignedByte pia1DRA ; /* PIA 1 Data Register A */
45
- protected UnsignedByte pia1CRA ; /* PIA 1 Control Register A */
46
- protected UnsignedByte pia1DDRA ; /* PIA 1 Data Direction Register A */
47
-
48
- protected UnsignedByte pia1DRB ;
49
- protected UnsignedByte pia1CRB ;
44
+ protected PIA1a pia1a ;
45
+ protected PIA1b pia1b ;
46
+ protected PIA2a pia2a ;
50
47
51
48
/* PIA2 */
52
49
protected UnsignedByte pia2DRA ; /* PIA 2 Data Register A */
@@ -79,12 +76,12 @@ public class IOController
79
76
/* The number of ticks to pass in 63.5 microseconds */
80
77
public static final int TIMER_63_5_MICROS = 56 ;
81
78
82
- /* The number of ticks to pass before poking disks */
83
- public static final int TIMER_DISK_COUNTER = 5000 ;
84
-
85
79
/* The number of ticks to pass in 16.6 milliseconds */
86
80
public static final int TIMER_16_6_MILLIS = 14833 ;
87
81
82
+ /* The number of ticks to pass before poking disks */
83
+ public static final int TIMER_DISK_COUNTER = 5000 ;
84
+
88
85
/* The number of ticks that is allowed to be processed in 0.89MHz mode and 1.78 MHz mode */
89
86
public static final int LOW_SPEED_CLOCK_FREQUENCY = 14917 ;
90
87
public static final int HIGH_SPEED_CLOCK_FREQUENCY = 29834 ;
@@ -106,13 +103,6 @@ public class IOController
106
103
107
104
public int verticalBorderTickValue ;
108
105
109
- /* PIA interrupt values */
110
- public int pia1FastTimer ;
111
- public int pia1SlowTimer ;
112
-
113
- public boolean pia1FastTimerEnabled ;
114
- public boolean pia1SlowTimerEnabled ;
115
-
116
106
public volatile int tickRefreshAmount ;
117
107
118
108
@@ -125,17 +115,16 @@ public IOController(Memory memory, RegisterSet registerSet, Keyboard keyboard, S
125
115
this .screen = screen ;
126
116
this .cassette = cassette ;
127
117
118
+ /* PIAs */
119
+ pia1a = new PIA1a (keyboard );
120
+ pia1b = new PIA1b (keyboard );
121
+ pia2a = new PIA2a (cassette );
122
+
128
123
/* Display registers */
129
124
verticalOffsetRegister = new UnsignedWord (0x0400 );
130
125
samDisplayOffsetRegister = new UnsignedByte (0x0 );
131
126
132
127
/* PIAs */
133
- pia1CRA = new UnsignedByte (0 );
134
- pia1DRA = new UnsignedByte (0 );
135
- pia1DDRA = new UnsignedByte (0 );
136
-
137
- pia1CRB = new UnsignedByte (0 );
138
- pia1DRB = new UnsignedByte (0 );
139
128
140
129
pia2CRA = new UnsignedByte (0 );
141
130
pia2DRA = new UnsignedByte (0 );
@@ -146,13 +135,13 @@ public IOController(Memory memory, RegisterSet registerSet, Keyboard keyboard, S
146
135
pia2DDRB = new UnsignedByte (0 );
147
136
148
137
/* Interrupts */
149
- irqStatus = new UnsignedByte (0 );
150
- firqStatus = new UnsignedByte (0 );
138
+ irqStatus = new UnsignedByte ();
139
+ firqStatus = new UnsignedByte ();
151
140
152
141
/* Timer related values */
153
142
timerTickThreshold = TIMER_63_5_MICROS ;
154
- timerResetValue = new UnsignedWord (0 );
155
- timerValue = new UnsignedWord (0 );
143
+ timerResetValue = new UnsignedWord ();
144
+ timerValue = new UnsignedWord ();
156
145
157
146
/* Disks */
158
147
diskDriveSelect = 0 ;
@@ -272,38 +261,69 @@ public UnsignedByte readIOByte(int address) {
272
261
switch (address ) {
273
262
/* PIA 1 Data Register A */
274
263
case 0xFF00 :
275
- /* Clear PIA 1 CRA bits 7 and 6 for interrupts */
276
- pia1CRA .and (~0xC0 );
277
- return keyboard .getHighByte (pia1DRB );
264
+ case 0xFF04 :
265
+ case 0xFF08 :
266
+ case 0xFF0C :
267
+ case 0xFF10 :
268
+ case 0xFF14 :
269
+ case 0xFF18 :
270
+ case 0xFF1C :
271
+ return pia1a .getRegister ();
278
272
279
273
/* PIA 1 Control Register A */
280
274
case 0xFF01 :
281
- return pia1CRA ;
275
+ case 0xFF05 :
276
+ case 0xFF09 :
277
+ case 0xFF0D :
278
+ case 0xFF11 :
279
+ case 0xFF15 :
280
+ case 0xFF19 :
281
+ case 0xFF1D :
282
+ return pia1a .getControlRegister ();
282
283
283
284
/* PIA 1 Data Register B */
284
285
case 0xFF02 :
285
- /* Clear PIA 1 CRB bits 7 and 6 for interrupts */
286
- pia1CRB .and (~0xC0 );
287
- return pia1DRB ;
286
+ case 0xFF06 :
287
+ case 0xFF0A :
288
+ case 0xFF0E :
289
+ case 0xFF12 :
290
+ case 0xFF16 :
291
+ case 0xFF1A :
292
+ case 0xFF1E :
293
+ return pia1b .getRegister ();
288
294
289
295
/* PIA 1 Control Register B */
290
296
case 0xFF03 :
291
- return pia1CRB ;
297
+ case 0xFF07 :
298
+ case 0xFF0B :
299
+ case 0xFF0F :
300
+ case 0xFF13 :
301
+ case 0xFF17 :
302
+ case 0xFF1B :
303
+ case 0xFF1F :
304
+ return pia1b .getControlRegister ();
292
305
293
306
/* PIA 2 Data Register A */
294
307
case 0xFF20 :
295
- if ( pia2CRA . isMasked ( 0x4 )) {
296
- pia2DRA . and ( 0 );
297
-
298
- /* Bit 0 = Cassette Data Input */
299
- pia2DRA . or ( cassette . nextBit ());
300
- return pia2DRA ;
301
- }
302
- return pia2DDRB ;
308
+ case 0xFF24 :
309
+ case 0xFF28 :
310
+ case 0xFF2C :
311
+ case 0xFF30 :
312
+ case 0xFF34 :
313
+ case 0xFF38 :
314
+ case 0xFF3C :
315
+ return pia2a . getRegister () ;
303
316
304
317
/* PIA 2 Control Register A */
305
318
case 0xFF21 :
306
- return pia2CRA ;
319
+ case 0xFF25 :
320
+ case 0xFF29 :
321
+ case 0xFF2D :
322
+ case 0xFF31 :
323
+ case 0xFF35 :
324
+ case 0xFF39 :
325
+ case 0xFF3D :
326
+ return pia2a .getControlRegister ();
307
327
308
328
/* PIA 2 DRB / DDRB */
309
329
case 0xFF22 :
@@ -447,7 +467,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
447
467
case 0xFF14 :
448
468
case 0xFF18 :
449
469
case 0xFF1C :
450
- pia1DRA = value . copy ( );
470
+ pia1a . setRegister ( value );
451
471
break ;
452
472
453
473
/* PIA 1 Control Register A */
@@ -459,17 +479,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
459
479
case 0xFF15 :
460
480
case 0xFF19 :
461
481
case 0xFF1D :
462
- /* Bit 0 = IRQ 63.5 microseconds */
463
- pia1FastTimerEnabled = value .isMasked (0x1 );
464
- pia1FastTimer = 0 ;
465
-
466
- /* Bit 1 = hi/lo edge trigger (ignored) */
467
-
468
- /* Bit 7 = IRQ triggered */
469
-
470
- pia1CRA = new UnsignedByte (value .getShort () +
471
- (pia1CRA .isMasked (0x80 ) ? 0x80 : 0 ) +
472
- (pia1CRA .isMasked (0x40 ) ? 0x40 : 0 ));
482
+ pia1a .setControlRegister (value );
473
483
break ;
474
484
475
485
/* PIA 1 Data Register B */
@@ -481,7 +491,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
481
491
case 0xFF16 :
482
492
case 0xFF1A :
483
493
case 0xFF1E :
484
- pia1DRB = value . copy ( );
494
+ pia1b . setDataRegister ( value );
485
495
break ;
486
496
487
497
/* PIA 1 Control Register B */
@@ -493,17 +503,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
493
503
case 0xFF17 :
494
504
case 0xFF1B :
495
505
case 0xFF1F :
496
- /* Bit 0 = IRQ 16 milliseconds */
497
- pia1SlowTimerEnabled = value .isMasked (0x1 );
498
- pia1SlowTimer = 0 ;
499
-
500
- /* Bit 1 = hi/lo edge trigger (ignored) */
501
-
502
- /* Bit 7 = IRQ triggered */
503
-
504
- pia1CRB = new UnsignedByte (value .getShort () +
505
- (pia1CRB .isMasked (0x80 ) ? 0x80 : 0 ) +
506
- (pia1CRB .isMasked (0x40 ) ? 0x40 : 0 ));
506
+ pia1b .setControlRegister (value );
507
507
break ;
508
508
509
509
/* PIA 2 Data Register A / Data Direction Register A */
@@ -528,17 +528,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
528
528
case 0xFF35 :
529
529
case 0xFF39 :
530
530
case 0xFF3D :
531
- /* Bit 0 = FIRQ from serial I/O port */
532
-
533
- /* Bit 1 = hi/lo edge triggered */
534
-
535
- /* Bit 3 = Cassette Motor Control */
536
- if (value .isMasked (0x08 )) {
537
- cassette .motorOn ();
538
- } else {
539
- cassette .motorOff ();
540
- }
541
- pia2CRA = value .copy ();
531
+ pia2a .setControlRegister (value );
542
532
break ;
543
533
544
534
/* PIA 2 Data Register B / Data Direction Register B */
@@ -1212,29 +1202,11 @@ public void timerTick(int ticks) {
1212
1202
verticalBorderTickValue += ticks ;
1213
1203
1214
1204
/* Check for old interrupts via PIAs */
1215
- /* Increment pia1FastTimer, trigger IRQ if interrupts on, otherwise just write to pia1CRA */
1216
- pia1FastTimer += ticks ;
1217
- if (pia1FastTimer >= TIMER_63_5_MICROS ) {
1218
- if (pia1FastTimerEnabled ) {
1219
- if (!regs .cc .isMasked (CC_I ) && !pia1CRA .isMasked (0x80 )) {
1220
- cpu .scheduleIRQ ();
1221
- }
1222
- }
1223
- pia1CRA .or (0x80 );
1224
- pia1FastTimer = 0 ;
1225
- }
1205
+ /* Increment pia1 FastTimer, trigger IRQ if interrupts on */
1206
+ pia1a .addTicks (ticks , cpu , regs );
1226
1207
1227
- /* Increment pia1SlowTimer, trigger IRQ if interrupts on, otherwise, just write to pia1CRB */
1228
- pia1SlowTimer += ticks ;
1229
- if (pia1SlowTimer >= TIMER_16_6_MILLIS ) {
1230
- if (pia1SlowTimerEnabled ) {
1231
- if (!regs .cc .isMasked (CC_I ) && !pia1CRB .isMasked (0x80 )) {
1232
- cpu .scheduleIRQ ();
1233
- }
1234
- }
1235
- pia1CRB .or (0x80 );
1236
- pia1SlowTimer = 0 ;
1237
- }
1208
+ /* Increment pia1 SlowTimer, trigger IRQ if interrupts on */
1209
+ pia1b .addTicks (ticks , cpu , regs );
1238
1210
1239
1211
/* Check for GIME timer related interrupts */
1240
1212
if (timerTickCounter >= timerTickThreshold ) {
0 commit comments