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
Bubu
Manic Miner
Posts: 542
Joined: Fri Apr 02, 2021 8:24 pm
Location: Spain

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

Post by Bubu »

Or even:

Code: Select all

ex de, hl
ex de, ix
If something works, don't touch it !!!! at all !!!
User avatar
Manu128k
Dizzy
Posts: 83
Joined: Tue Aug 13, 2019 9:45 pm
Location: Spain
Contact:

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

Post by Manu128k »

This thread is pure gold for any Z80 ASM apprentice (like me)
Last edited by Manu128k on Tue May 04, 2021 7:58 pm, edited 1 time in total.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
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 »

Bubu wrote: Tue May 04, 2021 7:51 pm Or even:

Code: Select all

ex de, hl
ex de, ix
Nope. EX DE,IX is not a valid Z80 instruction.
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
Bubu
Manic Miner
Posts: 542
Joined: Fri Apr 02, 2021 8:24 pm
Location: Spain

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

Post by Bubu »

Ast A. Moore wrote: Tue May 04, 2021 7:58 pm Nope. EX DE,IX is not a valid Z80 instruction.

Ooops, I wanted to check if you were aware :lol: :lol: :lol:
If something works, don't touch it !!!! at all !!!
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 »

Ast A. Moore wrote: Tue May 04, 2021 7:48 pm Or simply:

Code: Select all

push ix		;2 bytes
pop hl 		;(or any other register) 1 byte
Ah yes! Forgot the push/pop trick!

Though it's 1 T-state slower than my code, it's also 3 bytes smaller (half the size!) and doesn't require a sacrificial register!

And given all that, my point still stands: HL is usually nice, giving us both speed and size improvements, not making us choose! :x ;)

Code: Select all

PUSH IX   ; 15/2
POP HL    ; 10/1
; 25 Ts, 3 bytes


LD A, IXH   ; 8/2
LD H, A     ; 4/1
LD A, IXL   ; 8/2
LD L, A     ; 4/1
; 24 Ts, 6 bytes
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 »

Turtle_Quality wrote: Tue May 04, 2021 7:24 pm I think all those can be done with IX / IY also, slower but with the displacement byte when it's indirect ; such as OR (IX+d)
True. IX & IY get a lot of stick for being slow, but I very recently converted a chunk of code to use them. It was much quicker to use IX, rather than shunting data structures back & forth to where they needed to be for the original code to access them. Also prone to bugs having 2 copies of a data structure knocking about in different places, very easy to overwrite the wrong value and wonder why it hasn't updated!
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 »

Joefish wrote: Tue Apr 20, 2021 9:04 am the SBC A trick for sign-extending.
The what now...??! :shock:
User avatar
rastersoft
Microbot
Posts: 151
Joined: Mon Feb 22, 2021 3:55 pm

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

Post by rastersoft »

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 )
Well, it depends. In "Escape from M.O.N.J.A.S." I really needed IM2: I work on a temporary framebuffer, and I have to wait for an interrupt before copying it into the screen buffer. But doing a HALT would mean to waste a lot of CPU power, so what I do is paint in the buffer, when I ended I set a flag to indicate to the interrupt routine that it can dump the temporary framebuffer, and then I start to pre-calculate things for the next frame (like the next position of all the characters, which objects are near the main character, and so on), and when I did everything that I could before having to paint the new frame, THEN I wait for the interrupt to end copying the screen. This allowed me to gain between one and two FPS.
Tommo
Dizzy
Posts: 92
Joined: Sat Mar 20, 2021 3:23 pm

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

Post by Tommo »

On my Sam Coupé 3d stuff, I use the end-of-frame interrupt to maintain a frame counter and as the signal to switch frame buffers.

The latter is fairly obvious; the former allows for frame-rate independent movement. So even if the drawing rate slows down, objects continue to move at the same rate.
User avatar
Joefish
Rick Dangerous
Posts: 2042
Joined: Tue Nov 14, 2017 10:26 am

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

Post by Joefish »

Joefish wrote: Tue Apr 20, 2021 9:04 amthe SBC A trick for sign-extending.
presh wrote: Tue May 04, 2021 9:15 pmThe what now...??! :shock:
To sign-extend an 8-bit number in A to a 16-bit number in BC:

LD C,A
RLCA
SBC A,A
LD B,A

First LD C,A copies the 8-bit number into C
Then RLCA shifts the top (sign) bit off the original copy of that number and into the CARRY flag.
Then if you did SUB A,A you'd get 0, but because you do SBC A,A you get 0 and then subtract the CARRY flag bit, so you get either 0 or -1.
Then LD B,A puts either 0 or -1 (all bits set) into B.
User avatar
1024MAK
Bugaboo
Posts: 3104
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

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

Post by 1024MAK »

Of course, the original intended purpose of interrupts was to provide a fast response to hardware wanting attention without the software having to sit in a polling loop...

By using interrupts, the software can get on with doing other stuff.

For example, RS232 serial communications, fast parallel port(s) (either input or output), disk drives, etc.

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
User avatar
Morkin
Bugaboo
Posts: 3251
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 »

I still can't get my head around:

Code: Select all

LD H,(HL)
Just hurts my brain for some reason.
My Speccy site: thirdharmoniser.com
User avatar
1024MAK
Bugaboo
Posts: 3104
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

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

Post by 1024MAK »

LD H,(HL)

Load H with the contents of the memory location pointed to by HL.

It’s no different to LET h=PEEK h

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
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: 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).
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.
AndyC
Dynamite Dan
Posts: 1388
Joined: Mon Nov 13, 2017 5:12 am

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

Post by AndyC »

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.
User avatar
Morkin
Bugaboo
Posts: 3251
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: 2640
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: 2640
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: 777
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: 375
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: 2279
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