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
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.
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 »

A relatively simple method I use to distinguish a 128/+2 machine from a +2A/+3 is checking for the existence of port $3ffd. On the 128/+2 this port controls memory paging, so you can write to it and test known memory values in the $c000-$ffff range to see if they change. If they don't, then trying port $7ffd will let you know whether it's a +2A/+3. (As an aside, port $3ffd is generally preferable to the official paging port because it's not affected by contention.)
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 »

djnzx48 wrote: Sun May 31, 2020 11:18 am A relatively simple method I use to distinguish a 128/+2 machine from a +2A/+3 is checking for the existence of port $3ffd.
Yes, that’s a valid method; but for the floating bus behavior you only need to differentiate between a +2A/+3 and anything else, since the 48K/128K/+2 looping code will be identical. That’s why I opt for an even simpler method.
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: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum

Post by presh »

Ast A. Moore wrote: Sun May 31, 2020 10:48 am 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.
Thanks for this! Nice & simple :)
Ast A. Moore wrote: Sun May 31, 2020 10:48 am
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.
Yes, I'd come across the stack-based method in Jonathan Cauldwell's How To Write ZX Spectrum Games – Chapter 13 where he talks about unrolled LDI loops as well as the PUSH/POP method. The display screen area he mentions amounts to 4224 bytes, so I just assumed my 4096 byte unrolled LDI loop would do the job... oops! :oops:

I'd spent all day sat outside enjoying the sunshine, reading & planning how I was going to tackle this once it was time to head back indoors, hence my enormous rambling stream-of-consciousness post... I thought I had it all nailed down! Sigh :lol:
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 »

Image

Turns out I wasn't far off anyway... You can probably guess where my floating bus target values are! :lol:

Originally I had the play area at the top, energy bar directly beneath that, hoping my LDIs would complete before the beam got back around... they didn't!

So now the approach I have is to try & get behind the beam as soon as possible... by actually starting drawing a wee bit in front of it ;)

- upon discovering our value on the floating bus, immediately begin transferring stuff to the screen... but instead of just doing a ton of LDIs (which due to the Spectrum's screen layout, will jump between being in front of / behind the beam), traverse down pixel-by-pixel during the first block.

- by the 2nd block, the beam is way in front of where we're writing - so just do 2048 LDIs (CALL LDI_256, 8 times) for speed

This seems to work pretty well - there's a bit of attribute misalignment and tearing in the top few rows until the beam catches up, but it's barely noticeable. Good enough!!

The overall game is a bit slower than before due to waiting for the beam and the 1st block taking longer to transfer than before, but I've a ton of optimisations to do still so hoping to claw a decent chunk of that back.
Last edited by presh on Mon Jun 01, 2020 2:46 pm, edited 1 time in total.
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 »

Looks great! Love the graphics.
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
TomD
Manic Miner
Posts: 367
Joined: Tue Nov 13, 2018 9:47 am
Location: Leeds UK
Contact:

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

Post by TomD »

Very impressed with this, great for my new project where I needed to clear the sprites at at the bottom of the screen as I pushed the sprite drawing to the limit. I normally either redraw the entire screen from a back buffer or clear after a halt before plot if fast enough. That wasn't working for this so I started with an arbitrary wait loop which was tricky to get right if the number of sprites fluctuated. This seems to have solved that.

Any chance you could share your code to check if 48k/128k or +2A/+3 and how you modify the code for each?

At the moment I'm using the method you put on WoS

ld a,(2899) ;+2A/+3 ROMs return 126
cp 126
jr z,its_a_plus

and I just flip between the two versions of the fl_bus code.

Thanks in advance.

TomD
Retro enthusiast and author of Flynn's Adventure in Bombland, The Order of Mazes & Maze Death Rally-X. Check them out at http://tomdalby.com
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 »

TomD wrote: Mon Jun 01, 2020 10:15 pm Any chance you could share your code to check if 48k/128k or +2A/+3 and how you modify the code for each?

At the moment I'm using the method you put on WoS

ld a,(2899) ;+2A/+3 ROMs return 126
cp 126
jr z,its_a_plus

and I just flip between the two versions of the fl_bus code.
The above is exactly what I use in my real-world code for machine detection. The vanilla code is written for the +2A/+3, so the its_a_plus label just jumps forward without modifying anything. If the condition is not met, then I modify the floating bus sync code:

Code: Select all

		ld hl,v_sync+2
		ld (hl),$2b		;opcode for the DEC HL instruction [6]
		ld (v_sync_sw+1),hl	;redirect the JP NZ,** to DEC HL
		ld a,$40		;change top half of port addr (must be in the $40–$7f range)
		ld (port1+1),a
		ld a,$ff		;change bottom half of port addr
		ld (port2+1),a
The original code (before modification) looks like this:

Code: Select all

port1		ld de,$xx0f		;ATTR color (xx) into D, top half of port to read into E
v_sync		ld a,($5800)		;[13]point to contended memory and fetch a "blanking" attr
					;or DEC HL [6] for the 48K/128K/+2
		ld a,e			;[4]top half of port into A
port2		in a,($fd)		;[11]read port formed by A (MSB) and FDh (LSB) into A
		cp d			;[4]test for ATTR color
v_sync_sw	jp nz,v_sync		;[10]

After modification, the code will look like this:

Code: Select all

port1		ld de,$xx40		;ATTR color (xx) into D, top half of port to read into E
v_sync		ld a,($2b00)		;this makes no sense, but we’re only interested in the third byte,
					;which is the opcode for the DEC HL instruction
		ld a,e			;[4]top half of port into A
port2		in a,($ff)		;[11]read port formed by A (MSB) and FFh (LSB) into A
		cp d			;[4]test for ATTR color
v_sync_sw	jp nz,v_sync+2		;[10]note the changed jump address

Once the CPU reaches the JP instruction, it’ll read the above code differently, namely:

Code: Select all

SMC_v_sync	dec hl			;[6]the padding instruction necessary for syncing
		ld a,e			;[4]top half of port into A
port2		in a,($ff)		;[11]read port formed by A (MSB) and FFh (LSB) into A
		cp d			;[4]test for ATTR color
v_sync_sw	jp nz,SMC_v_sync	;[10]jumping to the last byte of the “nonsensical” LD A,($2B00) instruction

Hope this makes sense.
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
TomD
Manic Miner
Posts: 367
Joined: Tue Nov 13, 2018 9:47 am
Location: Leeds UK
Contact:

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

Post by TomD »

Ast A. Moore wrote: Tue Jun 02, 2020 12:52 am
Hope this makes sense.
Many thanks, I went with the following so it does the check on the fly rather than SMC, guess not great if you change the ROM in the middle of the program but I'm not planning on doing that :-)

One thing I did notice is the +2/+3 routine doesn't work on the Next (using Next/+3 mode). Works fine if you select 128k or Usr 0 mode though so not a major issue.

TomD

Code: Select all

; ==========================================+==================================
; floating bus wait routines (35b)
; ------------------------------------------+----------------------------------
; _fl_bus is for Sinclair 48/128k & Amstrad +2 (taken from sidewize)
; _fl2_bus is for Amstrad +2A/B & +3 (by Ast A. Moore)
; ==========================================+==================================
_fl_bus:
	ld a,($0b53)			; 13t - +2A/+3 ROMs return 126
	cp $7e				; 7t
	jr z,_fl2_bus			; 12/7t
	ld bc,$40ff			; 10t - port
	ld e,$18			; 7t - attr to compare to
_fl_bus100:
	ld a,r				; 4t
	in a,(c)			; 12t 
	cp e				; 4t - is it >=check attr
	jp nc,_fl_bus100		; 10t - loop till <
	ret				; 10t
_fl2_bus:
	ld de,$180f 			; 10t - attr into d, MSB of port addr into e 
_fl2_bus100:
	ld a,($5800) 			; 13t - point to contended memory and fetch a "blanking" attr 
	ld a,e 				; 4t - MSB of port addr into a 
	in a,($fd) 			; 11t - read port $0ffd into a 
	cp d 				; 4t - is it >=check attr
	jp nc,_fl2_bus100 		; 10t - loop till <
	ret				; 10t	
Retro enthusiast and author of Flynn's Adventure in Bombland, The Order of Mazes & Maze Death Rally-X. Check them out at http://tomdalby.com
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 »

TomD wrote: Tue Jun 02, 2020 2:09 pm One thing I did notice is the +2/+3 routine doesn't work on the Next (using Next/+3 mode). Works fine if you select 128k or Usr 0 mode though so not a major issue.
I’m not familiar with the Next well enough to comment, but keep in mind that on a real +2A/+3, the trick only works if paging hasn’t been explicitly disabled (i.e. it won’t work in 48K BASIC mode).
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
Seven.FFF
Manic Miner
Posts: 736
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

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

Post by Seven.FFF »

Next/+3 mode runs with +3 timings and the NextZXOS ROMs, which are significantly different from the +3 ROMs, given that they’re entirely rewritten with new NextBASIC functionality for new machine features. This tape loading mode is meant for loading new Next programs rather than for compatibility. So reading an arbitrary ROM byte in this mode isn’t a particularly good way to detect +3 timings.

Some of the other modes are intended for compatibility: 48K mode runs with 48K timings and the original 48K ROMs, with Next And 128K features disabled; 128K mode runs with 128K timings Bd the original 128K ROMs, with Next features disabled. Pentagon mode runs with Pentagon timings, and Pentagon/Profi paging. USR0 mode is not really a compatibility mode, it runs in +3 timings with Next features after invoking USR0.

It happens that there isn’t a dedicated +3 compatibility mode yet, because there is insufficient space to hold all 64K of alternate +3ROMs in the memory map. Alternate ROMs are a relatively new feature that avoided the need to endlessly patch the NextZXOS ROMs for compatibility with a succession of individual games. There was only 32K available to give to the scheme though, so it hasn’t yet been implemented for +2A/+3. This could change later after some other things have been reorganised.

As I said earlier in the thread, don’t get too hung up on expecting every program to work in every mode. The modes are pragmatic tools to let every program run in at least one common configuration, with some extra advanced options and manually applied disables to further tweak the environment where needed.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
Seven.FFF
Manic Miner
Posts: 736
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

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

Post by Seven.FFF »

* Oops, I said it in another Next thread somewhere else on this forum, not earlier in this thread. Soz.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
ketmar
Manic Miner
Posts: 612
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

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

Post by ketmar »

the emulation it is not completely right (i think), but ZXEmuT now can run Yankee in +2A/+3 mode! ;-)

thank you for your hard work, and for detailed explanations!
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 »

ketmar wrote: Thu Jul 30, 2020 7:40 pm the emulation it is not completely right (i think), but ZXEmuT now can run Yankee in +2A/+3 mode! ;-)

thank you for your hard work, and for detailed explanations!
Glad you found my little writeup useful! When I was helping Mark Woodmass to perfect the timings in SpecEmu, I made a special version of my test for him. Feel free to use it, tweak your emulator, and compare the results with this 50 fps video of my +2A running it. You can advance the video frame by frame and make sure the vertical shifts in the black gaps of the yellow border alight with the correct vertical white bars. Mark was able to nail it with the help of my test.
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
ketmar
Manic Miner
Posts: 612
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

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

Post by ketmar »

thank you even more! ;-)

for now it looks like my contention pattern for +2A is totally broken (no wonder, ZXEmuT couldn't properly run +2A/+3 at all until yesterday ;-), and Yankee works due to very specific timings. your test will definitely help to fix it all.
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 »

OK, so I had this working fine until I started messing around with interrupts - with IM2 enabled, the game locks up and the debugger shows it's stuck in the "floating_bus_loop" (see below).

At first I thought it might be because I hadn't DI / EI 'd either side of the code, but even after adding them it still locks up.

Any idea why this is happening?

(My interrupt code just cycles the border colour through 0-7 at the moment - a simple test routine, so that I can see it's being called successfully. Removing the bit of code which changes the border doesn't fix things either!)

Code: Select all

  DI

  LD D, 8     ; attr: PAPER 1, INK 0
  LD E, $40   ; MSB of port address ($40FF)
  
floating_bus_loop:

  DEC HL      ;[6]padding instruction
  LD A,E      ;[4]MSB of port addr into A
  IN A,($FF)  ;[11]read port 0x40FF into A
  CP D        ;[4]is it D (i.e. INK 1, PAPER 1, BRIGHT 0; FLASH 0)?
  JP NZ, floating_bus_loop	;[10]no? keep trying
	
  ; Found it!
  EI
Post Reply