Z80 Assembly 88: Block Move (memcpy) and Swap (memswap)

The Need for Block Operations In system programming and game development, you constantly need to move large chunks of data—transferring level data, shifting arrays, or buffering screen regions. Writing a loop for this is slow; the Z80 provides dedicated instructions for speed. Routine 1: Block Move (memcpy) `memcpy′ (Memory Copy) copies a block of bytes from a source address to a destination address. This is the fastest way to achieve the operation. ...

September 28, 2025

Z80 Assembly 87: 16-bit Comparison (Greater Than, Less Than, Equal)

The Need for 16-bit Comparison The Z80 has a dedicated CP R&prime; (Compare) instruction, but it only works on 8-bit values. When dealing with addresses, large scores, or multi-byte numbers, you need a robust routine to compare two 16-bit pairs, such as HL′ against `DE′. Goal: Compare HL with DE and set the flags (Zero, Carry) to indicate if HL &equals; DE&prime;, HL < DE′, or `HL > DE′. The Comparison Strategy: Subtraction The fastest way to compare two numbers is to subtract one from the other. ...

September 28, 2025

Z80 Assembly 86: Calculating a Checksum or CRC

The Need for Data Integrity When data is transferred over an unreliable medium (like a cassette tape or a network connection), or when code is loaded from disk, electrical noise or corruption can change the data bytes. A Checksum or CRC provides a simple way to verify that the data received is exactly what was sent. Method 1: The Simple Checksum (The Fast Way) A simple checksum is the fastest method. It involves adding up every byte in the data block. ...

September 28, 2025

Z80 Assembly 85: Fast Block Fill (memset/bfill) with a Constant

The Need for a Fast Block Fill In game development and system programming, you frequently need to clear large areas of RAM—such as setting the entire screen buffer to a black background or zeroing out a data structure. Doing this one byte at a time with a simple loop is slow. Goal: Write a routine that fills a specified memory range (START_ADDR&prime; to END_ADDR′) with a single constant byte (`FILL_BYTE′) as quickly as possible. ...

September 28, 2025

Z80 Assembly 84: 16-bit Binary to BCD Conversion

The Challenge of Displaying Numbers Once the Z80 has calculated a final value (e.g., a score of 4296 decimal), this number is stored as a 16-bit binary value (1000010000000000B). To display it on the screen, we need to convert it into a sequence of decimal digits (4&prime;, 2′, 9&prime;, 6′) that can be looked up in the font table. Goal: Convert a 16-bit binary number into a 16-bit BCD value (four decimal digits). ...

September 28, 2025

Z80 Assembly 83: 16-bit BCD to Binary Conversion

The Challenge of User Input When a user types a number (e.g., 4296), it is stored as a series of ASCII characters (or often converted immediately into Binary-Coded Decimal (BCD)). The Z80 needs this number in a single 16-bit binary value for fast calculation. Goal: Convert a 16-bit BCD value (representing a number from 0 to 9999) into a 16-bit binary value. The BCD Structure A 16-bit BCD value typically uses the entire word (two bytes) to store four decimal digits (0-9). ...

September 28, 2025

Z80 Assembly 82: Fixed-Point Arithmetic (Fast Fractions)

The Need for Fixed-Point Math As established (Part 30), Z80 floating-point math is extremely slow. Fixed-point arithmetic is the solution: it allows the Z80 to perform calculations involving fractions using only fast integer operations. The Principle: A fixed-point number is an integer where the position of the decimal point is implied and fixed by the programmer. The Q-Format (Standard Fixed-Point) We represent a fractional number (like 3.14) by scaling it up to make it an integer. This is often called a Q-format (e.g., Q16, Q8). ...

September 28, 2025

Z80 Assembly 81: Floating-Point Multiplication/Division by Powers of Two

The Optimization: Exploiting the Format In standard integer math, multiplying by a power of two is done with a fast left shift (`SLA′). In floating-point math (Part 30), a multiplication or division by a power of two (like $2^N$ or $2^{-N}$) is even faster: it requires no change to the Mantissa (precision) and only a simple addition or subtraction to the Exponent. The Rule: Multiplication by $2^N$: Add $N$ to the Exponent. Division by $2^N$: Subtract $N$ from the Exponent. The Exponent Field Recall that the exponent is usually stored as a biased 8-bit integer (e.g., a bias of 127 is added to the true exponent). Adjusting the number simply means adjusting this byte. ...

September 28, 2025

Z80 Assembly 80: Floating-Point Square Root (Newtons Method)

The Challenge: Precision and Speed Calculating the square root of a floating-point number (Part 30) is required for precise calculations like distance, physics, or graphics shading. This requires an iterative algorithm that works across the multi-byte structure of the float. Method: The Newton-Raphson Method is the preferred algorithm for floating-point square roots because it is computationally fast (it converges quadratically). The Newton-Raphson Formula The goal is to iteratively refine a guess ($x_{n+1}$) using the previous guess ($x_n$) until the guesses stop changing (convergence). ...

September 28, 2025

Z80 Assembly 79: Square Root Calculation (Newton's Method vs. Binary Search)

The Challenge of Square Roots The Z80 cannot natively calculate a square root. This complex operation must be achieved using an iterative algorithm that repeatedly guesses the answer and refines the guess until it is accurate enough. Goal: To find the largest integer $R$ such that $R^2 \le N$, where $N$ is the input number. Method 1: Integer Binary Search (The Reliable Method) The Binary Search method is the safest and most reliable way to find the integer square root on an 8-bit processor. It works by checking the midpoint of a search range. ...

September 28, 2025