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!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)
Z80 things that weren't obvious that you wish you'd known earlier
Re: Z80 things that weren't obvious that you wish you'd known earlier
- 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
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.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 )
Re: Z80 things that weren't obvious that you wish you'd known earlier
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.
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.
Re: Z80 things that weren't obvious that you wish you'd known earlier
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.
- 1024MAK
- Bugaboo
- Posts: 3123
- 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
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
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
Looking forward to summer later in the year.
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
Re: Z80 things that weren't obvious that you wish you'd known earlier
I still can't get my head around:
Just hurts my brain for some reason.
Code: Select all
LD H,(HL)
My Speccy site: thirdharmoniser.com
- 1024MAK
- Bugaboo
- Posts: 3123
- 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
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
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
Looking forward to summer later in the year.
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
- 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
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).Morkin wrote: ↑Wed May 05, 2021 11:30 pm I still can't get my head around:
Just hurts my brain for some reason.Code: Select all
LD H,(HL)
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.
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.
Re: Z80 things that weren't obvious that you wish you'd known earlier
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.
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.
Re: Z80 things that weren't obvious that you wish you'd known earlier
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...Ast A. Moore wrote: ↑Thu May 06, 2021 12:07 amWhy? 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).Morkin wrote: ↑Wed May 05, 2021 11:30 pm I still can't get my head around:
Just hurts my brain for some reason.Code: Select all
LD H,(HL)
My Speccy site: thirdharmoniser.com
- 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
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.Morkin wrote: ↑Thu May 06, 2021 9:17 amI'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...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).
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.
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.
- 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
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.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.
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.
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.
Re: Z80 things that weren't obvious that you wish you'd known earlier
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)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.
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
- flatduckrecords
- Manic Miner
- Posts: 787
- 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
This thread is a goldmine, thank you all for sharing.
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!
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!)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.
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!
Re: Z80 things that weren't obvious that you wish you'd known earlier
So far I have used an IM 2 for two reasonsBubu 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 )
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
Re: Z80 things that weren't obvious that you wish you'd known earlier
You may use IM2 just not to use other modes. And actually have an empty interrupt routineNever understood the reason for using IM2
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.