Skip to content

Commit 7fa91fd

Browse files
committed
Clean up PIA code.
1 parent 849d14b commit 7fa91fd

File tree

7 files changed

+121
-130
lines changed

7 files changed

+121
-130
lines changed

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

Lines changed: 96 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
package ca.craigthomas.yacoco3e.components;
66

77
import ca.craigthomas.yacoco3e.datatypes.*;
8-
import ca.craigthomas.yacoco3e.datatypes.screen.ScreenMode;
8+
import ca.craigthomas.yacoco3e.datatypes.screen.ScreenMode.Mode;
99

1010
import static ca.craigthomas.yacoco3e.datatypes.RegisterSet.*;
1111

@@ -44,6 +44,7 @@ public class IOController
4444
protected PIA1a pia1a;
4545
protected PIA1b pia1b;
4646
protected PIA2a pia2a;
47+
protected PIA2b pia2b;
4748

4849
/* PIA2 */
4950
protected UnsignedByte pia2DRA; /* PIA 2 Data Register A */
@@ -55,7 +56,6 @@ public class IOController
5556
protected UnsignedByte pia2DDRB;
5657

5758
/* Video mode related functions */
58-
protected UnsignedByte vdgOperatingMode;
5959
protected UnsignedByte samControlBits;
6060

6161
/* GIME IRQ enabled / disabled */
@@ -115,10 +115,14 @@ public IOController(Memory memory, RegisterSet registerSet, Keyboard keyboard, S
115115
this.screen = screen;
116116
this.cassette = cassette;
117117

118+
/* Screen controls */
119+
samControlBits = new UnsignedByte();
120+
118121
/* PIAs */
119122
pia1a = new PIA1a(keyboard);
120123
pia1b = new PIA1b(keyboard);
121124
pia2a = new PIA2a(cassette);
125+
pia2b = new PIA2b(this);
122126

123127
/* Display registers */
124128
verticalOffsetRegister = new UnsignedWord(0x0400);
@@ -146,9 +150,6 @@ public IOController(Memory memory, RegisterSet registerSet, Keyboard keyboard, S
146150
/* Disks */
147151
diskDriveSelect = 0;
148152

149-
samControlBits = new UnsignedByte();
150-
vdgOperatingMode = new UnsignedByte();
151-
152153
/* Initialize drive data */
153154
disk = new DiskDrive[NUM_DISK_DRIVES];
154155
for (int i = 0; i < NUM_DISK_DRIVES; i++) {
@@ -325,13 +326,25 @@ public UnsignedByte readIOByte(int address) {
325326
case 0xFF3D:
326327
return pia2a.getControlRegister();
327328

328-
/* PIA 2 DRB / DDRB */
329+
/* PIA 2 Data Register B */
329330
case 0xFF22:
330-
return pia2CRB.isMasked(0x4) ? vdgOperatingMode : pia2DDRB;
331+
case 0xFF2A:
332+
case 0xFF2E:
333+
case 0xFF32:
334+
case 0xFF36:
335+
case 0xFF3A:
336+
case 0xFF3E:
337+
return pia2b.getRegister();
331338

332339
/* PIA 2 Control Register B */
333340
case 0xFF23:
334-
return pia2CRB;
341+
case 0xFF2B:
342+
case 0xFF2F:
343+
case 0xFF33:
344+
case 0xFF37:
345+
case 0xFF3B:
346+
case 0xFF3F:
347+
return pia2b.getControlRegister();
335348

336349
/* Disk Drive Status Register */
337350
case 0xFF48:
@@ -491,7 +504,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
491504
case 0xFF16:
492505
case 0xFF1A:
493506
case 0xFF1E:
494-
pia1b.setDataRegister(value);
507+
pia1b.setRegister(value);
495508
break;
496509

497510
/* PIA 1 Control Register B */
@@ -540,13 +553,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
540553
case 0xFF36:
541554
case 0xFF3A:
542555
case 0xFF3E:
543-
if (pia2CRB.isMasked(0x4)) {
544-
vdgOperatingMode = value.copy();
545-
vdgOperatingMode.and(pia2DDRB.getShort());
546-
updateVideoMode();
547-
} else {
548-
pia2DDRB = value.copy();
549-
}
556+
pia2b.setRegister(value);
550557
break;
551558

552559
/* PIA 2 Control Register B */
@@ -558,10 +565,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
558565
case 0xFF37:
559566
case 0xFF3B:
560567
case 0xFF3F:
561-
/* Bit 2 = Control whether Data Register or Data Direction Register active */
562-
/* Bit 1 = hi/lo edge triggered */
563-
/* Bit 0 = FIRQ from cartridge ROM */
564-
pia2CRB = value.copy();
568+
pia2b.setControlRegister(value);
565569
break;
566570

567571

@@ -597,7 +601,9 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
597601

598602
/* Disk Command Register */
599603
case 0xFF48:
600-
// System.out.println("$FF48 - Writing command register drive " +diskDriveSelect + " value " + value);
604+
case 0xFF4C:
605+
case 0xFF58:
606+
case 0xFF5C:
601607
disk[diskDriveSelect].executeCommand(value);
602608
break;
603609

@@ -776,37 +782,37 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
776782
/* SAM - Video Display - V0 - Clear */
777783
case 0xFFC0:
778784
samControlBits.and(~0x1);
779-
updateVideoMode();
785+
updateVideoMode(pia2b.getVDGOperatingMode());
780786
break;
781787

782788
/* SAM - Video Display - V0 - Set */
783789
case 0xFFC1:
784790
samControlBits.or(0x1);
785-
updateVideoMode();
791+
updateVideoMode(pia2b.getVDGOperatingMode());
786792
break;
787793

788794
/* SAM - Video Display - V1 - Clear */
789795
case 0xFFC2:
790796
samControlBits.and(~0x2);
791-
updateVideoMode();
797+
updateVideoMode(pia2b.getVDGOperatingMode());
792798
break;
793799

794800
/* SAM - Video Display - V1 - Set */
795801
case 0xFFC3:
796802
samControlBits.or(0x2);
797-
updateVideoMode();
803+
updateVideoMode(pia2b.getVDGOperatingMode());
798804
break;
799805

800806
/* SAM - Video Display - V2 - Clear */
801807
case 0xFFC4:
802808
samControlBits.and(~0x4);
803-
updateVideoMode();
809+
updateVideoMode(pia2b.getVDGOperatingMode());
804810
break;
805811

806812
/* SAM - Video Display - V2 - Set */
807813
case 0xFFC5:
808814
samControlBits.or(0x4);
809-
updateVideoMode();
815+
updateVideoMode(pia2b.getVDGOperatingMode());
810816
break;
811817

812818
/* SAM - Display Offset Register - Bit 0 - Clear */
@@ -967,62 +973,70 @@ public void updateClockSpeed() {
967973
tickRefreshAmount = (samClockSpeed.isMasked(0x2)) ? HIGH_SPEED_CLOCK_FREQUENCY : LOW_SPEED_CLOCK_FREQUENCY;
968974
}
969975

970-
public void updateVideoMode() {
971-
ScreenMode.Mode mode = screen.getMode();
976+
/**
977+
* Sets the Video Display Generator operating mode based on the value of PIA2B
978+
* data register, plus the SAM control bits.
979+
*
980+
* @param vdgOperatingMode the Video Display Generator mode to set
981+
*/
982+
public void updateVideoMode(UnsignedByte vdgOperatingMode) {
983+
Mode mode;
972984
int colorSet = vdgOperatingMode.isMasked(0x8) ? 1 : 0;
973-
int vdgBytes = vdgOperatingMode.getShort() & 0x70;
974985

975-
if (!vdgOperatingMode.isMasked(0x80)) {
976-
if (vdgOperatingMode.isMasked(0x10)) {
977-
if (samControlBits.equals(new UnsignedByte())) {
978-
mode = ScreenMode.Mode.SG6;
979-
}
980-
} else {
981-
if (samControlBits.equals(new UnsignedByte())) {
982-
mode = ScreenMode.Mode.SG4;
983-
colorSet = 0;
984-
}
986+
if (vdgOperatingMode.isMasked(0x80)) {
987+
switch (samControlBits.getShort()) {
988+
case 0x1:
989+
mode = vdgOperatingMode.isMasked(0x10) ? Mode.G1R : Mode.G1C;
990+
break;
985991

986-
if (samControlBits.equals(new UnsignedByte(0x2))) {
987-
mode = ScreenMode.Mode.SG8;
988-
colorSet = 0; }
992+
case 0x2:
993+
mode = Mode.G2C;
994+
break;
989995

990-
if (samControlBits.equals(new UnsignedByte(0x4))) {
991-
mode = ScreenMode.Mode.SG12;
992-
colorSet = 0;
993-
}
996+
case 0x3:
997+
mode = Mode.G2R;
998+
break;
994999

995-
if (samControlBits.equals(new UnsignedByte(0x6))) {
996-
mode = ScreenMode.Mode.SG24;
997-
colorSet = 0;
998-
}
1000+
case 0x4:
1001+
mode = Mode.G3C;
1002+
break;
1003+
1004+
case 0x5:
1005+
mode = Mode.G3R;
1006+
break;
1007+
1008+
case 0x6:
1009+
mode = vdgOperatingMode.isMasked(0x10) ? Mode.G6R : Mode.G6C;
1010+
break;
1011+
1012+
default:
1013+
UnsignedByte fullMode = new UnsignedByte(vdgOperatingMode.getShort() + samControlBits.getShort());
1014+
throw new RuntimeException("Unknown screen mode: " + fullMode);
9991015
}
10001016
} else {
1001-
if (vdgBytes == 0x00 && samControlBits.equals(new UnsignedByte(0x1))) {
1002-
mode = ScreenMode.Mode.G1C;
1003-
}
1004-
if (vdgBytes == 0x10 && samControlBits.equals(new UnsignedByte(0x1))) {
1005-
mode = ScreenMode.Mode.G1R;
1006-
}
1007-
if (vdgBytes == 0x20 && samControlBits.equals(new UnsignedByte(0x2))) {
1008-
mode = ScreenMode.Mode.G2C;
1009-
}
1010-
if (vdgBytes == 0x30 && samControlBits.equals(new UnsignedByte(0x3))) {
1011-
mode = ScreenMode.Mode.G2R;
1012-
}
1013-
if (vdgBytes == 0x40 && samControlBits.equals(new UnsignedByte(0x4))) {
1014-
mode = ScreenMode.Mode.G3C;
1015-
}
1016-
if (vdgBytes == 0x50 && samControlBits.equals(new UnsignedByte(0x5))) {
1017-
mode = ScreenMode.Mode.G3R;
1018-
}
1019-
if (vdgBytes == 0x60 && samControlBits.equals(new UnsignedByte(0x6))) {
1020-
mode = ScreenMode.Mode.G6C;
1021-
}
1022-
if (vdgBytes == 0x70 && samControlBits.equals(new UnsignedByte(0x6))) {
1023-
mode = ScreenMode.Mode.G6R;
1017+
switch (samControlBits.getShort()) {
1018+
case 0x0:
1019+
mode = vdgOperatingMode.isMasked(0x20) ? Mode.SG6 : Mode.SG4;
1020+
break;
1021+
1022+
case 0x2:
1023+
mode = Mode.SG8;
1024+
break;
1025+
1026+
case 0x4:
1027+
mode = Mode.SG12;
1028+
break;
1029+
1030+
case 0x6:
1031+
mode = Mode.SG24;
1032+
break;
1033+
1034+
default:
1035+
UnsignedByte fullMode = new UnsignedByte(vdgOperatingMode.getShort() + samControlBits.getShort());
1036+
throw new RuntimeException("Unknown screen mode: " + fullMode);
10241037
}
10251038
}
1039+
10261040
int memoryOffset = screen.getMemoryOffset();
10271041
screen.setMode(mode, colorSet);
10281042
screen.setMemoryOffset(memoryOffset);
@@ -1039,9 +1053,17 @@ public void writeWord(int address, int value) {
10391053
writeWord(new UnsignedWord(address), new UnsignedWord(value));
10401054
}
10411055

1056+
/**
1057+
* Convenience function allowing the address to be a word, while the
1058+
* value to be an integer, instead of UnsignedWord objects.
1059+
*
1060+
* @param address the address to write to
1061+
* @param value the value to write
1062+
*/
10421063
public void writeWord(UnsignedWord address, int value) {
10431064
writeWord(address, new UnsignedWord(value));
10441065
}
1066+
10451067
/**
10461068
* Writes an UnsignedWord to the specified memory address.
10471069
*

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

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,11 @@ public abstract class PIA
1111
public UnsignedByte controlRegister;
1212
public UnsignedByte dataRegister;
1313
public UnsignedByte dataDirectionRegister;
14-
protected boolean interruptEnabled;
15-
protected boolean interruptTriggered;
1614

1715
public PIA() {
1816
controlRegister = new UnsignedByte();
1917
dataDirectionRegister = new UnsignedByte();
2018
dataRegister = new UnsignedByte();
21-
interruptEnabled = false;
22-
interruptTriggered = false;
2319
}
2420

2521
/**
@@ -54,31 +50,13 @@ public void setDataDirectionRegister(UnsignedByte newDataDirectionRegister) {
5450
dataDirectionRegister = newDataDirectionRegister;
5551
}
5652

57-
/**
58-
* Returns the status of the interrupt - enabled (true) or disabled (false).
59-
*
60-
* @return true if the interrupt is enabled, false otherwise
61-
*/
62-
public boolean interruptEnabled() {
63-
return interruptEnabled;
64-
}
65-
66-
/**
67-
* Returns true if an interrupt has been triggered.
68-
*
69-
* @return true if an interrupt has been triggered
70-
*/
71-
public boolean isInterruptTriggered() {
72-
return interruptTriggered;
73-
}
74-
7553
/**
7654
* Returns the contents of the control register.
7755
*
7856
* @return the contents of the control register
7957
*/
8058
public UnsignedByte getControlRegister() {
81-
return controlRegister;
59+
return controlRegister.copy();
8260
}
8361

8462
/**
@@ -90,15 +68,6 @@ public void setControlRegister(UnsignedByte newControlRegister) {
9068
controlRegister = newControlRegister.copy();
9169
}
9270

93-
/**
94-
* Perform a logical OR of the value in the control register.
95-
*
96-
* @param value the value to OR with the control register
97-
*/
98-
public void controlRegisterOr(int value) {
99-
controlRegister.or(value);
100-
}
101-
10271
/**
10372
* Gets either the data register, or the data direction register. The register
10473
* returned depends on the value of bit 2 in the control register. If it is set,
@@ -123,8 +92,8 @@ public UnsignedByte getRegister() {
12392
public void setRegister(UnsignedByte newRegisterValue) {
12493
if (controlRegister.isMasked(0x04)) {
12594
setDataRegister(newRegisterValue);
126-
} else {
127-
setDataDirectionRegister(newRegisterValue);
95+
return;
12896
}
97+
setDataDirectionRegister(newRegisterValue);
12998
}
13099
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ public void setDataRegister(UnsignedByte newDataRegister) {
5050
*/
5151
@Override
5252
public void setControlRegister(UnsignedByte newControlRegister) {
53-
interruptEnabled = newControlRegister.isMasked(0x1);
5453
controlRegister = new UnsignedByte(newControlRegister.getShort() +
5554
(controlRegister.isMasked(0x80) ? 0x80 : 0) +
5655
(controlRegister.isMasked(0x40) ? 0x40 : 0));

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ public void setDataRegister(UnsignedByte newDataRegister) {
5151
*/
5252
@Override
5353
public void setControlRegister(UnsignedByte newControlRegister) {
54-
interruptEnabled = newControlRegister.isMasked(0x1);
5554
controlRegister = new UnsignedByte(
5655
newControlRegister.getShort() +
5756
(controlRegister.isMasked(0x80) ? 0x80 : 0) +

0 commit comments

Comments
 (0)