Programming the Z80 (3rd edition) has the following code sample (section 3 p.135) for division of a 16-bit dividend by an 8-bit divisor returning an 8-bit quotient in L and an 8 bit remainder in H:
DIV168 LD A, (DVSAD) LOAD DIVISOR
LD D, A INTO D
LD E, 0
LD HL, (DVDAD) LOAD 16-BIT DIVIDEND
LD B, 8 INITIALIZE COUNTER
DIV XOR A CLEAR C BIT
SBC HL, DE DIVIDEND - DIVISOR
INC HL QUOTIENT = QUOTIENT + 1
JP P, NOADD TEST IF REMAINDER
POSITIVE
ADD HL, DE RESTORE IF NECESSARY
DEC HL QUOTIENT = QUOTIENT - 1
NOADD ADD HL, HL SHIFT DIVIDEND LEFT
DJNZ DIV LOOP UNTIL B = 0
RET
For 6/2 this seems to return 6/2 = 2 remainder 2. I think this is because it ends on a shift (ADD HL, HL
) when it should end with a subtract/test.
Moving ADD HL, HL
inside the loop just before XOR A
seems to fix the program.
My question: does the original code have a bug and is my proposed fix valid? Or is there another/better way to modify the program?