Next Registers

The Next’s machine state is in a bank of registers reached through two ports, not through the Z80’s I/O space directly. Write the register number to $243B, then read or write its value at $253B. The NEXTREG instructions do both in one instruction; see Z80N Instructions.

        nextreg $07,3           ; CPU speed: 28 MHz

A read returns the write format with reserved and one-shot bits forced to zero, unless an entry below says otherwise.

The page describes the hardware, as the FPGA design defines it. The examples are Z80N assembly.

Machine configuration

These registers reconfigure the whole machine.

$02 Reset

BitMeaning
7bus / expansion reset
4the I/O trap fired (read); see Sound and miscellaneous
3generate a Multiface NMI, gated by $06 bit 3
2generate a DivMMC NMI, gated by $06 bit 4
1hard reset
0soft reset

⚠ Bits 2 and 3 are as shown. The design documentation and the wiki label them bit 3 DivMMC and bit 4 Multiface, which is wrong.

        nextreg $02,%00000001   ; soft reset

$03 Machine type and display timing

Bits[2:0] select the machine type: 111 enters config mode, 001 to 100 select a machine and leave config mode, and 000 changes neither. Bits[6:4] select the machine timing: 000 or 001 48K, 010 128K, 011 +3, and 1xx Pentagon. Bit 3 toggles the user lock on display timing. A read returns the palette sub-index in bit 7, then the machine timing, the lock bit and the machine type.

Config mode is not in the read-back, so a program cannot read whether it is in config mode. The machine type changes only in config mode; entering config mode does not require it, so a running program can re-enter config mode.

The timing bits select the ULA timing, the contention pattern and which banks are contended, as well as the frame length; see Machine Timing. Any write to $03 also disables the boot ROM.

A read of $32 means +3 timing (011) and the 128K machine type (010).

$05 Peripheral 1

BitsMeaning
7–6left joystick mode, low bits
5–4right joystick mode, low bits
3left joystick mode, high bit
260 Hz (1) or 50 Hz (0)
1right joystick mode, high bit
0scandouble

The 50/60 Hz bit changes the vertical timing, so it changes the frame length, the interrupt line and the raster counter together. The joystick bits select what ports $1F and $37 present.

The 50/60 Hz and scandouble bits read back as the value latched at the last frame, so a read straight after a write can return the old value.

A value of $04 selects 60 Hz, with both joysticks in mode 0.

$06 Peripheral 2

BitMeaning
7CPU speed hotkey enable
6internal speaker beep
550/60 Hz hotkey enable
4DivMMC NMI button enable, gating $02 bit 2
3Multiface NMI button enable, gating $02 bit 3
2PS/2 mode
1–0PSG mode: 00 YM, 01 AY, 1x off

The PSG mode selects the envelope behaviour and the volume curve. The Next starts in YM mode, a different timbre from an AY-3-8910.

        nextreg $06,%10110001   ; both hotkeys, the DivMMC NMI button, AY mode

$07 CPU speed

Bits[1:0] select 3.5, 7, 14 or 28 MHz. A read returns the actual speed in bits[5:4] and the programmed one in bits[1:0]. Enabling the expansion bus holds the actual speed at 3.5 MHz whatever is programmed. Machine Timing covers the 28 MHz wait state.

With the CPU running at 28 MHz after nextreg $07,3, a read returns $33.

$08 Peripheral 3

BitMeaning
7write 1 to unlock $7FFD paging
6disable contention
5PSG stereo mode, ABC or ACB: swaps the centre channel B with C
4internal speaker enable
3DAC enable, gating every DAC port
2port $FF read enable
1Turbosound enable
0keyboard issue 2
        nextreg $08,%00011010   ; speaker, DAC and Turbosound on

$09 Peripheral 4

Bits[7:6] are the per-chip PSG mono bits, then the sprite-id lockstep, bit 4 the HDMI audio disable, bit 3 a one-shot that clears the DivMMC MAPRAM, and bits[1:0] the scanline weight. Bit 3 is the only way to clear MAPRAM short of a hard reset.

The scanline bits are cycled by the F7 hotkey, which is not gated by $06.

        nextreg $09,%00001000   ; clear MAPRAM; scanlines off

$0A Peripheral 5

BitsMeaning
7–6Multiface type: 00 MF+3, 11 MF48, otherwise MF128. It changes the ports the Multiface answers on
5SD card swap
4DivMMC automap enable
3mouse button reverse
1–0mouse DPI

The Multiface type and SD swap fields change only in config mode; the automap enable, button reverse and DPI change at any time. Clearing bit 4 resets the whole automap, the $0066 NMI entries included.

The DPI field scales each mouse packet in the mouse’s receiver, before the counters at ports $FBDF and $FFDF:

$0A bits 1–0Movement
00 low×2
01 default×1
10 medium÷2
11 high÷4

A higher setting divides more, since a higher-resolution mouse sends more counts for the same movement. The scaling is applied to each packet, at 80 packets a second, and the results are summed, so slow movement at a high divisor produces no movement at all.

        nextreg $0A,%00010010   ; automap on, mouse DPI medium

$0B Joystick I/O mode

Bit 7 enables I/O mode, and bits[5:4] select it. Bit 4 also picks the joystick port, left or right. Bit 0 picks the UART for the serial modes: 0 the ESP (UART 0), 1 the Pi (UART 1).

Bits 5–4Joystick pin 7 carries
00bit 0, as a static level
01a level toggled by CTC channel 3’s zero count. With bit 0 clear it toggles once, giving a single rising edge; with bit 0 set it toggles on every zero count, dividing by two
10, 11the selected UART’s transmit line, on the left (10) or right (11) port

In the serial modes the UART also takes its receive line from the pad’s C button pin and its CTS from the B button pin, both inverted, in place of the module connector, which is held off. CTS is live only when that UART uses hardware flow control.

$0B does not stop the joystick ports being read. $1F and $37 read the same pins the serial lines use. Pin 7 has no read-back path, so a program cannot read what it drove.

        nextreg $0B,%10100000   ; the ESP's UART on the left joystick port

$11 Video timing

Bits[2:0] select the display-timing profile. A write reprograms the clock generator, so every derived clock, the CPU’s included, moves together: a frame is the same number of cycles in every profile and only the wall-clock rate changes.

$11System clock, nominal (Hz)System clock, achieved (Hz)
028 000 00028 000 000
128 571 42928 583 333
229 464 28629 437 500
330 000 00030 000 000
431 000 00031 000 000
532 000 00032 000 000
633 000 00033 000 000

Modes 1 and 2 do not reach their nominal rate; a rate derived from the profile uses the achieved column.

There is no mode 7. A write of 111 stores 000. On an issue 2 board only modes 0 and 1 exist, and a write keeps bit 0 alone. The register changes only in config mode.

The UART prescaler counts cycles of this clock, so a baud rate programmed as clock ÷ rate holds in every profile: 115200 baud in mode 3 is a prescaler of 30 000 000 ÷ 115 200 = 260.

Identity

RegMeaning
$00 / $01machine id / core version
$0E / $0Fsub-version / board issue
$10anti-brick, core id and the board buttons on read
$7Fuser scratch register

Bizmuth emulates the KS3 board, whose machine id in $00 is $0A.

Video

Layer 2 and global

RegMeaning
$12 / $13Layer 2 active bank / shadow bank
$14global transparent colour
$15bit 7 LoRes enable, bit 6 sprite priority, bit 5 sprite border clip, bits[4:2] layer priority and blend, bit 1 sprites over border, bit 0 sprites enable
$16 / $17 / $71Layer 2 scroll X low, scroll Y, scroll X msb
$18Layer 2 clip window: four writes, auto-advancing
$70Layer 2 resolution and palette offset

⚠ $15 bit 6 is 0 at reset, which puts the highest-numbered sprite on top. A program assuming the opposite draws its sprites in the wrong order.

        nextreg $15,%00000011   ; sprites on, and over the border

ULA, clipping and scrolling

RegMeaning
$1AULA clip window: four writes
$1Ca write resets the Layer 2, sprite, ULA and tilemap clip indices; a read returns all four
$26 / $27ULA hardware scroll X / Y. X honours the $68 bit 2 fine-scroll enable
$42ULANext attribute format mask
$43palette write select, active palette selects, ULANext enable; bit 7 disables palette auto-increment
$68bit 7 ULA disable, bits[6:5] blend operand, bit 4 cancel extended keys, bit 3 ULA+ enable, bit 2 ULA fine scroll X enable, bit 0 ULA stencil
$69a mirror: bit 7 drives port $123B Layer 2 enable, bit 6 the $7FFD shadow bit, bits[5:0] the port $FF Timex mode

$69 is not a register of its own: writing it changes state that also lives in ports.

Setting the ULA clip window to the central 128 × 96 pixels:

        nextreg $1C,%00000100   ; reset the ULA clip index
        nextreg $1A,64          ; x1
        nextreg $1A,191         ; x2
        nextreg $1A,48          ; y1
        nextreg $1A,143         ; y2

Sprites, tilemap and LoRes

RegMeaning
$19sprite clip window: four writes
$1Btilemap clip window: four writes
$2F / $30tilemap scroll X, msb and low (10-bit)
$31tilemap scroll Y
$32 / $33LoRes scroll X / Y
$34sprite mirror id (read); $35–$39 write the attributes and auto-advance
$4B / $4Csprite / tilemap transparent index
$6ALoRes Radastan mode, XOR, and palette offset
$6B / $6Ctilemap control / default attribute
$6E / $6Ftilemap map base / tile definitions base, in bank 5 or 7
        nextreg $31,8           ; tilemap scrolled up 8 pixels

Palette

RegMeaning
$40palette index
$41palette data, 8-bit RRRGGGBB, auto-incrementing unless $43 bit 7 is set
$44palette data, 9-bit plus priority, in two writes
$28stored palette value read-back
$4Afallback colour, shown where every layer is transparent

Writing $40 or $43 restarts the two-byte sequence $44 is part way through, so an interrupted upload resumes on the wrong half unless the index is written again.

        nextreg $40,16          ; palette entry 16
        nextreg $41,%11100000   ; bright red

Memory and paging

MMU

$50–$57 hold one 8K page number per slot, and a read returns the live mapping. Pages run 0 to 223 on a machine with all its memory fitted. A page number from $E0 to $FF in slot 0 or 1 maps the ROM there, and in slots 2 to 7 maps nothing. Reset sets slots 0 and 1 to $FF.

MMU page P is physical 8K bank P + 32. Physical banks 0 to 31 have no page number and are reachable only through config mode.

        nextreg $56,20          ; page 20 at $C000

Paging and expansion

RegMeaning
$80 / $81expansion bus enable and control
$82–$85internal_port_enable: which internal port groups decode at all
$86–$8Abus_port_enable and propagate, for expansion-bus port decode
$8Calternate ROM: bit 7 enable, bit 6 write, and the lock bits
$8Epaging shortcut for $7FFD / $1FFD / $DFFD; the read reconstructs live state
$8Fmemory mapping mode, standard or Pentagon

An internal port group that is not enabled in $82–$85 does not decode, so a port that appears dead is checked there first. The bit map is on the ports page.

$8C loads a replacement ROM without config mode. With bits 7 and 6 both set, writes to the ROM region land in the alternate ROM while reads still come from the real ROM; clearing bit 6 then makes the alternate ROM live. The alternate ROM is physical banks 12 to 15: one 16K image for the 128K ROM slot and one for the 48K.

        nextreg $8C,%11000000   ; writes to $0000-$3FFF fill the alternate ROM

Copper

RegMeaning
$60copper instruction / data write
$61 / $62list index low / mode in bits[7:6] plus index msb
$63copper data pair write
$64copper and line-interrupt vertical offset
        nextreg $61,0
        nextreg $62,0           ; copper stopped, list index 0

Extended keys

$B0–$B2 are read-only, and a set bit means the key is pressed.

RegBit 7 → bit 0
$B0; " , . UP DOWN LEFT RIGHT
$B1DELETE EDIT BREAK INV TRUE GRAPH CAPS LOCK EXTEND
$B2the extended joystick buttons, right pad then left pad

With only the up arrow held, $B0 reads $08.

$68 bit 4 does not hide a key from $B0 or $B1. It stops an extended key also pressing its CAPS SHIFT combination in the $FE keyboard rows, so an arrow key no longer reads as CAPS SHIFT + 7 there; $B0 still reports it.

DivMMC automap entry points

Which addresses page DivMMC in, on what condition, and with what timing. Bit n of $B8–$BA refers to the RST entry at address n × 8.

RegMeaning
$B8RST entry enable. Reset $83 enables $0000, $0008 and $0038
$B9per-entry condition: 1 fires always; 0 fires only while the 128K ROM 3 is paged. Reset $01
$BAper-entry timing: 1 maps DivMMC for this fetch; 0 from the next instruction fetch. Reset $00
$BBthe other entries: bit 0 $0066 NMI delayed, bit 1 $0066 NMI instant, bit 2 $04C6, bit 3 $0562, bit 4 $04D7, bit 5 $056A, bit 6 $1FF8–$1FFF unmap, bit 7 $3Dxx instant. Reset $CD

The $BB bits 2 to 5 entries and the $3Dxx entry fire only while ROM 3 is paged, whatever $B9 holds. The $0066 entries fire only on a DivMMC NMI, so ordinary code running at $0066 does not map DivMMC in.

DivMMC outranks everything a program can page. An automap that fires wins over Layer 2, the alternate ROM and RAM the MMU put at $0000. But mapping RAM into slot 0 or 1 disables every entry conditional on ROM 3, so with the reset settings only $0000 still maps DivMMC in.

        nextreg $B8,%10000001   ; automap on RST $00 and RST $38 only

Interrupts

RegMeaning
$C0bits[7:5] IM2 vector base, bit 3 stackless NMI, bits[2:1] the CPU’s live interrupt mode (read only), bit 0 hardware IM2 mode
$C2 / $C3return address low / high for the stackless NMI
$C4interrupt enables: ULA, line, expansion bus
$C5CTC interrupt enable mask
$C6UART interrupt enables: bits 6 and 2 transmit empty, 5 and 1 receive near full, 4 and 0 receive available, for UART 1 and UART 0
$C8–$CAinterrupt status: line, ULA, CTC, UART, expansion bus; writing a 1 clears a bit
$CC–$CEwhich interrupt triggers the DMA

A UART’s receive near-full and receive-available conditions share one interrupt per channel: the enables select which raises it, and near-full wins when both are set. A device whose interrupt is disabled still sets its status bit, so it can be polled.

The interrupt priority, highest first: the line interrupt, UART 0 receive, UART 1 receive, CTC channels 0 to 7, the ULA, UART 0 transmit, UART 1 transmit. Receive outranks every CTC channel and the ULA; transmit ranks below all of them.

        nextreg $C0,%10100001   ; vectors from $A0, hardware IM2 mode on

Sound and miscellaneous

$2C, $2D and $2E are a DAC write alias of the Soundrive channels: $2C left to channel B, $2D mono to channels A and D, $2E right to channel C, all gated by $08 bit 3. A read returns the Pi’s I2S input sample instead, a different signal. The copper can write $2D once per scanline to stream digital audio.

        nextreg $2D,$80         ; mono DAC sample at the midpoint

$D8–$DA are the I/O trap: enable, the written byte, and the cause. A write to $2xFD or $3xFD with the trap enabled raises a Multiface NMI. $90–$93, $98–$9B and $A0 upward are Pi GPIO. $F0 and $F8–$FA are the xdev command and the FPGA’s own temperature and voltage sensing.

Unemulated hardware

These registers exist and store values, with nothing behind them:

  • Expansion bus devices: nothing is attached, so $81 and $86–$8A gate nothing. Enabling the bus with $80 still holds the CPU at 3.5 MHz.
  • Pi GPIO and I2S: $90–$93, $98–$9B, $A0 upward, and the read side of $2C/$2D/$2E.
  • FPGA hardware sensing: $F0, $F8–$FA.

See also

← Reference