Introduction
The Dicentra is a DLion spinoff packaged in a Multibus environment. It lets us put more than one ethernet controller in a box, and lets you write software in Mesa to control commercial IO boards.
David Boggs designed most of the hardware and nursed 4 boards through final layout. The routing was done at Versatec on a VAX/Sicards system. I've done most of the software and microcode. Tim Diebert designed the early memory board and the early Misc board. Mike Overton worked out the current packaging. The folks in PARC's Electronic Model Shop built them.
The idea, of course, was to be able to buy lots of wonderful hardware so we didn't have to design it. That's been a mixed success. There are many many Multibus boards available, but most of them are trash. Browse through the Multibus Buyer's Guide if you are curious.
A very serious problem is that all the off-the-shelf boards seem to come with a serious quirk or two that chews up a lot of time making them work. Boggs and I spent many hours chasing a smashed packet problem in the 3MB Ethernet board. The 3Com 10MB board doesn't work with some length of fibernet. Jim Gasbarro spent many hours discovering a known PAL bug in the Disk controller. The AMD memory board we have doesn't pass the memory diagnostics... Yes, it is faster than having to design something from scratch, but it is not as simple as I was (naively) expecting.
Another major problem is that commercial boards turn out to be quite expensive. That's not a serious problem if you only use one board in a widget controller, but for something like a memory board that gets used in every system, you can save quite a bit if you build your own.
Good ideas, not so good ideas
There were two really good things we did on the Dicentra project. First, we put a lot of time into the History Buffer on the Debugger board. It paid for itself the first time we used it to chase an obscure wild branch bug. I won't get involved with any more microcode without one. Second, we didn't change any of the microinstruction decoding. This let us steal the whole DLion Emulator. We were running Mesa code a day or two after the "last" bug was removed from CP.
There are two weak points in the Dicentra. The first is that the Emulator microcode lives in expensive PROM. It will be almost impossible to switch to a new instruction set if we get another batch of machines into the field. The second problem is that the Multibus is quite slow. A DLion does a memory cycle in 411ns. The Dicentra takes roughly twice as long.
Where to find it
All Dicentra related filea are stored on [Indigo]<Dicentra>. You will probably have to browse around in the subdirectories in order to find something.
This memo is DicentraManual.press/tioga on [Indigo]<Dicentra>Doc>. It's a Tioga format file so don't expect it to look reasonable if you try to read it from Tajo. The figures are in Figs.press.
The logic prints are stored on [Indigo]<Dicentra>First>. The press file for each board contains all the prom listings, wire lists, prescans and such. I'm willing to add helpful comments and such to the prints. Let me know if you have any suggestions. When I edit something, I update the date on the cover sheet. This makes it easy to verify that you are not working from out of date prints.
There are special versions of Burdock and Mass for use with Dicentras. They are stored on your favorite AMesa/APilot directory. You will also need TestDebuggerBoard.bcd and TestHistoryBuffer.bcd to check out a Debugger board. They come from the Burdock subdirectory. Copies of the Calaveras versions of all four files are on [Indigo]<Dicentra>Calaveras>.
Most of this memo assumes that you are familiar with DLion CP boards and/or microcode. Copies of Garner's Dandelion Hardware Manual (DLionManual*.press) and Dandelion Microcode Reference (DMR.press) are stored on [Indigo]<Dicentra>DLion>. You can skip all the chapters on IO devices.
If you are going to debug hardware, you should use BringOver to fetch the following files:
[Indigo]<Dicentra>11.1>DF>Diags.df.
[Indigo]<Dicentra>11.1>DF>Emulator.df.
[Indigo]<Dicentra>11.1>DF>ScopeHacks.df.
The Burdock documentation is [Indigo]<Dicentra>Doc>BurdockManual.press/tioga.
There are two boot files needed for normal gateway operations. OscarDicentra.boot is the gateway program. BootMeAgainDicentra.boot may be necessary if you store a buggy parameter file. The versions that we are using at PARC live on [Nebula]<Gateway>.
OscarDicentra.pb is the Pup version of the same OscarDicentra.boot. Install it on a Pup boot server (IFS or D0) if you might need to boot your machine from a 3MB net.
Normal Operations
Since Dicentras don't come with displays or keyboards, or even a disk, normal operations are very simple. When you turn them on, they boot themselves over the ethernet and go to work.
If anything goes wrong, you will probably find your Dicentra in 915 waiting to be Teledebugged.
Dicentras contain a watchdog timer. This makes the perceved reliability of connectionless servers like Gateways much higher, but it is occasionally frustrating when it goes off while you are Teledebugging.
Normal Booting
When you poke the Boot Button or turn on power, a Dicentra finds and tests memory, copies the germ into main memory from
EPROM on the Misc board, activates the watchdog timer, and then starts running the Germ. 108 will be in the
MP while it is testing the normal (8 banks) of memory. If you have 2 megabytes, the
MP will be 116 (16 banks). The Germ loads the desired program over then net. The boot file number and which device to boot from can be stored in the
EEROM. The default is to boot Oscar, the gateway program, from the first 10MB ethernet board. You can also use the Alt-Boot button to manually select an alternative boot file or device.
Fine print: The power up sequence forces the CP to execute from it's PROM. The Multibus INIT/ signal (from the boot button or watchdog timer) don't reset UseRom in the Debugger boards Control PAL. This lets you can test the booting part of new microcode if you load it with Burdock.
MP Codes
The 09xx codes are all direct from Pilot. See the Pilot documentation for the details. These are the common ones.
915 => Waiting to be TeleDebugged
917 => Being TeleDebugged
920 => Booting in progress (should blink to 910 occasionally)
921 => The desired device doesn't exist
924 => Booting timed out
925 => Missed a packet while Booting (should go back to 920 soon)
928 => Waiting for Boot Server
These codes come from InitDicentra.mc. Except as noted, these will blink.
0090 => Control Store Parity Error
0091 => Some board didn't respond (likely to be a Memory Parity Error)
You will get this if the switches on the 10MB board are set wrong.
0092 => Unknown Misc board Interrupt
0093 => Cycles Out of Phase (hardware or microcode bug in CP)
0100 => Testing Memory (101..10n is number of banks found)
0108 => Found 8 banks (1 board)
0116 => Found 16 banks (2 boards)
0150 => Bus Master Missing
0151 => Interrupt(s) Stuck On
0152 => (Part of) Memory Data Bus Stuck High
0153 => (Part of) Memory Data Bus Stuck Low
0154 => XAck Timeout broken (on Misc board) -- doesn't blink
0159 => Not Enough Memory (need 2 banks)
0160 => Memory Broken
0161 => XAck Timeout During Scan (parity bit broken?)
0170 => Copying Germ
0171 => Bad Germ Checksum
You will get this if the switches on the Misc board are set wrong. They are easy to bump.
0898 => Unreasonable processor ID from 3Com board (from processor head, doesn't blink)
0899 => About to start running Germ -- doesn't blink
Odds and ends
00xx => Trying to find a Time Server
1937 => Trying to find a Time Server
07xx => CPU Calibration from BootMeAgain.
0731 means that the Dicentra CPU is running at 73.1% of the speed of a DLion.
Once most Dicentra programs are up and running, the MP will show the % of the CPU in use, and a single dot will walk through all 4 decimal points - one step a second.
Alt-Booting
If you are having hardware troubles with that net or software troubles with the normal program, you can use the Alt-Boot button to manually select a different boot file or different device. The Alt-Boot button is tested as soon as the germ starts running. (That's the first time you see a 9xx number.) If it is down, you will get a series of numbers like Alt-Booting a DLion. The numbers cycle through pretty fast. Don't be surprised if you don't get the right one. I wait until the one before the one I want, and then let go as soon as it changes. Alt-Booting disables the watchdog timer. (You might be trying to boot over a slow phone line.)
The sequence of numbers you will see is 0240, 0241, 0242, 0243, 0244, 0260, 0261, 0262, 0263, 0264, 0280, 0281, 0282, 0283, 0284, 1240, 1241, ..., 1283, 1284, ... 2240, 2241, ..., 2283, 2284. The first digit is the board number. The last digit selects the boot file. x24x boots from the 10MB ethernet. x26x boots over the phone line. x28x boots over the 3MB net. Booting over the 10MB net or phone lines uses NS protocols. Booting from a 3MB net uses Pup protocols (just like Altos).
0240 loads boot file number 25200002000, octal, (the gateway program) from the first 10MB ethernet board. This is the default.
1240 loads boot file number 25200002000 from the second 10MB board.
2240 loads boot file number 25200002000 from the third 10MB board.
0241 loads boot file number 25200002001 from the first 10MB board.
0242 loads boot file number 25200002002 from the first 10MB board.
...
1240 loads boot file number 25200002000 from the second 10MB board.
2240 loads boot file number 25200002000 from the third 10MB board.
0260 loads boot file number 25200002000 from the first phone line.
1260 loads boot file number 25200002000 from the second phone line.
0280 loads Pup boot file number 140000 from the first 3MB board.
0281 loads Pup boot file number 140001 from the first 3MB board.
Booting over a phone line requires some magic in the parameter file if the other end of the phone line is also a Dicentra. As you can guess, it takes a long time to boot over a slow phone line (or through a very busy gateway).
Oscar
Most of the EEROM is used to hold a machine's parameter file. (Think of it as a very small fast disk.) This can be processed with the normal Usercm parsing routines.
Once you get Oscar going, you can Chat to it. There are several commands in Oscar used to setup the EEROM. Fetch Parm File is used to load a new parameter file. Set Boot Location is used to setup the default boot device and file number. Type Parm File will printout the default boot file and location as well as the contents of the parameter file. Don't be surprised by a bad checksum message. That's normal if you haven't yet setup the the boot file location or Fetched a parameter file.
Oscar is the Gateway program, so it scans the [Gateway] section of the parameter file. If there is a fatal bug in there, Oscar will dive into 915 every time you boot it. Since Oscar is also the only program that you can use to install a new parameter file, things get a bit sitcky.
BootMeAgain will smash the parameter file. This is just a hack, so you have to wait until it starts rebooting itself. It will take several minutes. 729, 730, and 731 are reasonable numbers while BootMeAgain is running. (BootMeAgain is also the CPU speed calibration program. The MP is 10 times the % execution rate of a DLion CPU. 730 means that this Dicentra is running at 73% of the speed of a DLion.) You can also use EERomTest if you have Burdock handy. On the first 10 machines, the EEROM chips are socketed. You can destroy the parameter file by right/left swapping them.
Bouncing dots, MP, Control-Shift-Swat
While Oscar and most other Dicentra programs are running, the MP shows the percentage of CPU being used. The decimal point should take a step every second.
While Oscar is initializing itself, the MP will read 990. It may blink to 981 while finding its Pup host number. It will blink to 1937 while finding the time. After initialization is finished, the number in the MP is the percent of the CPU that's being used.
If you lean on the Alt-Boot button, all 4 decimal points should turn on as a warning. If you hold it down for several seconds, you will get to 915. This is just a hack for debugging stubborn programs.
981 and Pup Host numbers
If you don't understand about 981 (on DLions), get somebody who does to explain it to you.
Oscar uses Pup protocols. It gets its Pup host number just like DLions and D0s that are running Pilot. (Actually, it does what D0s used to do. SDD "fixed" that for Klamath.) If there is a 3MB board, it uses the Pup host number from the first 3MB board on all the 10MB nets. If there is no 3MB board, it asks a name server for its Pup Address, and uses the Pup host number that comes back. While it is waiting for an answer, the MP will show 981. The net number that comes back is ignored. This makes it easy to move machines from one net to another if that host number is unused on the other net, but it also makes it easy to get confused if you move a machine and forget to update Pup-network.txt.
If you get a 981, you don't have any 3MB boards. If you think you have one, it is either broken, or the switches are set wrong.
Currently, Dicentras without any 3MB boards need a name server on the net to get out of 981. This is aa bit stupid considering that the desired info is probably in the parameter file, but I haven't written the code yet. Fortunately, there aren't many Dicentra gateways without at least one 3MB board.
Chassis
The power switch on the lower right of the front panel does the obvious thing.
The button marked Reset above the power switch doesn't do anything.
The left/white button above the MP is the Boot Button. Poking it will reboot the machine.
The right/red button is the Alt-Boot button. It can be read by the CP. Just like on a DLion, the Alt-Boot button is used at boot time to direct the machine to boot from an alternate device or file. The normal running software will go into 915 if you hold in the Alt-Boot button for several seconds. (It's like Control-Shift-Stop.) The Alt-Boot button "floats" pushed-in so you can't run a machine without its MP. (This wouldn't be too hard to fix.)
Physical
The chasis uses about 7 inches of a normal 19 inch rack. It's about 20 inches deep, more if you count the space needed by the connectors on the back. It comes with rubber feet, so table top mounting is quite reasonable.
The whole setup weighs about 55 pounds. You can move it by hand, but it is heavy and awkward. You won't want to carry it very far.
Some of the boards don't fit into their slots very well. Push harder! Yes, you have to push real hard! Sometimes it takes two people.
Cooling
A Dicentra makes a lot of heat. Make sure there is lots of room for air.
Power requirements
A Dicentra needs 115 volts AC. (There is a switch on the power supply for 230 volt operation, but you would also have to change the fan.) A lightly loaded machine (no extra ethernet boards) draws about 2.5 amps. A heavily loaded machine will take twice that.
The power supply will work on 50Hz. So will the fans on a few that we looked at. There are lots of opportunities for using similar but slightly different things so you should probably check carefully before you actully plug a machine into 50Hz. (I haven't checked the specs for the power supplys in the first 10 machines.)
Power supply
The power supply is beefy enough that you are unlikely to run out of anything: +5@80A, +12@8A -12@8A, -5@5A. The limiting factor is the Molex connectors behind the back plane.
Beware: Keep an eye on the Molex connectors used to connect the wires from the power supply to the backplane. If they turn light brown, replace them soon. Otherwise, they will turn dark black.
Beware: The power supplies on the first 10 machines don't provide -5.
We don't provide any fancy power (battery backup, analog...) on the P2 connector.
Board/Slot assignments
The normal Dicentra chassis has 9 slots. The bottom 2 slots don't have any P2 connectors.
Unless you are using a DMA device, you can put almost any board in any slot. The CP won't work in the bottom slot unless you arrange to ground its BPRN/. The bottom 2 slots don't have P2 connectors, so that's a bad place to put the CP, Misc, or memory. Unless you have a second memory board, there isn't any need for a P2 connector on a running system, but some of the diagnostics require it.
Cooling is serious consideration. The CP runs hottest, so try to leave an empty slot above it. (If you have a full system, the CP actually runs slightly cooler if it is in the middle of the stack rather than the top board. I guess there is too much extra room on top so the air doesn't get forced against the chips.)
The Debugger board needs to go next to the CP board. Of course, you probably don't need a Debugger board in a production system.
If you have several 10MB or 3MB boards, things can get pretty confused. By convention, the first board goes nearer the top and the last one goes nearer the bottom.
Thus I suggest the following arrangement for the normal system with 1 3MB and 1 10MB board. (There is nothing critical about this setup. It's at least as good as most and better than some.)
Slot 1: Memory (Top)
Slot 2: (empty)
Slot 3: CP
Slot 4: Debugger
Slot 5: (empty)
Slot 6: Misc
Slot 7: 10MB Ethernet
Slot 8: (empty)
Slot 9: 3MB Ethernet (Bottom)
Or, if you have no Debugger board:
Slot 1: Memory (Top)
Slot 2: (empty)
Slot 3: CP
Slot 4: (empty)
Slot 5: Misc
Slot 6: 10MB Ethernet
Slot 7: (empty)
Slot 8: 3MB Ethernet
Slot 9: (empty) (Bottom)
I suggest that another 10MB or 3MB board be placed directly under the first one if that slot is open.
Just to make life interesting, the EEROM chips on the Misc boards for the first 10 machines stick up so high that you have to leave a blank slot above them. Stitchweld boards also need a spare slot below them or wires get poped when they catch on things as boards are inserted or removed.
Bus Master
There are 2 sockets at the top of the back plane above the left edge of the P1 connector. They are intended to provide parallel priority resolution. There should be a DIP of 15 100 ohm resistors upside down in U2. Pin 15 of the DIP, the common connection to all 15 resisters goes into pin 8/GND of the socket. Pin 8 of the DIP has been removed to save power/heat. That's giving a Bus-Grant to the top 8 boards.
Multibus
If you are going fix anything inside a Dicentra, you have to understand how a Multibus works.
The Multibus boards are 6.75 by 12 inches. There are 2 connectors on the backplane. The big one is called P1, and the smaller one is called P2. The P2 connector is semi-optional. It only contains the 4 high order address bits. You can build a Dicentra system without any P2 connectors, but it will be limited to one megabyte (1/2 megaword, one board) of memory.
Figure 1 shows the pin assignments for the Multibus signals as they are used on the prints. (The extra 1xx and 2x on the pin numbers tell the design automation system which connector to use.)
The P1 connector provides +5, +12, -12, and -5. (The -5 isn't mentioned in my copy of the Intel Multibus specs, but we have several boards that expect it on pins 9 and 10, so that's where it goes.) We don't provide any fancy power (battery backup, analog...) on the P2 connector.
Address and Data
The data bus is 16 bits wide. Individual bits are named DATF/ through DAT0/. The signals are low True, TRI-State, but there are small pullups on the backplane so things float high (0) reliably.
Beware: DAT0/ is the LSB. That's the Intel way, but it is backwards from most schematics that come out of PARC.
The address bus is 24 bits wide. It's a byte address, not a word address. Individual bits are named AD17/ through ADR0/. Again, the signals are low True, TRI-State, and there is a small pullup on the backplane. The first 20 address bits are on the P1 connector. The high 4 are on the P2 connector. If you don't have any P2 connectors, you are limited to 1 megabyte of main memory. (That's one board.) Even if you do have a P2 connector, Mesa can't use more than 2 megabytes of memory. The limit is in the map flag format. The initialization microcode ignores any memory beyond the first 2 megabytes. It is also smart enough to stop after 1 megabyte if the P2 connector is missing.
Beware: Again, ADR0/ is the LSB...
Beware: The address on the bus is a byte address. Mesa is word oriented. So is everything in the CP. Most addresses you will see when debugging will be word addresses. When you get a new hardware widget, I suggest that you translate the byte addresses in the documentation into word addresses as soon as possible, and scribble the results back into the documentation as a reminder.
During word transfers, the low order byte is the even one.
Read/Write cycles
See Figure 2 for the basic timing diagrams. Everything involved with data transfers is asynchronous.
For a memory read operation, the processor puts the address on the bus, waits for (at least) 50ns of setup time, and then brings MRDC/ low. The board that recognizes its address puts the data on the bus and pulls down on XACK/. When the processor notices that XACK/ has gone low, it latches that data and raises MRDC/, and after 50ns of hold time, it stops driving the address. When the responding board notices that MRDC/ is no longer low, it lets go of XACK/ and the data.
To write memory, the processor puts the address and data on the bus, waits for (at least) 50ns of setup time, and then brings MWTC/ low. The board that recognizes its address does the write and then pulls down on XACK/. (It can latch the data and return XACK/ earlier if it is smart enough.) When the processor notices XACK/ has gone low, it raises MWTC/, and after 50ns of hold time, it stops driving the address. When the responding board notices that MWTC/ is no longer low, it lets go of XACK/..
Beware: The normal Dicentra memory boards do not support byte addressing. Some DMA controllers require this. To use those controllers, you have to buy a brand-X memory board.
Read and writes to IO space are the same except that the processor uses 2 different control signals: IORC/ for reading and IOWC/ for writing. All IO operations could have been done with memory mapped "memory" reads and writes, but by convention, most IO devices are located in IO address space. See MultibusAddresses.mesa for the normal address assignments.
For word transfers, BHEN/ is low and ADR0/ is high - the address points to the even byte of the word. For byte transfers, BHEN/ is high, ADR0/ is used to select odd/even bytes, and the data is on the low order part of the bus (DAT7/ through DAT0/).
If no board responds, things will hang forever. There is a timer on the Misc board that generates a fake XACK/ after about 12 microseconds. The Misc board also latches many of the signals that were on the bus each time it generates a fake XACK/.
Shadows
Some IO devices, in particular the 3Com 10MB Ethernet board that we use, fill up a lot of IO address space. Since many boards only decode 16 address bits, things could easily get quite crowded. (Remember, that's 16 bits of byte addressing, so it is only half the size you might think.) Fortunately, there is a handy trick. The 3Com boards will decode 20 or 24 address bits. Thus AD13 through AD10 can be used for board selection and all the boards will share the same window in the small 16 bit address space. In terms of the 16 bit address space, the second and third boards will be in the shadow of the first board.
Interrupts
There are 8 open collector interrupt lines: INT7/ through INT0/. A pair of PALs on the CP watch these lines, and generate a microcode interrupt/trap whenever they change. The microcode then scans the interrupt lines, and processes the ones that went down. (It's like watching for down transitions on a keyboard.) The microcode (in expensive PROM) uses INT0 for the Process timeout clock from the Misc board. INT4 is also known by the phone line driver in the PROM. INT2 is shared by all the 10MB ethernet boards. INT3 is shared by all the 3MB ethernet boards. These definitions are in DicentraInputOutput.mesa.
Bus Master, DMA
The Multibus rules provide two ways to exchange Bus Mastership: Serial and Parallel. Fortunately, Gateways don't need to do this so you don't really need to really understand this section.
Beware: If you are going to buy a simple controller, I strongly suggest you avoid "smart" boards that use DMA unless you really need the performance.
If you are going to use DMA, you must be prepared to read the specs and dig into the fine print. Basically, BPRN/ (Bus Priority In) needs to be low before a board can use the Bus. In serial mode, the first/top BPRN/ is wired to ground and BPRO/ (Bus Priority Out) of each board is connected to BPRN/ of the next board. Any board that wants to use the bus raises BPRO/ to lockout all the downstream boards. Any board that doesn't want to use memory copies BPRN/ to BPRO/. In parallel mode, BREQ/ (Bus Request) is low if a board wants to use the bus and BPRN/ is low if a board can use the bus. BUSY/ and BCLK/ are used by the bus master logic.
Beware: There is a bug on the CP board. It's doesn't work at full speed with DMA devices.
The chassis comes setup for Parallel priority resolution, but things get a bit confused because the CP doesn't ground BREQ/ and the Misc board internally jumpers BPRN/ to BPRO/. The solution to this mess is to assume that there is only one bus master and ground all BPRN/ on all slots. This is done by removing the U1 and U2 on the backplane (LS148, LS138), and inserting a 15 resistor DIP upside down into U2 so that it pulls down on the BPRN/ that is prewired to the first 8 boards.
Beware: Don't put the CP Board in the bottom slot. It doesn't have any BPRN/.
The first 10 machines are setup to use pins on the backplane for serial priority. They are all jumpered to GND so you can put the CP in any slot.
Odds and Ends
INIT/ is low whenever the Boot Button is pushed. It's also set by the Misc board during power up or by software command. It's is used to reinitialize everything. (Of course, if the software turns it on, "reinitialize" better mean let go of things like INIT/.)
CCLK/ is a 100ns clock that's always running. It comes from the Misc board.
PROMs and
PALs
The PROM technology around PARC is a bit old fashioned.
Except for the PROMs on the T1 board, all the small PROMs and PALs on the Dicentra were written in the Alto environment. The PROMs come from BCPL programs that generate MB files directly. The PALs get turned into MB files by Don Curry's PALASM. It is an Alto Mesa program. (I'm partway through translating it into Cedar.)
The MB file for the PROMs on the T1 board come from a Cedar program.
All the MB files get turned into real PROMs by PNew running on an Alto talking to a Prolog M920.
In the lab, near the PROMs blower there is a disk marked "Dicentra PROMs". It has everything needed to make more PROMs.
Building Germ
PROMs
Building Germ PROMs is quite easy. First, you make the Germ. It can be tested with Fetch.burdock. Then you use MakeGermMB to turn Dicentra.germ into Germ.mb. (All the fine print is included in NewGerm.cm.)
Then you take Germ.mb over to the PROM blower. The quirk here is that PNew can't blow 2764s. Actually, it blows them just fine, it just dies on the verify pass. So, there are 3 command files, one for each PROM. They are called Germ0, Germ1, and Germ2. Expect a "Bad Bit" message when each one is finished.
The Emulator PROMs on the CP board knows that the Germ fits into exactly 3 2764s, so if your Germ overflows the 3rd PROM, you are in trouble. (If you manage to shrink the Germ below 3 chips, you can use a blank one in the 3rd socket.)
Building CP Emulator
PROMs
The problem is that they are expensive, so you want to be reasonably sure you have things right before you make many sets.
The first step is to make the new Emulator microcode. You can test it with Emulator.burdock. Then, use MakeControlStoreMB to turn Emulator.fb into ControlStore.mb. (All the fine print is in Emulator.cm.)
Once you are happy with your new microcode, take ControlStore.mb to the PROM blower. There are 2 command files for blowing CS PROMs. CS2732.cm makes a set of 6 2732s. (Remember, you need to use a slower crystal and a special CPBank PROM to use 2732s on the CP board.) Unless your application is very speed critical, you should be able to do a lot of testing with a set of these PROMs.
Making the real (bipolar) PROMs is quite tricky. The first problem is that the address pins are labeled differently between a 3632 and a 2732. (A10 and A11 are swapped. On a RAM this wouldn't matter.) That's not a big problem. PNew can recover from things like that. CS3632.cm is a command file that will make a set of 6 3632s. Unfortunately, Intel never really figured out how to make these chips. I think they have been dropped. Fortunately, AMD's 27S43 is an alternate. Unfortunately, Prolog doesn't make the adapters to blow them.
So... To make 27S43s, I use the command file to make 3632s, but instead, make a set of 2732s. (Use the widgets for blowing 2732s. The command file doesn't know what kind of chip you are blowing.) Then send this set of chips out and get them copied into 27S43s. Note that the copy is a logical copy. They read the 2732s using the 2732 pin out, and write the 27S43s using the 27S43 pinout. That swaps the address bits. Thus you have to send them 2732s written with the address bits pre unswapped. That means you can't test the chips you send them.
When you get a sample set of 27S43s back, you can use Burdock to compare them with the raw Emulator.fb. The recipe is in the section on debugging the CP.
Software
Dicentras run the Klamath instruction set. If you have Mesa code that runs under UtilityPilot, it should be pretty easy to get it running on a Dicentra.
Building Boot files
The only part about building a boot file that will be unfamiliar to most Mesa programmers is MakeBoot. It's error messages are sometimes a bit obscure. Remember, for UtilityPilot, everything must be locked in memory somehow. Otherwise you get 915ed from PilotControl during initialization. Sometimes it is hard to figure out which module it is complaining about. Usually, a scan through the loadmap will uncover something fishy.
I usually lock things in memory by letting the Binder PACK them together with something else that is already locked. A few ALLs in the BootMesa file might be simpler, but I've never explored that approach. Scan the MakeBoot documentation in the Mesa User's Guide, and/or use Oscar or Fluke for examples.
I also let START traps do much of the initialization work. Alive is a module that's named UtilityPilotClientImpl and EXPORTS PilotClient.Run. UtilityPilot.bootmesa makes UtilityPilotClientImpl RESIDENT, so that specific name must be used. (You have to use a DIRECTORY statement in your config to dance around the name change.) Alive includes the code that bounces the dot in the MP and watches the Alt-Boot button to get you to CoPilot. It doesn't do anything silly.
If you use this approach, then it is trivial to add a new module to an existing boot file. Your new module's name will appear three times in a config: first to add an instance of it to the config, second to PACK it with something that's already locked in memory, and third to get it STARTed.
When setting up a new Dicentra boot file, you have to add it to some server's boot file list. Get a gateway wizard to help you.
Once you have built a boot file, you have to fix its checksum, and send it to a server. I normally make a command file that does the Bind, MakeBoot, FixChecksum steps, and another command file to FTP the new file to the boot server. (If you are booting from a 3MB net, you need to insert another step to Run PilotBootToEtherBoot to make the Pup format boot file.)
Accessing the Multibus
DicentraInputOutput contains all the opcodes needed to access the Multibus. MultibusAddresses contains the IO addresses of all the normal IO devices.
The Input and Output opcodes use a LONG POINTER to transfer a WORD of data to/from IO space. RawRead and RawWrite are similar, but they transfer to/from memory rather than IO space. They are normally used to access hyperspace. There are also 8 special Mesa opcodes to do byte transfers of even and odd bytes to hyperspace or IO space. There are 2 special Mesa opcodes to BLT data to/from hyperspace, 2 more to BLT data to/from IO space, and 2 more to BLT data to/from a single word in IO space. (The latter 2 are used by the 3MB ethernet board - the whole packet is poured through a single location.) The hyperspace opcodes can also be used to access main memory without going through the map, but you probably don't want to do that. See DicentraInputOutput.mesa, MiscDicentra.mc, or IOCopy.mc for the fine print.
RPC
There is version of Cedar's RPCRuntime that run's on Klamath/Calaveras. You can run Lupine (in the Mesa mode) using Cedar on your Dorado to generate the stubs, and then FTP them to a DLion to Compile the Dicentra version. Remember, there aren't any REFs on the Dicentra. Things are straightforward if you don't have any variable length data or other things that require storage. The tricky part is the things that would get garbage collected in Cedar. On the Dicentra, they are coppied over when you make the call. They get FREEd when you return to the stub. I remember this as follows: The caller owns the data, and can't pass ownership to you.
Peek Poke Server
FlukeDicentra.boot is a simple Peek/Poke server. It uses RPC via the Multibus interface.
Debugger Board
The Debugger board can be used for debugging microcode, and also as Control Store RAM so that microcode can be loaded on the fly. So far, all the operational programs will run from normal Control Store PROMs, so production systems don't need a Debugger board.
Switches
On the left switch, 1, 2 and 8 should be open/off. On the right switch, they should all be open/off.
Overview and Programming
Much of this discussion assumes that you are reasonably familiar with the CP board.
Normally, the Debugger board gets its clock from the CP. You can also work on a Debugger board without a CP by installing a crystal in the socket near the Burdock connector. (Normally, that socket should be empty.)
The pair of 50 pin connectors are for (short) ribbon cable jumpers to the CP board.
The 26 pin connector on the back of the card is for the Burdock cable. The other end plugs into the Burdock port on a DLion IOP board. (That's the socket at the bottom edge of the front of the IOP card. It's outside of the stiffener.) The pinout was intended to use ribbon cables, but there is too much crosstalk for that to work.
The Burdock port on a DLion is setup to connect directly to an 8255. There are 8 data bits, 2 address bits, a chip select, read and write strobes, and a reset line. (The IOP socket also has a boot line and an interrupt request, but they are only used when you are debugging the DLion.) The DLion can read and write 4 byte wide registers, so the Debugger board has 4 byte wide registers that can be read and written.
Register 0 is the command and status register. Register 1 is the byte wide data path to the 2950 on the CP. Register 3 is 2 nibbles called section and register. It's a pointer used to aim register 3 as the right place. (Yes, the "register" name is confusing.) Section 0 is the Control Store. Section 1 is the History Buffer. Register 3 is the data path to/from the rest of the debugger board. Page 18 of the prints is required reading at this point. While the CP is running, access to Registers 2 and 3 is switched to the Multibus path.
There is nothing tricky in the Status bits. Bit 0 is hard wired to a 0 so that Burdock can catch the case where you are trying to use BurdockDLion when you should be using BurdockDicentra. Bit 1 (run) is high if the CP is running. Bit 2 (HBDN) is high if the History Buffer is done. Bit 3 (BFULL) is high if the CP hasn't taken its data byte from the 2950 yet. Bit 4 (AFULL) is high if the CP has put a byte for Burdock into the 2950. Bits 5, 6, and 7 are C1, C2, and C3 from the CP. If anything other than one of them is high, something is broken or confused.
There are a few tricky parts in the Control bits. Bit 7 (INIT) activates INIT/ on the Multibus backplane. That's the Boot line. Bit 6 (CSA) uses the CAS register on the Debugger board to address Control Store RAM and ROM. When it is off, NIA from the CP drives the Control Store addresses. Bit 5 (RAM) disables the Control Store PROMs on the CP and activates the Control Store RAMs on the Debugger board. Bits 1, 2, and 3 (STOP, CLICK, and CYCLE) are used to halt the CP. STOP will stop the CP immediately, even if it is in the middle of a Click. CLICK stops it at the end of the current click, but ONLY IF the Multibus will be idle during the next click. CYCLE stops it at the end of the current instruction. They can also be used for single stepping. If you write the stop bits when the CP is already stopped, it will take the appropiate sized step. Stopping a machine at other than the end of a click may let a Multibus data transfer timeout.
Single CLICK doesn't really mean quite that. It keeps going until the Multibus machinery can be stopped at a safe place. Normally, that's only a few Clicks, but loops referencing memory may take a lot longer, or even forever. To Stop the CP, Burdock first tries Single CLICK. If that seems to take too long, it tries Single CYCLE. If that hangs, you are probably in the middle of a Multibus reference to a location that doesn't exist and your Misc board isn't timing things out. (Perhaps it isn't plugged in?). Burdock will then switch to just plain STOP.
Section 0 is the Control Store (CS) portion of the board. It has RAM to hold up to 16K microinstructions. Each bank of RAM chips holds 4K microinstructions. You can plug in up to 4 banks. You only need one for debugging.
The CS section has 16 registers. All the interesting ones are read/write so it is quite easy to check things out. Registers 0 and 1 are the CSA register. It is used to address Control Store RAM on the debugger board and ROM on the CP. Registers 2 through 7 make up the 48 bit word of a microinstruction. The CP should be stopped while you are writing control store to avoid parity errors. Register 8 and 9 are NIA from the CP. (Be sure that the CSA bit in the Control register is off or you will read the CSA register rather than NIA.) Register 10 (and 11 through 15) is called Temp. It's needed as a holding register when reading things from the Multibus, but it is also a handy way to checkout the internal data bus from Burdock.
Reading a CS register automatically adjusts the CS register to point to the next interesting register. This allows Burdock to read a whole microinstruction in one block transfer rather than having to read a byte, advance the register, read the next byte... See the arrows next to the chart on page 18. Similarly, the CSA register is bumped when the CS register is automatically switched from 8 (last byte of a microinstruction) to 0 (MSB of CSA) so you can write several microinstructions in a single call to the (slow) IOP.
To read the CP's PC, stop the CP, turn off CSA, and then read CS registers 8 and 9. To read a word from the CP's Control Store PROM, turn off RAM, turn on CSA, write the desired address into CS regsiters 0 and 1, and read/write CS registers 2 through 7. To the Control Store RAM on the Debugger board, turn on RAM, turn on CSA, write the desired address into CS regsiters 0 and 1, and read/write CS registers 2 through 7.
The Debugger board can force the CP to execute any instruction. Beware this is a bit tricky because of pipelineing. To do this, stop the CP, read some location from CP RAM, write the desired instruction there, set CSA to point to it, and single cycle the CP. Now restore the instruction to the location you borrowed. Your instruction hasn't been executed yet, but it has been loaded into MIR. The next instruction executed will be the desired one, but it will also load another instruction into MIR. Be sure that NIA or CSA is pointing at an instruction you like. Using this technique, you can write the CP's PC by executing a GOTO[xx] instruction.
Section 1 is the History Buffer (HB) portion of the board. It is a 256 word by 24 bit logic analyzer. Each 24 bit word holds the 16 bit PC from the CP and 8 extra bits. (The extra bits are wonderful - more later.) While the History Buffer is armed, the current word is written on each clock tick. On interesting clocks, the address is advanced to point to the next word. While all this is happening, the matcher is looking for an interesing PC. When it finds one, the HB gets triggered. After the HB is triggered, it waits for N more advances, and then disarms itself and sets HBDone. The N in the previous sentence is a critical concept. If N is big, the memory ends up holding mostly events after the trigger. If N is small, the memory will contain events before the trigger point.
Register 0 is HBAddr. It's used to read/write the HB memory. Reading registers 1, 2, and 3 gets 24 bits from the memory. Writing register 1, writes the current PC (NIA or CSA) into the PC portion of the memory, and the data byte being written by this write operation into the other 8 bits. Registers 4 and 5 are Match - the PC that the matcher is looking for. Register 6 is Count. After the matcher triggers, Count is incrimented each time a word is written into the memory. When Count reaches 0FF, writing is disabled and HBDN in the Status register is set.
Register 7 is the HB control register. It's write only. There are 4 HB control bits: 3 for HB mode, and another to manually trigger the matcher. The HB mode chart is on page 13 of the prints. Mode 0 will show every clock. Normally there will be 2 ticks per cycle, but if the CP is waiting for a response from the Multibus, you will see the wait states. Mode 1 shows every microinstruction. Mode 2 shows the first microinstruction of each clock. This is just a hack to compress data. Mode 3 shows the first microinstruction of every Emulator instruction. That compresses things even more. Unfortunately, there are a lot of Misc instructions.
Like the CS section, the HB register automaticaly advances to the next interesting register after every read or write operation. Again, see the arrows on page 18.
The 20 pin socket near the Burdock cable connector is the 8 extra data bits that go into the HB memory. The default jumpers setup various interesting signals from the CP. If you want to see when a signal is really happening, cliplead it up to one of these bits. For example, I used this to understand the interrupt latency when debugging the SDLC microcode driving the phone lines on the Misc board by looking at the interrupt request lines. Burdock expects to see DoIt, Cycle1, Cycle2, and Cycle3 on the low order bits, but it won't do more that print out of lot of crap if you connect up something else.
That socket also contains the output from the matcher. I've used it to trigger a scope on an obscure condition so I could see what was going on before the hardware did something crazy.
There is also an external trigger and external advance so you can brew up some external logic to trigger on something other than a PC match or control advancing the HM memory so you will see exactly the events you are interested in.
Sections 2 through 15 don't exist.
Logic details
There is only one clock on the Debugger board. The read and write strobes from the IOP and the control signals from the Multibus are synchronized before they are used. We had some troubles with clock delays and skew. The problem was that Run wasn't turning off fast enough. That's why PrePreArc is used on the Ctrl PAL.
Page 1 is the Burdock interface. When reading or writing, the IOP just flaps the read or write strobe. It doesn't wait for a response, but "knows" that it will be there in time. The Ctrl PAL does most of the work for starting and stopping the CP. The FF at u127b makes a one tick wide pulse out of the leading edge of the write strobe from the 8085 on the IOP. When Burdock reads data from the rest of the Debugger board (for example, a byte of Control Store), the PROMs controlling the CS (or HB) section are fast enough so that the desired info gets back to the IOP in time.
Page 2 is the Multibus interface. The low 2 bits from the switches go to CSBank PROM on page 5. They aren't used yet, but might be handy if you want more than 16K of control store and/or are scheming about some RAM/ROM overlay ideas.
Page 3 is the Section register, the clocks, the Burdock/Multibus switch, and several control signals. WAddrP is a one tick wide pulse at the start of a write to Section register. Run goes to the CP. Unless it is on, the CP can't do anything. ReadNIA determines wheather the CP drives NIA, or the Debugger board drives it from the CSA register.
Page 4 is the control logic for the CS section. The hard part is reading Control Store over the Multibus. You have to stop the CP (by turning off Run) switch the Control Store address drivers from NIA to CSA, put the desired byte on the Data bus, latch it into Temp, let the CP go back to work, and then drive the Multibus from Temp. Reads from Burdock use the same sequence, but the CP is already stopped in that case.
Page 5 is CSA, the bank selection PROM, and the address drivers for the RAM array. Page 6 is the '245s and '244s used to read and write the Control Store array and NIA/CSA. Pages 7 through 10 are the Control Store data chips.
Page 11 is the control logic for the HB section. Page 12 is the matcher. Page 13 is the advance and HB Count logic. The Advance PAL does all the work about decoding the HB Mode bits and cooridinating Advance and HBDone. Page 14 is the HB memory. The S157s on the bottom of the page are only used druing testing to write the HB memory from Burdock.
Debugging the Control Store section
TestDebuggerBoard is a program for debugging Debugger boards. All of the Test commands run until you poke the STOP key. While a test is running, Tajo's Notifier is tied up. (Translation: there is an hourglass in the cursor and the machine won't let you do anything else.) Each test prints out a ! occasionally to reassure you that things are working. To checkout the Control Store part of a board, start at the top left and run all of the Tests in a top to bottom, left to right order. Let each one run for several !!!s. You can actually start the first test, and then mouse ahead to start the rest of them, and then just poke STOP to go to the next one.
The Status command reads and prints the Status register. ReadStatus and WriteControl just loop (until you poke the STOP key) so you can scope things. ManyInit goes through the particular read, write, read sequence used by Burdock's initialization code. FlapBoot uses the Debugger board to flap the INIT/ line on the Multibus. Again, it loops until you poke the STOP key. BootDebuggee just does it once.
The Section command prints out the current value of the Section/Register register. TestSection verifies that the Section part of that register can be read and written. ReadWriteSection, WriteSection, and ReadSection are scoping loops.
The TestCSReg command tests the CS Register. It lives in the CS PROMs on page 4. TestCSRegIncr checks to verify that the auto-increment feature works correctly. (See the arrows on the chart on page 18.) ReadWriteCSReg, WriteCSReg, and ReadCSReg are scope loops.
The TestTemp command tests the Temp Register with 0 and FF. TestTempRipple tests it with all of the 8 bit patterns that are possible. If these work, the internal data bus is OK. ReadWriteTemp, WriteTemp, and ReadTemp are scope loops.
The NIA command prints out the current value of NIA from the CP. ReadNIA is a scope loop.
The CSA command prints out the current value of CSA register. TestCSA uses 0 and FFFF. TestCSARipple counts through all possible data patterns. WriteCSA, ReadCSA, and IncrCSA are scope loops. IncrCSA is actually reading and writing the last byte of the microcode, but that's supposed to increment CSA while it automatically adjusts CSReg back to 0.
SetCSA loads the specified (hex) value into CSA. CSRam prints the word of CS RAM pointed to by CSA. CSRom prints the word of CS ROM (on the CP) pointed to by CSA. Both of these commands automatically increment CSA (on a healthy board) so you can use them to poke around in RAM or ROM.
TestCS tests bank 0 of Control Store RAM. It takes a long time. WriteCS and ReadCS are scope loops. ClearCS fills all of bank 0 with 0s. SetCS fills all of bank0 with 1s.
SendCPData and Echo need special CP microcode. (It's been lost.) They were used for debugging the 2950 on the CP. Both send a byte to the CP, and then read a byte from the CP. The CP is fast enough so that there is no point in checking status bits. Echo will complain if the byte it reads doesn't match what it just wrote. SendCPData just discards what it reads.
FlapStop is a scope loop for debugging the stop/run timing on the Debugger board. PokeCount and PokeMatch are scope loops to stop the CP, poke the Count or Match registers in the HB section, and let the CP continue. This is what the Arm command in the History Buffer window does. These commands are leftover from debugging some timing troubles. You should be able to run these tests while Dawn is running. Well, almost it will get in trouble if you are unlucky enough to stop it in the middle of a memory reference. (They should also work with MemTest is running, but they use STOP rather than Single Click.)
TestDebuggerBoard contains all the commands we have needed to fix things. Don't be too surprised if something you want isn't there. If you want it badly enough, write it, or get a programmer to help you write it.
Testing other banks of Control Store
TestDebuggerBoard only checks the first bank of Control Store. If you have additional banks, use CPBankTester. It's on the intactive menu after you start Burdock. CPBankTester works on both DLions and Dicentras, so it calls CPKernel routines to do the actual reads and writes. Unfortunately, they fixup the bits that Mass generates. On the Dicentra, that means inverting the low order 4 bits. (On the DLion, it is much more complicated - the NIA bits get merged in between some others. Look at CPKernelCSDLion, or use trial and error by pulling chips or shorting a wire.)
Beware: There are 3 versions of code that test the first bank of Control Store: the first is TestCS in TestDebuggerBoard, the second is TestBank0 in CPKernelTester, the third is TestBank0 in CPBankTester. They don't print things out in the same format.
There are 4 TestBankN commands in CPBankTester. Each tests the obvious bank. When testing more than bank0, the last few words of each bank don't get tested because that's where the Kernel lives, and it is needed to switch (and unswitch) banks on a DLion.
CPKernelTester is another inactive tool that comes with Burdock. It is mostly for debugging microcode used in the CP Kernel, but it also contains several commands that are occasionally handy for debugging CP hardware and/or CP microcode. TestMIR reads and writes some location in Control Store with a pattern that contains two one bits. (That particular pattern has valid parity, so the parity fixing routines won't change anything.) The pattern shifts from 0000 0000 0003 to 0000 0000 0006, to 0000 0000 000C to ... to C000 0000 0000. If any bit in MIR is shorted high or low, this will find it. (Actually, it isn't testing MIR, but rather the inputs to MIR.) JumpNext fills bank 0 of Control Store with GOTO[$] instructions. The pattern on NIA should be conspicious when things are working right. FillBadParity fills bank 0 with instructions that will cause a bad parity trap. Either of these commands might be handy when chasing obscure wild branch bugs in microcode.
Debugging the History Buffer section
TestHistoryBuffer is a program for debugging the History Buffer section of Debugger boards. Again, all of the Test commands run until you poke the STOP key. While a test is running, it prints out a ! occasionally to reassure you that things are working. To checkout the History Buffer part of a board, start at the top left and run all of the Tests in a top to bottom, left to right order. Let each one run for several !!!s. You can actually mouse ahead on all of them, and then just poke STOP to go to the next one.
The Status, Section, NIA, and CSA commands are copied from TestDebuggerBoard. They just printout the appropiate register.
TestHBReg, and TestHBRegIncr test the HB Register. It lives inside the PROM on page 11. ReadWriteHBReg, WriteHBReg, and ReadHBReg are scope loops.
The Bits command prints the HB Control bits in u40. TestBits tests them.
The Match command prints the contents of the Match register on page 12. TestMatch tests it. Note that this doesn't test the matcher, only the Match register. SetMatch copies CSA into Match. The '682s on should now indicate a match. ClearMatch writes the compliment of CSA into Match.
The HAB command prints the contents of the HBA (History Buffer Address) register. TestHBA tests it.
The Count command prints the value of the Count register. TestCount tests it. ReadWriteCount is a scope loop. SpinCount sets the matcher and then writes a big number into Count. Count should count down through all of its values and get to 0. KickCount is similar, but it writes a small number into Count.
TestMatcher is the big one. It checks all the side effects of the matcher. It takes a while. Unfortunately, if it doesn't work, you don't get much to go on. (Sometimes putting a breakpoint inside the code will help.)
The HB command prints out the word of HB memory pointed to by the HBA register. TestHB tests the whole HB memory on page 14. WriteHB is a scope loop.
Again, TestHistoryBuffer has only the toys that we have needed so far. Don't be surprised if you want something that isn't there.
Debugging - odds and ends
If you don't have a Burdock cable plugged in, and the some PAL doesn't get cleared on Power Up, the Debugger board can hang the system. I've forgotten the details, but I'll update this section if I see it again.
CP Board
The LED on the back of the CP board indicates a Control Store Parity error. It gets reset every microinstruction, so something is solidly broken if you see any light.
There is a bug in the Bus Priority logic. It works, but not at full speed. If you are using a DMA device, you will have to use a slower crystal. 10MHZ works on the Versatec Color Plotter, but we haven't experimented much. (I think it can be fixed with a few blue wires and/or a PROM change.) If you don't have any DMA devices, you won't have any troubles.
CP Control Store
PROMs
A normal CP comes with 4K of control store in PROMs. There are 2 sets of standard 28 pin EPROM sockets, and 8K PROMs are now available, so you can get up to 16K of control store if you are desperate.
Like the DLion, the Emulator is about 3K. On the Dicentra, the initialization microcode can't be overlaid, so it chews up 300 words. Support for SDLC phone lines is roughly 400 words, the interrupt dispatcher is roughly 100 words, and the various forms of IO peeking, poking and sloshing are roughly another 100 words. (There are 60 words unused.)
The normal Dicentra Emulator microcode doesn't include TXTBLT.
The Emulator microcode is in expensive PROMs. Because of the cost, it will to be very inconvenient to make any changes to the instruction set.
Normally, the CP uses a 16MHZ crystal. Running at this speed, the CP is slightly faster than a DLion until it does a memory reference. Running at this speed requires fast, expensive PROMs for the microcode. If you are debugging microcode, you can use UV EPROMs, but that requires a slower crystal and a different PROM in CPBank-U28.
Accessing memory from CP Microcode
Beware: Mesa memory accesses are word oriented. Thus all the address bits are shifted left one bit position from what you might expect.
MAR← starts a normal memory cycle. Because the top 4 bits of the RH register are normally used for map flags, they are not sent to the bus. 0s are sent to AD17 through AD15, the 20 interesting address bits from YH/Y are sent to AD14 through ADR1, and 0 is sent to ADR0. (Remember that AD14 is on the P2 connector, so you can only access one megabyte of memory on a system without P2 connectors.)
MAP← starts a map cycle. Except for the timing, it is just like MAP← on a DLion.
Because 4 bits of the map flags normally are stored in RH and each map cell in main memory, a normal memory reference is limited to the first megaword of memory. Memory beyond that is called hyperspace. (The initialization microcode doesn't touch anything in hyperspace.) RawRef is an FY function used to access hyperspace. When RawRef is asserted, the top bit of YH/Y is ignored, the next 23 bits are sent to AD17 through ADR1, and, ADR0 is set to 0. This adds 3 more address bits.
IO← is an FY function that starts a reference to IO space. It has a builtin RawRef so you can control all the address bits on the bus. Many IO controllers only decode 16 address bits. Check the fine print if it might matter. Mass doesn't complain about possible page cross branching when you do an IO←. Since so many of the IO accesses involve adding small constants from the XBus to a base register which is known to have 0s in the low bits, this seems like a reasonable way to go. There is another IO← using FZ so you can do a branch while starting an IO access.
On a DLion, memory is a slow XBus device, so ALU operations or branching on MD don't happen in time. On the Dicentra, the delays needed to synchronize XACK/ leave plenty of time. Mass hasn't been modified to know this, so you still have to use LOOPHOLE[stw]. (MemTest is the only place I can think of that takes advantage of this.)
CP Microcode details
Dicentra microcode is very very similar to the DLion. The main differences are easy since all you have to do is ignore complications. On a Dicentra, there is no tasking. Honest folks, the differences between the two machines are trivial. We stole the whole emulator. Many modules required no edits. If you want to know how to program a Dicentra, read Garner's Dandelion Microcode Reference (DMR.press)Dandelion Hardware Manual (DLionManual*.press) and Dandelion Microcode Reference (DMR.press). Copies of these files are on [Indigo]<Dicentra>DLion>. You can skip all the chapters on IO devices.
Figure 3 is the Dicentra version of THE magic chart. It should be very familiar to DLion microcoders. All the functions for accessing IO devices have been deleted. The slots marked * have been reserved as NOOPs on the Dicentra to (slightly) simplify life for Burdock. For example, the same microcode can be used on both machines in some cases because the bit pattern for Refresh on a DLion is harmless on a Dicentra.
The details of accessing memory have been described above. There are only a few other new operations.
On a DLion, Bank← has 2 more cycles of pipeline dealy: if you do a Bank← in c1, you will execute out of the new bank on the next c1. On the Dicentra, there is only 1 cycle of delay: If you do a Bank← in c1, you will execute out of the new bank on c3.
DebA← writes a byte of data to the 2950 used to talk to Burdock. reads a byte from the other half of that chip. These are used only by Burdock. They overlay the corresponding DLions codes so the same microcode can be used.
ExtCtrl← writes 8 bits of data from the Y bus to the latches driving the MP. (It's on page 15 of the prints.) Bits 0 through 7 are ignored. Bits 8 through 11 are the decimal points on the MP. Bit 12 is unused. Bit 13 is IncMP'. The MP will increment on its rising edge. Bit 14 is ZeroMP'. The MP will get cleared when it goes low. Bit 15 is BlankMP'. When it is low, leading 0s in the MP will be invisible.
𡤎xtStat reads 12 bits of data onto the X bus. The high 8 bits are INT0 through INT7 from the Multibus backplane. Bits 8 through 11 float. Bit 12 is AltBoot from the MP. Bit 13 is Master' from the bus interface logic. (If it isn't on right after booting, the bus priority logic is probably broken.) Bits 14 and 15 are DebAFull and DebBFull from the 2950 used to talk to Burdock. (See pages 12 and 15 of the prints.)
Whenever any of the 8 INTx/ lines on the Multibus backplane changes state, the PALs on page 12 will generate a Mesa Interrupt. The microcode interrupt handler then scans the interrupt lines, and processes the ones that went down. (It's like watching for down transitions on a keyboard.)
Now for some really obscure fine print:
There is a change when interpreting a trap to microcode location 0. The 01 case means that the CP has been booted (via INIT/ on the backplane of the Multibus.) On a DLion, that case means the emulator encountered a parity error in main memory. Note that the first click of the trap handler will get executed repeatedly while INIT/ is low.
Since there are no TC bits to get left in a random state, the first instruction of a task doesn't need a CANCELBR[xx, 0F].
On a DLion, reading and writing during the same memory cycle does an exchange. On the Dicentra, that combination is a hack to test the data bits of the memory bus. The Dicentra should read what it writes. The only places where the DLion Emulator uses this feature are when returning frames or PSBs to the free list. On the Dicentra, an extra memory cycle is needed. (The Exchange with memory trick is also used by the Raven to clear out the band buffer as it sends bits to the printer. I don't know of any other uses.)
On a DLion, Bank← has 2 more cycles of pipeline delay: when you do a Bank← in c1, you will execute out of the new bank on the next c1. On the Dicentra, there is only 1 cycle of delay: when you do a Bank← in c1, you will execute out of the new bank on c3.
On a Dicentra, an IBDisp ignores the low 8 bits of the NIA field of the microinstruction. (On a DLion, you could OR them together. This was only used by Sunlight.)
CP Emulator Overivew
Most of the Emulator comes from the DLion with little or no modifications.
The initialization is all new. Unfortunately, it doesn't get overlaid. It checks lots of things, initializes various constants that live in U register, checks memory and sets up the map, and copies the germ from the EPROMs on the Misc board into main memory. Then it constructs a magic indirect link for XFER and dives into the normal Emulator.
The Dicentra Emulator contains several extra IO instructions. They are implemented in MiscDicentra and IOCopy. One interesting krock: for Klamath, somebody "fixed" the germ to save and restore the pulses clock when going to the Debugger. That raises havoc if you are using it for the time of day clock. Rather then unfix the germ (which would require cloning a big ugly module) I hacked the microcode to ignore attempts to write the pulses clock.
There are patches in the code to free frames and PSBs because the Dicentra doesn't support the exchange with memory trick that's used on the DLion.
Reading the pulses clock is a bit tricky. The hardware on the CIO chips has an extra bank of FFs so you can read both halves of a 16 bit counter in sync, but there isn't any way to sample a pair of 16 bit counters at the same time. Thus the microcode reads the high word, reads the low word, and reads the high word again. If both high words are the same, the low word couldn't have overflowed an a bad time.
Interrupt processing is the expected complication in the Dicentra emulator. On the DLion, the task microcode would OR the interrupt bits into nWW, and then turn on MesaInt. The Dicentra doesn't have any tasking so there isn't any task microcode to do that. The hardware turns on MesaInt whenever an interrupt line changes. InterruptDicentra.mc contains a preprocessor that runs before the normal process machinery looks at nWW. It scans for new interrupt requests and for each one it finds, it ORs the corresponding U register into nWW.
The SDLC microcode does all the work of IOCB processing to send and receive packets on a phone line. It should have been located in another CPU on another board, but this way avoided developing another debugging environment. The SDLC microcode is quite straightforward. There is a special case check for INT4 early in InterruptDicentra.mc. If the phone line CSB is setup, the preprocessor jumps directly to the SDLC microcode. It uses the Misc boards IntAck facility to get a dispatch vector, splits the vector into 3 bits of reason-for-interrupt and 3 bits of line number, converts the line number to a CSB, and dispatches to the appropiate service routine. All the state information is saved in the CSB or IOCBs. It wouldn't be very hard to add ring buffered support for TTY mode, but I doubt if there is room to do it without a lot of squeezing.
The problem with the SDLC microcode is that the interrupt latency of several sections of the main emulator was too long for two lines to work at 56KB. I dodged around this by checking for MesaInt at various critical but reasonably convenient places. To make some places convenient enough, the interrupt preprocessing section now has the concept of return-to-me. Most of the logic fell out of optimizing the no new interrupts in nWW case, but it is also needed when interrupts are disabled. (The HistoryBuffer was a lifesaver while working on this. I patched the microcode to have a trigger point for the overrun case, and added the INT4 wire to one of the spare bits. When it triggered, I scrolled backwards until the place where INT4 came on. The finky section of code was running by then. )
Logic details
Beware: Bit 0 on the CP prints is the MSB. The bit numbers get reversed as things go to/from the Multibus.
Clocking on the CP is very simple. Look at page 15. 2xClk only drives the Multibus control PROMs on page 13. Run comes from the Debugger board. It's used to stop everything (including the Multibus machinery). preClk and Clk'* go to the CPU. Everything gets clocked on the rising edge. DoIt comes from the Multibus control PROMs on page 13. If the CP isn't referencing memory, DoIt is high every other tick of 2xClk. That makes a 25% duty cycle for Clk'*. With a 16MHz crystal, they are high for 94ns then low for 31ns. During memory operations, DoIt the Multibus PROMs withhold DoIt to introduce wait states.
Page 1 is the 2901s. CarryOut, Overflow, and F.0 are branch condtions. Feq0 is wire ANDed together from all 4 chips.
Page 2 is some ALU related odds and ends, mostly having to do with shifts and carrys. This page also contains PC16, and the logic to read and write it. (PC16 is frequently used as a carry input to the ALU.)
Page 3 is the U registers. The U registers are read onto the XBus and writen from the YBus.
Page 4 holds the RH registers and the Stack pointer. The Stack prom does all the work of sorting out overflows and underflows.
Page 5 is the Rotater and the constant generator. The Rotater copies the YBus to the XBus, rotating by 0, 4, 8,or 12 bits. Rot4 rotates 4 bits to the right. Rot12 rotates 12 bits to the right, or 4 to the left. The constants go to the XBus. There are 2 forms of constants: 8 bit constants and 4 bit constants. (There is no provision for sign extending constants.)
Page 6 is the instruction buffer. It's a bit tricky, read Garner's description for the fine print. The top part is the data. The IB PROM does all of the hard work. The EnC2Funs FF on the bottom of the page disables memory writes when a page cross happens on a MAR← or an instruction tries to read data from the IB when it is already empty.
Page 7 is the parity checking logic, and FFs for MIR. Page 8 contains registered PROMs used for MIR decoding.
Page 9 is the branching logic and the link registers. All the branch conditons are unchanged from the DLion. (The 2 IODisp bits used by the DLion Ethernet are not used on the Dicentra.) The link registers are written from NIA, and can only be read by ORing them into the NIA field of a microinstruction. Again, see Garner for the fine print.
Page 10 is the NIA register. This is where the IB dispatching and branch conditions and link registers get merged into the NIA field of each instruction. ForceBank0 comes from the Trap prom on page 12 during INIT/.
The CPBank PROM is used to dance around the pinout differences between the AMD 27S43s and 2732s used for Control Store. (A 27S43 has an E and an E'. A 2732 has a CE' and an OE'.) The MapFlag outputs from the CPBank PROM go to the PALs on page 14 that drive the high order address bits on the Multibus. They could be used to allow the emulator to access more than a megaword of memory. ReadNIA and UseRom come from the DebuggerBoard. Their pullups are on page 16.
Page 11 has the sockets for the Control Store PROMs. Everything is setup for 32K chips, but the sockets have the extra pins needed for 28 pin chips. By tweaking the CPBank PROM, 64K chips could be used. Fast 64K PROMs are now available as MB7144s from Fijitsu.
Page 12 has the Trap PROM and the Interrupt PALs. The Interrupt PALs are identical. Page 19 is an exploded diagram. Basically, they automatically set Interrupt (the Mesa Interrupt Request FF) whenever any of the INTx/ lines on the backplane changes.
Page 13 has the Multibus control PROMs. This is one of the few sections of the CP that is drastically different from the DLion. The timing chart and state diagram are on page 20. Basically, the clock driving the Multibus PROMs ticks at least twice for each microinstruction. For non memory clicks, the states are C1FH (cycle 1, first half), C1SH (second half), C2FH, C2SH, C3FH, and C3SH. DoIt is low during all FH states and high during all SH states. It lets a clock pulse through to the CPU. (See page 15.) On Multibus reads, things hang in Read3FH until XACK/ comes back. Think of the extra steps as wait states. On writing, some time can be saved if the next click doesn't use memory. C1WFH, C1WSH, and C2WFH were all the spare states available. C1Wait is used while waiting to get control of the Multibus. Note that a normal memory operation is encoded as MAP← and IO, so it isn't possible to do that strange combination.
Beware: The 27S27s in the Multibus PROMs are running way over specs. If your CP is flakey, this is a good place to look. IO and MAP operations are the most sensitive. (I'm amazed that this works as well as it does.)
Page 14 has the data and address interface to the Multibus. Again, watch the LSB/MSB bit renumbering. The '576s on the lower right are used during MAP← operations. The ones on the lower left are used during MAR← and IO← operations. The PALs contain enough logic to sort out all the complexities about driving the high order address bits and ARD0 and BHEN.
Page 15 has the clocks, the Burdock interface chip, and the interface to the MP. On the clock area, notice that Run (from the Debugger board) stops the 2xClk which drives the Multibus control PROMs. DoIt comes from the Multibus control PROMs and disables the clocking to the rest of the machine during wait states.
Maintaince Panel
The MP is an extension of the CP. All the logic fits on one page. The N143 is a combined decimal counter, BCD to 7 segment decoder, and LED drivers.
Beware: As part of the general confusion about top/bottom pin numberings, the ribbon cable to the MP needs a twist on each pair of wires. It's done at the connector on the MP.
Debugging
Debugging a CP falls into two separate stages. On really sick boards, Burdock won't work. Once the board is over the hump, you can use Burdock to gather more data. Unfortunately, much of the CP (including the U registers) has to work before Burdock will run. This could be changed, but Burdock is normally used for debugging microcode rather than hardware, so things have been optimized to save space in control store.
The preliminary step in checking out a CP is running TestCS in TestDebuggerBoard and TestMIR in CPKernelTester to verify that NIA and MIR don't have any gross shorts.
The first real step in checking out a CP is to use the HistoryBuffer window to set Target to Error and do a LoadArmAndGo on Dawn. (Dawn is a spinoff from Garner's Sunlight for DLions.) Dawn needs a memory board: it tests the memory interface, the map logic, and the cancel write logic. It's also a very good idea to have a Misc board to timeout the Multibus in case the CP happens to address a location that doesn't exist.
On a good CP board, Dawn gets to Error once as it recovers from getting booted, and then bumps the MP every second or so. If your MP doesn't count, Arm the HistoryBuffer again, and this time it will probably show something interesting. If it doesn't trigger, something is really confused. Try ManualTrigger.
If the CP is really sick, there are lots of small hunks of microcode that are handy for scoping things. Look at [Indigo]<Dicentra>11.1>ScopeHacks>. Use LoadRaw to start them. It's easy to create more if there is a specific signal that you can't easily scope. If thing's go crazy, check for CP parity errors or use the History Buffer to verify that it is doing what you expect. (These are also handy on a DLion.) Many of these hacks use IB← as a sync point. It's handy and harmless.
Here is a quick summary. Look at the code for the details.
FlapShift wiggles all the shift 1 bit shift lines and Shift-End inputs. (It's leftover from chasing an obscure short.)
FlapPC16 wiggles all the signals near PC16 on page 2.
FlapStack wiggles all the signals near the stack PROM.
FlapTrap causes a stack underflow trap.
PokeBranch activates all the branch conditions. As much as possible, it makes both branches that do branch, and branches that don't.
PokeConst puts some simple constants on the XBus. It's real handy for chasing shorts.
PokeDevice wiggles all of the IO command signals, including the ones that aren't really IO devices, like IB← and LRotN. This is really a DLion program, but there is enough overlap with a Dicentra to be interesting.
PokeRot tries to wiggle all of the signals near the Rotaters. Things won't work right if the CPU is sick, so be sure to check the input signals on the YBus before jumping to any conclusions.
SpinAD generates all possible AD signals going into the 2901s.
SpinAF generates all possible AF signals going into the 2901s.
SpinAS generates all possible AS signals going into the 2901s.
SpinBank probably doesn't work on a Dicentra.
SpinRH puts a number into each RH register and then reads it back. Then it bumps the number and goes around the loop again.
SpinU wiggles a lot of signals near the U registers. It puts a number into a U register, and then reads it back. It does this for registers 00, 01, 02, 04, 08, 10, 20, 40, 80, and FF. Then it bumps the number and goes around the loop again.
SpinXY counts up in an R register as fast as it can. The result should be on the Y bus, and through LRot0, it should get to the XBus. This is handy for finding shorted bits.
Dawn also finds a lot of problems with CP boards that are healthy enough to run Burdock For example, Burdock doesn't use the IB dispatching. In that case, you can frequently put a breakpoint at the critical place and gather some more info by looking in the R Register. Beware, there are 2 versions of Dawn. Dwan.fb is setup for use with LoadRaw. DawnBur.fb is setup for use with Burdock.
To run Dawn with Burdock, Poke Boot in the CP Window, then select DawnBur, and poke Load. Then setup the CP Panel to show the desired registers and/or set the desired breakpoints. When you are ready, Poke Continue.
If you encounter a problem in a CP that Dawn doesn't catch, please tell me so I can try to fix it.
If you are looking for troubles, MemTest and DESTest also give the CP a lot of exercise.
You can check the Control Store ROMs by turning on the UseROM switch in the lower right part of the HistoryBuffer Window, poking BB to get it noticed, typing in "Emulator" somewhere and selecting it, and then hitting the Compare command in the CP Window. If things go right, it will take 30 seconds. You need the appropiate version of Emulator.fb on your disk. The current version of the Emulator microcode comes from [Indigo]<Dicentra>Nov26>Emulator>Public>. It's dated 4-Nov-84.
Memory Board
The LED on the back of a Memory board indicates a parity error. It gets cleared by INIT/, or another memory operation (excepting, of course, another read with bad parity). Remember, parity errors are normal if you power up a system and then read memory before writing it.
The Memory board does not support byte operations.
Switches
All switches should be open/off for the first memory board. Turn on 4 (rightmost) for the second memory board. Turn on 3 (and leave 4 off) for the third board. For the 4th board, turn on both 3 and 4... Remember, you need P2 connectors if you are using more than 1 memory board, and the Emulator can't use more than 2 memory boards.
Overview
There is nothing fancy on the memory board. It uses 64K chips. The data word is 16 bits wide, with a 17th bit for parity. There are 8 banks. That makes a total of 136 memory chips.
ADR0/ is ignored. The next 16 address bits (ADR1/ through AD10/) are fed directly to the address pins on the memory chips during RAS and CAS. The next 3 bits (AD11/ through AD13/) select the appropiate bank. The remaining 4 bits (AD14/ through AD17/) are used for board selection.
If there is a parity error during a read, the memory board puts the data it read onto the bus, but it doesn't generate XACK/. Eventually, the Misc board will generate a fake XACK/, and when it does that, it will also latch all the info on the bus. (If the data was what you expected, the error was in the parity bit.)
If there is a parity error during a read, the memory board puts the data it read onto the bus, but it doesn't generate XACK/. Eventually, the Misc board will generate a fake XACK/, and when it does that, it will also latch all the info on the bus. (If the data was what you expected, the error was in the parity bit.)
The CP can begin a new memory cycle every 800ns. Reads and writes take the same amount of time. (Actually, it is a bit slower than that if you correct for refresh.)
Logic details
On all of the prints, the bit numbering on the address and data bits follows the Intel/Multibus conventions. ADR0/ is the LSB, DAT0/ is the LSB. That's right/left reversed from the innards of the CP.
Page 1 has most of the timing and control logic. The refresh requests are generated by a simple R/C timer. Either a refresh request, or a memory request for this board starts the timing chain. The timing diagram on page 19 shows most of the interesting signals.
It's important that the LS14 used in the arbiter not be changed to an S14. The lower threshold voltage is critical. The jumpers on the outputs of the delay lines are there because we didn't know how converting the layout to a PC board was going to change the timings.
Another critical point is that WriteMB' (the output enable term driving the data to the Multibus) doesn't go low until after the data has been latched in the S373s. If you start driving the bus sooner, there is too much noise.
Page 2 uses the timing signals from page 1 to drive the memory chips. The lower right 2/3rds of the page is the address drivers. Each 240/244 drives 2 banks of memory chips. (The 240/244 helps to minimize fluctuations on the power requirements.) The 8 address bits for the memory array come from 3 places. The 393 is a counter that gets bumped during each refresh cycle. u4 and u5 drive the appropiate address bits from the Multibus during RAS or CAS.
The bank selection address bits are latched in u3 at the start of a memory cycle. They feed u19 and u16 to drive RAS and CAS for the appropiate bank of chips.
The S85, switches, and sip are used for board selection. There are 10K pullups on the address bits from the Multibus in case you plug the board into a slot without a P2 connector.
The P term on the ALS538 driving the RAS lines is wonderful for this use. It controls the polarity of the Y outputs, so they can all be flapped at the same time during refresh.
Pages 3 through 6 are data connections to the memory chips. Page 7 contains all the parity logic. During a write cycle, the output of the memory chips is disabled and r7 feeds a high to the S280s. Pages 8 through 15 are just the address, RAS, CAS, WE, and power connections to the memory chips.
Page 22 shows you where to find a particular memory chip. Yes, you have to search until you find the one you want. The chips in the memory array are numbered axyy, where x is the bank number, and yy is the bit number. (The parity bit is number 16.)
Debugging
The simplest way to find a solid bug in a memory board is to use Burdock to poke around in various memory locations. After you store something, Burdock automatically reads the contents of that location and shows you what it found. Simply storing various patterns into some location and watching what comes back will probably catch most stuck/shorted data bits. Poking Refresh in the CP Pannel will reread and redisplay all the locations currently setup in the CP Pannel. If you have the right locations visible, stores into one location will show up at another location when the address bits are stuck or shorted.
MemTest is the workhorse tool for testing memory boards. It's a collecton of all the tests I have written to chase any particular problem. While it is running, the decimal points in the MP will contain the current bank number. The MP gets kicked once each pass through memory. If the MP doesn't change every second, something is wedged. It takes 189 passes before things start over. That's about two minutes for one board.
When you Run MemTest, it sets things up and then halts in case you want to adjust some of the parmeters. lowBank is the first bank tested and highBank is the last bank tested. The default is to test the first 7 banks. That's the first memory board. If you think the problem is only in a particular bank, adjusting lowBank or highBank to skip that bank will verify that the rest of the board is healthy. Poking Continue will start the test. On a good memory board, MemTest will run forever. If anything goes wrong, you will get to a breakpoint.
If lowBank and highBank include bank 1, Pass 184 thorugh 186 test the Map. This is one of the critical timing paths in the CP. Yes, MemTest is also a good test of the CP.
Pass 188 includes a 5 second pause to see if anything will fall through the refresh cracks. (The main tests hit memory hard enough that most chips will remember their data even if refresh is disabled.)
On a DataMismatch break, address, expected, and found contain the obvious information. found2 is another copy of MD. found3 is another copy of the data from memory. Beware, MemTest works pretty hard to keep the CP busy, there could well be bugs in backing up the address to the right place. (There are actually two DataMismatch breaks. One with a MesaInt (from an XACK/ timeout, and one without.)
A break at MesaIntIsProbablyAParityError happens after a write pass if no board responds, or if there is a parity error with correct data due to problems in the parity circuit or a bad memory chip holding a parity bit.
Continuing after a breakpoint restarts the test at the beginning. If you ClearAllBreaks and then Continue, the MP will get set back to 0 every time an error happens.
In the back of MemTest.mc are a handful of simple scope loops. Search for ScopeReadLoop or ScopeWriteLoop, and browse around. You should check the microcode to be sure that they do what you want and/or you know what they are doing. Feel free to edit and recompile to tweak something. You can always BringOver a fresh copy to undo any real blunders. (@MemTest will Compile it.)
XACKTimeout.burdock is a simple command file that will read the data latched by the Misc board when it generates a fake XACK/. The results appear in the CP window. It will at least tell you if the problem is a memory board, a problem with an IO device, or a bug in the software.
MemBurnin.burdock is a command file that runs MemTest overnight to collect more than one data sample. It doesn't get used much. Mostly, it was an exercise in playing with fancy Burdock command files. It appends error info into a log file when anything goes wrong. To stop it, poke the STOP key when the mouse is in the CP window. (Poke STOP twice if you ran it from the Exec.)
Misc Board
Primarily, the Misc board contains the overflow from the CP. The rest of the board contains things that seemed handy for gateways. Most of the work is done by big chips (SCC, CIO) on an internal ZBus.
Here is a quick list of what's on the Misc board:
Power up booting, Watchdog timer, Software booting
Multibus timeout logic, CCLK
Germ PROMs
Timers for pulses clock and process interrupts
Phone line interfaces: 8 lines of RS232 with V35 interfaces on the first 2 lines
RS366 interface (Dialers)
DES encryption hardware and noise doide for random number generator
Switches
They should all be open/off except for 3.
Programming the Misc board
All IO operations to the Misc board are forwarded to an internal ZBus contianing 4 SCC chips, 6 CIO chips, and a DES chip. Their specs are in the AMD MOS Microprocessors and Peripherals book. Page 15 of the prints is the block diagram. The IO pins on the CIO chips do much of the real work on the board. If you are going to write any code for the CIO chips, you must be prepared to read the prints to find out which pins to wiggle. The discussion in the next section should help you figure out where to look.
The chart on page 2 shows the mapping between Multibus addresses and chip selection. Note that AD11 through AD 13 come from the RH register while AD10 is the high order bit of the R register. The address bits that get sent to the ZBus are the 8 low order word address bits. The CIO and SCC chips have an addressing mode that makes this useful. MultbusAddresses contains the addresses of all the chips on the ZBus.
The CIOs interrupt on INT0. The SCC chips interrupt on INT4. There is no interrupt from the DES chip. The device labeled IntAck doesn't correspond to a specific chip. It's used for processing interrupts from the SCC chips. All 4 SCC chips are chained together. An IntAck cycle goes through the normal ZBus handshaking to determine the first chip that is generating an interrupt request, and reads a dispatch byte back from that chip.
The SCC chips can talk to almost any kind of RS232 gizmo. The normal CP microcode includes support for SDLC mode which is used by gateways.
Logic details
Beware: The bit numbering is a bit mixed up. Internally, for example on the zData, mData, PromAD buses, bit 0 is the MSB. On the Multibus, bit 0 is the LSB.
If you are going to fix a Misc board, you will probably have to understand some software.
Page 1 is the interface to the Multibus. Page 2 is the ZBus controller. The timing charts are on page 16. Both the CIO and SCC chips require a 6 AS cycle delay between accesses. This is enforced by the ZBus PROMs, so the software doesn't have to worry about it. The ZBus is only a byte wide, so writes to the Misc board ignore the high byte and reads set it to 0. For speed, there is a word path to/from the DES chip. It transfers two bytes in one Multibus cycle. The word path bypasses the 6 cycle delay. The S74 driving zDS is needed because of some obscurities on the Reset timing for the DES chip. (The DES chip isn't really a first class ZBus citizen.)
The phone lines and process clocks need to interrupt the CPU. That's done by the PROM in the lower right corner of page 1. The 2 extra inputs to the PROM come from the Misc CIO on page 3. They might be necessary if a system is configured with more than one Misc board. (The Int PROM doesn't pay any attention to those bits yet.)
The Multibus timeout logic is the shift register on page 3. TOXACK clocks the data on the bus when the timeout happens into the six '576s on the bottom of page 3. It also goes into the Misc CIO which can be setup to interrupt the CP. The '576s can be read via the Misc CIO - the mEn bits from the B section select the desired chip. There are 2 unused bits on these chips. You can wire them up to something if you need some more info for chasing a problem. XACKTimeout.burdock is a Burdock command file that reads these chips and puts the data on the CP Panel. Running the normal initialization microcode generates a Multibus timeout and that will clobber the saved information. You have to use Burdock to get the info before it gets smashed.
Pages 4 and 5 contain the Germ PROMs. The addresses for the PROMs come from the EProm CIO on page 4. The EProm CIO also generates the PromOE' signal. The data is read via the Misc CIO and the mEn bits are used to select the desired prom chip. The sockets are generic 28 pin PROM sockets. They work fine for 64K through 512K UV EPROMs. The can also be used with EEROMs, but unfortunately, the sockets aren't setup right for 16K chips, so they need a blue wire for power. To write the EEROMs, the software must pulse the write enable pin.
Page 6 contains the clocks, the DES chip and random number generator, and the booting logic. The DES chip has many timing constraints. Don't be surprised if it stops working if you change anything. The randon number generator isn't very randon. I think the problem is noise from the power supply. Nobody has checked into it very much.
The booting section pulls down INIT/ when power is low, or Boot' has going low. The counter keeps INIT/ low for at least 6 ms. The Zener is the power up path. It lets q1 turn on when VCC gets to about 4 volts. Unfortunately, the new power supplys turn on very slowly, so 6ms isn't enough additional time for VCC to stabilize. The big cap adds enough extra delay. Boot' comes from the Misc CIO on page 3. (The 339 has an open collector output.) It can be activated directly by software, or connected to a counter for use as a watchdog timer.
Page 8 and 9 are the SCC chips and the RS232 level converters for 8 phone lines.
Page 7 contains the V35 (56KB) interfaces for the first 2 phone lines. Everything is carefully biased so things work correctly when you plug a modem into either the V35 interface OR the RS232 interface. (If you plug something in both of them at the same time, the signals will get ORed together. The 339s are open collector. They just pull hard enough to override the totem pole output in the 1489s.)
The Modem CIO on page 10 is the input path for the extra RS232 signals (DSR, RI) that didn't fit on the SCC chips. Pages 10 and 11 contain the Dialer CIOs and RS232 level converters. The Dialers are simply 24 input lines and 24 more output lines. There isn't any software yet. The C pins on these CIO chips all go over to a corner of the board near the Dialer connector. They might be handy if you wanted to use these chips as a parallel port. A counter section on these CIOs is used to drive loop back clocks. Each chip drives 2 lines.
Pages 12 and 13 are the filters and biasing for the RS232 level converters.
Beware: Like the DLion, a Dicentra doesn't work with Codex 9600 series modems. If your Dicentra is connected to one of them, I suggest you remove the appropiate SIP.
A Mesa machine needs two clocks. The exact rate of either clock isn't critical, the processor head exports the appropriate values. The Pulses clock is 32 bits wide, and gets incremented every 10 microseconds. This is used for timing short intervals and to derive the time of day clock if the machine doesn't have any better hardware. On a Dicentra, the Pulses clock lives in the Misc CIO on page 3. The second clock is used by the process timeout machinery. It needs to generate an interrupt every 50ms. On a Dicentra, it lives in the EProm CIO on page 4.
Debugging a Misc board
There are two sets of tests for checking out the Misc board. The first set is raw microcode. They are run from Burdock. The second set is Mesa code. They are included in Ocsar. There is a summary of this section in MiscDebug.doc. I run the Burdock tests by loading MiscDebug.doc into a file window and copying the name of the each test into Burdock's CP window.
The Burdock tests all bump the MP every second or so while things are working ok, and hit a breakpoint if anything goes wrong.
Beware, some of the inputs to the big chips float low. (I guess they are just trying to confuse people like me.)
Even if the Misc Board is pretty confused, the machine should still Boot, and put something in the MP when you poke the Boot Button. If it doesn't, check the clocks and INIT/ logic on page 6.
CioTest makes sure that all 6 CIO chips talk to the ZBus. Of course, the Multibus has to mostly work. SccTest makes sure that all 4 SCC chips talk to the ZBus.
DataTest checks a lot of the data ports comming out of the CIO chips. It needs an echo plug on the dialer port.
LatchTest tests all the logic for latching the info when a BUS timeout happens. The CP, the Misc board, and any Mem Boards need P2 connectors.
DESTest is a good test of the internal ZBus. This is the only way to test the word mode interface to the Multibus.
ClockTest tests the clocks as used by the Mesa Emulator. There isn't any thorough test of all the clocks on all of the CIO chips.
EERomTest tests a pair of Xicor 2816 EEROM chips in the sockets labeled Germ4 and Germ5. Beware: This is a destructive test. The first pass writes 0s (MP 0-2048). The second pass writes 1s (MP 2048-4096). The third pass writes the address of the word being written (MP 4096-6144). Then it falls into a loop checking what the third pass wrote. After the first 3 passes, the MP has dots on and gets bumped by one each scan. The EEROMs can only be written 10,000 times. That won't be a problem when used to store a parameter file, but you could wear out a chip if you aren't careful when debugging.
TTYTest runs all 8 lines at 9600 in TTY mode. It needs 8 echo plugs. Beware: This test doesn't complain if it doesn't receive anything. Stop it after a while and verify that sent* and recv* counters are all going, and about the same. The loopback clocks should all be flapping if you need to scope them.
It's not uncommon to find an SCC chip with a broken section, or a section that doesn't work in a specific mode.
SDLCTest runs the first 2 lines at 56KB in SDLC mode. It needs 2 echo plugs. Use the 56KB echo plugs instead of the normal ones to test the 56KB path. Beware: This test doesn't complain if it doesn't receive anything. Stop it after a while and check the counters. .MR 108 is the number of packets sent on line 0. .MR 10A is the number of packets received on line 0. .MR 118 is the number of packets sent on line 1. .MR 11A is the number of packets received on line 1. Packets on line 1 are shorter (.MR 214) than packets on line 0 (.MR 204) so there should be more packets going through line 1.
The following tests are writen in Mesa. They are included in Oscar. Use Chat to talk to it. Most of the tests run forever. Type something to terminate them.
PhoneLine Thrash runs all 8 phone lines in SDLC mode. You need 8 echo plugs. The first 2 lines run at 56KB. Use either the RS232 echo plugs, or the V35 echo plugs. The other 6 lines run at 9600 baud. All 8 lines should receive as many messages as they send (less 1 or 2). On the printout chart, G is Good, B is Bad. If lines 2 through 7 don't work, either the clock is sick, or the SCC doesn't work in Sync mode. (TTYTest tested the data paths.) It normaly prints out a cryptic line of junk when starting. Each clump of 3 or 4 characters is a bad packet. I've forgotten what it means. Look in the code if you really need to know. I think it is an initialization bug in the software/microcode. That's why the first packet on each line gets mashed.
Test Dialers Noisy flaps all 24 RS366 lines. (You need an echo plug.) Test Dialers Quietly is the same, but it doesn't print anything. It's intended for use with a scope.
DES Fixed Pattern Tests, DES Loop ECB, and DES Loop CBC are more DES tests. If they don't work, but Burdock's DESTest worked ok, the chip is probably broken. DESTest uses only a single pattern. These tests use many patterns and also test the software and emulator microcode.
Test Mesa Clocks is a good test of all the hardware, microcode, and software used to implement the clocks. (It's leftover from chasing some nasty problems.) The first 3 sections sample the clock and printout the numbers and the differences. If the differences in each clump are not very close, something is fishy. The next section (scanning for Hickups) is looking for cases where the clock goes backwards. The last section compares the time of day clock with a WAIT for one second as determined by the process ticker. The first column is the number of microseconds in each "second" of waiting. Things should be quite close. The other columns are the fine print - look at the code. Typing STOP (while the mouse is in your Chat window) to terminate the current section of the test sooner in case you are getting impatient.
When you are all done, use the Boot Button command to test software booting. Just watch the MP. It will be obvious if it works.
3MB Ethernet Boards
The 3MB boards can hear their own packets. This means that PupEcho to your own host number on a 3MB net is testing most of the board. The packet goes all the way out to the transceiver and back in again.
When sending, the controller doesn't tell the software how many collisions a packet encounters. Thus all packets look like they didn't have any collisions which makes the collision histogram a bit dull. (If lots of packets have been sent, you would probably be suspicious enough to guess something like this. This paragraph is mostly a reminder so that you don't go too far out on a limb while chasing an obscure bug.) There is a status bit for "too many collisions". It actually means "tried too long" rather than too many collisions, but it will go off if the net is broken.
Beware: Older versions of these boards from SUN or CADLINK need 3 blue wires and new microcode. Don't use unmodified versions: aside from mashing your packets, they will occasionally trash the whole net.
You can run a 3MB board at half speed (for use on the Voice net) by simply changing the crystal.
A 3MB board doesn't need a P2 connector.
Switches
There are 2 switches on the 3MB board. If you hold the board with the chips so you can read them, P1 will be on the lower right and P2 on the upper right. The upper switch, S507, is the host number, and the lower switch, S505, is the board address.
S507 is the host number. Closed/on is a 0 and open/off is a 1. The LSB is on the left (1) and the MSB is on the right (8). The bits are wired backwards. I set the host number by turning the board upside down.
S505 is the device address. For the first board, they should all be open/off except 7. For the second board, close switch 1 too. For the third board, close switch 2 (and leave 1 open). For the 4th board, close 1 and 2. (So far, the software only uses the first 3 boards. It will be trivial to add more.)
Blue wire
The 3MB boards have one cut and one blue wire. (We have several older 3MB boards around PARC. They need 3 blue wires.) The trace on top from pin 4 of U310 (the upper 2951) goes over to the right and vanishes under an LS533. Cut it. On the bottom of the board, run a 1/4 inch of wire from that pin over to pin 25 of U308 (the other 2951). That pin was previously cut, so the wire will have to stick through the board and reconnect to the remains of the pin.
12V (aka Red or Dorado) Transcievers
It's easy to modify a 3MB board to work with a Red transciever. The transciever is setup to get +12 on the 7th pair of wires in the drop cable.
On the top of the board, cut the fat trace from the power converter over to the connector. At the connector, add a jumper from pins 22 to 24 (GND). At a long wire from pin 23 to the +12 on the P1 connector. That's about as long a run as you can get on the board. The +12 is the 4th pin from the right edge of the P1 connector if you hold the board solder side up with the P1/P2 connectors towards you. (The P1 will be on the right.)
Programming the 3MB board
The tricky part about talking to the 3MB board is that the the receive data path has a front porch (in the 2951s). This adds a word of pipeline delay. Thus if you get a receiver interrupt, and read a status word that reports that the buffer is empty, read another status word.
Odds and ends
The 3MB boards won't work on an extender card. The problem is that there is too much noise and/or cross talk on the address lines when the 2951s driving the data bus turn on during a read cycle. The output of the LS521 (U506) generating BUSSEL\ glitches. It's worse if the chip in U407 is an S138 rather than an LS138.
Mux boxes and RED Transcievers
The 3MB for use at PARC have all been modified to use 12V transcievers. These are the ones painted bright RED. They are also used by Dorados and Etherphones, so there are plenty of them around. The change requires a cut on the fat trace from the power convertor box, 1 long wire to bring +12V from the Multibus to the Ethernet connector, and 1 short jumper at the Ethernet connector for GND.
The reason for this change was to allow Dicentras to work with Mux boxes. Unfortunately, that that didn't work out very well so far. Stay tuned....
Debugging
The T1 tests can also be used on the 3MB board. The T1 tests send packets to all hosts on the net. You probably want to do your testing on a private net. T1Thrash will complain if anybody else sends a packet, so you probably don't want to share the net with anybody. I use one of the small widgets with 2 red LEDs and 2 green LEDs. (Warning, you have to plug your drop cable into the correct end.)
T1 Boards
Much of the logic was snitched from the Stanford 3MB Ethernet board. In particular, the Multibus interface looks just like a 3MB board, and it is all setup to retransmit after collisions. To the software, a T1 board looks just like a 3MB board. Use EthernetOne in the parameter file. Read the previous section for more information about the 3MB boards.
The T1 board can talk to itself if you have an echo plug installed, but it can't hear itself in normal operation. The software doesn't understand this, so don't be surprised if nothing works when you try to PupEcho to yourself via a T1 board.
A T1 board doesn't need a P2 connector.
Switches
Just like the 3MB boards, there are 2 switches on the T1 board.
The switch in y29 is the host number. Closed/on is a 0 and open/off is a 1. The MSB is on the left (1) and the LSB is on the right (8). Unlike the 3MB boards, this is the way you would expect.
The switch in aa20 is the device address. For the first board, they should all be open/off except 2. For the second board, close switch 8 too. For the third board, close switch 7 (and leave 8 open). For the 4th board, close 7 and 8. Note that first and second refer to the combination of 3MB and T1 boards. You can set them up in any order, but it is probably simpler if all the T1 boards come after all the 3MB boards.
T1 rules
The fine print is Bell System Technical Reference PUB 41541. Be sure you get an up to date version. The latest one I've seen is marked January 1983. The May 1977 version is very different.
"T1" isn't a nice crisply defined interface yet. It was designed to cram many phone conversations under the streets of New York City. If you put repeaters every mile, you can get 24 conversations into a single twisted pair. To do that, phone company takes 8 bit samples on each line 8,000 times each second. 24 lines * 8 bits/line is 192. They add a 193rd bit for framing. 193*8000 gives 1.544 megabits/second. That's how I remember the T1 bit rate.
The basic rules are that you have to keep the repeater happy. That requires that your transmitting frequency be close enough to the resonant frequency of the repeaters tank circuit and that the data pattern contain enough pulses to keep the tank circuit ringing. The pulse density restriction is a bit complicated. As long as you have at least one bit on in each 8 bit "voice" sample, you will be ok. That means that there will be at most 15 0s in a row. (If the framing bit is a 0, and the preceeding sample is 10000000, and the following sample is 00000001, you have a total of 15 0s.) The older specs called for at least three 1 bits within every 24 bit window. (I think they forgot about the framing bit.) Clearly, they are trying to require at least one 1 bit within every 8 bit voice sample.
I think the real reason the clock needs to be quite accurate is because of the digital muxing scheme the phone companys use. An accurate crystal is good enough: 0.005% is 50ppm. That doesn't require anything really fancy, but it is the best of the standard small packages.
At the analog level on the wires, a 1 bit is a pulse in the middle of a bit cell. The pulse is half the width of the bit cell. Each pulse is 3 volts into 100 ohm balanced load. For a 0 bit in a cell, there is no pulse. Pulses alternate polarity so that the DC signal is 0. With this arrangement, it doesn't matter if you crisscross a pair of wires. There is no extra clock signal. You have to recover the clock by watching the data. Two consecutive pulses with the same parity is called a bipolar violation.
The new rules require a lot of mumbo jumbo on top of this. You have to put a fancy pattern onto the 193rd bit so they can sync up. They also want a 6 bit CRC for the previous frame. I don't really understand all the fine print. One good idea is that they have a way to let you send a sample of eight 0s by sending a special pattern with 4 pulses that have the wrong parity. (If you would expect 4 pulses to be +-+-, they instead send -++-.)
The horrible complexity of the new rules is not needed for local T1 lines or some microwave links. I plan to ignore them until I can understand them. I think it will require a fancy big chip before it is sensible to follow all the rules.
Another interesting complication about the way the phone company implements T1. If you get a long T1 line, they will mux it together with other T1 lines and demux it at the other end. The fine print of the way they do this requires that the transmit clocks at both customer ends be in sync. They use the transmit clock as the receive clock at the demuxer. If your clocks are not in sync, bits will get dropped or inserted. (I don't know how to implement something like this.)
Our packet format
The critical observation is that SDLC packets don't have any long strings of 0s. Thus if you inverted the data before sending it, an SDLC packet would keep a T1 line happy. Unfortunately, I couldn't think of any reasonably way to use an SDLC chip. (AMD claims their AMZ8036 will run at T1 rates. I haven't tried it.)
It's actually not too hard to do the bit stuffing or unstuffing. Just let a PROM watch the bits go by, and have it mask off the clock to the shift register when it needs to insert a bit. Unfortunately, that's not the only problem with making SDLC packets. I couldn't find any reasonable way to check the CRC. (The 9401 checks for all 0s. The SDLC expects a magic constant.)
I ended up using the packet format from the 3MB Ethernet: preamble bit and all. That had the advantage that I could put a scope on a 3MB Ethernet board and get a few sample packets to use for debugging.
So here is the packet format:
An idle line is all flags. A flag is 10000001. (That's 6 zeros in a row.)
Start with a 3MB Ethernet packet. That's a single 1 for the preamble bit, n 16 bit words, and a word of CRC. The preamble bit is included in the CRC. (The fine print on the CRC is that it uses mode 0 on a Fairchild 9401 which gets cleared to 0s before sending the first bit.)
Starting at the beginning, if any place in the 3MB Ethernet packet has six 0s in a row, insert a 1 bit after the 5th zero. The stuffed bit doesn't change the CRC. You have to check for six 0s in the CRC too.
Note that you can't tell that a packet has ended until 7 bits after it ended. This makes CRC checking a bit tricky since you can't back up the CRC checker.
Extra signals at the connector
There are several extra signals on the T1 connector. The idea is that jumpers in the connector can easily make the normal case work, but that the extra signals are there in case you want them. Some of their possible uses include:
You could simply externally clock the transmitter. This will be necessary to use a line that the phone company is sending through their multiplexor scheme.
You could multiplexing several T1 boards onto one T1 line by masking the external clock pulses. Two boards can alternate bits or several boards can alternate bytes without violating any bit density rules.
You can also make a shared line look like an Ethernet by using Line.Defer' and Line.Carrier'. The transmitter is all setup to retransmit after collisions.
The raw line could be shared with voice services. The T1 board will use all the available bandwidth, but it will also run with any reasonable portion of the line. (If you go too slowly, the packets will timeout before they get sent.)
Extensive external hardware could also be used to make the existing board conform to the new T1 rules.
Logic details
The clocking on the T1 board is a bit ugly. Except for a few places, all the clocks are derived from the same crystal, but many signals are clocked on the wrong edge, or clocked by PROM outputs rather than cleanly qualified clocks. The 2901s run at 162ns. Most of the small PROM machines run at 81ns.
Page 1 starts with the analog interface to the line. (Thanks to Bill Gunning.) It might be possible to find a chip that had 2 or 4 comparators, but we had the LM361s in the lab, and they are fast enough. (The pulse is only 325ns wide, so many comparators will be too slow.) R.Ref is half the average size of an incomming pulse. The transistor is needed because the leakage through all 3 LM361s might be too high if there were a long sequence of 0s on the line. During normal operations, the input to the transistor stutters during each 1 bit.
The second part of page 1 is the clock recovery (CR) section. The CR PROM is running at 8 times the nominal bit rate of the line. Every time it sees the rising edge of a pulse, it puts out a tick on R.MyTick. If it has counted 8 ticks since the previous tick, it puts out a tick anyway. If a rising edge happens in a strange place, it assumes it has lost sync and reinitializes itself. Actually, it doesn't put out a tick on every rising edge. If Line.RecvMask is low, the tick is masked off. (Think of it as an AND gate that's been pushed into the PROM to save a gate.) That's how the receive side implements muxing. Similarly, Line.R-Out goes to the connector and comes back in as Line.R-In so you can bypass all the analog section, and its possible timing delays, if you are building an external muxing box.
The bottom of page 1 is the bit unstuffing (BU) section. The main purpose of this PROM is to skip over the stuffing bits in the data stream. (Pd stands for Phase Decoder. On the 3MB board, Pd.Carrier and Pd.Shift come out of the Phase Decoder PROM.) During a packet, Pd.Shift will normally be high in the clock period immediately after R.Tick. The BU PROM counts zero bits. When it gets to 5, the next bit is skipped by not turning on Pd.Shift.
Since BU PROM already has all the logic to watch the incomming bit stream, the it also does the carrier detection. The 7 FFs are used to delay things so that the CRC chip hasn't already processed the flag when the PROM figures out that the packet is finished. At the start of a packet, Pd.Carrier is held off while the delay chain is getting filled. During this period, the PROM has to count to 7 as well as keep track of the number of zeros. That's way it needs so many state bits.
Note that it doesn't make any sense to be shifting in new data bits (Pd.Shift) when there isn't any carrier, so that bit combination out of the BU PROM can be used to indicate an Abort sequence on the line. (The existing PROM doesn't do this. This trick would conflict with loading the 7 delay FFs.)
The top of page 2 is the receiver control (RC) section. Rx.Word comes up when the shift register is full. Rx.FdOut is the output from the host filter ram. Remember, this board is really a 3MB Ethernet board. Host numbers are only 8 bits, so the packet filtering can be done by indexing into a bit vector stored in a RAM. The RAM is on the next page. Rx.Enable' goes to the shift registers on the next page. They need to get disabled when writing into the filter RAM.
The cloud of FFs on the bottom of page 2 are the handshaking signals to/from the 2901s and the Multibus. C.Eq indicates that the low order 11 bits of the ALU are zero. That's used when comparing 2 pointers into the packet buffers. R.Overflow means that this packet didn't fit into the buffer. R.Abort and R.CrcErr are just storage for those error bits until the 2901s can copy the ending status into the buffer. R.ReadyReq indicates that there is a word of data for the 2901s. R.EndReq tells the 2901s that a packet has ended. R.Interrupt tells the Multibus that there is data available to be read.
Page 3 is the shift registers, the holding registers before or after them, and the Address Filter Ram. The address for the Address Filter Ram comes from either the high byte of the receiver shift register, or from the Muldibus via an LS240 on page 9. The only tricky part of the shift registers is that the transmit one are clocked a whole bit cell early so that the CRC chip will have time to get setup.
Page 4 is the transmitter control (TC) section. Again, this board is really an ethernet board, so Line.Defer and Line.Coll are fed into the PROM. Tx.Carrier comming out of the PROM tells the bit stuffing PROM (on the next page) that a packet is now being sent. The Tx.PU input to the S151 is used for the preamble bit.
The FFs on the bottom of page 4 are used for handshaking between the transmit control section and the 2901s and Multibus. Tx.Ready indicates that the LS374s in front of the shift register are empty. T.AbortReq tells the 2901s that this packet collided with something. Tx.Inhibiit is set by the 2901s to tell the transmit control section that there is no (more) data to send. Turning it off is the signal to start sending a packet. T.Interrupt tells the Multibus that the packet being sent is finished. Tx.Timeout is set by the 2901s when it has been trying for too long to send the packet. This board doesn't retransmit only 16 times, but rather keeps retransmitting until a timer runs out. See the microcode comments for the details. Tx.Timeout is set by the 2901s when it gives up trying to send a packet. It also sets T.Interrupt so the Multibus knows the packet is finished too. Tx.Timeout can be read from the Multibus. Reading the switches clears both T.Interrupt and Tx.Timeout. That's a bit ugly, but it doesn't take any gates.
Page 5 starts with the bit stuffing (BS) section. I thought I was going to be able to merge the extra FF, inverter and AND gate used to make Tx.Tick into the PROM, but it didn't fit.
Line.TranClk is the transmit clock. The key to understanding this section is to notice that Line.TranClk does dual duty. In the Polarity Encoder section below, Line.TranClk is ANDed with the data bit (Line.T-Out) to create a pulse on the line. Thus a 50% duty cycle clock will drive the line at full speed. Line.ClkOut is 1.544MHz clock available at the connector that can be jumpered back in to Line.TranClk. A mux box gives a bit cell to this board by flapping Line.TranClk. There can be an arbitrary time between clock pulses, but each pulse must be half a bit cell wide.
Because of that ANDing, Line.T-Out can change while Line.TranClk is low. Thus the second job for Line.TranClk is to trigger the BS and TC PROMs into getting the next data bit ready before another clock pulse comes along. The tricky part of this section is that there is a long delay from Line.TranClock through the synchronizers to Tx.Tick through the BS PROM and the TC PROM before Tx.DataBit changes. Tx.Tick is a pulse on the leading edge of Line.TranClk. I tried to do it on the trailing edge, but the delays through the PROMs were too long. (An extra bit of buffering for the data bit at the BS section would make that approach work fine.) The extra FF after the synchronizer for Line.TranClk delays things long enough to make sure that Tx.DataBit doesn't change too soon and mash the end of a data bit as it is being sent to the line.
Now for the easy part. The bit stuffing PROM generates the flags when the line is idle. When it gets Tx.Carrier from the transmit control section, it waits until the end of the current flag, and then starts sending the data. It counts the 0 bits, and if it gets to 5, it inserts a 1 bit. Tx.Shift and Tx.BitClk go back to the transmit control section to kick another data bit through. Line.T-Out and Line.T-Active go to the T1 connector in case an external mux box prefers TTL signals. Line.T-Active is high when this board is sending data. It's low during idle periods when sending flags.
The FF in the Polarity Encoder section remembers the polarity of the last pulse that was sent. It gets inverted every time a 1 bit is sent. Note that the clocking on this FF is not synchronized with the main crystal if an external clock is used.
The Line Driver section turns TTL levels into the desired analog signals. The 220 ohm resistor to +12V is a current source. The transistor sucks up all the current that doesn't go through the transformer. The interesting thing about the N07s is that their open collector output transistor is strong enough to take the roughly 7 volts that appears on the side of the opposite side of the transformer from the active N07.
Debugging
The T1 board will happily send packets to itself. This makes debugging all the bit serial sections just a matter of following the signal through until you find out where something is getting lost or smashed.
A critical stage in checking the design of a board like this is to connect a very stable oscilator up as an external clock. If it is running very close to the on board clock, all the synchronizers will get plenty of exercise. I uncovered two more PROM bugs this way.
There are 2 microcode programs for debugging T1 boards. Both need an echo plug. For both tests, key is the value of the first work in the packet. wordIncr is added to each word to get the value of the next word. packetIncr is added to key each time around the loop.
T1Test is a simple test and/or scope loop. It only complains about gross things, like the switches not being reasonable. dally is a number used for a CPU spin loop that determines how long it waits before sending another packet. It doesn't complain about any recv problems, but it puts a sample of recv data into U registers so you can see what comes back with Burdock. This lets you poke around to look for stuck bits or other errors of that nature.
T1Thrash checks the data that comes back. (It seems to get a CRC error (WrongLength) on the first packet after power up. I think that's a PROM bug.) T1Thrash starts by sending a packet of minLength words long. Then it bumps the length by 1 and sends another packet. It stops after sending one maxLength words long. The Burdock command file is setup to send huge packets. This is the only way to test the back half of the transmit buffer RAMs. The MP gets bumped after each run of packets. The dots in the MP hold the number of good packets/16.