Z80 Assembly 28: Basic Sound Generation (The Beeper Port)

The Basics of Beeper Sound Many simple Z80 systems (like the ZX Spectrum) lack a dedicated sound chip and rely on a simple speaker connected to an I/O port. This speaker is known as the beeper. How Tones are Made: A tone is generated by rapidly toggling a single bit in the output port (switching the speaker ON and OFF) at a specific frequency. Frequency & Pitch: The speed of the toggling loop determines the tone’s frequency (pitch). ...

September 27, 2025

Z80 Assembly 22: Reading Keyboard Input via I/O Ports

The Keyboard Matrix Scan Unlike modern PCs, Z80 systems don’t receive ASCII codes from the keyboard. Instead, the keyboard is wired as a matrix of rows and columns. To detect a keypress, the Z80 must scan this matrix using its I/O ports. The Two-Step Process: Output (Strobe): The CPU writes a value to an I/O port to select (or “strobe”) a single row of the keyboard matrix. Input (Read): The CPU reads a value from another I/O port. The bits set to ‘1’ in the input byte indicate which keys in the selected row are currently being pressed. Example: Scanning a Single Row Let’s assume our target system uses I/O port FEH for both output (strobe) and input (read) and that the rows are addressed by setting one bit to ‘0’. ...

September 27, 2025

Z80 Assembly 21: Setting Up for a Target System (Screen and Memory)

The Shift to System Programming Up until now, our code has been generic. System programming requires us to stop using symbolic addresses (like PRINT_STRING_ADDR) and start using absolute hardware addresses specific to our target machine. Key System-Specific Areas We Must Identify: Program Load Address (ORG): Where our code starts. Screen Memory: The RAM address where display data is stored. I/O Ports: The addresses for keyboard, sound, and display chips. Setting the Origin (ORG) and Stack (SP) Before execution begins, the assembler must know where in memory the program will be placed. ...

September 27, 2025

Z80 Assembly 12: Block I/O (INIR, OTDR) for Hardware Speed

Block I/O: The Fastest Way to Talk to Hardware The Z80 features a unique set of block I/O instructions designed to quickly move data between a memory block and a single, fixed I/O port. These are crucial for fast operations like dumping screen memory to a display controller or quickly reading keyboard buffers. The Register Setup: Block I/O relies on the following registers for definition: Register Pair Purpose in Block I/O HL Memory Address (Source or Destination) B Counter (Number of transfers to perform) C I/O Port Address (The fixed hardware port) Input Block Commands (Reading from Port) The INIR (Input, Increment, Repeat) and INDR (Input, Decrement, Repeat) commands read data from the port specified by C and store it into memory pointed to by HL. ...

September 27, 2025

Z80 Assembly 10: Interrupt Modes and Handling External Events

What is an Interrupt? An interrupt is an external signal from a hardware device (like a timer or keyboard controller) that tells the CPU to immediately stop what it’s doing and execute a specific routine to handle the event. This is how the system maintains responsiveness. The Two Key Commands: Instruction Action Purpose EI Enable Interrupts Allows the CPU to listen for and respond to external interrupt requests. DI Disable Interrupts Prevents the CPU from responding to external requests (used for critical code sections). The routine that handles the interrupt must end with RETI (Return from Interrupt) or RETN (Return from Non-Maskable Interrupt) instead of a simple RET. ...

September 27, 2025