The Challenge of Fragmented Memory

In a simple Z80 OS, as programs are loaded and unloaded, the $64$ KB of RAM becomes fragmented (broken into small pieces of free and used memory). The OS kernel must have a fast way to find a contiguous block of free memory when a new program needs to be loaded.

The Free List (Simple Allocation)

The most common technique is the Free List, a simple linked list (Part 33) that tracks all available blocks of memory.

How it Works:

  1. Node Structure: Each node in the list points to a free memory block and stores its size (16-bit).
  2. Request: When a program requests $N$ bytes, the OS traverses the Free List to find the first block that is large enough.
  3. Split: If the block is larger than $N$, the block is split into a Used block (size $N$) and a smaller New Free block, which is re-inserted into the Free List.

Disadvantage: Over time, this leads to tiny, unusable free blocks (external fragmentation).

The Memory Map (Protection)

The kernel occupies the most critical area of memory. The OS must strictly prevent user programs from executing code or writing data into the kernel’s space, which would instantly crash the system.

Method 1: Hardware Protection (If Available) Some advanced Z80 systems (like the Z180 or Z8000) have hardware that can enforce memory boundaries, preventing writes outside a designated area. The Z80 itself does not have this hardware.

Method 2: Software Protection (The Boundary Check) The Z80 OS must enforce protection through software:

  1. Define Boundaries: The kernel is fixed to the highest or lowest memory addresses (e.g., F000H′ to FFFFH′).
  2. System Call Check: Every system call that allows the user program to write to memory must include a routine to check if the target address falls outside the allowed user space.
KERNEL_START EQU 0F000H

CHECK_ADDRESS:
    ; Assume HL holds the address requested by the user program
    LD   A, H             ; Load High Byte of HL
    CP   HIGH(KERNEL_START); Compare with the kernel's high byte
    JP   C, ADDRESS_OK    ; Jump if Carry set (HL is below F000H)
    
    ; If the jump is NOT taken, the address is ≥ F000H
    JP   SEGMENTATION_FAULT ; Terminate the program!

Swapping (Advanced)

For systems with more than $64$ KB of RAM, the OS must manage the allocation of physical memory banks (Part 43) to virtual address space, effectively giving each active process its own $64$ KB memory map. This is complex and relies heavily on the Memory Management Unit (MMU) hardware.