Commit a6c14ddc by Jessica Hawkwell

fixed the race condition, it works properly now

1 parent adb54524
Pipeline #214 passed
in 1 minute 8 seconds
......@@ -36,9 +36,9 @@ public class Kcpu extends BaseDevice {
* 0x0000 - 0x00ff : data stack
* 0x0100 - 0x017f : pc stack (return stack)
* 0x0180 - 0x019f : interrupt vectors
* 0x0120 : data stack pointer
* 0x0122 : pc stack pointer
* 0x0124 ~ unused
* 0x01a0 : data stack pointer
* 0x01a2 : pc stack pointer
* 0x01a4 ~ unused
* 0x01ff : irq state
*/
memory = new byte[0x0200];
......@@ -63,7 +63,8 @@ public class Kcpu extends BaseDevice {
short[] regs = Arrays.copyOf(registers, registers.length);
short counter = pc;
int intq = 0;
if (Thread.currentThread().getId() != initThread.getId()) {
boolean threaded = (Thread.currentThread().getId() != initThread.getId());
if (threaded) {
logln("Starting IRQ %x : %s", irq, Thread.currentThread().getName());
Thread.currentThread().setUncaughtExceptionHandler(new KcpuExceptions(this, logger));
synchronized(memory) {
......@@ -84,7 +85,26 @@ public class Kcpu extends BaseDevice {
}
short start = (short)((irq * 2) + 0x0180);
synchronized (memory) { pc = Converter.bytes2short(new byte[]{memory[start], memory[start + 1]}); }
/*
Here we make a backup of the CPU's internals (stacks and stack counters, mainly)
then wipe them clean, thus emulating the complete "clean slate" state of certain
processors when they enter interrupt mode
*/
byte[] memoryBackup;
int a;
synchronized (memory) {
// set program counter to the interrupt vector address
pc = Converter.bytes2short(new byte[]{memory[start], memory[start + 1]});
// make a backup of CPU memory
memoryBackup = Arrays.copyOf(memory, memory.length);
// now erase some key entries
for (a = 0; a <= 0x0180; a++) { memory[a] = 0; }
for (a = 0x01a0; a <= 0x01a3; a++) { memory[a] = 0; }
}
try {
while (true) {
workCycle(intq);
......@@ -92,12 +112,24 @@ public class Kcpu extends BaseDevice {
}
}
catch (CPUStoppedException x) {
synchronized (memory) {
for (a = 0; a < memoryBackup.length; a++) {
memory[a] = memoryBackup[a];
}
}
logln("CPU Stopped: %s", x.getMessage());
//x = null;
}
synchronized (memory) {
for (a = 0; a < memoryBackup.length; a++) {
memory[a] = memoryBackup[a];
}
}
if (Thread.currentThread().getId() != initThread.getId()) {
registers = Arrays.copyOf(regs, regs.length);
if (threaded) {
for (a = 0; a < registers.length; a++) {
registers[a] = regs[a];
}
pc = counter;
synchronized (memory) { memory[memory.length - 1]--; }
initThread.notify();
......@@ -177,8 +209,8 @@ public class Kcpu extends BaseDevice {
short data = ValueHelper.readShort(0, ref, registers, values, kboard);
synchronized (memory) {
short ps_c = Converter.bytes2short(new byte[]{memory[0x0122], memory[0x0123]});
short ps_d = Converter.bytes2short(new byte[]{memory[0x0120], memory[0x0121]});
short ps_c = Converter.bytes2short(new byte[]{memory[0x01a2], memory[0x01a3]});
short ps_d = Converter.bytes2short(new byte[]{memory[0x01a0], memory[0x01a1]});
short base_c = (short)(0x0100 + (ps_c * 2));
short base_d = (short)(ps_d * 2);
byte[] tmp;
......@@ -211,6 +243,12 @@ public class Kcpu extends BaseDevice {
ps_d--;
break;
}
tmp = Converter.short2bytes(ps_c);
memory[0x01a2] = tmp[0];
memory[0x01a3] = tmp[1];
tmp = Converter.short2bytes(ps_d);
memory[0x01a0] = tmp[0];
memory[0x01a1] = tmp[1];
}
switch (od) {
......
......@@ -29,7 +29,7 @@ public class BootRom extends BaseMemory {
Kasm kasm = kb.build();
// hardcoding some bootrom
//writeBytes(kasm.compileSegment("movs $0 r2"));
// create a device table
kasm.compileSegment("mark");
writeBytes(kasm.compileSegment("add r0 8"));
writeBytes(kasm.compileSegment("add r2 1"));
......@@ -54,6 +54,7 @@ public class BootRom extends BaseMemory {
writeBytes(kasm.compileSegment("add r3 1"));
writeBytes(kasm.compileSegment("jdle r3 32 mark"));
// move the device table to the end of the bootrom
writeBytes(kasm.compileSegment("movs r0 1f00,16"));
writeBytes(kasm.compileSegment("mov r1 0"));
......@@ -63,7 +64,9 @@ public class BootRom extends BaseMemory {
writeBytes(kasm.compileSegment("add r0 1"));
writeBytes(kasm.compileSegment("jdle r1 ff,16 mark"));
// lock the bootrom
writeBytes(kasm.compileSegment("irqm 1f00,16"));
writeBytes(kasm.compileSegment("irqdh 0 1"));
/*writeBytes(kasm.compileSegment("gpc"));
writeBytes(kasm.compileSegment("movs r0 60,16"));
......
package me.felinewith.kcpu.util.helpers;
import me.felinewith.kcpu.util.Converter;
import me.felinewith.kcpu.interfaces.IMemory;
import me.felinewith.kcpu.util.Converter;
/**
*
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!