mirror of
https://github.com/MiSTer-devel/Arcade-Dcon_MiSTer.git
synced 2026-06-07 03:01:51 +00:00
D-Con (Success, 1992) — FPGA core for the MiSTer FPGA platform (Terasic DE10-Nano). Reimplements the original Seibu hardware in SystemVerilog from MAME (seibu/dcon.cpp, seibu/seibu_crtc.cpp), hardware documentation, main 68000 ROM disassembly and observation of real PCB behavior. Hardware emulated: - M68000 main CPU @ 10 MHz (FX68K cycle-accurate) - Z80 sound CPU @ 4 MHz (T80s) with audio-rate multicycle SDC - YM3812 OPL2 FM (jtopl2) + OKI M6295 ADPCM (jt6295) - 320x224 active video area (Seibu D-Con timings) - BG / MG / FG tilemaps + Text layer + 16x16 sprites (SEI0211) - Seibu CRTC registers (scroll, layer enable, flip screen) - xBGR_555 palette, 2048 entries Includes: - 16 SystemVerilog RTL files in rtl/DCon/ - FX68K core (rtl/fx68k/), audio cores (rtl/sound/jtopl, jt6295, t80) - JTFRAME framework subset (rtl/jtframe/), Sorgelig SDRAM bridge - MiSTer sys/ framework (HPS_IO, OSD, video scaler, audio) - Pause overlay with logo, supporters list and patron scroll - Quartus project files (DCon.qpf/qsf/sdc) - Prebuilt RBF (releases/DCon_20260530.rbf) and parent MRA - 6 in-game screenshots in docs/ Licensed under GNU GPL v3 or later. ROMs not included.
104 lines
2.1 KiB
Verilog
104 lines
2.1 KiB
Verilog
|
|
module i2c
|
|
(
|
|
input CLK,
|
|
|
|
input START,
|
|
input READ,
|
|
input [6:0] I2C_ADDR,
|
|
input I2C_WLEN, // 0 - one byte, 1 - two bytes
|
|
input [7:0] I2C_WDATA1,
|
|
input [7:0] I2C_WDATA2,
|
|
output [7:0] I2C_RDATA,
|
|
output reg END = 1,
|
|
output reg ACK = 0,
|
|
|
|
//I2C bus
|
|
output I2C_SCL,
|
|
inout I2C_SDA
|
|
);
|
|
|
|
|
|
// Clock Setting
|
|
parameter CLK_Freq = 50_000_000; // 50 MHz
|
|
parameter I2C_Freq = 400_000; // 400 KHz
|
|
|
|
localparam I2C_FreqX2 = I2C_Freq*2;
|
|
|
|
reg I2C_CLOCK;
|
|
reg [31:0] cnt;
|
|
wire [31:0] cnt_next = cnt + I2C_FreqX2;
|
|
|
|
always @(posedge CLK) begin
|
|
cnt <= cnt_next;
|
|
if(cnt_next >= CLK_Freq) begin
|
|
cnt <= cnt_next - CLK_Freq;
|
|
I2C_CLOCK <= ~I2C_CLOCK;
|
|
end
|
|
end
|
|
|
|
assign I2C_SCL = (SCLK | I2C_CLOCK) ? 1'bZ : 1'b0;
|
|
assign I2C_SDA = SDO[3] ? 1'bz : 1'b0;
|
|
|
|
reg SCLK;
|
|
reg [3:0] SDO;
|
|
reg [0:7] rdata;
|
|
|
|
reg [5:0] SD_COUNTER;
|
|
reg [0:31] SD;
|
|
|
|
initial begin
|
|
SD_COUNTER = 'b111111;
|
|
SD = 'hFFFF;
|
|
SCLK = 1;
|
|
SDO = 4'b1111;
|
|
end
|
|
|
|
assign I2C_RDATA = rdata;
|
|
|
|
always @(posedge CLK) begin
|
|
reg old_clk;
|
|
reg old_st;
|
|
reg rd,len;
|
|
|
|
old_clk <= I2C_CLOCK;
|
|
old_st <= START;
|
|
|
|
// delay to make sure SDA changed while SCL is stabilized at low
|
|
if(old_clk && ~I2C_CLOCK && ~SD_COUNTER[5]) SDO[0] <= SD[SD_COUNTER[4:0]];
|
|
SDO[3:1] <= SDO[2:0];
|
|
|
|
if(~old_st && START) begin
|
|
SCLK <= 1;
|
|
SDO <= 4'b1111;
|
|
ACK <= 0;
|
|
END <= 0;
|
|
rd <= READ;
|
|
len <= I2C_WLEN;
|
|
if(READ) SD <= {2'b10, I2C_ADDR, 1'b1, 1'b1, 8'b11111111, 1'b1, 3'b011, 9'b111111111};
|
|
else SD <= {2'b10, I2C_ADDR, 1'b0, 1'b1, I2C_WDATA1, 1'b1, I2C_WDATA2, 4'b1011};
|
|
SD_COUNTER <= 0;
|
|
end else begin
|
|
if(~old_clk && I2C_CLOCK && ~&SD_COUNTER) begin
|
|
SD_COUNTER <= SD_COUNTER + 6'd1;
|
|
case(SD_COUNTER)
|
|
01: SCLK <= 0;
|
|
10: ACK <= ACK | I2C_SDA;
|
|
19: if(~rd) begin
|
|
ACK <= ACK | I2C_SDA;
|
|
if(~len) SD_COUNTER <= 29;
|
|
end
|
|
20: if(rd) SCLK <= 1;
|
|
23: if(rd) END <= 1;
|
|
28: if(~rd) ACK <= ACK | I2C_SDA;
|
|
29: if(~rd) SCLK <= 1;
|
|
32: if(~rd) END <= 1;
|
|
endcase
|
|
|
|
if(SD_COUNTER >= 11 && SD_COUNTER <= 18) rdata[SD_COUNTER[4:0]-11] <= I2C_SDA;
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|