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
TomD
Berk
Posts: 37
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
0 x
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
Dynamite Dan
Posts: 1686
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.
1 x
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
Berk
Posts: 37
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	
0 x
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
Dynamite Dan
Posts: 1686
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).
0 x
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: 492
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.
1 x
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins

User avatar
Seven.FFF
Manic Miner
Posts: 492
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.
0 x
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins

User avatar
ketmar
Microbot
Posts: 176
Joined: Tue Jun 16, 2020 5:25 pm

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!
0 x

User avatar
Ast A. Moore
Dynamite Dan
Posts: 1686
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.
1 x
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
Microbot
Posts: 176
Joined: Tue Jun 16, 2020 5:25 pm

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.
0 x

Post Reply