-
#850 Reply
Posted by
nockieboy
on 05 Jan, 2020 12:15
-
Upload the latest copy of what you are compiling with...
Attached is latest copy of the project with all the changes made yesterday.
-
#851 Reply
Posted by
nockieboy
on 05 Jan, 2020 12:25
-
Ok. Without superimposed multichannel scope shots, I cant tell if all your addresses are properly being asserted at the same time or not.
If you have a logic analyzer, you will want one with a good 100MHz sampling rate on at least half the data and and the first addresses + buss control signals, including the 'WAIT' states which may be asserted by a third device on the bus.
My scope is next to useless for digital testing and my logic analyser isn't really up to that sort of work - it's just an 8-channel 25 MHz 'cheapy' off eBay. It's served me just fine building the Microcom, but we're well out of '8 MHz-league', here.
I have a bit of time right now, so I'm going to try and sort the address bus and get those offending lanes moved to fast-input pins.
I made the current code sample the address at the fall of MREQn, after the fall of MREQ_DLY_CLK which run at 125MHz.
I downloaded the newer Zlog Z80 documents which have the 8/10/20 MHz variants included. The bus transactions and timing is not as simple as that old dumb 4MHz data sheet. The MREQn going up and down between bus cycles is not guaranteed, or, it can be such a small value in NS, that unless we make a true static interface, or a proper synchronous interface, things will go haywire. Also, there are other cycles right after transactions, like refresh cycles, or program code fetch which may also hold or shrink the MREQn.
It's not that the interface needs to be any more complicated that it is, it that I cannot see what is going on remotely and 95% of the Z80 docs out there assume a cheap static type design. And with you bread board wiring & choice of voltage level shifting, and choice of IOs, I'm not sure where the true problem is creeping in.
I know, it's a haystack and there's probably some fake needles in there to confuse things as well. Is there a better way of doing the voltage level shifting then? I'm always open to suggestions and guidance!
-
#852 Reply
Posted by
BrianHG
on 05 Jan, 2020 12:48
-
Without seeing, I have nothing to go on.
Try changing these 2 values:
Also try these parameter settings:
parameter DELAY_CYCLES = 0; // number of cycles to delay write for 245
parameter MREQ_DLY_CLK = 0; // number of cycles +1 to delay mreq trigger
This should accelerate the response. If it doesn't work, we can try full static approach. However, this isn't too wise a strategy for future upgrade.
Also, you shouldn't use pins 88,89,90,91 for your addresses. Please move them.
For these pins, you should only use them for Z80_CLK, only, or you may also tie MREQ, RD, WR to these pins as well. They are dedicated inputs and their timing to logic cells slightly differs to the main IOs where the rest of the addresses are wired.
This is important especially if we want to clock off of the Z80_CLK input.
Also, in assignment settings, compiler settings, 'Advanced Settings (Fitter)...', please turn on :
Perform Register Retiming For Performance.
PLEASE SWAP THE INPUT PINS LIKE I SAID...
-
#853 Reply
Posted by
BrianHG
on 05 Jan, 2020 13:06
-
I know, it's a haystack and there's probably some fake needles in there to confuse things as well. Is there a better way of doing the voltage level shifting then? I'm always open to suggestions and guidance!
Its more than just level shifting. With a bread board and 1 GND wire to something like 35 signal wires, do you have proper signal termination?
What does your signal bounce look like? The FPGA is still sensitive to signals in the 100MHz to 200MHz range even though the Z80 may only be sensitive to 20MHz.
When you build a PCB, will you be able to do proper resistor series and parallel termination on the right sides of the CMOS buffers?
Can you measure the signal bounce?
Without the above question being answered, you may want to use series resistor packs in dip or sip form so you may insert alternate values, or, you will have to design a quality layout PCB, with more than 1 GND wire going to the Z80...
-
#854 Reply
Posted by
nockieboy
on 05 Jan, 2020 14:03
-
Without seeing, I have nothing to go on.
Try changing these 2 values:
Also try these parameter settings:
parameter DELAY_CYCLES = 0; // number of cycles to delay write for 245
parameter MREQ_DLY_CLK = 0; // number of cycles +1 to delay mreq trigger
Okay, that's done, but shouldn't there be
some delay for the 245 to enable?
Also, you shouldn't use pins 88,89,90,91 for your addresses. Please move them.
For these pins, you should only use them for Z80_CLK, only, or you may also tie MREQ, RD, WR to these pins as well. They are dedicated inputs and their timing to logic cells slightly differs to the main IOs where the rest of the addresses are wired.
This is important especially if we want to clock off of the Z80_CLK input.
Okay, the offending address lanes have been moved to alternate input pins (84, 86, 105 & 106) - I've moved the Z80_CLK line to pin 90.
Also, in assignment settings, compiler settings, 'Advanced Settings (Fitter)...', please turn on :
Perform Register Retiming For Performance.
Done. Am just testing the output now - seems with DELAY_CYCLES set to zero and MREQ_DLY_CLK set to zero, I'm unable to read or write to the GPU RAM, although the Microcom was stable. Have just tried it with DELAY_CYCLES back to 2, that wasn't good - Microcom wouldn't boot into the DMI (where the GPU is set up) without locking up and the GPU RAM being corrupted.
-
#855 Reply
Posted by
nockieboy
on 05 Jan, 2020 14:10
-
-
#856 Reply
Posted by
BrianHG
on 05 Jan, 2020 14:14
-
Ok, this one is static read, one shot write:
module Z80_bridge (
// input
input wire reset, // GPU reset signal
input wire GPU_CLK, // GPU clock (125 MHz)
input wire Z80_CLK, // Microcom clock signal (8 MHz)
input wire Z80_M1n, // Z80 M1 - active LOW
input wire Z80_MREQn, // Z80 MREQ - active LOW
input wire Z80_WRn, // Z80 WR - active LOW
input wire Z80_RDn, // Z80 RD - active LOW
input wire [21:0] Z80_addr, // Microcom 22-bit address bus
input wire [7:0] Z80_wData, // Z80 DATA bus to pass incoming data to GPU RAM
input wire [7:0] gpu_rData,
input wire gpu_rd_rdy, // one-shot signal from mux that data is ready
// output
output reg Z80_245data_dir, // control level converter direction for data flow - HIGH = A -> B (toward FPGA)
output reg [7:0] Z80_rData, // Z80 DATA bus to return data from GPU RAM to Z80
output reg Z80_rData_ena, // flag HIGH to write data back to Z80
output reg Z80_245_oe, // OE for 245 level translator *** ACTIVE LOW ***
output reg gpu_wr_ena, // flag HIGH for 1 clock when writing to GPU RAM
output reg gpu_rd_req, // flag HIGH for 1 clock when reading from GPU RAM
output reg [19:0] gpu_addr, // connect to Z80_addr in vid_osd_generator to address GPU RAM
output reg [7:0] gpu_wdata, // 8-bit data bus to GPU RAM in vid_osd_generator
input wire sel_pclk, // make HIGH to trigger the Z80 bus on the positive edge of Z80_CLK
input wire sel_nclk // make LOW to trigger the Z80 bus on the negative edge of Z80_CLK
);
// TODO:
//
// 1) Prevent reads to GPU RAM above top of GPU RAM
// 2) Respond with appropriate data to any requests from Microcom ROM identification routines
//
parameter MEMORY_RANGE = 3'b010; // Z80_addr[21:19] == 3'b010 targets the 512KB 'window' at 0x100000-0x17FFFF (Socket 3 on the Microcom)
parameter DELAY_CYCLES = 2; // number of cycles to delay write for 245
parameter MEM_SIZE_BITS = 15; //
parameter MREQ_DLY_CLK = 2; // number of cycles +1 to delay mreq trigger
wire Z80_mreq, Z80_mreq_pulse, Z80_unmreq_pulse, Z80_write, Z80_read, Write_GPU_RAM;
wire Read_GPU_RAM_BEGIN, Read_GPU_RAM_END;
wire Z80_clk_pos,Z80_clk_neg,Z80_clk_trig;
reg Z80_clk_delay, last_Z80_WR, last_Z80_RD, mem_valid_range, MREQn_dly, MREQn_dly2, mem_window ;
reg [9:0] Z80_write_sequencer,Z80_mreq_dly;
assign Z80_clk_pos = ~Z80_clk_delay && Z80_CLK;
assign Z80_clk_neg = Z80_clk_delay && ~Z80_CLK;
assign Z80_clk_trig = (Z80_clk_pos && sel_pclk) || (Z80_clk_neg && ~sel_nclk);
assign Z80_mreq_pulse = ~Z80_mreq_dly[MREQ_DLY_CLK] && Z80_mreq_dly[MREQ_DLY_CLK+1];
assign Z80_unmreq_pulse = Z80_mreq_dly[MREQ_DLY_CLK] && ~Z80_mreq_dly[MREQ_DLY_CLK+1];
assign Z80_mreq = ~Z80_mreq_dly[MREQ_DLY_CLK+1] && Z80_M1n; // Define a bus memory access state
assign Z80_write = ~Z80_WRn && last_Z80_WR; // Isolate a single write transaction
assign Z80_read = ~Z80_RDn; // Isolate a single read transaction
assign Z80_readn = Z80_RDn && ~last_Z80_RD; // Isolate a single read transaction
assign Write_GPU_RAM = mem_window && Z80_mreq && Z80_write && mem_valid_range; // Define a GPU Write action - only write to address within GPU RAM bounds
assign Read_GPU_RAM_BEGIN = mem_window && Z80_mreq && Z80_read && mem_valid_range; // Define the beginning of a Z80 read request of GPU Ram.
assign Read_GPU_RAM_END = Z80_readn ; // Define the ending of a Z80 read request of GPU Ram.
// **********************************************************************************************************
always @ (posedge GPU_CLK) begin
Z80_mreq_dly[9:0] <= { Z80_mreq_dly[8:0], Z80_MREQn };
//if (Z80_mreq_pulse) begin
gpu_addr <= Z80_addr[18:0]; // latch address bus onto GPU address bus
mem_valid_range <= (Z80_addr[18:0] < 2**MEM_SIZE_BITS); // Define GPU addressable memory space
mem_window <= (Z80_addr[21:19] == MEMORY_RANGE); // Define an active memory range
//end else if (Z80_unmreq_pulse) begin
// mem_valid_range <= 1'b0; // Define GPU addressable memory space
// mem_window <= 1'b0; // Define an active memory range
//end
Z80_write_sequencer[9:0] <= { Z80_write_sequencer[8:0], Write_GPU_RAM };
if ( Z80_write_sequencer[0] ) Z80_245data_dir <= 1'b1; // set 245 dir toward FPGA
if ( Z80_write_sequencer[0] ) Z80_rData_ena <= 1'b0; // set FPGA pins to input (should be by default)
if ( Z80_write_sequencer[0] ) Z80_245_oe <= 1'b0; // enable 245 output (WAS 1 - moved forward to step 0)
if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wdata <= Z80_wData; // latch data bus onto GPU data bus
if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wr_ena <= 1'b1; // turn on FPGA RAM we
if ( Z80_write_sequencer[DELAY_CYCLES + 2] ) gpu_wr_ena <= 1'b0; // turn off FPGA RAM we (WAS STEP +2, now STEP +3 for additional WR)
if ( Z80_write_sequencer[DELAY_CYCLES + 2] ) Z80_245_oe <= 1'b1; // disable 245 output
if ( Read_GPU_RAM_BEGIN ) begin
gpu_rd_req <= 1'b1; // flag a read request to the mux which is one-shotted in the mux
Z80_245data_dir <= 1'b0; // set 245 direction (TO Z80)
Z80_245_oe <= 1'b0; // enable 245 output
Z80_rData_ena <= 1'b1; // set bidir pins to output
end else begin
gpu_rd_req <= 1'b0; // end GPU read req after 1 pulse
//if ( Read_GPU_RAM_END ) begin
Z80_rData_ena <= 1'b0; // re-set bidir pins to input
Z80_245_oe <= 1'b1; // disable 245 output
// end
end
if ( gpu_rd_rdy ) begin
if (mem_valid_range) Z80_rData[7:0] <= gpu_rData[7:0];// Latch the GPU RAM read into the output register for the Z80
else Z80_rData[7:0] <= 8'b11111111; // return $FF if addressed byte is outside the GPU's upper RAM limit
end
last_Z80_WR <= Z80_WRn;
last_Z80_RD <= Z80_RDn;
Z80_clk_delay <= Z80_CLK; // find the rising clock edge
end
// **********************************************************************************************************
endmodule
Change the 2 delay parameters to 0, then try 1 and 2. The parameters should only effect the writes.
Also, if your get timing violations, IE an FMAX too low, disable the 'register retiming' feature I told you to turn on earlier.
-
#857 Reply
Posted by
BrianHG
on 05 Jan, 2020 14:20
-
-
#858 Reply
Posted by
BrianHG
on 05 Jan, 2020 14:28
-
Ooops, logic bomb on the 245 controls during write. Here is the fix:
module Z80_bridge (
// input
input wire reset, // GPU reset signal
input wire GPU_CLK, // GPU clock (125 MHz)
input wire Z80_CLK, // Microcom clock signal (8 MHz)
input wire Z80_M1n, // Z80 M1 - active LOW
input wire Z80_MREQn, // Z80 MREQ - active LOW
input wire Z80_WRn, // Z80 WR - active LOW
input wire Z80_RDn, // Z80 RD - active LOW
input wire [21:0] Z80_addr, // Microcom 22-bit address bus
input wire [7:0] Z80_wData, // Z80 DATA bus to pass incoming data to GPU RAM
input wire [7:0] gpu_rData,
input wire gpu_rd_rdy, // one-shot signal from mux that data is ready
// output
output reg Z80_245data_dir, // control level converter direction for data flow - HIGH = A -> B (toward FPGA)
output reg [7:0] Z80_rData, // Z80 DATA bus to return data from GPU RAM to Z80
output reg Z80_rData_ena, // flag HIGH to write data back to Z80
output reg Z80_245_oe, // OE for 245 level translator *** ACTIVE LOW ***
output reg gpu_wr_ena, // flag HIGH for 1 clock when writing to GPU RAM
output reg gpu_rd_req, // flag HIGH for 1 clock when reading from GPU RAM
output reg [19:0] gpu_addr, // connect to Z80_addr in vid_osd_generator to address GPU RAM
output reg [7:0] gpu_wdata, // 8-bit data bus to GPU RAM in vid_osd_generator
input wire sel_pclk, // make HIGH to trigger the Z80 bus on the positive edge of Z80_CLK
input wire sel_nclk // make LOW to trigger the Z80 bus on the negative edge of Z80_CLK
);
// TODO:
//
// 1) Prevent reads to GPU RAM above top of GPU RAM
// 2) Respond with appropriate data to any requests from Microcom ROM identification routines
//
parameter MEMORY_RANGE = 3'b010; // Z80_addr[21:19] == 3'b010 targets the 512KB 'window' at 0x100000-0x17FFFF (Socket 3 on the Microcom)
parameter DELAY_CYCLES = 2; // number of cycles to delay write for 245
parameter MEM_SIZE_BITS = 15; //
parameter MREQ_DLY_CLK = 2; // number of cycles +1 to delay mreq trigger
wire Z80_mreq, Z80_mreq_pulse, Z80_unmreq_pulse, Z80_write, Z80_read, Write_GPU_RAM;
wire Read_GPU_RAM_BEGIN, Read_GPU_RAM_END;
wire Z80_clk_pos,Z80_clk_neg,Z80_clk_trig;
reg Z80_clk_delay, last_Z80_WR, last_Z80_RD, mem_valid_range, MREQn_dly, MREQn_dly2, mem_window ;
reg [9:0] Z80_write_sequencer,Z80_mreq_dly;
assign Z80_clk_pos = ~Z80_clk_delay && Z80_CLK;
assign Z80_clk_neg = Z80_clk_delay && ~Z80_CLK;
assign Z80_clk_trig = (Z80_clk_pos && sel_pclk) || (Z80_clk_neg && ~sel_nclk);
assign Z80_mreq_pulse = ~Z80_mreq_dly[MREQ_DLY_CLK] && Z80_mreq_dly[MREQ_DLY_CLK+1];
assign Z80_unmreq_pulse = Z80_mreq_dly[MREQ_DLY_CLK] && ~Z80_mreq_dly[MREQ_DLY_CLK+1];
assign Z80_mreq = ~Z80_mreq_dly[MREQ_DLY_CLK+1] && Z80_M1n; // Define a bus memory access state
assign Z80_write = ~Z80_WRn && last_Z80_WR; // Isolate a single write transaction
assign Z80_read = ~Z80_RDn; // Isolate a single read transaction
assign Z80_readn = Z80_RDn && ~last_Z80_RD; // Isolate a single read transaction
assign Write_GPU_RAM = mem_window && Z80_mreq && Z80_write && mem_valid_range; // Define a GPU Write action - only write to address within GPU RAM bounds
assign Read_GPU_RAM_BEGIN = mem_window && Z80_mreq && Z80_read && mem_valid_range; // Define the beginning of a Z80 read request of GPU Ram.
assign Read_GPU_RAM_END = Z80_readn ; // Define the ending of a Z80 read request of GPU Ram.
// **********************************************************************************************************
always @ (posedge GPU_CLK) begin
Z80_mreq_dly[9:0] <= { Z80_mreq_dly[8:0], Z80_MREQn };
//if (Z80_mreq_pulse) begin
gpu_addr <= Z80_addr[18:0]; // latch address bus onto GPU address bus
mem_valid_range <= (Z80_addr[18:0] < 2**MEM_SIZE_BITS); // Define GPU addressable memory space
mem_window <= (Z80_addr[21:19] == MEMORY_RANGE); // Define an active memory range
//end else if (Z80_unmreq_pulse) begin
// mem_valid_range <= 1'b0; // Define GPU addressable memory space
// mem_window <= 1'b0; // Define an active memory range
//end
Z80_write_sequencer[9:0] <= { Z80_write_sequencer[8:0], Write_GPU_RAM };
if ( Z80_write_sequencer[0] ) Z80_245data_dir <= 1'b1; // set 245 dir toward FPGA
if ( Z80_write_sequencer[0] ) Z80_rData_ena <= 1'b0; // set FPGA pins to input (should be by default)
if ( Z80_write_sequencer[0] ) Z80_245_oe <= 1'b0; // enable 245 output (WAS 1 - moved forward to step 0)
if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wdata <= Z80_wData; // latch data bus onto GPU data bus
if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wr_ena <= 1'b1; // turn on FPGA RAM we
if ( Z80_write_sequencer[DELAY_CYCLES + 2] ) gpu_wr_ena <= 1'b0; // turn off FPGA RAM we (WAS STEP +2, now STEP +3 for additional WR)
if ( Z80_write_sequencer[DELAY_CYCLES + 2] ) Z80_245_oe <= 1'b1; // disable 245 output
if ( Read_GPU_RAM_BEGIN && Z80_WRn ) begin
gpu_rd_req <= 1'b1; // flag a read request to the mux which is one-shotted in the mux
Z80_245data_dir <= 1'b0; // set 245 direction (TO Z80)
Z80_245_oe <= 1'b0; // enable 245 output
Z80_rData_ena <= 1'b1; // set bidir pins to output
end else begin
gpu_rd_req <= 1'b0; // end GPU read req after 1 pulse
if ( Z80_WRn ) begin
Z80_rData_ena <= 1'b0; // re-set bidir pins to input
Z80_245_oe <= 1'b1; // disable 245 output
end
end
if ( gpu_rd_rdy ) begin
if (mem_valid_range) Z80_rData[7:0] <= gpu_rData[7:0];// Latch the GPU RAM read into the output register for the Z80
else Z80_rData[7:0] <= 8'b11111111; // return $FF if addressed byte is outside the GPU's upper RAM limit
end
last_Z80_WR <= Z80_WRn;
last_Z80_RD <= Z80_RDn;
Z80_clk_delay <= Z80_CLK; // find the rising clock edge
end
// **********************************************************************************************************
endmodule
Delay cycles needs to be at least 2.
-
#859 Reply
Posted by
nockieboy
on 05 Jan, 2020 14:42
-
How do you prototype circuits that run at silly speeds (100MHz+) if breadboard (clearly) isn't up to the task?
Good thick grounding wiring. Decoupling caps everywhere, and, wire-wrap or soldered prototype boards usually do the trick.
Everything has decoupling caps - all the chips on the breadboard are decoupled (I'm using SOIC->DIP converters with a 100nF cap on the mini-PCB). There's two GND wires now (yay!) connecting the breadboard to both the FPGA and the Microcom.
Am just testing the delay settings now:
Both DLY valuse set to 0: Reading the GPU RAM caused a system crash. Timing's definitely out on the 245, I presume.
Both DLY values set to 1: Writing
any value to the GPU RAM writes $FF to that location. Any read crashes the system.
Both DLY values set to 2: Writing
any value to the GPU RAM writes $FF to that location. Any read crashes the system.
EDIT: Just spotted your last post! Above results don't take that into account.
-
#860 Reply
Posted by
BrianHG
on 05 Jan, 2020 14:50
-
Ooops, accidentally delaying the 'MREQ'. Ok, this one should work and not crash the system.
module Z80_bridge (
// input
input wire reset, // GPU reset signal
input wire GPU_CLK, // GPU clock (125 MHz)
input wire Z80_CLK, // Microcom clock signal (8 MHz)
input wire Z80_M1n, // Z80 M1 - active LOW
input wire Z80_MREQn, // Z80 MREQ - active LOW
input wire Z80_WRn, // Z80 WR - active LOW
input wire Z80_RDn, // Z80 RD - active LOW
input wire [21:0] Z80_addr, // Microcom 22-bit address bus
input wire [7:0] Z80_wData, // Z80 DATA bus to pass incoming data to GPU RAM
input wire [7:0] gpu_rData,
input wire gpu_rd_rdy, // one-shot signal from mux that data is ready
// output
output reg Z80_245data_dir, // control level converter direction for data flow - HIGH = A -> B (toward FPGA)
output reg [7:0] Z80_rData, // Z80 DATA bus to return data from GPU RAM to Z80
output reg Z80_rData_ena, // flag HIGH to write data back to Z80
output reg Z80_245_oe, // OE for 245 level translator *** ACTIVE LOW ***
output reg gpu_wr_ena, // flag HIGH for 1 clock when writing to GPU RAM
output reg gpu_rd_req, // flag HIGH for 1 clock when reading from GPU RAM
output reg [19:0] gpu_addr, // connect to Z80_addr in vid_osd_generator to address GPU RAM
output reg [7:0] gpu_wdata, // 8-bit data bus to GPU RAM in vid_osd_generator
input wire sel_pclk, // make HIGH to trigger the Z80 bus on the positive edge of Z80_CLK
input wire sel_nclk // make LOW to trigger the Z80 bus on the negative edge of Z80_CLK
);
// TODO:
//
// 1) Prevent reads to GPU RAM above top of GPU RAM
// 2) Respond with appropriate data to any requests from Microcom ROM identification routines
//
parameter MEMORY_RANGE = 3'b010; // Z80_addr[21:19] == 3'b010 targets the 512KB 'window' at 0x100000-0x17FFFF (Socket 3 on the Microcom)
parameter DELAY_CYCLES = 2; // number of cycles to delay write for 245
parameter MEM_SIZE_BITS = 15; //
parameter MREQ_DLY_CLK = 2; // number of cycles +1 to delay mreq trigger
wire Z80_mreq, Z80_mreq_pulse, Z80_unmreq_pulse, Z80_write, Z80_read, Write_GPU_RAM;
wire Read_GPU_RAM_BEGIN, Read_GPU_RAM_END;
wire Z80_clk_pos,Z80_clk_neg,Z80_clk_trig;
reg Z80_clk_delay, last_Z80_WR, last_Z80_RD, mem_valid_range, MREQn_dly, MREQn_dly2, mem_window ;
reg [9:0] Z80_write_sequencer,Z80_mreq_dly;
assign Z80_clk_pos = ~Z80_clk_delay && Z80_CLK;
assign Z80_clk_neg = Z80_clk_delay && ~Z80_CLK;
assign Z80_clk_trig = (Z80_clk_pos && sel_pclk) || (Z80_clk_neg && ~sel_nclk);
assign Z80_mreq_pulse = ~Z80_mreq_dly[MREQ_DLY_CLK] && Z80_mreq_dly[MREQ_DLY_CLK+1];
assign Z80_unmreq_pulse = Z80_mreq_dly[MREQ_DLY_CLK] && ~Z80_mreq_dly[MREQ_DLY_CLK+1];
assign Z80_mreq = ~Z80_MREQn && Z80_M1n; // Define a bus memory access state
assign Z80_write = ~Z80_WRn && last_Z80_WR; // Isolate a single write transaction
assign Z80_read = ~Z80_RDn; // Isolate a single read transaction
assign Z80_readn = Z80_RDn && ~last_Z80_RD; // Isolate a single read transaction
assign Write_GPU_RAM = mem_window && Z80_mreq && Z80_write && mem_valid_range; // Define a GPU Write action - only write to address within GPU RAM bounds
assign Read_GPU_RAM_BEGIN = mem_window && Z80_mreq && Z80_read && mem_valid_range; // Define the beginning of a Z80 read request of GPU Ram.
assign Read_GPU_RAM_END = Z80_readn ; // Define the ending of a Z80 read request of GPU Ram.
// **********************************************************************************************************
always @ (posedge GPU_CLK) begin
Z80_mreq_dly[9:0] <= { Z80_mreq_dly[8:0], Z80_MREQn };
//if (Z80_mreq_pulse) begin
gpu_addr <= Z80_addr[18:0]; // latch address bus onto GPU address bus
mem_valid_range <= (Z80_addr[18:0] < 2**MEM_SIZE_BITS); // Define GPU addressable memory space
mem_window <= (Z80_addr[21:19] == MEMORY_RANGE); // Define an active memory range
//end else if (Z80_unmreq_pulse) begin
// mem_valid_range <= 1'b0; // Define GPU addressable memory space
// mem_window <= 1'b0; // Define an active memory range
//end
Z80_write_sequencer[9:0] <= { Z80_write_sequencer[8:0], Write_GPU_RAM };
if ( Z80_write_sequencer[0] ) Z80_245data_dir <= 1'b1; // set 245 dir toward FPGA
if ( Z80_write_sequencer[0] ) Z80_rData_ena <= 1'b0; // set FPGA pins to input (should be by default)
if ( Z80_write_sequencer[0] ) Z80_245_oe <= 1'b0; // enable 245 output (WAS 1 - moved forward to step 0)
if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wdata <= Z80_wData; // latch data bus onto GPU data bus
if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wr_ena <= 1'b1; // turn on FPGA RAM we
if ( Z80_write_sequencer[DELAY_CYCLES + 2] ) gpu_wr_ena <= 1'b0; // turn off FPGA RAM we (WAS STEP +2, now STEP +3 for additional WR)
if ( Z80_write_sequencer[DELAY_CYCLES + 2] ) Z80_245_oe <= 1'b1; // disable 245 output
if ( Read_GPU_RAM_BEGIN && Z80_WRn ) begin
gpu_rd_req <= 1'b1; // flag a read request to the mux which is one-shotted in the mux
Z80_245data_dir <= 1'b0; // set 245 direction (TO Z80)
Z80_245_oe <= 1'b0; // enable 245 output
Z80_rData_ena <= 1'b1; // set bidir pins to output
end else begin
gpu_rd_req <= 1'b0; // end GPU read req after 1 pulse
if ( Z80_WRn ) begin
Z80_rData_ena <= 1'b0; // re-set bidir pins to input
Z80_245_oe <= 1'b1; // disable 245 output
end
end
if ( gpu_rd_rdy ) begin
if (mem_valid_range) Z80_rData[7:0] <= gpu_rData[7:0];// Latch the GPU RAM read into the output register for the Z80
else Z80_rData[7:0] <= 8'b11111111; // return $FF if addressed byte is outside the GPU's upper RAM limit
end
last_Z80_WR <= Z80_WRn;
last_Z80_RD <= Z80_RDn;
Z80_clk_delay <= Z80_CLK; // find the rising clock edge
end
// **********************************************************************************************************
endmodule
-
#861 Reply
Posted by
nockieboy
on 05 Jan, 2020 15:13
-
Okay, with that latest update:
DELAY_CYCLES | MREQ_DLY_CLK | RESULTS
-------------------+----------------------+----------------------------------------------------------------------
2 | 2 | Unstable. Crash on read. Write only writes $FF to GPU RAM.
2 | 1 | Unstable. Crash on read. Write only writes $FF to GPU RAM.
2 | 0 | Unstable. Crash on read. Write only writes $FF to GPU RAM.
1) When I've tried writing, I've tried values $00, $55, $AA, $01 etc. to a variety of addresses across the entire first page of GPU RAM.
2) Unstable means it's taken a couple of resets to get the Microcom's Bootstrap to show on the console. The Bootstrap does nothing to the GPU, other than a quick write/read loop through all the banks of memory to ascertain what's RAM and what's ROM. It's most likely the read part of that routine that is causing the crash when it tries to write to, then read from the GPU memory.
3) All attempts to read data manually (via the PEEK command) have resulted in a crash.
Should I start increasing the DLY values?
-
#862 Reply
Posted by
BrianHG
on 05 Jan, 2020 15:33
-
Seriously man, the read shouldn't be able to crash. The read delay is being ignored. It only delays the write capture of the Z80's data output.
Try this:
module Z80_bridge (
// input
input wire reset, // GPU reset signal
input wire GPU_CLK, // GPU clock (125 MHz)
input wire Z80_CLK, // Microcom clock signal (8 MHz)
input wire Z80_M1n, // Z80 M1 - active LOW
input wire Z80_MREQn, // Z80 MREQ - active LOW
input wire Z80_WRn, // Z80 WR - active LOW
input wire Z80_RDn, // Z80 RD - active LOW
input wire [21:0] Z80_addr, // Microcom 22-bit address bus
input wire [7:0] Z80_wData, // Z80 DATA bus to pass incoming data to GPU RAM
input wire [7:0] gpu_rData,
input wire gpu_rd_rdy, // one-shot signal from mux that data is ready
// output
output reg Z80_245data_dir, // control level converter direction for data flow - HIGH = A -> B (toward FPGA)
output reg [7:0] Z80_rData, // Z80 DATA bus to return data from GPU RAM to Z80
output reg Z80_rData_ena, // flag HIGH to write data back to Z80
output reg Z80_245_oe, // OE for 245 level translator *** ACTIVE LOW ***
output reg gpu_wr_ena, // flag HIGH for 1 clock when writing to GPU RAM
output reg gpu_rd_req, // flag HIGH for 1 clock when reading from GPU RAM
output reg [19:0] gpu_addr, // connect to Z80_addr in vid_osd_generator to address GPU RAM
output reg [7:0] gpu_wdata, // 8-bit data bus to GPU RAM in vid_osd_generator
input wire sel_pclk, // make HIGH to trigger the Z80 bus on the positive edge of Z80_CLK
input wire sel_nclk // make LOW to trigger the Z80 bus on the negative edge of Z80_CLK
);
// TODO:
//
// 1) Prevent reads to GPU RAM above top of GPU RAM
// 2) Respond with appropriate data to any requests from Microcom ROM identification routines
//
parameter MEMORY_RANGE = 3'b010; // Z80_addr[21:19] == 3'b010 targets the 512KB 'window' at 0x100000-0x17FFFF (Socket 3 on the Microcom)
parameter DELAY_CYCLES = 2; // number of cycles to delay write for 245
parameter MEM_SIZE_BITS = 15; //
parameter MREQ_DLY_CLK = 2; // number of cycles +1 to delay mreq trigger
wire Z80_mreq, Z80_mreq_pulse, Z80_unmreq_pulse, Z80_write, Z80_read, Write_GPU_RAM;
wire Read_GPU_RAM_BEGIN, Read_GPU_RAM_END;
wire Z80_clk_pos,Z80_clk_neg,Z80_clk_trig;
reg Z80_clk_delay, last_Z80_WR, last_Z80_RD, mem_valid_range, MREQn_dly, MREQn_dly2, mem_window ;
reg [9:0] Z80_write_sequencer,Z80_mreq_dly;
assign Z80_clk_pos = ~Z80_clk_delay && Z80_CLK;
assign Z80_clk_neg = Z80_clk_delay && ~Z80_CLK;
assign Z80_clk_trig = (Z80_clk_pos && sel_pclk) || (Z80_clk_neg && ~sel_nclk);
assign Z80_mreq = ~Z80_MREQn && Z80_M1n; // Define a bus memory access state
assign Z80_write = ~Z80_WRn && last_Z80_WR; // Isolate a single write transaction
assign Z80_read = ~Z80_RDn; // Isolate a single read transaction
assign Z80_readn = Z80_RDn && ~last_Z80_RD; // Isolate a single read transaction
assign Write_GPU_RAM = mem_window && Z80_mreq && Z80_write && mem_valid_range; // Define a GPU Write action - only write to address within GPU RAM bounds
assign Read_GPU_RAM_BEGIN = mem_window && Z80_mreq && Z80_read && mem_valid_range; // Define the beginning of a Z80 read request of GPU Ram.
// **********************************************************************************************************
always @ (posedge GPU_CLK) begin
Z80_mreq_dly[9:0] <= { Z80_mreq_dly[8:0], Z80_MREQn };
//if (Z80_mreq_pulse) begin
gpu_addr <= Z80_addr[18:0]; // latch address bus onto GPU address bus
mem_valid_range <= (Z80_addr[18:0] < 2**MEM_SIZE_BITS); // Define GPU addressable memory space
mem_window <= (Z80_addr[21:19] == MEMORY_RANGE); // Define an active memory range
//end else if (Z80_unmreq_pulse) begin
// mem_valid_range <= 1'b0; // Define GPU addressable memory space
// mem_window <= 1'b0; // Define an active memory range
//end
Z80_write_sequencer[9:0] <= { Z80_write_sequencer[8:0], Write_GPU_RAM };
if ( Z80_write_sequencer[0] ) Z80_245data_dir <= 1'b1; // set 245 dir toward FPGA
if ( Z80_write_sequencer[0] ) Z80_rData_ena <= 1'b0; // set FPGA pins to input (should be by default)
if ( Z80_write_sequencer[0] ) Z80_245_oe <= 1'b0; // enable 245 output (WAS 1 - moved forward to step 0)
if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wdata <= Z80_wData; // latch data bus onto GPU data bus
if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wr_ena <= 1'b1; // turn on FPGA RAM we
if ( Z80_write_sequencer[DELAY_CYCLES + 1] ) gpu_wr_ena <= 1'b0; // turn off FPGA RAM we (WAS STEP +2, now STEP +3 for additional WR)
if ( Read_GPU_RAM_BEGIN ) begin
gpu_rd_req <= 1'b1; // flag a read request to the mux which is one-shotted in the mux
Z80_245data_dir <= 1'b0; // set 245 direction (TO Z80)
Z80_245_oe <= 1'b0; // enable 245 output
Z80_rData_ena <= 1'b1; // set bidir pins to output
end else begin
gpu_rd_req <= 1'b0; // end GPU read req after 1 pulse
Z80_245data_dir <= 1'b1; // set 245 dir toward FPGA
Z80_rData_ena <= 1'b0; // re-set bidir pins to input
if ( Z80_WRn ) begin
//Z80_245_oe <= 1'b1; // disable 245 output
end
end
if ( gpu_rd_rdy ) begin
if (mem_valid_range) Z80_rData[7:0] <= gpu_rData[7:0];// Latch the GPU RAM read into the output register for the Z80
else Z80_rData[7:0] <= 8'b11111111; // return $FF if addressed byte is outside the GPU's upper RAM limit
end
last_Z80_WR <= Z80_WRn;
last_Z80_RD <= Z80_RDn;
Z80_clk_delay <= Z80_CLK; // find the rising clock edge
end
// **********************************************************************************************************
endmodule
If this one still crashes on read, something went haywire with your wiring changes, or new IO pin assignments, or breadboard wiring contacts.
When single writing, make sure the written 'FF' appear in the correct address. It would seem your are not outputting the 245 to the GPU FPGA. This may mean controls to the 245, or it's VCC/GND isn't wired good.
-
#863 Reply
Posted by
nockieboy
on 05 Jan, 2020 15:59
-
Seriously man, the read shouldn't be able to crash. The read delay is being ignored. It only delays the write capture of the Z80's data output.
Try this:
...
If this one still crashes on read, something went haywire with your wiring changes, or new IO pin assignments, or breadboard wiring contacts.
When single writing, make sure the written 'FF' appear in the correct address. It would seem your are not outputting the 245 to the GPU FPGA. This may mean controls to the 245, or it's VCC/GND isn't wired good.
I know, it's weird. I've had this a lot during development, though, so I almost figure it's normal for electronics development.. I take it that it isn't.

It's likely a loose connection somewhere, which frustrates me even more.
Well, that last update has certainly done
something.
Writing to GPU RAM is now a little hit and miss - sometimes characters are dropped for null ($00) values, but infrequently. I can
almost get the DMI boot screen to display, but because of the write errors the Microcom isn't setting up the display properly. If I load the default values using the RS232_debugger, I can see what I'm writing on the screen (but with the odd dropped character as mentioned previously).
Reading values appears to be solid - even if I 'dump' the entire first page of the GPU RAM to the console/screen, it's reading it accurately.
Here's the settings I'm using for this build:
DELAY_CYCLES 2
MREQ_DLY_CLK 0
-
#864 Reply
Posted by
BrianHG
on 05 Jan, 2020 16:04
-
Increase the delay cycles to 4 or 6 or 8 or 10 or 12.
You may have to increase the delay register size and it's shift register values...
-
#865 Reply
Posted by
nockieboy
on 05 Jan, 2020 16:16
-
Increase the delay cycles to 4 or 6 or 8 or 10 or 12.
You may have to increase the delay register size and it's shift register values...
Will do - not changing MREQ_DLY_CLK at all, right?
-
#866 Reply
Posted by
BrianHG
on 05 Jan, 2020 16:17
-
Increase the delay cycles to 4 or 6 or 8 or 10 or 12.
You may have to increase the delay register size and it's shift register values...
Will do - not changing MREQ_DLY_CLK at all, right?
Its no longer being used...
-
#867 Reply
Posted by
nockieboy
on 05 Jan, 2020 16:23
-
Will do - not changing MREQ_DLY_CLK at all, right?
Its no longer being used...
Aha, okay - removed it from the parameter block then. Just tried with DELAY_CYCLES set to 4 - still dropping chars, but noticed that the screen actually shifted up a couple of lines when I got to the bottom, with minimal corruption, so it seems we're going in the right direction..
-
#868 Reply
Posted by
BrianHG
on 05 Jan, 2020 16:31
-
Go to a delay of 8.
-
#869 Reply
Posted by
BrianHG
on 05 Jan, 2020 17:15
-
This version is fully static, the delays are ignored...
module Z80_bridge (
// input
input wire reset, // GPU reset signal
input wire GPU_CLK, // GPU clock (125 MHz)
input wire Z80_CLK, // Microcom clock signal (8 MHz)
input wire Z80_M1n, // Z80 M1 - active LOW
input wire Z80_MREQn, // Z80 MREQ - active LOW
input wire Z80_WRn, // Z80 WR - active LOW
input wire Z80_RDn, // Z80 RD - active LOW
input wire [21:0] Z80_addr, // Microcom 22-bit address bus
input wire [7:0] Z80_wData, // Z80 DATA bus to pass incoming data to GPU RAM
input wire [7:0] gpu_rData,
input wire gpu_rd_rdy, // one-shot signal from mux that data is ready
// output
output reg Z80_245data_dir, // control level converter direction for data flow - HIGH = A -> B (toward FPGA)
output reg [7:0] Z80_rData, // Z80 DATA bus to return data from GPU RAM to Z80
output reg Z80_rData_ena, // flag HIGH to write data back to Z80
output reg Z80_245_oe, // OE for 245 level translator *** ACTIVE LOW ***
output reg gpu_wr_ena, // flag HIGH for 1 clock when writing to GPU RAM
output reg gpu_rd_req, // flag HIGH for 1 clock when reading from GPU RAM
output reg [19:0] gpu_addr, // connect to Z80_addr in vid_osd_generator to address GPU RAM
output reg [7:0] gpu_wdata, // 8-bit data bus to GPU RAM in vid_osd_generator
input wire sel_pclk, // make HIGH to trigger the Z80 bus on the positive edge of Z80_CLK
input wire sel_nclk // make LOW to trigger the Z80 bus on the negative edge of Z80_CLK
);
// TODO:
//
// 1) Prevent reads to GPU RAM above top of GPU RAM
// 2) Respond with appropriate data to any requests from Microcom ROM identification routines
//
parameter MEMORY_RANGE = 3'b010; // Z80_addr[21:19] == 3'b010 targets the 512KB 'window' at 0x100000-0x17FFFF (Socket 3 on the Microcom)
parameter DELAY_CYCLES = 2; // number of cycles to delay write for 245
parameter MEM_SIZE_BITS = 15; //
parameter MREQ_DLY_CLK = 2; // number of cycles +1 to delay mreq trigger
wire Z80_mreq, Z80_mreq_pulse, Z80_unmreq_pulse, Z80_write, Z80_read, Write_GPU_RAM;
wire Read_GPU_RAM_BEGIN, Read_GPU_RAM_END;
wire Z80_clk_pos,Z80_clk_neg,Z80_clk_trig;
reg Z80_clk_delay, last_Z80_WR, last_Z80_RD, mem_valid_range, MREQn_dly, MREQn_dly2, mem_window ;
reg [9:0] Z80_write_sequencer,Z80_mreq_dly;
assign Z80_clk_pos = ~Z80_clk_delay && Z80_CLK;
assign Z80_clk_neg = Z80_clk_delay && ~Z80_CLK;
assign Z80_clk_trig = (Z80_clk_pos && sel_pclk) || (Z80_clk_neg && ~sel_nclk);
assign Z80_mreq = ~Z80_MREQn && Z80_M1n; // Define a bus memory access state
assign Z80_write = ~Z80_WRn ; // && last_Z80_WR; // Isolate a single write transaction
assign Z80_read = ~Z80_RDn; // Isolate a single read transaction
assign Z80_readn = Z80_RDn && ~last_Z80_RD; // Isolate a single read transaction
assign Write_GPU_RAM = mem_window && Z80_mreq && Z80_write && mem_valid_range; // Define a GPU Write action - only write to address within GPU RAM bounds
assign Read_GPU_RAM_BEGIN = mem_window && Z80_mreq && Z80_read && mem_valid_range; // Define the beginning of a Z80 read request of GPU Ram.
// **********************************************************************************************************
always @ (posedge GPU_CLK) begin
Z80_mreq_dly[9:0] <= { Z80_mreq_dly[8:0], Z80_MREQn };
//if (Z80_mreq_pulse) begin
gpu_addr <= Z80_addr[18:0]; // latch address bus onto GPU address bus
mem_valid_range <= (Z80_addr[18:0] < 2**MEM_SIZE_BITS); // Define GPU addressable memory space
mem_window <= (Z80_addr[21:19] == MEMORY_RANGE); // Define an active memory range
//end else if (Z80_unmreq_pulse) begin
// mem_valid_range <= 1'b0; // Define GPU addressable memory space
// mem_window <= 1'b0; // Define an active memory range
//end
// Z80_write_sequencer[9:0] <= { Z80_write_sequencer[8:0], Write_GPU_RAM };
// if ( Z80_write_sequencer[0] ) Z80_245data_dir <= 1'b1; // set 245 dir toward FPGA
// if ( Z80_write_sequencer[0] ) Z80_rData_ena <= 1'b0; // set FPGA pins to input (should be by default)
// if ( Z80_write_sequencer[0] ) Z80_245_oe <= 1'b0; // enable 245 output (WAS 1 - moved forward to step 0)
// if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wdata <= Z80_wData; // latch data bus onto GPU data bus
// if ( Z80_write_sequencer[DELAY_CYCLES] ) gpu_wr_ena <= 1'b1; // turn on FPGA RAM we
// if ( Z80_write_sequencer[DELAY_CYCLES + 1] ) gpu_wr_ena <= 1'b0; // turn off FPGA RAM we (WAS STEP +2, now STEP +3 for additional WR)
if ( Write_GPU_RAM ) begin
Z80_245data_dir <= 1'b1; // set 245 dir toward FPGA
Z80_rData_ena <= 1'b0; // set FPGA pins to input (should be by default)
Z80_245_oe <= 1'b0; // enable 245 output (WAS 1 - moved forward to step 0)
gpu_wdata <= Z80_wData; // latch data bus onto GPU data bus
gpu_wr_ena <= 1'b1; // turn on FPGA RAM we
end else begin
gpu_wr_ena <= 1'b0; // turn off FPGA RAM we
end
if ( Read_GPU_RAM_BEGIN ) begin
gpu_rd_req <= 1'b1; // flag a read request to the mux which is one-shotted in the mux
Z80_245data_dir <= 1'b0; // set 245 direction (TO Z80)
Z80_245_oe <= 1'b0; // enable 245 output
Z80_rData_ena <= 1'b1; // set bidir pins to output
end else begin
gpu_rd_req <= 1'b0; // end GPU read req after 1 pulse
Z80_245data_dir <= 1'b1; // set 245 dir toward FPGA
Z80_rData_ena <= 1'b0; // re-set bidir pins to input
if ( Z80_WRn ) begin
//Z80_245_oe <= 1'b1; // disable 245 output
end
end
if ( gpu_rd_rdy ) begin
if (mem_valid_range) Z80_rData[7:0] <= gpu_rData[7:0];// Latch the GPU RAM read into the output register for the Z80
else Z80_rData[7:0] <= 8'b11111111; // return $FF if addressed byte is outside the GPU's upper RAM limit
end
last_Z80_WR <= Z80_WRn;
last_Z80_RD <= Z80_RDn;
Z80_clk_delay <= Z80_CLK; // find the rising clock edge
end
// **********************************************************************************************************
endmodule
If this works, first I'll need to do a cleanup, then we'll decide what to do next...
-
#870 Reply
Posted by
nockieboy
on 05 Jan, 2020 18:37
-
If this works, first I'll need to do a cleanup, then we'll decide what to do next...
Oh boy does it work... CLS is clearing the screen nicely now and screen scrolling is working great with no artefacts at all...

-
#871 Reply
Posted by
BrianHG
on 06 Jan, 2020 00:01
-
I need a copy of your current project.
-
#872 Reply
Posted by
nockieboy
on 06 Jan, 2020 08:19
-
I need a copy of your current project.
Oops...

Here it is.
-
#873 Reply
Posted by
BrianHG
on 06 Jan, 2020 11:29
-
Ok, here you go.
I cleaned up the project. I had to also patch the MUX algorithm.
First, try the complete cleaned project 'GPU_Z80_bridge_staticIO.zip'.
If everything is ok, then switch the Z80_Bridge.v to the attached 'Z80_bridge_1-write.v'. This version only does 1 single write to the GPU ram once at the end of every write cycle instead of 62.5 million writes / second during the entire time the Z80_WRn signal is low with a valid address.
Only if the 1-write version works, next switch to the 'Z80_bridge_1-read.v', 1 read / cycle version. This version will send out a single read_req to the GPU ram at the beginning of the read cycle, latch the result and hold it on the output while the Z80_RDn is low instead of the static version which does a continuous 62.5 million reads / second during the entire time the Z80_RDn is low.
If the 1 read version works, then you have a good Z80 bridge interface which will eat practically no clock cycles from the GPU ram as a read and write to and from GPU ram will only come around once every 6 or more 8 MHz clock cycles.
In the future, it may be possible to enhance the MUX.v to better select the source A/B - READ/WRITE ports based on priority, but for now, it basically does a dumb 1 clk A, 1 clk B cycle.
-
#874 Reply
Posted by
nockieboy
on 06 Jan, 2020 12:55
-
Ok, here you go.
I cleaned up the project. I had to also patch the MUX algorithm.
First, try the complete cleaned project 'GPU_Z80_bridge_staticIO.zip'.
If everything is ok, then switch the Z80_Bridge.v to the attached 'Z80_bridge_1-write.v'. This version only does 1 single write to the GPU ram once at the end of every write cycle instead of 62.5 million writes / second during the entire time the Z80_WRn signal is low with a valid address.
Only if the 1-write version works, next switch to the 'Z80_bridge_1-read.v', 1 read / cycle version. This version will send out a single read_req to the GPU ram at the beginning of the read cycle, latch the result and hold it on the output while the Z80_RDn is low instead of the static version which does a continuous 62.5 million reads / second during the entire time the Z80_RDn is low.
If the 1 read version works, then you have a good Z80 bridge interface which will eat practically no clock cycles from the GPU ram as a read and write to and from GPU ram will only come around once every 6 or more 8 MHz clock cycles.
In the future, it may be possible to enhance the MUX.v to better select the source A/B - READ/WRITE ports based on priority, but for now, it basically does a dumb 1 clk A, 1 clk B cycle.
I seem to be fighting with a little instability today with one (or several) of the connections (which I've confirmed with the previous stable version of the project, it's not specific to the new project and Z80_bridge versions), but that aside, the new updates seems to be working very nicely.
EDIT: No - hang on.. more testing required.