Implementing CPU emulation logic
This commit is contained in:
parent
a98c35ee8e
commit
d1b8e293c3
|
@ -233,16 +233,17 @@ typedef struct {
|
||||||
* Function Prototypes *
|
* Function Prototypes *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
VUEAPI int32_t vueEmulate (VUE *vue, int32_t maxCycles);
|
VUEAPI int32_t vueEmulate (VUE *vue, int32_t maxCycles);
|
||||||
VUEAPI int32_t vueGetRegister(VUE *vue, int32_t index, vbool system);
|
VUEAPI int32_t vueGetBreakCode(VUE *vue);
|
||||||
VUEAPI void vueInitialize (VUE *vue);
|
VUEAPI int32_t vueGetRegister (VUE *vue, int32_t index, vbool system);
|
||||||
VUEAPI int32_t vueRead (VUE *vue, uint32_t address, int32_t type);
|
VUEAPI void vueInitialize (VUE *vue);
|
||||||
VUEAPI vbool vueReadBytes (VUE *vue, uint32_t address, uint8_t *dest, uint32_t length);
|
VUEAPI int32_t vueRead (VUE *vue, uint32_t address, int32_t type);
|
||||||
VUEAPI void vueReset (VUE *vue);
|
VUEAPI vbool vueReadBytes (VUE *vue, uint32_t address, uint8_t *dest, uint32_t length);
|
||||||
VUEAPI int32_t vueSetRegister(VUE *vue, int32_t index, vbool system, int32_t value);
|
VUEAPI void vueReset (VUE *vue);
|
||||||
VUEAPI vbool vueSetROM (VUE *vue, uint8_t *rom, uint32_t size);
|
VUEAPI int32_t vueSetRegister (VUE *vue, int32_t index, vbool system, int32_t value);
|
||||||
VUEAPI void vueWrite (VUE *vue, uint32_t address, int32_t type, int32_t value);
|
VUEAPI vbool vueSetROM (VUE *vue, uint8_t *rom, uint32_t size);
|
||||||
VUEAPI vbool vueWriteBytes (VUE *vue, uint32_t address, uint8_t *src, uint32_t length);
|
VUEAPI void vueWrite (VUE *vue, uint32_t address, int32_t type, int32_t value);
|
||||||
|
VUEAPI vbool vueWriteBytes (VUE *vue, uint32_t address, uint8_t *src, uint32_t length);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -198,6 +198,11 @@ int32_t vueEmulate(VUE *vue, int32_t maxCycles) {
|
||||||
return maxCycles;
|
return maxCycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Retrieve the application break code */
|
||||||
|
int32_t vueGetBreakCode(VUE *vue) {
|
||||||
|
return vue == NULL ? 0 : vue->breakCode;
|
||||||
|
}
|
||||||
|
|
||||||
/* Retrieve the value of a register */
|
/* Retrieve the value of a register */
|
||||||
int32_t vueGetRegister(VUE *vue, int32_t index, vbool system) {
|
int32_t vueGetRegister(VUE *vue, int32_t index, vbool system) {
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ class CPUWindow extends ChildWindow {
|
||||||
// Private Methods //
|
// Private Methods //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Determine the maximum character width of a hex character in a font
|
// Determine the maximum width of a hex character in a font
|
||||||
private static Dimension measureHex(Font font) {
|
private static Dimension measureHex(Font font) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
Dimension size = null;
|
Dimension size = null;
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package vue;
|
||||||
|
|
||||||
|
// Access state
|
||||||
|
public class Access {
|
||||||
|
|
||||||
|
// Instance fields
|
||||||
|
public int address; // CPU bus address
|
||||||
|
public int fetch; // Index of machine code unit
|
||||||
|
public int type; // Data type
|
||||||
|
public int value; // Value read/to write
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructors //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
Access() { }
|
||||||
|
|
||||||
|
}
|
|
@ -10,12 +10,15 @@ class CPU {
|
||||||
private JavaVUE vue; // Emulation state
|
private JavaVUE vue; // Emulation state
|
||||||
|
|
||||||
// Package fields
|
// Package fields
|
||||||
int cycles; // Cycles until next stage
|
Access access; // Access state
|
||||||
int fetch; // Fetch unit index
|
int cycles; // Cycles until next stage
|
||||||
Instruction inst; // Instruction state
|
int exception; // Exception code
|
||||||
int[] jumpFrom; // Source PCs of most recent jumps
|
int fetch; // Fetch unit index
|
||||||
int[] jumpTo; // Destination PCs of most recent jumps
|
Instruction inst; // Instruction state
|
||||||
int stage; // Current processing stage
|
int irq; // Interrupt lines
|
||||||
|
int[] jumpFrom; // Source PCs of most recent jumps
|
||||||
|
int[] jumpTo; // Destination PCs of most recent jumps
|
||||||
|
int stage; // Current processing stage
|
||||||
|
|
||||||
// Program registers
|
// Program registers
|
||||||
int[] program;
|
int[] program;
|
||||||
|
@ -67,14 +70,23 @@ class CPU {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Stages
|
// Stages
|
||||||
static final int FETCH = 0;
|
static final int FATAL = -1;
|
||||||
static final int EXECUTE = 1;
|
static final int FETCH = 0;
|
||||||
static final int HALT = 2;
|
static final int EXECUTE = 1;
|
||||||
static final int EXCEPTION = 3;
|
static final int EXCEPTION = 2;
|
||||||
static final int FATAL = 4;
|
static final int HALT = 3;
|
||||||
static final int CLEAR = 5;
|
static final int CLEAR = 4;
|
||||||
static final int DUMP = 6;
|
static final int DUMP = 5;
|
||||||
static final int RESTORE = 7;
|
static final int RESTORE = 6;
|
||||||
|
|
||||||
|
// Instruction cycle counts
|
||||||
|
private static final byte[] CYCLES = {
|
||||||
|
1, 1, 28, 1, 1, 1, 1, 1, 1, 26, 12, 1, 1, 10, 14, 16,
|
||||||
|
38, 44, 36, 1, 5, 5, 5, 3, 3, 3, 5, 5, 5, 8, 1, 1,
|
||||||
|
1, 1, 1, 9, 13, 30, 13, 1, 1, 1, 1, 1, 1, 4, 4, 4,
|
||||||
|
10, 22, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 4, 4,
|
||||||
|
4, 8, 1, 28, 15, 14, 6, 1, 1, 1, 1, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,6 +96,8 @@ class CPU {
|
||||||
|
|
||||||
// Default constructor
|
// Default constructor
|
||||||
CPU(JavaVUE vue) {
|
CPU(JavaVUE vue) {
|
||||||
|
access = new Access();
|
||||||
|
inst = new Instruction();
|
||||||
jumpFrom = new int[3];
|
jumpFrom = new int[3];
|
||||||
jumpTo = new int[3];
|
jumpTo = new int[3];
|
||||||
program = new int[32];
|
program = new int[32];
|
||||||
|
@ -96,6 +110,33 @@ class CPU {
|
||||||
// Package Methods //
|
// Package Methods //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Process the simulation
|
||||||
|
void emulate(int cycles) {
|
||||||
|
|
||||||
|
// The CPU is in permanent halt
|
||||||
|
if (stage == FATAL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Process for the given number of cycles
|
||||||
|
do {
|
||||||
|
|
||||||
|
// The next event occurs after the given number of cycles
|
||||||
|
if (this.cycles > cycles) {
|
||||||
|
this.cycles -= cycles;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processing by stage
|
||||||
|
switch (stage) {
|
||||||
|
case FETCH : if (fetch ()) return;
|
||||||
|
case EXECUTE : if (execute ()) return;
|
||||||
|
case HALT : testException(); break;
|
||||||
|
case EXCEPTION: if (exception()) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (cycles > 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Read a system register
|
// Read a system register
|
||||||
int getSystemRegister(int index) {
|
int getSystemRegister(int index) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
|
@ -131,9 +172,11 @@ class CPU {
|
||||||
void reset() {
|
void reset() {
|
||||||
|
|
||||||
// Configure instance fields
|
// Configure instance fields
|
||||||
cycles = 0; // Duration of first fetch
|
cycles = 0; // Duration of first fetch
|
||||||
fetch = 0;
|
exception = 0;
|
||||||
stage = FETCH;
|
fetch = 0;
|
||||||
|
irq = 0;
|
||||||
|
stage = FETCH;
|
||||||
|
|
||||||
// Clear all registers (hardware only sets ECR, PC and PSW)
|
// Clear all registers (hardware only sets ECR, PC and PSW)
|
||||||
for (int x = 0; x < 32; x++) {
|
for (int x = 0; x < 32; x++) {
|
||||||
|
@ -224,4 +267,227 @@ class CPU {
|
||||||
return test(condition & 7) ^ 1;
|
return test(condition & 7) ^ 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine the number of CPU cycles until something can happen
|
||||||
|
int until(int cycles) {
|
||||||
|
if (stage == FATAL || stage == HALT)
|
||||||
|
return cycles;
|
||||||
|
return cycles < 0 ? this.cycles : Math.min(cycles, this.cycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Private Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Operations for exception stage
|
||||||
|
private boolean exception() {
|
||||||
|
|
||||||
|
// Application callback
|
||||||
|
if (vue.onException != null) {
|
||||||
|
vue.breakCode = vue.onException.call(vue, exception);
|
||||||
|
if (vue.breakCode != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
exception &= 0xFFFF;
|
||||||
|
boolean isIRQ = (exception & 0xFF00) == 0xFE00;
|
||||||
|
int psw = getSystemRegister(VUE.PSW);
|
||||||
|
|
||||||
|
// Fatal exception
|
||||||
|
if (psw_np != 0) {
|
||||||
|
vue.write(0x00000000, VUE.S32, 0xFFFF0000 | exception);
|
||||||
|
vue.write(0x00000004, VUE.S32, psw);
|
||||||
|
vue.write(0x00000008, VUE.S32, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duplexed exception
|
||||||
|
if (psw_ep != 0) {
|
||||||
|
ecr_fecc = exception;
|
||||||
|
fepc = pc;
|
||||||
|
fepsw = psw;
|
||||||
|
pc = 0xFFFFFFD0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regular exception
|
||||||
|
else {
|
||||||
|
ecr_eicc = exception;
|
||||||
|
eipc = pc;
|
||||||
|
eipsw = psw;
|
||||||
|
pc = 0xFFFF0000 | exception & 0xFFF0;
|
||||||
|
if (pc == 0xFFFFFF70) // FIV
|
||||||
|
pc = 0xFFFFFF60;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interrupt
|
||||||
|
if (isIRQ)
|
||||||
|
psw_i = Math.min(15, exception >> 4 & 15);
|
||||||
|
|
||||||
|
// Common processing
|
||||||
|
exception = 0;
|
||||||
|
psw_ae = 0;
|
||||||
|
psw_id = 1;
|
||||||
|
stage = FETCH;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operations for execute stage
|
||||||
|
private boolean execute() {
|
||||||
|
|
||||||
|
// Application callback
|
||||||
|
if (vue.onExecute != null) {
|
||||||
|
vue.breakCode = vue.onExecute.call(vue, inst);
|
||||||
|
if (vue.breakCode != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the default number of cycles for the instruction
|
||||||
|
if (inst.id >= 0 && inst.id <= 75)
|
||||||
|
cycles = CYCLES[inst.id];
|
||||||
|
|
||||||
|
// Processing by instruction ID
|
||||||
|
switch (inst.id) {
|
||||||
|
//case VUE.ADD_IMM: ADD_IMM(); break;
|
||||||
|
//case VUE.ADD_REG: ADD_REG(); break;
|
||||||
|
//case VUE.ADDF_S : ADDF_S (); break;
|
||||||
|
//case VUE.ADDI : ADDI (); break;
|
||||||
|
//case VUE.AND : AND (); break;
|
||||||
|
//case VUE.ANDBSU : ANDBSU (); break;
|
||||||
|
//case VUE.ANDI : ANDI (); break;
|
||||||
|
//case VUE.ANDNBSU: ANDNBSU(); break;
|
||||||
|
//case VUE.BCOND : BCOND (); break;
|
||||||
|
//case VUE.CAXI : CAXI (); break;
|
||||||
|
//case VUE.CLI : CLI (); break;
|
||||||
|
//case VUE.CMP_IMM: CMP_IMM(); break;
|
||||||
|
//case VUE.CMP_REG: CMP_REG(); break;
|
||||||
|
//case VUE.CMPF_S : CMPF_S (); break;
|
||||||
|
//case VUE.CVT_SW : CVT_SW (); break;
|
||||||
|
//case VUE.CVT_WS : CVT_WS (); break;
|
||||||
|
//case VUE.DIV : DIV (); break;
|
||||||
|
//case VUE.DIVF_S : DIVF_S (); break;
|
||||||
|
//case VUE.DIVU : DIVU (); break;
|
||||||
|
//case VUE.HALT : HALT (); break;
|
||||||
|
//case VUE.IN_B : IN_B (); break;
|
||||||
|
//case VUE.IN_H : IN_H (); break;
|
||||||
|
//case VUE.IN_W : IN_W (); break;
|
||||||
|
//case VUE.JAL : JAL (); break;
|
||||||
|
//case VUE.JMP : JMP (); break;
|
||||||
|
//case VUE.JR : JR (); break;
|
||||||
|
//case VUE.LD_B : LD_B (); break;
|
||||||
|
//case VUE.LD_H : LD_H (); break;
|
||||||
|
//case VUE.LD_W : LD_W (); break;
|
||||||
|
//case VUE.LDSR : LDSR (); break;
|
||||||
|
//case VUE.MOV_IMM: MOV_IMM(); break;
|
||||||
|
//case VUE.MOV_REG: MOV_REG(); break;
|
||||||
|
//case VUE.MOVBSU : MOVBSU (); break;
|
||||||
|
//case VUE.MOVEA : MOVEA (); break;
|
||||||
|
//case VUE.MOVHI : MOVHI (); break;
|
||||||
|
//case VUE.MPYHW : MPYHW (); break;
|
||||||
|
//case VUE.MUL : MUL (); break;
|
||||||
|
//case VUE.MULF_S : MULF_S (); break;
|
||||||
|
//case VUE.MULU : MULU (); break;
|
||||||
|
//case VUE.NOT : NOT (); break;
|
||||||
|
//case VUE.NOTBSU : NOTBSU (); break;
|
||||||
|
//case VUE.OR : OR (); break;
|
||||||
|
//case VUE.ORBSU : ORBSU (); break;
|
||||||
|
//case VUE.ORI : ORI (); break;
|
||||||
|
//case VUE.ORNBSU : ORNBSU (); break;
|
||||||
|
//case VUE.OUT_B : OUT_B (); break;
|
||||||
|
//case VUE.OUT_H : OUT_H (); break;
|
||||||
|
//case VUE.OUT_W : OUT_W (); break;
|
||||||
|
//case VUE.RETI : RETI (); break;
|
||||||
|
//case VUE.REV : REV (); break;
|
||||||
|
//case VUE.SAR_IMM: SAR_IMM(); break;
|
||||||
|
//case VUE.SAR_REG: SAR_REG(); break;
|
||||||
|
//case VUE.SCH0BSD: SCH0BSD(); break;
|
||||||
|
//case VUE.SCH0BSU: SCH0BSU(); break;
|
||||||
|
//case VUE.SCH1BSD: SCH1BSD(); break;
|
||||||
|
//case VUE.SCH1BSU: SCH1BSU(); break;
|
||||||
|
//case VUE.SEI : SEI (); break;
|
||||||
|
//case VUE.SETF : SETF (); break;
|
||||||
|
//case VUE.SHL_IMM: SHL_IMM(); break;
|
||||||
|
//case VUE.SHL_REG: SHL_REG(); break;
|
||||||
|
//case VUE.SHR_IMM: SHR_IMM(); break;
|
||||||
|
//case VUE.SHR_REG: SHR_REG(); break;
|
||||||
|
//case VUE.ST_B : ST_B (); break;
|
||||||
|
//case VUE.ST_H : ST_H (); break;
|
||||||
|
//case VUE.ST_W : ST_W (); break;
|
||||||
|
//case VUE.STSR : STSR (); break;
|
||||||
|
//case VUE.SUB : SUB (); break;
|
||||||
|
//case VUE.SUBF_S : SUBF_S (); break;
|
||||||
|
//case VUE.TRAP : TRAP (); break;
|
||||||
|
//case VUE.TRNC_SW: TRNC_SW(); break;
|
||||||
|
//case VUE.XB : XB (); break;
|
||||||
|
//case VUE.XH : XH (); break;
|
||||||
|
//case VUE.XOR : XOR (); break;
|
||||||
|
//case VUE.XORBSU : XORBSU (); break;
|
||||||
|
//case VUE.XORI : XORI (); break;
|
||||||
|
//case VUE.XORNBSU: XORNBSU(); break;
|
||||||
|
default: exception = 0xFF90; // Invalid instruction
|
||||||
|
}
|
||||||
|
|
||||||
|
// Common processing
|
||||||
|
pc += inst.size;
|
||||||
|
program[0] = 0;
|
||||||
|
testException();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operations for fetch stage
|
||||||
|
private boolean fetch() {
|
||||||
|
|
||||||
|
// Read the bits from the bus
|
||||||
|
access.address = pc + (fetch << 1);
|
||||||
|
access.fetch = fetch;
|
||||||
|
access.type = VUE.U16;
|
||||||
|
access.value = vue.read(access.address, VUE.U16);
|
||||||
|
|
||||||
|
// Application callback
|
||||||
|
if (vue.onRead != null) {
|
||||||
|
vue.breakCode = vue.onRead.call(vue, access);
|
||||||
|
if (vue.breakCode != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First unit
|
||||||
|
if (fetch == 0) {
|
||||||
|
inst.bits = access.value << 16;
|
||||||
|
if (Instruction.size(access.value & 0x3F) == 4) {
|
||||||
|
fetch = 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second unit
|
||||||
|
else {
|
||||||
|
inst.bits |= access.value & 0xFFFF;
|
||||||
|
fetch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the instruction and advance to execute stage
|
||||||
|
inst.decode(inst.bits);
|
||||||
|
stage = EXECUTE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for an exception or interrupt
|
||||||
|
private void testException() {
|
||||||
|
|
||||||
|
// Check for an interrupt
|
||||||
|
if (irq != 0 && (exception | psw_id | psw_ep | psw_np) == 0) {
|
||||||
|
int level;
|
||||||
|
for (level = 4; level >= 0; level--)
|
||||||
|
if ((irq >> level & 1) != 0)
|
||||||
|
break;
|
||||||
|
exception = 0xFE00 | level << 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for an exception
|
||||||
|
if (exception != 0) {
|
||||||
|
cycles = 0;
|
||||||
|
stage = EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,15 @@ import java.util.*;
|
||||||
// Java emulation core implementation
|
// Java emulation core implementation
|
||||||
class JavaVUE extends VUE {
|
class JavaVUE extends VUE {
|
||||||
|
|
||||||
// State fields
|
|
||||||
int breakCode; // Application break code
|
|
||||||
byte[] wram; // System WRAM
|
|
||||||
|
|
||||||
// Package fields
|
// Package fields
|
||||||
CPU cpu; // Processor
|
int breakCode; // Application break code
|
||||||
GamePak pak; // Game pak
|
CPU cpu; // Processor
|
||||||
|
OnException onException; // Exception callback handler
|
||||||
|
OnExecute onExecute; // Execute callback handler
|
||||||
|
OnRead onRead; // Read callback handler
|
||||||
|
OnWrite onWrite; // Write callback handler
|
||||||
|
GamePak pak; // Game pak
|
||||||
|
byte[] wram; // System WRAM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,13 +55,19 @@ class JavaVUE extends VUE {
|
||||||
do {
|
do {
|
||||||
|
|
||||||
// Determine the number of cycles during which nothing will happen
|
// Determine the number of cycles during which nothing will happen
|
||||||
int cycles = maxCycles;
|
int cycles = -1;
|
||||||
//cycles = cpu .until(cycles);
|
|
||||||
//cycles = pad .until(cycles);
|
//cycles = pad .until(cycles);
|
||||||
//cycles = link .until(cycles);
|
//cycles = link .until(cycles);
|
||||||
//cycles = timer.until(cycles);
|
//cycles = timer.until(cycles);
|
||||||
//cycles = vip .until(cycles);
|
//cycles = vip .until(cycles);
|
||||||
//cycles = vsu .until(cycles);
|
//cycles = vsu .until(cycles);
|
||||||
|
cycles = cpu .until(cycles);
|
||||||
|
|
||||||
|
// Range checking
|
||||||
|
if (cycles == -1) // No activity on any component
|
||||||
|
break;
|
||||||
|
if (maxCycles >= 0) // Restrict to given number of cycles
|
||||||
|
cycles = Math.min(cycles, maxCycles);
|
||||||
|
|
||||||
// Process all system components
|
// Process all system components
|
||||||
breakCode = 0;
|
breakCode = 0;
|
||||||
|
@ -68,7 +76,7 @@ class JavaVUE extends VUE {
|
||||||
//timer.emulate(cycles);
|
//timer.emulate(cycles);
|
||||||
//vip .emulate(cycles);
|
//vip .emulate(cycles);
|
||||||
//vsu .emulate(cycles);
|
//vsu .emulate(cycles);
|
||||||
//cpu .emulate(cycles);
|
cpu .emulate(cycles);
|
||||||
|
|
||||||
// An application break was requested
|
// An application break was requested
|
||||||
if (breakCode != 0)
|
if (breakCode != 0)
|
||||||
|
@ -80,7 +88,12 @@ class JavaVUE extends VUE {
|
||||||
} while (maxCycles != 0);
|
} while (maxCycles != 0);
|
||||||
|
|
||||||
// A break condition has occurred
|
// A break condition has occurred
|
||||||
return maxCycles;
|
return Math.max(0, maxCycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the application break code
|
||||||
|
public int getBreakCode() {
|
||||||
|
return breakCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve a register value
|
// Retrieve a register value
|
||||||
|
@ -293,7 +306,7 @@ class JavaVUE extends VUE {
|
||||||
// Write a value to a byte buffer
|
// Write a value to a byte buffer
|
||||||
static void writeBuffer(byte[] data, int address, int type, int value) {
|
static void writeBuffer(byte[] data, int address, int type, int value) {
|
||||||
|
|
||||||
// Error checking
|
// The destination does not exist
|
||||||
if (data == null)
|
if (data == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,13 @@ JNIEXPORT jint JNICALL Java_vue_NativeVUE_emulate
|
||||||
return vueEmulate(&core->vue, maxCycles);
|
return vueEmulate(&core->vue, maxCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retrieve the application break code
|
||||||
|
JNIEXPORT jint JNICALL Java_vue_NativeVUE_getRegister
|
||||||
|
(JNIEnv *env, jobject vue) {
|
||||||
|
CORE *core = GetCore(env, vue);
|
||||||
|
return vueGetBreakCode(&core->vue);
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve a register value
|
// Retrieve a register value
|
||||||
JNIEXPORT jint JNICALL Java_vue_NativeVUE_getRegister
|
JNIEXPORT jint JNICALL Java_vue_NativeVUE_getRegister
|
||||||
(JNIEnv *env, jobject vue, jint index, jboolean system) {
|
(JNIEnv *env, jobject vue, jint index, jboolean system) {
|
||||||
|
|
|
@ -29,6 +29,9 @@ class NativeVUE extends VUE {
|
||||||
// Process the simulation
|
// Process the simulation
|
||||||
public native int emulate(int maxCycles);
|
public native int emulate(int maxCycles);
|
||||||
|
|
||||||
|
// Retrieve the application break code
|
||||||
|
public native int getBreakCode();
|
||||||
|
|
||||||
// Retrieve a register value
|
// Retrieve a register value
|
||||||
public native int getRegister(int index, boolean system);
|
public native int getRegister(int index, boolean system);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,17 @@ public abstract class VUE {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Types //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public interface OnException { int call(VUE vue, int code ); }
|
||||||
|
public interface OnExecute { int call(VUE vue, Instruction inst ); }
|
||||||
|
public interface OnRead { int call(VUE vue, Access access); }
|
||||||
|
public interface OnWrite { int call(VUE vue, Access access); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Constants //
|
// Constants //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -161,6 +172,9 @@ public abstract class VUE {
|
||||||
// Process the simulation
|
// Process the simulation
|
||||||
public abstract int emulate(int maxCycles);
|
public abstract int emulate(int maxCycles);
|
||||||
|
|
||||||
|
// Retrieve the application break code
|
||||||
|
public abstract int getBreakCode();
|
||||||
|
|
||||||
// Retrieve a register value
|
// Retrieve a register value
|
||||||
public abstract int getRegister(int index, boolean system);
|
public abstract int getRegister(int index, boolean system);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue