5
5
package ca .craigthomas .yacoco3e .components ;
6
6
7
7
import ca .craigthomas .yacoco3e .datatypes .*;
8
- import ca .craigthomas .yacoco3e .datatypes .screen .ScreenMode ;
8
+ import ca .craigthomas .yacoco3e .datatypes .screen .ScreenMode . Mode ;
9
9
10
10
import static ca .craigthomas .yacoco3e .datatypes .RegisterSet .*;
11
11
@@ -44,6 +44,7 @@ public class IOController
44
44
protected PIA1a pia1a ;
45
45
protected PIA1b pia1b ;
46
46
protected PIA2a pia2a ;
47
+ protected PIA2b pia2b ;
47
48
48
49
/* PIA2 */
49
50
protected UnsignedByte pia2DRA ; /* PIA 2 Data Register A */
@@ -55,7 +56,6 @@ public class IOController
55
56
protected UnsignedByte pia2DDRB ;
56
57
57
58
/* Video mode related functions */
58
- protected UnsignedByte vdgOperatingMode ;
59
59
protected UnsignedByte samControlBits ;
60
60
61
61
/* GIME IRQ enabled / disabled */
@@ -115,10 +115,14 @@ public IOController(Memory memory, RegisterSet registerSet, Keyboard keyboard, S
115
115
this .screen = screen ;
116
116
this .cassette = cassette ;
117
117
118
+ /* Screen controls */
119
+ samControlBits = new UnsignedByte ();
120
+
118
121
/* PIAs */
119
122
pia1a = new PIA1a (keyboard );
120
123
pia1b = new PIA1b (keyboard );
121
124
pia2a = new PIA2a (cassette );
125
+ pia2b = new PIA2b (this );
122
126
123
127
/* Display registers */
124
128
verticalOffsetRegister = new UnsignedWord (0x0400 );
@@ -146,9 +150,6 @@ public IOController(Memory memory, RegisterSet registerSet, Keyboard keyboard, S
146
150
/* Disks */
147
151
diskDriveSelect = 0 ;
148
152
149
- samControlBits = new UnsignedByte ();
150
- vdgOperatingMode = new UnsignedByte ();
151
-
152
153
/* Initialize drive data */
153
154
disk = new DiskDrive [NUM_DISK_DRIVES ];
154
155
for (int i = 0 ; i < NUM_DISK_DRIVES ; i ++) {
@@ -325,13 +326,25 @@ public UnsignedByte readIOByte(int address) {
325
326
case 0xFF3D :
326
327
return pia2a .getControlRegister ();
327
328
328
- /* PIA 2 DRB / DDRB */
329
+ /* PIA 2 Data Register B */
329
330
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 ();
331
338
332
339
/* PIA 2 Control Register B */
333
340
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 ();
335
348
336
349
/* Disk Drive Status Register */
337
350
case 0xFF48 :
@@ -491,7 +504,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
491
504
case 0xFF16 :
492
505
case 0xFF1A :
493
506
case 0xFF1E :
494
- pia1b .setDataRegister (value );
507
+ pia1b .setRegister (value );
495
508
break ;
496
509
497
510
/* PIA 1 Control Register B */
@@ -540,13 +553,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
540
553
case 0xFF36 :
541
554
case 0xFF3A :
542
555
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 );
550
557
break ;
551
558
552
559
/* PIA 2 Control Register B */
@@ -558,10 +565,7 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
558
565
case 0xFF37 :
559
566
case 0xFF3B :
560
567
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 );
565
569
break ;
566
570
567
571
@@ -597,7 +601,9 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
597
601
598
602
/* Disk Command Register */
599
603
case 0xFF48 :
600
- // System.out.println("$FF48 - Writing command register drive " +diskDriveSelect + " value " + value);
604
+ case 0xFF4C :
605
+ case 0xFF58 :
606
+ case 0xFF5C :
601
607
disk [diskDriveSelect ].executeCommand (value );
602
608
break ;
603
609
@@ -776,37 +782,37 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
776
782
/* SAM - Video Display - V0 - Clear */
777
783
case 0xFFC0 :
778
784
samControlBits .and (~0x1 );
779
- updateVideoMode ();
785
+ updateVideoMode (pia2b . getVDGOperatingMode () );
780
786
break ;
781
787
782
788
/* SAM - Video Display - V0 - Set */
783
789
case 0xFFC1 :
784
790
samControlBits .or (0x1 );
785
- updateVideoMode ();
791
+ updateVideoMode (pia2b . getVDGOperatingMode () );
786
792
break ;
787
793
788
794
/* SAM - Video Display - V1 - Clear */
789
795
case 0xFFC2 :
790
796
samControlBits .and (~0x2 );
791
- updateVideoMode ();
797
+ updateVideoMode (pia2b . getVDGOperatingMode () );
792
798
break ;
793
799
794
800
/* SAM - Video Display - V1 - Set */
795
801
case 0xFFC3 :
796
802
samControlBits .or (0x2 );
797
- updateVideoMode ();
803
+ updateVideoMode (pia2b . getVDGOperatingMode () );
798
804
break ;
799
805
800
806
/* SAM - Video Display - V2 - Clear */
801
807
case 0xFFC4 :
802
808
samControlBits .and (~0x4 );
803
- updateVideoMode ();
809
+ updateVideoMode (pia2b . getVDGOperatingMode () );
804
810
break ;
805
811
806
812
/* SAM - Video Display - V2 - Set */
807
813
case 0xFFC5 :
808
814
samControlBits .or (0x4 );
809
- updateVideoMode ();
815
+ updateVideoMode (pia2b . getVDGOperatingMode () );
810
816
break ;
811
817
812
818
/* SAM - Display Offset Register - Bit 0 - Clear */
@@ -967,62 +973,70 @@ public void updateClockSpeed() {
967
973
tickRefreshAmount = (samClockSpeed .isMasked (0x2 )) ? HIGH_SPEED_CLOCK_FREQUENCY : LOW_SPEED_CLOCK_FREQUENCY ;
968
974
}
969
975
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 ;
972
984
int colorSet = vdgOperatingMode .isMasked (0x8 ) ? 1 : 0 ;
973
- int vdgBytes = vdgOperatingMode .getShort () & 0x70 ;
974
985
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 ;
985
991
986
- if ( samControlBits . equals ( new UnsignedByte ( 0x2 ))) {
987
- mode = ScreenMode . Mode .SG8 ;
988
- colorSet = 0 ; }
992
+ case 0x2 :
993
+ mode = Mode .G2C ;
994
+ break ;
989
995
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 ;
994
999
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 );
999
1015
}
1000
1016
} 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 );
1024
1037
}
1025
1038
}
1039
+
1026
1040
int memoryOffset = screen .getMemoryOffset ();
1027
1041
screen .setMode (mode , colorSet );
1028
1042
screen .setMemoryOffset (memoryOffset );
@@ -1039,9 +1053,17 @@ public void writeWord(int address, int value) {
1039
1053
writeWord (new UnsignedWord (address ), new UnsignedWord (value ));
1040
1054
}
1041
1055
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
+ */
1042
1063
public void writeWord (UnsignedWord address , int value ) {
1043
1064
writeWord (address , new UnsignedWord (value ));
1044
1065
}
1066
+
1045
1067
/**
1046
1068
* Writes an UnsignedWord to the specified memory address.
1047
1069
*
0 commit comments