Page 1 of 1
Why doesn't this floating bus code work on a real Spectrum?
Posted: Fri Jan 11, 2019 7:30 pm
by Scavenger
I'm currently trying to develop a small game for my +2 using z88dk, but the code I'm using to sync up the display and avoid flickering isn't working on the real hardware where it does on an emulator. I mostly copied
Sidewize's vsync code by making one attribute tile 0x40, and waiting for it to be returned so I can write to the display memory safely. But on real hardware using this function instead of HALT just ends up with the program freezing?
Code: Select all
void WaitForVSync ()
{
unsigned char result;
while (result != 0x40)
result = M_INP(0x40FF); //Fetch data from ULA to check if the current attribute byte is 0x40.
}
...
//How I set up the last attribute byte.
attribute = zx_cyx2aaddr (0,0);
attribute [31*24] = 0x40;
I'm using an Interface 1bis if it helps, and the latest nightly build of z88dk. I'm afraid I don't know much assembler so I didn't know how to implement it exactly with the inline assembler.
Posted: Fri Jan 11, 2019 9:26 pm
by stefano
IIRC the +2 is the Spectrum model reacting differently to the floating bus behavior
Posted: Fri Jan 11, 2019 9:32 pm
by stefano
to be precise:
the floating bus tricks are not available in the +2A and +3
http://sky.relative-path.com/zx/floating_bus.html
Posted: Fri Jan 11, 2019 9:34 pm
by stefano
I created a detection fn called zx_floatingbus() which could help you in the checks
Posted: Fri Jan 11, 2019 10:02 pm
by Scavenger
That's the thing, I have the grey +2, which should react just like a 48k. I don't have the +2A.
Do you have any suggestions on how to handle vsync?
Posted: Fri Jan 11, 2019 10:51 pm
by Scavenger
yI've made a version that should run on all spectrums from the zx_floatingbus routine:
Code: Select all
void (*WaitforVSync) (void);
void FloatingBusWait ()
{
unsigned char result;
while (result != 0x40)
result = M_INP(0x40FF); //Fetch data from ULA bus to check if the current attribute byte is 0x40.
}
void HackyWait ()
{
#asm
halt
#endasm
}
//...
if (zx_floatingbus() == 1) //am I doing that right?
{
WaitforVSync = FloatingBusWait;
printf ("float");
}
else
{
WaitforVSync = HackyWait;
printf ("hack");
}
//...
WaitforVSync ();
But the compiler gives me this warning:
sccz80:"test.c" L:210 Warning:Assigning from a void expression [-Wvoid]
Line 210 is
result = M_INP(0x40FF);.
How do I write this so that it doesn't give a warning?
Posted: Fri Jan 11, 2019 11:08 pm
by stefano
you are not returning a value for:
void FloatingBusWait ()
..you should declare it as 'int' and return something
Posted: Fri Jan 11, 2019 11:09 pm
by stefano
so at the end of your fn:
return (result);
Posted: Fri Jan 11, 2019 11:14 pm
by Scavenger
The problem there is definitely in the M_INP () macro rather than the surrounding function, changing it to "inp (0x40FF)" removes the warning.
I guess I'm not sure how to use the macro version of inp properly there?
Posted: Sat Jan 12, 2019 11:01 am
by dom
It looks like the result of an asm("") function is marked as a void, hence the warning. I'll fix that up later on today.
However, these days, sccz80 supports the same syntax as sdcc for accessing ports.
extern __sfr __at 0x45 port;
extern __sfr __banked __at 0x45 port2;
port is then an 8 bit port, and port2 is a 16 bit port. You can use them as follows:
int val = port;
Which will generate the appropriate "in" instructions.