Laying the groundwork for the CPU
This commit is contained in:
@@ -87,9 +87,7 @@ public class App {
|
||||
|
||||
// Specify whether using the native module
|
||||
boolean setUseNative(boolean useNative) {
|
||||
this.useNative = useNative && VUE.isNativeLoaded();
|
||||
System.out.println("Native: " + (this.useNative ? "Yes" : "No"));
|
||||
return this.useNative;
|
||||
return this.useNative = useNative && VUE.isNativeLoaded();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class ChildWindow extends JInternalFrame {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Show or hide the component
|
||||
public void setVisible(boolean visible) {
|
||||
public void setVisible(boolean visible) {
|
||||
|
||||
// Making visible
|
||||
if (visible) {
|
||||
@@ -56,7 +56,11 @@ class ChildWindow extends JInternalFrame {
|
||||
}
|
||||
|
||||
// Already visible: bring to front
|
||||
else moveToFront();
|
||||
else {
|
||||
moveToFront();
|
||||
try { setSelected(true); } catch (Exception e) { }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Change visibility
|
||||
|
||||
@@ -64,6 +64,7 @@ class MainWindow extends JFrame {
|
||||
this.app = app;
|
||||
pwd = Util.PWD;
|
||||
vue = VUE.create(app.getUseNative());
|
||||
System.out.println("Native: " + (vue.isNative() ? "Yes" : "No"));
|
||||
|
||||
// Configure video pane
|
||||
video = new JPanel(null) {
|
||||
@@ -109,7 +110,6 @@ class MainWindow extends JFrame {
|
||||
private JMenuBar initMenus() {
|
||||
var bar = new JMenuBar();
|
||||
var loc = app.getLocalizer();
|
||||
bar.setBorder(null);
|
||||
bar.add(initMenuFile (loc));
|
||||
bar.add(initMenuDebug(loc));
|
||||
return bar;
|
||||
|
||||
@@ -227,6 +227,7 @@ class Memory extends ChildWindow {
|
||||
var label = row.bytes[x] = new JLabel();
|
||||
label.setFont(font);
|
||||
label.setForeground(SystemColor.windowText);
|
||||
label.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
label.setVisible(false);
|
||||
client.add(label);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ JNIEXPORT void JNICALL Java_vue_NativeVUE_construct
|
||||
// Produce and initialize s new core context
|
||||
CORE *core = calloc(sizeof (CORE), 1);
|
||||
vueInitialize(&core->vue);
|
||||
vueSetROM(&core->vue, calloc(1024, 1), 1024);
|
||||
|
||||
// Encode the context handle into a byte array
|
||||
jbyteArray pointer = (*env)->NewByteArray(env, sizeof (void *));
|
||||
@@ -73,19 +72,33 @@ JNIEXPORT void JNICALL Java_vue_NativeVUE_construct
|
||||
JNIEXPORT void JNICALL Java_vue_NativeVUE_dispose
|
||||
(JNIEnv *env, jobject vue) {
|
||||
CORE *core = GetCore(env, vue);
|
||||
free(core->vue.rom);
|
||||
if (core->vue.sram != NULL)
|
||||
free(core->vue.sram);
|
||||
if (core->vue.bus.rom != NULL)
|
||||
free(core->vue.bus.rom);
|
||||
if (core->vue.bus.sram != NULL)
|
||||
free(core->vue.bus.sram);
|
||||
free(core);
|
||||
}
|
||||
|
||||
// Retrieve a register value
|
||||
JNIEXPORT jint JNICALL Java_vue_NativeVUE_getRegister
|
||||
(JNIEnv *env, jobject vue, jint index, jboolean system) {
|
||||
CORE *core = GetCore(env, vue);
|
||||
return vueGetRegister(&core->vue, index, system);
|
||||
}
|
||||
|
||||
// Retrieve a copy of the ROM data
|
||||
JNIEXPORT jbyteArray JNICALL Java_vue_NativeVUE_getROM
|
||||
(JNIEnv *env, jobject vue) {
|
||||
CORE *core = GetCore(env, vue);
|
||||
jbyteArray ret = (*env)->NewByteArray(env, (jint) core->vue.rom_size);
|
||||
|
||||
// No ROM data
|
||||
if (core->vue.bus.rom == NULL)
|
||||
return NULL;
|
||||
|
||||
// Copy the ROM data
|
||||
jbyteArray ret = (*env)->NewByteArray(env, (jint)core->vue.bus.rom_size);
|
||||
jbyte *elems = (*env)->GetByteArrayElements(env, ret, NULL);
|
||||
memcpy(elems, core->vue.rom, core->vue.rom_size);
|
||||
memcpy(elems, core->vue.bus.rom, core->vue.bus.rom_size);
|
||||
(*env)->ReleaseByteArrayElements(env, ret, elems, 0);
|
||||
return ret;
|
||||
}
|
||||
@@ -117,6 +130,13 @@ JNIEXPORT jboolean JNICALL Java_vue_NativeVUE_read
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
// Specify a register value
|
||||
JNIEXPORT jint JNICALL Java_vue_NativeVUE_setRegister
|
||||
(JNIEnv *env, jobject vue, jint index, jboolean system, jint value) {
|
||||
CORE *core = GetCore(env, vue);
|
||||
return vueSetRegister(&core->vue, index, system, value);
|
||||
}
|
||||
|
||||
// Provide new ROM data
|
||||
JNIEXPORT jboolean JNICALL Java_vue_NativeVUE_setROM
|
||||
(JNIEnv *env, jobject vue, jbyteArray data, jint offset, jint length) {
|
||||
@@ -138,7 +158,8 @@ JNIEXPORT jboolean JNICALL Java_vue_NativeVUE_setROM
|
||||
|
||||
// Transfer the ROM data to the emulation state
|
||||
CORE *core = GetCore(env, vue);
|
||||
free(core->vue.rom);
|
||||
if (core->vue.bus.rom != NULL)
|
||||
free(core->vue.bus.rom);
|
||||
vueSetROM(&core->vue, rom, length);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
+27
-28
@@ -6,9 +6,14 @@ import java.util.*;
|
||||
// Simulation of the CPU bus
|
||||
class Bus {
|
||||
|
||||
// Instance fields
|
||||
// Private fields
|
||||
private JavaVUE vue; // Emulation state
|
||||
|
||||
// Package fields
|
||||
byte[] rom; // Cartridge ROM
|
||||
byte[] sram; // Cartridge SRAM
|
||||
byte[] wram; // System WRAM
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@@ -18,6 +23,7 @@ class Bus {
|
||||
// Default constructor
|
||||
Bus(JavaVUE vue) {
|
||||
this.vue = vue;
|
||||
wram = new byte[0x10000];
|
||||
}
|
||||
|
||||
// Read bytes from host memory
|
||||
@@ -40,23 +46,24 @@ class Bus {
|
||||
}
|
||||
|
||||
// Read a value directly from host memory
|
||||
int readMemory(byte[] data, int offset, int type) {
|
||||
int readMemory(byte[] data, int address, int type) {
|
||||
|
||||
// There is no source data
|
||||
if (data == null)
|
||||
return 0;
|
||||
|
||||
// Processing by type
|
||||
address &= data.length - 1;
|
||||
switch (type) {
|
||||
case VUE.S8 : return data[offset];
|
||||
case VUE.U8 : return data[offset] & 0xFF;
|
||||
case VUE.S8 : return data[address];
|
||||
case VUE.U8 : return data[address] & 0xFF;
|
||||
case VUE.S16: return
|
||||
data[offset+1] << 8 | data[offset ] & 0xFF;
|
||||
data[address+1] << 8 | data[address ] & 0xFF;
|
||||
case VUE.U16: return
|
||||
(data[offset+1] & 0xFF) << 8 | data[offset ] & 0xFF;
|
||||
(data[address+1] & 0xFF)<< 8 | data[address ] & 0xFF;
|
||||
case VUE.S32: return
|
||||
data[offset+3] << 24 | (data[offset+2] & 0xFF) << 16 |
|
||||
(data[offset+1] & 0xFF) << 8 | (data[offset ] & 0xFF);
|
||||
data[address+3] <<24 | (data[address+2] & 0xFF)<<16 |
|
||||
(data[address+1] & 0xFF)<< 8 | (data[address ] & 0xFF);
|
||||
}
|
||||
|
||||
return 0; // Unreachable
|
||||
@@ -71,11 +78,11 @@ class Bus {
|
||||
case 4: // Cartridge expansion (not supported)
|
||||
return 0;
|
||||
case 5: return
|
||||
readMemory(vue.wram, address & 0xFFFF , type);
|
||||
readMemory(wram, address & 0xFFFF , type);
|
||||
case 6: return
|
||||
readMemory(vue.sram, address & vue.sram.length - 1, type);
|
||||
readMemory(sram, address & sram.length - 1, type);
|
||||
case 7: return
|
||||
readMemory(vue.rom , address & vue.rom .length - 1, type);
|
||||
readMemory(rom , address & rom .length - 1, type);
|
||||
}
|
||||
return 0; // Unreachable
|
||||
}
|
||||
@@ -98,25 +105,26 @@ class Bus {
|
||||
}
|
||||
|
||||
// Write a value directly to host memory
|
||||
void writeMemory(byte[] data, int offset, int type, int value) {
|
||||
void writeMemory(byte[] data, int address, int type, int value) {
|
||||
|
||||
// There is no source data
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
// Processing by type
|
||||
address &= data.length - 1;
|
||||
switch (type) {
|
||||
case VUE.S32:
|
||||
data[offset + 3] = (byte) (value >> 24);
|
||||
data[offset + 2] = (byte) (value >> 16);
|
||||
data[address + 3] = (byte) (value >> 24);
|
||||
data[address + 2] = (byte) (value >> 16);
|
||||
// Fallthrough
|
||||
case VUE.S16: // Fallthrough
|
||||
case VUE.U16:
|
||||
data[offset + 1] = (byte) (value >> 8);
|
||||
data[address + 1] = (byte) (value >> 8);
|
||||
// Fallthrough
|
||||
case VUE.S8 : // Fallthrough
|
||||
case VUE.U8 :
|
||||
data[offset ] = (byte) value ;
|
||||
data[address ] = (byte) value ;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -125,18 +133,9 @@ class Bus {
|
||||
void writeValue(int address, int type, int value) {
|
||||
address &= ~JavaVUE.TYPE_SIZES[type] + 1;
|
||||
switch (address >> 24 & 7) {
|
||||
case 5:
|
||||
writeMemory(vue.wram,
|
||||
address & 0xFFFF , type, value);
|
||||
break;
|
||||
case 6:
|
||||
writeMemory(vue.sram,
|
||||
address & vue.sram.length - 1, type, value);
|
||||
break;
|
||||
case 7:
|
||||
writeMemory(vue.rom ,
|
||||
address & vue.rom .length - 1, type, value);
|
||||
break;
|
||||
case 5: writeMemory(wram, address, type, value); break;
|
||||
case 6: writeMemory(sram, address, type, value); break;
|
||||
case 7: writeMemory(rom , address, type, value); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
package vue;
|
||||
|
||||
// CPU state
|
||||
class CPU {
|
||||
|
||||
// Private fields
|
||||
private JavaVUE vue; // Emulation state
|
||||
|
||||
// Package fields
|
||||
int cycles; // Cycles until next stage
|
||||
int fetch; // Fetch unit index
|
||||
int stage; // Current processing stage
|
||||
|
||||
// Program registers
|
||||
int[] program;
|
||||
|
||||
// System registers
|
||||
int adtre; // Address Trap Register for Execution
|
||||
int eipc; // Exception/interrupt PC
|
||||
int eipsw; // Exception/interrupt PSW
|
||||
int fepc; // Duplexed exception PC
|
||||
int fepsw; // Duplexed exception PSW
|
||||
int pc; // Program Counter
|
||||
int sr29; // System register 29
|
||||
int sr31; // System register 31
|
||||
|
||||
// Program Status Word
|
||||
int psw_ae; // Address Trap Enable
|
||||
int psw_ep; // Exception Pending
|
||||
int psw_id; // Interrupt Disable
|
||||
int psw_cy; // Carry
|
||||
int psw_fiv; // Floating Reserved Operand
|
||||
int psw_fov; // Floating Overflow
|
||||
int psw_fpr; // Floating Precision
|
||||
int psw_fro; // Floating Reserved Operand
|
||||
int psw_fud; // Floating Underflow
|
||||
int psw_fzd; // Floating Zero Divide
|
||||
int psw_i; // Interrupt Level
|
||||
int psw_np; // NMI Pending
|
||||
int psw_ov; // Overflow
|
||||
int psw_s; // Sign
|
||||
int psw_z; // Zero
|
||||
|
||||
// Cache Control Word
|
||||
int chcw_cec; // Clear Entry Count
|
||||
int chcw_cen; // Clear Entry Number
|
||||
int chcw_icc; // Instruction Cache Clear
|
||||
int chcw_icd; // Instruction Cache Dump
|
||||
int chcw_ice; // Instruction Cache Enable
|
||||
int chcw_icr; // Instruction Cache Restore
|
||||
int chcw_sa; // Spill-Out Base Address
|
||||
|
||||
// Exception Cause Register
|
||||
int ecr_eicc; // Exception/Interrupt Cause Code
|
||||
int ecr_fecc; // Fatal Error Cause Code
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Constants //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Stages
|
||||
static final int FETCH = 0;
|
||||
static final int EXECUTE = 1;
|
||||
static final int HALT = 2;
|
||||
static final int EXCEPTION = 3;
|
||||
static final int FATAL = 4;
|
||||
static final int CLEAR = 5;
|
||||
static final int DUMP = 6;
|
||||
static final int RESTORE = 7;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Constructors //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Default constructor
|
||||
CPU(JavaVUE vue) {
|
||||
program = new int[32];
|
||||
this.vue = vue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Package Methods //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Read a system register
|
||||
int getSystemRegister(int index) {
|
||||
switch (index) {
|
||||
case VUE.ADTRE: return adtre;
|
||||
case VUE.EIPC : return eipc;
|
||||
case VUE.EIPSW: return eipsw;
|
||||
case VUE.FEPC : return fepc;
|
||||
case VUE.FEPSW: return fepsw;
|
||||
case VUE.ECR : return ecr_fecc << 16 | ecr_eicc;
|
||||
case VUE.PIR : return 0x00005346;
|
||||
case VUE.TKCW : return 0x000000E0;
|
||||
case VUE.CHCW : return chcw_ice << 1;
|
||||
case 29 : return sr29;
|
||||
case 30 : return 0x00000004;
|
||||
case 31 : return sr31;
|
||||
case VUE.PSW : return
|
||||
psw_i << 16 | psw_fro << 9 | psw_fpr << 4 |
|
||||
psw_np << 15 | psw_fiv << 8 | psw_cy << 3 |
|
||||
psw_ep << 14 | psw_fzd << 7 | psw_ov << 2 |
|
||||
psw_ae << 13 | psw_fov << 6 | psw_s << 1 |
|
||||
psw_id << 12 | psw_fud << 5 | psw_z
|
||||
;
|
||||
|
||||
// Remaining cases to encourage tableswitch
|
||||
case 8: case 9: case 10: case 11: case 12: case 13: case 14:
|
||||
case 15: case 16: case 17: case 18: case 19: case 20: case 21:
|
||||
case 22: case 23: case 26: case 27: case 28:
|
||||
return 0;
|
||||
}
|
||||
return 1; // Unreachable
|
||||
}
|
||||
|
||||
// System reset
|
||||
void reset() {
|
||||
|
||||
// Configure instance fields
|
||||
cycles = 0;
|
||||
fetch = 0;
|
||||
stage = FETCH;
|
||||
|
||||
// Reset program counter
|
||||
pc = 0xFFFFFFF0;
|
||||
|
||||
// Clear all registers (hardware only sets ECR, PC and PSW)
|
||||
for (int x = 0; x < 32; x++) {
|
||||
program[x] = 0;
|
||||
setSystemRegister(x, 0, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Write a system register
|
||||
int setSystemRegister(int index, int value, boolean debug) {
|
||||
switch (index) {
|
||||
case VUE.ADTRE: return adtre = value & 0xFFFFFFFE;
|
||||
case VUE.EIPC : return eipc = value & 0xFFFFFFFE;
|
||||
case VUE.EIPSW: return eipsw = value & 0x000FF3FF;
|
||||
case VUE.FEPC : return fepc = value & 0xFFFFFFFE;
|
||||
case VUE.FEPSW: return fepsw = value & 0x000FF3FF;
|
||||
case 29 : return sr29 = value;
|
||||
case 31 : return sr31 = debug || value >= 0 ? value : -value;
|
||||
|
||||
case VUE.CHCW :
|
||||
chcw_cen = value >> 20 & 0x00000FFF;
|
||||
chcw_cec = value >> 8 & 0x00000FFF;
|
||||
chcw_sa = value >> 8 & 0x00FFFFFF;
|
||||
chcw_icr = value >> 5 & 1;
|
||||
chcw_icd = value >> 4 & 1;
|
||||
chcw_ice = value >> 1 & 1;
|
||||
chcw_icc = value & 1;
|
||||
|
||||
// Only one of ICC, ICD or ICR is set
|
||||
value &= 0x00000031;
|
||||
if ((value & value - 1) == 0) {
|
||||
// Clear
|
||||
// Dump
|
||||
// Restore
|
||||
}
|
||||
|
||||
return chcw_ice << 1;
|
||||
|
||||
case VUE.PSW :
|
||||
psw_i = value >> 16 & 15; psw_fov = value >> 6 & 1;
|
||||
psw_np = value >> 15 & 1; psw_fud = value >> 5 & 1;
|
||||
psw_ep = value >> 14 & 1; psw_fpr = value >> 4 & 1;
|
||||
psw_ae = value >> 13 & 1; psw_cy = value >> 3 & 1;
|
||||
psw_id = value >> 12 & 1; psw_ov = value >> 2 & 1;
|
||||
psw_fro = value >> 9 & 1; psw_s = value >> 1 & 1;
|
||||
psw_fiv = value >> 8 & 1; psw_z = value & 1;
|
||||
psw_fzd = value >> 7 & 1;
|
||||
return value & 0x000FF3FF;
|
||||
|
||||
// Remaining cases to encourage tableswitch
|
||||
case 4: case 6: case 7: case 8: case 9: case 10: case 11:
|
||||
case 12: case 13: case 14: case 15: case 16: case 17: case 18:
|
||||
case 19: case 20: case 21: case 22: case 23: case 26: case 27:
|
||||
case 28: case 30:
|
||||
return 0;
|
||||
}
|
||||
return 1; // Unreachable
|
||||
}
|
||||
|
||||
// Test a condition
|
||||
int test(int condition) {
|
||||
switch (condition) {
|
||||
case 0: return psw_ov;
|
||||
case 1: return psw_cy;
|
||||
case 2: return psw_z;
|
||||
case 3: return psw_cy | psw_z;
|
||||
case 4: return psw_s;
|
||||
case 5: return 1;
|
||||
case 6: return psw_ov | psw_s;
|
||||
case 7: return psw_ov ^ psw_s | psw_z;
|
||||
}
|
||||
return test(condition & 7) ^ 1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,13 +3,9 @@ package vue;
|
||||
// Java emulation core implementation
|
||||
class JavaVUE extends VUE {
|
||||
|
||||
// Instance fields
|
||||
byte[] rom; // Cartridge ROM
|
||||
byte[] sram; // Cartridge SRAM
|
||||
byte[] wram; // System WRAM
|
||||
|
||||
// Components
|
||||
Bus bus; // Memory bus
|
||||
CPU cpu; // Processor
|
||||
|
||||
|
||||
|
||||
@@ -28,8 +24,8 @@ class JavaVUE extends VUE {
|
||||
|
||||
// Default constructor
|
||||
JavaVUE() {
|
||||
bus = new Bus(this);
|
||||
wram = new byte[0x10000];
|
||||
bus = new Bus(this);
|
||||
cpu = new CPU(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,10 +37,26 @@ class JavaVUE extends VUE {
|
||||
// Release any used resources
|
||||
public void dispose() { }; // No action needed
|
||||
|
||||
// Retrieve a register value
|
||||
public int getRegister(int index, boolean system) {
|
||||
return
|
||||
index == VUE.PC && system ? cpu.pc :
|
||||
index < 0 || index > 31 ? 0 :
|
||||
system ? cpu.getSystemRegister(index) :
|
||||
cpu.program[index]
|
||||
;
|
||||
}
|
||||
|
||||
// Retrieve a copy of the ROM data
|
||||
public byte[] getROM() {
|
||||
var ret = new byte[rom.length];
|
||||
System.arraycopy(rom, 0, ret, 0, ret.length);
|
||||
|
||||
// No ROM data
|
||||
if (bus.rom == null)
|
||||
return null;
|
||||
|
||||
// Copy the ROM data
|
||||
var ret = new byte[bus.rom.length];
|
||||
System.arraycopy(bus.rom, 0, ret, 0, ret.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -79,16 +91,16 @@ class JavaVUE extends VUE {
|
||||
break;
|
||||
case 3: // Fallthrough, unmapped
|
||||
case 4: // Cartridge expansion (not supported)
|
||||
bus.readBytes(null, dest, address, 0 , count);
|
||||
bus.readBytes(null , dest, address, 0 , count);
|
||||
break;
|
||||
case 5: /* System WRAM */
|
||||
bus.readBytes(wram, dest, address, offset, count);
|
||||
bus.readBytes(bus.wram, dest, address, offset, count);
|
||||
break;
|
||||
case 6: /* Cartridge RAM */
|
||||
bus.readBytes(sram, dest, address, offset, count);
|
||||
bus.readBytes(bus.sram, dest, address, offset, count);
|
||||
break;
|
||||
case 7: /* Cartridge ROM */
|
||||
bus.readBytes(rom , dest, address, offset, count);
|
||||
bus.readBytes(bus.rom , dest, address, offset, count);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -96,6 +108,16 @@ class JavaVUE extends VUE {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Specify a register value
|
||||
public int setRegister(int index, boolean system, int value) {
|
||||
return
|
||||
index == VUE.PC && system ? cpu.pc = value & 0xFFFFFFFE :
|
||||
index < 0 || index > 31 ? 0 :
|
||||
system ? cpu.setSystemRegister(index, value, true) :
|
||||
index == 0 ? 0 : cpu.program[index]
|
||||
;
|
||||
}
|
||||
|
||||
// Provide new ROM data
|
||||
public boolean setROM(byte[] data, int offset, int length) {
|
||||
|
||||
@@ -109,8 +131,8 @@ class JavaVUE extends VUE {
|
||||
) return false;
|
||||
|
||||
// Accept the new ROM data
|
||||
rom = new byte[length];
|
||||
System.arraycopy(data, offset, rom, 0, length);
|
||||
bus.rom = new byte[length];
|
||||
System.arraycopy(data, offset, bus.rom, 0, length);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -135,13 +157,13 @@ class JavaVUE extends VUE {
|
||||
// Process by component
|
||||
switch (address >> 24 & 7) {
|
||||
case 5: /* System WRAM */
|
||||
bus.writeBytes(wram, src, address, offset, count);
|
||||
bus.writeBytes(bus.wram, src, address, offset, count);
|
||||
break;
|
||||
case 6: /* Cartridge RAM */
|
||||
bus.writeBytes(sram, src, address, offset, count);
|
||||
bus.writeBytes(bus.sram, src, address, offset, count);
|
||||
break;
|
||||
case 7: /* Cartridge ROM */
|
||||
bus.writeBytes(rom , src, address, offset, count);
|
||||
bus.writeBytes(bus.rom , src, address, offset, count);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ class NativeVUE extends VUE {
|
||||
// Release any used resources
|
||||
public native void dispose();
|
||||
|
||||
// Retrieve a register value
|
||||
public native int getRegister(int index, boolean system);
|
||||
|
||||
// Retrieve a copy of the ROM data
|
||||
public native byte[] getROM();
|
||||
|
||||
@@ -36,6 +39,9 @@ class NativeVUE extends VUE {
|
||||
public native boolean read(int address, byte[] dest, int offset,
|
||||
int length);
|
||||
|
||||
// Specify a register value
|
||||
public native int setRegister(int index, boolean system, int value);
|
||||
|
||||
// Provide new ROM data
|
||||
public native boolean setROM(byte[] data, int offset, int length);
|
||||
|
||||
|
||||
@@ -19,6 +19,19 @@ public abstract class VUE {
|
||||
public static final int U16 = 3;
|
||||
public static final int S32 = 4;
|
||||
|
||||
// System register indexes
|
||||
public static final int ADTRE = 25;
|
||||
public static final int CHCW = 24;
|
||||
public static final int ECR = 4;
|
||||
public static final int EIPC = 0;
|
||||
public static final int EIPSW = 1;
|
||||
public static final int FEPC = 2;
|
||||
public static final int FEPSW = 3;
|
||||
public static final int PC = -1;
|
||||
public static final int PIR = 6;
|
||||
public static final int PSW = 5;
|
||||
public static final int TKCW = 7;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@@ -55,6 +68,9 @@ public abstract class VUE {
|
||||
// Release any used resources
|
||||
public abstract void dispose();
|
||||
|
||||
// Retrieve a register value
|
||||
public abstract int getRegister(int index, boolean system);
|
||||
|
||||
// Retrieve a copy of the ROM data
|
||||
public abstract byte[] getROM();
|
||||
|
||||
@@ -65,6 +81,9 @@ public abstract class VUE {
|
||||
public abstract boolean read(int address, byte[] dest, int offset,
|
||||
int length);
|
||||
|
||||
// Specify a register value
|
||||
public abstract int setRegister(int index, boolean system, int value);
|
||||
|
||||
// Provide new ROM data
|
||||
public abstract boolean setROM(byte[] data, int offset, int length);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user