namespace Contralto.Display
{
///
/// FakeDisplayController draws the display without the aid of the
/// display microcode tasks (i.e. it cheats). It reads the displaylist
/// starting at DASTART and renders the display from there.
///
public class FakeDisplayController : IClockable
{
public FakeDisplayController(AltoSystem system)
{
_system = system;
Reset();
}
public void AttachDisplay(IAltoDisplay display)
{
_display = display;
}
public void Reset()
{
}
public void Clock()
{
_clocks++;
if (_clocks > _frameClocks)
{
_clocks -= _frameClocks;
RenderDisplay();
_display.Render();
}
}
private void RenderDisplay()
{
// pick up DASTART; if zero we render a blank screen.
ushort daStart = _system.MemoryBus.DebugReadWord(0x110);
if (daStart == 0)
{
for (int scanline = 0; scanline < 808; scanline++)
{
for (int word = 0; word < 38; word++)
{
_display.DrawDisplayWord(scanline, word, 0xffff, false);
}
}
_display.Render();
return;
}
DCB dcb = GetNextDCB(daStart);
int dcbScanline = 0;
for (int scanline = 0; scanline < 808; scanline++)
{
int wordOffset = 0;
// fill in HTAB
for(int htab = 0;htab> 8;
dcb.nWrds = (mode & 0xff);
dcb.startAddress = _system.MemoryBus.DebugReadWord((ushort)(address + 2));
dcb.scanlineCount = _system.MemoryBus.DebugReadWord((ushort)(address + 3)) * 2;
return dcb;
}
private struct DCB
{
public ushort daNext;
public bool lowRes;
public bool whiteOnBlack;
public int hTab;
public int nWrds;
public ushort startAddress;
public int scanlineCount;
}
private double _clocks;
private AltoSystem _system;
private IAltoDisplay _display;
// Timing constants
// 38uS per scanline; 4uS for hblank.
// ~35 scanlines for vblank (1330uS)
private const double _scanlineClocks = 38.0 / 0.017;
private const double _frameClocks = _scanlineClocks * 850; // approx.
}
}