LDDR wrong in Z80 manual?

By DarkSchneider

Paladin (965)

Аватар пользователя DarkSchneider

17-05-2016, 11:20

It is supposed to do: copy, dec HL/DE, dec BC and check if 0. But what I have is not that, it seems to dec bc and check at first. I made the reverse memcpy because I need it, in this way:

; VOID rvmcpy(char *src, char *dst, size_t count)
rvmcpy@:
	; data already in registers
	inc bc ; it seems LDDR dec BC before and not after?
	LDDR
	ret

Well, if I don't "inc bc", it copies count-1, not count. Tested with ints.

You can try by yourself and talk about your results, becuase this confuses me.

This is the testing code I used:

VOID main (argc, argv)
int argc;
char *argv[];
{
	int i, a[100], b[100];

	for(i=0; i<100; i++) a[i] = i;
	/*memcpy(b, a, sizeof(int)*100);*/
	printf("%a: %d %d %d\nb: %d %d %d\n", a[0], a[50], a[99], b[0], b[50], b[99]);
	rvmcpy((&a[99])+1, (&b[99])+1, sizeof(int)*100);
	printf("%a: %d %d %d\nb: %d %d %d\n", a[0], a[50], a[99], b[0], b[50], b[99]);
}

Also, is modifying the source as well? oO I am getting different values for a before and after the call.
Remember that values are [0], [50] and [99].
Before:
a - 0 50 99
b - 21 8314 836 (these are random)
After:
a- 0 50 490 oO
b- 0 50 867

For strings works fine, removing the "inc bc". Why with integers not?

Updated: OK is solved, it was some kind of weird casting made by C. With this line works, of course, without the "inc bc":
rvmcpy(&a[99]+1, &b[99]+1, sizeof(int)*100);
Compared with the previous one, it has no () for the & (address).
rvmcpy((&a[99])+1, (&b[99])+1, sizeof(int)*100);
Because is an ASM code, compiler does not warns about types.

Для того, чтобы оставить комментарий, необходимо регистрация или !login

By bore

Master (161)

Аватар пользователя bore

17-05-2016, 12:01

(&a[99])+1 and (&b[99])+1 might not do what you expect it to do.
&a[99] is of the type int *, it is expected of the compiler to add sizeof(int) in that case.
Try changing it to ((char *)&a[99])+1 and ((char *)&b[99])+1

By killimolli

Supporter (14)

Аватар пользователя killimolli

17-05-2016, 12:39

Zeesus christ Bore Big smile

By DarkSchneider

Paladin (965)

Аватар пользователя DarkSchneider

17-05-2016, 13:03

Thanks @bore, as you say is that, as I said in the update at the end of the message. The problem were C castings, now solved. And be careful because C compiler will not warn about this because it is an ASM function without C declaration.

We need to be very careful with the C ninja castings Wink

By killimolli

Supporter (14)

Аватар пользователя killimolli

17-05-2016, 14:21

((char *)&a[99])+1 and ((char *)&b[99])+1
...