2 JPC-RR: A x86 PC Hardware Emulator
5 Copyright (C) 2007-2009 Isis Innovation Limited
6 Copyright (C) 2009 H. Ilari Liusvaara
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as published by
10 the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 Based on JPC x86 PC Hardware emulator,
22 A project from the Physics Dept, The University of Oxford
24 Details about original JPC can be found at:
26 www-jpc.physics.ox.ac.uk
30 package org
.jpc
.pluginsaux
;
32 import org
.jpc
.emulator
.PC
;
33 import org
.jpc
.diskimages
.DiskImage
;
34 import org
.jpc
.emulator
.DriveSet
;
35 import static org
.jpc
.Misc
.errorDialog
;
40 import java
.awt
.event
.*;
43 public class PCConfigDialog
implements ActionListener
, WindowListener
45 private JFrame window
;
47 private PC
.PCHardwareInfo hw
;
48 private PC
.PCHardwareInfo hwr
;
49 private boolean answerReady
;
50 private Map
<String
, JTextField
> settings
;
51 private Map
<String
, JComboBox
> settings2
;
52 private Map
<String
, JCheckBox
> settings3
;
53 private Map
<String
, Long
> settings2Types
;
54 private Map
<String
, String
[]> settings2Values
;
55 private JComboBox bootDevice
;
57 public void addOption(String name
, String id
, String deflt
)
59 JLabel label
= new JLabel(name
);
60 JTextField text
= new JTextField(deflt
, 40);
61 settings
.put(id
, text
);
66 public void addBoolean(String name
, String id
)
68 JLabel label
= new JLabel(name
);
69 JCheckBox box
= new JCheckBox("");
70 settings3
.put(id
, box
);
75 public void addDiskCombo(String name
, String id
, long type
) throws Exception
77 String
[] choices
= DiskImage
.getLibrary().imagesByType(type
);
78 JLabel label
= new JLabel(name
);
83 settings2
.put(id
, new JComboBox(choices
));
85 settings2
.put(id
, new JComboBox());
87 panel
.add(settings2
.get(id
));
88 settings2Types
.put(id
, new Long(type
));
89 settings2Values
.put(id
, choices
);
94 //Hack to default the BIOS images.
95 if((type
& 16) != 0 && Arrays
.binarySearch(choices
, id
, null) >= 0)
96 settings2
.get(id
).setSelectedItem(id
);
99 public void updateDiskCombo(String id
) throws Exception
101 String
[] choices
= DiskImage
.getLibrary().imagesByType(
102 settings2Types
.get(id
).longValue());
104 throw new Exception("No valid " + id
+ " image");
105 Arrays
.sort(choices
);
106 String
[] oldChoices
= settings2Values
.get(id
);
107 int oldChoicesLen
= 0;
108 if(oldChoices
!= null)
109 oldChoicesLen
= oldChoices
.length
;
110 JComboBox combo
= settings2
.get(id
);
113 while(i
< oldChoicesLen
|| j
< choices
.length
) {
115 if(i
== oldChoicesLen
)
117 else if(j
== choices
.length
)
120 x
= oldChoices
[i
].compareTo(choices
[j
]);
123 combo
.removeItem(oldChoices
[i
]);
126 combo
.addItem(choices
[j
]);
133 settings2Values
.put(id
, choices
);
136 public PCConfigDialog() throws Exception
138 hw
= new PC
.PCHardwareInfo();
141 window
= new JFrame("PC Settings");
142 settings
= new HashMap
<String
, JTextField
>();
143 settings2
= new HashMap
<String
, JComboBox
>();
144 settings3
= new HashMap
<String
, JCheckBox
>();
146 settings2Types
= new HashMap
<String
, Long
>();
147 settings2Values
= new HashMap
<String
, String
[]>();
149 GridLayout layout
= new GridLayout(0, 2);
150 panel
= new JPanel(layout
);
152 window
.addWindowListener(this);
154 addDiskCombo("BIOS image", "BIOS", 16);
155 addDiskCombo("VGA BIOS image", "VGABIOS", 16);
156 addDiskCombo("Fda image", "FDA", 3);
157 addDiskCombo("Fdb image", "FDB", 3);
158 addDiskCombo("Hda image", "HDA", 5);
159 addDiskCombo("Hdb image", "HDB", 5);
160 addDiskCombo("Hdc image", "HDC", 5);
161 addDiskCombo("Hdd image", "HDD", 5);
162 addDiskCombo("CD-ROM image", "CDROM", 9);
163 addOption("Initial RTC time", "INITTIME", "1000000000000");
164 addOption("CPU freq. divider", "CPUDIVIDER", "50");
165 addOption("Memory size (4KiB pages)", "MEMSIZE", "4096");
166 addOption("Modules", "MODULES", "");
167 addBoolean("Emulate I/O delay", "IODELAY");
169 JLabel label1
= new JLabel("Boot device");
170 bootDevice
= new JComboBox(new String
[]{"fda", "hda", "cdrom"});
171 bootDevice
.setEditable(false);
173 panel
.add(bootDevice
);
175 JButton ass
= new JButton("Assemble");
176 ass
.setActionCommand("ASSEMBLE");
177 ass
.addActionListener(this);
178 JButton cancl
= new JButton("Cancel");
179 cancl
.setActionCommand("CANCEL");
180 cancl
.addActionListener(this);
185 window
.setDefaultCloseOperation(JFrame
.DO_NOTHING_ON_CLOSE
);
188 public void popUp() throws Exception
190 updateDiskCombo("BIOS");
191 updateDiskCombo("VGABIOS");
192 updateDiskCombo("FDA");
193 updateDiskCombo("FDB");
194 updateDiskCombo("HDA");
195 updateDiskCombo("HDB");
196 updateDiskCombo("HDC");
197 updateDiskCombo("HDD");
198 updateDiskCombo("CDROM");
200 window
.setVisible(true);
203 public synchronized PC
.PCHardwareInfo
waitClose()
209 while(!answerReady
) {
212 } catch(InterruptedException e
) {
219 private String
textFor(String field
)
222 if(settings
.containsKey(field
))
223 x
= settings
.get(field
).getText();
225 x
= (String
)(settings2
.get(field
).getSelectedItem());
227 if(!("".equals(x
))) {
233 private boolean booleanValue(String field
)
236 if(settings3
.containsKey(field
))
237 x
= settings3
.get(field
).isSelected();
241 private boolean checkOK()
244 String sysBIOSImg
= textFor("BIOS");
245 hw
.biosID
= DiskImage
.getLibrary().canonicalNameFor(sysBIOSImg
);
246 if(hw
.biosID
== null)
247 throw new IOException("Can't find image \"" + sysBIOSImg
+ "\".");
249 String vgaBIOSImg
= textFor("VGABIOS");
250 hw
.vgaBIOSID
= DiskImage
.getLibrary().canonicalNameFor(vgaBIOSImg
);
251 if(hw
.vgaBIOSID
== null)
252 throw new IOException("Can't find image \"" + vgaBIOSImg
+ "\".");
254 String hdaImg
= textFor("HDA");
255 hw
.hdaID
= DiskImage
.getLibrary().canonicalNameFor(hdaImg
);
256 if(hw
.hdaID
== null && hdaImg
!= null)
257 throw new IOException("Can't find image \"" + hdaImg
+ "\".");
259 String hdbImg
= textFor("HDB");
260 hw
.hdbID
= DiskImage
.getLibrary().canonicalNameFor(hdbImg
);
261 if(hw
.hdbID
== null && hdbImg
!= null)
262 throw new IOException("Can't find image \"" + hdbImg
+ "\".");
264 String hdcImg
= textFor("HDC");
265 hw
.hdcID
= DiskImage
.getLibrary().canonicalNameFor(hdcImg
);
266 if(hw
.hdcID
== null && hdcImg
!= null)
267 throw new IOException("Can't find image \"" + hdcImg
+ "\".");
269 String hddImg
= textFor("HDD");
270 hw
.hddID
= DiskImage
.getLibrary().canonicalNameFor(hddImg
);
271 if(hw
.hddID
== null && hddImg
!= null)
272 throw new IOException("Can't find image \"" + hddImg
+ "\".");
274 String cdRomFileName
= textFor("CDROM");
275 if (cdRomFileName
!= null) {
277 throw new IOException("-hdc and -cdrom are mutually exclusive.");
278 hw
.initCDROMIndex
= hw
.images
.addDisk(new DiskImage(cdRomFileName
, false));
279 hw
.images
.lookupDisk(hw
.initCDROMIndex
).setName(cdRomFileName
+ " (initial cdrom disk)");
281 hw
.initCDROMIndex
= -1;
283 String fdaFileName
= textFor("FDA");
284 if(fdaFileName
!= null) {
285 byte[] fdaID
= DiskImage
.getLibrary().canonicalNameFor(fdaFileName
);
286 if(fdaID
== null && fdaFileName
!= null)
287 throw new IOException("Can't find image \"" + fdaFileName
+ "\".");
288 hw
.initFDAIndex
= hw
.images
.addDisk(new DiskImage(fdaFileName
, false));
289 hw
.images
.lookupDisk(hw
.initFDAIndex
).setName(fdaFileName
+ " (initial fda disk)");
291 hw
.initFDAIndex
= -1;
293 String fdbFileName
= textFor("FDB");
294 if(fdbFileName
!= null) {
295 byte[] fdbID
= DiskImage
.getLibrary().canonicalNameFor(fdbFileName
);
296 if(fdbID
== null && fdbFileName
!= null)
297 throw new IOException("Can't find image \"" + fdbFileName
+ "\".");
298 hw
.initFDBIndex
= hw
.images
.addDisk(new DiskImage(fdbFileName
, false));
299 hw
.images
.lookupDisk(hw
.initFDBIndex
).setName(fdbFileName
+ " (initial fdb disk)");
301 hw
.initFDBIndex
= -1;
303 String initTimeS
= textFor("INITTIME");
305 hw
.initRTCTime
= Long
.parseLong(initTimeS
, 10);
306 if(hw
.initRTCTime
< 0 || hw
.initRTCTime
> 4102444799999L)
307 throw new Exception("Invalid time value (bounds are 0 and 4102444799999).");
308 } catch(Exception e
) {
309 if(initTimeS
!= null)
311 hw
.initRTCTime
= 1000000000000L;
314 String cpuDividerS
= textFor("CPUDIVIDER");
316 hw
.cpuDivider
= Integer
.parseInt(cpuDividerS
, 10);
317 if(hw
.cpuDivider
< 1 || hw
.cpuDivider
> 256)
318 throw new Exception("Invalid CPU divider value (bounds are 1 and 256).");
319 } catch(Exception e
) {
320 if(cpuDividerS
!= null)
325 hw
.fpuEmulator
= null;
327 String memoryPagesS
= textFor("MEMSIZE");
329 hw
.memoryPages
= Integer
.parseInt(memoryPagesS
, 10);
330 if(hw
.memoryPages
< 256 || hw
.memoryPages
> 262144)
331 throw new Exception("Invalid memory size value (bounds are 256 and 262144).");
332 } catch(Exception e
) {
333 if(memoryPagesS
!= null)
335 hw
.memoryPages
= 4096;
338 String bootArg
= (String
)bootDevice
.getSelectedItem();
339 bootArg
= bootArg
.toLowerCase();
340 if (bootArg
.equals("fda"))
341 hw
.bootType
= DriveSet
.BootType
.FLOPPY
;
342 else if (bootArg
.equals("hda"))
343 hw
.bootType
= DriveSet
.BootType
.HARD_DRIVE
;
344 else if (bootArg
.equals("cdrom"))
345 hw
.bootType
= DriveSet
.BootType
.CDROM
;
347 String hwModulesS
= textFor("MODULES");
348 if(hwModulesS
!= null) {
349 hw
.hwModules
= PC
.parseHWModules(hwModulesS
);
352 hw
.ioportDelayed
= booleanValue("IODELAY");
353 System
.err
.println("hw.ioportDelayed = " + hw
.ioportDelayed
);
354 } catch(Exception e
) {
355 errorDialog(e
, "Problem with settings.", window
, "Dismiss");
361 public void actionPerformed(ActionEvent evt
)
363 String command
= evt
.getActionCommand();
364 System
.err
.println("Command: " + command
);
365 if(command
== "ASSEMBLE") {
367 hw
= new PC
.PCHardwareInfo();
370 window
.setVisible(false);
375 hw
= new PC
.PCHardwareInfo();
377 hw
= new PC
.PCHardwareInfo();
378 } else if(command
== "CANCEL") {
379 window
.setVisible(false);
388 public void windowActivated(WindowEvent e
) { /* Not interested. */ }
389 public void windowClosed(WindowEvent e
) { /* Not interested. */ }
390 public void windowDeactivated(WindowEvent e
) { /* Not interested. */ }
391 public void windowDeiconified(WindowEvent e
) { /* Not interested. */ }
392 public void windowIconified(WindowEvent e
) { /* Not interested. */ }
393 public void windowOpened(WindowEvent e
) { /* Not interested. */ }
395 public void windowClosing(WindowEvent e
)
397 window
.setVisible(false);