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).
Byte | Bits 15-12 (Digit 4) | Bits 11-8 (Digit 3) | Bits 7-4 (Digit 2) | Bits 3-0 (Digit 1) |
---|---|---|---|---|
High Byte | Thousands | Hundreds | ||
Low Byte | Tens | Units |
The Conversion Algorithm
The conversion is done by multiplying each BCD digit by its place value ($1, 10, 100, 1000$) and summing the results. This relies on the shift-and-add method for 16-bit multiplication (Part 16).
The Calculation Sequence (Simplified):
- Initialize Result (`HL′) to 0.
- Get the Thousands digit. Multiply it by $1000$ and add to `HL′.
- Get the Hundreds digit. Multiply it by $100$ and add to `HL′.
- Get the Tens digit. Multiply it by $10$ and add to `HL′.
- Get the Units digit. Add it to `HL′.
Z80 Implementation Focus
The routine focuses on isolating the BCD digits and running the efficient 16-bit multiplication routines.
Step 1: Isolate a Digit We use the `AND′ instruction to isolate the four bits of the desired digit.
BCD_VAL_LOW EQU 8000H
GET_HUNDREDS_DIGIT:
LD A, (BCD_VAL_LOW + 1) ; A ← High byte of BCD (Thousands/Hundreds)
AND 0FH ; A ← Mask off Thousands, isolate Hundreds
; The result in A is a value from 0 to 9.
RET
Step 2: Multiply and Accumulate The core of the loop calls the 16-bit multiply routine with a fixed constant (1000, 100, or 10) and accumulates the result in a final 16-bit register pair.
CONVERT_ROUTINE:
LD HL, 0000H ; HL ← Final binary result (accumulator)
; Process Hundreds Digit (example)
CALL GET_HUNDREDS_DIGIT ; C ← hundreds digit (0-9)
LD B, 0 ; B ← 0
LD DE, 100 ; DE ← Multiplier (100)
CALL MULTIPLY_8_BY_16 ; Multiplies BCD digit by 100
; Add result (often stored in DEHL) to HL
CALL ADD_32_TO_16_BIT
; Repeat for other digits
RET