/* 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 . */ using Contralto.Logging; using System; namespace Contralto.CPU { public partial class AltoCPU { /// /// OrbitTask provides the implementation of the Orbit (printer rasterizer) controller /// specific functions. /// private sealed class OrbitTask : Task { public OrbitTask(AltoCPU cpu) : base(cpu) { _taskType = TaskType.Orbit; _wakeup = false; } public override void OnTaskSwitch() { // We put ourselves back to sleep immediately once we've started running. //_wakeup = false; } protected override void ExecuteBlock() { //_wakeup = false; _cpu._system.OrbitController.Stop(); } protected override InstructionCompletion ExecuteInstruction(MicroInstruction instruction) { // TODO: get rid of polling. //_wakeup = _cpu._system.OrbitController.Wakeup; return base.ExecuteInstruction(instruction); } 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 0x0; // 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)); } } } } }