The Challenge of Portability

Throughout this series, we encountered system-specific hardware addresses: screen memory (4000H′), keyboard ports (FEH′), and sound chips (`AY-3-8910′). Code written for the ZX Spectrum will not run on an MSX or a CP/M machine without significant modification.

Code Portability is the practice of writing code that minimizes these machine-specific differences, allowing the main logic to be compiled for multiple platforms.

Method 1: Conditional Assembly

The most fundamental technique is Conditional Assembly. The assembler is instructed to include or exclude specific blocks of code based on a platform constant defined at the beginning of the file.

The Logic:

PLATFORM_SPECTRUM EQU 1       ; Set this constant to 1 for Spectrum builds
PLATFORM_MSX    EQU 0

IF PLATFORM_SPECTRUM
    KEYBOARD_PORT EQU 0FEH    ; Use Spectrum's specific I/O port
ELSEIF PLATFORM_MSX
    KEYBOARD_PORT EQU 0A0H    ; Use MSX's specific I/O port
ENDIF

; ...
; The main code always uses the KEYBOARD_PORT label, regardless of the target.
; ...

Method 2: The Hardware Abstraction Layer (HAL)

For complex operations (like drawing a pixel or playing a sound), simply changing a port number is insufficient. A Hardware Abstraction Layer (HAL) is required.

How the HAL Works:

  1. Define Standard API: Create a standard set of function labels (e.g., HAL_PUT_PIXEL′, HAL_PLAY_SOUND′) that your main application code will always call.
  2. Platform-Specific Routines: Create a separate source file (e.g., hal_spectrum.asm′ or hal_msx.asm′) for each target platform. These files contain the actual machine code that implements the API using the correct port I/O and memory maps for that specific machine.
  3. Linking: At compile time, you link the main application code only with the HAL file corresponding to your target platform.

Advantage: The main application logic remains 100% portable, ensuring future maintenance is simple.

Conclusion: The Z80 Programmer’s Triumph

The Z80, with its tiny $64$ KB address space and reliance on peripherals, forces programmers to be masters of organization, timing, and optimization. By learning techniques like the HAL, you transcend the limitations of the hardware itself.

From Core Logic to Networking: You have mastered everything from bit manipulation (`BIT/SET/RES′) to full network stack implementation (TCP/IP concepts). The Z80 remains a testament to what is possible with brilliant software engineering.