pvbemu/src/desktop/vue/JavaVUE.java

196 lines
6.0 KiB
Java
Raw Normal View History

2020-08-03 02:21:59 +00:00
package vue;
// Java emulation core implementation
class JavaVUE extends VUE {
2020-08-03 02:21:59 +00:00
// Instance fields
Instruction inst; // Instruction state
2020-08-05 02:17:56 +00:00
// Components
Bus bus; // Memory bus
2020-08-06 01:40:23 +00:00
CPU cpu; // Processor
///////////////////////////////////////////////////////////////////////////
// Constants //
///////////////////////////////////////////////////////////////////////////
// Memory access type sizes
2020-08-05 02:17:56 +00:00
static final int[] TYPE_SIZES = { 1, 1, 2, 2, 4 };
2020-08-03 02:21:59 +00:00
///////////////////////////////////////////////////////////////////////////
// Constructors //
///////////////////////////////////////////////////////////////////////////
// Default constructor
JavaVUE() {
bus = new Bus(this);
cpu = new CPU(this);
inst = new Instruction();
2020-08-06 21:37:05 +00:00
reset();
2020-08-03 02:21:59 +00:00
}
///////////////////////////////////////////////////////////////////////////
// Public Methods //
///////////////////////////////////////////////////////////////////////////
// Release any used resources
public void dispose() { }; // No action needed
2020-08-06 01:40:23 +00:00
// Retrieve a register value
public int getRegister(int index, boolean system) {
2020-08-07 19:21:03 +00:00
// 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];
2020-08-07 19:21:03 +00:00
case VUE.PC : return cpu.pc;
}
// Indexed registers
2020-08-06 01:40:23 +00:00
return
index < 0 || index > 31 ? 0 :
system ? cpu.getSystemRegister(index) :
cpu.program[index]
;
}
2020-08-03 02:21:59 +00:00
// Retrieve a copy of the ROM data
public byte[] getROM() {
2020-08-06 01:40:23 +00:00
// 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);
2020-08-03 02:21:59 +00:00
return ret;
}
// Determine whether the context is native-backed
public boolean isNative() {
return false;
}
2020-08-05 02:17:56 +00:00
// 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
2020-08-05 02:17:56 +00:00
if (
dest == null ||
offset < 0 ||
length < 0 ||
2020-08-05 02:17:56 +00:00
offset + length > dest.length
) return false;
// Perform the operation
2020-08-05 02:17:56 +00:00
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)
2020-08-06 01:40:23 +00:00
bus.readBytes(null , dest, address, 0 , count);
2020-08-05 02:17:56 +00:00
break;
case 5: /* System WRAM */
2020-08-06 01:40:23 +00:00
bus.readBytes(bus.wram, dest, address, offset, count);
2020-08-05 02:17:56 +00:00
break;
case 6: /* Cartridge RAM */
2020-08-06 01:40:23 +00:00
bus.readBytes(bus.sram, dest, address, offset, count);
2020-08-05 02:17:56 +00:00
break;
case 7: /* Cartridge ROM */
2020-08-06 01:40:23 +00:00
bus.readBytes(bus.rom , dest, address, offset, count);
2020-08-05 02:17:56 +00:00
break;
}
};
return true;
}
2020-08-06 21:37:05 +00:00
// Initialize all system components
public void reset() {
bus.reset();
cpu.reset();
}
2020-08-06 01:40:23 +00:00
// 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) :
2020-08-06 21:37:05 +00:00
index == 0 ? 0 : (cpu.program[index] = value)
2020-08-06 01:40:23 +00:00
;
}
2020-08-03 02:21:59 +00:00
// 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;
2020-08-03 02:21:59 +00:00
// Accept the new ROM data
2020-08-06 01:40:23 +00:00
bus.rom = new byte[length];
System.arraycopy(data, offset, bus.rom, 0, length);
2020-08-03 02:21:59 +00:00
return true;
}
2020-08-05 02:17:56 +00:00
// 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 */
2020-08-06 01:40:23 +00:00
bus.writeBytes(bus.wram, src, address, offset, count);
2020-08-05 02:17:56 +00:00
break;
case 6: /* Cartridge RAM */
2020-08-06 01:40:23 +00:00
bus.writeBytes(bus.sram, src, address, offset, count);
2020-08-05 02:17:56 +00:00
break;
case 7: /* Cartridge ROM */
2020-08-06 01:40:23 +00:00
bus.writeBytes(bus.rom , src, address, offset, count);
2020-08-05 02:17:56 +00:00
break;
}
};
return true;
}
2020-08-03 02:21:59 +00:00
}