I need a Z80 expert to tell me exactly what the following code does. It's short and simple, and just involves a little bit of math. However, I picked up Z80 exactly a few hours ago, and I can't seem to make sense of the how the flags work in relation to the mathematical operators. The comments that appear below may, of course, be very wrong. Here's the challenge: Code (Text): 2a12 67 ld h,a ; h = a 2a13 5f ld e,a ; e = a 2a14 2e00 ld l,#00 ; l = 00 2a16 55 ld d,l ;d = 00 2a17 0e08 ld c,#08 ; c = 08 ; loop start 2a19 29 add hl,hl ; hl += hl 2a1a d21e2a jp nc,#2a1e ; jump on overflow???? 2a1d 19 add hl,de ; hl += de 2a1e 0d dec c ; c-- 2a1f c2192a jp nz,#2a19 ; jump to loop start if c is not 1 2a22 c9 ret This code is taking the distance between two characters on screen and turning them into a destination coordinate. The return value of this function is whatever is in HL -- and will be interpreted as XXYY coordinates. Weird huh? I can't imagine why they are perfoming an add hl, hl eight times in a row! So, who here is smart enough with the Z80 to tell me what the mathematical significance of this peice of code is?
It's a neat subroutine to compute a square of a given integer. Basically, HL = A^2. Also, the 'jp nc' is Jump when No Carry. I assume you know what carry is. When you add two bytes: 128+128, the result is 0, and the carry is 1. If you need a detailed description of how this works, let me know.
The entire routine just squares an integer? It seems like it multiplies it by 8, to me. What is the significance of having the loop run 8 times? My understanding was this: If the value of A, coming into the function is, say, 5. It'll set: HL = 0500 DE = 0005 BC = 0008 Then proceed to add HL to itself 8 times, since there is no carry -- leaving HL = 2D00. If the highbyte of HL overflows the value, then it'll add DE to HL.
ok, I'll break it down for you: add hl,hl is the same as hl = hl + hl which is the same as hl = hl * 2 which is the same as shifting the value of HL by one bit to the left (binary arithmetic). So after doing this you shift the higher byte of HL out of HL :P That's right, it's gone. So why was it there? To serve as a helpful byte for telling when to add DE (A) and when not. what the loop does is: Code (Text): for (counter = 8; counter > 0; c--) { HL = HL << 1 if (CARRY) HL += A; } I think it's similar to the Horner thing in polynomials. Ie. you can represent an integer in binary: 1110 0011 as 1*2^7 + 1*2^6 + 1*2^5 + 1*2^1 + 1*2^0. But you can also represent that as (((1*2+1)*2+1)*2*2*2*2+1)*2+1. So what you're doing in each step of the loop is multiply the whole integer by 2 and add 1/0 depending on the binary represantation. The same scheme was used here, except for squaring the number. I'm sorry if my explanation sucks, I'm tired :P
Aha! Could you tell me what this does, then? It's full of binary math, and I assume it is receiving HL as XXYY coordinates into the playfield grid, and then returning HL as the memory address of the grid location. (#4040 + whatever has been calculated) Code (Text): 202d f5 push af 202e c5 push bc 202f 7d ld a,l 2030 d620 sub #20 2032 6f ld l,a 2033 7c ld a,h 2034 d620 sub #20 2036 67 ld h,a 2037 0600 ld b,#00 2039 cb24 sla h 203b cb24 sla h 203d cb24 sla h 203f cb24 sla h 2041 cb10 rl b 2043 cb24 sla h 2045 cb10 rl b 2047 4c ld c,h 2048 2600 ld h,#00 204a 09 add hl,bc 204b 014040 ld bc,#4040 -- map location 204e 09 add hl,bc 204f c1 pop bc 2050 f1 pop af 2051 c9 ret