The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
Joefish
Rick Dangerous
Posts: 2042
Joined: Tue Nov 14, 2017 10:26 am

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Joefish »

Ast A. Moore wrote: Tue Apr 17, 2018 5:55 pm If you’re referring to the +2A/+3 code, then the port itself doesn’t seem to be contended. The LD A,(NNNN) instruction is what affects the timing, as reading from a non-contended address will break the sync.
I was asking about both, so what about the 48K code? Is Ersh right? Doesn't the contention of IN always give you the attribute byte? i.e. it's impossible to catch the pixel byte?
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Ast A. Moore »

Ersh wrote: Tue Apr 17, 2018 5:46 pm If the CPU is suspended for 4 T-states while the ULA fetches bitmap, attr, bitmap, attr. When the CPU is released shouldn't every read of the port be that last 'attr'? Clearly that's not the case, just wondering how that works.
No, that’s precisely what happens. On a +2A, the last read value is latched onto the bus. That’s why we need to keep the LD A,(NNNN) in the loop; otherwise we’ll get a bunch of false positives.

One thing to keep in mind, though. Contention only applies to the code running in contended memory (that’s why it’s called that). Code running elsewhere is unaffected and the CPU is running at full speed all the time.
Ersh wrote: Tue Apr 17, 2018 5:46 pmAlso how is the well-timed loop 'synchronized' to always get the attr? It takes a certain amount of T-states but doesn't it need to start at the right time as well?
That’s a bit of a mystery to me. However, if you move the border-changing code down in the top border are (by increasing the delay), you’ll see that the position of the first blue pixels jitters a bit. So syncing is not cell-perfect. However, with the padding instructions I suggest, you can be rest assured that it’ll only fetch the attribute byte. Fill the bitmap area of the screen with the same byte as the attribute byte you’re expecting, and you’ll see that the sync will only occur in the attribute area.
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: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Ast A. Moore »

Joefish wrote: Tue Apr 17, 2018 6:10 pm
Ast A. Moore wrote: Tue Apr 17, 2018 5:55 pm If you’re referring to the +2A/+3 code, then the port itself doesn’t seem to be contended. The LD A,(NNNN) instruction is what affects the timing, as reading from a non-contended address will break the sync.
I was asking about both, so what about the 48K code? Is Ersh right? Doesn't the contention of IN always give you the attribute byte? i.e. it's impossible to catch the pixel byte?
I partially answered that already while you were typing your question. Contention is only pertinent to the code running in contended memory, or if you’re addressing contended memory or contended port. It is my understanding that the ports available for this trick on the +2A are non-contended, but contention applies partially to the LD A,(NNNN) instruction.

On a 48K/128K/+2, however, the situation is different. You have more ports to choose from—some contended some not. If you play around with the port address in my sample code, you’ll see the effect immediately.

But yes, it is technically possible to catch the pixel byte. That’s why I used a bitmap pattern of the same byte as the attribute in my initial tests—as a booby trap for myself.

Insert something like the following right before the fl_bus label in my example code and observe the effect:

Code: Select all

	ld bc,6144	
	ld hl,$4000
2$	ld a,9			;pattern fill
	ld (hl),a
	cpi
	jp pe,2$
See? The sync stays still happens only on the attribute line, even though the entire bitmap area of the screen file is filled with the value 9. No false triggering.
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
Ersh
Manic Miner
Posts: 480
Joined: Mon Nov 13, 2017 1:06 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Ersh »

Ast A. Moore wrote: Tue Apr 17, 2018 6:28 pm One thing to keep in mind, though. Contention only applies to the code running in contended memory (that’s why it’s called that). Code running elsewhere is unaffected and the CPU is running at full speed all the time.
Totally forgot about that! :lol:

Thanks for putting all this together. It'll be fun to explore this in the future.
User avatar
Joefish
Rick Dangerous
Posts: 2042
Joined: Tue Nov 14, 2017 10:26 am

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Joefish »

Ersh wrote: Tue Apr 17, 2018 6:42 pm
Ast A. Moore wrote: Tue Apr 17, 2018 6:28 pm One thing to keep in mind, though. Contention only applies to the code running in contended memory (that’s why it’s called that). Code running elsewhere is unaffected and the CPU is running at full speed all the time.
Totally forgot about that! :lol:

Thanks for putting all this together. It'll be fun to explore this in the future.
I was just thinking that he should be a politician - 3 replies and still no answer to the original question!!!! :lol:

So in the first (48K) example, the IN address is 0x40FF. Since this is equivalent to a memory address in the video RAM (16639) the ULA treats it as contended, so it's this contention of the IN instruction that keeps the loop synchronised when not in the border, so that it's always looking at either (a) the floating bus byte or (b) the attribute byte.

(If you did want to read the pixel byte, you'd need another contended memory or port operation to synchronise things, then use an uncontended IN port address to catch the pixel byte at the right moment).
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Ast A. Moore »

Joefish wrote: Tue Apr 17, 2018 6:48 pm I was just thinking that he should be a politician - 3 replies and still no answer to the original question!!!! :lol:
Please address your complains to my secretary. You will receive an official reply in 7–12 days.
Joefish wrote: Tue Apr 17, 2018 6:48 pm So in the first (48K) example, the IN address is 0x40FF.
That’s assuming that port contention pattern is identical to memory contention. I’m not a hundred percent sure of that, though.
Joefish wrote: Tue Apr 17, 2018 6:48 pmSince this is equivalent to a memory address in the video RAM (16639) the ULA treats it as contended, so it's this contention of the IN instruction that keeps the loop synchronised when not in the border, so that it's always looking at either (a) the floating bus byte or (b) the attribute byte.

(If you did want to read the pixel byte, you'd need another contended memory or port operation to synchronise things, then use an uncontended IN port address to catch the pixel byte at the right moment).
Quite possible, quite possible. It seems we do need contention in both cases—either port contention (for the IN instruction), or memory contention (for the LD A,(NNNN) instruction). It’s been over a year since my original experiments. I remember trying a gazillion different combinations of loop instructions before nailing it.
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
djnzx48
Manic Miner
Posts: 729
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by djnzx48 »

Nice, it all makes a lot more sense now. So the whole reason for the timing loop is to ensure that only the attribute byte is read and not the bitmap byte? And I suppose that you can still check for attribute bytes with even INK values, as long as you don't have any other attributes where the corresponding odd value is used?

It's a shame that the only two emulators capable of using this technique are closed source, and both seem to have dead download links at the moment. I know that if you're using an emulator, you can easily just switch to 128K mode, but it means you can't really make games using the +2A/+3 floating bus unless you've got real hardware to test it on. So it's of limited use at the moment.
Nomad
Manic Miner
Posts: 600
Joined: Thu Dec 28, 2017 12:38 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Nomad »

One thing that should make everyone uncomfortable..

This is just one un-implemented behavior of a core system. How many more behaviors are left unimplemented by emulators on core/primary systems they are presenting as accurate.

Now consider that many of these same emulators have had continuous development for more than a decade and still do not implement behaviors that are known on core/primary systems?
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Ast A. Moore »

An update: I added an example of filling the bitmap area of the display file with the same value as the attribute byte we’re using as a sync trigger to clearly demonstrate that it does not break the sync.

djnzx48 wrote: Wed Apr 18, 2018 6:58 am Nice, it all makes a lot more sense now. So the whole reason for the timing loop is to ensure that only the attribute byte is read and not the bitmap byte? And I suppose that you can still check for attribute bytes with even INK values, as long as you don't have any other attributes where the corresponding odd value is used?
Yes and yes. Just keep in mind that the returned value will always have Bit 0 set, so black ink will be misread as blue, red as magenta, green as cyan, and yellow as white.
djnzx48 wrote: Wed Apr 18, 2018 6:58 amIt's a shame that the only two emulators capable of using this technique are closed source, and both seem to have dead download links at the moment.
I don’t believe the links are dead: SpecEmu, Spectramine.
djnzx48 wrote: Wed Apr 18, 2018 6:58 amI know that if you're using an emulator, you can easily just switch to 128K mode, but it means you can't really make games using the +2A/+3 floating bus unless you've got real hardware to test it on. So it's of limited use at the moment.
On the contrary. It’s because you can easily switch Spectrum models in an emulator that you can use the floating bus on all models in your code.

My philosophy is very simple and straighforward: I consider myself to be a Spectrum developer. Not a particular-flavor-of-a-software-or-hardware-emulator-or-clone-of-the-Spectrum developer. At the same time, I hold absolutely no grudge against the latter. I’ve brought this issue up a few times already: emulator authors—both software and hardware—each has his own agenda and it may not always be the accuracy of emulation of the original hardware. At the very least, it might not be at the top of the list. Again, there’s nothing wrong with that.

But we as developers can (to an extent) influence their decisions. If enough people request a feature, chances are it’ll be implemented sooner rather than later. By avoiding the use of a feature of the original hardware “because [insert name of emulator] doesn’t support it,” we’ll only create a vicious circle and reinforce the notion that “meh, nobody really uses it anyway.” Conversely, if a particular feature receives widespread use among developers, users themselves will ask for it to be implemented. Even if they don’t know what’s wrong, they’ll say, “Hey, this works on my +2A, but it doesn’t in my emulator! What gives?”

So far, A Yankee in Iraq is the only game that exploits the floating bus trick on the +2A/+3. Yes, it won’t work on most emulators, but, as you pointed out, it takes a second to switch to a different Spectrum model, so most people will simply do that. After all, there are plenty of commercial games from way back when that only work on a particular Spectrum model. But one game alone is never going to convince emulator authors to implement this feature. Mark and weiv did it because they found it challenging, worth their effort, amusing, fun—you name it. I don’t know what motivated them exactly. (It certainly wasn’t the game itself :lol: )

So, petition your local MP. ;) Or contribute to the development of an emulator. Here’s the original ticket for Fuse. It has links to all the pertinent information necessary to test the implementation the floating bus behavior on the +2A/+3, including my original tests that Mark Woodmass and weiv used (my handle on SourceForge is “Nichals Naime”). But more importantly, write your own games that use it.
Nomad wrote: Wed Apr 18, 2018 7:30 am This is just one un-implemented behavior of a core system. How many more behaviors are left unimplemented by emulators on core/primary systems they are presenting as accurate.

Now consider that many of these same emulators have had continuous development for more than a decade and still do not implement behaviors that are known on core/primary systems?
This ties in neatly to what I wrote above: I don’t for a second think there’s malice behind any of this. Both emulator development and reverse engineering the Spectrum can be quite daunting. Both are carried out by enthusiasts and usually provided free of charge. At some point, however, their priorities change from “let’s make the most accurate Spectrum emulator” to “hey, that’s good enough for me, let’s add tons of new features.”

As for something esoteric such as the floating bus on the +2A, unless there’s an incentive, it’s never going to be implemented by an emulator author whose priorities have long changed.

There’s also a more trivial reason—people simple lose interest.
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
Joefish
Rick Dangerous
Posts: 2042
Joined: Tue Nov 14, 2017 10:26 am

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Joefish »

There is an alternative, which is to write your code with the right timing built-in to its execution time, and synch it to the interrupt. But you do have to identify the machine you're running on to get the timing right.

There are various approaches to make sure your code always takes the same time to execute. Generally you have to work out your 'worst case' that takes the longest time, then make sure that shorter branches of code are padded out to take the same time as the longer branches. It may seem wasteful, but then if your code can't handle its 'worst case' every time then it's not going to work properly anyway.

So you avoid IF-THEN-CALL-RETURN type structures, and do IF-THEN-JUMP and JUMP back, and if the jump isn't taken, pad for time.
And a sprite routine should draw the maximum number of sprites every time, even if it means dumping some to off-screen (but still contended) memory. The timing doesn't have to be perfect (unless you're trying to do multicolour effects), just close enough with a bit of a safety margin.

Though if you want to start shifting graphics during the bottom border time, you have to time your code right from the top of the TV frame to the bottom of the pixel area, then be sure you can take a break and wait for the interrupt, then continue.

If you're doing a complex A.I. routine, or a sort, you might be relying on it completing well short of the worst case 99% of the time, and just let the odd frame drop or flicker if it does run a particularly bad case. In which case yes, you'd still need a synchronisation trick like this floating bus.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Ast A. Moore »

Joefish wrote: Wed Apr 18, 2018 11:06 am There is an alternative . . .
Methinks, kind sir, thou meant to make thy post here. :)
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
Joefish
Rick Dangerous
Posts: 2042
Joined: Tue Nov 14, 2017 10:26 am

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Joefish »

Nope, I deliberately set out to undermine all your hard work in this thread. :D
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Ast A. Moore »

Joefish wrote: Wed Apr 18, 2018 1:52 pm Nope, I deliberately set out to undermine all your hard work in this thread. :D
Oh, ol’ right, then. :P
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: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by AndyC »

Nomad wrote: Wed Apr 18, 2018 7:30 am One thing that should make everyone uncomfortable..

This is just one un-implemented behavior of a core system. How many more behaviors are left unimplemented by emulators on core/primary systems they are presenting as accurate.

Now consider that many of these same emulators have had continuous development for more than a decade and still do not implement behaviors that are known on core/primary systems?
On the other hand, it's a very tiny detail of emulation for a platform which has a staggeringly accurate level of emulation in multiple emulators. For comparison, I've written a ton of code for the Amstrad GX4000 that has revealed numerous fairly major deviations from what the handful of emulators do. They're slowly getting better but are a long way from being anywhere near as accurate as even the lesser end of the Speccy equivalents.
Nomad
Manic Miner
Posts: 600
Joined: Thu Dec 28, 2017 12:38 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Nomad »

True it depends what you compare it against, I would compare it against something like altirra. One guy in college wrote probably one of the best Atari emulators and what many consider to be one of the best 8-bit emulators while he was in college :lol: The documentation is some of the best I have seen for a emulator but the nicest thing was you could use the program like it was a real system. Even with obscure hardware it emulates it just fine. I couldn't believe it.

But fair enough compared to other systems Spectrum emulators are not so bad - in a much better state than say BBC micro emulators.
User avatar
druellan
Dynamite Dan
Posts: 1466
Joined: Tue Apr 03, 2018 7:19 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by druellan »

On Spectrum we always got good emulators IMO. I think part of the problem was the transition from DOS to Windows. A lot of good emulators where left behind during that period. Take for example Ramsoft's RealSpectrum for DOS. I used that emulator to preserve REAL 5 1/4 40 SD Disciple discs, using the PC floppy drive.
User avatar
Blerkotron
Dizzy
Posts: 90
Joined: Mon Nov 13, 2017 12:36 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Blerkotron »

This is fascinating, and very clearly explained - thanks for taking the time, [mention]Ast A. Moore[/mention]!
User avatar
Morkin
Bugaboo
Posts: 3251
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Morkin »

Nice article on something that's had me a bit perplexed when people have been talking about it.

I think it's a good point you make about the programmers back in the day - it probably wouldn't have been worth their while taking time to implement this with the different model changes, given the tight deadlines everyone seemed to be working under and general craziness (if a lot of the stories are true!).
My Speccy site: thirdharmoniser.com
Magnus
Dizzy
Posts: 61
Joined: Sat Jan 06, 2018 6:47 am
Location: Sweden

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Magnus »

Thank you for an excellent guide (and the effort to investigate this issue)!

My emulator now handles the +2A/+3 floating bus correctly I think. Here it is running "Woody’s Special" test (epileptics look away ;)):

Image.
My ZX Spectrum emulator project: https://softspectrum48.weebly.com.
User avatar
Woodster
Drutt
Posts: 47
Joined: Mon Nov 13, 2017 12:17 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Woodster »

That looks familiar!
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Ast A. Moore »

Magnus wrote: Fri Mar 08, 2019 9:07 pm My emulator now handles the +2A/+3 floating bus correctly I think. Here it is running "Woody’s Special” test.
Det här ser perfekt ut (unlike my Swedish). Grattis, Magnus!
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
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by R-Tape »

Also the 2019 Turner Prize winner: "Floating Booc", visuals played to the sound of interstellar noise.
presh
Manic Miner
Posts: 237
Joined: Tue Feb 25, 2020 8:52 pm
Location: York, UK

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by presh »

Thank you Ast A. Moore for such great well-written info and for introducing me to this fascinating & useful quirk!

My "lockdown project" is coming along nicely and I'm looking to implement the floating bus trick to fix the currently horrific display shredding.

Initially I'm planning to implement the 48/128/+2 version the figure out the +2A/+3 variations via self modification at the start of execution.

There's a couple of things I'm unsure of though!

How do I determine which of the floating bus methods is available?

Are there any emulators which don't support the 48/138/+2 floating bus trick? As I notice there aren't many supporting the +2A/+3 variant.

(Aside: What happens if I run the code on an emulator which doesn't support it? I'm not planning to code around the quirks of an emulator, mind.)

Where to put it? This is the biggie... My game loop looks like this:

Code: Select all

Background buffer updates (scroll map etc here)
Collision map write all loop
Collision detection all loop
Copy background buffer to display buffer
Draw all to display buffer loop
*Copy display buffer to display*
Handle player input
Move/AI all loop
... repeat ...
By the time we reach Copy display buffer to display, the beam could be anywhere. I could just wait until I pick up my target value on the floating bus (in the bottom 1/3 of the display), but that seems wasteful... what if we're in the bottom border?

So it'd make sense to carry on into the other parts, checking again every so often. One concern is that I don't really want the player's input being read waaay before the display has been updated, in case the controls appear to lag as a result

It's probably worth mentioning here that there's a huuuuuge variation in how many T-states the whole loop takes depending on number of enemies, bullets, what type enemy/bullet they are... I think it's running at ~8 fps when things get really busy so maybe it won't be noticeable - though on the flip side I don't want it appearing any worse! And this of course makes it impossible to predict the number of T-states an entire "frame" requires, so no hints available there.

I guess I'm hoping to stumble upon the correct floating bus value between iterations of my Move/AI all loop, but would probably have to extend it to check throughout my game loop. But then I'm conscious of slowing the whole game down by checking too often!

So then I'm thinking - as a "get out" clause, if I reach a certain point (say, the collision detection all loop section) and it's still not happened, then it's probably a "quiet" loop with not much going on... so just sit and wait at that point until we catch our value, then draw the screen. Any delay should feel no worse than on a "busy" loop anyway.

Am I on the right track, or am I missing a trick? I find code comes together much easier the better planned it is, nevertheless I'm anticipating a ton of trial & error, rinse & repeat to get it nailed though... so I'm keen to know if I've overlooked or misinterpreted anything! :)
 
presh
Manic Miner
Posts: 237
Joined: Tue Feb 25, 2020 8:52 pm
Location: York, UK

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by presh »

Hmm, looks like I was getting rather too ahead of myself. Initial tests still contain a lot of shredding in the middle 1/3rd of the screen.

My "buffer to screen" routine is just an unrolled loop of 16 x CALL LDI_256 (which as you may have guessed is just 256 LDI's and a RET) so I figured it'd be fast enough... however I now learn that each of these 16 CALLs is 17 + (256 * 16) + 10 = 4123 T-states, 65968 in total... almost a full frame of T-states to draw 2/3rds of the screen! :shock:

How do other implementations using a display buffer manage it? ... or is that a question for another thread?
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by Ast A. Moore »

presh wrote: Sat May 30, 2020 6:10 pm Thank you Ast A. Moore for such great well-written info and for introducing me to this fascinating & useful quirk!
Thanks! I’m glad you liked it.
presh wrote: Sat May 30, 2020 6:10 pm How do I determine which of the floating bus methods is available?
There are various methods for determining which platform your code is running on. I test a specific ROM address (2899) for a particular value. A +2A/+3 returns a value of 126 (on all the ROMs I’ve tested it). I then use self-modifying code (for speed) in the main loop, and replace the port number to poll and the padding instruction accordingly.

There are other, more sophisticated, methods for determining a machine’s architecture, but so far I haven’t found much use for them.
presh wrote: Sun May 31, 2020 12:39 am How do other implementations using a display buffer manage it? ... or is that a question for another thread?
Often, the fastest method is to use the stack. Particular implementations will affect the effectiveness, naturally, but pushing a register pair onto the stack is the fastest way of moving two bytes the Z80 can manage.

Still, I suggest you create a separate thread for your question. The floating bus trick won’t give you more T states per frame. It’s just a method for syncing your main loop to a (more or less) arbitrary vertical position, instead of relying on the usual fixed top-of-the-frame interrupt.
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.
Post Reply