Hardware Ports

When an port is read from (with 'IN') or written to (with 'OUT'), it will activate a number of devices external to the Z80, depending on the port address. In general, devices respond if certain bits in the binary representation port number are set and/or reset, rather than to a specific port number; this is known as 'partial decoding'. Whilst this makes the decoding hardware easier to make, it does mean that a considerable amount of congestion has occured in the space available for new peripherals to respond to if they do not wish to clash with any current devices.

The next complication is to do with the Z80's I/O instructions: it is quicker and easier to select the low 8 bits of the port number than it is to select the high 8 bits; this means that, when outputting to peripherals for which the upper 8 bits make no difference, this will often be left unset, and may contain garbage. Thus, the 48K ULA, which responds to all even port addresses, is often referred to as Port 0xfe, rather than the full 16-bit port 0xfffe.

Listed below are some of the available peripherals (including those like the ULA, which are in every machine), and the bit fields to which they respond. In the table, '-' means 'don't care', '0' means the bit must be reset for the peripheral to respond, and '1' means it must be set.

All definitions shown below were provided by Erik Kunze, author of the XZX-Pro emulator.

  • Systems:
    • Peripheral: 48K ULA.
      Port: ---- ---- ---- ---0 (More information).

    • Peripheral: Timex TS2068 ULA.
      Port: ---- ---- 1111 1110 (Same as 48K ULA).

    • Peripheral: Timex TS2068 Display mode.
      Port: ---- ---- 1111 1111

    • Peripheral: Timex TS2068 Horizontal Select Register.
      Port: ---- ---- 1111 0100

  • Audio:
    • Peripheral: 128K AY Register.
      Port: 11-- ---- ---- --0- (More information).

    • Peripheral: 128K AY (Data).
      Port: 10-- ---- ---- --0- (More information).

    • Peripheral: Timex TS2068 AY Register.
      Port: ---- ---- 1111 0101

    • Peripheral: Timex TS2068 AY (Data).
      Port: ---- ---- 1111 0110

    • Peripheral: Fuller Audio Box.
      /* Definitions for Fuller Audio Box */
      #define P_FULLER_CONTROL                0x3f    /* AY control */
      #define P_FULLER_DATA                   0x5f    /* AY data */
      #define P_FULLER_JOY                    0x7f    /* Joystick */
  • Memory:
    • Peripheral: ZX Spectrum +2A / +3 Memory
      Port: 01-- ---- ---- --0- (More information).

    • Peripheral: ZX Spectrum 128K / +2 Memory
      Port: 0--- ---- ---- --0- (More information).

    • Peripheral: +3 Memory.
      Port: 0001 ---- ---- --0- (More information).

  • Disk Controllers:
    • Peripheral: +3 FDC (Data).
      Port: 0011 ---- ---- --0- (More information).

    • Peripheral: +3 FDC (Status).
      Port: 0010 ---- ---- --0- (More information).

    • Peripheral: Beta 128.
      /* Definitions for Beta 128 */
      #define P_TRDOS_CMD                     0x1f    /* Command */
      #define P_TRDOS_STATE                   0x1f    /* State */
      #define P_TRDOS_TRACK                   0x3f    /* Track */
      #define P_TRDOS_SECTOR                  0x5f    /* Sector */
      #define P_TRDOS_DATA                    0x7f    /* Data */
      #define P_TRDOS_SYSTEM                  0xff    /* System */
    • Peripheral: +D.
      /* Definitions for +D */
      #define P_PLUSD_CMD                     0xe3    /* Command */
      #define P_PLUSD_STATE                   0xe3    /* State */
      #define P_PLUSD_PAGE                    0xe7    /* Memory paging */
      #define P_PLUSD_TRACK                   0xeb    /* Track */
      #define P_PLUSD_SYSTEM                  0xef    /* System register */
      #define P_PLUSD_SECTOR                  0xf3    /* Sector */
      #define P_PLUSD_PRINTER                 0xf7    /* Printer data/ready */
      #define P_PLUSD_DATA                    0xfb    /* Data */
    • Peripheral: D80.
      /* Definitions for D80 */
      #define P_D80_CMD                       0x81    /* Command (write) */
      #define P_D80_STATE                     0x81    /* State (read) */
      #define P_D80_TRACK                     0x83    /* Track (read/write) */
      #define P_D80_SECTOR                    0x85    /* Sector (read/write) */
      #define P_D80_DATA                      0x87    /* Data (read/write) */
      #define P_D80_SYSTEM                    0x89    /* System register (write)*/
    • Peripheral: JLO (Status/Command).
      Port: ---- ---- 1000 1111

    • Peripheral: JLO (Track).
      Port: ---- ---- 1001 1111

    • Peripheral: JLO (Sector).
      Port: ---- ---- 1010 1111

    • Peripheral: JLO (Data).
      Port: ---- ---- 1011 1111

    • Peripheral: JLO (Select).
      Port: ---- ---- 1011 0111

  • Interfaces:
    • Peripheral: +3 Centronics Interface.
      Port: 0000 ---- ---- --0-

    • Peripheral: Aerco Centronics Interface.
      Port: ---- ---- 0111 1111

    • Peripheral: ZX Interface I (RS232/Network).
      Port: ---- ---- ---1 0--- (More information).

    • Peripheral: ZX Interface I (Control).
      Port: ---- ---- ---0 1--- (More information).

    • Peripheral: ZX Interface I (Microdrive).
      Port: ---- ---- ---0 0--- (More information).

    • Peripheral: Kempston Joystick.
      Port: ---- ---- 000- ---- (More information).
      /* Definitions for Kempston joystick */
      #define P_KEMPSTON                      0x1f    /* Port address */
      #define B_KEMPSTON                      0x20    /* ---- ---- --0- ---- */
    • Peripheral: Sinclair Interface II Joysticks.
      /* Definitions for Sinclair Joysticks (Interface II) */
      #define P_SINCLAIR1                     0xeffe  /* Port address */
      #define B_SINCLAIR1                     0x1000  /* ---0 ---- ---- ---- */
      #define P_SINCLAIR2                     0xf7fe  /* Port address */
      #define B_SINCLAIR2                     0x0800  /* ---- 0--- ---- ---- */
    • Peripheral: Multiface I.
      /* Definitions for Multiface I */
      #define P_MF1_IN                        0x9f    /* Port address */
      #define P_MF1_OUT                       0x1f    /* Port address */
    • Peripheral: Multiface 128.
      /* Definitions for Multiface 128 */
      #define P_MF128_IN                      0xbf    /* Port address */
      #define P_MF128_IN_V2                   0x9f    /* Port address (Disciple)     
      */
      #define P_MF128_OUT                     0x3f    /* Port address */
    • Peripheral: Multiface 3.
      /* Definitions for Multiface 3 */
      #define P_MF3_IN                        0x3f    /* Port address */
      #define P_MF3_OUT                       0xbf    /* Port address */
      #define P_MF3_BUTTON                    0x3f    /* Port address */
      #define P_MF3_P7FFD                     0x7f3f  /* Port address */
      #define P_MF3_P1FFD                     0x1f3f  /* Port address */
  • Other:
    • Peripheral: ZX Printer.
      Port: ---- ---- ---- -0--

    • Peripheral: Timex TS2040 / Alphacom 32 Printers.
      Port: ---- ---- 1111 1011

    • Peripheral: ZX LPrint III.
      * Definitions for ZX LPrint III */
      #define P_LPRINT_ON                     0xfb    /* Page in LPRINT ROM */
      #define B_LPRINT_ON                     0x84    /* ---- ---- 1--- -0-- */
      #define P_LPRINT_OFF                    0x7b    /* Page out LPRINT ROM */
      #define B_LPRINT_OFF                    0x84    /* ---- ---- 0--- -0-- */
    • Peripheral: Grafpad (British Micro).
      /* Definitions for Grafpad (British Micro) */
      #define P_GRAFPAD_PEN                   0xff3f  /* Pen up/down */
      #define P_GRAFPAD_X                     0xffbf  /* Pen position X coordinate   
      */
      #define P_GRAFPAD_Y                     0xff7f  /* Pen position Y coordinate   
      */
    • Peripheral: Kempston Mouse.
      /* Definitions for Kempston Mouse */
      #define P_KMOUSE_BUTTONS                0xfadf  /* Port address */
      #define B_KMOUSE_BUTTONS                0x0120  /* ---- ---0 --0- ---- */
      #define P_KMOUSE_X                      0xfbdf  /* Port address */
      #define B_KMOUSE_X                      0x0520  /* ---- -0-1 --0- ---- */
      #define P_KMOUSE_Y                      0xffdf  /* Port address */
      #define B_KMOUSE_Y                      0x0520  /* ---- -1-1 --0- ---- */