Sonic and Sega Retro Message Board: Show your Z80 prowess! - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
Page 1 of 1
    Locked
    Locked Forum

Show your Z80 prowess!

#1 User is offline Dr. Ivo 

  Posted 03 April 2007 - 10:14 PM

  • Professional Reverse Engineer
  • Posts: 42
  • Joined: 04-February 04
  • Gender:Male
  • Location:Philadelphia, PA
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:

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?
This post has been edited by Dr. Ivo: 03 April 2007 - 10:15 PM

#2 User is offline drx 

Posted 04 April 2007 - 08:05 AM

  • <Shade> fuck MJ
  • Posts: 2175
  • Joined: 02-March 04
  • Gender:Male
  • Project::rolleyes:
  • Wiki edits:8
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.

#3 User is offline Dr. Ivo 

  Posted 04 April 2007 - 09:59 AM

  • Professional Reverse Engineer
  • Posts: 42
  • Joined: 04-February 04
  • Gender:Male
  • Location:Philadelphia, PA
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.
This post has been edited by Dr. Ivo: 04 April 2007 - 10:34 AM

#4 User is offline drx 

Posted 04 April 2007 - 11:20 AM

  • <Shade> fuck MJ
  • Posts: 2175
  • Joined: 02-March 04
  • Gender:Male
  • Project::rolleyes:
  • Wiki edits:8
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:

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

#5 User is offline Dr. Ivo 

Posted 04 April 2007 - 03:09 PM

  • Professional Reverse Engineer
  • Posts: 42
  • Joined: 04-February 04
  • Gender:Male
  • Location:Philadelphia, PA
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)


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

This post has been edited by Dr. Ivo: 04 April 2007 - 03:15 PM

Page 1 of 1
    Locked
    Locked Forum

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users