From 15ce721eb3616bed12c7ecfcbe970229529e315e Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Mon, 6 Sep 2010 04:01:16 +0300 Subject: [PATCH] Refactor system flags Refactor the system flags so adding new flag is much easier. --- Changelog.utf8 | 1 + org/jpc/emulator/PC.java | 162 +++++++++++++++------ .../codeblock/optimised/ProtectedModeUBlock.java | 2 +- .../memory/codeblock/optimised/RealModeUBlock.java | 2 +- .../codeblock/optimised/Virtual8086ModeUBlock.java | 2 +- org/jpc/emulator/motherboard/IOPortHandler.java | 17 +-- org/jpc/emulator/pci/peripheral/VGACard.java | 17 +-- org/jpc/emulator/processor/Processor.java | 10 +- org/jpc/pluginsaux/PCConfigDialog.java | 8 +- 9 files changed, 146 insertions(+), 75 deletions(-) diff --git a/Changelog.utf8 b/Changelog.utf8 index ed47f43..c46c54a 100644 --- a/Changelog.utf8 +++ b/Changelog.utf8 @@ -74,6 +74,7 @@ Changes since JPC-RR Release 10.5: - Add nearest neighbor resizer. - Add image dumping support. — Fix HDD image dumping. +- Refactor system flags (less places to modify to add one). Changes since JPC-RR Release 10.16: =================================== diff --git a/org/jpc/emulator/PC.java b/org/jpc/emulator/PC.java index 3ca9378..de89cc7 100644 --- a/org/jpc/emulator/PC.java +++ b/org/jpc/emulator/PC.java @@ -88,9 +88,8 @@ public class PC implements SRDumpable public String fpuEmulator; public Map> hwModules; public DriveSet.BootType bootType; - public boolean ioportDelayed; - public boolean vgaHretrace; - public boolean flushOnModify; + public Map booleanOptions; + public Map intOptions; public void dumpStatusPartial(StatusDumper output2) throws IOException { @@ -144,12 +143,14 @@ public class PC implements SRDumpable output.println("LOADMODULE " + e.getKey()); } } - if(ioportDelayed) - output.println("IOPORTDELAY"); - if(vgaHretrace) - output.println("VGAHRETRACE"); - if(flushOnModify) - output.println("FLUSHONMODIFY"); + if(booleanOptions != null) + for(Map.Entry setting : booleanOptions.entrySet()) + if(setting.getValue().booleanValue()) + output.println(setting.getKey()); + if(intOptions != null) + for(Map.Entry setting : intOptions.entrySet()) + if(setting.getValue().intValue() != 0) + output.println(setting.getKey() + " " + setting.getValue()); } public void dumpStatus(StatusDumper output) @@ -193,9 +194,26 @@ public class PC implements SRDumpable } else output.dumpBoolean(false); output.dumpByte(DriveSet.BootType.toNumeric(bootType)); - output.dumpBoolean(ioportDelayed); - output.dumpBoolean(vgaHretrace); - output.dumpBoolean(flushOnModify); + //Following are old system setting bits. They are RESERVED now. + output.dumpBoolean(false); + output.dumpBoolean(false); + output.dumpBoolean(false); + //The new system setting stuff. + if(intOptions != null) + for(Map.Entry setting : booleanOptions.entrySet()) + if(setting.getValue().booleanValue()) { + output.dumpBoolean(true); + output.dumpString(setting.getKey()); + } + output.dumpBoolean(false); + if(intOptions != null) + for(Map.Entry setting : intOptions.entrySet()) + if(setting.getValue().intValue() != 0) { + output.dumpBoolean(true); + output.dumpString(setting.getKey()); + output.dumpInt(setting.getValue()); + } + output.dumpBoolean(false); } public PCHardwareInfo() @@ -237,9 +255,26 @@ public class PC implements SRDumpable } } bootType = DriveSet.BootType.fromNumeric(input.loadByte()); - ioportDelayed = input.loadBoolean(); - vgaHretrace = input.loadBoolean(); - flushOnModify = input.loadBoolean(); + //Compat stuff. + boolean ioportDelayed = input.loadBoolean(); + boolean vgaHretrace = input.loadBoolean(); + boolean flushOnModify = input.loadBoolean(); + booleanOptions = new TreeMap(); + intOptions = new TreeMap(); + if(ioportDelayed) + booleanOptions.put("IOPORTDELAY", true); + if(vgaHretrace) + booleanOptions.put("VGAHRETRACE", true); + if(flushOnModify) + booleanOptions.put("FLUSHONMODIFY", true); + //Real settings stuff. + while(input.loadBoolean()) + booleanOptions.put(input.loadString(), true); + while(input.loadBoolean()) { + String name = input.loadString(); + int value = input.loadInt(); + intOptions.put(name, value); + } } public void makeHWInfoSegment(UTFOutputLineStream output, DiskChanger changer) throws IOException @@ -283,12 +318,14 @@ public class PC implements SRDumpable output.encodeLine("LOADMODULE", e.getKey()); } } - if(ioportDelayed) - output.encodeLine("IOPORTDELAY"); - if(vgaHretrace) - output.encodeLine("VGAHRETRACE"); - if(flushOnModify) - output.encodeLine("FLUSHONMODIFY"); + if(booleanOptions != null) + for(Map.Entry setting : booleanOptions.entrySet()) + if(setting.getValue().booleanValue()) + output.encodeLine(setting.getKey()); + if(intOptions != null) + for(Map.Entry setting : intOptions.entrySet()) + if(setting.getValue().intValue() != 0) + output.encodeLine(setting.getKey(), setting.getValue().toString()); } public static int componentsForLine(String op) @@ -329,12 +366,6 @@ public class PC implements SRDumpable return 3; if("DISKNAME".equals(op)) return 3; - if("IOPORTDELAY".equals(op)) - return 1; - if("VGAHRETRACE".equals(op)) - return 1; - if("FLUSHONMODIFY".equals(op)) - return 1; return 0; } @@ -343,6 +374,8 @@ public class PC implements SRDumpable { PCHardwareInfo hw = new PCHardwareInfo(); + hw.booleanOptions = new TreeMap(); + hw.intOptions = new TreeMap(); hw.initFDAIndex = -1; hw.initFDBIndex = -1; hw.initCDROMIndex = -1; @@ -350,6 +383,20 @@ public class PC implements SRDumpable hw.hwModules = new LinkedHashMap>(); String[] components = nextParseLine(input); while(components != null) { + if(componentsForLine(components[0]) == 0 && components.length == 1) { + hw.booleanOptions.put(components[0], true); + components = nextParseLine(input); + continue; + } + if(componentsForLine(components[0]) == 0 && components.length == 2) { + try { + hw.intOptions.put(components[0], Integer.parseInt(components[1])); + } catch(Exception e) { + throw new IOException("Bad " + components[0] + " line in initialization segment"); + } + components = nextParseLine(input); + continue; + } if(components.length != componentsForLine(components[0])) throw new IOException("Bad " + components[0] + " line in ininitialization segment: " + "expected " + componentsForLine(components[0]) + " components, got " + components.length); @@ -464,12 +511,6 @@ public class PC implements SRDumpable if(!hw.hwModules.containsKey(components[1])) hw.hwModules.put(components[1],new LinkedHashSet()); hw.hwModules.get(components[1]).add(components[2]); - } else if("IOPORTDELAY".equals(components[0])) { - hw.ioportDelayed = true; - } else if("VGAHRETRACE".equals(components[0])) { - hw.vgaHretrace = true; - } else if("FLUSHONMODIFY".equals(components[0])) { - hw.flushOnModify = true; } components = nextParseLine(input); } @@ -586,7 +627,7 @@ public class PC implements SRDumpable */ public PC(DriveSet drives, int ramPages, int clockDivide, String sysBIOSImg, String vgaBIOSImg, long initTime, DiskImageSet images, Map> hwModules, String fpuClass, - boolean ioportDelayed, boolean vgaHretrace, boolean flushOnModify) + Map bools, Map ints) throws IOException { parts = new LinkedHashSet(); @@ -622,8 +663,6 @@ public class PC implements SRDumpable parts.add(processor); manager = new CodeBlockManager(); - processor.reloadCurrentBlockOnModification = flushOnModify; - System.err.println("Informational: Creating FPU..."); try { if(fpuClass != null) { @@ -664,7 +703,7 @@ public class PC implements SRDumpable //Motherboard System.err.println("Informational: Creating I/O port handler..."); - parts.add(new IOPortHandler(ioportDelayed)); + parts.add(new IOPortHandler()); System.err.println("Informational: Creating IRQ controller..."); parts.add(new InterruptController()); @@ -726,8 +765,6 @@ public class PC implements SRDumpable if(displayController == null) { System.err.println("Informational: Creating VGA card..."); VGACard card = new VGACard(); - if(vgaHretrace) - card.enableVGAHretrace(); parts.add(card); displayController = card; } @@ -750,6 +787,46 @@ public class PC implements SRDumpable numBase.put(c.getClass().getName(), base + channels); } + System.err.println("Informational: Setting system flags..."); + Set found = new HashSet(); + for(HardwareComponent part : parts) { + Class clazz = part.getClass(); + Field[] fields = clazz.getDeclaredFields(); + for(Field field : fields) + if(field.getName().startsWith("SYSFLAG_")) { + String name = field.getName().substring(8); + found.add(name); + Boolean b = null; + Integer i = null; + if(bools != null) + b = bools.get(name); + if(ints != null) + i = ints.get(name); + if(b != null && b.booleanValue()) { + try { + field.setBoolean(part, true); + } catch(IllegalAccessException e) { + throw new IOException("System flag field for " + name + " is of wrong type"); + } + } + if(i != null && i.intValue() != 0) { + try { + field.setInt(part, i.intValue()); + } catch(IllegalAccessException e) { + throw new IOException("System flag field for " + name + " is of wrong type"); + } + } + } + } + if(bools != null) + for(Map.Entry b : bools.entrySet()) + if(!found.contains(b.getKey())) + throw new IOException("Unrecognized system flag " + b.getKey() + " encountered"); + if(ints != null) + for(Map.Entry i : ints.entrySet()) + if(!found.contains(i.getKey())) + throw new IOException("Unrecognized system flag " + i.getKey() + " encountered"); + System.err.println("Informational: Configuring components..."); if(!configure()) throw new IllegalStateException("Can't initialize components (cyclic dependency?)"); @@ -980,7 +1057,7 @@ public class PC implements SRDumpable DriveSet drives = new DriveSet(hw.bootType, hda, hdb, hdc, hdd); pc = new PC(drives, hw.memoryPages, hw.cpuDivider, biosID, vgaBIOSID, hw.initRTCTime, hw.images, - hw.hwModules, hw.fpuEmulator, hw.ioportDelayed, hw.vgaHretrace, hw.flushOnModify); + hw.hwModules, hw.fpuEmulator, hw.booleanOptions, hw.intOptions); FloppyController fdc = (FloppyController)pc.getComponent(FloppyController.class); DiskImage img1 = pc.getDisks().lookupDisk(hw.initFDAIndex); @@ -1011,9 +1088,8 @@ public class PC implements SRDumpable hw2.bootType = hw.bootType; hw2.hwModules = hw.hwModules; hw2.fpuEmulator = hw.fpuEmulator; - hw2.ioportDelayed = hw.ioportDelayed; - hw2.vgaHretrace = hw.vgaHretrace; - hw2.flushOnModify = hw.flushOnModify; + hw2.booleanOptions = hw.booleanOptions; + hw2.intOptions = hw.intOptions; return pc; } diff --git a/org/jpc/emulator/memory/codeblock/optimised/ProtectedModeUBlock.java b/org/jpc/emulator/memory/codeblock/optimised/ProtectedModeUBlock.java index 8bfb2ab..0db3073 100644 --- a/org/jpc/emulator/memory/codeblock/optimised/ProtectedModeUBlock.java +++ b/org/jpc/emulator/memory/codeblock/optimised/ProtectedModeUBlock.java @@ -1262,7 +1262,7 @@ public class ProtectedModeUBlock implements ProtectedModeCodeBlock case INSTRUCTION_START: executeCount++; if(cpu.eflagsMachineHalt) throw ProcessorException.TRACESTOP; - if(invalidated && cpu.reloadCurrentBlockOnModification) { + if(invalidated && cpu.SYSFLAG_FLUSHONMODIFY) { invalidated = false; throw ProcessorException.SELFMODIFIED; } diff --git a/org/jpc/emulator/memory/codeblock/optimised/RealModeUBlock.java b/org/jpc/emulator/memory/codeblock/optimised/RealModeUBlock.java index d7c68f1..fb830ce 100644 --- a/org/jpc/emulator/memory/codeblock/optimised/RealModeUBlock.java +++ b/org/jpc/emulator/memory/codeblock/optimised/RealModeUBlock.java @@ -1163,7 +1163,7 @@ public final class RealModeUBlock implements RealModeCodeBlock case INSTRUCTION_START: executeCount++; if(cpu.eflagsMachineHalt) throw ProcessorException.TRACESTOP; - if(invalidated && cpu.reloadCurrentBlockOnModification) { + if(invalidated && cpu.SYSFLAG_FLUSHONMODIFY) { invalidated = false; throw ProcessorException.SELFMODIFIED; } diff --git a/org/jpc/emulator/memory/codeblock/optimised/Virtual8086ModeUBlock.java b/org/jpc/emulator/memory/codeblock/optimised/Virtual8086ModeUBlock.java index 516843d..6bf1b8e 100644 --- a/org/jpc/emulator/memory/codeblock/optimised/Virtual8086ModeUBlock.java +++ b/org/jpc/emulator/memory/codeblock/optimised/Virtual8086ModeUBlock.java @@ -1148,7 +1148,7 @@ public class Virtual8086ModeUBlock implements Virtual8086ModeCodeBlock case JNA_O8: jna_o8((byte)reg0); break; case INSTRUCTION_START: if(cpu.eflagsMachineHalt) throw ProcessorException.TRACESTOP; - if(invalidated && cpu.reloadCurrentBlockOnModification) { + if(invalidated && cpu.SYSFLAG_FLUSHONMODIFY) { invalidated = false; throw ProcessorException.SELFMODIFIED; } diff --git a/org/jpc/emulator/motherboard/IOPortHandler.java b/org/jpc/emulator/motherboard/IOPortHandler.java index b6cd500..9d075f7 100644 --- a/org/jpc/emulator/motherboard/IOPortHandler.java +++ b/org/jpc/emulator/motherboard/IOPortHandler.java @@ -49,19 +49,18 @@ public class IOPortHandler extends AbstractHardwareComponent implements IOPortCa private static final IOPortCapable defaultDevice = new UnconnectedIOPort(); private IOPortCapable[] ioPortDevice; private Clock clock; - private boolean ioportDelayed; + public boolean SYSFLAG_IOPORTDELAY; private final static int IOPORT_READ_DELAY = 666; /** * Constructs a new IOPortHandler with an initially empty ioport * mapping. All ioports map to the unconnected instance. */ - public IOPortHandler(boolean doDelay) + public IOPortHandler() { ioPortDevice = new IOPortCapable[MAX_IOPORTS]; for (int i = 0; i < ioPortDevice.length; i++) ioPortDevice[i] = defaultDevice; - ioportDelayed = doDelay; } public void dumpStatusPartial(StatusDumper output) @@ -91,7 +90,7 @@ public class IOPortHandler extends AbstractHardwareComponent implements IOPortCa for(int i = 0; i < ioPortDevice.length; i++) output.dumpObject(ioPortDevice[i]); output.dumpObject(clock); - output.dumpBoolean(ioportDelayed); + output.dumpBoolean(SYSFLAG_IOPORTDELAY); } public IOPortHandler(SRLoader input) throws IOException @@ -102,30 +101,30 @@ public class IOPortHandler extends AbstractHardwareComponent implements IOPortCa for(int i = 0; i < ioPortDevice.length; i++) ioPortDevice[i] = (IOPortCapable)input.loadObject(); clock = null; - ioportDelayed = false; + SYSFLAG_IOPORTDELAY = false; if(input.objectEndsHere()) return; clock = (Clock)input.loadObject(); - ioportDelayed = input.loadBoolean(); + SYSFLAG_IOPORTDELAY = input.loadBoolean(); } public int ioPortReadByte(int address) { - if(clock != null && ioportDelayed) + if(clock != null && SYSFLAG_IOPORTDELAY) Clock.timePasses(clock, IOPortHandler.IOPORT_READ_DELAY); return ioPortDevice[address].ioPortReadByte(address); } public int ioPortReadWord(int address) { - if(clock != null && ioportDelayed) + if(clock != null && SYSFLAG_IOPORTDELAY) Clock.timePasses(clock, IOPortHandler.IOPORT_READ_DELAY); return ioPortDevice[address].ioPortReadWord(address); } public int ioPortReadLong(int address) { - if(clock != null && ioportDelayed) + if(clock != null && SYSFLAG_IOPORTDELAY) Clock.timePasses(clock, IOPortHandler.IOPORT_READ_DELAY); return ioPortDevice[address].ioPortReadLong(address); } diff --git a/org/jpc/emulator/pci/peripheral/VGACard.java b/org/jpc/emulator/pci/peripheral/VGACard.java index 2904d87..29a9ba0 100644 --- a/org/jpc/emulator/pci/peripheral/VGACard.java +++ b/org/jpc/emulator/pci/peripheral/VGACard.java @@ -305,7 +305,7 @@ public class VGACard extends AbstractPCIDevice implements IOPortCapable, TimerRe private boolean vgaDrawHackFlag; private boolean vgaScroll2HackFlag; - private boolean hretraceEnabled; + public boolean SYSFLAG_VGAHRETRACE; private boolean paletteDebuggingEnabled; //Not saved. @@ -363,7 +363,7 @@ public class VGACard extends AbstractPCIDevice implements IOPortCapable, TimerRe output.printArray(lastChar, "lastChar"); output.println("\tvgaDrawHackFlag " + vgaDrawHackFlag); output.println("\tvgaScroll2HackFlag " + vgaScroll2HackFlag); - output.println("\thretraceEnabled " + hretraceEnabled); + output.println("\tSYSFLAG_VGAHRETRACE " + SYSFLAG_VGAHRETRACE); } public void dumpStatus(StatusDumper output) @@ -451,7 +451,7 @@ public class VGACard extends AbstractPCIDevice implements IOPortCapable, TimerRe output.dumpLong(frameNumber); output.dumpBoolean(updated); output.dumpBoolean(vgaDrawHackFlag); - output.dumpBoolean(hretraceEnabled); + output.dumpBoolean(SYSFLAG_VGAHRETRACE); output.dumpBoolean(vgaScroll2HackFlag); output.dumpInt(usePixelPanning); } @@ -532,14 +532,14 @@ public class VGACard extends AbstractPCIDevice implements IOPortCapable, TimerRe updated = input.loadBoolean(); vgaDrawHackFlag = false; vgaScroll2HackFlag = false; - hretraceEnabled = false; + SYSFLAG_VGAHRETRACE = false; usePixelPanning = pixelPanning; if(input.objectEndsHere()) return; vgaDrawHackFlag = input.loadBoolean(); if(input.objectEndsHere()) return; - hretraceEnabled = input.loadBoolean(); + SYSFLAG_VGAHRETRACE = input.loadBoolean(); if(input.objectEndsHere()) return; vgaScroll2HackFlag = input.loadBoolean(); @@ -563,11 +563,6 @@ public class VGACard extends AbstractPCIDevice implements IOPortCapable, TimerRe vgaScroll2HackFlag = true; } - public void enableVGAHretrace() - { - hretraceEnabled = true; - } - public VGADigitalOut getOutputDevice() { return outputDevice; @@ -909,7 +904,7 @@ public class VGACard extends AbstractPCIDevice implements IOPortCapable, TimerRe chunk = rescaleValue((int)frametime, (int)FRAME_TIME, chunks); st01 &= ~ST01_V_RETRACE; //claim we are not in vertical retrace (in the process of screen refresh) - if(!hretraceEnabled || chunk % 10 < 9) + if(!SYSFLAG_VGAHRETRACE || chunk % 10 < 9) st01 &= ~ST01_DISP_ENABLE; //is set when in h/v retrace (i.e. if e-beam is off, but we claim always on) else { st01 |= ST01_DISP_ENABLE; //is set when in h/v retrace (i.e. if e-beam is off. diff --git a/org/jpc/emulator/processor/Processor.java b/org/jpc/emulator/processor/Processor.java index 9bf7401..ab02769 100644 --- a/org/jpc/emulator/processor/Processor.java +++ b/org/jpc/emulator/processor/Processor.java @@ -139,7 +139,7 @@ public class Processor implements HardwareComponent private boolean started = false; private Clock vmClock; - public boolean reloadCurrentBlockOnModification = false; + public boolean SYSFLAG_FLUSHONMODIFY = false; public FpuState fpu; @@ -262,7 +262,7 @@ public class Processor implements HardwareComponent output.println("\tzeroCalculated " + zeroCalculated + " carryMethod " + carryMethod); output.println("\tcarryCalculated " + carryCalculated + " carryLong " + carryLong); output.println("\tcarryOne " + carryOne + " carryTwo " + carryTwo); - output.println("\treloadCurrentBlockOnModification " + reloadCurrentBlockOnModification); + output.println("\tSYSFLAG_FLUSHONMODIFY " + SYSFLAG_FLUSHONMODIFY); output.println("\tcs "); if(cs != null) cs.dumpStatus(output); output.println("\tds "); if(ds != null) ds.dumpStatus(output); output.println("\tes "); if(es != null) es.dumpStatus(output); @@ -401,7 +401,7 @@ public class Processor implements HardwareComponent } output.dumpBoolean(false); output.dumpBoolean(eflagsWaiting); - output.dumpBoolean(reloadCurrentBlockOnModification); + output.dumpBoolean(SYSFLAG_FLUSHONMODIFY); } public Processor(SRLoader input) throws IOException @@ -503,10 +503,10 @@ public class Processor implements HardwareComponent modelSpecificRegisters.put(key, value); } eflagsWaiting = input.loadBoolean(); - reloadCurrentBlockOnModification = false; + SYSFLAG_FLUSHONMODIFY = false; if(input.objectEndsHere()) return; - reloadCurrentBlockOnModification = input.loadBoolean(); + SYSFLAG_FLUSHONMODIFY = input.loadBoolean(); } diff --git a/org/jpc/pluginsaux/PCConfigDialog.java b/org/jpc/pluginsaux/PCConfigDialog.java index 413b66b..a818111 100644 --- a/org/jpc/pluginsaux/PCConfigDialog.java +++ b/org/jpc/pluginsaux/PCConfigDialog.java @@ -164,7 +164,7 @@ public class PCConfigDialog implements ActionListener, WindowListener addOption("CPU freq. divider", "CPUDIVIDER", "50"); addOption("Memory size (4KiB pages)", "MEMSIZE", "4096"); addOption("Modules", "MODULES", ""); - addBoolean("Emulate I/O delay", "IODELAY"); + addBoolean("Emulate I/O delay", "IOPORTDELAY"); addBoolean("Emulate VGA Hretrace", "VGAHRETRACE"); addBoolean("Shorten pipeline for self-modifying code", "FLUSHONMODIFY"); settings3.get("FLUSHONMODIFY").setSelected(true); @@ -352,9 +352,9 @@ public class PCConfigDialog implements ActionListener, WindowListener hw.hwModules = PC.parseHWModules(hwModulesS); } - hw.ioportDelayed = booleanValue("IODELAY"); - hw.vgaHretrace = booleanValue("VGAHRETRACE"); - hw.flushOnModify = booleanValue("FLUSHONMODIFY"); + hw.booleanOptions = new TreeMap(); + for(Map.Entry box : settings3.entrySet()) + hw.booleanOptions.put(box.getKey(), booleanValue(box.getKey())); } catch(Exception e) { errorDialog(e, "Problem with settings.", window, "Dismiss"); return false; -- 2.11.4.GIT