DID | DRL | |
---|---|---|
1 | 1 | CS161 bus controller - see LAMEbus spec |
2 | 1 | Timer/clock card |
3 | 2 | Fixed disk |
4 | 1 | Serial console |
5 | 1 | Text screen |
6 | 2 | Network interface |
7 | 1 | Emulator filesystem |
8 | 1 | Hardware trace control |
9 | 1 | Random number generator |
An interrupt is generated when the countdown time reaches 0. The countdown timer is automatically restarted if the restart-on-expiry register has a nonzero value.
Offset Description 0-3 Current time (seconds) 4-7 Current time (nanoseconds) 8-11 Restart-on-expiry flag 12-15 True if interrupt (reading clears) 16-19 Countdown time (usec) (writing starts timer) 20-23 Speaker (write any value to beep) 24-27 Reserved 28-31 Reserved
Reading from the speaker produces undefined behavior.
The current time registers represent UTC, where the epoch is midnight on January 1, 1970, as per the unix time() call.
A 512-byte sector transfer buffer is mapped at offset 32768.
Offset Description 0-3 Number of sectors (total) 4-7 Status 8-11 Sector number 12-15 Rotation speed (RPM)
The disk can do one operation at a time. To perform an operation, store the sector number into the sector register, and then write either the read-in-progress or write-in-progress values into the status register. Changing the sector number register while an operation is in progress produces undefined results.
The status register reports the present state of the disk. When it is reporting a completed operation, the IRQ line is raised. Writing zero back (or starting another operation) clears the interrupt condition. Writing zero back when an operation is in progress aborts the operation. Writing values other than zero or the values that start operations into the status register produces undefined results.
The disk is assumed to never need low-level formatting. The sector size is 512 bytes. Note that the 32-bit linear sector addressing limits disk size to 2^32 * 512 = 2^41 bytes, or 2 TB. In practice implementations may have lower limits.
The status register bits are as follows:
This results in the following values being meaningful in the status register:
Code Description 1 Operation in progress 2 Operation is write 4 Operation completed 8 Invalid sector number 16 Media error
Once a write operation has reported successful completion, the disk guarantees that the complete sector written will in fact make it to stable storage.
Code Description 0 Device idle 1 Read operation in progress 3 Write operation in progress 4 Read operation succeeded 6 Write operation succeeded 12 Invalid sector number on read 14 Invalid sector number on write 20 Media error on read 22 Media error on write
This is a very, very simple console interface. Writing to the first register causes a character to be printed. Reading from it returns the last character typed.
Offset Description 0-3 Character buffer 4-7 Write IRQ register 8-11 Read IRQ register 12-15 Reserved
The two IRQ registers have two bits each: if bit 0 is set, an IRQ will be generated when the device has completed an operation, and if bit 1 is set, the device has in fact completed a (read or write) operation.
You must wait until one write has completed before starting another one, or the output may be garbled.
The characters read are 8-bit ASCII and control characters in the range 0-255. Non-ASCII keys, such as cursor keys or function keys, may appear as strings beginning with an escape sequence, or as values greater than 255. Unfortunately, in practice such characters may come from any of a number of sources and it isn't practical to attempt to document their values or even map them into a single consistent set.
Memory mapped screen interface. 32k of screen memory is mapped at offset 32768. The cursor position and display size registers are encoded with the X value in the most significant 16 bits and the Y value in the least significant 16 bits, with a zero base.
Offset Description 0-3 Cursor position 4-7 Display size 8-11 Character input buffer 12-15 Read IRQ register
To make the cursor invisible, move it off the screen. This may or may not work depending on the display.
Reading is the same as with the serial console device. Writing is accomplished by scribbling in screen memory, one byte per character, increasing addresses moving first to the right then down across the screen.
Writing to the display size register should, in principle, work, but in practice will not.
A 4k read buffer followed by a 4k write buffer is mapped at offset 32768. Packets may not exceed 4k.
Offset Description 0-3 Receive interrupt register 4-7 Transmit interrupt register 8-11 Control register 12-15 Status register
Simple network interface.
Bit 0 of each interrupt register is set when a receive (or transmit) is complete. These bits may be cleared by writing 0 back. If either interrupt register is nonzero, the card's IRQ line is asserted.
The control register contains two bits: bit 0 controls promiscuous mode, and bit 1 controls packet sending. If the promiscuous mode bit is set, all packets seen will be received, even those whose destination is elsewhere. Setting bit 1 starts a packet transmit. Do not set bit 1 while a transmit is already in progress; undefined behavior may result. The rest of the control register is reserved and should be set to 0.
The lower 16 bits of the status register report the device hardware address. The rest is reserved. The status register is read-only.
To transmit, a packet should first be assembled in the send buffer. The destination and length fields in the link-level header must be set correctly. (The source and frame fields will be set by the card during transmit. However, the entire link-level header should be placed in the send buffer.) Then bit 1 of the control register should be set to 1 to start transmission. An interrupt will occur when transmission is complete.
To receive, merely copy each packet out of the receive buffer as receive interrupts occur. Further packets arriving are discarded while the receive interrupt register is nonzero, so packets may be copied without being corrupted by further input.
The link-level packet header is 8 bytes long and has the following fields (always in network byte order):
The length field should hold the entire packet length, including the space taken by the header.
Offset Size Description 0 2 Framing word (0xa4b3) 2 2 Hardware from-address 4 2 Total packet length 6 2 Hardware to-address
The hardware address 0xffff is the broadcast address; the hardware address 0x0000 is reserved for sending keepalives to the network hub. Software should not send packets to hardware address 0x0000.
A 16384-byte I/O buffer is mapped at offset 32768.
Offset Description 0-3 Handle number to do I/O with 4-7 File offset for read/readdir/write 8-11 Length of I/O 12-15 Operation code 16-19 Result code 20-31 Reserved
The operation codes are:
The result codes are:
Code Description 1 Open a file 2 Create a file 3 Create a file exclusively (O_EXCL) 4 Close a file 5 Read from a file 6 Read one filename from a directory 7 Write to a file 8 Get size of a file 9 Truncate a file
The rest of the documentation for this device is reserved, on the grounds that it is complicated, messy, unclean, and may be subject to frequent change.
Code Description 0 Operation in progress or device idle 1 Success 2 Bad handle 3 Bad operation code 4 Bad pathname 5 Bad I/O size 6 File exists 7 File is a directory 8 Media error 9 Out of handles 10 Out of disk space 11 File is not a directory 12 Unknown other error 13 Unsupported operation
This device controls trace161's trace flags, allowing them to be set or cleared on the fly. To set a trace flag, write the letter of its trace option to the trace-on register; to clear it, use the trace-off register. The letters are the same as those used on the trace161 command line. If running sys161 rather than trace161, this device may exist and be used, but the trace registers have no effect.
Offset Description 0-3 Trace-on register 4-7 Trace-off register 8-11 Debugging printout register 12-15 System state dump register
The debugging printout register, if written to, causes trace161 or sys161 to print a debug message, which includes the value written to the register.
The system state dump register, if written to, will cause a complete dump of the simulation state, tagged with the value written to the register. This feature is primarily intended for testing and debugging System/161 itself.
All these registers are write-only.
Reading the register returns a 32-bit random value. In the simulated version, this value is generated by a pseudo-random generator whose seed can be specified explicitly. This allows for repeatable results, which can be helpful in some contexts.
Offset Description 0-3 Random value