pvbemu/src/desktop/vue/JavaVUE.java

196 lines
6.0 KiB
Java

package vue;
// Java emulation core implementation
class JavaVUE extends VUE {
// Instance fields
Instruction inst; // Instruction state
// Components
Bus bus; // Memory bus
CPU cpu; // Processor
///////////////////////////////////////////////////////////////////////////
// Constants //
///////////////////////////////////////////////////////////////////////////
// Memory access type sizes
static final int[] TYPE_SIZES = { 1, 1, 2, 2, 4 };
///////////////////////////////////////////////////////////////////////////
// Constructors //
///////////////////////////////////////////////////////////////////////////
// Default constructor
JavaVUE() {
bus = new Bus(this);
cpu = new CPU(this);
inst = new Instruction();
reset();
}
///////////////////////////////////////////////////////////////////////////
// Public Methods //
///////////////////////////////////////////////////////////////////////////
// Release any used resources
public void dispose() { }; // No action needed
// Retrieve a register value
public int getRegister(int index, boolean system) {
// Non-indexed registers
if (system) switch (index) {
case VUE.JUMP_FROM: return
cpu.jumpFrom[cpu.psw_np != 0 ? 2 : cpu.psw_ep];
case VUE.JUMP_TO : return
cpu.jumpTo [cpu.psw_np != 0 ? 2 : cpu.psw_ep];
case VUE.PC : return cpu.pc;
}
// Indexed registers
return
index < 0 || index > 31 ? 0 :
system ? cpu.getSystemRegister(index) :
cpu.program[index]
;
}
// Retrieve a copy of the ROM data
public byte[] getROM() {
// 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;
}
// Determine whether the context is native-backed
public boolean isNative() {
return false;
}
// Read bytes from the CPU bus
public boolean read(int address, byte[] dest, int offset, int length) {
int count = 0; // Bytes to read in one iteration
// Error checking
if (
dest == null ||
offset < 0 ||
length < 0 ||
offset + length > dest.length
) return false;
// Perform the operation
for (; length > 0; address += count, length -= count, offset += count){
// Determine the maximum number of bytes to process at once
count = Math.min(length, 0x01000000 - (address & 0x00FFFFFF));
// Process by component
switch (address >> 24 & 7) {
case 1: // VSU
// Will support debug reads
bus.readBytes(null, dest, address, 0 , count);
break;
case 3: // Fallthrough, unmapped
case 4: // Cartridge expansion (not supported)
bus.readBytes(null , dest, address, 0 , count);
break;
case 5: /* System WRAM */
bus.readBytes(bus.wram, dest, address, offset, count);
break;
case 6: /* Cartridge RAM */
bus.readBytes(bus.sram, dest, address, offset, count);
break;
case 7: /* Cartridge ROM */
bus.readBytes(bus.rom , dest, address, offset, count);
break;
}
};
return true;
}
// Initialize all system components
public void reset() {
bus.reset();
cpu.reset();
}
// 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] = value)
;
}
// Provide new ROM data
public boolean setROM(byte[] data, int offset, int length) {
// Error checking
if (
data == null ||
offset < 0 ||
length < 1024 || length > 0x01000000 ||
(length & length - 1) != 0 ||
offset + length > data.length
) return false;
// Accept the new ROM data
bus.rom = new byte[length];
System.arraycopy(data, offset, bus.rom, 0, length);
return true;
}
// Write bytes to the CPU bus
public boolean write(int address, byte[] src, int offset, int length) {
int count = 0; // Bytes to process in one iteration
// Error checking
if (
src == null ||
offset < 0 ||
length < 0 ||
offset + length > src.length
) return false;
// Perform the operation
for (; length > 0; address += count, length -= count, offset += count){
// Determine the maximum number of bytes to process at once
count = Math.min(length, 0x01000000 - (address & 0x00FFFFFF));
// Process by component
switch (address >> 24 & 7) {
case 5: /* System WRAM */
bus.writeBytes(bus.wram, src, address, offset, count);
break;
case 6: /* Cartridge RAM */
bus.writeBytes(bus.sram, src, address, offset, count);
break;
case 7: /* Cartridge ROM */
bus.writeBytes(bus.rom , src, address, offset, count);
break;
}
};
return true;
}
}