The Combined I/O Port: FEH
The ZX Spectrum uses the same I/O port address **FEH′** for multiple output functions. When you execute an
OUT (FEH), A` instruction, every bit in the Accumulator (A) controls a different piece of hardware.
The Output Byte Breakdown (OUT to `FEH′):
Bit | Function | Value (If Set) | Purpose |
---|---|---|---|
0-2 | Border Color | 000B - 111B |
Sets the color of the screen border (0=Black, 7=White). |
3 | Beeper Output | `08H′ | Toggles the speaker (0=Off, 1=On). |
4 | EAR Socket | `10H′ | Controls the tape recorder output (used for data saving/loading). |
5-7 | Unused | N/A | Ignored by the 48K Spectrum hardware. |
Controlling the Beeper
To produce sound, you must create a fast timing loop (Part 28) that toggles Bit 3 of the output byte.
Example: Beeper ON and OFF
BEEPER_ON EQU 08H
BEEPER_OFF EQU 00H
IO_PORT EQU 0FEH
PLAY_BEEP:
; 1. Turn Beeper ON (Bit 3)
LD A, BEEPER_ON
OUT (IO_PORT), A
CALL DELAY_ROUTINE ; Wait half a cycle (sets the pitch)
; 2. Turn Beeper OFF (Bit 3)
LD A, BEEPER_OFF
OUT (IO_PORT), A
CALL DELAY_ROUTINE ; Wait the other half cycle
RET ; Loop this entire block for duration/melody
Important: To avoid disrupting the EAR socket (Bit 4), you must ensure that Bit 4 remains low (0) if you are only playing sound, or you risk confusing the tape recorder.
Changing the Border Color
The border color is determined by the three lowest bits (Bits 0-2). To change the border color, you simply write the desired color code to the port.
Example: Setting Border to BRIGHT RED (Color Code 2)
BORDER_RED_CODE EQU 02H ; Color code for Red
SET_RED_BORDER:
LD A, BORDER_RED_CODE
; Ensure the Beeper bit (Bit 3) is also controlled if needed.
; If we want sound OFF, A = 00000010B
OUT (IO_PORT), A
RET
Pitfall: The Accumulator Overwrite
Since every bit in the Accumulator (A) affects a piece of hardware, you must always be careful not to accidentally turn the beeper ON while trying to change the border color, or vice versa. Always load the full 8-bit pattern into A before sending it to `FEH′.