mirror of
https://github.com/grumpycoders/pcsx-redux.git
synced 2025-04-02 10:41:54 -04:00
324 lines
8.5 KiB
Verilog
324 lines
8.5 KiB
Verilog
module piodev3(
|
|
// The address lines we have connected.
|
|
input A0,
|
|
input A1,
|
|
input A2,
|
|
input A3,
|
|
input A4,
|
|
input A16,
|
|
input A17,
|
|
input A18,
|
|
input A19,
|
|
input A20,
|
|
input A21,
|
|
input A22,
|
|
|
|
// The internal data bus, that connects to all of our parts on the board.
|
|
inout [0:7] D,
|
|
|
|
// The PIO's !WR and !RD pins.
|
|
input nWR,
|
|
input nRD,
|
|
|
|
// The CS pin of the SRAM.
|
|
output nCS_SRAM,
|
|
|
|
// The !OE pin of the switch's latch.
|
|
output nCS_SWITCH,
|
|
|
|
// Our 12Mhz clock.
|
|
input CLK,
|
|
|
|
// A20 and CS pins for the onboard flash, and zif socket.
|
|
output A20_FLASH,
|
|
output nCS_FLASH,
|
|
output A20_SOCKET,
|
|
output nCS_SOCKET,
|
|
|
|
// Two hardware jumpers, pulled up. Grounded on version 3.0 of the board.
|
|
// Version 3.1 has the actual jumpers traces.
|
|
input JP1,
|
|
input JP2,
|
|
|
|
// The CH375's CS pin.
|
|
output nCS_CH,
|
|
|
|
// The CH375's interrupt line.
|
|
input nIN_CH,
|
|
|
|
// The LE pin of the LED's latch.
|
|
output CS_LEDS,
|
|
|
|
// Our momentary soft button, pulled up.
|
|
input SOFT,
|
|
|
|
// The FT2232H's !CS, A0, and !RESET lines. The !RESET line is
|
|
// pulled down by default, and goes up when a usb cable is
|
|
// connected to the computer, providing 5v.
|
|
output nCS_PORTB,
|
|
output A0_PORTA,
|
|
output nCS_PORTA,
|
|
inout nRESET_FT,
|
|
|
|
// The 10 optional GPIO pins on top of the CPLD.
|
|
inout [1:10] GPIO,
|
|
|
|
// The additional pins from the PIO.
|
|
inout DACK,
|
|
input nWR2,
|
|
inout DREQ,
|
|
|
|
// The two small dip switches near the CPLD.
|
|
input SW1,
|
|
input SW2,
|
|
|
|
// The A20 pin of the SRAM.
|
|
output A20_SRAM,
|
|
|
|
// The interrupt line of the PIO port.
|
|
output nIN10,
|
|
|
|
// The Switch Board enable pin, to redirect the CS2 line.
|
|
// If the line 5 of the PIO port hasn't been cut, this will
|
|
// make the CPLD burn 3.3v through ground. There is a 200ohm
|
|
// resistor to prevent damage.
|
|
output SBEN,
|
|
|
|
// !CS0 and !CS2 from the PIO. The !CS2 line will only work if
|
|
// the Switch Board has been installed, SBEN is high, and the
|
|
// line 39 of the PIO port has been cut and redirected to the
|
|
// Switch Board properly.
|
|
//
|
|
// By default, !CS0 will be active when reading from the
|
|
// 0x1f000000 memory range, and !CS2 will be active when reading
|
|
// from the 0xbfc00000 memory range.
|
|
input nCS0,
|
|
input nCS2,
|
|
|
|
// The PIO's data line. It isn't connected on any other device on
|
|
// the PCB, leaving it up to the CPLD to latch it.
|
|
inout [0:7] PD,
|
|
|
|
// The PSX's !RESET line. Will go high after ~300ms after power up,
|
|
// as long as the reset controller chips are still there on the PSU.
|
|
// Can be used to cause the PSX to reset, by asserting this line low.
|
|
inout nRESET
|
|
);
|
|
|
|
// --------------------------------
|
|
|
|
// Some helpers. Should be easily optimized away by the compiler.
|
|
|
|
wire [23:0] A = {
|
|
1'b0, A22, A21, A20,
|
|
A19, A18, A17, A16,
|
|
1'b0, 1'b0, 1'b0, 1'b0,
|
|
1'b0, 1'b0, 1'b0, 1'b0,
|
|
1'b0, 1'b0, 1'b0, 1'b0,
|
|
1'b0, 1'b0, 1'b0, A4,
|
|
A3, A2, A1, A0
|
|
};
|
|
|
|
wire WR = ~nWR;
|
|
wire RD = ~nRD;
|
|
wire IN_CH = ~nIN_CH;
|
|
wire CS0 = ~nCS0;
|
|
wire CS2 = ~nCS2;
|
|
|
|
// Defaults for all of the outputs.
|
|
//assign nCS_SRAM = 1'b1;
|
|
//assign nCS_SWITCH = 1'b1;
|
|
//assign CS_LEDS = 1'b0;
|
|
//assign A20_FLASH = 1'b0;
|
|
//assign nCS_FLASH = 1'b1;
|
|
//assign A20_SOCKET = 1'b0;
|
|
//assign nCS_SOCKET = 1'b1;
|
|
|
|
//assign nCS_CH = 1'b1;
|
|
|
|
//assign nCS_PORTB = 1'b1;
|
|
//assign A0_PORTA = 1'b0;
|
|
//assign nCS_PORTA = 1'b1;
|
|
|
|
assign nRESET_FT = 1'bz;
|
|
|
|
assign GPIO = 10'bzzzzzzzzzz;
|
|
|
|
assign DACK = 1'bz;
|
|
assign DREQ = 1'bz;
|
|
|
|
//assign A20_SRAM = 1'b0;
|
|
assign nIN_10 = 1'b1;
|
|
|
|
//assign SBEN = 1'b0;
|
|
|
|
//assign PD = 8'bzzzzzzzz;
|
|
//assign D = 8'bzzzzzzzz;
|
|
assign nRESET = 1'bz;
|
|
|
|
// --------------------------------
|
|
|
|
// Quick diagnostics code. Will make LEDs blink,
|
|
// according to the clock by default, and according to
|
|
// the dip switches when the soft button is pressed.
|
|
//
|
|
// Tests if the dip switches, the LEDs, the latches and the clock
|
|
// are properly wired and working correctly.
|
|
|
|
/*
|
|
assign CS_LEDS = 1'b1;
|
|
assign nCS_SWITCH = SOFT;
|
|
|
|
reg [31:0] cnt = 0;
|
|
always @(posedge CLK) cnt <= cnt + 1;
|
|
|
|
assign D = SOFT ? ~cnt[27:20] : 8'bzzzzzzzz;
|
|
*/
|
|
|
|
// --------------------------------
|
|
|
|
// Passthrough from CS0 to the FT2232H's port A (recovery)
|
|
|
|
/*
|
|
assign nCS_PORTA = nCS0;
|
|
assign A0_PORTA = 1'b0;
|
|
assign PD = RD && CS0 ? D : 8'bzzzzzzzz;
|
|
*/
|
|
|
|
// --------------------------------
|
|
|
|
// Passthrough from CS0 to the socket flash (caetla)
|
|
|
|
/*
|
|
assign nCS_SOCKET = nCS0;
|
|
assign A20_SOCKET = 1'b0;
|
|
assign PD = RD && CS0 ? D : 8'bzzzzzzzz;
|
|
*/
|
|
|
|
// --------------------------------
|
|
|
|
// Passthrough from CS2 to the socket flash (bios)
|
|
|
|
/*
|
|
assign nCS_SOCKET = nCS2;
|
|
assign A20_SOCKET = 1'b0;
|
|
assign PD = RD && CS2 ? D : 8'bzzzzzzzz;
|
|
assign SBEN = 1'b1;
|
|
*/
|
|
|
|
// --------------------------------
|
|
|
|
// Main behavior description of the PIO board
|
|
|
|
reg [7:0] bufferOut = 8'b00000000;
|
|
reg [7:0] bufferIn = 8'b00000000;
|
|
reg activateOutput = 0;
|
|
reg [7:0] bits = 8'b00000000;
|
|
|
|
// Helper for making sure CS isn't strobing.
|
|
wire strobe = WR || RD;
|
|
|
|
// Our mappings.
|
|
|
|
// Flash1 runs from 0x000000 to 0x1fffff, so check address bits A21 and A22,
|
|
// and ignore everything else.
|
|
assign nCS_FLASH = !(strobe && CS0 && !A22 && !A21);
|
|
// Flash2 runs from 0x200000 to 0x3fffff, so check address bits A21 and A22,
|
|
// and ignore everything else. It's also used to mirror the BIOS, so toggle
|
|
// it for any CS2 read.
|
|
assign nCS_SOCKET = !(strobe && CS2 || CS0 && !A22 && A21);
|
|
// SRAM runs from 0x400000 to 0x5fffff, so check address bits A21 and A22,
|
|
// and ignore everything else.
|
|
assign nCS_SRAM = !(strobe && CS0 && A22 && !A21);
|
|
// While all of the above are full-length mappings, the next ones are one
|
|
// or two bytes larges, therefore we need to check more address bits.
|
|
// We technically have more address bits than that tied to the CPLD, but
|
|
// for now, that's all we need to distinguish. If we need to add more
|
|
// addresses to watch for, then we'll have to add more address bits to
|
|
// these checks.
|
|
// FT2232H's port A runs from 0x600000 to 0x600001.
|
|
assign nCS_PORTA = !(strobe && CS0 && A22 && A21 && !A2 && !A1);
|
|
// FT2232H's port B runs from 0x600002 to 0x600003.
|
|
assign nCS_PORTB = !(strobe && CS0 && A22 && A21 && !A2 && A1);
|
|
// CH375B's runs from 0x600004 to 0x600005.
|
|
assign nCS_CH = !(strobe && CS0 && A22 && A21 && A2 && !A1);
|
|
// Switches and leds are at 0x600006. Writing to this address means
|
|
// assigning some value to the LEDs. Reading this address means
|
|
// reading the dip switch values.
|
|
assign nCS_SWITCH = !(strobe && CS0 && A22 && A21 && A2 && A1 && !A0 && RD);
|
|
assign CS_LEDS = (strobe && CS0 && A22 && A21 && A2 && A1 && !A0 && WR);
|
|
// Configuration bits are at 0x600007.
|
|
wire internalData = strobe && A22 && A21 && A2 && A1 && A0;
|
|
|
|
|
|
// We need to pay attention for CS0 and CS2.
|
|
// Note that CS2 is on a grounded line of the PIO by default.
|
|
// If not cut, this will always be active.
|
|
wire CS = CS0 || CS2;
|
|
|
|
// When the CPU is writing, the PIO's data port needs to be an input.
|
|
assign PD = WR ? 8'bzzzzzzzz :
|
|
// Otherwise, if we're currently being read, pass through the data bus
|
|
// to the PIO data bus.
|
|
(CS && RD ? (internalData ? bits : D) :
|
|
// RD goes up before CS usually. When that's the case, try to sustain
|
|
// the sampled value of the data bus.
|
|
(CS && activateOutput ? bufferOut :
|
|
// By default, in any other case, present a high-Z bus to the PIO.
|
|
8'bzzzzzzzz));
|
|
|
|
// When the CPU is writing, just be a pass through from the CPU to
|
|
// our data bus.
|
|
assign D = WR ? PD :
|
|
// Othewise, when the CPU is reading from us, we need to be an input
|
|
// for the devices on our data bus.
|
|
(CS && RD ? 8'bzzzzzzzz :
|
|
// In all other cases, mirror on the data bus the last sampled value
|
|
// from the CPU. This last case covers the moment when WR goes up before
|
|
// CS, giving time to the devices on our data bus to sample it properly.
|
|
bufferIn);
|
|
|
|
// For now, no special paging.
|
|
assign A20_FLASH = A20;
|
|
assign A20_SOCKET = A20;
|
|
assign A20_SRAM = A20;
|
|
|
|
// Disable real BIOS chip.
|
|
assign SBEN = 1'b1;
|
|
|
|
// For now, no special meaning for port A's A0.
|
|
// Might be useful for recovery mode later on.
|
|
assign A0_PORTA = A0;
|
|
|
|
// When RD goes up, sample the devices on our data bus.
|
|
always @(posedge nRD) begin
|
|
bufferOut <= internalData ? bits : D;
|
|
end
|
|
|
|
// When WR goes up, sample the PIO's data bus.
|
|
always @(posedge nWR) begin
|
|
bufferIn <= PD;
|
|
end
|
|
|
|
// Our internal configuration bits' special needs.
|
|
always @(posedge nWR or posedge nRESET) begin
|
|
if (nRESET) begin
|
|
bits <= 8'b00000000;
|
|
end else if (internalData) begin
|
|
bits <= PD;
|
|
end
|
|
end
|
|
|
|
// Sample our boolean telling us if we need to emit data on the
|
|
// PIO port when RD goes low.
|
|
always @(negedge nRD) begin
|
|
activateOutput <= CS;
|
|
end
|
|
|
|
assign GPIO[1] = nCS_PORTB;
|
|
assign GPIO[2] = nCS_CH;
|
|
assign GPIO[3] = nCS_SRAM;
|
|
assign GPIO[4] = nCS_FLASH;
|
|
assign GPIO[5] = nCS_PORTA;
|
|
|
|
endmodule
|