Skip to content

Fix simple IO bugs #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/main/java/ca/craigthomas/yacoco3e/components/CPU.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ public int executeInstruction() throws MalformedInstructionException {
* stored at $FFF8.
*/
public void interruptRequest() {
io.regs.cc.or(CC_E);
io.pushStack(Register.S, io.regs.pc);
io.pushStack(Register.S, io.regs.u);
io.pushStack(Register.S, io.regs.y);
io.pushStack(Register.S, io.regs.x);
io.pushStack(Register.S, io.regs.dp);
io.pushStack(Register.S, io.regs.b);
io.pushStack(Register.S, io.regs.a);
io.regs.cc.or(CC_E);
io.pushStack(Register.S, io.regs.cc);
io.regs.cc.or(CC_I);
io.regs.pc.set(io.readWord(0xFFF8));
Expand All @@ -63,8 +63,8 @@ public void interruptRequest() {
* $FFF6.
*/
public void fastInterruptRequest() {
io.pushStack(Register.S, io.regs.pc);
io.regs.cc.and(~CC_E);
io.pushStack(Register.S, io.regs.pc);
io.pushStack(Register.S, io.regs.cc);
io.regs.cc.or(CC_F);
io.regs.cc.or(CC_I);
Expand All @@ -77,14 +77,14 @@ public void fastInterruptRequest() {
* stored at $FFFC.
*/
public void nonMaskableInterruptRequest() {
io.regs.cc.or(CC_E);
io.pushStack(Register.S, io.regs.pc);
io.pushStack(Register.S, io.regs.u);
io.pushStack(Register.S, io.regs.y);
io.pushStack(Register.S, io.regs.x);
io.pushStack(Register.S, io.regs.dp);
io.pushStack(Register.S, io.regs.b);
io.pushStack(Register.S, io.regs.a);
io.regs.cc.or(CC_E);
io.pushStack(Register.S, io.regs.cc);
io.regs.cc.or(CC_I);
io.regs.cc.or(CC_F);
Expand Down
15 changes: 10 additions & 5 deletions src/main/java/ca/craigthomas/yacoco3e/components/Emulator.java
Original file line number Diff line number Diff line change
Expand Up @@ -460,11 +460,10 @@ public void run() {
status = EmulatorStatus.PAUSED;
}

/* Increment timers if necessary */
io.timerTick(operationTicks);

/* Fire interrupts if set */
cpu.serviceInterrupts();
/* Check to see if we had an instruction - if it's a SYNC, just add to the timers */
if (io.waitForIRQ) {
operationTicks += 1;
}

/* Check to see if we should trace the output */
if (this.trace) {
Expand All @@ -474,6 +473,12 @@ public void run() {
System.out.println();
}
}

/* Increment timers if necessary */
io.timerTick(operationTicks);

/* Fire interrupts if set */
cpu.serviceInterrupts();
}
}
this.shutdown();
Expand Down
32 changes: 4 additions & 28 deletions src/main/java/ca/craigthomas/yacoco3e/components/IOController.java
Original file line number Diff line number Diff line change
Expand Up @@ -348,22 +348,18 @@ public UnsignedByte readIOByte(int address) {

/* Disk Drive Status Register */
case 0xFF48:
// System.out.println("$FF48 - Reading drive " + diskDriveSelect + " status register " + disk[diskDriveSelect].getStatusRegister());
return disk[diskDriveSelect].getStatusRegister();

/* Disk Track Status Register */
case 0xFF49:
// System.out.println("$FF49 - Reading drive " + diskDriveSelect + " track register " + disk[diskDriveSelect].getTrack());
return new UnsignedByte(disk[diskDriveSelect].getTrack());

/* Disk Sector Status Register */
case 0xFF4A:
// System.out.println("$FF4A - Reading drive " + diskDriveSelect + " sector register " + disk[diskDriveSelect].getSector());
return new UnsignedByte(disk[diskDriveSelect].getSector());

/* Disk Data Register */
case 0xFF4B:
// System.out.println("$FF4B - Reading drive " + diskDriveSelect + " data register " + disk[diskDriveSelect].getDataRegister());
return new UnsignedByte(disk[diskDriveSelect].getDataRegister());

/* IRQs Enabled Register */
Expand Down Expand Up @@ -571,7 +567,6 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {

/* Disk Drive Control Register */
case 0xFF40:
// System.out.println("$FF40 - Writing control register drive " + diskDriveSelect + " value " + value);
/* Bit 2-0 = Disk drive select */
diskDriveSelect = (value.isMasked(0x1)) ? 0 : diskDriveSelect;
diskDriveSelect = (value.isMasked(0x2)) ? 1 : diskDriveSelect;
Expand Down Expand Up @@ -609,19 +604,16 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {

/* Track Status Register */
case 0xFF49:
// System.out.println("$FF49 - Writing track register drive " + diskDriveSelect + " value " + value);
disk[diskDriveSelect].setTrack(value);
break;

/* Sector Status Register */
case 0xFF4A:
// System.out.println("$FF4A - Writing sector register drive " + diskDriveSelect + " value " + value);
disk[diskDriveSelect].setSector(value);
break;

/* Disk Data Register */
case 0xFF4B:
// System.out.println("$FF4B - Writing data register drive " + diskDriveSelect + " value " + value);
disk[diskDriveSelect].setDataRegister(value);
break;

Expand Down Expand Up @@ -658,7 +650,6 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
}

/* Bit 5 = Timer Rate - 0 is 63.5 microseconds, 1 is 70 nanoseconds */
// timerTickThreshold = (value.isMasked(0x20)) ? TIMER_63_5_MICROS : TIMER_63_5_MICROS;
timerTickThreshold = TIMER_63_5_MICROS;
break;

Expand Down Expand Up @@ -782,37 +773,31 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
/* SAM - Video Display - V0 - Clear */
case 0xFFC0:
samControlBits.and(~0x1);
updateVideoMode(pia2b.getVDGOperatingMode());
break;

/* SAM - Video Display - V0 - Set */
case 0xFFC1:
samControlBits.or(0x1);
updateVideoMode(pia2b.getVDGOperatingMode());
break;

/* SAM - Video Display - V1 - Clear */
case 0xFFC2:
samControlBits.and(~0x2);
updateVideoMode(pia2b.getVDGOperatingMode());
break;

/* SAM - Video Display - V1 - Set */
case 0xFFC3:
samControlBits.or(0x2);
updateVideoMode(pia2b.getVDGOperatingMode());
break;

/* SAM - Video Display - V2 - Clear */
case 0xFFC4:
samControlBits.and(~0x4);
updateVideoMode(pia2b.getVDGOperatingMode());
break;

/* SAM - Video Display - V2 - Set */
case 0xFFC5:
samControlBits.or(0x4);
updateVideoMode(pia2b.getVDGOperatingMode());
break;

/* SAM - Display Offset Register - Bit 0 - Clear */
Expand Down Expand Up @@ -922,17 +907,6 @@ public void writeIOByte(UnsignedWord address, UnsignedByte value) {
break;

default:
switch(address.getInt()) {
case 0xFFFA:
case 0xFFF2:
case 0xFFF4:
System.out.println("Write to IO address " + address);
break;

default:
break;
}
memory.writeByte(address, value);
break;
}
}
Expand Down Expand Up @@ -1011,7 +985,8 @@ public void updateVideoMode(UnsignedByte vdgOperatingMode) {

default:
UnsignedByte fullMode = new UnsignedByte(vdgOperatingMode.getShort() + samControlBits.getShort());
throw new RuntimeException("Unknown screen mode: " + fullMode);
System.out.println("Unknown screen mode: " + fullMode);
return;
}
} else {
switch (samControlBits.getShort()) {
Expand All @@ -1033,7 +1008,8 @@ public void updateVideoMode(UnsignedByte vdgOperatingMode) {

default:
UnsignedByte fullMode = new UnsignedByte(vdgOperatingMode.getShort() + samControlBits.getShort());
throw new RuntimeException("Unknown screen mode: " + fullMode);
System.out.println("Unknown screen mode: " + fullMode);
return;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,24 @@ public void testBranchToSubroutineSavesPCAndReturnsTrue() {

@Test
public void testBranchSubroutine() throws MalformedInstructionException {
io.writeWord(0x0000, 0x8D1F);
io.regs.s.set(0x3000);
regs.pc.set(0x1021);
io.writeWord(0x1021, 0x8D1F);
cpu.executeInstruction();
assertEquals(0x0021, regs.pc.getInt());
assertEquals(0x02, memory.readByte(io.getWordRegister(Register.S).next()).getShort());
assertEquals(0x1042, regs.pc.getInt());
assertEquals(0x23, memory.readByte(0x2FFF).getShort());
assertEquals(0x10, memory.readByte(0x2FFE).getShort());
}

@Test
public void testBranchSubroutineNegativeOffsetCorrect() throws MalformedInstructionException {
regs.pc.set(0x0021);
io.writeWord(0x0021, 0x8DDD);
io.regs.s.set(0x3000);
regs.pc.set(0x1021);
io.writeWord(0x1021, 0x8DDD);
cpu.executeInstruction();
assertEquals(0x0000, regs.pc.getInt());
assertEquals(0x23, memory.readByte(io.getWordRegister(Register.S).next()).getShort());
assertEquals(0x1000, regs.pc.getInt());
assertEquals(0x23, memory.readByte(0x2FFF).getShort());
assertEquals(0x10, memory.readByte(0x2FFE).getShort());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,26 @@ public void testLongBranchNever() throws MalformedInstructionException {

@Test
public void testLongBranchSubroutine1() throws MalformedInstructionException {
io.writeByte(0x0000, 0x17);
io.writeWord(0x0001, 0x001F);
io.regs.s.set(0x3000);
io.regs.pc.set(0x1000);
io.writeByte(0x1000, 0x17);
io.writeWord(0x1001, 0x001F);
cpu.executeInstruction();
assertEquals(0x0022, regs.pc.getInt());
assertEquals(0x03, memory.readByte(io.getWordRegister(Register.S).next()).getShort());
assertEquals(0x1022, regs.pc.getInt());
assertEquals(0x03, memory.readByte(0x2FFF).getShort());
assertEquals(0x10, memory.readByte(0x2FFE).getShort());
}

@Test
public void testLongBranchSubroutineNegativeOffsetCorrect() throws MalformedInstructionException {
regs.pc.set(0x0021);
io.writeByte(0x0021, 0x17);
io.writeWord(0x0022, 0xFFDC);
cpu.executeInstruction();
assertEquals(0x0000, regs.pc.getInt());
assertEquals(0x24, memory.readByte(io.getWordRegister(Register.S).next()).getShort());
regs.s.set(0x3000);
regs.pc.set(0x1021);
io.writeByte(0x1021, 0x17);
io.writeWord(0x1022, 0xFFDC);
cpu.executeInstruction();
assertEquals(0x1000, regs.pc.getInt());
assertEquals(0x24, memory.readByte(0x2FFF).getShort());
assertEquals(0x10, memory.readByte(0x2FFE).getShort());
}

@Test
Expand Down