2022-12-18
EMT 250 home
EMT 250 Instructions
This document provides a technical analysis of the EMT 250 digital reverb, primarily focused on the digital computer which seems to have no publicly available manual. Any references to “EMT-1”, “EMT-2”, etc., refer to the schematics that may be obtainable by contacting Barco (the company that bought EMT).
Some information on the computer design can be found by looking for papers published by Dr. Barry Blesser and Ralph Zaorski. (See the main page for references.) The published papers discuss simulating on a larger computer, and thus there are quite a few differences between the simulated computer and the final design.
The computer has a Harvard architecture: instructions are stored in read-only memory (ROM) which cannot be changed while the machine is operating. The ROM contains 512 32-bit words called instructions. The details of the 32-bit instructions are found in a later section. A dedicated 8-bit program counter (PC) selects the current immediate instruction (IM), which is stored into the instruction register (IR) on the next clock cycle. The programmer can load the PC with an 8-bit address from the output of the arithmetic logic unit (ALU). Otherwise the PC automatically increments on each clock cycle, rolling over from the maximum address of 255 to 0, counting endlessly. The ROM is banked between the lower and upper 256 address space using the front panel “REV” button. More details explained in the ROM section.
To store program data, there are three different random-access memories (RAM) available:
“Register A” and “Register B” can each store 4 16-bit data words. Immediate access.
“Main memory” can store 8,192 16-bit data words. Reads are delayed by 3 clocks cycles; writes are delayed by 8 clock cycles.
“Multiplier memory” can store 16 18-bit data words: 16-bit data words plus 2 bits for storing status information (overflow and arithmetic sign). Immediate access.
The main memory is used to store the digitized audio samples. A pointer for the current main memory index is kept in Register B, address 3.
32-bit instructions are stored across 8, 4-bit ROM ICs, with 9 address pins. These ROMs are labeled “1B” to “8B”. There is an additional ROM labeled “XA” which contains the microcode to select ALU functions which is not discussed here. The MSB of the ROM address bus is controlled by the user control panel button “REV”. The other 8 address bits are driven by the program counter, which is made up of a pair of 74163 counter ICs. The program counter is wired to the first 8 bits of the ALU output for programmable execution branches.
From a cold start, the first 8 address bits will be zeros. The 9th bit will be 0 if “REV” is selected, 1 otherwise.
There are two commands available to cause the program counter to follow the ALU result: jump and jump-if-interrupt. There is a 1-instruction delay between either jump commands and the actual change to the PC. This means the next instruction after either jump is also executed.
Jumps and other actions can be made conditional by using the “skip logic” hardware, which is primarily implemented using a 74S151 multiplexer IC (E20, see “EMT-4”). The instruction can select a skip condition. The options are explained in the “Skip function” section.
The “REV” program begins with an initialization routine (addresses 0-58) where the state of the controls are converted to multiplication factors for the DSP. From the initialization routine, it jumps into the main reverb routine (addresses 122-255, 88-255, 88-255, …) If the “SET” button is pressed, this will raise the interrupt flag which will cause the main routine to jump back the initialization routine (address 120 jumps to 0).
Switching from “REV” to another program, or vice-versa, toggles the 9th address bit and the execution immediately jumps by 256 instructions. The programming must take this unexpected jumping behavior into account.
The remaining five programs use the state of the front panel buttons to determine which ROM address to read from. There is a common path for all programs that starts at address 510, wraps to 256 via program counter overflow, checks the state of the program buttons, and jumps to the correct program.
Each program is responsible for telling the AD converter to make a conversion via the “START A/D” command, thus the program sets the sample rate. This means each program needs to be around 166 instructions in total length to maintain an approximate 24 kHz sampling rate when using a 4 MHz instruction clock. Indeed, this is the case in the EMT 250 ROMs. Alternatively, the program could track the number of cycles, triggering the conversion when the count reaches 166, but this would be complex and waste program space and time with the tracking.
To aid in keeping a length of around 166 instructions, there is a
subroutine for the processor to do nothing for a set number of cycles, as
is commonly found in programming (e.g. delay(int ms)
on
Arduino, or sleep [seconds]
on Linux). This subroutine is
used by the Delay, Phase, Echo, and Space routines. Reverb and Chorus are
the largest routines and do not require additional delay to achieve the
correct sample rate.
The A/D arrives via serial lines to 3 input registers: “A/D #1”, “A/D #2”, and “A/D #3”. The instructions can copy these to a general register, memory, or the multiplier hardware.
Each program is responsible for streaming output to the 4 analog outputs, also at the approximate 24 kHz sampling rate. The command “START D/A” is available for resetting the DA system. After resetting the system, the command “LOAD D/A” will move the ALU result to the first analog output. Subsequent calls to “LOAD D/A” will cycle through the remaining outputs automatically. Thus, each program calls “START D/A” once and “LOAD D/A” four times.
The EMT 250 uses a 32 bit instruction word. This section examines these bits in detail.
There are 3 mutually exclusive formats to organize the word. Each option makes a different use of the lower significant byte.
Data immediate (16-bit literal)
Multiplier immediate (8-bit literal)
Register A read/write addresses and multiplier memory address
31: “A mux sel.” selects between the Register A latch and the input mux in conjunction with bit 23, the high “Carry select” bit. Bit 31 selects the A latch or the input mux. Bit 23 shifts the bits around. If bit 31 = \(2^0\) and bit 23 = \(2^1\), then the options are
A Latch
Input Mux
A Latch shifted
Input shifted
Bit 31 will disable skipping if high.
When A Latch is shifted, the top byte is all latch 15, and the bottom byte is the top byte (IR 15:8).
15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
When the input mux is shifted, it has this strange order:
15 | 15 | 13 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
30-29: “Source sel.” controls the input mux (input to register A).
immediate register [15:0]
ALU
I/O (output of I/O mux)
Memory Output Register (MOR)
Bits 28-26: “ALU function” selects the ALU operation (see dedicated ALU section below).
Bits 25-24: “Destination” drives a binary to octal decoder, of which only outputs 1, 2, and 3 are utilized. “Destination” can be disabled by the SKIP CLK: if “skipping”, then the IC is disabled. Bit 24 also is part of a 4 input NAND, output labeled “I/O CLK”. The destination bits control which registers on the ALU bus are enabled.
No operation (misnomer: probably reading/writing to register A or B)
I/O. LD MPLR (with IR 11, MSB of I/O Func)
Memory buffer register. LOAD MBR and reset the MEM WRT delay line
Memory address register. LOAD MAR and reset the LOAD MOR delay line
Bits 23-22: “Carry select” see Bit 31 for bit 23. Bit 22 is negated (F29-3) and sent to ’181 N29-7 (Cn input) and ’182 S23-13 (Cn input). The \(\overline{\mathrm{IR}23}\) marking on (2) is missing, but should be on the far right side of the page.
Bit 21: “A reg write” is NAND’d with the \(\overline{\mathrm{SKIP\ CLK}}\) from the skip logic (E20, page 4) and OR’d with the A CLK DIS signal. This presumably inhibits writing when skipping or using the A/D converter.
Bit 20: “B reg write” is also NAND’d with the \(\overline{\mathrm{SKIP\ CLK}}\).
Bits 19-16: “B Register Read/Write Address” should really be broken into two sections:
Bits 19-18: “B Register Read Address”
Bits 17-16: “B Register Write Address”
These ’670 registers can be read and written to simultaneously. The output is routed by the read address, and the input is routed by the write address. The B register’s only input is the ALU output.
Bits 15-0: “Data immediate”. If source select is 0, then these bits are a literal value.
Bits 15-13: “Skip function” sets the conditions for skipping over the next instruction (see section below).
Bits 12: “Mulnd sel” short for multiplicand select. Chooses between bits 7-0 (multiplier immediate) when low and the multiplier RAM when high.
Bits 11-8 “I/O Function Select” appears in several places. On page 2, bit 11 is involved in the multiplier memory. On page 3, it drives the I/O mux (see relevant section). On page 4, it drives a binary decoder (see relevant section). Also page 4, (10:8) control the A CLK DIS. (see relevant section).
Bits 7-0: “Multiplier immediate”. Possibly look at "Mulnd sel" to see if this is active as an immediate value.
Bits 7-4: “A reg read write address”, which like the B register version is really two bits for read (6,7), two for write (3,4). Same as the B register, this are ’670 ICs which can read and write simultaneously. The read address routes the output pins; the write address routes the input pins. Unlike B, the input here is selected by the input mux, so any source can appear at the A register.
Bits 3-0: “Mult. mem address” address for the multiplier RAM.
“ALU function” drives the XA ROM to set the ’181 functions. Confusingly, the A mux is wired to the ’181 B inputs and the B latch is wired to the A inputs. The following table refers to EMT 250 registers, not ’181 inputs. Each function may have a slightly different behavior if the carry flag is set.
# | Logic | No Carry | Carry |
---|---|---|---|
0 | \(B\) | \(B + 1\) | |
1 | \(B - A - 1\) | \(B - A\) | |
2 | \(B + A\) | \(B + A + 1\) | |
3 | \(\overline{A}\) (bitwise negation) | ||
4 | \(A \oplus B\) (bitwise XOR) | ||
5 | \(A\) | ||
6 | \(A \cdot B\) (bitwise AND) | ||
7 | \(B + B\) | \(B + B + 1\) |
IR[11:8] are the “I/O Function Select” bits and they span pages 2, 3, and 4.
The MSB, IR11, can control the multiplier memory output. Details are in the multiplier memory section.
On “EMT-3”, all 4 bits are used at the I/O mux. Bits 8, 9, 10 primarily select the input for the I/O mux. Bit 11 is used in conjunction with the other bits and \(\overline{\overline{\mathrm{OF}}\ \mathrm{V\ NEG}}\) to drive the mux strobe input (if that input is high, all the outputs are zero). For the strobe to go high, the \(\overline{\overline{\mathrm{OF}}\ \mathrm{V\ NEG}}\) would need to be high, and the entire I/O word needs to be 6. TBD what this does. \(\overline{\overline{\mathrm{OF}}\ \mathrm{V\ NEG}}\) is an output from the multiplier memory (RAM) on “EMT-2”.
Multiplier memory output register
Front panel controls
“8-rotate” (Latch A A8-15 swap with A1-7, top bit = 0)
“Noise” (linear-feedback shift register for PRNG)
A/D #1 (shortest pre-delay tap)
A/D #2
A/D #3 (longest pre-delay tap)
Product register
On “EMT-4”, the E16 mux determines various side effects. E16 mux can be disabled (all outputs HIGH) by either the I/O word (IR[11:8]) or by the I/O clock (output of the B18 NAND gate).
I/O clock goes high (and does not disable E16) when
SKIP is high (Not skipping)
Destination is I/O (IR25=0, IR24=1)
\(\overline{\mathrm{SKIP\ CLK\ IN}}\) is high (division of 20 MHz clock)
The I/O func select word must be 6 or 8-15 to not disable E16.
LOAD D/A
SKIP and clear IRPT (IRPT signal can override)
WRITE SP (multiplier RAM, OR’d with 7)
SKIP
START D/A
SYNC (unknown function)
START A/D
WRITE SP (multiplier RAM, OR’d with 2)
If either 2 or 7 are selected (WRITE SP), then the AND gate goes low and the multiplier RAM is in write mode.
Note that the SKIP depends on the status of the skip signal from E20.
Also on “EMT-4”, the lower bits (10:8) appear to control the “A CLK DIS.” via AND gate A15. This line is wired to the A register, but the input is from the “START A/D (9)” line; this it is ambiguous whether “A” stands for register A or analog, and unclear what “DIS.” is short for. “A Register Clock Disable” is my current guess.
“Skip” controls if a register write or I/O function (via E16) should occur. “Skip” can prevent a PC jump, but does not cause a PC jump. To convert C code like
if (b0 - a0 >= 0)
a0 = inputValue;
to EMT 250 machine code, the programmer would set the ALU to subtract
b0
from a0
and set the skip bits to
“skip-on-negative” in the instruction before the
a0
assignment instruction.
IR[15:13] controls the E20 mux which selects various possible flags (see below) to drive the “SKIP” and “\(\overline{\mathrm{SKIP\ CLK}}\)” lines.
The E20 mux takes in what would be the Current Program Status Register (CPSR) is a modern architecture and outputs 1 selection based on the current instruction. If the selection is a logical low, then a skip is produced.
The E20 mux can be disabled by IR31 (A mux select) by making the \(\overline{\mathrm{EN}}\) input high. E20 also disables itself via the D18 flip flop at its own output. This would seem to prohibit chaining multiple skip instructions at the hardware level.
If we are skipping, then output W is low, and “SKIP” will be low on the next 4 MHz clock cycle so the skip acts on the next instruction.
The E17 mux controlled by the destination bits will be disabled when “SKIP” is low (skipping).
The registers cannot be written to if we are skipping. Register A has an additional restraint with the “A CLK DIS.” that will prevent writing if high.
Notation note: the symbol \(\lor\) is used to represent a logical OR condition.
No skip (input connected to GND)
Negative (checks ALU 15)
Carry (checks the carry out from ALU)
Positive (checks \(\overline{\mathrm{ALU}\ 15}\))
\(\overline{\mathrm{OF}}\) (checks quite a bit of logic! TBD)
\(\overline{\mathrm{OF}}\ \lor\) Negative
\(\overline{\mathrm{OF}}\ \lor\) Positive
Always (input connected to +5 V)
Notes on the \(\overline{\mathrm{OF}}\):
Uses A MUX 15, LAT B 15, ROM OF (ALU ROM, “XA”), and ALU 15.
Analog audio is converted to a 15 bit word: 12-bit value with three leading scale bits (pg. 17 of the 1980 user’s manual). A/D conversion begins at the analog circuit (page 36 of service manual PDF). Page “EMT-9” shows the computer’s interface to the analog circuit. There are some minor naming differences for the same signals between the computer and analog schematics; use the pin numbers on the analog board referenced against the J1 table on “EMT-1” if there is any confusion. There is some back and forth between the analog board and the computer (see below), and eventually a digital word is sent serially to the computer (“A/D SER DATA”). The computer adds the scaling used for that conversion to produce “A/D SCALED DATA”, which is sent to the +t\(_d\) delay line on “EMT-7”. 3 different paths can be taken with the same serial stream resulting in output registers A/D #1-3. The CPU can access the registers via the I/O mux.
For the EMT 250 programmer, the only interface is the “START A/D” instruction and reading the A/D registers from the I/O mux.
A successive approximation IC (Am2504) and 12-bit DAC IC (BB DAC80) make up the core of the analog to digital converter (user’s manual page 24).
The user manual’s converter offset adjustment procedure indicates that a digital word of 2048 indicates a zero voltage input and numbers higher indicate a higher voltage and lower numbers indicate a lower voltage.
Supporting circuitry causes a trigger if the input voltage to the converter is outside of \(\pm\)2.5 V. The trigger causes a previous amplifier stage to reduce the gain. There are 4 possible gain setting for the previous stage and the final gain setting is encoded into the leading 3 bits of the stored digital word. The D/A section has similar programmable gain amplifiers that perform the inverse gain reduction for each sample.
If E16 is active (see relevant section), then a low output 6 indicates the “START A/D” instruction was given. This low output will set flip flops C7\(_B\) (triggers “CONV CLK” and “CONV CMD”) and C3\(_A\) (triggers “\(\overline{\mathrm{T}}\)/H”).
As explained in the program ROM section, the programmer is responsible for calling the “START A/D” command as often as needed for the target sample rate, which is about once every 166 instructions at 4 MHz for a 24 kHz rate.
Analog board to computer signals
“EXEC THRES” (exceed/over threshold) is triggered when the window comparator goes TBD.
“A/D SER DATA” is the output from the A/D IC.
Computer to analog board signals
“G1/G2” shorts out a resistor on the analog board, halving the amount of voltage the window comparator sees.
“A/D S1” and “A/D S2” are switch commands to control the gain of the amplifier between the FET gate and the A/D ICs. The “EXEC THRES” signal appears to advance these signals; details TBD.
“\(\overline{\mathrm{T}}\)/H” (track and hold) controls the FET that latches the signal so it can be converted.
“CONV CLK” goes to the A/D IC (AM 2504) clock input.
“CONV CMD” goes to the A/D IC (AM 2504) start pin.
4 LED indicators (Register, 0dB, -6dB, -12dB)
The 2-bit value of the +t\(_d\) control is directly wired to C1 (“EMT-7”), which selects taps from a long series of serial shift registers (Signetics 2533).
“SSR DATA” connects the scaled (S1/S2 encoded) A/D result from (9) to the delay line (7). “SSR CLK” is from “SHIFT CLK” (9), which is part of the A/D logic rats nest (todo: details).
D1 is a Signetics 2518 hex 32-bit static shift register. Sections 1-4 are used.
There should be a rapid sequence of 1s and 0s flowing through all the shift registers that can be roughly observed with a simple oscilloscope probe. If any output is stuck, that IC is probably dead. These are rare ICs but perhaps some SMD components on a DIP-8 sized PCB could be designed to cheaply replace them.
Six 74LS164 8-bit shift registers are used to store and access the output from the A/D. The registers are paired into three 16-bit registers named “A/D #1”, “A/D #2”, and “A/D #3”. All three appear at the I/O mux.
“A/D #1” is the first available output from the variable “+t\(_d\)” pre-delay line.
“A/D #2” adds the K1…G2 delays, and D1 (Signetics 2518) section 1.
“A/D #3” is the longest delay. It adds the F1…E2 delays, and D1 sections 2, 3, and 4 from the #2 tap.
It appears that REV and SPC are the only two programs to read all 3 A/D registers. CHOR, PHAS, and DEL read from A/D #1 immediately in their programs. DEL also reads A/D #3 at 462. ECHO appears to only read A/D #3 at the start of the program.
Page “EMT-8” shows the computer’s D/A circuit. There is a typo on X23: what appears to be “4 10” should actually be “10 8” (pin 10, output 8).
To do: we need a timing diagram. The output of the ALU has a 12-bit audio sample plus 2-bits for the gain controls, and perhaps something else in the remaining 2-bits (could be stop or parity; there is a xor with a ‘stop’ label…). The ’195 shift registers are arranged to shift the lower bits up and the upper bits out.
At some point in the timing, the parallel outputs of the ’195 shift registers are sent “out” via the appropriate channel gate. Documenting the state of the shift registers when the gate command signal occurs should clear up which bits are audio.
“START D/A” resets the counters V22, V23, and X20. It also goes to NAND gates P22. Counter V22 is effectively a divide-by-8 for the 4 MHz clock (500 kHz).
Counter V23, and its decoder, X23, control which output channels are active. The AND gates on N21 are control signals to select which output (I, II, III, or IV) is active.
Output I is active on count 3.
Output II is active on count 5.
Output III is active on count 7.
Output IV is active on count 8.
Counter V23 also controls the read address for the D/A registers (L22, H22, H21, and H20 - all ’670 registers). The read address A and B inputs are wired directly to the counter’s B and C outputs, respectively, which means the register being read is counting up once every two 500 kHz clock cycles (250 kHz).
“LOAD D/A” increments the write address for the registers and controls the write enable pin. X20 forms a simple 0 to 4 counter. The “LOAD D/A” signal is coming from the I/O Function Select mux on page 4. The signal is active low (it is normally high when idle). The first “LOAD” signal after “START” should write the current ALU output into D/A register 0, and the rising edge of “LOAD” resuming it’s normal high state will advance the register address to 1. The next “LOAD” writes the current ALU output into D/A register 0, and the address increments. This continues two more times so register addresses 0-4 all have data.
Presumably the instructions trigger “LOAD D/A” fairly quickly compared to the reading of the D/A registers. The reading is limited to changing at 250 kHz, but the writing is limited to the speed of toggling the “LOAD D/A” line, which probably requires two 4 MHz cycles to set and reset the I/O Func Select mux. Further inspection of the I/O Func Select mux (E16, page 4) is required. It may have some logic that allows for quickly toggling “LOAD D/A”; TBD.
“LOAD D/A” is attached to I/O Function Select 0 (only active when IR11 is high, so the whole I/O Func word is \(1000_{2}\) or \(8_{16}\))
The main memory has a 13-bit address that can be set by transferring the ALU result to the memory address register (MAR). 13-bits allows for storage of 8,192 16-bit words. After writing to the MAR, the memory output register (MOR) is updated after 3 instruction cycles and can be read from.
After setting the MAR, a new value can be stored by writing to the memory buffer register (MBR). It takes 8 instruction cycles to update the memory.
The main memory is large but slow and is therefore used to store audio samples and create delay lines.
The original RAM board has 8 rows of 16 1024x1 bit RAM ICs. Each RAM IC had 10 pins for the address connected to the “MAR” latch. 3 additional ALU bits control a 3-to-8 decoder IC to select a row of RAM.
The second RAM board has 2 groups of 16 4096x1 bit RAM ICs. Since the 3-to-8 decoding from the main board no longer made sense, the new RAM board has extra logic to encode the 8 “CE” lines back into 3 address bits. It does not simply reverse the logic of the decoder, but maps it in the following way: “MEM ADDR CE”(0:7) maps to 74148 inputs 4, 5, 3, 2, 7, 6, 1, 0.
This mapping results in the desired behavior of creating two groups of memory, “A” and “B”.
In the programs, the memory location pointer will just auto-increment and wrap around as an unsigned 16 bit integer. Since the memory circuit ignores the most significant bits, this does not cause any issue.
The 1980 manual mentions a rhythmic 3 Hz sound indicates bad memory. Running the machine with no RAM chips, and installing 1 bit pair (group A/B) at a time can help track this down. Running the machine with the higher bits removed results in non-rhythmic, random noise. Inserting each bit pair in sequence from LSB to MSB, you will eventually add in an IC that introduces the rhythmic noise, and then you can just swap a good RAM with A or B to determine if one or both are defective.
The multiplier memory is shown in the overview page as 16 bit words in 16 addresses. It also includes 2 extra bits that save the \(\overline{\mathrm{OF}}\ \lor\) Negative and \(\overline{\mathrm{OF}}\ \lor\) Positive status results. See page “EMT-2” for the schematic. The saved “overflow or negative” result is part of the logic to strobe the I/O mux (“EMT-3”). The saved “overflow or positive” result works with IR11 to control the MPLR MEM (also “EMT-2”).
The address for the multiplier RAM is set by IM 3:0, which means the RAM addresses are hardcoded in the ROMs. The RAM data input is connected to the ALU output.
In addition to remembering the status of an operation, the multiplier memory has no delay, so it is appropriate for storing intermediate results and magic constants used for the DSP.
A dedicated multiplier circuit allows multiplication to happen in parallel with the ALU. The multiplicand is always the ALU result and the multiplier can be sourced from the multiplier memory or a literal value from ROM. “EMT-5” shows the multiplier circuit. There is a 3 instruction cycle delay before the result is available at the product register. A new multiplication operation can be loaded while awaiting a previous result; this feature is used extensively in the reverb program.
The 20 MHz system clock drives the clock input of shift register E9. This part of the schematic is illegible and had to be traced out with the machine. The parallel “A” input to shift register E9 comes from the “LD MPLR” (4) signal, which corresponds to the destination setting “IO” (destination = 1). Figure 1 shows the “LD MPLR” timing simulated in Logisim. The “LD MPLR” line is usually high and just pulses low. The pattern shown in Logisim (see figure 1) is also observed on the machine: pulses low on the “LD MPLR” line are followed by 3 pulses that clock the “PPREG” flip-flops.
The AM25S05 4-bit by 2-bit multiplication ICs perform the function \(S = XY + K\). The \(X\) input comes from the ALU output bus. The \(Y\) input is select by IR12 (the “mulnd sel.” bit) which can be either IR[7:0] or the multiplier memory \(\overline{15}\) and [14:8] (high byte, with the MSB inverted). \(K\) comes from the PPREG (partial product register) which is the result \(S\) latched. PPREG is made available at the debugging headers.