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.
The Principle: The routine loops 16 times (once for each bit of the dividend). In each loop:
- Shift the Dividend one bit left (into the Carry flag).
- Shift the Quotient one bit left (with the Carry flag filling the new low bit).
- Conditionally subtract the Divisor from the high part of the Dividend.
Z80 Implementation Focus
We’ll use dedicated registers for the operation:
Register | Purpose |
---|---|
HL | Dividend (Initially holds the number to be divided) |
B | Divisor (The number to divide by) |
DE | Quotient (The final result) |
C | Loop Counter (16 iterations) |
Core Loop Logic (Simplified):
DIVIDE_16_BY_8:
LD C, 16 ; C ← Loop 16 times
LD DE, 0000H ; DE ← Quotient (Starts at 0)
DIV_LOOP:
; 1. Shift Dividend Left (through Carry flag)
ADD HL, HL ; Shift HL left (MSB goes into Carry)
; 2. Shift Quotient Left (Carry goes into Quotient's LSB)
RL E ; Rotate E left (Carry goes into bit 0)
RL D ; Rotate D left (Carry goes into bit 8)
; 3. Check if we can subtract Divisor
LD A, H ; Check the high byte of the Dividend
CP B ; Compare H with Divisor (B)
JP C, NO_SUBTRACT ; If Carry=1 (H < B), cannot subtract, skip
; Subtraction is possible: Subtract Divisor from High Byte of Dividend
SUB B ; A ← H - B
LD H, A ; H ← Result of subtraction (H now updated)
NO_SUBTRACT:
DJNZ DIV_LOOP ; Loop 16 times
; The 16-bit Quotient is in DE. The 8-bit Remainder is in H.
RET
Final Output
The final result of this process is:
- The Quotient (the main result) is in the DE register pair.
- The Remainder (the fractional part) is in the H register.