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):

  1. Initialize Result (`HL′) to 0.
  2. Get the Thousands digit. Multiply it by $1000$ and add to `HL′.
  3. Get the Hundreds digit. Multiply it by $100$ and add to `HL′.
  4. Get the Tens digit. Multiply it by $10$ and add to `HL′.
  5. 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