<!-- PDF page 244 -->

### The ZX Spectrum Next Hardware Ports List

**NOTE**

The following Hardware Ports are not listed:\
**ULA 254 (FEh), Legacy Memory Paging 3765 (7FFDh), 8189 (1FFDh), 57341 (DFFDh), 61431 (EFF7h), Layer 2 4667 (123Bh) and ULAplus 65339 (FF3Bh) / 48955 (BF3B)**\
Ports are arranged according to their function.\
Please also consult the **ports.txt** document found in your **System/Next™** distribution for a complete list of ports

### Input / Output / Legacy Video

#### Port 255 (FFh) – Timex SCLD ULA Extensions\*

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td rowspan="4">Screen Mode Select</td><td rowspan="4">■</td><td rowspan="4">■</td><td></td><td></td><td></td><td></td><td></td><td>0</td><td>0</td><td>0</td><td>Std: DFILE0+COLOURFILE0 @ 4000h</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td>0</td><td>0</td><td>1</td><td>Shd: DFILE1+COLOURFILE1 @ 6000h</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td>0</td><td>1</td><td>0</td><td>HC: DFILE @ 4000h, COLOURFILE @ 6000h</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td>1</td><td>1</td><td>0</td><td>HR: even DFILE @ 4000h, odd DFILE @6000h</td></tr>
<tr><td rowspan="8">HiRes Colour Scheme Select</td><td rowspan="8">■</td><td rowspan="8">■</td><td></td><td></td><td>0</td><td>0</td><td>0</td><td></td><td></td><td></td><td>BRIGHT Black on White</td></tr>
<tr><td></td><td></td><td>0</td><td>0</td><td>1</td><td></td><td></td><td></td><td>BRIGHT Blue on Yellow</td></tr>
<tr><td></td><td></td><td>0</td><td>1</td><td>0</td><td></td><td></td><td></td><td>BRIGHT Red on Cyan</td></tr>
<tr><td></td><td></td><td>0</td><td>1</td><td>1</td><td></td><td></td><td></td><td>BRIGHT Magenta on Green</td></tr>
<tr><td></td><td></td><td>1</td><td>0</td><td>0</td><td></td><td></td><td></td><td>BRIGHT Green on Magenta</td></tr>
<tr><td></td><td></td><td>1</td><td>0</td><td>1</td><td></td><td></td><td></td><td>BRIGHT Cyan on Red</td></tr>
<tr><td></td><td></td><td>1</td><td>1</td><td>0</td><td></td><td></td><td></td><td>BRIGHT Yellow on Blue</td></tr>
<tr><td></td><td></td><td>1</td><td>1</td><td>1</td><td></td><td></td><td></td><td>BRIGHT White on Black</td></tr>
<tr><td>Frame Interrrupt Control</td><td>■</td><td>■</td><td></td><td>•</td><td></td><td></td><td></td><td></td><td></td><td></td><td>1 to Disable ULA Frame Interrupt</td></tr>
<tr><td>Timex MMU Select¹</td><td>■</td><td>■</td><td>•</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>Timex Horizontal MMU Bank Select</td></tr>
</tbody>
</table>

\* Only readable if **NR 8 (08h):D2** = **1**\
¹ Not implemented on the ZX Spectrum Next

#### Port 64479 (FBDFh) – Kempston Mouse X position

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>Current X Position</td><td>■</td><td></td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>Value 0 – 255*</td></tr>
</tbody>
</table>

\* Returns the current X position of the mouse **0 - 255**.\
The value wraps from **255** to **0** on a right movement and from **0** to **255** on a left movement.

#### Port 65503 (FFDFh) – Kempston Mouse Y position

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>Current Y Position</td><td>■</td><td></td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>Value 0 - 255*</td></tr>
</tbody>
</table>

\* Returns the current Y position of the mouse **0 - 255**.\
The value decrements and wraps from **255** to **0** on a downward movement and increments and wraps from **0** to **255** on an upward movement.

#### Port 64223 (FADFh) – Kempston Mouse Button Status

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td rowspan="3">Mouse Button Flags¹</td><td rowspan="3">■</td><td rowspan="3"></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>•</td><td>Left Mouse button status</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td>•</td><td></td><td>Right Mouse button status</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td>•</td><td></td><td></td><td>Middle Mouse button status</td></tr>
<tr><td>Mouse Wheel Position²</td><td>■</td><td></td><td>•</td><td>•</td><td>•</td><td>•</td><td></td><td></td><td></td><td></td><td>Mouse Wheel position (Wraps)</td></tr>
</tbody>
</table>

¹ Pressed = **1**, Not Pressed = **0**\
² Value **0** to **15**. Upwards scroll **15** to **0** – wraps to **15**; Downards scroll **0** to **15** – wraps to **0**

#### Port 31 (1Fh) – Kempston Joystick 1 / Mega Drive Pad 1 Status

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td rowspan="4">Joystick Movement Status</td><td rowspan="4">■</td><td rowspan="4"></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>•</td><td>Right (pin 4)</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td>•</td><td></td><td>Left (pin 3)</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td>•</td><td></td><td></td><td>Down (pin 2)</td></tr>
<tr><td></td><td></td><td></td><td></td><td>•</td><td></td><td></td><td></td><td>Up (pin 1)</td></tr>
<tr><td rowspan="4">Joystick Button Status</td><td rowspan="4">■</td><td rowspan="4"></td><td></td><td></td><td></td><td>•</td><td></td><td></td><td></td><td></td><td>Fire 1 (MD = B) (pin 6)</td></tr>
<tr><td></td><td></td><td>•</td><td></td><td></td><td></td><td></td><td></td><td>Fire 2 (MD = C) (pin 9)</td></tr>
<tr><td></td><td>•</td><td></td><td></td><td></td><td></td><td></td><td></td><td>MD = A (0 on Kempston)</td></tr>
<tr><td>•</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>MD Start (0 on Kempston)</td></tr>
</tbody>
</table>

Joystick ports can be placed in I/O mode via NR 11 (0Bh)\
Kempston joysticks and Mega Drive Pads share ports but MD pads use more bits\
The X/Y/Z buttons on MD pads can be read via NR 178 (B2h)\
All twelve MD pad buttons can be assigned to the keyboard – See NR 05 (05h)\
When using an MD pad in more limited joystick modes, the excess buttons can generate keypresses if so programmed

#### Port 55 (37h) – Kempston Joystick 2 / Mega Drive Pad 2 Status

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td rowspan="4">Joystick Movement Status</td><td rowspan="4">■</td><td rowspan="4"></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>•</td><td>Right (pin 4)</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td>•</td><td></td><td>Left (pin 3)</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td>•</td><td></td><td></td><td>Down (pin 2)</td></tr>
<tr><td></td><td></td><td></td><td></td><td>•</td><td></td><td></td><td></td><td>Up (pin 1)</td></tr>
<tr><td rowspan="4">Joystick Button Status</td><td rowspan="4">■</td><td rowspan="4"></td><td></td><td></td><td></td><td>•</td><td></td><td></td><td></td><td></td><td>Fire 1 (MD = B) (pin 6)</td></tr>
<tr><td></td><td></td><td>•</td><td></td><td></td><td></td><td></td><td></td><td>Fire 2 (MD = C) (pin 9)</td></tr>
<tr><td></td><td>•</td><td></td><td></td><td></td><td></td><td></td><td></td><td>MD = A (0 on Kempston)</td></tr>
<tr><td>•</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>MD Start (0 on Kempston)</td></tr>
</tbody>
</table>

Joystick ports can be placed in I/O mode via NR 11 (0Bh)\
Kempston joysticks and Mega Drive Pads share ports but MD pads use more bits\
The X/Y/Z buttons on MD pads can be read via NR 178 (B2h)\
All twelve MD pad buttons can be assigned to the keyboard – See NR 05 (05h)\
When using an MD pad in more limited joystick modes, the excess buttons can generate keypresses if so programmed

### Audio

#### Port 65533 (FFFDh) – PSG Control and Register Select

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>Selected Register Status</td><td>■</td><td></td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>Value in selected register of active PSG</td></tr>
<tr><td rowspan="4">Active PSG Control</td><td rowspan="4"></td><td rowspan="4">■</td><td></td><td></td><td></td><td></td><td></td><td></td><td>0</td><td>0</td><td>Reserved</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>1</td><td>PSG 0 made active*</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>0</td><td>PSG 1 made active</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td>0</td><td>1</td><td>PSG 2 made active</td></tr>
<tr><td rowspan="6">Stereo Channel Control¹</td><td rowspan="6"></td><td rowspan="6">■</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td></td><td></td><td>Reserved, must be 1</td></tr>
<tr><td></td><td></td><td></td><td></td><td>1</td><td></td><td></td><td></td><td>Reserved, must be 1</td></tr>
<tr><td></td><td></td><td></td><td>1</td><td></td><td></td><td></td><td></td><td>Reserved, must be 1</td></tr>
<tr><td></td><td></td><td>•</td><td></td><td></td><td></td><td></td><td></td><td>Right Channel Enable</td></tr>
<tr><td></td><td>•</td><td></td><td></td><td></td><td></td><td></td><td></td><td>Left Channel Enable</td></tr>
<tr><td>1</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>Reserved, must be 1</td></tr>
<tr><td>Register Select²</td><td></td><td></td><td>•</td><td>•</td><td>•</td><td>•</td><td></td><td></td><td></td><td></td><td>If <b>0000</b> selects a register from the Active PSG</td></tr>
</tbody>
</table>

\* Default value\
¹ If **NR 8 (08h):D1** = **1** and **D7** through **D4** are not **0000**

#### Port 49149 (BFFDh) – PSG Data

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>Selected Register Status¹</td><td>■</td><td></td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>Value in selected register of active PSG</td></tr>
<tr><td>Active PSG Register Data</td><td></td><td>■</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>Value to write to the register</td></tr>
</tbody>
</table>

¹ Readable if machine type is ZX Spectrum Next or ZX Spectrum +3 only.

#### Port 49141 (BFF5h) – PSG Info

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>Currently selected PSG register</td><td>■</td><td></td><td></td><td></td><td></td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>Value of selected register of active PSG</td></tr>
<tr><td>Reserved</td><td>■</td><td></td><td></td><td></td><td>•</td><td></td><td></td><td></td><td></td><td></td><td>Reserved</td></tr>
<tr><td rowspan="3">Active PSG</td><td rowspan="3">■</td><td rowspan="3"></td><td>1</td><td>1</td><td></td><td></td><td></td><td></td><td></td><td></td><td>PSG 0 is active</td></tr>
<tr><td>1</td><td>0</td><td></td><td></td><td></td><td></td><td></td><td></td><td>PSG 1 is active</td></tr>
<tr><td>0</td><td>1</td><td></td><td></td><td></td><td></td><td></td><td></td><td>PSG 2 is active</td></tr>
</tbody>
</table>

#### Ports 251¹, 223², 31³, 241⁴, 63⁵ (FBh, DFh, 1Fh, F1h, 3Fh) – DAC Channel A (Left)

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>DAC output</td><td></td><td>■</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>8-bit unsigned sample value</td></tr>
</tbody>
</table>

All DACs originate from various ZX Spectrum peripherals and compatible models and are kept for compatibility. DACs are enabled by setting **NR 8 (08h):D3** = **1**\
¹ Found in Pentagon and ATM\
² Found in SpecDRUM™\
³ Found in SoundDrive 1\
⁴ Found in SoundDrive 2\
⁵ Found in Profi Covox

#### Ports 179¹, 15², 243³ (B3h, 0Fh, F3h) – DAC Channel B (Left)

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>DAC output</td><td></td><td>■</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>8-bit unsigned sample value</td></tr>
</tbody>
</table>

All DACs originate from various ZX Spectrum peripherals and compatible models and are kept for compatibility. DACs are enabled by setting **NR 8 (08h):D3** = **1**\
¹ Found in GS Govox\
² Found in SoundDrive 1 and Covox\
³ Found in SoundDrive 2

#### Ports 179¹, 79², 249³ (B3h, 4Fh, F9h) – DAC Channel C (Right)

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>DAC output</td><td></td><td>■</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>8-bit unsigned sample value</td></tr>
</tbody>
</table>

All DACs originate from various ZX Spectrum peripherals and compatible models and are kept for compatibility. DACs are enabled by setting **NR 8 (08h):D3** = **1**\
¹ Found in GS Govox\
² Found in SoundDrive 1 and Covox\
³ Found in SoundDrive 2

#### Ports 251¹, 223², 95³ (FBh, DFh, 5Fh) – DAC Channel D (Right)

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>DAC output</td><td></td><td>■</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>•</td><td>8-bit unsigned sample value</td></tr>
</tbody>
</table>

All DACs originate from various ZX Spectrum peripherals and compatible models and are kept for compatibility. DACs are enabled by setting **NR 8 (08h):D3** = **1**\
¹ Found in Pentagon, ATM and SoundDrive 2\
² Found in SpecDRUM™\
³ Found in SoundDrive 1 and Profi Covox

### Storage

#### Port 227 (E3h) – divMMC Control

<table>
<thead>
<tr><th rowspan="2">Group Name</th><th rowspan="2">R</th><th rowspan="2">W</th><th colspan="8">Data Bits</th><th rowspan="2">Description</th></tr>
<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th><th>2</th><th>1</th><th>0</th></tr>
</thead>
<tbody>
<tr><td>RAM bank Control</td><td>■</td><td>■</td><td></td><td></td><td></td><td></td><td>•</td><td>•</td><td>•</td><td>•</td><td>Memory Bank Select for 8K - 16K region</td></tr>
<tr><td>MapRAM Control¹</td><td>■</td><td>■</td><td></td><td>•</td><td></td><td></td><td></td><td></td><td></td><td></td><td>MapRAM Enable</td></tr>
<tr><td>ConMEM Control²</td><td>■</td><td>■</td><td>•</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td>ConMEM Enable</td></tr>
</tbody>
</table>

¹ Can only be set once. On the original divMMC only a power cycle can reset it. The ZX Spectrum Next implementation uses **NR 9 (09h)** where **D3** can be set,in order to reset this bit. When set, it replaces the expected esxDOS ROM with divMMC RAM bank **3**\
² Can be used to manually control divMMC mapping. When set it maps in divMMC; **0K - 8K** will contain the esxDOS ROM, **8K - 16K** will contain the selected divMMC bank (from **D0** through **D3**). The divMMC automatically maps itself in when instruction fetches hit specific addresses in the ROM. When this happens, the esxDOS ROM (or divMMC bank **3** if mapRAM is set) appears in **0K - 8K** and the selected divMMC bank appears as RAM in **8K - 16K**. DivMMC automapping is normally disabled by NextZXOS. See **NR 6 (06h):D4**. The divMMC has been enhanced, in order to add entry points and make them programmable.

