DID | DRL | |
---|---|---|
1 | 1 | Old uniprocessor 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 |
10 | 1 | Multiprocessor bus controller -- see LAMEbus spec |
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. (In 2038 this will break. Oh no.)
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
You must wait until one write has completed before starting another one, or the output may be garbled.
The two IRQ registers have three bits each. Bit 0 (IRQEN) controls whether interrupts are generated; if bit 0 is clear, interrupts for writes or reads (respectively) will not be generated at all.
Bit 1 (CMPL) is latched on when the device completes a (write or read, respectively) operation. It can be cleared by software. Bit 2 (FORCE) is controlled only by software. The device's IRQ line is asserted if either the write or read IRQ register is in an asserting state; an IRQ register is in an asserting state if bit 0 is set and either bit 1 or bit 2 is set.
The FORCE bit can be used to perform polled I/O without causing the IRQ line to flap, which can cause problems in multiprocessor configurations. The basic approach is to set FORCE during the polled I/O if an IRQ was already pending, to keep it pending until the polled I/O is complete, and to clear IRQEN during the polled I/O if an IRQ was not already pending, to avoid triggering a spurious interrupt. See the OS/161 2.x driver (1.99.06 or higher) for example code.
NOTE: Bit 2 is only supported in System/161 versions 1.99.05 and up. The device revision is 1 regardless; if necessary the feature can be probed by writing FORCE (without IRQEN) to one of the IRQ registers and then reading the register back. If FORCE is read back, the feature is present; if 0 is read back, the feature is not available. Note that drivers written for prior versions of System/161 without the FORCE bit will continue to work as before.
The characters read from the device 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 is not 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