AT&T 3B2/310 and 3B2/400 System Internals

1 Introduction and Overview

The purpose of this document is to keep track of my exploration of the internals of the AT&T 3B2/310 and 3B2/400 computers, for the eventual purpose of emulating the system.

There is scant information online about the internals of the 3B2. It has proven very difficult – nearly impossible, in fact – to find detailed documentation about how the 3B2 actually works. This document is a collection of notes taken during the process of reverse engineering the 3B2 system.

But why the 3B2? In main part because it is historically significant, and yet not very well known. The 3B2 was AT&T's main porting platform for System V Release 3 UNIX™ (SVR3). It is a fully 32-bit computer system built around a microprocessor and chipset by Western Electric called the WE32100. The WE32100 and its earlier predecessors, the WE32000 and the BELLMAC 32 processor, represent major leaps forward in building architectures specially suited for UNIX.

2 Links and Source Materials

The following are the source materials I've been using in my quest to understand how the 3B2 works.

3 Hardware

3.1 Major Components

Visual inspection reveals the following major components on the System Board.

  • WE32100 CPU
  • WE32101 MMU
  • WE32102 Bi-phase Crystal Oscillator
  • WE32106 Math Accelerator Unit (Optional)
  • 4 x D2764A EPROMs holding the system boot ROM
  • TMS2797NL floppy disk controller
  • NEC μPD7261A hard disk controller
  • NEC μPD8253C interval timer
  • AM9517A Multimode DMA Controller
  • SCN2681A Dual UART
  • MM58174A Real Time/Time of Day clock

3b2_block_diagram_clean_sm.png

Figure 1: 3B2 System Board Block Diagram

In addition to these major components, there is a tremendous amount of LSI glue logic, plus 14 PLAs/PALs on the system board. These seem to implement the DRAM controller, Control Status Register, and Interrupt Logic. Their exact layout is unknown, as no schematics are available.

Finally, there is one 18-pin DIP package IC labeled with in-house part number "O WE 62C", stamped with a date code and the number "53". The chip remains unidentified. Presumably it is custom LSI logic.

3.2 WE32100 CPU

As stated, the CPU is the WE32100 32-bit CPU. It has both a 32-bit address bus and a 32-bit data bus. The CPU has 9 general purpose and 7 special purpose 32-bit registers, supports four privilege modes (User, Supervisor, Executive, Kernel), supports addressing in words (32-bit), halfwords (16-bit), and bytes (8-bit), and has a highly orthogonal instruction set with many addressing modes. It is paired with the WE32101 MMU, the WE32102 dual-phase crystal oscillator which provides two 10MHz clocks 90° out of phase, and the optional WE32106 Math Accelerator UNIT.

3.3 WE32101 MMU

The WE32101 MMU provides virtual address to physical address translation using both segmented and paged memory.

On the 3B2, virtual address space is divided into four sections, identified by the top two bits of the address.

The MMU uses these top two bits as a Segment ID (SID) to look up the address in physical memory of a Segment Descriptor Table (SDT).

The next 13 bits of the address are known as the Segment Select field, and are used to index into the Segment Descriptor Table to find a Segment Descriptor.

The Segment Descriptor contains a bit that determines whether the virtual address being translated is to be treated as a Contiguous Segment, or Paged.

The rest of the bits of the virtual address are then treated differently depending on the value of this bit.

This process is described in great detail in the WE 32100 Microprocessor Information Manual and in the WE 32101 MMU datasheet.

3.3.1 Segmented Memory Virtual Addresses

Segmented virtual addresses further divide the virtual address into a Segment Offset (SOT). The physical memory address is then translated as in the figure below.

 31    30  29   17   16      0
+--------+---------+-----------+
|   SID  |   SSL   |    SOT    |
+--------+---------+-----------+

segmented.png

Figure 2: Segmented Memory Translation

3.3.2 Paged Memory Virtual Addresses

Paged virtual addresses further divide the lower 17 bits into a 6-bit Page Select field and an 11 bit Page Offset field. The physical memory address is then translated as in the figure below.

 31    30  29   17   16   11  10    0
+--------+---------+--------+--------+
|   SID  |   SSL   |   PSL  |   POT  |
+--------+---------+--------+--------+

paged.png

Figure 3: Paged Memory Translation

3.4 8253 Programmable Interval Timer

This timer is responsible for driving much of the interrupt system. Its functions are IO mapped to the following addresses:

Physical Address 8253 Function SBD Function
0x42003 Counter 0 Sanity Timer (used for softpower)
0x42007 Counter 1 Interval Timer
0x4200b Counter 2 Not yet known
0x4200f Command  
0x42013 Clear Latch  
Counter 0
Set during ROM init. This appears mainly to be used for softpower status. The clock for Counter 0 on pin 9 runs at 100KHz.
Counter 1
Set during UNIX boot. Provides the level 15 interrupt used by UNIX for process switching. This is initialized to 0x03e8 (decimal 1000) by UNIX in the function clkstrt(). This gives us a period of 10ms, since the clock on Counter 1 on pin 15 runs at 100KHz.
Counter 2
Set during ROM init. The clock for Counter 2 on pin 18 runs at 2MHz. We don't know what this is for. It's not referenced in the AT&T source code. The ROM initialization puts 0xa (decimal 10) into the counter, so the timer output (if enabled) would pull low for 500ns every 5μs. So far, I have observed only that the gate is set so that this timer is not enabled.

3.5 Control Status Register

This is, as far as I can tell, just a set of latches that can be set or cleared by writing to various memory locations.

I suspect, but do not know, that four 74LS279s provide 16 CSR latches.

The base address of the CSR is at 0x44000.

The structure struct wcsr in usr/src/uts/3b2/sys/csr.h describes the programmer-accessible latch bits. There are no comments in the source, so comments are my own.

Address Name Description
0x44003 c_sanity Clear softpower timer bit
0x44007 c_parity Clear parity error bit
0x4400b s_reqrst Request firmware reset
0x4400f c_align Clear memory alignment trap
0x44013 s_led Turn on the green LED
0x44017 c_led Turn off the green LED
0x4401b s_flop Set Floppy Interrupt Source
0x4401f c_flop Clear Floppy Interrupt Source
0x44023 s_timers Unknown (not used in SVR3)
0x44027 c_timers Unknown (not used in SVR3)
0x4402b s_inhibit Unknown (not used in SVR3)
0x4402f c_inhibit Unknown (not used in SVR3)
0x44033 s_pir9 Request Programmed Interrupt 9
0x44037 c_pir9 Clear Programmed Interrupt 9
0x4403b s_pir8 Request Programmed Interrupt 8
0x4403f c_pir8 Clear Programmed Interrupt 8

3.6 2681 Dual UART

The UART provides two serial ports integrated into the main system. One is the console, the other is a secondary TTY. Additionally, the UART provides a general purpose counter/timer circuit with an interrupt output.

The UART is clocked at 230.525 KHz. Due to the 16-bit counter, the maximum delay for the UART interrupt timer is 284 ms.

3.7 Floppy Drive

The standard floppy drive (known as IF, "Integrated Floppy") is a CDC 9429. The floppy format used is a little unusual: It is a Double-Sided, Quad Density format (DSQD) holding 720KB per diskette. The format is:

  • Double sided
  • 80 tracks per side
  • 9 sectors per track
  • 512KB per sector
  • 3:1 interleave
  • 250kbps MFM data

4 Memory Map

4.1 ROM Space

The ROM is mapped too the bottom 64KB of the address space, at physical addresses 0x000000000x0000ffff. The ROM itself is only 32KB, so I still need to do some additional diagnostic programming to determine exactly how the ROM maps to the top half of its space, if at all.

When running under SVR3, the ROM is mapped at virtual address 0x00020000.

I have decoded and disassembled the ROM, and discovered that there are several distinct areas

  • Strings
  • Vector Tables
  • Code
  • System Version Number

4.1.1 Vector Tables

The Vector Tables are described in detail in the SVR3 source code, in the header file sys/firmware.h.

Special RAM Locations

Table 1: Pointers to RAM Locations
ROM Pointer SVR3 Name Description
Addr Addr    
0x48c 0x02000864 p_runflag Flag indicating whether system is safe for booting
0x490 0x02001514 p_edt Ptr. to Equipped Device Table (EDT)
0x494 0x020011f8 p_inthand Ptr. to location containing address of interrupt handlers
0x498 0x020011f4 p_exchand Ptr. to location containing address of exception handler
0x49c 0x02000858 p_rsthand Ptr. to location containing address of reset handler
0x4a0 0x02001200 p_cmdqueue Ptr. to command queue for boot command
0x4a4 0x020012a8 p_fl_cons Ptr. to float cons struct
0x4a8 0x0200126c p_option Ptr. to Ptr. to Option Number (for getedt)
0x4c4 0x02001268 p_access Access permissions for printf, etc.
0x4e0 0x020011f0 p_num_edt Ptr. to location containing number of devices in EDT
0x4e4 0x020011ec p_memsize Ptr. to location containing size of main memory
0x4e8 0x02001504 p_memstart Ptr. to location containing start of main memory for UNIX
0x4f0 0x02000a80 p_physinfo Ptr. to disk physical info
0x4f4 0x02001258 p_pswstore Ptr. to PSW before exception or interrupt
0x4f8 0x0200125c p_pcstore Ptr. to PC before exception or interrupt
0x4fc 0x020011e8 p_console Ptr. to pointer to console UART
0x504 0x02001264 p_save_r0 Ptr. to %r0 before exception
0x50c 0x020012d8 p_bpthand Ptr. to location containing address of exception handler
0x510 0x020012d0 p_spwrinh Location for soft power inhibit
0x514 0x0200086c p_meminit Location for memory init flag
0x52c 0x020012dc dmn_vexc Demon virtual process / stack exception handler PCB
0x530 0x020012e0 dmn_vgate Demon virtual gate table location
0x534 0x020012e4 dmn_vsint Demon virtual stray interrupt PCB location
0x544 0x02000a74 p_hdcspec Location of fw hdc spec params

ROM Routines

Table 2: Pointers to ROM Routines
ROM Pointer Name Description
Addr Addr    
0x4ac 0x00004dd4 p_getedt Routine to fill EDT structure
0x4b0 0x000044e4 p_printf Location of printf routine
0x4b4 0x00004360 p_gets Location of gets routine
0x4b8 0x00004ae4 p_sscanf Location of sscanf routine
0x4bc 0x00007f68 p_strcmp Location of strcmp routine
0x4c0 0x00002af8 p_excret Routine to set up a return point for exceptions
0x4c8 0x00004484 p_getstat Routine to check console for a character present
0x4cc 0x00005320 p_chknvram Location of routine to verify checksum over NVRAM
0x4d0 0x00005224 p_rnvram Location of routine to read NVRAM
0x4d4 0x000052a0 p_wnvram Location of routine to write NVRAM
0x4d8 0x00007698 p_hd_acs Location of routine to access hard disk
0x4dc 0x00007b2c p_fd_acs Location of routine to access floppy disk
0x4ec 0x00001168 p_release Pointer to location containing release of code
0x500 0x00003d74 p_setbaud Pointer to setbaud routine
0x508 0x00007ff0 p_serno Pointer to serial number struct
0x518 0x00005438 p_bzero Pointer to memory zero routine
0x51c 0x00005450 p_setjmp Pointer to setjmp routine
0x520 0x000054a1 p_longjmp Pointer to longjmp routine
0x524 0x00004e14 p_dispedt Pointer to display edt routine
0x528 0x00005504 p_hwcntr pointer to DUART counter delay routine
0x538 0x000055ec p_fw_sysgen Pointer to generic sysgen routine
0x53c 0x00005baa p_ioblk_acs Pointer to ioblk_acs routine
0x540 0x000051d2 p_brkinh Pointer to break inhibit routine
0x548 0x0081e100 p_symtell Function to tell xmcp where the symbol table is
0x54c 0x0000421f p_demon Function to enter demon without init

String Locations

There's a large block of string literals in the ROM which are referenced by the various subroutines. I have added these to the ROM source code as I've found them.

4.2 IO Space

Looking through the SVR3 source code has revealed the following system board map, in the file usr/src/uts/3b2/vuifile.

Name Address Description
unxsbdst 0x40000 System Board Start Address
mmusdc1 0x40000 MMU SDC bits 0-31
mmusdc2 0x40100 MMU SDC bits 32-64
mmupdc1r 0x40200 MMU Right Half PDC Bits 0-31
mmupdc2r 0x40300 MMU Right Half PDC Bits 32-63
mmupdc1l 0x40400 MMU Left Half PDC Bits 0-31
mmupdc2l 0x40500 MMU Left Half PDC Bits 32-63
mmusrama 0x40600 MMU Section RAM A
mmusramb 0x40700 MMU Section RAM B
mmufltcr 0x40800 MMU Fault Code Register
mmufltar 0x40900 MMU Fault Address Register
mmucr 0x40a00 MMU Configuration Register
mmuvar 0x40b00 MMU Virtual Address Register
sbdpit 0x42000 Programmable interval timer (8253)
clrclkint 0x42013 Clear clock interrupt
sbdnvram 0x43000 NVRAM (0x400 bytes)
sbdrcsr 0x44000 CSR Read (reads the whole 16-bit halfword)
sbdwcsr 0x44000 CSR Write base address
dmaid 0x45000 DMA Integrated Disk (hard disk) page buffer
dmaiuA 0x46000 DMA UART A page buffer
dmaiuB 0x47000 DMA UART B page buffer
dmac 0x48000 DMA controller status/command register
duart 0x49000 2681 UART
idisk 0x4a000 7261 Disk Controller
ifloppy 0x4d000 2797 Floppy Controller
dmaif 0x4e000 DMA Integrated Floppy page buffer

4.3 Memory

Main memory ("mainstore") appears to start at 0x2000000 on the 3B2. Interestingly, on SYSVR3 this is mapped to /dev/mainstore.

4.4 The Equipped Device Table (EDT)

4.4.1 Basic Structure

The EDT lives in main memory at 0x2001514, referenced by ROM pointer p_edt at ROM vector address 0x490.

The EDT holds information about cards on the IO bus discovered at start-up. Each slot is 128 bytes long (4 words), and uses the following structure:

Table 3: Device Structure
Field Width (bits) Description
opt_code 16 Option code
opt_slot 4 Slot number the board is in
opt_num 4 Which of given option types the board is
rq_size 8 Request queue entry size
cq_size 8 Completion queue entry size
resrvd 14 Reserved for future use
cons_cap 1 1 = can support console, 0 = cannot
cons_file 1 0 = no pump file for console, 1 = does
boot_dev 1 1 = has possible boot device
word_size 1 0 = 8-bit, 1 = 16 bit
brd_size 1 0 = single width, 1 = double width
smrt_brd 1 0 = dumb board, 1 = smart board
n_subdev 4 Subdevice count
subdev 32 Pointer to array of n_subdev subdevice structures
dev_name 10 10-byte (including terminator) name
diag_file 10 Name of resident file containing diag. phases
padding 12 Padding for word alignment

Note that in the table, slot entries are aligned on 8-word boundaries. So the first slot 0, the system board (SBD) is at 0x2001514, while slot two appears at 0x2001534, slot three at 0x2001554, and so on.

Subdevice structures are very simple 4-byte entries.

Table 4: Sub-Device Structure
Field Width (bits) Description
opt_code 16 Option code
name 10 Option name
padding 6 Padding for word alignment

4.4.2 Detecting Devices

The ROM startup code is responsible for filling the skeleton of the EDT with option codes and slot numbers, and for keeping track of the total number of entries.

On start-up, it begins by filling in the SBD entry in slot 0. Then it queries each card address from slot 1 to slot 12, one by one, probing for cards. It does so by writing the byte 0x00 into the card's command register (the slot's base address + 5), then by reading the card's option ID in two bytes: the high byte of the ID from the base address, and the low byte of the ID from base address + 1.

If an External Memory Exception occurs during either write or read, and the TIMEO bit is set in the CSR indicating that a bus timeout occurred, it is assumed that no card is available in the slot and it is removed from the EDT.

Table 5: IO Slot Base Addresses
Slot No. Base Address
0 N/A (SBD)
1 0x200000
2 0x400000
3 0x600000
4 0x800000
5 0xa00000
6 0xc00000
7 0xe00000
8 0x1000000
9 0x1200000
10 0x1400000
11 0x1600000
12 0x1800000

5 Interrupts

The WE32100 has fairly complex interrupt handling capabilities. Interrupt vectors can be set by the external device, or internally set via an auto-vector. Interrupts may be handled via a "quick-interrupt" handler, which is a simulated GATE instruction, or via a "full-interrupt" handler, which is a full process switch analogous to CALLPS. And finally, there's an non-maskable interrupt (NMI).

The 3B2 ROM and UNIX SVR3 do not use NMI, auto-vector interrupts, or quick interrupts at all. Running the 3B2 under a logic analyzer revealed that the /NMI, /AVEC, and /INTOPT inputs on the CPU is never asserted, either during ROM initialization or UNIX boot. Everything is handled via the full interrupt sequence.

Moreover, interrupts are completely disabled during ROM initialization, before UNIX boot. The IPL in the processor status word is always set to 15 (1111b), so no interrupts except NMIs will be handled. Interrupts are enabled in in the PSW by the UNIX kernel when it starts the 10ms interval timer.

The ROM area that would normally be used for quick interrupt handlers is instead used for PCBPs.

Table 6: Full-interrupt vector table in ROM
Address Contents IPL Notes
0x8C 0x02000BC8   NMI Handler
0x90 0x02000BC8 0 Auto-Vector Handler (not used)
0x94 0x02000BC8 1 PCBPs (31 words)
 
0xAC 0x02000C18 8 Programmed Interrupt 8 (PIR8)
0xB0 0x02000C68 9 Programmed Interrupt 9 (PIR9)
0xB4 0x02000CB8    
0xB8 0x02000D08 11 Hard Disk & Floppy
0xBC 0x02000D58    
0xC0 0x02000DA8 13 UART
0xC4 0x02000DA8    
0xC8 0x02000E48 15 10ms interval timer and Syserr
0xCC 0x02000BC8    
0xD0 0x02000BC8    
   
0x10C 0x02000BC8   Device Interrupt Handler
0x110 0x02000BC8   PCBPs (224 words)
  (All identical PCBPs)

5.1 The PCB

The PCB pointed at by the PCBP 0x0200BC8 is in RAM space, so the ROM must set it up during startup.

The PCB gets set up like this:

Table 7: Interrupt PCB
Address Value Notes
0x02000BC8 0x0081E180 Processor status word
0x02000BCC 0x000040A0 Program Counter
0x02000BD0 0x020010E8 Stack Pointer

This sets up the address of the routine to call at 0x40A0.

000040a0: 84 ce fc 40                MOVW -4(%isp),%r0
000040a4: 84 50 7f 58 12 00 02       MOVW (%r0),$0x2001258
000040ab: 70                         NOP
000040ac: 84 c0 04 7f 5c 12 00 02    MOVW 4(%r0),$0x200125c
000040b4: 70                         NOP
000040b5: 87 00 7f 60 12 00 02       MOVB &0x0,$0x2001260
000040bc: 70                         NOP
000040bd: 2c 5c 7f ec 64 00 00       CALL (%sp),$0x64ec
000040c4: 30 c8                      RETPS

Here, the call to 0x64EC is the important bit.

000064ec: 10 49                      SAVE %fp
000064ee: 9c 4f 00 00 00 00 4c       ADDW2 &0x0,%sp
000064f5: 2c 5c ef f8 11 00 02       CALL (%sp),*$0x20011f8
000064fc: 04 c9 e8 4c                MOVAW -24(%fp),%sp
00006500: 20 49                      POPW %fp
00006502: 08                         RET
00006503: 70                         NOP

The routine at 0x64EC is responsible for calling a routine pointed at by 0x20011f8. That location is the "real" interrupt handler, and is frequently updated inside the ROM as different handlers are required. Thus, the ROM can insert any arbitrary code as an interrupt handler at any time.

5.2 Interrupt Sources

There appear to be several sources for interrupts in the 3B2:

  1. Software can trigger a programmed interrupt at priority 8 by setting the PIR8 flag in the CSR.
  2. The system can generate an interrupt at priority 9 by setting the PIR9 flag in the CSR. In SVR3, this interrupt is either a request from the UART or the DMA controller. The UART uses it both for servicing send and receive buffers, and for delaying floppy activity.
  3. There is a 100Hz system clock (the output of Counter 1 on the 8253 timer chip) that generates an interrupt at priority 15 every 10 ms. In SVR3, this interrupt is used for process switching and calling functions that are delayed by some multiple of 10 ms. Process switching involves issuing a level 8 programmed interrupt request (PIR8).
  4. The floppy and hard disk IRQ lines generate interrupts at IPL 11. The system distinguishes between them by examining the FLOP status flag in the CSR.
  5. The UART generates interrupts at IPL 13.

6 Decoding the 3B2 ROMs

According to Section 2.11.1 of the WE32100 Microprocessor Information Manaul, on reset the CPU does the following

  • Changes to Physical Addressing Mode (same effect as DISVJMP privileged instruction)
  • Fetch word at location 80 hex and stores it in the PCBP register.
    pcbp = 00 00 05 d8
    
  • Fetch the word a the PCB address and store it in the status word.

    The word at 05D8 is 0081e180, so we set that to the status word:

    psw = 00 81 e1 80
    

    Now let's interpret this:

    3                   2                   1                   0
  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  ---------------------------------------------------------------
  0 0 0 0 0 0|0|0|1|0|0 0 0 0|0|1 1 1 1|0 0|0 0|1 1|0 0 0 0|0|0 0


From right to left, the fields are:

  ET   = 0  (Exception type b00 is "Reset Exception")
  TM   = 0
  ISC  = 0  (Exception Internal State Code b0000 is "Old PCB* Fault")
  RI   = 3  (R=1, I=1)
  PM   = 0  (Previous Mode = Kernel level)
  CM   = 0  (Current Mode = Kernel level)
  IPL  = 15 (Highest Level: Nothing may interrupt the CPU)
  TE   = 0
  NZVC = 0  (No flags set)
  OE   = 0
  CD   = 1  (Cache is disabled)
  QIE  = 0
  CFD  = 0

NB: PCB = "Process Control Block"
  • Fetch the word at the Process Control Block (PCB) address + 4 bytes, and store it in the PC.

    pcbp + 4 = 00 00 12 74

    So we set PC = 00 00 12 74

  • Fetch the word at the PCB address + 8 bytes, and store it in the SP.

    pcbp + 8 = 02 00 00 08

    So we set SP = 02000008

  • If the PSW I bit (from RI) is set (yes, it is), CLEAR the bit (RI becomes 10) then fetch the word at PCB address + 12 bytes, and store it in the PCBP

    PCBP = 00 00 00 00

  • Start running at the PC (0x1274)
  • This means we can start to disassemble code starting at address 0x1274 in the ROM image, because it is mapped to memory location 0.

That initial part of the ROM, when disassembled, looks like this:

00001274: 04 7f 08 00 00 02 4c           MOVAW $0x2000008,%sp
0000127b: 04 7f 08 00 00 02 49           MOVAW $0x2000008,%fp
00001282: 04 7f 08 00 00 02 4a           MOVAW $0x2000008,%ap
00001289: 04 7f 08 08 00 02 4e           MOVAW $0x2000808,%isp
00001290: 87 16 7f 0f 20 04 00           MOVB &0x16,$0x4200f
00001297: 70                             NOP
00001298: 87 6f 64 7f 03 20 04 00        MOVB &0x64,$0x42003
000012a0: 70                             NOP
000012a1: 87 5f 94 00 7f 0f 20 04 00     MOVB &0x94,$0x4200f
000012aa: 70                             NOP
000012ab: 87 0a 7f 0b 20 04 00           MOVB &0xa,$0x4200b
000012b2: 70                             NOP
000012b3: 87 6f 74 7f 0f 20 04 00        MOVB &0x74,$0x4200f
000012bb: 70                             NOP
000012bc: 24 7f d5 12 00 00              JMP $0x12d5
...

The very first thing the ROM does is set up the programmable timer.

The next thing it does is a complex set of power-on self test diagnostics. These are actually incredibly useful, because they exercise the CPU, and therefore also exercise the simulator.

Once power on self test is completed, a magic word is deposited into the p_runflag memory location (0x02000864). It can be any one of the following:

  • 0xFEEDBEEF: Fatal error. System reset.
  • 0x3B02F1D0: MAS has been init'ed (what's MAS?)
  • 0xA11C0DED: Reset goes to rst_handler
  • 0x8BADF00D: Reboot w/o diags for UN*X
  • 0xADEBAC1E: Re-enter firmware from a reset w/o failure message

7 Simulation Notes

For the 3B2 simulator, if we want to mimic an 10MHz system clock, each virtual machine cycle has a 100 ns period.

One step of the interval timer clock input is 10 ms. So every 100000 steps of the simulator is one step of the interval timer coming from the 8253 SIT.

8 Booting

8.1 Hard Disk Initialization

The hard disk is initialized on boot as described below.

  • The hard disk controller is asked to reset with an AUX RESET command.
  • The processor examines bit 7 of the status register, CONTROLLER BUSY. If the device is available, we clear the data buffer and CE bits, then give it the SPECIFY command with the following arguments:
    • 0x18 means Soft Sectored, Stepping Rate 3.
    • 0xf2 is the DTLH byte. The first nybble means:
      • initialize the Polynomial Counter with all 1s
      • Select ID and data pad of 0x4e
      • Polling mode is OFF
    • 0x00 is the DTLL byte. It is appended to the low nybble of DTLH to form the word 0x200, meaning a data length of 512 bytes.
    • 0x03 is the Ending Track Number (ETN)
    • 0x11 is the Ending Sector Number (ESN)
    • 0x0d is the Gap 2 Length
    • 0x00 is the Reduced Write Current cylinder high byte
    • 0x80 is the Reduced Write Current cylinder low byte

    NB: "ETN" and "ESN" are used to convert logical cylinders and sectors to physical cylinders and sectors, as described in the uPD7261 datasheet:

"LSN is incremented at the end of each sector until the value of ESN is reached. LSN is then set to 0 and LHN is incremented. If LHN reaches the value of ETN, then LHN is cleared and LCN is incremented."

  • The host checks to see if the command completed successfully. If it did, the CEH bit of the status register should be set, and the CEL bit should be clear.
  • The host issues a CLEAR CE BITS command to clear CEH and CEL.
  • The host issuesa CLEAR DATA BUFFER command.
  • The host issues another CLEAR CE BITS command.
  • The host issues a SENSE UNIT STATUS command with the argument 0x1e. This argument is the UNIT STATUS (UST) byte and is broken down into the following bits:
    • bits 7-5: Always 0
    • bit 4: Drive Selected SET
    • bit 3: Seek Complete SET
    • bit 2: Track 0 SET
    • bit 1: Ready SET
    • bit 0: Write Fault CLEAR
  • The host again checks for successful completion of this command.
  • The host then reads the data field, which should be a UNIT STATUS byte containing the current status of the drive:
    • bits 7-5: Always 0
    • bit 4: Drive Selected SET
    • bit 3: Seek Complete SET
    • bit 2: Track 0 SET
    • bit 1: Ready SET
    • bit 0: Write Fault CLEAR
  • The host clears the data buffer and the CE bits again
  • The host issues a RECALIBRATE command. RECALIBRATE repositions the drive head to Cylinder 0. IST is available as a result byte.

… Much more to come, as I need to document it.

9 Appendix A: System Board Components

The System Board has 157 integrated circuits and 2 crystal oscillators. The table below summarizes the parts.

9.1 Major Components

3b2_310_numbered_sm.jpg

In this figure, numbers are somewhat arbitrarily ordered, but roughly from top to bottom, right to left.

Table 8: Major Components
Number Name Purpose
1 WE32100 CPU
2 WE32101 MMU
3 WE32106 Math Accelerator Unit
10 WE32102 CPU clock source
4,5,6,7 i2764 System ROM
8 8253 Interval timer interrupt source
57 TMS2797 Floppy disk controller
93 AM9517A Multimode DMA controller
94 2681 Dual UART and interval timer interrupt source
156 μDP7261 Hard disk controller
A Header Floppy disk connector
B Header MFM hard disk data connector
C Header MFM hard disk data connector
D Header MFM hard disk control connector
E,F Connector Backplane card edge connector
G Memory Memory slot A (1MB,2MB)
H Memory Memory slot B (1MB,2MB)

9.2 All Parts

Table 9: AT&T 3B2/310 and 3B2/400 System Board (Part # ED-4C637-32-G)
IC Qty. Description Notes
2681 1 Dual UART Console serial I/O
26LS32 1 Quad differential line receiver Hard disk MFM receiver
27LS31 1 Quad differential line driver Hard disk MFM driver
7406 2 Hex inverter buffer drivers with O.C. outputs  
7407 2 Hex buffer drivers with O.C. outputs  
74F04 1 Hex inverters  
74F11 1 Triple 3-input AND gates  
74LS00 1 Quad 2-input NAND gates  
74LS02 1 Quad 2-input NOR gates  
74LS04 5 Hex inverters  
74LS05 1 Hex inverters with O.C. outputs  
74LS08 2 Quad 2-input AND gates  
74LS09 1 Quad 2-input AND gates with O.C. outputs  
74LS10 1 Triple 3-input NAND gates  
74LS11 1 Triple 3-input AND gates  
74LS112 1 Dual neg.-edge-triggered master/slave J-K flip-flops  
74LS125 1 Quad bus buffers with tri-state outputs Non-inverted G input
74LS126 1 Quad bus buffers with tri-state outputs Inverted G input
74LS138 6 3-to-8 line decoder/demux  
74LS139 1 Dual 2-to4 decoder/demux  
74LS14 2 Hex inverter with Schmitt trigger inputs  
74LS148 1 8-to-3 priority encoder  
74LS151 1 8-input multiplexer  
74LS157 1 Quad 2-input multiplexers  
74LS164 1 8-bit serial-in/parallel-out shift reg.  
74LS174 1 Hex D-type flip-flops  
74LS21 3 Dual 4-input AND gates  
74LS244 5 Non-inverting buffer/driver  
74LS257 7 Quad 2-input multiplexers with tri-state outputs  
74LS279 4 Quad SR Latches  
74LS32 5 Quad 2-input OR gates  
74LS374 6 Octal D-Type latches with tri-state outputs  
74LS390 1 Dual decade counter  
74LS393 2 Dual 4-state binary counter  
74LS645 9 Octal bus transceiver  
74LS646 4 Octal bus transceiver with tri-state output  
74LS74 5 Dual D-type flip-flop  
74S00 2 Quad 2-input NAND gates  
74S02 1 Quad 2-input NOR gates  
74S03 1 Quad 2-input NAND gates with O.C. outputs  
74S04 1 Hex inverters  
74S05 1 Hex inverters with O.C. outputs  
74S08 3 Quad 2-input AND gates  
74S10 1 Triple 3-input NAND gates  
74S112 1 Dual neg.-edge-triggered master/slave J-K flip-flops  
74S174 2 Hex D-type flip-flops  
74S175 4 Quad D-type flip-flops  
74S32 2 Quad 2-input OR gates  
74S74 8 Dual D-Type positve edge triggered flip-flops  
75188 1 Quad RS-232 line drivers Some boards use MC1488 parts
75189 1 Quad RS-232 line receivers Some boards use MC1489 parts
82S153 12 Field programmable logic array (PLA)  
974-6033-0 1 20 MHz xtal osc.  
AM29843 5 Bus interface latches  
AM29853 5 Parity bus transceiver  
AM9517A 1 Multimode DMA controller  
AMPAL16 2 Programmable array logic (PAL) Marked: AAUWW, AAUYA
D2764A 4 EPROM Marked: AAYYC, AAYYD, AAYYE, AAYYF
D8253C 1 Programmable interval timer Interrupt source
DP8465 1 PLL Used in data separator for HD controller
MM58174A 1 Real time clock TOD clock. Supported by a 32.768 KHz xtal
TMS2797 1 Floppy disk controller  
μDP7261 1 Hard disk controller Uses DP8465 as PLL/data separator
WE32100 1 CPU  
WE32101 1 MMU  
WE32102 1 Bi-phase 10MHz xtal osc. Clock source for the WE32100
WE32106 1 FPU/MAU  
WE62C 1 Unknown Unknown. Marked: "O WE 62C"
Total 159    

9.3 Notes

  • The 12 82S153 PLAs are marked: AAUWG, ABGLU, AAUWS, AAYBN, AAUWH, AAUWL, AAUWT, ABGWT, AAUWN, AAUWK, AAUWR, AAUWJ

10 Appendix B: IO Expansion Connectors

There are two card edge connectors on the system board, Connector A (100 pins) and Connector B (60 pins). These together form the I/O Expansion Bus. A backplane fits into these connectors and provides 4 (on the 3B2/300 and 3B2/310) or 12 (on the 3B2/400) Peripheral Connectors.

The connectors are documented in: "3B2 IO Bus", December 1983.

10.1 100-Pin I/O Expansion Connector A

Pin Number Signal   Pin Number Signal
1 VCC   2 PPA[23]
3 PPA[22]   4 GRD
5 PPA[21]   6 PPA[20]
7 PPA[19]   8 GRD
9 PPA[18]   10 PPA[17]
11 VCC   12 GRD
13 PPA[16]   14 PPA[15]
15 PPA[14]   16 GRD
17 PPA[13]   18 PPA[12]
19 PPA[11]   20 PPA[10]
21 VCC   22 PPA[09]
23 PPA[08]   24 GRD
25 PPA[07]   26 PPA[06]
27 PPA[05]   28 GRD
29 PPA[04]   30 PPA[03]
31 VCC   32 GRD
33 PPA[02]   34 PPA[01]
35 PPA[00]   36 GRD
37 /PLOCK   38 /PR1W
39 /PPAS   40 GRD
41 VCC   42 /PBACK
43 /PBRQ   44 GRD
45 PD[15]   46 PD[14]
47 PD[13]   48 GRD
49 PD[12]   50 PD[11]
51 VCC   52 GRD
53 PD[10]   54 PD[09]
55 PD[08]   56 GRD
57 PD[07]   58 PD[06]
59 PD[05]   60 GRD
61 VCC   62 PD[04]
63 PD[03]   64 GRD
65 PD[02]   66 PD[01]
67 PD[00]   68 GRD
69 /PDS[1]   70 /PDS[0]
71 VCC   72 GRD
73 /PDTACK   74 /PSIZE16
75 /PFLT   76 GRD
77 /PFAIL   78 /PBUSY
79 /SYSRST   80 GRD
81 VCC   82 /PIAK[0]
83 /RQRST   84 /PIAK[1]
85 /PINT[0]   86 /PIAK[2]
87 /PINT[1]   88 GRD
89 /PINT[2]   90 VBKUP
91 VCC   92 GRD
93 /PCS[01]   94 V12N
95 /PCS[02]   96 GRD
97 /PCS[03]   98 V12P
99 /PCS[04]   100 GRD

10.2 60-Pin I/O Expansion Connector B

Pin Number Signal   Pin Number Signal
1 VCC   2 /PCS[05]
3 VCC   4 GRD
5 /PCS[06]   6 GRD
7 VCC   8 GRD
9 VCC   10 GRD
11 /PCS[07]   12 GRD
13 VCC   14 GRD
15 VCC   16 GRD
17 /PCS[08]   18 GRD
19 VCC   20 GRD
21 VCC   22 GRD
23 /PCS[09]   24 GRD
25 VCC   26 GRD
27 VCC   28 GRD
29 /PCS[10]   30 GRD
31 VCC   32 GRD
33 VCC   34 GRD
35 /PCS[11]   36 GRD
37 VCC   38 GRD
39 VCC   40 GRD
41 /PCS[12]   42 GRD
43 VCC   44 GRD
45 VCC   46 GRD
47 /PCS[13]   48 GRD
49 VCC   50 GRD
51 VCC   52 GRD
53 /PCS[14]   54 GRD
55 VCC   56 GRD
57 VCC   58 GRD
59 /PCS[15]   60 GRD

10.3 86-Pin Peripheral Connector

Pin Number Signal   Pin Number Signal
1 V12P   2 /PINT[2]
3 V12N   4 /PINT[1]
5 /PBACKI   6 /PINT[0]
7 PCS   8 /RQRST
9 GRD   10 /SYSRST
11 VBKUP   12 /PFAIL
13 /PIAKO[2]   14 /PFLT
15 /PIAKI[2]   16 GRD
17 /VCC   18 /PDTACK
19 /PIAKI[1]   20 /PDS[1]
21 /PIAKO[1]   22 PD[00]
23 /PIAKI[0]   24 PD[02]
25 GRD   26 PD[03]
27 /PBUSY   28 PD[05]
29 /PIAKO[0]   30 PD[07]
31 /PSIZE16   32 GRD
33 /PDS[0]   34 PD[08]
35 PD[01]   36 PD[10]
37 GRD   38 PD[12]
39 PD[04]   40 VCC
41 GRD   42 PD[13]
43 PD[06]   44 PD[15]
45 PD[09]   46 /PBRQ
47 PD[11]   48 GRD
49 GRD   50 /PPAS
51 PD[14]   52 /PLOCK
53 /PBACKO   54 PPA[00]
55 /PR1W   56 GRD
57 GRD   58 PPA[02]
59 PPA[01]   60 PPA[04]
61 PPA[03]   62 PPA[05]
63 PPA[06]   64 VCC
65 GRD   66 PPA[07]
67 PPA[09]   68 PPA[08]
69 PPA[10]   70 PPA[11]
71 PPA[12]   72 GRD
73 GRD   74 PPA[13]
75 PPA[15]   76 PPA[14]
77 PPA[17]   78 PPA[16]
79 PPA[20]   80 GRD
81 GRD   82 PPA[18]
83 PPA[23]   84 PPA[19]
85 PPA[21]   86 PPA[22]

Author: Seth Morabito

Created: 2017-03-27 Mon 08:25

Emacs 25.1.1 (Org mode 8.2.10)

Validate