Z80 Assembly 90: 16-bit Integer Division (Quotient and Remainder)

The Challenge of Integer Division The Z80 CPU has no instruction for division. Every division operation must be performed using software algorithms based on repeated subtraction or shifting and subtraction (the same method used for manual long division). Goal: Divide a 16-bit number (the Dividend) by an 8-bit number (the Divisor) to produce a 16-bit Quotient and an 8-bit Remainder. The Algorithm: Binary Long Division The most efficient method is to implement the Binary Long Division algorithm, which uses shifts and conditional subtraction. ...

September 28, 2025

Z80 Assembly 89: Block Search (memchr) and Compare (memcmp)

The Need for Block Search and Compare In system programming, you need routines to: Search (memchr): Find the first occurrence of a specific character (e.g., a null terminator, space, or command byte) within a buffer. Compare (memcmp): Verify that two large blocks of memory (e.g., two versions of a game level, or a password against a stored hash) are identical. Routine 1: Block Search (memchr) Block Search scans a memory area for the first occurrence of a specific 8-bit value. ...

September 28, 2025

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