Z80 things that weren't obvious that you wish you'd known earlier

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
Morkin
Bugaboo
Posts: 3270
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: Z80 things that weren't obvious that you wish you'd known earlier

Post by Morkin »

Ast A. Moore wrote: Thu May 06, 2021 12:07 am
Morkin wrote: Wed May 05, 2021 11:30 pm I still can't get my head around:

Code: Select all

LD H,(HL)
Just hurts my brain for some reason.
Why? It’s no different than, say, IN A,(*) (where the full port address is formed by the contents of A placed in the top eight bits).
I'm not sure - it feels like you're trying to scoop water out of a bucket, using the same bucket that's holding the water... :lol:
My Speccy site: thirdharmoniser.com
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: Z80 things that weren't obvious that you wish you'd known earlier

Post by Ast A. Moore »

Morkin wrote: Thu May 06, 2021 9:17 am
Ast A. Moore wrote: Thu May 06, 2021 12:07 am Why? It’s no different than, say, IN A,(*) (where the full port address is formed by the contents of A placed in the top eight bits).
I'm not sure - it feels like you're trying to scoop water out of a bucket, using the same bucket that's holding the water... :lol:
I see what you mean, but in fact the instruction takes several machine cycles to execute, so by the time H is loaded with the value of the address pointed to by HL, the HL has already been used up, as it were. There are two internal registers in the Z80—W and Z—that are used to temporarily hold some values. They are invisible to the programmer, but they’re there.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: Z80 things that weren't obvious that you wish you'd known earlier

Post by Ast A. Moore »

AndyC wrote: Thu May 06, 2021 8:49 am Not strictly Z80, but it took me a very long time to realise the benefits of fixed point arithmetic in writing a 2D game. I was always thinking in terms of pixels and could never really get the kind of smoothness I wanted.

Having read how Super Mario does it, the answer is obvious. Use 16-bit math but only pay attention to the top 8-bits as an on screen position (effectively the lower 8-bits being the decimal portion). Now you can manage much smoother speeds etc without sacrificing performance.
Yes, that’s the approach I use in Yankee. Sometimes, though, there’s an issue with rounding, but overall it works great. I use it to calculate the position of almost all the sprites.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
presh
Manic Miner
Posts: 237
Joined: Tue Feb 25, 2020 8:52 pm
Location: York, UK

Re: Z80 things that weren't obvious that you wish you'd known earlier

Post by presh »

AndyC wrote: Thu May 06, 2021 8:49 am fixed point arithmetic in writing a 2D game ... Use 16-bit math but only pay attention to the top 8-bits as an on screen position (effectively the lower 8-bits being the decimal portion). Now you can manage much smoother speeds etc without sacrificing performance.
That's how I'm doing things in my overhead driving engine. The decimal part is only considered for movement, literally everything else uses the integer part only (as if all values had been floor()ed first)

For anyone interested, [mention]ZedaZ80[/mention]'s got a wonderful collection of fast routines for 8.8 Fixed Point maths, you can find them here - they are the filenames with a _88 suffix :)
User avatar
flatduckrecords
Manic Miner
Posts: 785
Joined: Thu May 07, 2020 11:47 am
Location: Oban, Scotland
Contact:

Re: Z80 things that weren't obvious that you wish you'd known earlier

Post by flatduckrecords »

This thread is a goldmine, thank you all for sharing.
AndyC wrote: Thu May 06, 2021 8:49 am Having read how Super Mario does it, the answer is obvious. Use 16-bit math but only pay attention to the top 8-bits as an on screen position (effectively the lower 8-bits being the decimal portion). Now you can manage much smoother speeds etc without sacrificing performance.
And so, indeed, does Sonic! By coincidence Jon Burton posted a new Coding Secrets video today which demonstrates the same technique in 68000 assembly (assuming I’ve understood and recognised it correctly!)

I’ve been working on some Spectrum pixel-plotting and rudimentary sprite-drawing routines recently so I’ll certainly give this approach a try. Thanks!
Dr beep
Manic Miner
Posts: 381
Joined: Mon Oct 01, 2018 8:53 pm

Re: Z80 things that weren't obvious that you wish you'd known earlier

Post by Dr beep »

Bubu wrote: Tue May 04, 2021 7:29 pm Z80 things that weren't obvious that you wish you'd known earlier:

When I started programming with Z80, I thought that using IM2 would be a symbol of professional developing... but I never found a real use or utility to implement interrupts: it makes code run so slow, avoids to have sounds meanwhile playing... Never understood the reason for using IM2. My Anteater game doesn't use it at all ( well, only for detecting the coin at the beginning :D )
So far I have used an IM 2 for two reasons

1) in my emulators (ZX81 and videopac) the intrupt is used to read the keyboard and update the screen
2) in a game I set a 20 seconds timer. During the time the computer does calculations but after this time the best result counts. The IM-2 stops the calculation.

A third option is to play music
Ralf
Rick Dangerous
Posts: 2286
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: Z80 things that weren't obvious that you wish you'd known earlier

Post by Ralf »

Never understood the reason for using IM2
You may use IM2 just not to use other modes. And actually have an empty interrupt routine ;)

This way you get free from Basic interrupts which, as was said here before, change registers, use system variables (so you can't overwrite them) and do a lot of other stuff that you may don't want in your program.

Some may say - then disable interrupts. But sometimes it's not possible. You may need interrupts to use HALT instruction and synchronise
your sprite drawing with the screen refresh and at the same time don't need to do anything useful in interrupt code.
Post Reply