Skip to content

Commit 849d14b

Browse files
committed
Refactor PIAs to be self-contained.
1 parent cd43b31 commit 849d14b

File tree

11 files changed

+882
-355
lines changed

11 files changed

+882
-355
lines changed

src/main/java/ca/craigthomas/yacoco3e/components/Cassette.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,10 @@ public Cassette() {
6767
}
6868

6969
/**
70-
* Turns the cassette motor off.
70+
* Turns the cassette motor on or off.
7171
*/
72-
public void motorOff() {
73-
motorOn = false;
74-
}
75-
76-
/**
77-
* Turns the cassette motor on.
78-
*/
79-
public void motorOn() {
80-
motorOn = true;
72+
public void setMotorOn(boolean turnOn) {
73+
motorOn = turnOn;
8174
}
8275

8376
public boolean isMotorOn() {

src/main/java/ca/craigthomas/yacoco3e/components/IOController.java

Lines changed: 72 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,9 @@ public class IOController
4141
protected UnsignedByte samDisplayOffsetRegister;
4242

4343
/* 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;
5047

5148
/* PIA2 */
5249
protected UnsignedByte pia2DRA; /* PIA 2 Data Register A */
@@ -79,12 +76,12 @@ public class IOController
7976
/* The number of ticks to pass in 63.5 microseconds */
8077
public static final int TIMER_63_5_MICROS = 56;
8178

82-
/* The number of ticks to pass before poking disks */
83-
public static final int TIMER_DISK_COUNTER = 5000;
84-
8579
/* The number of ticks to pass in 16.6 milliseconds */
8680
public static final int TIMER_16_6_MILLIS = 14833;
8781

82+
/* The number of ticks to pass before poking disks */
83+
public static final int TIMER_DISK_COUNTER = 5000;
84+
8885
/* The number of ticks that is allowed to be processed in 0.89MHz mode and 1.78 MHz mode */
8986
public static final int LOW_SPEED_CLOCK_FREQUENCY = 14917;
9087
public static final int HIGH_SPEED_CLOCK_FREQUENCY = 29834;
@@ -106,13 +103,6 @@ public class IOController
106103

107104
public int verticalBorderTickValue;
108105

109-
/* PIA interrupt values */
110-
public int pia1FastTimer;
111-
public int pia1SlowTimer;
112-
113-
public boolean pia1FastTimerEnabled;
114-
public boolean pia1SlowTimerEnabled;
115-
116106
public volatile int tickRefreshAmount;
117107

118108

@@ -125,17 +115,16 @@ public IOController(Memory memory, RegisterSet registerSet, Keyboard keyboard, S
125115
this.screen = screen;
126116
this.cassette = cassette;
127117

118+
/* PIAs */
119+
pia1a = new PIA1a(keyboard);
120+
pia1b = new PIA1b(keyboard);
121+
pia2a = new PIA2a(cassette);
122+
128123
/* Display registers */
129124
verticalOffsetRegister = new UnsignedWord(0x0400);
130125
samDisplayOffsetRegister = new UnsignedByte(0x0);
131126

132127
/* 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);
139128

140129
pia2CRA = new UnsignedByte(0);
141130
pia2DRA = new UnsignedByte(0);
@@ -146,13 +135,13 @@ public IOController(Memory memory, RegisterSet registerSet, Keyboard keyboard, S
146135
pia2DDRB = new UnsignedByte(0);
147136

148137
/* Interrupts */
149-
irqStatus = new UnsignedByte(0);
150-
firqStatus = new UnsignedByte(0);
138+
irqStatus = new UnsignedByte();
139+
firqStatus = new UnsignedByte();
151140

152141
/* Timer related values */
153142
timerTickThreshold = TIMER_63_5_MICROS;
154-
timerResetValue = new UnsignedWord(0);
155-
timerValue = new UnsignedWord(0);
143+
timerResetValue = new UnsignedWord();
144+
timerValue = new UnsignedWord();
156145

157146
/* Disks */
158147
diskDriveSelect = 0;
@@ -272,38 +261,69 @@ public UnsignedByte readIOByte(int address) {
272261
switch (address) {
273262
/* PIA 1 Data Register A */
274263
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();
278272

279273
/* PIA 1 Control Register A */
280274
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();
282283

283284
/* PIA 1 Data Register B */
284285
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();
288294

289295
/* PIA 1 Control Register B */
290296
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();
292305

293306
/* PIA 2 Data Register A */
294307
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();
303316

304317
/* PIA 2 Control Register A */
305318
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();
307327

308328
/* PIA 2 DRB / DDRB */
309329
case 0xFF22:
@@ -447,7 +467,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
447467
case 0xFF14:
448468
case 0xFF18:
449469
case 0xFF1C:
450-
pia1DRA = value.copy();
470+
pia1a.setRegister(value);
451471
break;
452472

453473
/* PIA 1 Control Register A */
@@ -459,17 +479,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
459479
case 0xFF15:
460480
case 0xFF19:
461481
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);
473483
break;
474484

475485
/* PIA 1 Data Register B */
@@ -481,7 +491,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
481491
case 0xFF16:
482492
case 0xFF1A:
483493
case 0xFF1E:
484-
pia1DRB = value.copy();
494+
pia1b.setDataRegister(value);
485495
break;
486496

487497
/* PIA 1 Control Register B */
@@ -493,17 +503,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
493503
case 0xFF17:
494504
case 0xFF1B:
495505
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);
507507
break;
508508

509509
/* PIA 2 Data Register A / Data Direction Register A */
@@ -528,17 +528,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
528528
case 0xFF35:
529529
case 0xFF39:
530530
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);
542532
break;
543533

544534
/* PIA 2 Data Register B / Data Direction Register B */
@@ -1212,29 +1202,11 @@ public void timerTick(int ticks) {
12121202
verticalBorderTickValue += ticks;
12131203

12141204
/* 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);
12261207

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);
12381210

12391211
/* Check for GIME timer related interrupts */
12401212
if (timerTickCounter >= timerTickThreshold) {

0 commit comments

Comments
 (0)