# Assembly experiment: bouncing block

صفحة 2/7
1 | | 3 | 4 | 5 | 6 | 7
Pbk71 wrote:

For my optimization I want to change the sign of my variable speed (dw).
So for two's complement I've got to xor it with 0xFFFF and then add 1.

To do this for a word in memory I've now written this code:

```        ld de,(test)
ld a, d
xor 0xFF
ld d,a
ld a, e
xor 0xFF
ld e,a
inc de
ld (test),de
test:   dW 0x1000```

I've tested it and it seems to work. Is this the most fast way to do this?

Nice understanding of 2’s complement math. This can be key to some smart optimisations. Here, instead of `xor 0xFF` you can use `cpl` which is a dedicated instruction for inverting all the bits.

However I think subtracting from 0 directly is more readable:

```ld de,(test)
ld hl,0
and a
sbc hl,de
ld (test),hl
```

It also happens to be a few cycles faster. But cycle micro-optimisations generally don’t matter much unless it’s executed frequently, in an inner loop. So I wouldn’t focus on cycles too much, and just make sure to write your code in such a way that you still understand it a month from now.

E.g. you could write the `ld hl,0 / and a` part here as `xor a / ld l,a / ld h,a` to save 1 more cycle, but readability suffers and the gain is irrelevant imo. Although of course on the forum finding the fastest solution is always fun, and I reckon also educational.

Grauw wrote:

However I think subtracting from 0 directly is more readable:

```ld de,(test)
ld hl,0
and a
sbc hl,de
ld (test),hl
```

Thanks, this is indeed shorter and more readable.

```ld hl,test
xor a
sub (hl)
ld (hl),a
inc hl
ld a,0
sbc a,(hl)
ld (hl),a```

Is less readable but should be faster and save some bytes.

@Bore: Thanks

Good call Grauw, on readability. I'm a big fan of making source code clean and understandable. For us, assembler geeks, it sometimes is a job that seems out of reach. But with a bit of effort, you can make beautiful, readable, and fast code. Like you just demonstrated.

I've seen my share of Italian code, even my own. #cleancode

Ok, I've optimized my code a bit. I removed the DIR variable for direction. When the y-coordinate is above maximum it is set to maximum and the speed is made negative what makes the coin bounce up again.

You can see it here: https://msxpen.com/codes/-M_AQ5RrEyM7b7CBgKvU

There's a thing I can't figure out. In this version I don't make the speed negative but the maximumspeed. If I don't do that the bouncing will decrease and in the end it will stop bouncing. See line 113...117:

```ld de,(maxspeed); make speed negative maxspeed (as for now make negative speed does not work)
ld hl,0
and a
sbc hl,de
ld (speed),hl```

I don't see what I am doing wrong here. The coin should already have the maximum speed...
I also see that after the speed is made negative the coin still drops a little bit (the y coordinate increases). This puzzles me as I make the y coordinate equal to the maximum of y and then also make the speed negative. So why does the coin still drops a little bit...

I anyone can help me out... thanks!

Next optimization will be the VDP vram pointer auto-increments ass ARTRAG pointed out.

Ok, managed to find it by myself, with some help of a debugger

I found some mistakes and further cleaned up my code. That solved the problem that the maximum value of the y-coordinate was exceeded

In the end, there turned out to be no mistake in the bouncing algoritm. The first time the coin falls it is 'dropped' from a higher place and reached the maxspeed, but after that it does not get so high anymore and when it hits the floor it has not reached the maximum speed. So then it won't get that high anymore, causing an even lower speed the next time it hits the floor, and so on.

I've decided to keep it the way that it bounces endlessly: I just take the maxspeed and make that negative.

Nice!

Grauw wrote:

Nice!

Thanks. I made the final version in where I've implemented the other suggestions by ARTRAG about VDP vram pointer auto-increments. I only did this for the initial display of the sprites. It did not make my program smaller on updating x and y coordinates and speed is not in issue for this little demo.

I started just over 500 bytes and now it's exactly 400 bytes. I'm happy with that and I'm happy with my first real program in assembly for the MSX. I've added a lot of comments, hopefully it is helpful for other beginners.

Final version can be found here: https://msxpen.com/codes/-M_CtHD19xjHdPi_p5wI

Thanks for the help, I've learned a lot by doing this. On to the next project.

Great! Welcome to the assembler world! What are you planning on doing next?

صفحة 2/7
1 | | 3 | 4 | 5 | 6 | 7