Hic Draconis
This chapter is a work in progress. There'll be broken references, speling mistakes, badly written copy and some details missing altogether. Tread lightly! Oh, and yes. It's immense.

The CFT minicomputer is intended to be similar to a 1960s minicomputer, and it could never be similar enough without a programmer's front panel: a front panel that can boot and program the computer.

The front panel allows the state of the computer to be inspected and modified. State inspection is made possible via a number of lights corresponding to the state of the processor's registers in binary. State modification is via a number of switches which control the operation of the computer's main units and allow for user input to enter the computer.

The Debugging Front Panel is a very large sub-project, replacing both the early Programmer’s Front Panel and Debugging Board. It is built on two boards providing a three-way interface between the CFT processor, the front panel, and an optional computer used to automate testing the CFT. The computer may be replaced by a human when running custom diagnostics or even using the front panel remotely.

The DFP forms a triple bidirectional interface.

The DFP forms a triple interface between the CFT computer, the front panel, and a remote test operator, which can be a computer or human.

On the computer side, the DFP behaves as a processor extension. It connects to the Control Bus like processor boards do; it connects to each processor board's front panel interface which mostly outputs register values; and it connects to the Expansion Bus so it can be treated like a peripheral and also control peripherals itself.

On the front panel side, the DFP is connected to most of the lights on the front panel. It directly controls some (but not all of them). It is also connected to all the front panel switches.

On the serial port side, the DFP provides two services. A Virtual Front Panel, a superset of the test harness features of the defunct DEB board: this can read and manipulate the state of the computer, front panel lights and switches, and receive test results from the computer via the DFP controller. The second service is a (slow) Virtual Console, which is a simplistic serial terminal the computer can use to interact with a user.

You can see the integration of computer, panel and serial port in action: in this this video, I toggle in a simple program to demonstrate some of the processor. The video shows the front panel being used to program and operate the computer. The serial port interface shows the state of the switches and memory and is used to verify the work. When the program finally runs, the computer uses the DFP to register successes and display data while the panel lights show its state.

If this reminds you of the unholy love child of 1970s monitor software and modern server management, it's because it's been heavily influenced by both. Monitor software (including the one in the Apple II, AIM-65 and the ‘M’ in ‘CP/M’) came about when computers stopped having physical front panels—they bridge the world of toggle switches and command line operating systems). And of course server management hardware provides a command-line interface to diagnose and control a modern computer.

There's another precedent though: many minicomputers and even workstations used an auxiliary processor for diagnostics. For example, the Xerox Star's IOP board is responsible for the computer's early diagnostics. It even initialises the microcode (held in RAM) and makes the computer able to boot. After boot, it stays around and behaves like an interface to the slower devices like the keyboard and mouse. And to make it even more similar, it's an MCU-baseddiagnostics/testing/peripheral board used to bring up a microcoded processor made out of discrete chips.

C3.1. Subsystems and Facilities

The device is made up of more parts and sub-assemblies and cabling than any other CFT sub-project. There are numerous facilities, both physical and logical.

  • The eponymous front panel, the traditional input/output device of mini-computers.

  • It has 160 lights, though many are left unconnected and some are meant for future expansion. 145 lights are currently installed, wired or assigned future functions.

  • There are switches to control, debug and test the computer.

  • There are some switches to control the front panel itself.

  • Another 16 switches are directly connected to the SR, which can be read by both the computer and front panel. They are the computer's sole input device.

  • A key lock switch to control power.

  • A key lock switch to lock the panel. I put those in because they make the whole thing look more realistic and professionally done. Many mini-computers had them, after all.

  • An internal bank of DIP switches to allow the user to set non-volatile preferences. These depend entirely on the CFT's ROM for interpretation.

  • Wiring facilities that route the processor boards' front panel connectors to the correct front panel lights. These involve a large number of connectors and an even larger quantity of wiring.

  • More wiring facilities to route signals from add-on cards to the lights, including the MBU and IRC.

  • A debouncing facility for the switches controlling computer functions and programming.

  • Mutual lock-out for control switches so that multiple panel operations can't be started simultaneously by mistake. This also includes locking out most panel operations when the panel lock is activated.

  • An optional auto-repeat facility for the Step/Microstep switch. This is useful in debugging and saves wear on the switch.

  • A 16-bit Output Register (OR) which displays its value on the front panel MFD.

  • A sequencer to perform memory and I/O space reads and writes, and optionally increment the address after each cycle. This provides a total of eight bus functions, assigned to four double-throw toggle switches on the front panel.

  • A switch to configure the optional MBU for either bare-metal operation (the computer starts halted, and the entire 64 kWords of memory is RAM), or turn-key operation (ROM is mapped to the top 32 kWords, and the computer starts in the run state, like all modern computers).

  • A switch to issue panel-initiated interrupt requests for interacting with computer programs.

  • A slow clock generator capable of providing two slow clock rates, in addition to the rate provided by the CFT processor's own clock generator. These are useful for debugging and demonstrations.

  • A state machine used to halt the computer at the appropriate part of the processor cycle. This state machine is also used for stepping and micro-stepping.

When the DFP was merged with the DEB board, a number of additional facilities were added, and many were merged together.

C3.2. Standalone Mode

You may see some references to this. Initially, the DFP was meant to operate the computer's buses and peripherals with the precious processor boards unplugged. This would let me test new peripherals without risking damage to the most complex (and thus most difficult to diagnose) components of the system.

Eventually, three things became apparent. One, the DFP was a very good contender for the most difficult component to diagnose problems with. In fact, I'd rather delve into the Processor Boards because at least they're nice and neat. Two, once you have some basic rules down, it's hard to damage the ICs. Three, the processor boards provide some facilities (like bus hold and conditioning, wait states, write strobes, etc.) I'd rather not replicate on the DFP. So the DFP and processor can't operate independently anyway, and Standalone Mode went away. The code is still there in the DFP firmware, and some messages (like those that indicate a processor was found) still hint at how it all was.

C3.3. The Front Panel

The front panel allows the state of the computer to be observer via a number of lights. It also allows the state of the computer to be modified using a number of switches. The CFT front panel is expected to provide a number of services.

  • It provides a means of testing most of the computer's individual units on their own. With some rewiring or reconfiguration, all of the computer's features can be tested.

  • It allows microcode to be inspected and debugged.

  • It allows the computer to be programmed without a ROM. A front panel was historically the only built-in means of programming a minicomputer, and in many cases was the only way the computer could be booted up.

  • It helps debug software and hardware by allowing the computer to be stopped, its state inspected and perhaps changed, and then resuming execution.

  • It allows the state of the running computer to be inspected with varying degrees of success. The human eye is incapable of registering individual light pulses at more than around 20 Hz, seeing varying intensities instead. A trained operator can glean plenty of information from these patterns.

  • It provides the computer with a simple input device (sense switches) and output device (the Output Register).

  • It also provides a simple (if very slow) serial port for early debugging of interactive features, before the TTY board is built.

C3.3.1. Layout of the Front Panel

The front panel displays up to 177 bits of information on 145 lights arranged in two to three columns by five rows. Some lights serve multiple purposes, and others are not yet tasked. It also includes 30 toggle switches that modify the state of the computer and the front panel itself. There are also two key locks: one to control power and one to lock the front panel itself.

All lights and switches displaying multi-bit quantities are arranged with the most significant bit to the right, in the conventional notation of binary numbers. Bit numbers start at 0, which is the least significant bit or rightmost light. This follows the conventional notation of powers-of-two.

Front Panel version 9.

The ninth iteration of the front panel's design, featuring 145 lights, 30 switches and two key locks.

C3.3.2. Evolution of the Front Panel Design

Like everything about the CFT, the front panel has gone through an insane number of revisions. Like everything about the CFT, the front panel wasn't created in a vacuum, either. I was inspired by the front panels of various PDP machines, but finally found my muse in John Doran's D16/M—which also provided some much needed tips on how to construct a beautiful front panel.

Front Panel version 1.

Front Panel version 1: a 6U monstrosity with six rows of light, two rows of switches, a single key switch, and the original, cheekily retro logo.

Front Panel version 2.

Front Panel version 2: the switches are more compact now.

Front Panel version 3.

Front Panel version 3: reorganises the lights to fit the UCB extension indicators.

Front Panel version 4.

Front Panel version 4: the first 4U version, with a single row of switches, two key switches and a more compact arrangement of lights.

Front Panel version 5.

Front Panel version 5: a few minor changes to the light legends to accommodate newer versions of the Microcode.

Front Panel version 6.

Front Panel version 6: the key locks have moved so the keys don't dangle over the toggle switches. The panel is centred. The instruction set cheat sheet under the switches reflects recent Microcode updates. New logo!

Front Panel version 7.

Front Panel version 7: legend changes.

Front Panel version 8.

Front Panel version 8: again, minor incremental changes.

Front Panel version 9.

Front Panel version 9: the logo has moved to the top right corner. Mock switches in roughly the correct colours have been added to the diagram.

C3.3.3. Console Lights

The 144 console lights are arranged in two to three columns and five rows, arranged on a 32×5 grid. The centre of the panel represents various 16-bit values, usually registers. The left side shows smaller vectors and individual bits of state. The right side is reserved for peripherals.

Hey, No Cheating Now!
Yes, there's an Microcontroller Unit (MCU) on board. However, nearly all of the lights on the front panel are connected directly to the Processor Boards. the MCU can sample their values, but it doesn't control them. This is why the back of the front panel is such a rat's nest of cables. There are two exceptions: the Output Register, controlled entirely by the MCU(naturally, since it's a peripheral provided by it), and the Run and Stop lights, which are outputs from the Run Control State Machine which is controlled by the MCU too.

C3.3.3.1. Micro-Instruction Control Vector

●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

This row of 24 lights displays the current output of the microcode store, and the current micro-operation performed by the processor. A light being on indicates an asserted signal: active low signals are inverted to make the display clearer to humans.

C3.3.3.2. Memory Bank Unit

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

This row of 8 yellow lights displays the currently selected memory bank (address bits 13–20). It is driven by the MBU. An additional green MBENlight (leftmost on the third row from the top) indicates that the MBU's soft memory mapping is enabled. When on, the leftmost light indicates the ROM is being accessed. For more information, please consult MBU.

C3.3.3.3. Program Counter

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

This row of 16 red lights displays the current value of the Program Counter (PC).

C3.3.3.4. Flags

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

This row of five green lights displays the state of the processor's flags: the Negative flag (N), Zero flag (Z), Overflow flag (V), Interrupt flag (I) and Link register (L).

C3.3.3.5. Accumulator

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

This row of sixteen red lights displays the current value of the Accumulator (AC).

C3.3.3.6. State

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

This row of seven lights displays major and minor states of the processor. States include Reset, Run, Stop, Wait State, Fetch, Execute states, as well as the Interrupt state, which lights to indicate an interrupt has been received but not yet serviced.

Of these lights, the Run and Stop lights are controlled by the MCU since it controls running, stepping and stopping of the computer. The MCU blinks the Stop light when it encounters a critical fault during self-diagnostics or processor diagnostics at power on. If the Stop light is blinking, it's a clear indication the computer isn't healthy enough to be allowed to come out of reset.

C3.3.3.7. Output Register, Data Register and Micro-Address Vector

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

This row of sixteen lights is an Multi-Function Display (MFD) that can display the value of the front panel's Output Register (OR), the Data Register (DR), or the current Micro-Address vector. The latter represents bits 0–14 of the current address of the Microcode store. The value of the Microcode Store at this address is displayed on the top row. Please note that this is a 15-bit vector, and the rightmost light is not used. Some bits, corresponding to active-low signals, are inverted. These are not inverted to ease reading, since the value is meant to be interpreted as a Microcode Store address.

The Output Register is controlled entirely by the MCU since it's a peripheral provided by it. What appears on the MFD, though, is set by two bits output by the two poles of the OR/DR/µADDR Vector switch (decoded by a 74HC138 3-to-8 decoder—to provide sanity checking and indirectly deal with bounces and switch noise).

C3.3.3.8. Microcode Bank

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

These four lights represent bits 15—18 of the current Micro-Address vector, if the optional MBU is installed. Under most normal circumstances, these lights should be off.

C3.3.3.9. Instruction Register

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●

Sixteen lights display the current value of the Instruction Register (IR). Different colours indicate different fields of the instruction.

C3.3.3.10. Interrupt Requests and Enabled Interrupts

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

Sixteen lights in two rows display the state of each of the eight interrupt lines of the optional IRC. Enabled interrupts are shown on the top line, while requested interrupts are shown below.

C3.3.3.11. Spare Lights

●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
○○○●●●●●●●●●●●●●●●●●●●●●●●●●●●●

Sixteen lights in two rows are available for peripherals to attach to. Devices such as hard drives and network interfaces that display their state using LEDs may do so here. Future iterations of the front panel will assign values to at least some of these.

C3.3.4. Switches

There are 30 switches and two key locks on the front panel. Many switches perform two actions depending on whether they are pushed up or down.

The power lock controls the computer's power supply. It may be locked in the on or off position.

The panel lock controls access to the rest of the front panel. The panel may be open or locked out. When in the locked out position, most panel functions are unavailable. This is useful for displaying the computer, and for security.

The remaining 30 toggle switches are split into four groups: run control and panel settings, the Switch Register (SR), and programming functionality.

C3.3.4.1. Run Control

The Run Control and Panel Settings switch group is located on the bottom row of switches, below the Switch Register switches. It comprises three momentary action switches with six functions. Switches may be pushed up or down momentarily to activate their corresponding functions.

C3.3.4.1.1. The Reset/Start Switch

Actuated upwards (RESET), this switch resets the computer. If the computer is halted, it will go through the reset sequence and remain halted. When the switch is pushed downwards (START), the computer will reset and start running if stopped. (this combines the RUN and RESET functions)

C3.3.4.1.2. The Run/Stop Switch

Actuated upwards (RUN), this switch causes the computer to leave the Halt state and start executing code (Run state). If actuated downwards (STOP), the computer finishes executing the current instruction and stops, entering the Halt state.

C3.3.4.1.3. The µStep/Step Switch

This switch has no effect unless the computer is halted. Actuating it upwards (µSTEP) causes this computer to perform a single microstep. This is useful for diagnosing microcode issues. Pushing the switch downwards (STEP) causes the computer to step through one whole machine instruction. The processor will halt at the end of the instruction, so that the IRlights will display the instruction that just ran and the PC lights will show the address of the next instruction to execute.

C3.3.4.1.4. Fast/Slow/Creep

This switch has three positions controlling the CFT processor's clock speed. In FASTmode, the computer operates at the fastest available speed, typically 4 MHz. In SLOWmode, the computer operates at a speed that allows program execution to be inspected, typically 80 Hz (approximately ten instructions per second). In CREEP mode, the clock slows down to 8 Hz, so microprograms can be seen running.

C3.3.4.2. Panel Control

The Panel Control group configures the front panel.

C3.3.4.2.1. Lights On/Off

This switch has two positions. In the ON position, all panel lights are operational. In the OFF position, many of the panel lights are disabled to avoid visual clutter while the computer is running. The groups of lights that can be disabled are configurable using blocks of jumpers on the Front Panel Controller Board.

C3.3.4.2.2. OR/DR/µADDR Vector

This three-position switch controls what is displayed by the 16 Multi-Function Display (MDF) lights. In ORmode, the Front Panel's OR is shown. In DR mode, the DR is displayed. In µADDR mode, the Microcode Address is shown.

C3.3.4.3. The Switch Register

The Switch Register comprises sixteen switches. Together, they provide a 16-bit value used as input by the front-panel itself as well as the computer (sense switches, ready using the LSRextended instruction. Switches pushed up represent set bits (binary 1). Switches pushed down represent clear bits (binary 0).

C3.3.4.4. Programming Switches

The programming and state modification group is the rightmost group of switches. It comprises seven momentary action action switches and one on-on toggle switch.

C3.3.4.4.1. The SR → IR and SR → PC Switch

Pushed up, this switch copies the value of the SR to the IR. This modifies the instruction being executed. The computer must be halted. Obviously, changing the IR changes the microprogram being executed. It should, ideally, be done before the Execute state is reached, otherwise the microcode-level side-effects are difficult to gauge. This switch is most useful in debugging microcode issues.

Pushed down, the value of the Switch Register is copied to the PC. The computer must be halted for this. This switch is often used when programming or debugging via the front panel. It sets the address of all subsequent data entry (or examination) via the front panel.

Address Weirdness
For lack of available registers, modifying the PC is the way front panels often did it in the days of olde. The DFP's test interface (over the serial port) has a separate a register which allows examining and modifying memory without touch the computer's registers. That register isn't visible on the front panel lights, though, so modifying the PCwas the easy way. Why keep things too simple though? Actuating the SR→PC switch will also set the a register. This keeps the front panel and serial interface in sync, and interoperable. You can set an address via the switches, then dump memory via the serial interface.
C3.3.4.4.2. The SR → AC Switch

Activated either up or down, this switch copies the value of the SR to the AC. The computer must be halted for this.

C3.3.4.4.3. The Memory Write and Memory Write Next Switch

Pushed up, the current value of the SR is stored to the memory address indicated by the PC. Pushing the switch down performs the same task, but increments the PC afterwards. The computer must be halted for this. If this switch is kept down, it auto-repeats in three stages of increasing speeds. This allows large areas of memory to be filled quickly.

Pushed up, the value at the memory address indicated by the PC is read into the AC, and obviously displayed on the front panel. Pushing the switch down performs the same task, but increments the PC afterwards. The computer must be halted for this. If this switch is kept down, it auto-repeats in three stages of increasing speeds. This allows large areas of memory to be read and visualised quickly.

C3.3.4.4.5. The I/O Write and I/O Write Next Switch

Pushed up, the current value of the SR is output to the I/O space address indicated by the PC. Pushing the switch down performs the same task, but increments the PC afterwards. The computer must be halted for this. If this switch is kept down, it auto-repeats in three stages of increasing speeds. This allows large areas of I/O space to be filled with the same value quickly. Care should be taken when doing this, as it can have very unexpected effects.

C3.3.4.4.6. The I/O Read and I/O Write Next Switch

Pushed up, the value at the I/O space address indicated by the PC is read into the ACand displayed on the front panel. Pushing the switch down performs the same task, but increments the PC afterwards. The computer must be halted for this. If this switch is kept down, it auto-repeats in three stages of increasing speeds. This allows large areas of I/O space to be read and visualised quickly.

C3.3.4.4.7. RAM Bank/ROM Bank

This is a two position switch. In the RAM BNK position, the MBU's initial hard mapping provides 64 kWords of RAM and no ROM. When powered on, the computer will reset to the Halt state, allowing a program to be toggled in. In the ROM BNK position, the MBU's initial hard mapping provides 32 kWords of RAM and 32 kWords of ROM. The computer powers up in Run mode, allowing the boot code in ROM to be executed. This switch does nothing if the MBU's soft mapping has been enabled (the green MBEN light is on).

C3.3.4.4.8. IFR1/IFR6 Switch

If the optional IRC card is installed, this switch can signal Interrupts Level 1 and 6 to the computer. This may be used for debugging or asynchronous input. If the IRC card isn't present, a jumper on the DFP board makes IFR6 work with the CFT's single interrupt source. IFR1 won't work without the IRC card, though.

C3.3.5. Using the Front Panel

This section describes how to use and program the computer via the front panel.

C3.3.5.1. Power

Insert the power key in the power key switch. Turn the key clockwise to the ‘on’ position. The computer activates, performs power supply diagnostics (the DFP also performs its own power-on diagnostics at this point). The processor then goes through a reset cycle, and:

  • if the RAM BNK/ROM BNK switch is in the RAM BNK position, the processor halts. The STOP light should illuminate at this point, and the PC will indicate a binary address of 1111·1111·1111·0000, or FFF0.

  • if the RAM BNK/ROM BNK switch is in the ROM BNK position, the RUN light illuminates and the processor starts executing the boot code in ROM.

C3.3.5.2. The Panel Lock

When the panel lock is activated, access to the physical front panel is restricted. Only the SR, and IFR1, and IFR6 switches are operational. The panel may be locked using the physical front panel lock, or via the lock command on the DFP Console.

The physical and logical panel locks are in a mutual override relationship. Any change to either changes the state of the panel lock. So, if the panel has been locked via the DFP console and the key switch is in the unlocked position, it will be necessary to operate the key switch twice (move from unlock to lock, then back from lock to unlock) in order to unlock the panel.

C3.3.5.3. The Switch Register

The SR is made up of 16 switches, colour-coded in four groups of four (nybbles). A legend below the switches shows bit numbers (exponents), hexadecimal bit values (powers of two) and octal bit values (this could change to decimal prior to panel construction, which is slightly more useful on the CFT). A mnemonic of the 16 base instructions of the CFT is also provided.

Clear bits by pushing switches down. Set bits by pushing switches up. Simple enough.

The DFP monitors these switches for changes and sets the SR whenever a change to any of the switches occurs. This is done because the SR may also be set from the DFP Console (mutual override). If this has been done, to set the SR back to the value on the switches, it is necessary to toggle any switch twice.

C3.3.5.4. Boot or Reboot from ROM

With the computer powered up, move the RAM BNK/ROM BNK switch to the ROM BNK position and depress the RESET or START switch. The computer boots from ROM address FFF0 and begins execution.

You may now secure the front panel by turning the panel key switch to the LOCKED position.

Naturally, RESET and START also reset any peripheral on the CFT bus that acts on the RESET signal.

C3.3.5.5. Resetting the Computer

With the key switch in the UNLOCKED position, depress RESET or START. The computer resets. If the computer is halted, START will also set it running.

C3.3.5.6. Toggle in Boot Code

Ensure the computer is freshly powered up and halted, or halted and reset.

Set the SR for a low value such as 0000·0100·0000·0000 or 0400. (one kWord from start of memory). Depress SR→PC. The PC will change to the address selected on the SR.

Set the SR to the opcode of the first instruction of bootstrap code. Depress MEM W NEXT. The value of the SR is written to the memory address of the PC, and that memory address is incremented. Repeat this step as required until all code has been entered.

Reset the SR to the initial address of the bootstrap program. Depress SR→PC. The PC will be set to that address.

Depress RUN. The computer starts execution of the code from the specified address.

You may now secure the front panel by turning the panel key switch to the LOCKED position.

C3.3.5.7. Examining Memory

Ensure the computer is powered up and halted.

Set the SR to the start of the memory area you need to examine. Depress SR→PC. The PC will change to the address selected on the Switch Register.

Depress the MEM R NEXT switch. The value at the selected memory address is loaded into the AC and displayed on the front panel. The memory address is incremented. Repeat this step as many times as necessary.

C3.3.5.8. Halting the Computer Forcibly

With the key switch in the UNLOCKED position, depress STOP. The computer finishes its current instruction and halts. The RUN light will extinguish, and the STOP light should turn on.

C3.3.5.9. Debugging with the Front Panel

The front panel may be used to interrupt normal computer operation and inspect or modify its state for debugging purposes. The computer can then resume operation. The user should, however, be aware of a number of considerations when using the front panel to do this:

  • Operating the STOP switch halts the computer immediately after the next instruction is fetched, and before its execution starts. At this point, the µSTEP or STEP switches may be operated repeatedly.

  • Using the SR→PC switch to set the address for examining or modifying code also modifies the PC. When the computer resumes operation, and after execution of the current instruction, the processor will jump to the address set via the front panel. If this is not desired, the user must note the value of the PC and manually restore it before continuing.

  • Using the memory and I/O functions also cause the MAR to change. This is safe to do when using the STEP switch, but be aware of it while debugging microprograms!

  • Obviously, modifying the IR, memory, or I/O devices can have unexpected side effects and can cause the program to fail when it's resumed. The front panel is powerful, but can be too powerful if not used wisely!

C3.4. The Debugging System

The DFP allows a remote computer to automatically and programmatically control the CFT for debugging and testing purposes, effectively providing a virtual front panel. This interface may also be operated by a human. It allows facilities more advanced than the front panel's and is an integral part of constructing the CFT, as it allows for automated unit testing and detailed diagnostics.

C3.4.1. Attaching a Computer or Terminal

The MCU connects to the controlling device via a TTL, non-inverted serial port terminating at a 6-pin header. The header fits the plug of an FTDI USB-to-serial cable, but can also be used with an external FTDI USB-to-serial module. A plain RS-232 connection is possible, but the DFP firmware would have to be recompiled with bit rate low enough to work with RS-232 connections.

The serial parameters are 460,800 bps, 8 data bits, 1 stop bit, no parity, and no software or hardware flow control.

C3.4.2. The Two Consoles of the DFP

The serial connection provides access to two multiplexed terminals.

The DFP Console allows testing and interaction with the virtual front panel, as well as debugging facilities. It lets a human or controlling computer operate the front panel over a serial link. (Virtual Front Panel)

The Virtual Console provides a simple but functional terminal for the CFT computer to use to interact with the user. This is the first user interface device provided by the CFT, followed by the TTY card (two or four RS-232 serial ports) and the VDU card (video output and keyboard input).

The user normally interacts with the DFP Console, but can activate the Virtual Console at will with the cons command. With the virtual console activated, the user is interacting with whatever program is running on the computer. An escape character sequence returns to the DFP Console.

This is similar in spirit to operating a Hayes-style Smart Modem using AT commands, or using a lights-out remote server management system on 21st century server hardware.

C3.4.3. Interacting with the DFP Console

The DFP firmware presents an interactive user interface intended for both humans and machines, in the style of the SMTP, FTP and HTTP protocols. The user enters short commands, optionally followed by one or more arguments, and the board responds with a three digit response code and a human-readable message. A human usually ignores the response code; a machine usually ignores the textual message.

On boot up, the DFP will display a sequence of diagnostic and informational messages like this:

101 Processor: found
201 Version: 1.2 2016-06-10+dis
102 VP Shift Reg chain: OK
103 DEB Shift Reg chain: OK
104 ABUS driver: OK
105 ABUS tristate: OK
106 DBUS driver: OK
107 DBUS tristate: OK
108 Bus quiet during reset: OK
109 AC: OK
110 PC: OK
111 IR: OK
201 Version: 1.2 2016-06-10+dis
202 (c) 2012-2016 Alexios Chouchoulas 
202 Licensed under the GNU Public License v.2.
202 http://www.bedroomlan.org/cft
202 All values base 16 unless otherwise noted.
204 BufSize: 200
205 Processor found.
[running]> 

The bottom line is a prompt.

A rudimentary line editor is provided:

Backspace, DEL or Ctrl-H
delete the last character in the current command.
Ctrl-C or Ctrl-X
abort the current command, and may also be used to abort a long-running process.
Enter, Return, Ctrl-J, or Ctrl-M
submit the current command for processing.
Ctrl-N or Ctrl-P
repeat the last entered command. Due to memory limitations on the DFP controller, the keys must be the very first character received on a new line for this to work.
Ctrl-T
toggles terminal mode. When on, terminal directives for colour output are used, and the output generally looks a little nicer. This is better for humans on modern terminals, but not ideal for other computers.
Ctrl-L
reprints the prompt and the current command to fix cases where the output may be mangled by serial communication issues.

Help may be obtained by using the ? or help commands, which print out something like this:

[halted] c021> help
201 Available commands:
201     ? -- Show help
201     help -- Show help
201     ver -- Show version
201     buf -- Show size of command buffer
201     term [ BOOL ] -- Get/set terminal bells & whistles.
201     echo [ BOOL ] -- Get/set local echo.
201     mesg [ BOOL ] -- Get/set async messages.
201     s -- Current CFT/DEB status
201     us -- Microcode control state
201     sws -- Show Switch state
201     abus -- Read Address bus
201     dbus -- Read Data bus
201     swtest -- Test switch assembly and OR
201     dfps -- Show DFP state
201     cons -- Virtual console ( # . to exit).
201     lock [ BOOL ] -- Get/set software switch lock.
201
201     reset [ BOOL ] -- Reset (if TRUE, cold boot)
201     start -- Reset & run
201     stop -- Stop
201     halt -- Stop (same as stop, for versatility)
201     run -- Run
201     step [ N ] -- Step to next fetch (default: 1)
201     ustep [ N ] -- Microstep the CPU (default: 1)
201     trace -- Status trace
201     utrace -- Microcode status trace
201     bp [ NUM [ off | ADDR ] ] -- Set breakpoint (see docs)
201     hof [ BOOL ] -- Get/set halt on FAIL
201     hos [ BOOL ] -- Get/set halt on SENTINEL
201     fast -- CPU at full speed
201     slow -- CPU at slow speed
201     creep -- CPU at creep speed
201     clk PS DIV -- Arbitrary clock speed (see docs).
201
201     ir [ WORD ] -- Get/set IR
201     pc [ WORD ] -- Get/set PC
201     ac [ WORD ] -- Get/set AC.
201
201     a [ WORD ] -- Get/set address
201     r -- Read mem[a++]
201     d [ C ] -- Dump C words (default: 80)
201     dis [ C ] -- Disassemble C words (default: 10)
201     db [ C ] -- Binary dump C words (default: 80)
201     w WORD [ WORD... ] -- Write c words to mem[a++]
201     fill COUNT VALUE -- Fill memory
201     in ADDR -- Read I/O address ADDR
201     out ADDR WORD -- Write WORD to I/O addr ADDR.
201
201     i1 -- Signal IRQ1
201     i6 -- Signal IRQ6
201     sr -- Read front panel switches
201     or [ WORD ] -- Get/set OR lights
201 
201 Ctrl-C Ignore command line, stop output, abort command.
201 Ctrl-X Ignore command line.
201 Ctrl-T Toggle terminal mode.
201 Consult documentation for more details.
[halted] c021> 

The prompt takes two forms. When the computer is running:

[running]> 

When the computer is halted, the prompt changes to display this fact and the current address where data is entered.

[halted] 826c> 

For the benefit of humans, the firmware makes use of colours using a tiny subset of ANSI X3.64 terminal directive. User input is shown in yellow; asynchronous messages are in purple. Flags turned on are in green. Flags turned off are in red. Some important bits of information are displayed in white, or bold. Errors are in red.

C3.4.4. Hardware Diagnostics

When first started up (or when cold reset via the reset y command), the DFP will go through a series of hardware diagnostics to verify its own health, the health of its interface to the CFT hardware, and the CFT hardware itself. During these diagnostics, the DFP Console prints out diagnostic messages, and the OR lights reflect the same information. For a test code like 103, the lights will display 0103 or 0000·0001·0000·0011. The following diagnostics are currently performed:

101:
Processor presence test.
102:
Virtual Front Panel shift chain test. This ensures the virtual front panel inputs are operating properly and shifting data correctly to the microcontroller at the fastest possible rate.
103:
Debugging shift chain test. This ensures the debugging inputs are operating properly and shifting data correctly to the microcontroller at the maximum possible rate.
104:
Address Bus Driver tests. This ensures the DFP can drive the address bus correctly. The test outputs a number of bit patterns to the address bus and ensures they are read back correctly.
105:
Address Bus tri-state tests. This ensures the DFP can release the address bus and let it float correctly.
106:
Data Bus Driver tests. This ensures the DFP can drive the data bus correctly. The test outputs a number of bit patterns to the data bus and ensures they are read back correctly.
107:
Data Bus tri-state tests. This ensures the DFP can release the data bus and let it float correctly.
108:
Bus quiet during reset. Ensures there is no bus traffic while reset is being asserted.
109:
AC tests. Ensures the AC can be written to correctly, and the same values written can be read back.
110:
PC tests. Ensures the PC can be written to correctly, and the same values written can be read back.
111:
IR tests. Ensures the IR can be written to correctly, and the same values written can be read back.

C3.4.5. When Hardware Diagnostics Fail

If any of the DFP diagnostics fail, the DFP freezes, does not allow the computer to start, and blinks the STOP light slowly. Eight seconds later, it performs a cold reset and reruns the diagnostics. This is to account for cases where a diagnostic terminal has been connected halfway through the process.

On failure, the OR will display the code of the test that failed:

0101:
the processor was not found. The DFP firmware was originally coded to run without a processor necessarily present, but this is becoming far less useful as the project goes on and a missing processor is now a fault.
0102:
The Virtual Front Panel shift chain test failed. Bits are not propagating correctly along the chain. The shift registers may be improperly connected, faulty, or incapable of supporting the data rate of the DFP microcontroller. There may be excessive noise in the area.
0103:
The Debugging shift chain test failed. Bits are not propagating correctly along the chain. The shift registers may be improperly connected, faulty, or incapable of supporting the data rate of the DFP microcontroller. There may be excessive noise in the area.
0104:
The DFP was unable to drive the address bus, write values to it, and/or read them back correctly. Mismatches between expected and seen values will be shown on the DFP Console.
0105:
The DFP was unable to tri-state the address bus, the address bus hold circuitry is missing, or is faulty. There may be excessive noise in the area.
0106:
The DFP was unable to drive the data bus, write values to it, and/or read them back correctly. Mismatches between expected and seen values will be shown on the DFP Console.
0107:
The DFP was unable to tri-state the data bus, the address bus hold circuitry is missing, or is faulty. There may be excessive noise in the area.
0108:
Bus chatter was detected during a reset. The processor's reset circuitry may be broken, a peripheral may be misbehaving, or there is excessive noise in the environment. Bus hold circuitry may be malfunctioning.
0109:
The AC is malfunctioning. Values were unable to be written, written incorrectly, read back incorrectly or not read back at all. Value mismatches will be printed out to the DFP Console.
0110:
The PC is malfunctioning. Values were unable to be written, written incorrectly, read back incorrectly or not read back at all. Value mismatches will be printed out to the DFP Console.
0111:
The IR is malfunctioning. Values were unable to be written, written incorrectly, read back incorrectly or not read back at all. Value mismatches will be printed out to the DFP Console.

C3.4.6. Computer Mode

When operated by a computer, it is useful to disable features needed mostly by humans. A hidden ‘computer mode’ is provided for this purpose. Sending ASCII code 30 to the DFP Console enters this mode, disabling echo and terminal mode:

[running]> ***
312 Terminal: off
310 Echo: off
299 T0sgQ09NUFVURVI=
[running]> █

To disable computer mode, type (the first line in the blind):

[running]> echo on
310 Echo: on
[running]> term on
312 Terminal: on
[running]> 

C3.4.7. Asynchronous Messages

The DFP is asynchronous by nature. Whenever switches are operated or the DFP issues an instruction to it, the DFP Console reacts by printing out an appropriate message asynchronously, then repeating the prompt and as much of the input line as the user has entered. This can be annoying when simultaneously entering commands on the DFP Console as it interrupts typing. To mitigate the problem partially in terminal mode, the input line remains at the bottom of the screen and asynchronous messages scroll up from Asynchronous messages are displayed in magenta (with terminal mode activated):

[halted] ff84> start
306 Host reset
304 Host running
[running]> 345 SUCCESS
[running]> 340 PRINTH 0000
[running]> 340 PRINTH 0000
[running]> 340 PRINTc 10
[running]> 305 Host halted
[halted] c021> 

With terminal mode off, the line is interrupted by three asterisks *** and asynchronous messages always start at the beginning of the line to simplify parsing:

[halted] ff84> start
306 Host reset
304 Host running
[running]> ***
345 SUCCESS
[running]> ***
340 PRINTH 0000
[running]> ***
340 PRINTH 0000
[running]> ***
340 PRINTc 10
[running]> ***
305 Host halted
[halted] c021> █

Asynchronous messages can be disabled using the mesg n command:

[halted] c021> mesg no
311 Async messages: off
[halted] c021> 

C3.4.8. How the DFP Console Reacts to Front Panel Activity

When most of the front panel switches are operated, the DFP logs an appropriate message to the DFP console. This message is often the exact same message shown when the corresponding commands are issued via the DFP console. The only way to distinguish front panel operations from virtual front panel operations is thus the asynchronous nature of the message: if a message about a change to the SR is received, and no change to the SR has been requested, then this is a result of a front-panel operation. During testing, it is beneficial for the panel to be locked to avoid test failures due to this. The automated test framework locks the front panel during testing.

C3.4.8.1. Using the Run Control Switches

Operating these switches will log appropriate messages to the DFP Console. When the STOP switch is actuated:

[running]> 305 Host halted

When the RUN switch is actuated:

[halted] e010> 304 Host running

When the RESET switch is actuated:

[halted] 0182> 306 Host reset

When the START switch is actuated:

[halted] 0182> 306 Host reset
[halted] 0182> 304 Host running

When stepping and microstepping, a detailed dump of the computer's state is printed. The STEP switch prints out the PC, AC and IR and disassembles the IR. The µSTEP switch additionally prints out the micro-instruction control vector and decodes that. In the example below, the computer steps through an ISZ instructions, and then micro-steps the last step of fetching the next instruction (a LOAD) and executing that.

[halted] e00d> 323 Step. n---- PC:e00d AC:e000 IR:e000 ISZ     &000
[halted] e00d> 324 Microstep. n---- PC:e00e AC:93cf IR:ebbe ISZ I   &3be 001100000000000001000000 IR <- mem[ar]
[halted] e00e> 324 Microstep. n---- PC:e010 AC:93cf IR:203c LOAD    &03c 000000000000000000100010 AR <- AGL
[halted] e010> 324 Microstep. n---- PC:e010 AC:93cf IR:203c LOAD    &03c 001100000000000001100000 AC <- mem[ar]
[halted] e010> 324 Microstep. -z--- PC:e010 AC:0000 IR:203c LOAD    &03c 100000000000000000000000 END

Changing the clock speed will issue one of these messages:

[halted] e010> 327 Full speed clock.
[halted] e010> 328 Slow clock.
[halted] e010> 329 Very slow clock.

C3.4.8.2. The Panel Lock Key Switch

When the panel lock key switch is operated, the panel lock is enabled or disabled, and one of the following messages appear:

[running]> 374 Panel lock: on
[running]> 374 Panel lock: off

C3.4.8.3. Changes to the Switch Register

The entire SR is output as an asynchronous message whenever any of its switches are operated. The SR is displayed in hexadecimal, decimal, and as an Assembly instruction (if disassembly is included in this firmware).

[running]> 220 Switch Register: 0000000000000001    0001    1       TRAP      &001
[running]> 220 Switch Register: 0000000000000011    0003    3       TRAP      &003
[running]> 220 Switch Register: 0000000000000111    0007    7       TRAP      &007
[running]> 220 Switch Register: 0000000000001111    000f    15      TRAP      &00f
[running]> 220 Switch Register: 0000000001001111    004f    79      TRAP      &04f
[running]> 220 Switch Register: 0000000001101111    006f    111     TRAP      &06f
[running]> 220 Switch Register: 0010000001101111    206f    8303    LOAD      &06f
[running]> 220 Switch Register: 0110000001101111    606f    24687   JMP       &06f
[running]> 220 Switch Register: 0110100001101111    686f    26735   JMP I     &06f
[running]> 220 Switch Register: 0110110001101111    6c6f    27759   JMP I R   &06f

C3.4.8.4. Using the Programming Switches

The effects of some of the programming switches may be slightly counter-intuitive, but show their side effects much more clearly. When the SR→PC, SR→IR and SR→AC switches are operated, obvious messages are logged: (here, the SR is set to e000)

[halted] 0000> 354 PC: e000
[halted] e000> 355 IR: e000
[halted] e000> 353 AC: e000

The examine/deposit switches show their side effects in detail. The only way to distinguish between the plain and NEXT variants (automatic address advance) of the operations is the fact that the address in the prompt steps after each switch operation. For example, the log below starts with three presses of the MEM W NEXT switch, followed by a single press of the MEM W switch (where the e004 address does not increment after the switch press).

[halted] e000> 370 Write mem[e000] <- e000
[halted] e001> 370 Write mem[e001] <- e000
[halted] e002> 370 Write mem[e002] <- e000
[halted] e003> 370 Write mem[e003] <- e000
[halted] e004> 370 Write mem[e004] <- e000
[halted] e004> 371 Read mem[e004] -> 0123
[halted] e005> 371 Read mem[e005] -> ffed
[halted] e006> 371 Read mem[e006] -> 76d3
[halted] e007> 371 Read mem[e007] -> ffff
[halted] e007> 372 Write I/O[e007] <- e000
[halted] e008> 372 Write I/O[e008] <- e000
[halted] e009> 372 Write I/O[e009] <- e000
[halted] e00a> 372 Write I/O[e00a] <- e000
[halted] e00a> 373 Read I/O[e00a] -> e000
[halted] e00b> 373 Read I/O[e00b] -> e000
[halted] e00c> 373 Read I/O[e00c] -> e000
[halted] e00d> 373 Read I/O[e00d] -> e000

When the RAM/ROM switch changes state, the following is logged:

[halted] e00d> 333 ROM/RAM# switch: RAM
[halted] e00d> 333 ROM/RAM# switch: ROM

When the IFR1 and IFR6 switches are operated, the following messages appear.

[halted] e00d> 358 IRQ1 signaled
[halted] e00d> 359 IRQ6 signaled

If the CFT has not enabled the IFR1 and/or IFR6 interrupts, the messages are different:

[halted] e00d> 458 IRQ1 masked by CFT
[halted] e00d> 459 IRQ6 masked by CFT

C3.4.9. DFP Console Command Reference

C3.4.9.1. ver — Display Version

Displays the current version of the DFP firmware.

[halted] c021> ver
201 Version: 1.2 2016-05-21+dis

C3.4.9.2. buf — Display Buffer Size

Displays the size of the command buffer in hexadecimal. The buffer size dictates the maximum size of a DFP command, and indirectly the speed of automated program entry, since the write to memory (w) command is one of the few that can become very long.

[halted] c021> buf
204 BufSize: 200

C3.4.9.3. term — Get or Set Terminal Mode

The term command shows whether or not terminal mode is enabled, and can enable or disable it. Without an argument, it simply shows the current state:

[halted] c021> term
212 Terminal: on

With an appropriate argument, it controls terminal mode.

[halted] c021> term off
312 Terminal: off
[halted] c021> term on
312 Terminal: on

C3.4.9.4. echo — Get or Set Echo

The echo command displays the state of echo, and can also control it. When echo is on, characters sent to the DFP by a terminal are also output back to the terminal. This works well on terminals without local echo (the majority) but is undesirable when a testing computer operates the DFP automatically.

[halted] c021> echo
210 Echo: on
[halted] c021> echo off
310 Echo: off
[halted] c021> 310 Echo: on

C3.4.9.5. mesg — Get or Set Asynchronous Message Delivery

The mesg command displays and controls the delivery of asynchronous messages. Without an argument, the current state is displayed. With an argument, the state is changed appropriately.

[halted] c021> mesg
211 Async messages: on
[halted] c021> mesg yes
311 Async messages: on
[halted] c021> mesg no
311 Async messages: off
[halted] c021> mesg on
311 Async messages: on
[halted] c021> mesg off
311 Async messages: off

C3.4.9.6. s — Get CFT Status

This command shows the current state the CFT processor. Shown are processor flags and the values of the PC, AC and IR. The latter is also disassembled into a symbolic instruction, if disassembly is available.

[halted] c021> s
250 Machine state: -z--l PC:c021 AC:0000 IR:6021 JMP       &021

C3.4.9.7. us — Display Microcode Control State

This command reads and displays the current microcode 24-bit control vector in binary form. If disassembly is available, it also decodes it into a human readable string. Please note that this shows the same vector as that displayed on the top row of the front panel, so active-low signals are inverted (‘1’ signifies asserted signals).

[halted] c021> us
252 Microcode control: 000000000000000000100011 AR <- PC

C3.4.9.8. sws — Show Front Panel Switches

Displays, in binary, the current state of all switches on the front panel.

[halted] c021> sws
251 Switch state: 00000000 1001100111100011 001000000000 0000 00000000 

Five fields are displayed:

  1. The state of the left switch group.
  2. The Switch Register.
  3. The state of the right switch group.
  4. The state of the four bit DIP switches.
  5. The state of the eight bit DIP switches.

The left switches are encoded as follows:

76543210
SPEEDµSTEPSTEPRUNSTOPRESETLOCK

A set bit indicates an activated switch. SPEED encodes the three speeds as follows:

SPEEDMeaning
10Full clock speed.
11Slow clock speed.
01Creep clock speed.
00Should never happen!

The switch register is displayed in the second field, in the conventional binary form with the most significant to the left. 1 indicates a switch is up or on.

The third field shows the state of the right hand switches.

11109876543210
IFR1IFR6ROMPROGSR→ACSR→IRSR→PC

A set bit indicates an activated switch. PROG encodes the programming switches. When decoding these switches, the firmware ignores all patterns not listed below. This provides software interlock and prioritisation. If multiple switches are operated simultaneously, the action will be ignored. For example, if both the Memory Deposit and I/O Write Next switches are activated, the pattern would be 01011, and nothing would happen.

PROGMeaning
00001Memory Deposit switch operated.
00011Memory Deposit Next switch operated.
00100Memory Examine switch operated.
00101Memory Examine Next switch operated.
01000I/O Write switch operated.
01001I/O Write Next switch operated.
10000I/O Read switch operated.
10001I/O Read Next switch operated.
All othersShould never happen!

The fourth and fifth fields are simply the state of the 12 DIP switches.

C3.4.9.9. swtest — Test front panel switches

Helps the user perform a test of most switches on the front panel. This command allows all switches to be operated with impunity, with no changes made to the computer. It shows all changes to switch states, using the same output as the sws command.

To test the switches, every change to a switch must log a line on the DFP console, and not changing any switches must not log any lines. Use the sws command reference above to ensure the correct bits are changed.

When done, press Ctrl-C to terminate the command.

[halted] c021> swtest
334 Operate toggles/DIP switches. Ctrl-C ends.
251 Switch state: 00000000 0000000000000000 001000000000 0000 00000000 
251 Switch state: 00000000 0000000000000001 001000000000 0000 00000000 
251 Switch state: 00000000 0000000000000011 001000000000 0000 00000000 
251 Switch state: 00000000 0000000000000111 001000000000 0000 00000000 
251 Switch state: 00000000 0001000000000111 001000000000 0000 00000000 
251 Switch state: 00000000 0011000000000111 001000000000 0000 00000000 
251 Switch state: 00000000 0111000000000111 001000000000 0000 00000000 
251 Switch state: 00000000 1111000000000111 001000000000 0000 00000000 
251 Switch state: 00000000 0111000000000111 001000000000 0000 00000000 
251 Switch state: 00000000 0011000000000111 001000000000 0000 00000000 
301 Done
[halted] c021> 

C3.4.9.10. abus — Read the Address Bus

This command reads the current value of the Address Bus and prints it out. The computer must be halted. Both CFT and DFP drive the Address Bus only when performing memory cycles, so the value read will either be the value currently being driven, or the last value written (since the CFT has bus hold circuitry).

[halted] c021> abus
260 ABUS: c021

C3.4.9.11. dbus — Read the Data Bus

This command reads the current value of the Data Bus and prints it out. The computer must be halted. Since the Data Bus is only driven part of the time, the value read here may be the last value read from the Data Bus (a result of bus hold circuitry), and not a current value. There is no way to determine whether a circuit is driving the Data Bus.

[halted] c021> dbus
261 DBUS: 0000

C3.4.9.12. dfps — Show DFP State

[halted] c021> dfps
201 Version: 1.2 2016-05-21+dis
204 BufSize: 200
205 Processor found.
212 Terminal: on
210 Echo: on
211 Async messages: off
215 Front panel lock: off
213 On FAIL: off
214 On SENTINEL: off
203 Address: c021
221 Output Register: 0000
220 Switch Register: 0011000000000111    3007    12295   STORE     &007
260 ABUS: c021
261 DBUS: 0000
251 Switch state: 00000000 0011000000000111 001000000000 0000 00000000 
[halted] c021> 

C3.4.9.13. cons — Enter Virtual Console

This command switches from the DFP Console to the CFT Virtual Console, an emulated serial port that allows the computer to be interacted with before a serial board is built for it. To escape back from the Virtual Console to the DFP Console, press Enter followed by #..

[running]> cons
331 Virtual console (press Enter # . to exit).
... interacting with the CFT ...
#.
332 Left virtual console.
[running]> 
An improvement
The cons command needs an optional argument that starts the console and sets the computer running at the same time. This is useful for testing, and an easy way to perform a common task. It should also issue a warning if the computer is halted and the console is started without this argument (but start the console anyway—the operator might want to use the front panel switches instead).
A necessary fix
When the DFP Console is active, characters written to the CFT Virtual Console are reported as asynchronous messages. This should probably not happen. To fix it, the dfp.TX I/O address must be made separate from the PRINTC one, and the part of the Firmware that handles dfp.TX needs to change to handle this special case.

C3.4.9.14. lock — Panel Lock

This command sets or clears the panel lock, overriding the state of the physical switch. The physical switch can, in turn, override this one if operated. With the lock activated, only the SRand IFR switches are operable. All others are locked out. The logical lock is useful (among other things) for locking the front panel out while running sensitive tests on the processor.

[halted] c021> lock
215 Front panel lock: off
[halted] c021> lock on
315 Front panel lock: on
[halted] c021> lock off
315 Front panel lock: off
[halted] c021> 

C3.4.9.15. reset — Reset the computer

This command resets the computer. If the computer is running, it will immediately start executing at address FFF8. If the computer is halted, it will simply perform a reset. This will also reset any peripherals on the bus that act on the RESET signal.

[halted] c021> reset
306 Host reset

Another function of the reset command is to carry out a cold reset of the DFP. This will revert the DFP to its power-on state. It will also reset the processor and all peripherals, and go through all DFP diagnostics. To perform a cold reset, execute reset cold.

Any ‘true’ argument will cause a cold reset, i.e. anything but 0 or no, noor off.
200 Ready
[halted] c021> reset cold
307 Cold reset

101 Processor: found
201 Version: 1.2 2016-06-10+dis
102 VP Shift Reg chain: OK
103 DEB Shift Reg chain: OK
104 ABUS driver: OK
105 ABUS tristate: OK
106 DBUS driver: OK
107 DBUS tristate: OK
108 Bus quiet during reset: OK
109 AC: OK
110 PC: OK
111 IR: OK
201 Version: 1.2 2016-06-10+dis
202 (c) 2012-2016 Alexios Chouchoulas 
202 Licensed under the GNU Public License v.2.
202 http://www.bedroomlan.org/cft
202 All values base 16 unless otherwise noted.
204 BufSize: 200
205 Processor found.
[running]> 

C3.4.9.16. start — Start the computer

This command resets the computer and starts its clock. The processor will immediately start executing at address FFF8. Any peripherals on the bus that act on the RESETsignal will also be reset.

[halted] 826d> start
306 Host reset
304 Host running

C3.4.9.17. stop or halt — Stop the computer

This command waits until the computer has completed its current instruction, then halts the clock. The exact microstep when the clock is stopped is configurable, but is usually set to the last step of the Fetch state.

[running]> halt
305 Host halted

C3.4.9.18. run — Continue Execution

This command re-enables the clock and resumes execution.

[halted] e348> start
[running]> halt
305 Host halted
304 Host running

C3.4.9.19. step — Single-stepping

With the computer halted, this instruction will single-step once and print out the computer's state. An optional hexadecimal number can be provided to perform multiple single steps.

Multiple microsteps can be aborted using Ctrl-C, operating the STOP switch on the front panel, or if an extended instruction halts the processor (this includes HALT and FAIL when Halt-on-Fail is enabled).

[running]> step
503 Halt host first
[running]> halt
305 Host halted
[halted] 826c> step 5
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
301 Done
[halted] 826c> step
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
[halted] 826c> step
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
[halted] 826c> run
304 Host running
Tip
When single-stepping, pressing Ctrl-N re-runs the previous command and saves typing the whole step command anew.
Tip
A long sequence of steps can always be stopped early using Ctrl-C.

C3.4.9.20. ustep — Microstepping

This command works much like the step command, but it performs microsteps instead. The output of each step includes the computer's state plus the microcode control vector in binary and symbolic form.

Multiple microsteps can be aborted using Ctrl-C, operating the STOP switch on the front panel, or if an extended instruction halts the processor (this includes HALT and FAIL when Halt-on-Fail is enabled).

[running]> ustep 5
503 Halt host first
[running]> halt
305 Host halted
[halted] 826c> ustep 5
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP &26c  000000000000000000100011 AR <- PC  
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP &26c  000000000000000000100011 AR <- PC  
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP &26c  000000000000000000100011 AR <- PC  
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP &26c  000000000000000000100011 AR <- PC  
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP &26c  000000000000000000100011 AR <- PC  
301 Done
[halted] 826c> ustep
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP &26c  000000000000000000100011 AR <- PC  
[halted] 826c> ustep
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP &26c  000000000000000000100011 AR <- PC  
[halted] 826c> run
304 Host running
Tip
A long sequence of steps can always be stopped early using Ctrl-C.
todo
The strange behaviour of the example above is due to a microstepping bug in the emulated DFP. Microstepping normally steps through instructions, and doesn't repeat the same microinstruction endlessly.

C3.4.9.21. trace — Trace code execution

The trace command simply runs the step command continuously. The endless sequence of steps can be aborted using Ctrl-C or operating the STOP switch on the front panel. It will also stop if an extended instruction halts the processor (this includes HALT and FAIL when Halt-on-Fail is enabled). It will also stop if a breakpoint is encountered.

[halted] 826c> trace
325 Tracing.
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
323 Step. ----- PC:826c AC:0000 IR:626c JMP       &26c
302 Aborted
Yes, yes, I know it's a bad example
JMP to the current address, so the PC will never change anyway. I'm not sure why I collected this particular example. I'll eventually get a better one.

C3.4.9.22. utrace — Trace microcode execution

The utrace command simply runs the ustep command continuously. The endless sequence of micro-steps can be aborted using Ctrl-C or operating the STOP switch on the front panel. It will also stop if an extended instruction halts the processor (this includes HALT and FAIL when Halt-on-Fail is enabled), or if a breakpoint is encountered.

[halted] 826c> utrace
326 Microtracing.
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP       &26c  000000000000000000100011 AR <- PC  
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP       &26c  000000000000000000100011 AR <- PC  
324 Microstep. ----- PC:826c AC:0000 IR:626c JMP       &26c  000000000000000000100011 AR <- PC  
302 Aborted
[halted] 826c> 
To Do
The strange behaviour of the example above is due to a microstepping bug in the emulated DFP. Microstepping normally steps through instructions, and doesn't repeat the same microinstruction endlessly.

C3.4.9.23. bp — Breakpoint Facility

Due to the way the DFP is designed, the breakpoint facility can only work when the DFP can inspect the computer's state between instructions, and this is only the case with the step, ustep, trace and utrace commands. When the computer runs normally, breakpoints will not be honoured.

The DFP supports up to eight breakpoints. These can be either off, or set to any 16-bit address, which implies that they are somewhat limited if the MBU is installed, enabled and memory banks switch.

To list breakpoints, issue the bp command without any arguments.

[halted] 826c> bp
259 Breakpoint 0: off
259 Breakpoint 1: off
259 Breakpoint 2: off
259 Breakpoint 3: off
259 Breakpoint 4: off
259 Breakpoint 5: off
259 Breakpoint 6: off
259 Breakpoint 7: off

To set a breakpoint, use the bp command with two arguments: a breakpoint number in the range 0–7 and a hexadecimal address.

[halted] 826c> bp 0 c000
259 Breakpoint 0: c000
[halted] 826c> bp 1 c500
259 Breakpoint 1: c500

To examine specific breakpoints, use a single argument denoting the breakpoint number.

[halted] 826c> bp 0
259 Breakpoint 0: c000
[halted] 826c> bp 2
259 Breakpoint 2: off

To disable a breakpoint, use off as its address:

[halted] 826c> bp 0 c000
259 Breakpoint 0: c000
[halted] 826c> bp 0 off
259 Breakpoint 0: off
[halted] 826c> bp
259 Breakpoint 0: off
259 Breakpoint 1: c500
259 Breakpoint 2: off
259 Breakpoint 3: off
259 Breakpoint 4: off
259 Breakpoint 5: off
259 Breakpoint 6: off
259 Breakpoint 7: off
To Do
Show trace or step execution with breakpoints set.

C3.4.9.24. hof — Halt on FAIL

This command inspects or sets the Halt-on-Fail setting. When Halt-on-Fail is on, executing a FAIL instruction will also halt the computer. A suitable failure message is always printed on the DFP and Virtual Consoles regardless of the state of this setting. The setting may also be modified programmatically using the ENEF or DISEF extended instructions.

[running]> hof
213 On FAIL: off
[running]> hof on
313 On FAIL: on
[running]> hof off
313 On FAIL: off
[running]> 

C3.4.9.25. hos — Halt on SENTINEL

This command inspects or sets the Halt-on-Sentinel setting. When Halt-on-Sentinel is on, executing a SENTINEL instruction will also halt the computer. A suitable message is always printed on the DFP and Virtual Consoles regardless of the state of this setting. The setting may also be modified programmatically using the ENEF or DISEF extended instructions.

[running]> hos
214 On SENTINEL: off
[running]> hos on
314 On SENTINEL: on
[running]> hos off
314 On SENTINEL: off
[running]> 

C3.4.9.26. fast — Full Clock Speed

This command disables the DFP's clock generator and enables the processor's. The processor will operate at its full speed. The setting of the speed switch on the front panel will be overridden until the switch is operated again.

[running]> fast
327 Full speed clock.
[running]> 

C3.4.9.27. slow — Slow Clock Speed

This command disables the processor's clock generator and enables the DFP's. The DFP will direct the processor using a slow clock, which allows instruction execution to be seen on the front panel. The setting of the speed switch on the front panel will be overridden until the switch is operated again.

[running]> slow
328 Slow clock.
[running]> 

C3.4.9.28. creep — Very Slow Clock Speed

This command disables the processor's clock generator and enables the DFP's. The DFP will direct the processor using a very slow clock, which allows micro-instruction execution to be seen on the front panel (also instruction execution, if one is inhumanly patient, drugged up, or an Ent). The setting of the speed switch on the front panel will be overridden until the switch is operated again.

[running]> creep
329 Very slow clock.
[running]> 
What the Hell am I Doing Here?
Should I change message 329 to 329 Weirdo? I think I should.

C3.4.9.29. clk — Custom Clock Speed

This command disables the processor's clock generator and enables the DFP's using a custom clock rate. The setting of the speed switch on the front panel will be overridden until the switch is operated again.

The clock rate is specified in the form of two parameters: a prescaler 1 ≤ psn ≤ 5, and a 16-bit divisor 0 ≤ div ≤ 65535 (specified, as always, in hexadecimal). These directly drive the MCU's pulse-width modulator, generating a frequency of:

$$ \begin{eqnarray}% && \frac{14.7456~\mbox{MHz}}{\mbox{prescaler} (1 + \mbox{div})}\nonumber \end{eqnarray} $$

The psn parameter selects the prescaler value like this:

psnPrescaler
12
216
3128
4512
52,048
[running]> clk 1 2
330 Clock set to 14745600 Hz / (2 * (1 + 2)) (base 10)
[running]> clk 1 123
330 Clock set to 14745600 Hz / (2 * (1 + 291)) (base 10)
[running]> clk 2 124
330 Clock set to 14745600 Hz / (16 * (1 + 292)) (base 10)
[running]> clk 3 200
330 Clock set to 14745600 Hz / (128 * (1 + 512)) (base 10)
[running]> clk 4 42
330 Clock set to 14745600 Hz / (512 * (1 + 66)) (base 10)
[running]> clk 1 100
330 Clock set to 14745600 Hz / (2 * (1 + 256)) (base 10)
[running]> clk 2 9
330 Clock set to 14745600 Hz / (16 * (1 + 9)) (base 10)
[running]> clk 3 a
330 Clock set to 14745600 Hz / (128 * (1 + 10)) (base 10)
[running]> clk 4 b
330 Clock set to 14745600 Hz / (512 * (1 + 11)) (base 10)i
[running]> clk 5 c
330 Clock set to 14745600 Hz / (2048 * (1 + 12)) (base 10)
[running]> 

Please be aware that it is possible to generate exceedingly slow clocks with this command: the slowest clock is just over 0.1 Hz, where it takes 10 seconds for a single clock tick. The processor's clock generator divides this by 4, so a single micro-instruction will step in 40 seconds. The clock will be used when the computer is running, but also when it is stepping or microstepping, and it also affects the length of time it takes for the computer to stop when the STOP switch is operated on the front panel. If a very slow clock is requested (approximately 0.22 Hz here), the DFP will issue a warning:

[running]> clk 5 8000
430 Warning: stopping/stepping will be REALLY slow.
330 Clock set to 14745600 Hz / (2048 * (1 + 32768)) (base 10)
[running]> 

C3.4.9.30. ir — Get or Set the Instruction Register

This command displays or changes the current value of the IR. This can only be done with the host halted.

[running]> ir
255 IR: 0000
[running]> ir 1234
503 Halt host first
[running]> halt
305 Host halted
[halted] 826c> ir 1234
355 IR: 1234
[halted] 826c> ir
255 IR: 1234
[halted] 826c> 

Note that register changes are always verified by the DFP to detect faulty hardware or cases where, during microprogram debugging, the control vector is overriding that particular action. An appropriate error is output in such a case:

[halted] 826c> ir
255 IR: 626c
[halted] 826c> ir 1234
355 IR: 626c
910 Value mismatch. Wrote 1234, was 626c
[halted] 826c> 
This is a very powerful and dangerous debugging command, as it can cause a jump from one microprogram to another. The five most significant bits of the IR form part of the microprogram address and they are not latched, so any change takes effect immediately. Changing the top five bits of the IR during instruction execution could have repercussions that are difficult to predict.

C3.4.9.31. pc — Get or Set the Program Counter

This command displays or changes the current value of the PC. This can only be done with the host halted.

[running]> pc 1234
503 Halt host first
[running]> halt
305 Host halted
[halted] 826c> pc fff8
354 PC: fff8
[halted] 826c> pc
254 PC: fff8
[halted] 826c> 

C3.4.9.32. ac — Get or Set the Accumulator

This command displays or changes the current value of the AC. This can only be done with the host halted.

[running]> ac 1234
503 Halt host first
[running]> halt
305 Host halted
[halted] 826c> ac 4342
353 AC: 4342
[halted] 826c> ac
253 AC: 4342
[halted] 826c> 

C3.4.9.33. a — Set the Address

This command shows or sets the current address. This address is used by a number of other panel operations.

[halted] 826d> a 
203 Address: 826d
[halted] 826d> a 2000
203 Address: 2000
[halted] 2000> pc
254 PC: 826d
[halted] 2000> 

Please note that this will not modify the PC. The only way for the physical front panel to set an address is to change the PC to it, while the virtual front panel has a separate address to ease debugging without having to constantly restore the value of the PC.

C3.4.9.34. r — Examine memory

This command reads and prints out consecutive words from the current memory address, which may be set at any point with the a command. The address is incremented every time the instruction is issued. The host must be halted.

[running]> r
503 Halt host first
[running]> halt
305 Host halted
[halted] 826d> a 2000
203 Address: 2000
[halted] 2000> r
356 Read: 8264
[halted] 2001> r
356 Read: e023
[halted] 2002> r
356 Read: 0000
[halted] 2003> 

C3.4.9.35. d — Hex Dump Memory

This command prints a CFT-style hexadecimal dump of memory starting at the current address, which may be set at any point with the a command. An optional hexadecimal argument may be used to dump a specified number of words. The default is 80, which dumps 128 words. The d command always dumps in groups of 8 words. If the optional argument is not a multiple of 8, it is rounded up.

[halted] 826d> a 8480
203 Address: 8480
[halted] 8480> d  
8480: 646f 3a65 2020 0000 4d0a 6d65 726f 3a79 ........ ode:  ...Memory: 0002264b
8488: 2020 2020 2020 0000 4b20 2057 4152 2c4d ........       .. KW RAM, 00035fc1
8490: 0020 4b20 2057 4f52 0a4d 0000 6544 6574  .......  . KW ROM...Dete 0004efaf
8498: 7463 6465 203a 2020 0020 6554 6d72 6e69 .... ... cted:    .Termin 00074a20
84a0: 6c61 3a73 2020 0020 424d 0055 4644 0050 ... .U.P als:   .MBU.DFP. 00089a6a
84a8: 5249 0043 5454 0059 4449 0045 5452 0043 .C.Y.E.C IRC.TTY.IDE.RTC. 0009dac6
84b0: 4d54 0052 564e 0052 4446 0043 5053 004a .R.R.C.J TMR.NVR.FDC.SPJ. 000b1432
84b8: 5350 0047 504c 0054 4456 0055 5445 0048 .G.T.U.H PSG.LPT.VDU.ETH. 000c51a1
84c0: 4947 004f 3f3f 003f 6e45 6976 6f72 6d6e .O.?.... GIO.???.Environm 000e8f50
84c8: 6e65 3a74 0020 6576 6972 6f6c 0a67 0000 .. ..... ent: .verilog... 00108104
84d0: 736a 652d 756d 0000 6d65 6c75 7461 726f ........ js-emu..emulator 00138fb2
84d8: 000a 3432 2400 3cb5 f52a 3431 f132 3430 ........ ..24.$5<*u142q04 00167360
84e0: 60e9 3432 2400 3cb5 f547 3431 f153 3430 ........ i`24.$5<Gu14Sq04 0019b82b
84e8: 60e9 f400 3529 2c31 b5a3 d014 60f4 e431 ........ i`.t)51,#5.Pt`1d 001e394a
84f0: b430 d014 60fe 60eb 2432 3c31 f532 3433 ........ 04.P~`k`2$1<2u34 0022093f
84f8: 2c31 3434 0da6 dcb5 3400 6c00 f41e 3529 ........ 1,44&.5\.4.l.t)5 00251d46
301 Done
[halted] 8500> d 1
8500: dcb5 3400 0a0a 0a0a 2020 2020 2323 2323 ........ 5\.4....    #### 0001ab4f
301 Done
[halted] 8508> d 8
8508: 2323 2323 2e23 2020 2020 2020 232c 2323 ........ #####.      ,### 00011b18
301 Done
[halted] 8510> d 20
8510: 2323 2323 2323 2323 2323 2323 0a23 2020 ........ #############.   0000fd15
8518: 2323 2323 2323 2323 2323 2323 2c23 2020 ........ #############,   00021c2a
8520: 2320 2020 2020 2020 2020 2020 2020 2020 ........  #               0003202a
8528: 2020 0a23 2320 2323 2323 2027 2020 2327 ........   #. #####'   '# 00041741
301 Done
[halted] 8530> 

The output is in five groups:

Address:
the leftmost column shows the starting address for the row.
Hexadecimal data:
the next eight columns are hexadecimal data starting at the row address.
Word-aligned characters:
this group decodes word-aligned or unpacked characters, interpreted as ASCII. Characters outside the range 32–126 (inclusive) are shown as dots.
Byte-aligned characters:
this group decodes byte-aligned or packed 7-bit ASCII characters. Characters outside the range 32–126 (inclusive) are shown as dots. The eighth bit is ignored, so negative-terminated packed strings (where the eighth bit of each character is used as a string terminator) are still printable.
Checksum:
a naïve 32-bit checksum of all data dumped so far (starting with the execution of the d command) in hexadecimal.

C3.4.9.36. dis — Disassemble Program

This command disassembles CFT assembly starting at the current address. An optional hexadecimal number may be provided to disassemble a specific number of words. The default value is 10(16 words).

[halted] 2005> a fff8
203 Address: fff8
[halted] fff8> dis 8
fff8:   JMP I     &3f9  ; [&fff9] &6bf9
fff9:   ISZ I     &000  ; [&fc00] &e800
fffa:   JMP I R   &002  ; [&fc02] &6c02
fffb:   TRAP      &000  ; [&fc00] &0000
fffc:   TRAP      &000  ; [&fc00] &0000
fffd:   TRAP      &000  ; [&fc00] &0000
fffe:   TRAP      &000  ; [&fc00] &0000
ffff:   TRAP      &000  ; [&fc00] &0000
301 Done

The disassembly is (by necessity) trivial, but does provide a decoded target address (in brackets) for local page addressing instructions (those without the R bit set). For instance, the JMP I &3f9 instruction above addresses memory at FFF9.

C3.4.9.37. db — Dump Binary Data

This command dumps memory in binary format, for download by a testing system. It works similarly to the d command, but the dump is not in human readable format. After the 303 Dumping message (which includes a newline!), as many words as specified will be output to the DFP Console. The least significant 8 bits of each word are output first. When the dump is done, the message 301 Done is printed, followed by the dump's checksum.

[halted] 2020> a 2000
203 Address: 2000
[halted] 2000> fill 20 4241
301 Done
[halted] 2020> a 2000
203 Address: 2000
[halted] 2000> db 20
300 Dumping
ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB301 Done
303 Checksum: 4820
[halted] 2020> 

C3.4.9.38. w — Write to Memory

This command writes one or more words of data to memory at the current address, as set by a. Each word must be in hexadecimal and separated by at least one space. The host must be halted first. The address will increment accordingly so consecutive w commands will operate as expected. A naïve 32-bit checksum of the written values is output. No verification takes place to avoid unexpected side effects on memory-mapped devices.

[running]> halt
305 Host halted
[halted] 826c> a 2000
203 Address: 2000
[halted] 2000> w 1234 5678 9abc def0
303 Checksum: e258
[halted] 2004> 

C3.4.9.39. fill — Fill Memory with a Value

This command fills a block of memory with a single value. It is provided with two arguments: the number of words to write, and the value to write. For large jobs, a progress message is printed every 256 words.

[running]> halt
305 Host halted
[halted] 826e> a 2000
203 Address: 2000
[halted] 2000> fill 8 4241
301 Done
[halted] 2008> a 2000
203 Address: 2000
[halted] 2000> d 20
2000: 4241 4241 4241 4241 4241 4241 4241 4241 ........ ABABABABABABABAB 00021208
2008: 0000 0000 0000 0000 0000 0004 e015 0000 ........ .............`.. 0002f221
2010: 8067 7f98 fffe 0000 0000 0000 0000 0000 ........ g...~........... 0004f21e
2018: 0000 0000 0000 0000 0000 0000 0000 0000 ........ ................ 0004f21e
301 Done
[halted] 2020> a 2000
203 Address: 0000
[halted] 2000> fill 400 5555
203 Address: 2100
203 Address: 2200
203 Address: 2300
203 Address: 2400
301 Done
[halted] 2400> 
Tip
The DFP only allows 16-bit hexadecimal integers. This implies that the maximum number of words that can be written to memory is 65,535. To fill all 65,536 words of memory, it is thus necessary to use two fill commands, or a fill of 65,535 and a single w command.

C3.4.9.40. in — Input from I/O Device

This command reads a word from the supplied I/O address and prints it out. The host must be halted. This is a potentially dangerous instruction and must be used with care as even reading from an I/O address can cause side-effects.

[running]> in 300
503 Halt host first
[running]> halt
305 Host halted
[halted] 826c> in 60
234 IN Address: 0060 Value: ffff
[halted] 826c> in 61
234 IN Address: 0061 Value: 0001
[halted] 826c> in 62
234 IN Address: 0062 Value: 00c1

The DFP microcontroller is a limited device and the firmware is not re-entrant. To avoid potential issues, the DFP firmware will not issue I/O transactions to its own address range (0100–011F), printing out a less than self-explanatory error message.

[halted] 826c> in 100
510 You talkin' to me?

C3.4.9.41. out — Output to I/O Device

This command outputs a word to an I/O address. The address is specified first, followed by the word. Both must be specified in hexadecimal, as always. The host must be halted. The following example writes the characters A, B and C to the TTY0 Universal Asynchronous Receiver-Transmitter (UART) (if installed and enabled).

[halted] 826c> out 60 41
357 OUT Address: 0060 Value: 0041
[halted] 826c> out 60 42
357 OUT Address: 0060 Value: 0042
[halted] 826c> out 60 43
357 OUT Address: 0060 Value: 0043

The DFP microcontroller is a limited device and the firmware is not re-entrant. To avoid potential issues, the DFP firmware will not issue I/O transactions to its own address range (0100–011F), printing out a less than self-explanatory error message.

[halted] 826c> out 100 ffff
510 You talkin' to me?

C3.4.9.42. i1 — Interrupt Level 1

This command signals a level 1 interrupt, behaving in the same was as operating the IFR1 switch on the front panel.

[running]> i1
358 IRQ1 signaled

If this particular interrupt has not been enabled by the CFT (and this is the default at power-up), an appropriate warning will be issued:

[running]> i1
458 IRQ1 masked by CFT

C3.4.9.43. i6 — Interrupt Level 6

This command signals a level 6 interrupt, behaving in the same was as operating the IFR6 switch on the front panel.

[running]> i6
359 IRQ6 signaled

If this particular interrupt has not been enabled by the CFT (and this is the default at power-up), an appropriate warning will be issued:

[running]> i6
459 IRQ6 masked by CFT

C3.4.9.44. sr — Read the Switch Register

This command prints the current value of the SR. The value of the SR is also displayed using the same message (albeit asynchronously) whenever the SR changes, and if asynchronous messages are enabled. The register's value is printed in binary, hexadecimal, decimal, and as a disassembled CFT instruction.

[running]> sr
220 Switch Register: 0000000000000000  0000  0  TRAP    &000

C3.4.9.45. or — Get or Set the Output Register

This command displays the current value of the OR. If an optional hexadecimal value is provided, the OR is set to that value. If the OR is selected for display on the front panel, the MFD lights will change to reflect the new value.

[running]> or
221 Output Register: 0000
[running]> or ffff
321 Output Register: ffff
[running]> or 8888
321 Output Register: 8888

C3.5. Using the DFP from the CFT

The DFP appears to the computer as a block of 32 addresses in I/O space. Some of these addresses are reserved for future expansion. The addresses are meant to be used as Extended Instructions. Many of these are direct descendants of those on the original DEB card, and have the same semantics. The binary opcodes, however, have changed and are no longer compatible with the DEB card. Other instructions and a few I/O-addressed registers have been added to use the DFP's extra features.

The mapping of the DFP board to the I/O space provides 32 locations, most of which are extended CFT instructions. Not all 32 addresses are used, and there are no read/write registers.

AddressDirectionInstructionSame asAction
100WriteSOROUT R &100
100ReadLSRIN R &100Load value of SR into AC.
101ReadLDSRIN R &101Load value of DIP switches into AC.
108WriteENEFOUT R &108Enable Feature.
108ReadQEFIN R &108Query enabled features.
109WriteDISEFOUT R &109Disable Feature.
109ReadIN R &109Copy of QEF.
10AWriteOUT dfp.ICROUT R &10Adfp.ISR: Interrupt Control Register.
10AReadIN dfp.ISRIN R &10Adfp.ISR: Interrupt Status Register.
10FWriteSENTINELOUT R &3FFLog a sentinel instruction (and maybe halt).
110WritePRINTAOUT R &3F0Print word as an address.
111WritePRINTCOUT R &101Print word as character.
111ReadREADCIN R &101Read a character from the Virtual Console.
112WritePRINTDOUT R &102Print word as decimal signed integer.
113WritePRINTUOUT R &103Print word as decimal unsigned integer.
114WritePRINTHOUT R &104Print word in hexadecimal.
115WritePRINTBOUT R &105Print word in binary.
116WritePRINTSPOUT R &106Print a space.
117WritePRINTNLOUT R &107Print a new line character.
118WriteDEBUGONOUT R &108Emulator only: start tracing.
119WriteDEBUGOFFOUT R &109Emulator only: stop tracing.
11AWriteDUMPOUT R &10AEmulator only: dump processor state.
11BWritePRINTHIOUT R &10BPrint 32-bit value, high order.
11CWritePRINTLOOUT R &10CPrint 32-bit value, high order.
11DWriteHALTOUT R &10DHalt the system.
11EWriteSUCCESSOUT R &10ELog a test success.
11FWriteFAILOUT R &3FFLog a test failure (and maybe halt).

The DFP is driven by a relatively slow MCU. Okay, that isn't entirely true. The MCU is technically much faster than the CFT itself, running at 14.7456 MHz rather than 4 MHz, but the CFT can complete an I/O transaction in 500 ns where the MCU needs hundreds of clock cycles to sample the CFT's buses and decide what the transaction is about. To keep them in sync, the DFP's address decoder circuitry asserts a CFT Wait State as soon as the computer addresses it. The Wait State stays asserted until the MCU has woken up and performed its task.

Even worse, this task almost always transmits information via the MCU's serial port, and the DFP will wait until all information has been sent out before releasing the Wait State. Even at 460,800 bps, or 46,080 BPS, a character takes 21.7 µs to transmit. A 30-character string will take a glacial 650 µs.

This makes DFP instructions extremely slow but since the DFP instructions are mostly used for early testing and debugging, this is acceptable.

C3.5.1. Accessing the Front Panel Lights and Switches

The following extended instructions are available:

SOR:
(Set Output Register). Writes the current value of the AC to the OR, driving the Output Register lights on the front panel. If the MFD switch isn't set to OR, changes of the OR won't be immediately apparent.
LSR:
(Load Switch Register). Loads into the AC the current value of the SR, the sixteen sense switches in the middle section of the front panel.
LDSR:
(Load DIP Switch Register). Loads into the AC the current value of the DIP switches on Board 1 of the DFP. There are twelve switches, split into SW1 (eight least significant bits) and SW2 (four most significant bits). The remaining four bits are always zero.
1514131211109876543210
0000SW2SW1

C3.5.2. Detecting, Querying and Setting Special Features

There are a number of debugging facilities in the CFT project. Starting with the early Verilog emulator, on to the C emulator, the JavaScript microcode-level and assembly-level emulators, and of course the hardware itself. Each of these has special features for special tasks, and not all platforms support all of them. What's worse, the DFP is firmware based, so features can come and go far too easily. To help the hardware deal with these changes, the debugging framework offers these extended commands. They work to detect the presence of the test/debugging framework, whether the ROM is running on real hardware or not, and allow the computer to set test features. This allows a test to be configured in-band with a CFT test program. I've also found at least one case where I had to temporarily disable some debugging features for normal operation: probing for RAM and ROM can cause the test framework to log failures and halt the computer.

To query the DFP for presence, available, and enabled features, the QEF extended instruction is issued. This loads the AC with the following bitfield:

1514131211109876543210
DetectionLCKHOSHOFSNTDMPUTRTRCTSTTTYDEBPFP

The bits are defined as follows:

BitValueSymbolWhat it means
PFP---------------1dfp.QEF_PFPThe Programmer's Front Panel is installed.
DEB--------------1-dfp.QEF_DEBThe Debugging subsystem is available.
TTY-------------1--dfp.QEF_TTYThe Virtual Console is available.
TST------------1---dfp.QEF_TSTThe PRINTx instructions are available.
TRC-----------1----dfp.QEF_TRCThe DEBUGON and DEBUGOFF instructions are available.
UTR----------1-----dfp.QEF_UTRMicrocode tracing is available.
DMP---------1------dfp.QEF_DMPThe DUMP instruction is available.
SNT--------1-------dfp.QEF_SNTThe SENTINEL instruction is available.
HOF-------1--------dfp.QEF_HOFExecuting FAIL will halt the computer.
HOS------1---------dfp.QEF_HOSExecuting SENTINEL will halt the computer.
LCK-----1----------dfp.QEF_LCKThe front panel has been locked.
Detection000-------------dfp.QEF_DVERunning in the ancient Verilog emulator.
Detection010-------------dfp.QEF_DHWRunning on hardware.
Detection110-------------dfp.QEF_DCERunning on the C emulator.
Detection111-------------dfp.QEF_DJERunning on a JavaScript emulator.

Note that all current versions of the DFP firmware (on physical or emulated hardware) will return at least the PFP, DEB, TTY, TST, TRC, UTR, DMP, and SNT bits set. The Javascript implementation returns a subset of these as it was never meant for testing.

The HOF and HOS bits can be changed using the ENEF and DISEF virtual instructions. The LCK bit represents the current state of the panel lock switch. To use these instructions, load the AC with an appropriate value and call ENEF to enable the features for which the corresponding bit is set, or DISEF to disable them. The feature bitfield for both instructions is as follows:

1514131211109876543210
HOFHOSUTRTRCHOB
BitValueSymbolWhat it means
HOB---------------1dfp.FTR_HOBEmulator only: halt on ‘bus errors’.
TRC-----------1----dfp.FTR_TRCTraces assembly execution. Slow.
UTR----------1-----dfp.FTR_UTRTraces microcode execution. Slower than molasses.
HOF-------1--------dfp.FTR_HOFIf set, executing FAIL halts the computer.
HOS------1---------dfp.FTR_HOSIf set, executing SENTINEL halts the computer.
HOB:
only available on the emulator. When enabled, the emulator will terminate and dump its state when ‘bus errors’ are encountered. They're in inverted commas because the CFT doesn't have bus errors, but the emulator can halt execution if the emulated computer tries to access an address that decodes to nothing. This plays havoc with, e.g. memory detection logic which reads from various memory addresses that may or may not map to memory.
TRC:
when enabled, assembly code being executed will be printed out instruction by instruction. This is useful for testing only. It produces copious amounts of output on the emulator and causes the hardware to run at a very slow speed to facilitate tracing.
UTR:
microcode being executed will be printed out micro-instruction by micro-instruction. Only of use in testing microprogram issues. Causes hardware to run at a very slow speed to facilitate tracing.
HOF:
halt on FAIL. When enabled, the FAIL instruction will also halt the computer. Another feature used for testing.
HOS:
halt on SENTINEL. When enabled, the SENTINEL instruction will also halt the computer. Another feature used for testing.
Hardware Implementation
As of early 2019, the current version of the DFP firmware only honours the TRC and HOS requests (and only implements the HOS feature!), but this can and probably will change when it's called upon to run the test suite.

C3.5.3. Sentinels, Successes, Failures, Oh My!

The SENTINEL, SUCCESS and FAIL extended instructions are checkpoint instructions used in testing. They are used to ensure that execution is following the expected flow, but also to provide test programs with a facility for self-checking their results and registering successes and failures.

SUCCESS:
this instruction registers a success with the test framework. To mark this, the sequence ‘[ok]’ is transmitted to the controlling computer in the Virtual Console. The DFP console will print the message ‘345 SUCCESS’.
FAIL:
registers a failed test assertion with the test harness. This is used to provide information to the controlling computer. The failure is shown by sending the sequence ‘[fail]’ to the Virtual Console. The DFP Console will instead print out ‘346 FAIL’. If the Halt-On-Fail flag is set, the computer will also halt at this point.
SENTINEL:
this instruction is very similar to FAIL in that most tests treat its execution as a test failure. It's used to detect a secondary failure of a test program, often a failed skip or jump. Many tests fill all available memory with SENTINEL instructions, then load a program. If the PC runs away from program execution, the sentinels will catch it. When a sentinel is encountered, the Virtual Console will display ‘[sentinel]’. The DFP Console will instead print out ‘341 SENTINEL’.

C3.5.4. Registering Test Results

There are numerous extended instructions hailing back to the original Verilog testbed for the processor. The opcodes have changed, and some of the semantics have changed a little, but the instructions are still there.

PRINTH:
The current value of the AC is output to the Virtual Console as a hexadecimal integer in the range 0000–FFFF, zero-padded to four digits. The DFP console receives the message ‘340 PRINTH XXXX’.
PRINTA:
The current value of the AC is output to the Virtual Console as a hexadecimal integer in the range 0000-FFFF, zero-padded to four digits. The DFP Console receives the message ‘340 PRINTA XXXX’. This is meant to print out an address. On the emulator with a ROM map file loaded, the address is shown as a 16-bit hexadecimal followed by a symbolic form (last_label+XXXX). On the DFP, PRINTA works just like PRINTH.
PRINTB:
The current value of the AC is output to the Virtual Console as a binary 16-bit integer in the range 00000000000000001111111111111111, zero-padded to sixteen digits. The DFP console receives the message ‘340 PRINTB XXXXXXXXXXXXXXXX’.
PRINTC:
The least significant eight bits of the AC are output to the Virtual Console. The DFP console receives the string ‘340 PRINTC X where X is the character itself. If the character is unprintable, the message ‘340 PRINTc X’ (lower case c) is output instead, with a lower case ‘c’ and the character represented by its integer codepoint.
PRINTD:
The current value of the AC is output to the Virtual Console as a base-10 signed, two's complement integer in the range -32,768–32,767. There is no zero-padding. The DFP console receives the message ‘340 PRINTD X’ where X is the integer.
PRINTU:
The current value of the AC is output to the Virtual Console as a base-10 unsigned, integer in the range 0–65,535. There is no zero-padding. The DFP console receives the message ‘340 PRINTU X’.
PRINTHI:
Stores the current value of the AC in a temporary register on board the DFP board. The register should be the most significant 16 bits of a 32-bit unsigned value. The value is printed when PRINTLO is executed.
PRINTLO:
Prints out the 32-bit integer made by combining the last value stored by PRINTHI, shifted 16 bits to the left, and the current value of the AC. The number reported is in the range 00000000-FFFFFFFF and is zero padded to eight digits. The DFP console will receive the message ‘340 PRINTL XXXXXXXX (note, PRINTL, not PRINTLO). The case of the alphabetic digits is purposefully unspecified. Parsers should understand both lower and upper case.
PRINTSP:
A helper for early test code that's stayed with us because it makes some tests easier (and doesn't change the AC). It simplifies debugging and testing, since none of the PRINTx instructions space-pad their outputs. Since the value of the AC does not need to change, it is especially convenient while printing out these values and keeps tests simple. It prints out a single space (ASCII codepoint 32) to the Virtual Console. The DFP Console prints out ‘340 PRINTc 32’ instead.
PRINTNL:
Another old helper. It prints out a (Unix) end-of-line character, ASCII line feed (codepoint 10) to the Virtual Console. The DFP Console prints out ‘340 PRINTc 10’ instead.

C3.5.5. Debugging, Tracing and Halting

And of course there are some extended instructions that just don't fit anywhere.

DEBUGON:
On the hardware DFP, this instruction starts single-stepping the computer at a pace slow enough for its state to be read between steps. This may be equivalent to running the computer at the slow speed setting of about ten instructions per second. The code printed out is disassembled by the DFP, and may be difficult to follow without the source of the program being executed. On the emulator with a ROM map file loaded, this shows actual preprocessed CFT assembly which is fairly close to the source code (with macros expanded), and symbolic labels rather than just addresses.
DEBUGOFF:
Stops symbolic tracing of all instructions executed and resumes executing at full speed. This is the default behaviour on start-up.
DUMP:
Prints out the current state of the processor and DFP in a machine-parseable format. The format is very different between the physical DFP and the CFT emulator. The emulator intercepts the execution of DUMP and augments it with its own state. The format is still in flux, and the command might go away completely since it's not used that much these days.
HALT:
Completes executing the current instruction, then halts the computer.
The DEBUGON, DEBUGOFF and DUMP instructions aren't fully implemented on the DFP as of yet.

C3.5.6. I/O Registers

In addition to the extended instructions, the DFP also provides four I/O addresses used as ordinary registers. The registers allow the Virtual Console to be used as a nearly ordinary (if very slow and simple) UART. They also allow the DFP's interrupt behaviour to be inspected and modified.

To transmit a character to the Virtual Console, OUT it to dfp.TX. The least significant eight bits of the AC will be output to the Virtual Console. This register works exactly like the PRINTC extended instruction, and it's no wonder: it's the same thing, and even shares the same address. This implies that the DFP console will also receive its 340 PRINTC or 340 PRINTcasynchronous message.

Molasses Alert!
The DFP's serial output isn't buffered. The DFP will assert a Wait State until the character has been dispatched. This will make using the Virtual Console fairly slow. At 460,800 bps, a character takes approximately 22 µs or nearly 87 processor cycles to broadcast! If the DFP Console is active, it could take 30 times longer!

To receive characters from the Virtual Console, you can use polling, interrupt driven communication, or a combination of both. The DFP has a small ring buffer that stores incoming characters until the CFT is ready to receive them. To do that, read a value from dfp.RX. The result will follow this format:

1514131211109876543210
RBECharacter

If the AC is negative (i.e. RBE is set), there is no character available. If the AC is positive, its least significant eight bits will hold the received character. Execute IN dfp.RXrepeatedly until it yields a negative number to receive all characters from the DFP's Virtual Console ring buffer.

To read characters using Interrupt driven communications, the DFP's interrupts must be configured. This is done by writing to the dfp.ICR, the Interrupt Control Register. This controls what interrupts are issued by the DFP according to the following bitfield:

1514131211109876543210
TTYQIFR6IFR1
BitValueSymbolWhat it means
IFR1--------------1-dfp.ICR_IFR1Assert IRQ1 when IFR1 is pressed.
IFR6-------------1--dfp.ICR_IFR6Assert IRQ6 when IFR6 is pressed.
TTYQ------------1---dfp.ICR_TTYQAssert IRQ6 when input available on Virtual Console
IFR1:
if this bit is set, the IFR1 switch on the front panel and ifr1 command will strobe IRQ1 to interrupt the CFT. If this bit is clear, the message ‘458 IRQ1 masked by CFT’ is shown on the DFP console and the CFT is not interrupted. This is the default.
IFR6:
if this bit is set, the IFR6 switch on the front panel and ifr6 command will strobe IRQ6 to interrupt the CFT. If this bit is clear, the message ‘459 IRQ6 masked by CFT’ is shown on the DFP console and the CFT is not interrupted. This is the default.
TTYQ:
if this bit is set, when the Virtual Console receives a character, an IRQ6 interrupt will be generated. The character or characters can be read from the dfp.RX register. If this bit is clear, incoming characters are queued in the Virtual Console ring buffer but the CFT is not interrupted. This is the default.

This facility relies on the IRC (interrupt controller) card and currently does nothing on an unexpanded CFT. To provide basic terminal functionality, the DFP sports a jumper that can reroute its IRQ6 requests to IRQ instead. This last signal reaches the processor directly.

So, to enable interrupt-driven communications, first write the required bit pattern to dfp.ICR. Then, in the Interrupt Service Routine, read dfp.ISR, the Interrupt Status Register. It will yield a bitfield like this:

1514131211109876543210
TTYQIFR6IRQ1IRQ6
BitValueSymbolWhat it means
IRQ6---------------1dfp.ISR_IRQ6IRQ6 (or IRQ) has been signalled.
IRQ1--------------1-dfp.ISR_IRQ1The IFR1 has signalled IRQ1.
IFR6-------------1--dfp.ISR_IFR6The IFR6 has signalled IRQ6.
TTYQ------------1---dfp.ISR_TTYQIRQ6 was signalled because there are input characters to read.
IRQ6:
if this bit is set, IRQ6 (or IRQ, depending on the interrupt jumper) has been strobed since the last time this register was read. This may be due to the IFR6 switch being operated, the ifr6 command entered on the DFP console, one or more characters being available on the Virtual Console, or a combination of the above. Examine the IFR6 and TTYQ bits below to determine which case or cases are true.
IRQ1:
if this bit is set, IRQ1 has been strobed since the last time this register was read. This may be due to the IFR1 switch being operated or the ifr1 command entered on the DFP console.
IFR6:
if this bit is set, the IFR1 switch has been operated operated or the ifr1 command has been entered on the DFP console.
TTYQ:
if this bit is set, one or more characters have been received on the Virtual Console. Read dfp.RX until it returns a negative value to retrieve them all.

Like many Interrupt Status Registers, every time the dfp.ISR is read, all flags are reset to zero, so don't read this register if you don't intend to act on it, or you risk losing input events.

C3.6. The DFP Firmware

C3.6.1. Messages

This is a list of all messages emitted by the DFP firmware. All messages start with a three-digit code that can be used to identify the message.

C3.6.1.1. Messages 100-199: Diagnostics

These messages are printed out during the DFP's power-on diagnostics routine. In the following, DIAGNOSTIC-STATUS is either OK or faulty.

101 Processor: not found
Initial testing of the buses failed to find a processor. On early versions of the DFP firmware, this means Standalone Mode is enabled, where the DFP becomes the sole bus master. This has been removed in recent versions of the firmware and the processor is expected to be present.
101 Processor: found
Initial testing of the buses failed to find a processor. This is the expected outcome, and means further testing can be carried out.
102 VP Shift Reg chain: DIAGNOSTIC-STATUS
The DFP has just checked the Virtual Front Panel shift register chain.
103 DEB Shift Reg chain: DIAGNOSTIC-STATUS
The DFP has just checked the DEB (bus interface) shift register chain.
104 ABUS driver: DIAGNOSTIC-STATUS
The DFP has just checked its Address Bus drivers.
105 ABUS tristate: DIAGNOSTIC-STATUS
The DFP has just checked its ability to safely tristate the Address Bus.
106 DBUS driver: DIAGNOSTIC-STATUS
The DFP has just checked its Data Bus drivers.
107 DBUS tristate: DIAGNOSTIC-STATUS
The DFP has just checked its ability to safely tristate the Data Bus.
108 Bus quiet during reset: DIAGNOSTIC-STATUS
The DFP has checked if the CFT buses remain quiescent while RESET is asserted.
109 AC: DIAGNOSTIC-STATUS
The DFP has checked its interface to the AC and is confident all the bits work for reading and writing.
110 PC: DIAGNOSTIC-STATUS
The DFP has checked its interface to the PC and is confident all the bits work for reading and writing.
111 IR: DIAGNOSTIC-STATUS
The DFP has checked its interface to the IR and is confident all the bits work for reading and writing.

C3.6.1.2. Messages 200-299: Information

These messages display various types of information.

201 Version: TEXT
Displays the version of the firmware. If the version strings contains the characters +dis, it is capable of code and microcode disassembly. Currently all versions of the firmware support this feature—originally it was optional as it caused the firmware to be too large to fit the Flash RAM of the original microcontroller. The part currently used has plenty of memory, though.
202 TEXT
Informational text intended for humans such as URLs, licensing terms, boot-up banners, etc. It can safely be ignored.
204 BufSize: HEX-NUMBER
The maximum length of the command buffer (and thus, commands entered at the prompt) in hexadecimal. This mostly impacts the number of words that can be written at once.
200 Ready
The DFP firmware is ready to receive commands. Output when given an empty command.
203 Address: HEX-NUMBER
The current address set for various operations. Appears after the address has been explicitly queried or set.
205 Processor found.
Appears during the DFP boot process if a processor has been located. After this message, the DFP is in full mode.
206 No processor.
Appears during the DFP boot process if no processor was found. In this condition, certain commands are impossible.
210 Echo: BOOLEAN-STATE
Displays the state of the terminal echo feature. Echo should usually be on for terminals operated by humans, but is often preferred to be off when the DFP is operated by another computer. This is modified by the echo command.
211 Async messages: BOOLEAN-STATE
Displays whether or not asynchronous messages are allowed. Asynchronous messages interrupt commands being entered to display a change in state of the front panel or computer, or when the computer executes one of the debugging extended instructions. This can be disruptive when entering commands manually and so can be disabled. The mesg command controls the delivery of asynchronous messages.
212 Terminal: BOOLEAN-STATE
Displays whether or not the DFP is driving a terminal or terminal emulator. When this mode is enabled, the output is optimised for humans, with terminal directives providing a better experience. In the off state, output is optimised for automated tools.
213 On FAIL: HALT-STATE
Displays the behaviour of the FAIL extended instruction. HALT-STATE is either HALT or Ignore.
214 On SENTINEL: HALT-STATE
Displays the behaviour of the SENTINEL instruction. HALT-STATE is either HALT or Ignore.
215 Front panel lock: BOOLEAN-STATE
Displays the state of the front panel lock switch. BOOLEAN-STATE is either on or off.
220 Switch Register:
Displays the state of the switch register. The message is followed by three or four space separated fields: the state of the switches as a 16-character string made up of 0 (off) or 1 (on); the same value in hexadecimal; the same value again in unsigned decimal; and, if the firmware includes disassembly features (versions ending in +dis), the Assembly instruction and operand corresponding to this value.
221 Output Register: HEX-NUMBER
Displays the current value of the output register as a four-digit, zero-padded hexadecimal number.
234 IN Address: HEX-ADDRESS Value: HEX-NUMBER
Result of a successful execution of the in command showing the I/O space address and the value read from that address.
250 Machine state: FLAGS PC:HEX-ADDRESS AC:HEX_VALUE IR:HEX_VALUE INSTRUCTION-DISASSEMBLY
Output of the s command. Outputs the CPU flags (a field nzvil representing the N, Z, V, I and L flags, where clear flags are shown as - and set flags are shown as their letter in lower case), and the contents of the PC, AC and IR. If disassembly is available (versions ending in +dis), the IR is disassembled and printed too.
251 Switch state: FIELD1 FIELD2 FIELD3 FIELD4 FIELD5
Output of the sws or swtest commands showing the state of all switches on the front panel, including DIP switches. All five fields are binary numbers of different lengths. Please refer to the description of the sws command for more information.
252 Microcode control: BINARY-NUMBER DISASSEMBLED FIELDS
Output in an number of situations to show the current state of the Microcode Control Vector. BINARY-NUMBER is a 24-bit binary number representing the vector. If disassembly is available, this is followed by a number of fields representing the actions performed by the Control Unit.
253 AC: HEX-NUMBER
Displays the current value of the AC.
254 PC: HEX-NUMBER
Displays the current value of the PC.
255 IR: HEX-NUMBER
Displays the current value of the IR.
259 Breakpoint HEX-NUMBER STATE
Displays the state of a DFP breakpoint. The number is the breakpoint index (a base 16 number between 0 and 7, though this could change in the future). STATE is either a 16-bit hexadecimal number representing the address of the breakpoint, or off if the breakpoint is unset.

C3.6.1.3. Messages 300-299: Successful Operations

310 Echo: BOOLEAN-STATE
Shown after setting local echo. Displays the new state of this setting as either on or off.
311 Async messages: BOOLEAN-STATE
Shown after enabling or disabling asynchronous messages with mesg. Displays the new state of this setting as either on or off.
312 Terminal: BOOLEAN-STATE
Shown after enabling or disabling terminal mode with term. Displays the new state of this setting as either on or off.
313 On FAIL: HALT-STATE
Shown after setting or clearing halt-on-FAIL mode. HALT-STATE is either HALT or Ignore.
314 On SENTINEL: HALT-STATE
Shown after setting or clearing halt-on-SENTINEL mode. HALT-STATE is either HALT or Ignore.
315 Front panel lock: BOOLEAN-STATE
Shown in answer to the lock command with no arguments. Displays the current state of the panel lock. BOOLEAN-STATE is either on or off. Note, the 374 message is similar but displays asynchronously when the physical key switch has changed position.
353 AC: HEX-NUMBER
Acknowledges the AC has been set and displays its value.
354 PC: HEX-NUMBER
Acknowledges the PC has been set and displays its value.
355 IR: HEX-NUMBER
Acknowledges the IR has been set and displays its value.
359 Breakpoint HEX-NUMBER STATE
Acknowledges breakpoint HEX-NUMBER has been set to STATE. STATE is either a 16-bit hexadecimal address if the breakpoint was set, or off if it was cleared.
299 T0sgQ09NUFVURVI=
The DFP serial protocol has just switched to computer mode: local echo and terminal niceties have been turned off to help a remote computer operate the DFP for testing.
300 Dumping
Output by the db command when a binary dump is about to commence. To parse a 300 message, parse until the end of line indicator \n. The binary dump (as many 16-bit words as specified in the parameter of the db command) will follow immediately after followed by a 301 Done message.
301 Done
Sent at the end of any long or repeated process that can potentially print out a lot of information. This message should be used as a terminator for such multi-line output.
302 Aborted
Sent instead of 300 Done when a long or repeated process is aborted before completion using, e.g. Ctrl-C on the DFP Console.
303 Checksum: HEX-NUMBER
Sent at the end of commands that read or modify blocks of memory. The HEX-NUMBER is a 32-bit quantity denoting the sum of all 16-bit values read from or written to memory. Automated tools should test this checksum to verify correctness.
304 Host running
Acknowledges that the computer has started running from the halted state.
305 Host halted
Acknowledges that the computer has been halted.
306 Host reset
Acknowledges that the computer has been reset.
307 Cold reset.
Acknowledges that a cold reset is about to take place. Random, invalid characters may be sent out on the DFP console while this is taking place. The next valid message after the DFP resets should be a 101 message.
321 Output Register: HEX-VALUE
Acknowledges the OR has been set and displays its value.
322 Breakpoint HEX-VALUE
Signifies that execution has stopped because a breakpoint has been encountered. HEX-VALUE is the number of the encountered breakpoint (currently between 0 and 7).
323 Step. FLAGS PC:HEX-VALUE AC:HEX_VALUE IR:HEX_VALUE INSTRUCTION-DISASSEMBLY
Acknowledges the processor has stepped. Outputs the CPU flags (a field nzvil representing the N, Z, V, I and L flags, where clear flags are shown as - and set flags are shown as their letter in lower case), and the contents of the PC (the next instruction to execute), AC and IR. If disassembly is available (versions ending in +dis), the IR is disassembled and printed too. The instruction shown is the instruction about to be executed.
324 Microstep. FLAGS PC:HEX-VALUE AC:HEX_VALUE IR:HEX_VALUE INSTRUCTION-DISASSEMBLY BINARY-NUMBER DISASSEMBLED FIELDS
Acknowledges the processor has micro-stepped. Outputs a combination of the processor state (as seen, e.g. after message 324 above) and the Microcode Control Vector. If the firmware includes disassembly features, both IR and the Microcode Control Vector will be disassembled. Please note that this makes it more difficult for an automated test to parse the output. Also, this will print very long lines.
325 Tracing.
Acknowledges the trace instruction has been issued.
326 Microtracing.
Acknowledges the utrace instruction has been issued.
327 Full speed clock.
Acknowledges the processor clock has been enabled and the computer is running at its full speed.
328 Slow clock.
Acknowledges the computer is running at slow speed.
329 Very slow clock.
Acknowledges the computer is running at very slow speed.
330 Clock set to 14745600 Hz / (PRESCALER * (1 + DIVIDER)) (base 10)
Acknowledges the computer is running at a custom speed. PRESCALER and DIVIDER are both base 10 numbers. For more information on this message (and why it looks like this), please refer to the description of the clk command.
331 Virtual console (press Enter # . to exit).
The Virtual Console has been activated. To exit, the sequence #. must be encountered as the first two characters of a new line.
332 Left virtual console.
The Virtual Console has been deactivated.
333 ROM/RAM# switch: POSITION
The RAM BNK/ROM BNK switch has changed state. POSITION is either ROM or RAM, identifying the type of memory mapped to the top 32 kWords of memory at boot time, before the MBU has been enabled.
334 Operate toggles/DIP switches. Ctrl-C ends.
A switch test has been requested via the swtest command. This is an interactive process that must be ended manually with Ctrl-C.
340 PRINTx VALUE
An extended printing command has been executed. This message is unusual in that the same message number appears for all printing commands. The first word following 340 identifies what is printed: PRINTA (address), PRINTB (16-bit binary number), PRINTC (character), PRINTc (unprintable character), PRINTD (base 10 signed number), PRINTH (16-bit hexadecimal), PRINTL (32-bit hexadecimal output by PRINTLO), or PRINTU (16-bit base-10 unsigned integer). The exact format of VALUE depends on the first word.
341 SENTINEL
A SENTINEL instruction has been executed.
342 DEBUGON
A DEBUGON instruction has been executed and the DFP is about to start tracing instructions.
343 DEBUGOFF
A DEBUGON instruction has been executed and the DFP has just stopped tracing instructions.
345 SUCCESS
A SUCCESS instruction has just executed.
346 FAIL
A FAIL instruction has just executed.
356 Read: HEX-VALUE
The result of executing a r instruction. Prints out data retrieved from the current memory address (as set by a).
357 OUT Address: HEX-ADDRESS Value: HEX-VALUE
Result of a successful execution of the out command showing the I/O space address and the value written to that address.
358 IRQ1 signaled
The IFR1 switch has been actuated and the IRQ1 signal has been asserted.
359 IRQ6 signaled
The IFR6 switch has been actuated and the IRQ6 signal has been asserted.
370 Write mem[HEX-ADDRESS] &lt;- HEX-VALUE
Either the MEM W or MEM W NEXT switch has been actuated. The memory address and value written to that address (i.e. the value of the SR) are shown.
371 Read mem[HEX-ADDRESS] &lt;- HEX-VALUE
Either the MEM R or MEM R NEXT switch has been actuated. The memory address and value read from are shown.
372 Write I/O[HEX-ADDRESS] &lt;- HEX-VALUE
Either the I/O W or I/O W NEXT switch has been actuated. The I/O space address and value written to that address (i.e. the value of the SR) are shown.
373 Read I/O[HEX-ADDRESS] &lt;- HEX-VALUE
Either the I/O R or I/O R NEXT switch has been actuated. The memory address and value read from are shown.
374 Panel lock: BOOLEAN-STATE
The panel lock key switch has changed position. BOOLEAN-STATE shows the current state of the lock. Note that the 315 message is similar, but displays only as a result of the lock query command.

C3.6.1.4. Messages 400-499: Warnings

These messages are warnings. If terminal mode is on, they are displayed in yellow.

401 Warning: write will wrap around.
The next write or fill will cause the address set by a to wrap around. This is just informational if the intention is to wrap around, but that intention is rare enough that the warning makes sense.
430 Warning: stopping/stepping will be REALLY slow.
A custom clock rate has been set with clk, and the rate is so slow that stepping and halting will take significant lengths of time. Solution: set a faster clock or operate the clock speed switch.
458 IRQ1 masked by CFT
The IFR1 switch has been operated, but the CFT has not enabled reception of IRQ1 interrupts from the DFP. The computer ignores the switch.
459 IRQ6 masked by CFT
The IFR6 switch has been operated, but the CFT has not enabled reception of IRQ6 interrupts from the DFP. The computer ignores the switch.

C3.6.1.5. Messages 500-599: Interaction Errors

The messages are errors. If terminal mode is on, they are displayed in red.

500 Unknown command
The DFP did not recognise this command entered on the DFP console.
501 Bad value
A parameter to the last command did not parse.
502 Count must be multiple of 8
Dump commands output whole lines of data, and each line dumps eight words. Dump counts must thus be multiples of eight.
503 Halt host first
This operation can't be performed while the computer clock is running.
504 Bus chatter
After halting the computer, the DFP checks the buses are idle. This is done as a sanity check before writing values that could cause bus contention. (or worse) This error message indicates that there was bus traffic after the processor was halted. This is a serious breach of bus protocol and should never happen.
505 Already halted
The halt instruction was issued or the STOP switch was actuated, but the computer is already halted. Nothing happened.
506 Already running
The run instruction was issued, or the RUN or START switches were actuated, but the computer was already running. In the case of the START switch. Nothing happened.
507 No processor
DFP diagnostics failed to find a processor on the bus. Early versions of the DFP allowed this (to test boards with the processor present), but the DFP became more and more dependent on a processor, and I started running out of Flash RAM space on the MCU, so the no-processor mode has gone away to comment-out-land and it is now an error to boot the DFP without a processor.
508 Syntax error
The last multi-argument command on the DFP console had one or more syntax errors.
509 Not implemented
Lazy programmer detected. Please replace with a more diligent programmer and try again. Also, have you tried turning it off and on again?
510 You talkin' to me?
An attempt was made to use the DFP from itself, either by making it address itself using the in or out commands, or by trying to be clever and using the front panel toggle switches. This could make the universe explode, and is generally frowned upon.

C3.6.1.6. Messages 900-999: Severe Operational Errors

901 Diagnostics failed.
Boot-time diagnostics of the DFP or computer have failed. The STOP light should be blinking slowly. The DFP will reboot and try again after eight seconds.
910 Value mismatch. Wrote HEX-VALUE, was HEX-VALUE.
An attempt was made to change a register, but the value of the register was not the one expected after this process.
920 ABUS error. Wrote HEX-VALUE, was HEX-VALUE.
The DFP drive the ABUS with one value, but read another one during sanity checking.
921 DBUS error. Wrote HEX-VALUE, was HEX-VALUE.
The DFP drive the DBUS with one value, but read another one during sanity checking.
922 AC mismatch. Wrote HEX-VALUE, was HEX-VALUE.
An attempt was made to set the AC, but the value of the register was not the one expected after this process. This indicates a possible fault in the Internal Bus (IBUS) or Control Bus signaling.
923 PC mismatch. Wrote HEX-VALUE, was HEX-VALUE.
An attempt was made to set the PC, but the value of the register was not the one expected after this process. This indicates a possible fault in the IBUS or Control Bus signaling.
924 IR mismatch. Wrote HEX-VALUE, was HEX-VALUE.
An attempt was made to set the IR, but the value of the register was not the one expected after this process. This indicates a possible fault in the IBUS or Control Bus signaling.
930 Timeout waiting for processor halt.
A processor halt was requested, but the processor didn't oblige in time, the selfish bastard.

C3.7. The Hardware

The DFP has more hardware than some Eighties home micros. It comes on:

  • A 6U Eurocard with connectors totalling 250 pins to connect to the front panel and another 200 pins to connect to the Processor Boards.
  • A 3U Eurocard with connectors to the CFT Processor Control Bus.
  • A Light Assembly made up of eight LED module boards mounted on a backplate.
  • A Switch Assembly mounted on the Light Assembly.
  • A Switch Break Out board that collects all the wires from the switches into a 50-pin header.

This implies that the DFP also has more ribbon cable than the average Eighties SCSI-1 server. Enough so that the whole thing had to be designed to simplify cable routing.

Plans, Plans

Now that I'm convinced the DFP board works well, and since (thanks to KiCAD) I can finally route and fabricate boards larger than 160×100 mm, I'm considering redoing the DFP on a proper PCB, with surface-mount components to keep the size down. I think I can fit it all. Especially if I also redo the front panel PCB to be a single board and multiplex enough signals to keep things simpler. This will let me use an MCU with more I/O pins, ditch the shift register chains, and make the DFP considerably faster, perhaps by a whole order of magnitude. But first, let's get the whole computer running nicely.

C3.7.1. Board 1

Board 1 is really the former (and never built) PFP controller, which was meant to collect front panel signals from the Processor Boards and drive the front panel with simple logic ICs. This worked well, but became obsolete when the DEB board died. The PFP-DEB merger brought in an MCU and shifted the logic from discrete chips to software, dropping the IC count by a lot. Unfortunately, the board estate needed by all the connectors stayed the same, so the board is 6U just to fit it all.

C3.7.2. Board 2

Board 2 is, in essence, a vestigial DEB board. It connects to the Control Bus and Expansion Bus and hosts logic to drive the IBUS, Address Bus and Data Bus (DBUS).

C3.7.3. The Light Assembly

The Front Panel Light Assembly is an overly complicated construction housing all of the front panel's LEDs. It is made up of a backplate on which are mounted eight identical single-sided Printed Circuit Boards. Each module contains five rows of four LEDs each. Each row connects to a five-pin header with one drive signal for each LED plus a common ground. The complexity is a workaround for three issues:

  • Manufacturing a single copy of a board the size of the front panel would be very expensive. Most PCB fabrication houses will happily provide a small run of multiple copies of the same, smaller board and the repeating pattern of the front panel makes it easy to modularise.

  • The hobbyist version of CadSoft EAGLE cannot lay out a board the size of the entire light assembly.

  • The 40 five pin headers were a more cost effective option than fewer, larger connectors.

The constructed front panel modules have surface mount components on the bottom (front-facing) side, and through-hole headers on the top (rear-facing side). All the LED and resistor positions are populated, which allows for the front panel to be easily reconfigured, within reason.

The five pin headers connect to board 1 of the DFP via four 50-way ribbon cables. These cables are terminated with 50-pin plugs on the DFP side and branch out to ten 5-pin plugs on the front panel side. Each 50-pin cable addresses all four rows across two modules.

Each group of four LEDs has its own common ground which may be configured by the DFP to either honour or ignore the Lights off switch, and also to allow for the relatively high total current with using relatively thin wires. (between 0.8 and 1.3 A).

Each module has four separate ground planes, one for each row, each connected to the corresponding common ground. For better isolation characteristics, there are pads on either side of each module to allow these ground planes to be connected across modules. This will probably not happen on the assembled CFT because it reduces the ease of reconfiguring LEDs.

All the LEDs are white, bright units. The front panel fascia will have coloured gels glued on the inside to colourise the LEDs appropriately (and to diffuse the light). This makes reconfiguration a lot simpler, and it also keeps the relative brightness of differently coloured LEDs more even.

Front Panel cross-section

Cross-section of the entire front panel showing its various parts. This isn't entirely up to date, but gives you an idea of how it's meant to come together.

Front panel Light Assembly, front

Engineering rendering of the front panel light assembly showing how the eight modules mount on the backplate. Visible on each module are 20 LEDs and four mounting screws. The resistors are not modelled. The front panel fascia fits on the longer hex spacers around the assembly. The shorter ones along the long slot keep the switch assembly (not pictured) close enough to the openings on the fascia for the switches to be easily operable.

Front panel Light Assembly, rear

Engineering rendering of the front panel light assembly (rear view) showing how the eight modules mount on the backplate and how the connectors are arranged.

C3.7.4. The Switch Assembly

The front panel switches are mounted on the switch assembly, and wired point-to-point to a quick-and-dirty Veroboard break-out board mounted in the back of the front panel assembly. The break-out board connects those cables to a 50-pin IDC ribbon cable socket, which in turn connects the assembly to Board 1. To save on wiring, all necessary diodes are soldered directly on the switches.

The two lock switches mount directly on the front panel fascia but are still wired to the break-out board.

Switches share a common ground. Before the DFP design acquired a microcontroller, panel lock-out (via the panel lock key switch) was completely hardwired, done by isolating the common ground of certain switch groups. For that reason, there are still multiple ground wires connecting the DFP board to the switch assembly. In the implemented version of the DFP, these are all permanently connected to ground, and panel lock-out is implemented in the DFP firmware instead.

Rendering of the front side of the switch assembly.

Engineering rendering of the front size of the switch assembly. The switch assembly is spaced from the panel assembly to align the switch paddles with the openings on the front panel fascia. The gap along the bottom of the panel backplate is clearance for the two key switches.

Rendering of the rear of the switch assembly.

Engineering rendering of the front panel light assembly (rear view). This shows the location of the switch wiring breakout board, near the right edge (left edge from the operator's perspective), with a 50-pin connector to DFP Board 1.

Schematic of the front panel switch assembly.

Figure 32. Schematic of the front panel switch assembly. The strange style represents the way wires are physically laid out between switches.

C3.8. Theory of Operation

Since I designed and built the DFP using chips I already had in stock, the design is really convoluted so hundreds of input signals can be stuffed into a 28-pin Atmega MCU, and to provide safety interlocks for as many of those signals as possible. Prepare for untold horrors. There will also be weird little hacks.

Also, I promise: no more Radiohead references.

C3.8.1. CFT Bus Interface

For the DFP to be usable from the CFT, it needs to implement the bus interface for I/O space read and write transactions. This is tricky, because the MCU is far too slow and (since it contains a microprocessor) its timings are far too inconsistent to stay within the tight time limits of a CFT bus transaction. To resolve this issue, an ‘autonomic’ system built out of discrete logic implements the bus interface.

A simple state machine is used to interrupt the MCU when the CFT processor is addressing it via the CFT bus. A 74HC138 decoder is responsible for address decoding. The decoder enables when the bus signal IODEV1XX is asserted, i.e. when an I/O space address in the range 0100-01FF is seen. When enabled, the decoder decodes lines AB5–7 to generate an active-low enable when the Address Bus holds a value in the range 0100-011F. This is a complete decoding, since the DFP will react to all 32 addresses—however, some of these addresses perform no task (yet).

The enable signal is named PFP-SEL (a misnomer from the days when the DFP was still the Programmer's Front Panel controller, PFP). The falling edge of the enable signal clocks half of a 74HC112 J-K flip flop, configured as a falling edge detector: J is tied to Vcc, K is tied to Ground, and Q feeds back to the flip-flop's CLR reset input. When PFP-SELgoes low, the flip-flop is clocked, and Q transitions to low. The low state immediately resets the flip flop, and Q transitions to high again, generating a brief pulse on IOCMD.

In turn, IOCMD is connected to the MCU's INT0 interrupt pin, which is configured to interrupt the firmware on a negative edge. This lets the firmware know that the CFT has selected it for an I/O operation. The DFP will stop its normal operation and act according to the address and data bus.

Finally, the same strobe is connected to the 74HC112's second J-K flip flop's PREpin. This asynchronously and immediately sets the flip flop. Its active-low Q output is fed through a diode (forming a poor man's open collector output) and fed to the CFT bus signal WS. This triggers a Wait State as soon as the DFP is selected for I/O. The flip-flop has its J input tied to Ground, and the K input tied to Vcc. The clock input is connected directly to the MCU's CLR-WS output. Its interrupt handler routine will send a short positive strobe when it has finished sampling the CFT bus (or writing to it), removing the Wait State and letting the processor proceed normally.

Depending on how the flip flop powers up, there may be a spurious interrupt pulse when power is first applied to the DFP, but the MCU is configured to wait a relatively long time for the CFT's circuitry to stabilise before coming out of reset. After that, it goes through self-diagnostics for a few seconds. So, any early pulses will be ignored before interrupts are enabled on the MCU.
Timing diagram of a bus transaction addressing the DFP.

Timing diagram of a DFP bus transaction. When the CFT selects the DFP for I/O, a Wait State is generated and the DFP MCU is interrupted to service the transaction. Once this is done, the MCU strobes the CLR-WS signal, clearing the Wait State and letting the processor carry on.

The Expansion Bus Interface and MCU.

Figure 33. CFT Expansion Bus interface (rows A and B) and MCU.

C3.8.2. Driving the Data Bus

Reading from the Data Bus during bus transactions is fairly easy. Writing to it is another story altogether. Even with ‘autonomic’ Wait State assertion at the start of a bus cycle addressing the DFP, we can't trust the MCU to drive the Data Bus itself. It is obviously very difficult to predict the latency when the MCU reacts to an interrupt. Letting the MCU drive the DBUS directly would result in the bus driven later than we wanted, and this could cause bus contention if the bus is still driven after the end of the bus transaction.

The solution to this is another ‘autonomic’ system. The Data Bus is driven automatically during an I/O read cycle. The DB-OE signal from the MCU is allowed to override this to drive the Data Bus programmatically for diagnostics, panel operations, et cetera when the computer is halted. This can only be done safely when the processor is halted and the bus isn't in use. This is why most of the DFP's programming and debugging functions can only be performed with the processor halted.

When the CFT reads from the DFP, the driver automatically starts driving the Data Bus (DBUS), likely before the correct value has been put on the bus by the DFP. This is acceptable behaviour during a Wait State. This ends automatically when the bus transaction has ended. A Wait State has been asserted, so the end of the transaction will happen at the end of the processor cycle after the DFP is done with its work and deasserted the Wait State. But even if a Wait State hasn't been asserted (e.g. due to a fault), this circuit will disable the bus drivers automatically, protecting the bus.

This happens quite simply, using a complex gate to enable the Data Bus drivers. The DBUS enable signal, DB-OE-COMBINED, is a function of the CFT Bus R input, the DFP being selected for I/O (PFP-SEL asserted) and the MCU's override signal DB-OE:

DB-OERPFP-SELDB-OE-COMBINEDNotes
XX00MCU accessing the DBUS.
0010CFT reading from the DFP.
0111DFP selected, but not a read cycle (yet).
1011Read cycle, DFP not selected.
1111DFP not selected or bus idle.

This truth table is encoded using a 74HC251 1-of-8 multiplexer configured as an arbitrary, 3-input gate. The non-inverted output drives the OE signals of the Data Bus parallel out shift registers, driving the DBUS. Here's how this is implemented:

Data Bus Driver

Figure 34. ‘Autonomic’ Data Bus driver (IC26 and IC27, column 3) and its decoder, IC1 (location D2).

C3.8.3. How the DFP Performs I/O

The DFP's input/output needs are prodigious, extravagant, gargantuan, and other words I clearly looked up in a thesaurus. It (the DFP, not the thesaurus) needs access to many more signals than the MCU's pin count. The original DEB board used three expensive but temperamental I²C16-bit GPIO devices to provide 48 bits of programmable I/O. I thought that was a lot, but the DFP has hundreds of inputs and outputs. It interfaces those signals to the MCU in a much more robust way than the GPIO chips (but that's not saying a lot, as they were a bad choice). It also does it cheaper, faster and more reliably. Also in a very convoluted way. Or (literally) three:

  • Direct I/O by the MCU. This is used where speed or accuracy are of the essence, where MCU-specific features are required, as well as to communicate with the other two I/O mechanisms.

  • Output via 74HC259 addressable latches, the Command Latches. Two such units are used for a maximum of 16 output-only signals. All are used where relatively fast response times are required. Some outputs are combined with diodes to make them equivalent to open drain signals and take away the speed advantage. (these signals can ramp down slowly when deasserted)

  • Serial I/O via several chains of cascaded 8-bit shift registers. 74HC165 parallel in, serial out devices are used for input, and 74HC595 serial in, parallel out devices for output. These provide significantly slower I/O than parallel I/O, but allow for 248 bits of I/O using a total of 31 devices on both boards of the DFP. Most of the chip count of the DFP is due to these shift registers. Shift registers are the slowest devices used by the DFP, but are still faster than the GPIO devices used by the DEB.

There are two shift register chains used for input:

  • The Debugging Input chain: is 80 bits long. It is used to read the state of the front panel's switches, as well as the Address Bus and DBUS. The chain is split across DFP Boards 1 and 2, with the switches sampled by Board 1 and buses by Board 2.

  • The Virtual Front Panel Input chain: is also 80 bits long and used to read the state of the AC, PC, IR and microcode vector from the CFT's processor boards. These drive front panel LEDs directly, but are also read by the DFP for automated testing.

An additional five shift register chains are used for output:

  • The Output Register chain: is 16 bits long and drives the MFD on the front panel when the MFD switch is the ‘OR’ position.

  • The Address Bus chain: is 16 bits long and drives the Address Bus. An additional 8 bits were considered to drive the AEXT0–7 for access to the full 21-bit address space, but this was not implemented.

  • The DBUS chain: is 16 bits long and drives the Data Bus.

  • The IBUS chain: is 16 bits long and drives the IBUS.

  • The Control chain: is 24 bits long, split between Board 1 and 2, and drives a range of control signals.

The chains are split up to enhance sampling speed. Input chains have their most often used signals near the beginning of the chain so they can be sampled first. Output chains are kept at a minimum length and split by register.

C3.8.3.1. Direct I/O

A number of features are controlled directly by the MCU:

C3.8.3.1.1. Serial Terminal I/O

The MCU's internal UART is used for interaction between the DFP and a human or controlling computer. The only pins used for this are the TXD and RXD pins, so no hardware flow control is available. The implemented DFP provides a 6-pin header for an FTDI USB to 5V TTL serial cable, which allows the DFP's serial port to be connected to a remote computer over USB. This also makes very high serial bit rates possible without hardware flow control.

To provide accurate RS-232 timings, the MCU is clocked using a 14.7456 MHz crystal. The UARTdivides this by 16, which allows a maximum 921,600 bps rate. The DFP firmware then derates this to half the speed, running the serial port at 460800 bps which works very reliably over USB.

C3.8.3.1.2. Bus Enables

The three CFT buses (Address Bus, DBUS and IBUS) require careful timing and full control. To make this less prone to software bugs and hardware failures, the MCU can tristate the bus drivers directly. The three signals are AB-OE, DB-OE and IBUS-OE, respectively connected to MCU pins PD3, PD4 and PD5.

C3.8.3.1.3. Clock Generation and Control

The CFT processor includes a built-in clock generator running at 16 MHz, and divided by four to generate a four-phase clock. To slow down the computer, the DFP disables the processor's clock by driving FPCLKEN low and then pulses the FPUSTEP signal at the appropriate rate. Since the timing of these signals is critical, they are controlled directly by the MCU. The MCU's built-in timer on pin OC1B is used to generate regular square waves at the desired frequency.

C3.8.3.2. Command Outputs

Two 74HC259 addressable 8-bit latches provide 16 output lines that can be individually set or cleared by the MCU. There are three address lines and a data line shared between both command output chips and one active low chip enable line each, for a total of six MCU-controlled signals.

The first 74HC259 is on Board 1 and is selected when CMD0 is low (asserted).

CMD0CMD1IOADDRAction when COUT = 1
11XXXNo change to outputs.
01000Assert SAMPLE.
01001Assert VPEN.
01010Assert DBEN.
01011Not assigned.
01100Assert CLR, resetting command latches.
01101Run mode if COUT = 1, Step mode otherwise.
01110Assert USTEP.
01111ORCLK set to COUT (non-inverted).
10000DBCLK set to COUT (non-inverted).
10001ABCLK set to COUT (non-inverted).
10010IBUSCLK set to COUT (non-inverted).
10011CTLCLK set to COUT (non-inverted).
10100Not assigned.
10101STCP set to COUT (non-inverted).
10110Not assigned.
10111Activate bus pull-ups. (not currently used).

To ensure no glitches, the algorithm for setting a command output is:

  1. Deassert CMD0 and CMD1.
  2. Set COUT to desired value.
  3. Set IOADDR to address of required signal.
  4. Assert CMD0 or CMD1 depending on signal. (never both)
  5. Deassert CMD0 and CMD1.

This securely sets an output to the specified value even if some signals have been left in an unknown state from another process.

Here's a brief explanation of what these output signals do:

SAMPLE
causes all input shift registers to sample their inputs, resetting the shift process. This is done before reading from any shift register chain.
VPEN
enable the Virtual Front Panel input chain for reading. This reads the values of the AC, PC, IR, the Microcode Control Vector, and some flags and miscellaneous signals output by the processor via the Front Panel connector. The same signals are directly connected to the Front Panel lights, hence Virtual Front Panel.
DBEN
enable the Debugging input chain for reading. This samples the Expansion and Control Buses, reads from the Address Bus, DBUS, IBUS and some other signals.
CLR
generates a reset pulse. When command latch address 100 set to 1, CLR goes low. (is asserted) This feeds back to the CLR pin on both command latches, resetting all sixteen of their outputs to 0. This deasserts CLR too, and restores the latches to normal functionality.
USTEP
signals the Run Control State Machine to advance the Control Unit by a single microstep, i.e. perform a single processor cycle.
ORCLK
clocks serial data into the OR.
DBCLK
clocks serial data into the DBUS output registers on Board 2.
ABCLK
clocks serial data into the Address Bus output registers on Board 2.
IBUSCLK
clocks serial data into the IBUS output registers on Board 2.
CTLCLK
clocks serial data into Control Bus output registers on Board 2. This can control internal units of the processor to e.g. load a value into the AC.
STCP
causes all output shift registers to copy the values shifted into them to their outputs. This makes sure all changes are nearly synchronous. (there's also clock skew, and the fact that not all output register chips will have the exact same timings, but it's close enough for our purposes)
BUSPU
was meant to activate bus pull-ups on most buses. Without the processor boards which add bus conditioning, bus holding and termination, transmission line effects would make it very hard to operate peripherals in Standalone mode. This signal is still there, and some components for it are still available on Board 2, but it was never actually used in the end since I abandoned Standalone mode entirely.

C3.8.3.3. Input Shift Registers

There are two shift register chains used for input.

The Debugging Input chain: is 80 bits long. It is used to read the state of the front panel's switches, as well as the Address Bus and DBUS. The chain is split across DFP Boards 1 and 2, with the switches sampled by Board 1 and buses by Board 2.

This looks complicated, but the theory is simple: ten 74HC165 chips each handle up to eight bits of input. Each line is meant to be pulled up to avoid issues with CMOS inputs. In practice, to simplify construction, half the bits are pulled up and the other half are pulled down. This isn't represented in the schematics, but since CMOS inputs are symmetric, pulling up or down has the same effect. Also, the characteristic 00001111 pattern makes diagnostics easier.

Each 74HC165 chip is daisy-chained to the next. Their sample, enable and shift clocks are controlled by the MCU. The chain is arranged so that the signals that need to be read faster are located nearer the ‘front’ of the shift chain. So, to read just the Address Bus and DBUS, the shift register only needs to clock in the first 32 bits, rather than the whole 80. The sequence may be reset at will by strobing the chips' PL inputs, which are connected to the SAMPLEcommand output.

The last IC in a chain normally has its cascade input tied to Vcc or Ground. The DEB does something different: it connects it to IOADDR0. This cascade input is sampled whenever the shift register chain's output is clocked, and shifts all 80 bits towards the MCU's input, one by one. Normally, the MCU clocks in up to 80 bits. In early diagnostics, it sets IOADDR0 to either 0 or 1 and clocks in 81 bits. The last bit read should match the value of IOADDR0. If it does, this is an indication that the shift chain is working fully, including the cascade out from Board 1 to Board 2, and the shift out back from Board 2 to the MCU on Board 1. If this test passes, it's a very good indication that all 10 chips and their connections are sane and healthy. If not, well, the logic analyser, oscilloscope and ohm meter are about to get a thorough workout.

The input chain shifts in the following, in order of first-read to last-read:

BitsSignalNotes
0–15ABFrom AB15 to AB0. This is on Board 2.
16–31DBFrom DB15 to DB0. This is also on Board 2.
32–35DIP Switch 2DSW11 to DSW8, the upper 4 bits of the DIP switch bank.
36SWIFR1The state of the IFR1 switch on the front panel.
37SWIFR6The state of the IFR6 switch on the front panel.
38SWRAMThe state of the RAM BNK switch on the front panel.
39SWIORLow if the I/O R or I/O R NEXT switches are activated.
40SWIOWLow if the I/O W or I/O W NEXT switches are activated.
41SWMEMRLow if the MEM R or MEM R NEXT switches are activated.
42SWINCLow if any of the MEM R NEXT, MEM W NEXT, I/O R NEXT or I/O W NEXT switches are activated.
43SWMEMWLow if the MEM W or MEM W NEXT switches are activated.
44SWSPARELow if the ‘spare’ momentary switch position of the SR → AC switch.
45SWLDACLow if the SR → AC switch is actuated.
46SWLDIRLow if the SR → IR switch is actuated.
47SWLDADDRLow if the SR → PC switch is actuated.
48–63SRFrom SR15 to SR0. This reads all 16 sense/data switches that form the Switch Register.
64–71DIP Switch 1The lower eight bits of the DIP switch bank): DSW7 to DSW0.
72SWFASTHalf of the encoding the position of the Fast/Slow/Creep switch.
73SWSLOWThe other half of the encoding the position of the Fast/Slow/Creep switch.
74SWUSTEPLow if the µSTEP switch is actuated.
75SWSTEPLow if the STEP switch is actuated.
76SWRUNLow if either the RUN or START switch is actuated.
77SWSTOPLow if the STOP switch is actuated.
78SWRESETLow if either the RESET or START switch is actuated.
79SWLOCKLow if the panel is unlocked.
Part one of the Virtual Front Panel.

Figure 35. Part one of the Virtual Front Panel input shift register chain.

Part two of the Virtual Front Panel.

Figure 36. Continuation of the debugging shift register chain.

The other input chain is the Virtual Front Panel Input chain. Like the Debugging one, this one is also 80 bits long and used to read the state of the AC, PC, IR and microcode vector from the CFT's processor boards. These drive front panel LEDs directly, but are also read by the DFP for automated testing.

The design of this input chain is identical to the Virtual Front Panel Input chain, including the diagnostic use of IOADDR0.

The input chain shifts in the following, in order of first-read to last-read. Please note that the R and WEN signals have been moved from their proper position in the Microcode Control Vector field, so they can be the first two bits to be read. They're also not inverted, unlike other signals. Both of these choices were made to make I/O transaction processing faster. Moving them to the beginning of the input chain saves many precious microseconds of CFT Wait States per transaction. Sampling them before they're inverted saves a few nanoseconds, but we might as well do that too, right? By the way, the inversion happens so that the Microcode Control Vector (µCV) can be displayed on the top row of lights of the front panel in an intuitive way: the END light will be on when END is asserted.

BitsSignalNotes
0RMicrocode Control Vector, Read.
1WENMicrocode Control Vector, Write.
2WAITWhen low, the DEB has been addressed. A Wait State is active.
3LState of Link Register (L).
4FIRQInverted version of IRQS from the Expansion Bus.
5FVOverflow flag.
6FZEROZero flag.
7FNEGNegative flag.
8ENDInverted version of END from the µCV.
9Not used
10Not used
11MEMInverted version of MEM from the µCV.
12IOInverted version of IO from the µCV.
13DECInverted version of DEC from the µCV.
14STPACInverted version of STPAC from the µCV.
15STPDRInverted version of STPDR from the µCV.
16INCPCInverted version of INCPC from the µCV.
17CLIInverted version of CLI from the µCV.
18STIInverted version of STI from the µCV.
19CLLInverted version of CLL from the µCV.
20CPLInverted version of CPL from the µCV.
21–24OPIFOPIF3 to OPIF0.
25-27WUNITWUNIT2 to WUNIT0.
28-31RUNITRUNIT3 to RUNIT0.
32-47IRThe IR, IR15 to IR0.
48-63PCThe PC, PC15 to PC0.
64-79ACThe AC, AC15 to AC0.
Propagation Delays and Other Evils
These signals are sourced from the front panel connections of the Processor Boards. They are buffered (and in some cases inverted) on their respective boards to make them ready to drive front panel lights directly. The lights are LEDs, and 5 mA is enough. The buffers were chosen for their ability to source that much current. This implies that there'll be propagation delays. Human eyes have a very low sampling rate, so this is fine for us meat sacks. Not so for other circuitry, so these signals are never used for decision making! The R and WEN signals are an exception, but they're sampled microseconds after their assertions. Propagation delays of even dozens of nanoseconds won't matter there.
Schematic of the Debugging Input Chain

Figure 37. The debugging input chain.

C3.8.3.4. Output Shift Registers

There are five output chains.

  • The OR chain writes values to the 16-bit OR.
  • The DBUS chain writes values to the DBUS. This is controlled by combinational logic as described in section Driving the Data Bus, to implement fast bus transactions. It can be overridden by the DFP for debugging purposes.
  • The Address Bus chain writes 16-bit values to the Address Bus. This has an optional 8-bit extension to also drive the AEXT address extension bus. This wasn't implemented since the processor now has the MBU extension built-in.
  • The IBUS chain writes 16-bit values to the IBUS.
  • The Control chain is 24 bits long, and drives a number of control signals. Some of them are open drain outputs, and we cheat by using diodes. Yes, this makes the signals slower, but the DFP is much slower than that anyway.

All chains share a single serial-in pin, controlled by signal DOUT. To write to a particular register, the MCU sets DOUT and strobes the serial in clock for that particular chain. When all bits have been loaded, it strobes the STCP signal copying the shifted value to the outputs. This signal is shared among all output chains, so changes will happen mostly synchronously.

The 24-bit control chain is split between the two DFP boards and controls the following signals:

BitBoardSignalNotes
0Board 2IRQ1Open drain output to the Expansion Bus.
1Board 2IRQ6 or IRQJumper selectable. Open drain output to the Expansion Bus.
2Board 2INCPCOpen drain output to the Expansion Bus.
3Board 2WACOpen drain output to the Control Bus.
4Board 2RPCOpen drain output to the Control Bus.
5Board 2WAROpen drain output to the Control Bus.
6Board 2WIROpen drain output to the Control Bus.
7Board 2WPCOpen drain output to the Control Bus.
8Board 1SAFEOpen drain. Low to enable the programming switches.
9Board 1RESETOpen drain output. Resets the computer.
10Board 1RSTHOLDOpen drain output. Formerly used in Standalone Mode.
11Board 1SpareNot used.
12Board 1SpareNot used.
13Board 1WENOpen drain to the Control Bus. Requests write transactions.
14Board 1FPRAMOutput to the MBU: state of the RAM BNK/ROM BNK switch.
15Board 1FPRESETOutput to Processor Board 0, reset requested via the front panel switches.
16Board 1SpareNot used.
17Board 1HALTOpen drain output to the Expansion Bus.
18Board 1WTotem pole output to the Expansion Bus. Formerly used in Standalone Mode.
19Board 1RTotem pole output to the Expansion Bus.
20Board 1MEMTotem pole output to the Expansion Bus
21Board 1IOTotem pole output to the Expansion Bus
22Board 1FPRUNControls the Run light on the front panel.
23Board 1FPSTOPControls the Stop light on the front panel.

Some notes about the less than obvious signals:

SAFE
This signal is low when the computer is halted and the DFP is idle, waiting for a command. It's at high impedance at all other times. SAFE directly controls power to the programming switches on the front panel. It's a remnant of the PFP sub-project, when the front panel controller was built out of discrete logic and a safety lock-out was needed so the programming switches couldn't mess up the computer when it was running. The lock-out is implemented in the DFP's firmware now, but the wiring is still there.
FPRUN
Controls the ‘RUN’ light on the front panel.
FPSTOP
Controls the ‘STOP’ light on the front panel. This light is on when the Run Control State Machine has halted the computer. The DFP also blinks it slowly when its power-on self-tests or early CFT diagnostics fail.
Caution: Open Drain drivers, Totem Pole signals!
Note that the open drain outputs to the Control Bus drive signals that aren't meant to be open drain! As a result, the processor must be halted and its own control bus outputs at high impedance before these can be asserted. There is no safety interlock here, the firmware just makes sure this is the case programmatically.
Out of Date Schematics!
The schematics are slightly out of date about the actual layout of the control signals. The firmware and the table above seem to be more correct. To do: check the implementation of the board (including diodes) and update the schematics.
Schematic of the output shift registers on Board 1.

Figure 38. Output shift registers on Board 1.

Schematic of the output shift registers on Board 2.

Figure 39. Output shift registers on Board 2.

C3.8.4. The Run Control State Machine

The Run Control State Machine allows the processor to be smoothly and safely moved from the running state to the stopped state, and also to perform single steps through whole instructions, as well as single microsteps. The state machine is implemented using flip flops to ensure accurate timing, with the MCU only initiating some state changes.

With some magic and combinational logic, we get three flip-flops to implement a state machine with six states and eleven transitions. Some states and transitions are controlled directly by the MCU. Others, the more time-critical ones, are just requested by it, and the state machines takes care of them.

The state machine comprises two 74HC74 dual positive triggered flip flops with asynchronous set and reset circuitry and complementary outputs. Three of the four flip flop devices are used. The flip flops represent three of the machine's states: resetting, stepping, and microstepping. The states are entered asynchronously by suitable pulses on the Preset pins. Synchronous conditions (derived from predictable clock inputs) terminate the respective processes and move to a new state.

All flip-flops are wired to reset to clear outputs when the CLR signal is asserted, so the MCU can reset the state machine to a sane state at power on or during a hard MCUreset.

These three states are used with a 74HC253 configured as a dual 2-input gate with tri-state support. It outputs the FPCLKEN clock enable signal and FPUSTEP clock to the clock generator on Processor Board 1. These signals work like this:

The 74HC253 is configured for this truth table:

RESETTINGSTEPPINGUSTEPPINGFPCLKENFPUSTEPNotes
1XXZZHigh impedance. Resetting.
00000Computer halted.
0011XMicrostepping at full speed.
0010Square waveMicrostepping at custom speed.
00100Never happens (MCU firmware).
00101Never happens (MCU firmware).
0101XStepping at full speed.
0100Square waveStepping at custom speed.
01000Never happens (MCU firmware).
01001Never happens (MCU firmware).
011XXNever happens (MCU firmware).

During reset, the 74HC253 stops driving FPCLKEN and FPUSTEP. They go to a high-impedance state. The processor's clock generator pulls FPCLKEN up so it can still run if the front panel is disconnected. This has the effect that resets always happen at the full speed of the processor. This is necessary, because the reset sequencer holds RSTHOLD active for 8 to 128 4 MHz periods—up to 32 μs normally. With a slow clock (and remember, the MCU can slow the clock a lot), this process could take minutes to complete. Worse yet, if the processor clock were stopped entirely, the process would never complete. The reset sequencer can't count clock cycles that aren't happening.

Some of the state transitions are handled by the MCU, and it implements most of the interlocks. For instance, it's impossible to be stepping while resetting or microstepping. The state machine implements a mechanism where the MCU can request a particular time-critical state, and the state machine will perform it, and notify the MCUwhen it's done. (technically, the MCU polls the state machine's WAIT output).

The one exception to this is the reset, signal: this one is triggered whenever the Expansion Bus signal RESET is asserted. The MCU can assert this directly, but any device on the bus can too. Regardless, the state machine will tri-state its outputs and let the reset sequence complete at full speed. The MCU will be unaware of this because it doesn't monitor this signal.

Well, this is unfortunate, isn't it?
It'd be nice if we could monitor resets by other devices too, but the poor Atmega8 is already stretched to its limits. If I ever have enough of this Byzantine rat's nest and design a better DEB board, it's getting a much larger Atmega chip with tons of I/O and getting simplified lots.

So here's the state transition diagram for the whole thing. It's a little bit more complicated than a toggle switch.

Transition diagram of the Run Control state machine

The Run Control state machine. This state machine controls how and when the processor clock is enabled and disabled depending on its state. 1 In the resetting state, the clock always runs at full speed. 2 In these states, the clock runs at the currently selected speed. 3 ROM mode is selected when the RAM BNK/ROM BNK switch is in the ROM BNK position. 4 RAM mode is selected when the RAM BNK/ROM BNK switch is in the RAM BNKposition. 5 Reset is requested via the DFP console or Reset switch. 6 There are a number of ways to request a machine halt, including a DFP Console command, the RUN/STOP switch and various CFT instructions. 7 Requested via the DFP console or Step switch. 8 Requested via the DFP console or the Microstep switch.

Schematic of the Run Control State machine

Figure 40. Fetch/execute decoder, Run Control State Machine.

C3.8.4.1. Resetting

This is the initial state, using a D flip-flop with its D input tied to ground and its CLR input tied to Vcc to deassert it permanently.

RESET is connected to the flip flop's PRE signal. While RESET is asserted, the flip-flop's Q positive output deasserts the 74HC253's output enables and the flip-flop ignores every other input. WAIT (on the flip-flop's Q output) is asserted to let the MCU know an unstable state has been entered.

Both FPCLKEN and FPUSTEP go to high impedance.

Many clock cycles after RESET is no longer asserted, the processor's reset mechanism deasserts RSTHOLD. The positive edge clocks in a 0 into the flip flop. The 74HC253 starts driving and WAIT deasserts.

At that point, the MCU (which will have been waiting for that exact condition) decides whether to enter the Running or Stopped states:

  • If the bank switch on the front panel is in the RAM BNK position, the computer is in ancient minicomputer mode, and starts halted. There's no ROM to run anyway!
  • If the switch is in the ROM BNK, the computer starts running.

This decision is made by the DFP firmware rather than in hardware.

C3.8.4.2. Running

In FAST mode, running allows the processor to run at its normal clock. In SLOW, CREEP or a custom speed set on the DFP console, the processor clock is off and the DFP outputs an appropriate square wave on FPUSTEP.

This is implemented using both a flip flop and the 74HC253.

To run the processor, the MCU drives its STEP/RUN signal low. This is connected to the flip-flop's PRE preset signal. The flip-flop asserts its active-high STEPPING output, which causes the 74HC253 to give run control to the MCU. The MCUmakes a speed decision at that point:

  • For full speed, it asserts its FPCLKEN-IN signal.
  • For anything else, it deasserts its FPCLKEN-IN signal and sets up a hardware timer to strobe FPUSTEP-IN.

This condition will assert WAIT, but the DFP doesn't care about its when the processor is running.

To leave running mode, the MCU drives the STEP/RUN signal high. The state machine enters the Stepping state, and continues to run until the end of the next instruction fetch.

C3.8.4.3. Stepping

Stepping is accomplished using the same flip-flop as the Running state. The MCU sends a very short negative edge on the STEP/RUN signal. Anything longer than the minimum reset pulse for the flip-flop (guaranteed to be the case because the MCU is so much slower) and shorter than a processor cycle at the current speed will do.

As soon as this is done, the state machine enters the Running state. When the strobe ends, it goes straight back to the Stopping state.

To stop, we wait for the end of the next fetch cycle. The CFT doesn't treat fetch and execute differently, so the only way to detect this is to decode the Microcode Address. We compare the 4-bit microprogram counter UPC against a preset value:

Microcode VersionsFetch cycle length
Versions 1–33 processor cycles.
Versions 4 onwards2 processor cycles.

An 74HC85 comparator is used to compare the UPC to this preset value (on jumpers or DIP switches). It outputs separate signals for less-than, equal or greater-than conditions. When UPC < 2 (for modern Microcode versions), FPFETCH is high. When UPC ≥ 2, FPEXEC is high (this is done by a wired OR circuit). These signals also drive the FETCH and EXEC lights on the front panel.

The (faster; no diodes!) FPFETCH signal is also fed to the clock input of the flip-flop. Its positive edge will clock in a hardwired 0 and clear the outputs. The 74HC253 will disable the processor's clock immediately, and clear the WAIT signal to the DFP which will know the process is done.

The DFP samples the WAIT input and waits until it's high. If this takes too long, a timeout fault is logged: this is a severe hardware fault and causes the computer to stop (if it can!) and the DFP to reset.

Why stop here?
The end of the fetch cycle is harder to stop at than, say, the beginning of a processor cycle. The upside of doing it this way is that the IRwill reflect the instruction about to be executed, and the PC the address of the next instruction to be executed. This is the somewhat arbitrary point in a processor's operation human programmers consider the ‘start’ of an instruction and is more intuitive to work with.

C3.8.4.4. Stopping

Stopping is essentially the same as stepping, except we're coming from a Running state rather than a Stopped state. To stop the running processor, The MCU drives STEP/RUN high. The Stepping circuitry takes control, and the processor stops at the end of the next fetch cycle.

When stopping is requested, the DFP samples the WAIT input and waits until it's high. If this takes too long, a timeout fault is logged: this is a severe hardware fault and causes the computer to stop (if it can!) and the DFP to reset.

C3.8.4.5. Microstepping

This is similar to stepping. In fact, it works the same way and has the same effects and side-effects, except the MCU keeps STEP/RUN high and drives low USTEP. This sets the microstepping flip flop and enters the Microstepping state. The state is left on the next positive edge of CLK4, which signals the end of a processor cycle. At this point, the state machine is back at the Stopped state.

Again, when stepping is requested, the DFP samples the WAIT input and waits until it's high. If this takes too long, a timeout fault is logged: this is a severe hardware fault and causes the computer to stop (if it can!) and the DFP to reset.

C3.8.4.6. Stopped

This is what happens when all three flip-flops are left to reset to their idle states. The 74HC253 disables the processor clock, WAIT is deasserted. The DFP firmware will assert HALT to put the CFT processor ‘in neutral’, with the Control Unit's outputs and buses in high impedance mode. In this state, the DFP is free to examine and manipulate the computer's state.

C3.8.5. MFD Buffers and Decoder

The MDF row displays one of three values on the front panel. The selection is made using the MFD switch. To keep costs down, a single-pole, double-through (ON-OFF-ON) toggle switch is used for the MFD. The switch connects to ground in the on positions and is pulled high in the off positions. This way, it provides a two-bit truth-table as follows:

Switch PositionMeaningSWMFD0–1
UpOR10
MiddleDR11
DownMicrocode Address Vector (µADDR)10

The SWMFD0–1 vector is decoded using a 74HC138 decoder configured as a permanently enabled 2-to-4 decoder where one output is unused. The mutually exclusive outputs drive the enables of three pairs of 8-bit devices:

  • The OR, a pair of 74HC595 8-bit shift registers.

  • The DR buffers, a pair of 74HC541 8-bit buffers.

  • The µADDR buffers, a pair of 74HC541 8-bit buffers. These ones have the most-significant bit permanently tied to ground to keep the corresponding light off, since this is a 15-bit quantity.

The 74HC138 ensures at most one pair is enabled. When a pair of devices is disabled, the outputs are in a high impedance state. This allows the three outputs for each bit to be wired together and connected directly to the 16 LEDs on the front panel.

Schematic of the MFD.

Figure 41. Schematic of the Multi-Function Display.

C3.8.6. Connectors

There are so many connectors!

  • Four 50-pin IDC ribbon connectors connect to the front panel lights. There separate into a wiring loom with 10 5-pin connectors each. Each connector drives all five rows of two front panel modules. This harness connects to all lights, including unused ones. And let me tell you, crimping 200 pins individually wasn't fun.
  • One 50-pin IDC ribbon connector for the Switch Assembly.
  • One 40-pin connector to connect Board 1 to Board 2. Two, really, since there's one on each board.
  • One 40-pin connector to the front panel connector on Processor Board 0.
  • One 40-pin connector to the front panel connector on Processor Board 1.
  • Two 40-pin connectors to the front panel connectors on Processor Board 2.
  • One 20-pin connector to the MBU on Processor Board 3. This hasn't been wired yet.
  • A two-pin header to connect to a mundane ATX PSU for power on and power good signals.
  • A five-pin connector for FTDI serial-to-USB adapter cables in a fairly standard Adafruit pin-out.
  • A six-pin connector for in-circuit programming of the MCU.
  • Two 40-pin connectors for the Processor's Control Bus.
  • Two 96-pin connectors to the Processor's Expansion Bus, one on each DPF Board.

The following schematic sheets show most of these connectors.

Schematic of Board 1 Connectors, part 1

Figure 42. Board 1: connectors to the light assembly. Note the jumpers that connect ground pins to either ground (lights always on) or SWLEDSON, which is controlled by the LTS ON/LTS OFF switch.

Schematic of Board 1 Connectors, part 2

Figure 43. Board 1: connectors to the switch assembly and processor boards.

Schematic of Board 1 Connectors, part 3

Figure 44. Board 1: connectors to Board 2 and the CFT Expansion Bus.

Schematic of Board 2's connection to Board 1

Figure 45. Board 2: the connector back to Board 1.

Schematic of Expansion and Control Bus Connections

Figure 46. Board 2: connectors to the Processor Control Bus and Expansion Bus.

C3.9. Construction

DFP Layout.

Diagram of the layout of both Board 1 and Board 2.

Board 1, early top view.

Placement of IC sockets and connectors on DFP Board 1, during the early stages of wiring. The 12 DIP switches are on the left edge. Connectors in the middle (this eases routing the cables to the processor boards). The larger socket for the MCU and its crystal oscillator are near the right edge.

Wiring of Board 1

Wiring of DFP Board 1. Yes, it's as insane as it looks. Red Kynar wires are for signals from/to the shift register chains. Blue is for addressing signals, yellow is for clocks, black is for ground. The masses of black ground cables near the bottom go to the front panel LEDs.

Surface-mount Resistors

Construction-time detail showing how the surface mount resistors (0805 packages) are mounted between IC pins, and power and ground rails. For each input shift register, half the resistors are pull-ups and half are pull-downs, resulting in characteristic 0000111100001111 bit patterns.

Testing the DFP

Testing the DFP on the backplane. The processor isn't plugged in yet to avoid potential damage. The nybble pattern of the pull-up and pull-down resistors is visible. The front panel is mounted on a piece of cardboard with the exact size and board placement of the the final acrylic panel.

C3.10. The Front Panel

The front panel is made up of two groups of assemblies:

  • The light assembly collects all eight LED modules and mounts them together to form a single array of lights. This was done to reduce costs, and because my hobbyist version of Eagle can't generate boards larger than 160×100 mm.
  • The switch assembly mounts all the switches together on a single plate, and wires them to a break-out board. From there, they're connected to DFP Board 1 using 50-pin IDC connectors and ribbon cable.

C3.10.1. The Light Assembly

The light assembly of the front panel uses LEDs. To save money, and because the Hobbyist version of Eagle CAD is limited to 160×100 mm boards, the assembly is made up of eight identical small boards, each hosting up to five rows of four LEDs each. The boards are single-sided.

Each module contains five 5-pin headers:

PinConnection
1Ground
2LED 1 cathode
3LED 2 cathode
4LED 3 cathode
5LED 4 cathode

The boards have five separate ground planes, one for each row. Each module has pads so the ground planes can be daisy chained between modules, for extra capacitance, and also so the ground planes can shield the computer from a little bit of electromagnetic interference. This feature isn't used, so the ground plane can disconnected, disabling all four LEDs on a row. This is controlled by the LTS ON/LTS OFF switch to disable groups of lights. Because of the design of the front panel, these groups all happen to be multiples of four and this scheme works perfectly.

Since I wasn't sure if I was going to go with through-hole or surface mount LEDs, the boards can take either. Through-hole LEDs need to be soldered on the solder side of the board. Headers are on the component side.

The constructed version uses surface-mount white LEDs, scavenged from cheap LED strips. They are very bright, and meant to be placed behind colour gels and protected by a suitable fascia.

Schematic of the LED module board

Figure 47. Schematic of the LED module board. Eight of these boards are combined to make the front panel LED section.

The LED Module PCB.

Figure 48. The LED module board PCB. From left to right: a top view of the board; placement of through-hold components; the bottom of the board; and placement of (mostly surface mount) components on the bottom. The same board can be used with both through-hole and surface-mount LEDs.

C3.10.2. The Switch Assembly

The switch assembly construction is still temporary, on Veroboard using Kynar wire to connect to the toggle and key switches. It looks horrible, and should probably be replaced by something less so. But it works, it's by far the simplest part of the whole project. It will probably need to be rewired or secured somehow, since the wires (despite protective heat-shrink tubing) have a tendency to break off their solder joints. In retrospect, perhaps I should have used thicker wire.