VAXstation 100 firmware notes
Some random notes from running the DEC-supplied standard firmware for the VAXstation 100 in an emulator.
The firmware analyzed announces itself as version 05.00. It deviates in minor details from the information in the 1983 "VS100 Engineering Specification".
Contents
Memory map
Firmware 5.00 extends the LOOPBACK region to one more word at 4A0004. Apparently this loops back the value written to 480004.
The BBA scratchpad has been moved to 30000. An accesses to a byte at 280000 seems to clear a BBA interrupt.
RAM memory map
Most of the RAM is available for uploaded software. However, regions at the ends are used by the ROM for fixed purposes:
000000 | 32 longwords | Exception vectors |
000080 | 15 longwords | Saved screen contents under mouse pointer |
0000C0 | two words | Mouse x,y copied from hardware register |
0000C4 | two words | Old mouse x,y screen coordinates |
0000C8 | two words | New mouse x,y screen coordinates |
<01FFC0 | extends towards lower addresses | Stack |
01FFC0 | one longword | Keyboard fifo read pointer |
01FFC4 | one longword | Keyboard fifo write pointer |
01FFC8 | one longword | Tablet fifo read pointer |
01FFCC | one longword | Tablet fifo write pointer |
01FFD0 | one word | Cursor column |
01FFD2 | one word | Cursor line |
01FFD4 | Connection timeout counter | |
01FFD6 | 16 bytes | Keyboard output fifo |
01FFE6 | 16 bytes | Tablet output fifo |
01FFF6 | one byte | Size data in keyboard fifo |
01FFF7 | one byte | Size data in tablet fifo |
01FFF8 | one byte | Mouse buttons |
01FFF9 | one byte | Keyboard input (LK201 code) |
01FFFA | one byte | Tablet input |
01FFFB | one byte | State of CTRL and SHIFT, for entering maintenance menu |
Error LEDs
Indicates which test failed. During power-up, green light turned off. During idle loop, green light remains on.
Apparently there's a bug.
Interrupts
All VS100 interrupts use the autovector feature.
Firmware 5.00 doesn't use the level 1 interrupt. The firmware only reads the mouse position during maintenance test.
Keyboard test
The firmware transmits code FD (hex) to the LK201 keyboard, which commands it to jump to the power-up sequence and self-test. The keyboard transmits a four-byte message back. The VS100 ignores the keyboard ID, and checks that the third is not 3D.
This information is from the VT220 Technical Manual.
D0 flags
The firmware maintains a set of flags in register D0.
Bit (decimal) | Meaning |
16 | Manufacturing mode. |
17 | BBA present. |
18 | Link down. |
19 | Power-up error. |
20 | LEDs locked. |
21 | Suppress printing test result. |
22 | In maintenance menu. |
23 | Keyboard ok. |
24 | BBA done. |
25 | Vertical retrace interrupt. |
26 | Test not executed. (E.g. hardware not present.) |
27 | Test timed out. |
28 | Host wants attention. (Same vector as TRAP #1?!?) |
Built-in graphics
The firmware has a mouse pointer, a text font, and three icons. The first two are straight bitmaps, whereas the icons are run length encoded.
This icon is displayed when a user can be logged into the system.
This icon is displayed when there's an internal error.
This icon is displayed when there's a communication problem.
Communication
The firmware communicates with the host through a set of eight 16-bit registers. (There is also a 256K window into the host Unibus address space.)
These registers are written.
CSR0 | Bit 0 - clear "go" bit. |
CSR1 | Interrupt reason. |
CSR2 | Peripheral event. |
CSR3+CSR4 | Unibus window address. |
CSR5 | Firmware version. |
CSR6 | BBA info. |
These events are sent. Numbers are hexadecimal bit masks.
0000 | |
0001 | Init done. |
0002 | Function performed ok. |
0008 | Mouse buttons. |
0080 | Powerup done. |
8000 | Function error. |
8001 | Bad function number. |
8002 | Bad command number. |
These registers are read.
CSR0 | Bit 0 - check "go" bit. Bits 1-5: function code. |
CSR3+CSR4 | Parameter. |
These functions are implemented in ROM. Numbers are decimal.
1 | Init - setup hardware. |
2 | Command - further decoded. Parameter is an address in Unibus memory. |
3 | Start firmware. Parameter is address. |
5 | Reset. |
18 | Clear infinite retry counter. |
19 | Clear finite retry counter. |
BitBlit Accelerator
The BBA is a custom microcoded processor based on the Am2901 family. It was initially to be an optional add on, but later it was required. The BBA can access the frame buffer and has its own 256 by 16 bit scratchpad RAM.
The 68000 CPU communicates with the BBA through the scratchpad. When a command has been written, the CPU pokes a hardware register to signal the BBA to start. The BBA interrupts the CPU when done.
The contents and structure of the commands are being reverse engineered. The first word in the scratchpad is a bit mask indicating various functions to be done.
Scratchpad locations.
Address | Size | Firmware | Function |
000 | 16 bits | 5F96, 60AC | Command bitmask; see below |
002 | 32 bits | 5F9C, 3B2A | Source bitmap address |
006 | 16 bits | 5FA6 | Source x offset |
008 | 16 bits | 5FAA | Source bitmap width in bytes |
00A | 32 bits | 3B2E, 6014 | Mask bitmap address |
00E | 16 bits | Mask x offset | |
010 | 16 bits | 6022 | Mask bitmap width in bytes |
012 | 32 bits | 3B32 | Destination bitmap address |
016 | 16 bits | Destination x offset | |
018 | 16 bits | 3036 | Destination bitmap width in bytes |
01A | 16 bits | Mask width | |
01C | 16 bits | 6026 | Mask height |
01E | 16 bits | 5F98 | ALU function |
020 | 32 bits | 5FB0 | Tile address |
024 | 16 bits | Destination y offset | |
026 | 32 bits | Line destination bitmap address | |
02A | 16 bits | Line steps (optionally including last point) | |
02C | 16 bits | Line major axis | |
02E | 16 bits | Line minor axis | |
030 | 16 bits | Line x delta, when accumulator overflows (see below) | |
032 | 16 bits | Line address, delta when accumulator overflows | |
034 | 16 bits | Line x delta, when accumulator doesn't overflow | |
036 | 16 bits | Line address delta, when accumulator doesn't overflow | |
038 | 16 bits | Line mask x offset | |
03A | 32 bits | Line mask bitmap address | |
03E | 16 bits | Line mask bitmap width in bytes | |
040 | 32 bits | ||
044 | 16 bits | ||
046 | 16 bits | ||
048 | 16 bits | ||
04A | 16 bits | ||
04C | 16 bits | ||
04E | 32 bits | Cursor source bitmap address | |
052 | 16 bits | Cursor source x offset | |
054 | 16 bits | Cursor source width in bytes | |
056 | 32 bits | Cursor mask bitmap address | |
05A | 16 bits | Cursor mask x offset | |
05C | 16 bits | Cursor mask width in bytes | |
05E | 32 bits | Cursor destination bitmap address | |
062 | 16 bits | Cursor destination x offset | |
064 | 16 bits | Cursor destination width in bytes | |
066 | 16 bits | Cursor mask width | |
068 | 16 bits | Cursor mask height | |
06A | 16 bits | Cursor ALU function | |
06C | 32 bits | (Cursor) |
Command bits.
Bit | Function |
0 | Use source bitmap |
1 | Use mask bitmap |
2 | Horizontal direction: 0 - right, 1 - left |
3 | Vertical direction: 0 - downwards, 1 - upwards |
4 | Use source tile |
5 | Draw cursor |
6 | Draw line |
7 |
Scratchpad location 01E specifies a four-bit code for the ALU function. It's an enumeration of all possible logical functions between two binary inputs, where the code specifies the result.
Bits | Function |
0000 | 0 |
0001 | src ∧ dst |
0010 | src ∧ ¬dst |
0011 | src |
0100 | ¬src ∧ dst |
0101 | dst |
0110 | src ⊻ dst |
0111 | src ∨ dst |
1000 | ¬(src ∨ dst) |
1001 | ¬(src ⊻ dst) |
1010 | ¬dst |
1011 | src ∨ ¬dst |
1100 | ¬src |
1101 | ¬src ∨ dst |
1110 | ¬(src ∧ dst) |
1111 | 1 |
Line drawing is done with a classic Bresenham algorithm. For each step along the major axis, scratchpad location 02E is added to an accumulator. If the accumulator overflows, the location pair 030,032 is used to update the point on the line, and location 02C is subtracted from the accumulator. Otherwise, 034,036 is used.