102 lines
2.5 KiB
C#
102 lines
2.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
using Essgee.Exceptions;
|
|
using Essgee.Utilities;
|
|
|
|
namespace Essgee.Emulation.Peripherals
|
|
{
|
|
public class Intel8255 : IPeripheral
|
|
{
|
|
[StateRequired]
|
|
public byte PortAInput { get; set; }
|
|
[StateRequired]
|
|
public byte PortBInput { get; set; }
|
|
[StateRequired]
|
|
public byte PortCInput { get; set; }
|
|
[StateRequired]
|
|
public byte PortAOutput { get; set; }
|
|
[StateRequired]
|
|
public byte PortBOutput { get; set; }
|
|
[StateRequired]
|
|
public byte PortCOutput { get; set; }
|
|
|
|
[StateRequired]
|
|
byte configByte, setResetControlByte;
|
|
|
|
int operatingModeGroupA => ((configByte >> 5) & 0x03);
|
|
bool isPortAInput => ((configByte & 0x10) == 0x10);
|
|
bool isPortCUInput => ((configByte & 0x08) == 0x08);
|
|
int operatingModeGroupB => ((configByte >> 2) & 0x01);
|
|
bool isPortBInput => ((configByte & 0x02) == 0x02);
|
|
bool isPortCLInput => ((configByte & 0x01) == 0x01);
|
|
int bitToChange => ((setResetControlByte >> 1) & 0x07);
|
|
bool isSetBitOperation => ((setResetControlByte & 0x01) == 0x01);
|
|
|
|
public Intel8255() { }
|
|
|
|
public void Startup()
|
|
{
|
|
//
|
|
}
|
|
|
|
public void Shutdown()
|
|
{
|
|
//
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
PortAInput = PortAOutput = 0x00;
|
|
PortBInput = PortBOutput = 0x00;
|
|
PortCInput = PortCOutput = 0x00;
|
|
|
|
WritePort(0x03, 0x9B);
|
|
}
|
|
|
|
public byte ReadPort(byte port)
|
|
{
|
|
switch (port & 0x03)
|
|
{
|
|
case 0x00: return (isPortAInput ? PortAInput : PortAOutput);
|
|
case 0x01: return (isPortBInput ? PortBInput : PortBOutput);
|
|
case 0x02: return (byte)(((isPortCUInput ? PortCInput : PortCOutput) & 0xF0) | (isPortCLInput ? PortCInput : PortCOutput) & 0x0F);
|
|
case 0x03: return 0xFF; /* Cannot read control port */
|
|
|
|
default: throw new EmulationException(string.Format("i8255: Unsupported read from port 0x{0:X2}", port));
|
|
}
|
|
}
|
|
|
|
public void WritePort(byte port, byte value)
|
|
{
|
|
switch (port & 0x03)
|
|
{
|
|
case 0x00: PortAOutput = value; break;
|
|
case 0x01: PortBOutput = value; break;
|
|
case 0x02: PortCOutput = value; break;
|
|
|
|
case 0x03:
|
|
/* Control port */
|
|
if ((value & 0x80) == 0x80)
|
|
{
|
|
configByte = value;
|
|
}
|
|
else
|
|
{
|
|
setResetControlByte = value;
|
|
|
|
byte mask = (byte)(1 << bitToChange);
|
|
if (isSetBitOperation) PortCOutput |= mask;
|
|
else PortCOutput &= (byte)~mask;
|
|
}
|
|
break;
|
|
|
|
default: throw new EmulationException(string.Format("i8255: Unsupported write to port 0x{0:X2}, value 0x{1:X2}", port, value));
|
|
}
|
|
}
|
|
}
|
|
}
|