The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
Still mega stumped by this!
I took a backup before I started messing with the interrupts, so I rolled back to that working version.
Ended up in the same situation - interrupt routine runs fine, but gets stuck in the floating bus loop and never "catches" the target value...
Added DI/EI either side - no effect.
Removed the border colour changing part of the interrupt routine again (in case my OUT (254), colour was messing with things) - no effect.
Same behaviour in Spectaculator & ZX Spin (emulating a +2 throughout development) so not convinced it's an emulator "feature" (also as it's the old "tried & tested" rather than the new +2A/+3 method)
Are there any caveats regarding interrupts, interrupt modes, etc I've overlooked?
I took a backup before I started messing with the interrupts, so I rolled back to that working version.
Ended up in the same situation - interrupt routine runs fine, but gets stuck in the floating bus loop and never "catches" the target value...
Added DI/EI either side - no effect.
Removed the border colour changing part of the interrupt routine again (in case my OUT (254), colour was messing with things) - no effect.
Same behaviour in Spectaculator & ZX Spin (emulating a +2 throughout development) so not convinced it's an emulator "feature" (also as it's the old "tried & tested" rather than the new +2A/+3 method)
Are there any caveats regarding interrupts, interrupt modes, etc I've overlooked?
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
Hmm. Could you post the entire code (well, the relevant portions) so I could test it? The only reason for it not to be working I can think of off the top of my head is that it’s sitting somewhere in contended memory (including the respective RAM banks).
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: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
Sure, my interrupt is set up at the very beginning like so:
The interrupt itself is:
Interrupt table is 257 bytes of $66. Interrupt runs fine and produces the desired headache-inducing border effect.
The floating bus loop is at $B187 and was working right up until I added the above bits of code in.
Code: Select all
; Set up interrupts
DI
LD A, $65 ; Interrupt table at page $6500
LD I, A ; Set the interrupt register to that page
IM 2 ; Set the interrupt mode
EI ; Enable interrupts
Code: Select all
ORG $6666 ; 26214
INTERRUPT:
DI
PUSH AF
PUSH BC
PUSH DE
PUSH HL
EXX
PUSH AF
PUSH BC
PUSH DE
PUSH HL
EXX
PUSH IX
PUSH IY
; --- Main interrupt routine --- ;
; Update border colour
LD HL, intrpt_test
INC (HL)
LD A, (HL)
AND 7
OUT (254), A
; --- End of main interrupt routine --- ;
POP IY
POP IX
EXX
POP HL
POP DE
POP BC
POP AF
EXX
POP HL
POP DE
POP BC
POP AF
EI
RET
intrpt_test:
DB 0
The floating bus loop is at $B187 and was working right up until I added the above bits of code in.
-
- Microbot
- Posts: 134
- Joined: Tue Jun 09, 2020 6:14 am
- Contact:
Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
If it's not a typo, chances are you're testing for a different attr value rather than the one you put onscreen.presh wrote: ↑Sun Sep 06, 2020 9:43 pmCode: Select all
LD D, 8 ; attr: PAPER 1, INK 0 <...> CP D ;[4]is it D (i.e. INK 1, PAPER 1, BRIGHT 0; FLASH 0)?
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
Either that, or the tested area is not wide enough for the loop to catch it. Make sure you have enough consecutive cells with the desired attributes. Depending on which machine you run this on (48K/128K), the loop will take a different amount of time to sync up. To be on the safe side, I recommend setting the same attribute value for an entire row.Nienn Heskil wrote: ↑Wed Sep 09, 2020 8:12 pmIf it's not a typo, chances are you're testing for a different attr value rather than the one you put onscreen.presh wrote: ↑Sun Sep 06, 2020 9:43 pmCode: Select all
LD D, 8 ; attr: PAPER 1, INK 0 <...> CP D ;[4]is it D (i.e. INK 1, PAPER 1, BRIGHT 0; FLASH 0)?
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: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
Yes, your interrupt vector is pointing to the contended RAM area ($40–$7f). This will trigger the ULA snow effect. You should always make sure it’s outside that range. The ISR itself can sit anywhere in RAM, but the interrupt vector table must reside in non-contended RAM.
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: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
Haha, yes. Those are [mention]Ast A. Moore[/mention]'s original comments which I hadn't updated! Well spottedNienn Heskil wrote: ↑Wed Sep 09, 2020 8:12 pmIf it's not a typo, chances are you're testing for a different attr value rather than the one you put onscreen.presh wrote: ↑Sun Sep 06, 2020 9:43 pmCode: Select all
LD D, 8 ; attr: PAPER 1, INK 0 <...> CP D ;[4]is it D (i.e. INK 1, PAPER 1, BRIGHT 0; FLASH 0)?
Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
Ah! Another one of those "quirks" I've heard about but never encountered and thus forgotten. Thanks for the explanation. I shall attempt to find room up there, but it's pretty... RAMmedAst A. Moore wrote: ↑Wed Sep 09, 2020 10:08 pmYes, your interrupt vector is pointing to the contended RAM area ($40–$7f). This will trigger the ULA snow effect. You should always make sure it’s outside that range. The ISR itself can sit anywhere in RAM, but the interrupt vector table must reside in non-contended RAM.
Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
Having read through this thread and your webpage am I right in thinking that your code loop will catch one of the attribute bytes on the relevant row, but you can't be sure which one? And is it also the case that you're not 100% sure why this 35 t-state loop only catches attributes?Ast A. Moore wrote: ↑Wed Sep 09, 2020 9:59 pmEither that, or the tested area is not wide enough for the loop to catch it. Make sure you have enough consecutive cells with the desired attributes. Depending on which machine you run this on (48K/128K), the loop will take a different amount of time to sync up. To be on the safe side, I recommend setting the same attribute value for an entire row.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: The Definitive Programmer’s Guide to Using the Floating Bus Trick on the ZX Spectrum
True, you can’t be absolutely sure which attribute cell the loop will catch, but if I remember correctly, an entire row is certainly overkill. However, it would be difficult to set up a test that would reveal the exact pattern definitively. Moreover, I suspect that the exact timing of the triggering will depend on the length of the instructions preceding the sync loop and will thus be pretty much unpredictable.DoctorRad wrote: ↑Wed Mar 27, 2024 2:55 pm Having read through this thread and your webpage am I right in thinking that your code loop will catch one of the attribute bytes on the relevant row, but you can't be sure which one? And is it also the case that you're not 100% sure why this 35 t-state loop only catches attributes?
As for why the loop takes the number of T states it does (note that it’ll differ on different Spectrum models), you’re right, I can’t fully explain it. I ran a few dozen tests with different padding instructions and the example outlined in my writeup is just the quickest one that works. It’s reasonable to assume that using another padding instruction (or, indeed, instructions) will let you be more precise in picking and choosing the exact attribute location at the expense of causing a significant delay (for example, you may be limited to just a single attribute per two or more rows). I’d argue it is possible to create a very sophisticated timing pattern for several consecutive loops (each with its own timing) and get very precise indeed. However practical that would be, I am not certain.
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.