Question about bus arbiter

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Question about bus arbiter

Post by mickagame » Thu Sep 04, 2014 5:35 am

When dma is progressing The Z80 can't access to 68K bus.
How it works?
For example i think when dma start there is a bus request sent to 68K wich freeze 68K during dma 5I think the correct vdp pin is connected to the correct 68K pin to avoid this mecanism).

How it works in Z80 side?

There is a block diagram describing how pins are connected?

Mask of Destiny
Very interested
Posts: 616
Joined: Thu Nov 30, 2006 6:30 am

Post by Mask of Destiny » Thu Sep 04, 2014 6:56 am

Both the VDP and the Z80 bus arbiter use the 68K's bus request mechanism to gain access to the bus. If the VDP has already requested the bus, the Z80 will not be granted access until after the DMA operation is complete. The 68K's bus arbitration protocol is fairly well documented in the 68000 User Manual (separate from the Programmer Manual).

That said, this isn't the only way 68K<->VDP interaction can block the bus. Generally speaking, the 68K will not grant a bus request while there's an active bus operation. If the 68K attempts to do a write and the FIFO is full, the VDP will hold !DTACK high until there's space in the FIFO for the write. This will prevent the Z80 from getting access until the write is fully complete. This tends to be less of an issue than DMA, but it's worth keeping in mind.

On the Z80 side, I believe the delay is implemented using the !WAIT signal.

mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Sat Sep 06, 2014 6:02 pm

I work at this moment on my emulator and i think about a code design to emulate this correctly.
My emulator is coded in object mode (C++).

My M68K object communicate with an object called Bus to perform bus operation.

void readByte(u32 adr, u8* data)
void readWord(u32 adr, u8* data)
void writeByte(u32 adr, u8 data)
void writeWord(u32 adr, u8 data)

So when the cpu acess to the bus it perform for example to read a byte :
bus.readByte(adr, &data);
etc ...

Generally all genesis emulator (except exodus because the design is different) do like that.

My idea is that this function return the number of extra cycle du to bus latency.

u32 writeByte(u32 adr, u8 data)

To write a byte the 68K need by default 4 cycles.
When FIFO is full the next write will take more cycle until the next slot is free.

So in the cpu code each time a bus access is done we will have :

cycles_exec += bus.writeByte(adr, data);

in the bus object code :

return (vdp.writeByte(adr, data));

And in the vdp code (I simplify the concept here) :

if (fifo.isFull())
{
return (CCL_PER_SLOT);
}


Is there an emulator programmer here who already use this design?

I want to precise that my goal is not to emulate genesis at the level of exodus but i'm focusing on code clarity and comprehensive (all respecting object rules design) at the level of genesis plus.

Thanks ;-)

Post Reply