private static string DisassembleEmulatorSpecialFunction1(MicroInstruction instruction) { EmulatorF1 ef1 = (EmulatorF1)instruction.F1; switch (ef1) { case EmulatorF1.SWMODE: return("SWMODE "); case EmulatorF1.WRTRAM: return("WRTRAM "); case EmulatorF1.RDRAM: return("RDRAM "); case EmulatorF1.LoadRMR: return("RMR← "); case EmulatorF1.LoadESRB: return("ESRB← "); case EmulatorF1.RSNF: return("RSNF "); case EmulatorF1.STARTF: return("STARTF "); default: return(String.Format("F1 {0}", Conversion.ToOctal((int)ef1))); } }
protected override void ExecuteSpecialFunction1Early(MicroInstruction instruction) { EmulatorF1 ef1 = (EmulatorF1)instruction.F1; switch (ef1) { case EmulatorF1.RSNF: // // Early: // "...decoded by the Ethernet interface, which gates the host address wired on the // backplane onto BUS[8-15]. BUS[0-7] is not driven and will therefore be -1. If // no Ethernet interface is present, BUS will be -1. // _busData &= (ushort)((0xff00 | _cpu._system.EthernetController.Address)); break; } }
protected override void ExecuteSpecialFunction1(MicroInstruction instruction) { EmulatorF1 ef1 = (EmulatorF1)instruction.F1; switch (ef1) { case EmulatorF1.LoadRMR: // // "The emulator F1 RMR<- causes the reset mode register to be loaded from the processor bus. The 16 bits of the // processor bus correspond to the 16 Alto tasks in the following way: the low order bit of the processor // bus specifies the initial mode of task 0, the lowest priority task (emulator), and the high-order bit of the // bus specifies the initial mode of task 15, the highest priority task(recall that task i starts at location i; the // reset mode register determines only which microinstruction bank will be used at the outset). A task will // commence in ROM0 if its associated bit in the reset mode register contains the value 1; otherwise it will // start in RAM0.Upon initial power - up of the Alto, and after each reset operation, the reset mode register // is automatically set to all ones, corresponding to starting all tasks in ROM0." // _cpu._rmr = _busData; break; case EmulatorF1.RSNF: // Handled in the Early handler. break; case EmulatorF1.STARTF: // Dispatch function to Ethernet I/O based on contents of AC0. if ((_busData & 0x8000) != 0) { // // BOOT (soft-reset) operation. // Reset the CPU using the current RMR (start tasks in RAM or ROM as specified.) _cpu.SoftReset(); // Since this is a soft reset, we don't want MPC to be taken from the NEXT // field at the end of the cycle, setting this flag causes the main Task // implementation to skip updating _mpc at the end of this instruction. _softReset = true; } else if (_busData != 0) { // // Dispatch to the appropriate device. // switch (_busData) { case 1: case 2: case 3: // Ethernet _cpu._system.EthernetController.STARTF(_busData); break; case 4: // Orbit _cpu._system.OrbitController.STARTF(_busData); break; default: Log.Write(Logging.LogType.Warning, Logging.LogComponent.EmulatorTask, "STARTF for non-Ethernet device (code {0})", Conversion.ToOctal(_busData)); break; } } break; case EmulatorF1.SWMODE: _swMode = true; break; case EmulatorF1.RDRAM: _rdRam = true; break; case EmulatorF1.WRTRAM: _wrtRam = true; break; case EmulatorF1.LoadESRB: _rb = (ushort)((_busData & 0xe) >> 1); if (_rb != 0 && _systemType != SystemType.ThreeKRam) { // Force bank 0 for machines with only 1K RAM. _rb = 0; } break; default: throw new InvalidOperationException(String.Format("Unhandled emulator F1 {0}.", ef1)); } }
protected override void ExecuteSpecialFunction1(MicroInstruction instruction) { EmulatorF1 ef1 = (EmulatorF1)instruction.F1; switch (ef1) { case EmulatorF1.LoadRMR: // // "The emulator F1 RMR<- causes the reset mode register to be loaded from the processor bus. The 16 bits of the // processor bus correspond to the 16 Alto tasks in the following way: the low order bit of the processor // bus specifies the initial mode of task 0, the lowest priority task (emulator), and the high-order bit of the // bus specifies the initial mode of task 15, the highest priority task(recall that task i starts at location i; the // reset mode register determines only which microinstruction bank will be used at the outset). A task will // commence in ROM0 if its associated bit in the reset mode register contains the value 1; otherwise it will // start in RAM0. Upon initial power-up of the Alto, and after each reset operation, the reset mode register // is automatically set to all ones, corresponding to starting all tasks in ROM0." // _cpu._rmr = _busData; break; case EmulatorF1.RSNF: // Handled in the Early handler. break; case EmulatorF1.STARTF: // Dispatch function to Ethernet I/O based on contents of AC0. if ((_busData & 0x8000) != 0) { // Since this is a soft reset, we don't want MPC to be taken from the NEXT // field at the end of the cycle, setting this flag causes the main Task // implementation to skip updating _mpc at the end of this instruction. _softReset = true; } else if (_busData != 0) { // // Dispatch to the appropriate device. // switch (_busData) { case 0x01: case 0x02: case 0x03: // Ethernet _cpu._system.EthernetController.STARTF(_busData); break; case 0x04: // Orbit _cpu._system.OrbitController.STARTF(_busData); break; case 0x10: case 0x20: // Trident start _cpu._system.TridentController.STARTF(_busData); break; // // The following are not actual Alto STARTF functions, // these are used to allow writing Alto programs that can // alter behavior of the emulator. At the moment, these // are all related to scripting, and are only enabled // when a script is running. // case 0x2000: // // Unpause script. // if (ScriptManager.IsPlaying) { ScriptManager.CompleteWait(); } break; case 0x4000: // // Emulator exit, commit disks. // if (ScriptManager.IsPlaying) { throw new ShutdownException(true); } break; default: Log.Write(Logging.LogType.Warning, Logging.LogComponent.EmulatorTask, "STARTF for unknown device (code {0})", Conversion.ToOctal(_busData)); break; } } break; case EmulatorF1.SWMODE: _swMode = true; break; case EmulatorF1.RDRAM: // TODO: move RDRAM, WRTRAM and S-register BS stuff into the main Task implementation, // guarded by a check of _ramTask. _rdRam = true; break; case EmulatorF1.WRTRAM: _wrtRam = true; break; case EmulatorF1.LoadESRB: _rb = (ushort)((_busData & 0xe) >> 1); if (_rb != 0 && _systemType != SystemType.ThreeKRam) { // Force bank 0 for machines with only 1K RAM. _rb = 0; } break; default: throw new InvalidOperationException(String.Format("Unhandled emulator F1 {0}.", ef1)); } }