Geneve CRU definitions

From Ninerpedia
Jump to: navigation, search


CRU bits may be tested with the TB command, with the base address in R12. The bit is copied to the EQ flag of the status register so that a JEQ will cause a branch whenever the bit is set.

The bits of the 9901 are tested in positive logic, which means that a low value on the pin will make a TB yield EQ=0, and a high value on the pin makes EQ=1. The signals on the pins may show negative logic themselves. That is, if the joystick button is pressed, a low value is put on the /INT3 input (bit 3), and a TB 3 will make EQ=0, while a not pressed button would be EQ=1.

TMS9901 lines may be configured as inputs (in), outputs (out), and the first 16 addresses may be configured as interrupt inputs (int), triggering an outgoing interrupt if the mask is set to 1 for the respective input. The interrupt mask configuration may be changed as desired; for instance, one could enable interrupts from the real-time clock by setting bit 11 to 1. The setting as shown here is the typical setting when working in MDOS.

/signal means negative logic. The first column is the base address for the respective bit if that bit is addressed without offset. You see that the base address is shifted one bit position to the left. Thus, setting R12 to >0004 and accessing bit 0 is the same as setting R12 to >0000 and accessing bit 2.

TMS 9901
Address Bit Kind Default Meaning Modification
0000 0 flag 0 Clock mode (/Interrupt mode) -
0002 1 int 1 /INTA (P-Box, pin 17) -
0004 2 int 1 /V9938 INT -
0006 3 in 1 /Joystick button -
0008 4 in 1 /Joystick left -
000A 5 in 1 /Joystick right -
000C 6 in 1 /Joystick down -
000E 7 in 1 /Joystick up -
0010 8 int 1 /Keyboard scancode available -
0012 9 in 0 (mirrors 003A) -
0014 10 in 1 /Left Mouse button (mirrors 0038) -
0016 11 in 1 /Real-time clock interrupt (mirrors 0036) -
0018 12 in 1 /INTB (mirrors 0034) -
001A 13 in 1 (reflects output 0032) -
001C 14 in 0 - -
001E 15 in 1 (reflects output 002E) -
0020 16 out 0 RESET (P-Box, pin 6 (inverted)) -
0022 17 out 1 /V9938 reset -
0024 18 out 1 Joystick select -
0026 19 - 0 - -
0028 20 - (out) 0 - PFM512 bank-switch 1 of 2
002A 21 - 0 - -
002C 22 out 1 /Keyboard reset -
002E 23 out 1 PAL pin 5 (System clock speed?) -
0030 24 - 0 - -
0032 25 out 1 Video wait states (PAL pin 19) -
0034 26 in 1 /INTB (P-Box pin 18) -
0036 27 in 1 /Real-time clock interrupt -
0038 28 in 1 /Left mouse button -
003A 29 in (out) 0 Connected to GND PFM512 bank switch 2 of 2
003C 30 in 1 /Keyboard interrupt (mirrors 0010, no int) -
003E 31 in 1 /Joystick up (mirrors 000e) -
13C0-13FE Single step
Address Bit Default Meaning
1EE0 0 0 Decrementer in event counter mode (0=in timer mode)
1EE2 1 0 Enable decrementer
1EE4 2 0 Interrupt level 1 latch
1EE6 3 0 Interrupt level 2 latch
1EE8 4 1 Interrupt level 4 latch
1EEA 5 0 not used
1EEC 6 0 not used
1EEE 7 0 CapsLock flag
1EF0 8 1 Keyboard control
1EF2 9 1 Keyboard control
1EF4 10 1 Geneve mode (/TI mode)
1EF6 11 0 Direct mode (/Mapper mode)
1EF8 12 1 Cartridge rom size (1=8 KiB, 0=16 Kib)
1EFA 13 1 /Protect 6xxx
1EFC 14 1 /Protect 7xxx
1EFE 15 1 /Add wait state per memory cycle
1FDA 125 0 Macro Instruction Detect

The MID flag is set whenever the CPU encounters an unknown opcode. This (together with the interrupt) may be used to implement new "commands" on the application level.

The bits on addresses 1EEA to 1EFE are so-called user-defined internal CRU flags. As such, they are just latches that store the recent setting (0 or 1) and return it when reading the bit again. However, the TMS 9995 processor propagates the setting to the outside world, while ignoring input from there. That is, when we set bit 15 to 1 (here on address 1efe),

  • the CPU stores the 1 on the corresponding flag
  • it also outputs the 1 on CRUOUT, with the address bus set to 1EFE, where it may have some specific effect. Here, it turns off wait states.

When we test the bit using TB, the processor reads the flag value, but it ignores any incoming bit on CRUIN. This is reasonable, as the address is visible outside, and external devices may attempt to send some value to the CPU.

Obviously these flag bits only make sense when used as outputs. Storing bits for later reading can be done better within the CPU RAM.


As always, CRU bits are queried and set with special commands. Bits are addressed as offsets to a base address which is stored in Workspace Register 12 (R12). The base address is stored in bits 3-14, so the R12 value is twice as high as the absolute bit address. (Note that bit 15 cannot be used since A15 and CRUOUT share the same line.) Base addresses are commonly noted as register 12 values.

Turn on Geneve mode:

LI   R12,>1EF4
SBO  0

or, equivalently

LI   R12,>1EE0
SBO  10

since >1EE0 + 2·10 = >1EE0 + >14 = >1EF4

(bit numbers are often given in decimal notation)

The LDCR and STCR commands are used to write or read multiple CRU bits. The base address is automatically incremented for each bit transfer. Bit transfers begin at the least significant bit. Note that it is relevant whether less than 9 bits are transferred: If less, the memory location is treated as a byte address, if more, as a word address.

LI   R12,>0006

reads the five joystick lines, storing the bits in the least significant five bits of the high byte of R0, with bit 3 at the right.

x x x up down right left but x x x x x x x x

If we had transferred 9 bits, all bits as shown above are shifted to the right by 8 positions (starting at the very right bit).

LI   R12,>1EF0
LI   R1,>F100   * binary: 11110001

This enables the keyboard clock, not clearing the input register, activating TI mode and mapping, cartridges have 8K, no write protection to 6xxx and 7xxx, and no wait states.