package org.jpc.emulator.motherboard;
import java.io.*;
import java.nio.charset.Charset;
import java.util.logging.*;
import org.jpc.emulator.*;
/**
* This class provides a <code>Bios</code> implementation for the emulated
* machines system bios. The system bios is loaded so that it runs up to address
* 0x100000 (1M).
* <p>
* IO ports <code>0x400-0x403</code> are registered for debugging output. Byte
* writes cause ASCII characters to be written to standard output, and word
* writes indicate a BIOS panic at the written value line number.
* <p>
* IO port <code>0x8900</code> is registered for system shutdown requests.
* Currently this triggers a debugging output, but does not actually shutdown
* the machine.
* @author Chris Dennis
*/
public class SystemBIOS extends Bios implements IODevice
{
private static final Logger LOGGING = Logger.getLogger(SystemBIOS.class.getName());
private static final Charset US_ASCII = Charset.forName("US-ASCII");
private boolean ioportRegistered;
public SystemBIOS(String image) throws IOException
{
super(image);
ioportRegistered = false;
}
public void loadState(DataInput input) throws IOException
{
super.loadState(input);
ioportRegistered = false;
}
public int[] ioPortsRequested()
{
return new int[]{0x400, 0x401, 0x402, 0x403, 0x8900};
}
public void ioPortWrite8(int address, int data)
{
switch (address) {
/* Bochs BIOS Messages */
case 0x402:
case 0x403:
print(new String(new byte[]{(byte) data}, US_ASCII));
break;
case 0x8900:
LOGGING.log(Level.INFO, "attempted shutdown");
break;
default:
}
}
public void ioPortWrite16(int address, int data)
{
switch (address) {
/* Bochs BIOS Messages */
case 0x400:
case 0x401:
LOGGING.log(Level.SEVERE, "panic in rombios.c at line {0,number,integer}", Integer.valueOf(data));
}
}
public int ioPortRead8(int address)
{
return 0xff;
}
public int ioPortRead16(int address)
{
return 0xffff;
}
public int ioPortRead32(int address)
{
return 0xffffffff;
}
public void ioPortWrite32(int address, int data)
{
}
protected int loadAddress()
{
return 0x100000 - length();
}
public boolean updated()
{
return super.updated() && ioportRegistered;
}
public void updateComponent(HardwareComponent component)
{
super.updateComponent(component);
if ((component instanceof IOPortHandler) && component.updated()) {
((IOPortHandler) component).registerIOPortCapable(this);
ioportRegistered = true;
}
}
public boolean initialised()
{
return super.initialised() && ioportRegistered;
}
public void acceptComponent(HardwareComponent component)
{
super.acceptComponent(component);
if ((component instanceof IOPortHandler) && component.initialised()) {
((IOPortHandler) component).registerIOPortCapable(this);
ioportRegistered = true;
}
}
public void reset()
{
super.reset();
ioportRegistered = false;
}
}