mirror of
https://github.com/livingcomputermuseum/ContrAlto.git
synced 2026-01-21 18:14:54 +00:00
Added file-backed disk image implementation for use with Trident disk images, did some basic refactoring of disk load/unload logic, added support for creating new (empty) disk images for both Trident and Diablo disks. Added UI for loading/unloading/creating up to 8 trident packs; added blank Diablo pack creation UI. (Both Windows and *nix interfaces.) Added configuration support for same (both Windows and *nix.) Small correction to Print output path browsing logic. Fixed Windows installer, now places the right ROMs for Alto I configurations in the right place. Fixed issue when starting up with corrupted configuration. Corrupted configuration is ignored and ContrAlto will run with default config.
163 lines
6.1 KiB
C#
163 lines
6.1 KiB
C#
/*
|
|
This file is part of ContrAlto.
|
|
|
|
ContrAlto is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
ContrAlto is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with ContrAlto. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
using Contralto.Logging;
|
|
using System;
|
|
|
|
namespace Contralto.CPU
|
|
{
|
|
public partial class AltoCPU
|
|
{
|
|
/// <summary>
|
|
/// OrbitTask provides the implementation of the Orbit (printer rasterizer) controller
|
|
/// specific functions.
|
|
/// </summary>
|
|
private sealed class OrbitTask : Task
|
|
{
|
|
public OrbitTask(AltoCPU cpu) : base(cpu)
|
|
{
|
|
_taskType = TaskType.Orbit;
|
|
_wakeup = false;
|
|
|
|
// The Orbit task is RAM-related.
|
|
_ramTask = true;
|
|
}
|
|
|
|
protected override void ExecuteBlock()
|
|
{
|
|
_cpu._system.OrbitController.Stop();
|
|
}
|
|
|
|
protected override ushort GetBusSource(MicroInstruction instruction)
|
|
{
|
|
//
|
|
// The Orbit task is wired to be a RAM-enabled task so it can use
|
|
// S registers.
|
|
// This code is stolen from the Emulator task; we should refactor this...
|
|
//
|
|
EmulatorBusSource ebs = (EmulatorBusSource)instruction.BS;
|
|
|
|
switch (ebs)
|
|
{
|
|
case EmulatorBusSource.ReadSLocation:
|
|
if (instruction.RSELECT != 0)
|
|
{
|
|
return _cpu._s[_rb][instruction.RSELECT];
|
|
}
|
|
else
|
|
{
|
|
// "...when reading data from the S registers onto the processor bus,
|
|
// the RSELECT value 0 causes the current value of the M register to
|
|
// appear on the bus..."
|
|
return _cpu._m;
|
|
}
|
|
|
|
case EmulatorBusSource.LoadSLocation:
|
|
// "When an S register is being loaded from M, the processor bus receives an
|
|
// undefined value rather than being set to zero."
|
|
_loadS = true;
|
|
return 0xffff; // Technically this is an "undefined value," we're defining it as -1.
|
|
|
|
default:
|
|
throw new InvalidOperationException(String.Format("Unhandled bus source {0}", instruction.BS));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
protected override void ExecuteSpecialFunction1Early(MicroInstruction instruction)
|
|
{
|
|
OrbitF1 of1 = (OrbitF1)instruction.F1;
|
|
switch (of1)
|
|
{
|
|
|
|
case OrbitF1.OrbitDeltaWC:
|
|
_busData &= _cpu._system.OrbitController.GetDeltaWC();
|
|
break;
|
|
|
|
case OrbitF1.OrbitDBCWidthRead:
|
|
_busData &= _cpu._system.OrbitController.GetDBCWidth();
|
|
break;
|
|
|
|
case OrbitF1.OrbitOutputData:
|
|
_busData &= _cpu._system.OrbitController.GetOutputDataAlto();
|
|
break;
|
|
|
|
case OrbitF1.OrbitStatus:
|
|
_busData &= _cpu._system.OrbitController.GetOrbitStatus();
|
|
|
|
// branch:
|
|
// "OrbitStatus sets NEXT[7] of IACS os *not* on, i.e. if Orbit is
|
|
// not in a character segment."
|
|
//
|
|
if (!_cpu._system.OrbitController.IACS)
|
|
{
|
|
_nextModifier |= 0x4;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
|
|
{
|
|
OrbitF2 of2 = (OrbitF2)instruction.F2;
|
|
switch (of2)
|
|
{
|
|
case OrbitF2.OrbitDBCWidthSet:
|
|
_cpu._system.OrbitController.SetDBCWidth(_busData);
|
|
break;
|
|
|
|
case OrbitF2.OrbitXY:
|
|
_cpu._system.OrbitController.SetXY(_busData);
|
|
break;
|
|
|
|
case OrbitF2.OrbitHeight:
|
|
_cpu._system.OrbitController.SetHeight(_busData);
|
|
|
|
// branch:
|
|
// "OrbitHeight sets NEXT[7] if the refresh timer has expired, i.e.
|
|
// if the image buffer needs refreshing."
|
|
//
|
|
if (_cpu._system.OrbitController.RefreshTimerExpired)
|
|
{
|
|
_nextModifier |= 0x4;
|
|
}
|
|
break;
|
|
|
|
case OrbitF2.OrbitFontData:
|
|
_cpu._system.OrbitController.WriteFontData(_busData);
|
|
break;
|
|
|
|
case OrbitF2.OrbitInk:
|
|
_cpu._system.OrbitController.WriteInkData(_busData);
|
|
break;
|
|
|
|
case OrbitF2.OrbitControl:
|
|
_cpu._system.OrbitController.Control(_busData);
|
|
break;
|
|
|
|
case OrbitF2.OrbitROSCommand:
|
|
_cpu._system.OrbitController.SendROSCommand(_busData);
|
|
break;
|
|
|
|
default:
|
|
throw new InvalidOperationException(String.Format("Unhandled orbit F2 {0}.", of2));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|