Why doesn't this floating bus code work on a real Spectrum?

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
Scavenger
New member
Posts: 4
Joined: Fri Jan 11, 2019 6:48 pm

Why doesn't this floating bus code work on a real Spectrum?

Post 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.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

IIRC the +2 is the Spectrum model reacting differently to the floating bus behavior :(
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post 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
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I created a detection fn called zx_floatingbus() which could help you in the checks
Scavenger
New member
Posts: 4
Joined: Fri Jan 11, 2019 6:48 pm

Post 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?
Scavenger
New member
Posts: 4
Joined: Fri Jan 11, 2019 6:48 pm

Post 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?
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

you are not returning a value for:
void FloatingBusWait ()
..you should declare it as 'int' and return something
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

so at the end of your fn:
return (result);
Scavenger
New member
Posts: 4
Joined: Fri Jan 11, 2019 6:48 pm

Post 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?
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post 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.
Post Reply