pub struct ControlUnit {
regs: ControlRegisters,
trap: TrapCircuit,
alarm_unit: AlarmUnit,
}
Expand description
ControlUnit
simulates the operation of the Control Element of the TX-2 computer.
Fields§
§regs: ControlRegisters
§trap: TrapCircuit
§alarm_unit: AlarmUnit
Implementations§
Source§impl ControlUnit
impl ControlUnit
Sourcepub(crate) fn op_spg(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_spg( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the SPG instruction.
Source§impl ControlUnit
impl ControlUnit
Sourcepub(crate) fn op_dpx(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_dpx( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the DPX
instruction (Opcode 016, User Handbook,
page 3-16).
Sourcepub(crate) fn op_aux(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_aux( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the AUX instruction (Opcode 010, User Handbook, page 3-22).
Sourcepub(crate) fn op_rsx(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_rsx( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the RSX instruction (Opcode 011, User Handbook, page 3-14).
Sourcepub(crate) fn op_skx(&mut self, _ctx: &Context) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_skx(&mut self, _ctx: &Context) -> Result<OpcodeResult, Alarm>
Implements the SKX instruction (Opcode 012, User Handbook, page 3-24).
Sourcepub(crate) fn op_jpx(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_jpx( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the JPX (jump on positive index) opcode (06).
Sourcepub(crate) fn op_jnx(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_jnx( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the JNX (jump on positive index) opcode (07).
pub(crate) fn impl_op_jpx_jnx<F: FnOnce(&Signed18Bit) -> bool>( &mut self, ctx: &Context, predicate: F, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Source§impl ControlUnit
impl ControlUnit
Sourcepub(crate) fn op_opr(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
devices: &mut DeviceManager,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_opr( &mut self, ctx: &Context, mem: &mut MemoryUnit, devices: &mut DeviceManager, ) -> Result<OpcodeResult, Alarm>
OPR: Implements the IOS opcode and the AOP opcode.
Bits 2.7 and 2.8 of the N register (i.e. the instruction word) distinguish between IOS and AOP (which together are known as OPR). This decoding is described in section 7-11 (“MISCELLANEOUS OPERATION CODES”) in Volume 1 of the Technical Manual. Neither of these insructions are indexable or configurable (probably because they don’t perform a memory access).
fn op_ios( &mut self, ctx: &Context, mem: &mut MemoryUnit, devices: &mut DeviceManager, ) -> Result<OpcodeResult, Alarm>
fn connect_unit( ctx: &Context, devices: &mut DeviceManager, regs: &mut ControlRegisters, trap: &mut TrapCircuit, unit: Unsigned6Bit, mode: Unsigned12Bit, alarm_unit: &mut AlarmUnit, ) -> Result<(), Alarm>
pub(crate) fn op_tsd( &mut self, ctx: &Context, devices: &mut DeviceManager, execution_address: Address, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Source§impl ControlUnit
§“Jump Skip Class” opcodes
impl ControlUnit
§“Jump Skip Class” opcodes
Sourcepub(crate) fn op_jmp(
&mut self,
_ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_jmp( &mut self, _ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the JMP opcode and its variations (all of which are unconditional jumps).
Sourcepub(crate) fn op_skm(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_skm( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
The SKM instruction. This has a number of supernumerary mnemonics. The index address field of the instruction identifies which bit (within the target word) to operate on, and the instruction configuration value determines both how to manipulate that bit, and what to do on the basis of its original value.
The SKM instruction is documented on pages 7-34 and 7-35 of the TX-2 User Handbook.
Sourcepub(crate) fn op_sed(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_sed( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implement the SED instruction. This is described on page 3-36 of the Users Handbook.
Source§impl ControlUnit
impl ControlUnit
Sourcepub(crate) fn op_lda(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_lda( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the LDA instruction (Opcode 024, User Handbook, page 3-6).
Sourcepub(crate) fn op_ldb(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_ldb( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the LDB instruction (Opcode 025, User Handbook, page 3-6).
Sourcepub(crate) fn op_ldc(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_ldc( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the LDC instruction (Opcode 026, User Handbook, page 3-6).
Sourcepub(crate) fn op_ldd(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_ldd( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the LDD instruction (Opcode 027, User Handbook, page 3-6).
Sourcepub(crate) fn op_lde(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_lde( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the LDE instruction (Opcode 020, User Handbook, page 3-6).
Sourcepub(crate) fn op_sta(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_sta( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the STA instruction (Opcode 034, User Handbook, page 3-8).
Sourcepub(crate) fn op_stb(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_stb( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the STB instruction (Opcode 035, User Handbook, page 3-8).
Sourcepub(crate) fn op_stc(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_stc( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the STC instruction (Opcode 036, User Handbook, page 3-8).
Sourcepub(crate) fn op_std(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_std( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the STD instruction (Opcode 036, User Handbook, page 3-8).
Sourcepub(crate) fn op_ste(
&mut self,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<OpcodeResult, Alarm>
pub(crate) fn op_ste( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<OpcodeResult, Alarm>
Implements the STE instruction (Opcode 030, User Handbook, page 3-8).
Sourcefn op_store_ae_register(
&mut self,
ctx: &Context,
register_value: Unsigned36Bit,
mem: &mut MemoryUnit,
update_e: &UpdateE,
) -> Result<OpcodeResult, Alarm>
fn op_store_ae_register( &mut self, ctx: &Context, register_value: Unsigned36Bit, mem: &mut MemoryUnit, update_e: &UpdateE, ) -> Result<OpcodeResult, Alarm>
Implement opcodes ST{A,B,C,D,E}.
Sourcefn op_load_value(
&mut self,
ctx: &Context,
existing: &Unsigned36Bit,
mem: &mut MemoryUnit,
update_e: &UpdateE,
) -> Result<Unsigned36Bit, Alarm>
fn op_load_value( &mut self, ctx: &Context, existing: &Unsigned36Bit, mem: &mut MemoryUnit, update_e: &UpdateE, ) -> Result<Unsigned36Bit, Alarm>
Implement loads as if for opcodes LD{A,B,C,D,E}.
Source§impl ControlUnit
impl ControlUnit
pub fn new( panic_on_unmasked_alarm: PanicOnUnmaskedAlarm, configuration_memory_config: ConfigurationMemorySetup, ) -> ControlUnit
pub fn diagnostics(&self) -> &CurrentInstructionDiagnostics
fn make_alarm(&self, details: AlarmDetails) -> Alarm
fn fire_details_if_not_masked( &mut self, alarm_details: AlarmDetails, ) -> Result<(), Alarm>
pub fn set_alarm_masked( &mut self, kind: AlarmKind, masked: bool, ) -> Result<(), Alarm>
pub fn unmasked_alarm_active(&self) -> bool
pub fn get_status_of_alarm(&self, name: &str) -> Option<AlarmStatus>
pub fn get_alarm_statuses(&self) -> Vec<AlarmStatus>
pub fn set_metabits_disabled(&mut self, disable: bool)
Sourcepub fn codabo(
&mut self,
ctx: &Context,
reset_mode: &ResetMode,
devices: &mut DeviceManager,
mem: &mut MemoryUnit,
) -> Result<(), Alarm>
pub fn codabo( &mut self, ctx: &Context, reset_mode: &ResetMode, devices: &mut DeviceManager, mem: &mut MemoryUnit, ) -> Result<(), Alarm>
There are actually 9 different CODABO buttons (see page 5-18
of the User Guide). There are also 9 corresponding RESET
buttons. Each RESET button has a corresponding CODABO button.
See the reset
method for address assignments.
The CODABO operation leaves the Start Point Register set to the selected start point. There are also 9 reset buttons which perform a similar task.
Pressing the main CODABO button (the one which uses the Toggle Start Point register) will result in memory being cleared, F-memory being set up in a standard way, and then a program being read from the paper tape reader using the standard readin program set up on the plugboard.
The standard readin program executes the program it read in from the address specified by the program. The program executes as sequence 52 (PETR) with the PETR unit initially turned off.
The Users Handbook (page 5-18) states that flags are cleared but it doesn’t state anywhere that any registers are reset. So we don’t do that. But there’s no unit test for that, since I haven’t found (or cannot recall) a piece of documentation which states that this is so.
Sourcefn preset(
&mut self,
ctx: &Context,
devices: &mut DeviceManager,
) -> Result<(), Alarm>
fn preset( &mut self, ctx: &Context, devices: &mut DeviceManager, ) -> Result<(), Alarm>
Simulate the effect of the PRESET button. This is described on page 5-19 of the Users Handbook. It:
- clears all flags
- Clears all “Connect” flip-flops
- Set all interlocks and indicators to their proper “PRESET” value.
PRESET is supposedly interlocked so that it is ineffective unless the machine is in the STOP state. But our simulation, right now, has no representation for the STOP state.
Sourcefn calaco(&mut self)
fn calaco(&mut self)
Simulate the effect of the CALACO button. This is described on page 5-19 of the Users Handbook.
fn clear_alarms(&mut self)
pub fn disconnect_all_devices( &mut self, ctx: &Context, devices: &mut DeviceManager, ) -> Result<(), Alarm>
Sourcepub fn reset(
&mut self,
ctx: &Context,
reset_mode: &ResetMode,
mem: &mut MemoryUnit,
)
pub fn reset( &mut self, ctx: &Context, reset_mode: &ResetMode, mem: &mut MemoryUnit, )
There are 9 separate RESET buttons, for 8 fixed addresses and another which uses the Toggle Start Point register. There appear to be two Toggle Start Point switches, one on the front panel and a second on a remote control unit. The fixed-address RESET buttons correspond to the fixed addresses 3777710 through 3777717, inclusive.
RESET only loads the Start Point Register, nothing else.
Sourcepub fn startover(
&mut self,
ctx: &Context,
reset_mode: &ResetMode,
mem: &mut MemoryUnit,
)
pub fn startover( &mut self, ctx: &Context, reset_mode: &ResetMode, mem: &mut MemoryUnit, )
Handle press of STARTOVER (or part of the operation of CODABO). STARTOVER does RESET and then raises flag zero.
Sourcefn tsp(&self) -> Address
fn tsp(&self) -> Address
Return the value in the Toggle Start Register (TSP).
The TSP is a set of toggle switches on the TX-2’s console (see the TX-2 Users Handbook section 4-2.2).
For now, we haven’t made it configurable (i.e. have not emulated the hardware) yet. We just hard-code it to point at the F-memory configuration routine (which does its job and then invokes the standard tape reader).
§Caveat
We used to set this to point at the “Memory Clear / Memory
Smear” program in the plugboard (see
memory::get_standard_plugboard()
), but that accesses
addresses which are not mapped (e.g. the gap between U-memory
and V-memory) and so should only be run qith QSAL disabled,
which is not our default config.
We should double-check how the TX-2’s TSP was normally set and how the TX-2 behaved around this.
fn trap_seq() -> Unsigned6Bit
fn raise_trap(&mut self)
fn change_sequence( &mut self, mem: &mut MemoryUnit, prev_seq: Option<SequenceNumber>, next_seq: SequenceNumber, )
fn set_program_counter(&mut self, change: ProgramCounterChange)
Sourcefn select_sequence(&mut self, mem: &mut MemoryUnit) -> RunMode
fn select_sequence(&mut self, mem: &mut MemoryUnit) -> RunMode
Consider whether a change of sequence is needed. If yes, perform the change.
fn fetch_instruction( &mut self, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<(), Alarm>
pub fn poll_hardware( &mut self, ctx: &Context, devices: &mut DeviceManager, run_mode: RunMode, ) -> Result<(RunMode, Option<Duration>), Alarm>
fn update_n_register( &mut self, instruction_word: Unsigned36Bit, ) -> Result<(), Alarm>
fn invalid_opcode_alarm(&self) -> Alarm
fn invalid_opr_subcode(&self, bit2dot7: bool) -> Alarm
fn estimate_execute_time_ns(&self, orig_inst: &Instruction) -> u64
Sourcepub fn execute_instruction(
&mut self,
ctx: &Context,
devices: &mut DeviceManager,
mem: &mut MemoryUnit,
poll_order_change: &mut Option<SequenceNumber>,
) -> Result<(u64, RunMode, Option<OutputEvent>), (Alarm, Address)>
pub fn execute_instruction( &mut self, ctx: &Context, devices: &mut DeviceManager, mem: &mut MemoryUnit, poll_order_change: &mut Option<SequenceNumber>, ) -> Result<(u64, RunMode, Option<OutputEvent>), (Alarm, Address)>
Fetch and execute the next instruction pointed to by the P register. Returns the estimated number of nanoseconds needed to execute the instruction.
fn get_config(&self) -> SystemConfiguration
fn fetch_operand_from_address_with_exchange( &mut self, ctx: &Context, mem: &mut MemoryUnit, operand_address: &Address, existing_dest: &Unsigned36Bit, update_e: &UpdateE, ) -> Result<(Unsigned36Bit, ExtraBits), Alarm>
fn fetch_operand_from_address_without_exchange( &mut self, ctx: &Context, mem: &mut MemoryUnit, operand_address: &Address, update_e: &UpdateE, ) -> Result<(Unsigned36Bit, ExtraBits), Alarm>
fn memory_store_without_exchange( &mut self, ctx: &Context, mem: &mut MemoryUnit, target: &Address, value: &Unsigned36Bit, update_e: &UpdateE, meta_op: &MetaBitChange, ) -> Result<(), Alarm>
fn memory_store_with_exchange( &mut self, ctx: &Context, mem: &mut MemoryUnit, target: &Address, value: &Unsigned36Bit, existing: &Unsigned36Bit, update_e: &UpdateE, meta_op: &MetaBitChange, ) -> Result<(), Alarm>
Sourcefn operand_address_with_optional_defer_and_index(
self: &mut ControlUnit,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<Address, Alarm>
fn operand_address_with_optional_defer_and_index( self: &mut ControlUnit, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<Address, Alarm>
Determine the address of the operand for instructions that use indexing.
Sourcefn operand_address_with_optional_defer_without_index(
self: &mut ControlUnit,
ctx: &Context,
mem: &mut MemoryUnit,
) -> Result<Address, Alarm>
fn operand_address_with_optional_defer_without_index( self: &mut ControlUnit, ctx: &Context, mem: &mut MemoryUnit, ) -> Result<Address, Alarm>
Determine the address of the operand for instructions that do not use indexing.
Sourcefn resolve_operand_address(
self: &mut ControlUnit,
ctx: &Context,
mem: &mut MemoryUnit,
initial_index_override: Option<Unsigned6Bit>,
) -> Result<Address, Alarm>
fn resolve_operand_address( self: &mut ControlUnit, ctx: &Context, mem: &mut MemoryUnit, initial_index_override: Option<Unsigned6Bit>, ) -> Result<Address, Alarm>
Resolve the address of the operand of the current instruction, leaving this address in the Q register.
§Arguments
ctx
- context data for the execution of the instruction.mem
- the memory unit (which we would use for deferred indexing).initial_index_override
- source of the j bits (index register number) to be used; this is specified when processing theJNX
instruction for example. If the value isNone
, the value is instead taken from the N register.