
// Decoding and strobing of z80 signals

module zsignals
(
	// clocks
	input wire clk,

	// z80 interface input
	input wire iorq_n,
	input wire mreq_n,
	input wire m1_n,
	input wire rfsh_n,
	input wire rd_n,
	input wire wr_n,

	// Z80 signals
	output wire m1,
	output wire rfsh,
	output wire rd,
	output wire wr,
	output wire iorq,
	output wire mreq,
	output wire rdwr,
	output wire iord,
	output wire iowr,
	output wire iorw,
	output wire memrd,
	output wire memwr,
	output wire memrw,
	output wire opfetch,
	output wire intack,

	// Z80 signals strobes, at fclk
	output wire iorq_s,
	output wire mreq_s,
	output wire iord_s,
	output wire iowr_s,
	output wire iorw_s,
	output wire memrd_s,
	output wire memwr_s,
	output wire memrw_s,
	output wire opfetch_s
);

// invertors
assign m1 = !m1_n;
assign rfsh = !rfsh_n;
assign rd = !rd_n;
assign wr = !wr_n;

// requests
assign iorq = !iorq_n && m1_n;       // this is masked by ~M1 to avoid port decoding on INT ack
assign mreq = !mreq_n && rfsh_n;     // this is masked by ~RFSH to ignore refresh cycles as memory requests

// combined
assign rdwr = rd || wr;
assign iord = iorq && rd;
assign iowr = iorq && wr;
assign iorw = iorq && rdwr;
assign memrd = mreq && rd;
assign memwr = mreq && !rd;
assign memrw = mreq && rdwr;
assign opfetch = memrd && m1;
assign intack = !iorq_n && m1;		// NOT masked by M1

// strobed
assign iorq_s = iorq_r[0] && !iorq_r[1];
assign mreq_s = mreq_r[0] && !mreq_r[1];
assign iord_s = iorq_s && rd;
assign iowr_s = iorq_s && wr;
assign iorw_s = iorq_s && rdwr;
assign memrd_s = mreq_s && rd;
assign memwr_s = mreq_s && !rd;
assign memrw_s = mreq_s && rdwr;
assign opfetch_s = memrd_s && m1;

// latch inputs on FPGA clock
reg [1:0] iorq_r, mreq_r;
always @(posedge clk) begin
	iorq_r <= {iorq_r[0], iorq};
	mreq_r <= {mreq_r[0], mreq};
end

endmodule
