1
0
mirror of https://github.com/livingcomputermuseum/ContrAlto.git synced 2026-01-21 18:14:54 +00:00
Josh Dersch 523a4bb27f Initial implementation of Trident controller and drives (supporting T-80 and T-300 packs). TFU works and can certify, erase, exercise and manipulate files on Trident packs. TriEx doesn't quite work properly yet. Still some issues to iron out.
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.
2017-08-22 13:18:31 -07:00

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));
}
}
}
}
}