Revisions to CPU register interface
This commit is contained in:
parent
7d8d33158f
commit
ddbde757ae
|
@ -39,12 +39,13 @@ console {
|
||||||
|
|
||||||
# CPU window
|
# CPU window
|
||||||
cpu {
|
cpu {
|
||||||
float Float
|
float Float
|
||||||
hex Hex
|
hex Hex
|
||||||
last_pc Last PC
|
jump_from From
|
||||||
signed Signed
|
jump_to To
|
||||||
title CPU
|
signed Signed
|
||||||
unsigned Unsigned
|
title CPU
|
||||||
|
unsigned Unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
# Memory window
|
# Memory window
|
||||||
|
|
|
@ -62,9 +62,9 @@ static int32_t busReadValue(VUE *vue, uint32_t address, int type) {
|
||||||
case 5: /* System WRAM */
|
case 5: /* System WRAM */
|
||||||
return busReadMemory(vue->bus.wram, address & 0xFFFF, type);
|
return busReadMemory(vue->bus.wram, address & 0xFFFF, type);
|
||||||
case 6: return busReadMemory(vue->bus.sram, /* Cartridge RAM */
|
case 6: return busReadMemory(vue->bus.sram, /* Cartridge RAM */
|
||||||
address & (vue->bus.sram_size - 1), type);
|
address & (vue->bus.sramSize - 1), type);
|
||||||
case 7: return busReadMemory(vue->bus.rom , /* Cartridge ROM */
|
case 7: return busReadMemory(vue->bus.rom , /* Cartridge ROM */
|
||||||
address & (vue->bus.rom_size - 1), type);
|
address & (vue->bus.romSize - 1), type);
|
||||||
}
|
}
|
||||||
return 0; /* Unreachable */
|
return 0; /* Unreachable */
|
||||||
}
|
}
|
||||||
|
@ -128,11 +128,11 @@ static void busWriteValue(VUE *vue, uint32_t address, int type, int32_t value){
|
||||||
break;
|
break;
|
||||||
case 6: /* Cartridge RAM */
|
case 6: /* Cartridge RAM */
|
||||||
busWriteMemory(vue->bus.sram,
|
busWriteMemory(vue->bus.sram,
|
||||||
address & (vue->bus.sram_size - 1), type, value);
|
address & (vue->bus.sramSize - 1), type, value);
|
||||||
break;
|
break;
|
||||||
case 7: /* Cartridge ROM */
|
case 7: /* Cartridge ROM */
|
||||||
busWriteMemory(vue->bus.rom ,
|
busWriteMemory(vue->bus.rom ,
|
||||||
address & (vue->bus.rom_size - 1), type, value);
|
address & (vue->bus.romSize - 1), type, value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,8 @@ static void cpuReset(VUE *vue) {
|
||||||
|
|
||||||
/* Configure registers */
|
/* Configure registers */
|
||||||
vue->cpu.ecr_eicc = 0xFFF0;
|
vue->cpu.ecr_eicc = 0xFFF0;
|
||||||
vue->cpu.lastPC = 0xFFFFFFF0;
|
vue->cpu.jumpFrom = 0xFFFFFFF0;
|
||||||
|
vue->cpu.jumpTo = 0xFFFFFFF0;
|
||||||
vue->cpu.pc = 0xFFFFFFF0;
|
vue->cpu.pc = 0xFFFFFFF0;
|
||||||
vue->cpu.psw_np = 1;
|
vue->cpu.psw_np = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,11 +38,15 @@ extern "C" {
|
||||||
#define VUE_EIPSW 1
|
#define VUE_EIPSW 1
|
||||||
#define VUE_FEPC 2
|
#define VUE_FEPC 2
|
||||||
#define VUE_FEPSW 3
|
#define VUE_FEPSW 3
|
||||||
#define VUE_PC -1
|
|
||||||
#define VUE_PIR 6
|
#define VUE_PIR 6
|
||||||
#define VUE_PSW 5
|
#define VUE_PSW 5
|
||||||
#define VUE_TKCW 7
|
#define VUE_TKCW 7
|
||||||
|
|
||||||
|
/* Non-standard register indexes */
|
||||||
|
#define VUE_PC -1
|
||||||
|
#define VUE_JUMP_FROM -2
|
||||||
|
#define VUE_JUMP_TO -3
|
||||||
|
|
||||||
/* Program register indexes */
|
/* Program register indexes */
|
||||||
#define VUE_GP 4
|
#define VUE_GP 4
|
||||||
#define VUE_HP 2
|
#define VUE_HP 2
|
||||||
|
@ -65,18 +69,19 @@ typedef struct {
|
||||||
/* Memory bus */
|
/* Memory bus */
|
||||||
struct {
|
struct {
|
||||||
uint8_t *rom; /* Cartridge ROM */
|
uint8_t *rom; /* Cartridge ROM */
|
||||||
uint32_t rom_size; /* Number of bytes in cartridge ROM */
|
uint32_t romSize; /* Number of bytes in cartridge ROM */
|
||||||
uint8_t *sram; /* Cartridge RAM */
|
uint8_t *sram; /* Cartridge RAM */
|
||||||
uint32_t sram_size; /* Number of bytes in cartridge RAM */
|
uint32_t sramSize; /* Number of bytes in cartridge RAM */
|
||||||
uint8_t wram[0x10000]; /* System memory */
|
uint8_t wram[0x10000]; /* System memory */
|
||||||
} bus;
|
} bus;
|
||||||
|
|
||||||
/* CPU state */
|
/* CPU state */
|
||||||
struct {
|
struct {
|
||||||
uint32_t cycles; /* Cycles until next stage */
|
uint32_t cycles; /* Cycles until next stage */
|
||||||
int fetch; /* Fetch unit index */
|
int fetch; /* Fetch unit index */
|
||||||
int32_t lastPC; /* Previous value of PC */
|
int32_t jumpFrom; /* Source PC of most recent jump */
|
||||||
int stage; /* Current processing stage */
|
int32_t jumpTo; /* Destination PC of most recent jump */
|
||||||
|
int stage; /* Current processing stage */
|
||||||
|
|
||||||
/* Program registers */
|
/* Program registers */
|
||||||
int32_t program[32];
|
int32_t program[32];
|
||||||
|
|
|
@ -26,8 +26,20 @@ static const int TYPE_SIZES[] = { 1, 1, 2, 2, 4 };
|
||||||
|
|
||||||
/* Retrieve the value of a register */
|
/* Retrieve the value of a register */
|
||||||
int32_t vueGetRegister(VUE *vue, int index, vbool system) {
|
int32_t vueGetRegister(VUE *vue, int index, vbool system) {
|
||||||
return vue == NULL ? 0 :
|
|
||||||
index == VUE_PC && system ? vue->cpu.pc :
|
/* Error checking */
|
||||||
|
if (vue == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Non-indexed registers */
|
||||||
|
if (system) switch (index) {
|
||||||
|
case VUE_PC : return vue->cpu.pc;
|
||||||
|
case VUE_JUMP_FROM: return vue->cpu.jumpFrom;
|
||||||
|
case VUE_JUMP_TO : return vue->cpu.jumpTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Indexed registers */
|
||||||
|
return
|
||||||
index < 0 || index > 31 ? 0 :
|
index < 0 || index > 31 ? 0 :
|
||||||
system ? cpuGetSystemRegister(vue, index) :
|
system ? cpuGetSystemRegister(vue, index) :
|
||||||
vue->cpu.program[index]
|
vue->cpu.program[index]
|
||||||
|
@ -66,13 +78,13 @@ vbool vueRead(VUE *vue, uint32_t address, uint8_t *dest, uint32_t length) {
|
||||||
busReadBytes(NULL, dest, address, 0, count);
|
busReadBytes(NULL, dest, address, 0, count);
|
||||||
break;
|
break;
|
||||||
case 5: busReadBytes(vue->bus.wram, dest, /* System WRAM */
|
case 5: busReadBytes(vue->bus.wram, dest, /* System WRAM */
|
||||||
address, 0x10000 , count);
|
address, 0x10000 , count);
|
||||||
break;
|
break;
|
||||||
case 6: busReadBytes(vue->bus.sram, dest, /* Cartridge RAM */
|
case 6: busReadBytes(vue->bus.sram, dest, /* Cartridge RAM */
|
||||||
address, vue->bus.sram_size, count);
|
address, vue->bus.sramSize, count);
|
||||||
break;
|
break;
|
||||||
case 7: busReadBytes(vue->bus.rom , dest, /* Cartridge ROM */
|
case 7: busReadBytes(vue->bus.rom , dest, /* Cartridge ROM */
|
||||||
address, vue->bus.rom_size , count);
|
address, vue->bus.romSize , count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,8 +122,8 @@ vbool vueSetROM(VUE *vue, uint8_t *rom, uint32_t size) {
|
||||||
) return VUE_FALSE;
|
) return VUE_FALSE;
|
||||||
|
|
||||||
/* Accept the new ROM buffer */
|
/* Accept the new ROM buffer */
|
||||||
vue->bus.rom = rom;
|
vue->bus.rom = rom;
|
||||||
vue->bus.rom_size = size;
|
vue->bus.romSize = size;
|
||||||
return VUE_TRUE;
|
return VUE_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,10 +149,10 @@ vbool vueWrite(VUE *vue, uint32_t address, uint8_t *src, uint32_t length) {
|
||||||
busWriteBytes(vue->bus.wram, src, address, 0x10000, count);
|
busWriteBytes(vue->bus.wram, src, address, 0x10000, count);
|
||||||
break;
|
break;
|
||||||
case 6: busWriteBytes(vue->bus.sram, src, /* Cartridge RAM */
|
case 6: busWriteBytes(vue->bus.sram, src, /* Cartridge RAM */
|
||||||
address, vue->bus.sram_size, count);
|
address, vue->bus.sramSize, count);
|
||||||
break;
|
break;
|
||||||
case 7: busWriteBytes(vue->bus.rom , src, /* Cartridge ROM */
|
case 7: busWriteBytes(vue->bus.rom , src, /* Cartridge ROM */
|
||||||
address, vue->bus.rom_size , count);
|
address, vue->bus.romSize , count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,13 @@ import vue.*;
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
// Instance fields
|
// Instance fields
|
||||||
private Localizer localizer; // UI localization manager
|
|
||||||
private boolean useNative; // Produce native core contexts
|
private boolean useNative; // Produce native core contexts
|
||||||
private Localizer.Locale[] locales; // Language translations
|
private Localizer.Locale[] locales; // Language translations
|
||||||
private ArrayList<MainWindow> windows; // Application windows
|
private ArrayList<MainWindow> windows; // Application windows
|
||||||
|
|
||||||
|
// Configuration fields
|
||||||
|
Localizer localizer; // UI localization manager
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -47,21 +49,11 @@ public class App {
|
||||||
windowsChanged();
|
windowsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the currently active locale
|
|
||||||
Localizer.Locale getLocale() {
|
|
||||||
return localizer.getLocale();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine whether the native module is in use
|
// Determine whether the native module is in use
|
||||||
boolean getUseNative() {
|
boolean getUseNative() {
|
||||||
return useNative;
|
return useNative;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the localization manager
|
|
||||||
Localizer getLocalizer() {
|
|
||||||
return localizer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve a list of registered locales
|
// Retrieve a list of registered locales
|
||||||
Localizer.Locale[] listLocales() {
|
Localizer.Locale[] listLocales() {
|
||||||
var ret = new Localizer.Locale[locales.length];
|
var ret = new Localizer.Locale[locales.length];
|
||||||
|
@ -80,11 +72,6 @@ public class App {
|
||||||
windowsChanged();
|
windowsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify a new locale
|
|
||||||
void setLocale(Localizer.Locale locale) {
|
|
||||||
localizer.setLocale(locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specify whether using the native module
|
// Specify whether using the native module
|
||||||
boolean setUseNative(boolean useNative) {
|
boolean setUseNative(boolean useNative) {
|
||||||
return this.useNative = useNative && VUE.isNativeLoaded();
|
return this.useNative = useNative && VUE.isNativeLoaded();
|
||||||
|
|
|
@ -56,7 +56,7 @@ class CPU extends ChildWindow {
|
||||||
outer.setResizeWeight(1);
|
outer.setResizeWeight(1);
|
||||||
|
|
||||||
client.add(outer);
|
client.add(outer);
|
||||||
client.setPreferredSize(new Dimension(640, 480));
|
client.setPreferredSize(new Dimension(480, 300));
|
||||||
setFont2(font);
|
setFont2(font);
|
||||||
pack();
|
pack();
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,8 @@ class CPU extends ChildWindow {
|
||||||
case VUE.SP: name = "sp"; break;
|
case VUE.SP: name = "sp"; break;
|
||||||
case VUE.TP: name = "tp"; break;
|
case VUE.TP: name = "tp"; break;
|
||||||
}
|
}
|
||||||
registers.add(new Register(parent,lst,name,x,Register.PROGRAM));
|
registers.add(new Register(
|
||||||
|
parent, lst, name, x, Register.PROGRAM));
|
||||||
}
|
}
|
||||||
endList(lst);
|
endList(lst);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +143,8 @@ class CPU extends ChildWindow {
|
||||||
system.putClientProperty("shown", true);
|
system.putClientProperty("shown", true);
|
||||||
|
|
||||||
// Add the first two system registers and expand PSW
|
// Add the first two system registers and expand PSW
|
||||||
registers.add(new Register(parent, lst, "PC" , VUE.PC , VUE.PC ));
|
int plain = Register.PLAIN;
|
||||||
|
registers.add(new Register(parent, lst, "PC" , VUE.PC , plain ));
|
||||||
Register psw =new Register(parent, lst, "PSW" , VUE.PSW , VUE.PSW );
|
Register psw =new Register(parent, lst, "PSW" , VUE.PSW , VUE.PSW );
|
||||||
psw.setExpanded(true);
|
psw.setExpanded(true);
|
||||||
registers.add(psw);
|
registers.add(psw);
|
||||||
|
@ -151,18 +153,18 @@ class CPU extends ChildWindow {
|
||||||
shown = false;
|
shown = false;
|
||||||
|
|
||||||
// Add the remaining system registers
|
// Add the remaining system registers
|
||||||
registers.add(new Register(parent, lst, "EIPC" , VUE.EIPC , VUE.PC ));
|
registers.add(new Register(parent, lst, "EIPC" , VUE.EIPC , plain ));
|
||||||
registers.add(new Register(parent, lst, "EIPSW", VUE.EIPSW, VUE.PSW ));
|
registers.add(new Register(parent, lst, "EIPSW", VUE.EIPSW, VUE.PSW ));
|
||||||
registers.add(new Register(parent, lst, "FEPC" , VUE.FEPC , VUE.PC ));
|
registers.add(new Register(parent, lst, "FEPC" , VUE.FEPC , plain ));
|
||||||
registers.add(new Register(parent, lst, "FEPSW", VUE.FEPSW, VUE.PSW ));
|
registers.add(new Register(parent, lst, "FEPSW", VUE.FEPSW, VUE.PSW ));
|
||||||
registers.add(new Register(parent, lst, "ECR" , VUE.ECR , VUE.ECR ));
|
registers.add(new Register(parent, lst, "ECR" , VUE.ECR , VUE.ECR ));
|
||||||
registers.add(new Register(parent, lst, "ADTRE", VUE.ADTRE, VUE.PC ));
|
registers.add(new Register(parent, lst, "ADTRE", VUE.ADTRE, plain ));
|
||||||
registers.add(new Register(parent, lst, "CHCW" , VUE.CHCW , VUE.CHCW));
|
registers.add(new Register(parent, lst, "CHCW" , VUE.CHCW , VUE.CHCW));
|
||||||
registers.add(new Register(parent, lst, "PIR" , VUE.PIR , VUE.PIR ));
|
registers.add(new Register(parent, lst, "PIR" , VUE.PIR , VUE.PIR ));
|
||||||
registers.add(new Register(parent, lst, "TKCW" , VUE.TKCW , VUE.TKCW));
|
registers.add(new Register(parent, lst, "TKCW" , VUE.TKCW , VUE.TKCW));
|
||||||
registers.add(new Register(parent, lst, "29" , 29, VUE.PC ));
|
registers.add(new Register(parent, lst, "29" , 29, plain ));
|
||||||
registers.add(new Register(parent, lst, "30" , 30, VUE.PC ));
|
registers.add(new Register(parent, lst, "30" , 30, plain ));
|
||||||
registers.add(new Register(parent, lst, "31" , 31, VUE.PC ));
|
registers.add(new Register(parent, lst, "31" , 31, plain ));
|
||||||
endList(lst);
|
endList(lst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ class ChildWindow extends JInternalFrame {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
|
||||||
// Configure component
|
// Configure component
|
||||||
parent.app.getLocalizer().add(this, key);
|
parent.app.localizer.add(this, key);
|
||||||
addInternalFrameListener(Util.onClose2(e->setVisible(false)));
|
addInternalFrameListener(Util.onClose2(e->setVisible(false)));
|
||||||
setClosable(true);
|
setClosable(true);
|
||||||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||||
|
|
|
@ -87,7 +87,7 @@ class MainWindow extends JFrame {
|
||||||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||||
setIconImage(APPICON);
|
setIconImage(APPICON);
|
||||||
setJMenuBar(initMenus());
|
setJMenuBar(initMenus());
|
||||||
app.getLocalizer().add(this, "app.title.default");
|
app.localizer.add(this, "app.title.default");
|
||||||
|
|
||||||
// Configure child windows
|
// Configure child windows
|
||||||
desktop = new JDesktopPane();
|
desktop = new JDesktopPane();
|
||||||
|
@ -112,7 +112,7 @@ class MainWindow extends JFrame {
|
||||||
// Produce the window's menu bar
|
// Produce the window's menu bar
|
||||||
private JMenuBar initMenus() {
|
private JMenuBar initMenus() {
|
||||||
var bar = new JMenuBar();
|
var bar = new JMenuBar();
|
||||||
var loc = app.getLocalizer();
|
var loc = app.localizer;
|
||||||
bar.add(initMenuFile (loc));
|
bar.add(initMenuFile (loc));
|
||||||
bar.add(initMenuDebug(loc));
|
bar.add(initMenuDebug(loc));
|
||||||
return bar;
|
return bar;
|
||||||
|
@ -194,7 +194,7 @@ class MainWindow extends JFrame {
|
||||||
void windowsChanged(int number, boolean only) {
|
void windowsChanged(int number, boolean only) {
|
||||||
this.number = number;
|
this.number = number;
|
||||||
this.only = only;
|
this.only = only;
|
||||||
app.getLocalizer().put(this, "ctrl.number", "" + number);
|
app.localizer.put(this, "ctrl.number", "" + number);
|
||||||
updateTitle();
|
updateTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ class MainWindow extends JFrame {
|
||||||
|
|
||||||
// File -> Load ROM
|
// File -> Load ROM
|
||||||
private void onLoadROM() {
|
private void onLoadROM() {
|
||||||
var loc = app.getLocalizer();
|
var loc = app.localizer;
|
||||||
|
|
||||||
// Prompt the user to select a file
|
// Prompt the user to select a file
|
||||||
var dlgFile = new JFileChooser(pwd);
|
var dlgFile = new JFileChooser(pwd);
|
||||||
|
@ -324,7 +324,7 @@ class MainWindow extends JFrame {
|
||||||
|
|
||||||
// Update the window title
|
// Update the window title
|
||||||
private void updateTitle() {
|
private void updateTitle() {
|
||||||
app.getLocalizer().add(this,
|
app.localizer.add(this,
|
||||||
only ? romFile != null ?
|
only ? romFile != null ?
|
||||||
"app.title.rom" :
|
"app.title.rom" :
|
||||||
"app.title.default"
|
"app.title.default"
|
||||||
|
|
|
@ -57,7 +57,7 @@ class Memory extends ChildWindow {
|
||||||
client.addMouseWheelListener(e->onWheel(e));
|
client.addMouseWheelListener(e->onWheel(e));
|
||||||
client.setBackground(SystemColor.window);
|
client.setBackground(SystemColor.window);
|
||||||
client.setFocusable(true);
|
client.setFocusable(true);
|
||||||
client.setPreferredSize(new Dimension(640, 480));
|
client.setPreferredSize(new Dimension(480, 360));
|
||||||
|
|
||||||
// Configure component
|
// Configure component
|
||||||
var content = new JPanel(new BorderLayout());
|
var content = new JPanel(new BorderLayout());
|
||||||
|
|
|
@ -14,21 +14,25 @@ import vue.*;
|
||||||
class Register {
|
class Register {
|
||||||
|
|
||||||
// Instance fields
|
// Instance fields
|
||||||
boolean expanded; // The expanded area is being shown
|
boolean expandable; // The expansion area can be shown
|
||||||
Font font; // Hexadecimal font
|
boolean expanded; // The expanded area is being shown
|
||||||
int index; // Register index
|
Font font; // Hexadecimal font
|
||||||
int mode; // Display mode for program registers
|
int index; // Register index
|
||||||
MainWindow parent; // Containing window
|
int mode; // Display mode for program registers
|
||||||
int type; // Expansion controls type
|
MainWindow parent; // Containing window
|
||||||
int value; // Current register value
|
int type; // Expansion controls type
|
||||||
|
int value; // Current register value
|
||||||
|
|
||||||
// UI components
|
// UI components
|
||||||
private JPanel expansion; // Expansion area
|
private JPanel expansion; // Expansion area
|
||||||
private JLabel btnExpand; // Expand button
|
private JLabel btnExpand; // Expand button
|
||||||
private JLabel lblName; // Register name
|
private JLabel lblLastPC; // Last PC name
|
||||||
private JPanel list; // Containing element
|
private JLabel lblName; // Register name
|
||||||
private JPanel spacer; // Expansion area spacer
|
private JPanel list; // Containing element
|
||||||
private JTextField txtValue; // Register value
|
private JPanel spacer; // Expansion area spacer
|
||||||
|
private JTextField txtJumpFrom; // Jump-from value
|
||||||
|
private JTextField txtJumpTo; // Jump-to value
|
||||||
|
private JTextField txtValue; // Register value
|
||||||
private ArrayList<JComponent> controls; // Expansion controls
|
private ArrayList<JComponent> controls; // Expansion controls
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,6 +48,7 @@ class Register {
|
||||||
static final int UNSIGNED = 2;
|
static final int UNSIGNED = 2;
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
static final int PLAIN = -1;
|
||||||
static final int PROGRAM = -2;
|
static final int PROGRAM = -2;
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +62,7 @@ class Register {
|
||||||
|
|
||||||
// Configure instance fields
|
// Configure instance fields
|
||||||
controls = new ArrayList<JComponent>();
|
controls = new ArrayList<JComponent>();
|
||||||
|
expandable = type != PLAIN && index != 0 || index == VUE.PC;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.list = list;
|
this.list = list;
|
||||||
this.mode = HEX;
|
this.mode = HEX;
|
||||||
|
@ -64,13 +70,13 @@ class Register {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
||||||
// Click handler for expand and name controls
|
// Click handler for expand and name controls
|
||||||
MouseListener expand = type == VUE.PC ? null : Util.onMouse(
|
MouseListener expand = !expandable ? null : Util.onMouse(e->{
|
||||||
e->{ if (e.getButton() == 1) setExpanded(!expanded); }, null);
|
if (e.getButton() == 1) setExpanded(!expanded); }, null);
|
||||||
|
|
||||||
// Expand button
|
// Expand button
|
||||||
btnExpand = new JLabel(expand != null ? "+" : " ");
|
btnExpand = new JLabel(expandable ? "+" : " ");
|
||||||
btnExpand.setHorizontalAlignment(SwingConstants.CENTER);
|
btnExpand.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
if (expand != null)
|
if (expandable)
|
||||||
btnExpand.addMouseListener(expand);
|
btnExpand.addMouseListener(expand);
|
||||||
var gbc = new GridBagConstraints();
|
var gbc = new GridBagConstraints();
|
||||||
gbc.anchor = GridBagConstraints.NORTH;
|
gbc.anchor = GridBagConstraints.NORTH;
|
||||||
|
@ -79,7 +85,7 @@ class Register {
|
||||||
|
|
||||||
// Name label
|
// Name label
|
||||||
lblName = new JLabel(name);
|
lblName = new JLabel(name);
|
||||||
if (expand != null)
|
if (expandable)
|
||||||
lblName.addMouseListener(expand);
|
lblName.addMouseListener(expand);
|
||||||
gbc = new GridBagConstraints();
|
gbc = new GridBagConstraints();
|
||||||
gbc.anchor = GridBagConstraints.NORTH;
|
gbc.anchor = GridBagConstraints.NORTH;
|
||||||
|
@ -94,7 +100,7 @@ class Register {
|
||||||
txtValue.setText("00000000");
|
txtValue.setText("00000000");
|
||||||
gbc = new GridBagConstraints();
|
gbc = new GridBagConstraints();
|
||||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||||
gbc.insets = new Insets(0, 4, 0, 0);
|
gbc.insets = new Insets(0, 4, 0, 0);
|
||||||
list.add(txtValue, gbc);
|
list.add(txtValue, gbc);
|
||||||
|
|
||||||
// Value changed
|
// Value changed
|
||||||
|
@ -116,6 +122,7 @@ class Register {
|
||||||
case PROGRAM : initProgram(); break;
|
case PROGRAM : initProgram(); break;
|
||||||
case VUE.CHCW: initCHCW (); break;
|
case VUE.CHCW: initCHCW (); break;
|
||||||
case VUE.ECR : initECR (); break;
|
case VUE.ECR : initECR (); break;
|
||||||
|
case VUE.PC : initPC (); break;
|
||||||
case VUE.PIR : initPIR (); break;
|
case VUE.PIR : initPIR (); break;
|
||||||
case VUE.PSW : initPSW (); break;
|
case VUE.PSW : initPSW (); break;
|
||||||
case VUE.TKCW: initTKCW (); break;
|
case VUE.TKCW: initTKCW (); break;
|
||||||
|
@ -123,19 +130,25 @@ class Register {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expansion spacer
|
// Expansion spacer
|
||||||
spacer = new JPanel(null);
|
if (index != VUE.PC) {
|
||||||
spacer.setOpaque(false);
|
spacer = new JPanel(null);
|
||||||
spacer.setPreferredSize(new Dimension(0, 0));
|
spacer.setOpaque(false);
|
||||||
spacer.setVisible(false);
|
spacer.setPreferredSize(new Dimension(0, 0));
|
||||||
list.add(spacer, new GridBagConstraints());
|
spacer.setVisible(false);
|
||||||
|
gbc = new GridBagConstraints();
|
||||||
|
list.add(spacer, gbc);
|
||||||
|
}
|
||||||
|
|
||||||
// Expansion area
|
// Expansion area
|
||||||
expansion.setOpaque(false);
|
expansion.setOpaque(false);
|
||||||
expansion.setVisible(false);
|
expansion.setVisible(false);
|
||||||
gbc = new GridBagConstraints();
|
gbc = new GridBagConstraints();
|
||||||
gbc.anchor = GridBagConstraints.WEST;
|
gbc.anchor = GridBagConstraints.WEST;
|
||||||
|
if (index == VUE.PC)
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||||
gbc.insets = new Insets(0, 4, 0, 0);
|
gbc.insets = new Insets(0, 4, 0, 0);
|
||||||
|
gbc.weightx = 1;
|
||||||
list.add(expansion, gbc);
|
list.add(expansion, gbc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +181,50 @@ class Register {
|
||||||
group.add(addRadioButton("cpu.float" , FLOAT ));
|
group.add(addRadioButton("cpu.float" , FLOAT ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expansion controls for PC
|
||||||
|
private void initPC() {
|
||||||
|
expansion = new JPanel(new GridBagLayout());
|
||||||
|
|
||||||
|
// Configure controls
|
||||||
|
for (int x = 0; x < 2; x++) {
|
||||||
|
|
||||||
|
// Indentation
|
||||||
|
var spacer = new JPanel(null);
|
||||||
|
spacer.setOpaque(false);
|
||||||
|
spacer.setPreferredSize(new Dimension(0, 0));
|
||||||
|
var gbc = new GridBagConstraints();
|
||||||
|
gbc.weightx = 1;
|
||||||
|
expansion.add(spacer, gbc);
|
||||||
|
|
||||||
|
// Name label
|
||||||
|
var label = new JLabel();
|
||||||
|
parent.app.localizer.add(label,
|
||||||
|
x == 0 ? "cpu.jump_from" : "cpu.jump_to" );
|
||||||
|
gbc = new GridBagConstraints();
|
||||||
|
gbc.anchor = GridBagConstraints.NORTHWEST;
|
||||||
|
expansion.add(label, gbc);
|
||||||
|
|
||||||
|
// Value text box
|
||||||
|
var txt = new JTextField();
|
||||||
|
txt.addActionListener(e->{
|
||||||
|
txt.setText((String) txt.getClientProperty("text"));
|
||||||
|
list.requestFocus();
|
||||||
|
});
|
||||||
|
txt.setBorder(null);
|
||||||
|
txt.setOpaque(false);
|
||||||
|
gbc = new GridBagConstraints();
|
||||||
|
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||||
|
gbc.insets = new Insets(0, 4, 0, 0);
|
||||||
|
expansion.add(txt, gbc);
|
||||||
|
|
||||||
|
// Initialize the corresponding component field
|
||||||
|
if (x == 0)
|
||||||
|
txtJumpFrom = txt;
|
||||||
|
else txtJumpTo = txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Expansion controls for PSW
|
// Expansion controls for PSW
|
||||||
private void initPSW() {
|
private void initPSW() {
|
||||||
expansion = new JPanel(new GridBagLayout());
|
expansion = new JPanel(new GridBagLayout());
|
||||||
|
@ -221,13 +278,23 @@ class Register {
|
||||||
txtValue.setText(
|
txtValue.setText(
|
||||||
type != PROGRAM || mode == HEX ?
|
type != PROGRAM || mode == HEX ?
|
||||||
String.format("%08X", value) :
|
String.format("%08X", value) :
|
||||||
mode == SIGNED ? Integer.toString(value) :
|
mode == SIGNED ? Integer.toString(value) :
|
||||||
mode == UNSIGNED ? Long.toString(value & 0xFFFFFFFFL) :
|
mode == UNSIGNED ? Long.toString(value & 0xFFFFFFFFL) :
|
||||||
Float.toString(Float.intBitsToFloat(value))
|
Float.toString(Float.intBitsToFloat(value))
|
||||||
);
|
);
|
||||||
|
|
||||||
// Expansion controls
|
// PC expansion controls
|
||||||
for (var control : controls) {
|
if (index == VUE.PC) for (int x = 0; x < 2; x++) {
|
||||||
|
JTextField txt = x == 0 ? txtJumpFrom : txtJumpTo;
|
||||||
|
int index = x == 0 ? VUE.JUMP_FROM : VUE.JUMP_TO;
|
||||||
|
int value = parent.vue.getRegister(index, true);
|
||||||
|
String text = String.format("%08X", value);
|
||||||
|
txt.putClientProperty("text", text);
|
||||||
|
txt.setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other expansion controls
|
||||||
|
else for (var control : controls) {
|
||||||
|
|
||||||
// Check box
|
// Check box
|
||||||
if (control instanceof JCheckBox) {
|
if (control instanceof JCheckBox) {
|
||||||
|
@ -256,16 +323,16 @@ class Register {
|
||||||
void setExpanded(boolean expanded) {
|
void setExpanded(boolean expanded) {
|
||||||
|
|
||||||
// Error checking
|
// Error checking
|
||||||
if (type == VUE.PC)
|
if (!expandable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update controls
|
// Update controls
|
||||||
this.expanded = expanded;
|
this.expanded = expanded;
|
||||||
btnExpand.setText (expanded ? "-" : "+");
|
btnExpand.setText(expanded ? "-" : "+");
|
||||||
|
if (index != VUE.PC)
|
||||||
|
spacer.setVisible(expanded);
|
||||||
expansion.setVisible(expanded);
|
expansion.setVisible(expanded);
|
||||||
spacer .setVisible(expanded);
|
|
||||||
list.revalidate();
|
list.revalidate();
|
||||||
list.repaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify the width of the expand button
|
// Specify the width of the expand button
|
||||||
|
@ -280,9 +347,15 @@ class Register {
|
||||||
this.font = font;
|
this.font = font;
|
||||||
|
|
||||||
// Value text box
|
// Value text box
|
||||||
|
var size = new Dimension(8 * fontWidth + 4, fontHeight);
|
||||||
txtValue.setFont(font);
|
txtValue.setFont(font);
|
||||||
txtValue.setPreferredSize(
|
txtValue.setPreferredSize(size);
|
||||||
new Dimension(8 * fontWidth + 4, fontHeight));
|
if (index == VUE.PC) {
|
||||||
|
txtJumpFrom.setFont(font);
|
||||||
|
txtJumpFrom.setPreferredSize(size);
|
||||||
|
txtJumpTo .setFont(font);
|
||||||
|
txtJumpTo .setPreferredSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
// Expansion controls
|
// Expansion controls
|
||||||
for (var ctrl : controls) {
|
for (var ctrl : controls) {
|
||||||
|
@ -291,7 +364,7 @@ class Register {
|
||||||
if ((Boolean) ctrl.getClientProperty("hex"))
|
if ((Boolean) ctrl.getClientProperty("hex"))
|
||||||
((JTextField) ctrl).setFont(font);
|
((JTextField) ctrl).setFont(font);
|
||||||
int digits = (Integer) ctrl.getClientProperty("digits");
|
int digits = (Integer) ctrl.getClientProperty("digits");
|
||||||
var size = ctrl.getPreferredSize();
|
size = ctrl.getPreferredSize();
|
||||||
size.width = digits * fontWidth + 4;
|
size.width = digits * fontWidth + 4;
|
||||||
ctrl.setPreferredSize(size);
|
ctrl.setPreferredSize(size);
|
||||||
}
|
}
|
||||||
|
@ -334,7 +407,7 @@ class Register {
|
||||||
var gbc = new GridBagConstraints();
|
var gbc = new GridBagConstraints();
|
||||||
gbc.anchor = GridBagConstraints.NORTHWEST;
|
gbc.anchor = GridBagConstraints.NORTHWEST;
|
||||||
gbc.gridwidth = 2;
|
gbc.gridwidth = 2;
|
||||||
gbc.insets = new Insets(0, 4, 0, 0);
|
gbc.insets = new Insets(0, 4, 0, 4);
|
||||||
expansion.add(ctrl, gbc);
|
expansion.add(ctrl, gbc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +416,7 @@ class Register {
|
||||||
|
|
||||||
// Configure control
|
// Configure control
|
||||||
var ctrl = new JRadioButton();
|
var ctrl = new JRadioButton();
|
||||||
parent.app.getLocalizer().add(ctrl, key);
|
parent.app.localizer.add(ctrl, key);
|
||||||
ctrl.setBorder(null);
|
ctrl.setBorder(null);
|
||||||
ctrl.setFocusable(false);
|
ctrl.setFocusable(false);
|
||||||
ctrl.setOpaque(false);
|
ctrl.setOpaque(false);
|
||||||
|
|
|
@ -314,6 +314,7 @@ public class Localizer {
|
||||||
control instanceof AbstractButton ||
|
control instanceof AbstractButton ||
|
||||||
control instanceof JFrame ||
|
control instanceof JFrame ||
|
||||||
control instanceof JInternalFrame ||
|
control instanceof JInternalFrame ||
|
||||||
|
control instanceof JLabel ||
|
||||||
control instanceof JPanel || // TitledBorder
|
control instanceof JPanel || // TitledBorder
|
||||||
control instanceof JTextComponent
|
control instanceof JTextComponent
|
||||||
)) return false;
|
)) return false;
|
||||||
|
@ -490,6 +491,8 @@ public class Localizer {
|
||||||
((JFrame ) control).setTitle(values[0]);
|
((JFrame ) control).setTitle(values[0]);
|
||||||
if (control instanceof JInternalFrame)
|
if (control instanceof JInternalFrame)
|
||||||
((JInternalFrame) control).setTitle(values[0]);
|
((JInternalFrame) control).setTitle(values[0]);
|
||||||
|
if (control instanceof JLabel )
|
||||||
|
((JLabel ) control).setText (values[0]);
|
||||||
if (control instanceof JTextComponent)
|
if (control instanceof JTextComponent)
|
||||||
((JTextComponent) control).setText (values[0]);
|
((JTextComponent) control).setText (values[0]);
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,11 @@ class CPU {
|
||||||
private JavaVUE vue; // Emulation state
|
private JavaVUE vue; // Emulation state
|
||||||
|
|
||||||
// Package fields
|
// Package fields
|
||||||
int cycles; // Cycles until next stage
|
int cycles; // Cycles until next stage
|
||||||
int fetch; // Fetch unit index
|
int fetch; // Fetch unit index
|
||||||
int lastPC; // Previous value of PC
|
int jumpFrom; // Source PC of most recent jump
|
||||||
int stage; // Current processing stage
|
int jumpTo; // Destination PC of most recent jump
|
||||||
|
int stage; // Current processing stage
|
||||||
|
|
||||||
// Program registers
|
// Program registers
|
||||||
int[] program;
|
int[] program;
|
||||||
|
@ -149,7 +150,8 @@ class CPU {
|
||||||
|
|
||||||
// Configure registers
|
// Configure registers
|
||||||
ecr_eicc = 0xFFF0;
|
ecr_eicc = 0xFFF0;
|
||||||
lastPC = 0xFFFFFFF0;
|
jumpFrom = 0xFFFFFFF0;
|
||||||
|
jumpTo = 0xFFFFFFF0;
|
||||||
pc = 0xFFFFFFF0;
|
pc = 0xFFFFFFF0;
|
||||||
psw_np = 1;
|
psw_np = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,16 @@ class JavaVUE extends VUE {
|
||||||
|
|
||||||
// Retrieve a register value
|
// Retrieve a register value
|
||||||
public int getRegister(int index, boolean system) {
|
public int getRegister(int index, boolean system) {
|
||||||
|
|
||||||
|
// Non-indexed registers
|
||||||
|
if (system) switch (index) {
|
||||||
|
case VUE.PC : return cpu.pc;
|
||||||
|
case VUE.JUMP_FROM: return cpu.jumpFrom;
|
||||||
|
case VUE.JUMP_TO : return cpu.jumpTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indexed registers
|
||||||
return
|
return
|
||||||
index == VUE.PC && system ? cpu.pc :
|
|
||||||
index < 0 || index > 31 ? 0 :
|
index < 0 || index > 31 ? 0 :
|
||||||
system ? cpu.getSystemRegister(index) :
|
system ? cpu.getSystemRegister(index) :
|
||||||
cpu.program[index]
|
cpu.program[index]
|
||||||
|
|
|
@ -99,9 +99,9 @@ JNIEXPORT jbyteArray JNICALL Java_vue_NativeVUE_getROM
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Copy the ROM data
|
// Copy the ROM data
|
||||||
jbyteArray ret = (*env)->NewByteArray(env, (jint)core->vue.bus.rom_size);
|
jbyteArray ret = (*env)->NewByteArray(env, (jint)core->vue.bus.romSize);
|
||||||
jbyte *elems = (*env)->GetByteArrayElements(env, ret, NULL);
|
jbyte *elems = (*env)->GetByteArrayElements(env, ret, NULL);
|
||||||
memcpy(elems, core->vue.bus.rom, core->vue.bus.rom_size);
|
memcpy(elems, core->vue.bus.rom, core->vue.bus.romSize);
|
||||||
(*env)->ReleaseByteArrayElements(env, ret, elems, 0);
|
(*env)->ReleaseByteArrayElements(env, ret, elems, 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,17 +20,21 @@ public abstract class VUE {
|
||||||
public static final int S32 = 4;
|
public static final int S32 = 4;
|
||||||
|
|
||||||
// System register indexes
|
// System register indexes
|
||||||
public static final int ADTRE = 25;
|
public static final int ADTRE = 25;
|
||||||
public static final int CHCW = 24;
|
public static final int CHCW = 24;
|
||||||
public static final int ECR = 4;
|
public static final int ECR = 4;
|
||||||
public static final int EIPC = 0;
|
public static final int EIPC = 0;
|
||||||
public static final int EIPSW = 1;
|
public static final int EIPSW = 1;
|
||||||
public static final int FEPC = 2;
|
public static final int FEPC = 2;
|
||||||
public static final int FEPSW = 3;
|
public static final int FEPSW = 3;
|
||||||
public static final int PC = -1;
|
public static final int PIR = 6;
|
||||||
public static final int PIR = 6;
|
public static final int PSW = 5;
|
||||||
public static final int PSW = 5;
|
public static final int TKCW = 7;
|
||||||
public static final int TKCW = 7;
|
|
||||||
|
// Non-standard register indexes
|
||||||
|
public static final int PC = -1;
|
||||||
|
public static final int JUMP_FROM = -2;
|
||||||
|
public static final int JUMP_TO = -3;
|
||||||
|
|
||||||
// Program register indexes
|
// Program register indexes
|
||||||
public static final int GP = 4;
|
public static final int GP = 4;
|
||||||
|
|
Loading…
Reference in New Issue