I am attempting to run the following code:
HLDIVC:
LD B,16
D0: XOR A
ADD HL,HL
RLA
CP C
JR C, D1
INC L
SUB C
DJNZ D0
D1: RET
EDIT: The original code from (http://z80-heaven.wikidot.com/math#toc18) is:
HL_Div_C:
;Inputs:
; HL is the numerator
; C is the denominator
;Outputs:
; A is the remainder
; B is 0
; C is not changed
; DE is not changed
; HL is the quotient
;
ld b,16
xor a
add hl,hl
rla
cp c
jr c,$ 4
inc l
sub c
djnz $-7
ret
On an old pocket computer I have. I had to edit the code a little bit, namely because it would seem the assembler on this pocket computer simply does not support the "jr c,$ 4" syntax and rather must use labels or absolute addresses. It would seem this may be causing issues, however, because the algorithm does not seem to be working properly. I am running it using the following code:
ORG O100H
LD HL,20
LD C,10
CALL REGOUT; Display all register values
CALL HLDIVC
CALL REGOUT
RET
With this I am trying to divide 20 by 10, so after calling the function the correct value in HL should be 2, and the value in A (The remainder) should be 0, from my understanding. This is not the case, however. Before running the HLDIVC program, these are the register values:
| PC = 0107 | AF = 00 44 |
| SP = 7FE8 | BC = 00 0A |
| IX = 7C06 | DE = 00 14 |
| IY = 7C0C | HL = 00 14 |
(All values are hexadecimal)
After running the program, these are the register values:
| PC = 010D | AF = 00 9B | <- A is correct
| SP = 7FE8 | BC = 10 0A | <- B is supposed to be 0
| IX = 7C06 | DE = 00 14 | <- DE is correct
| IY = 7C0C | HL = 00 14 | <- HL should be 2(?)
What's going on? Any help would be much appreciated, thank you for your time.
CodePudding user response:
The problem with your code is that $ 4 and $-7 are both referring to byte counts, not instruction counts, and the JR instruction is 2 bytes. The indentation gives you a clue. You need to move your labels:
HLDIVC:
LD B,16
XOR A
D0: ADD HL,HL
RLA
CP C
JR C, D1
INC L
SUB C
D1: DJNZ D0
RET