Browse Source

FPGA: merge recent changes into sd2sneslite

Maximilian Rehkopf 12 years ago
parent
commit
b05c89cdbf

+ 35 - 82
verilog/sd2sneslite/address.v

@@ -18,93 +18,46 @@
 //
 //////////////////////////////////////////////////////////////////////////////////
 module address(
-    input CLK,
-    input [2:0] MAPPER,       // MCU detected mapper
-    input [23:0] SNES_ADDR,   // requested address from SNES
-    input SNES_CS,            // "CART" pin from SNES (active low)
-    output [22:0] ROM_ADDR,   // Address to request from SRAM0
-    output ROM_SEL,            // enable SRAM0 (active low)
-    input MCU_OVR,            // enable MCU master mode (active low)
-    input MODE,               // MCU(1) or SNES(0) ("bus phase")
-    output IS_SAVERAM,        // address/CS mapped as SRAM?
-    output IS_ROM,            // address mapped as ROM?
-    input [23:0] MCU_ADDR,    // allow address to be set externally
-    input ADDR_WRITE,
-    output ROM_ADDR0,
-    input [23:0] SAVERAM_MASK,
-    input [23:0] ROM_MASK,
-	 input use_msu,
-	 output msu_enable
-    );
-
-wire [1:0] SRAM_BANK;
-
-wire [23:0] SRAM_ADDR_FULL;
-
-/* currently supported mappers:
-   Index     Mapper     
-      000      HiROM
-      001      LoROM
-      010      ExHiROM (48-64Mbit)
-      110      brainfuck interleaved 96MBit Star Ocean =)
-      111      menu (ROM in upper SRAM)
+  input CLK,
+  input [23:0] SNES_ADDR,   // requested address from SNES
+  input SNES_CS,            // "CART" pin from SNES (active low)
+  output [23:0] ROM_ADDR,   // Address to request from SRAM0
+  output ROM_SEL,           // enable SRAM0 (active low)
+  output IS_SAVERAM,        // address/CS mapped as SRAM?
+  output IS_ROM,            // address mapped as ROM?
+  input [23:0] MCU_ADDR,    // allow address to be set externally
+  input ADDR_WRITE,
+  input [23:0] SAVERAM_MASK,
+  input [23:0] ROM_MASK
+);
+
+wire [23:0] SRAM_SNES_ADDR;
+
+/* static mapper:
+      menu (ROM in upper SRAM)
 */
 
-/*                               HiROM:   SRAM @ Bank 0x30-0x3f, 0xb0-0xbf
-                                          Offset 6000-7fff */
-
-assign IS_ROM = ( (MAPPER == 3'b000) ? ((!SNES_ADDR[22] & SNES_ADDR[15])
-                                       |(SNES_ADDR[22]))
-                : (MAPPER == 3'b001) ? ((!SNES_ADDR[22] & SNES_ADDR[15])
-                                       |(SNES_ADDR[22]))                                         
-                : (MAPPER == 3'b010) ? ((!SNES_ADDR[22] & SNES_ADDR[15])
-                                       |(SNES_ADDR[22]))
-					 : (MAPPER == 3'b110) ? ((!SNES_ADDR[22] & SNES_ADDR[15])
-					                        |(SNES_ADDR[22]))
-                : (MAPPER == 3'b111) ? ((!SNES_ADDR[22] & SNES_ADDR[15])
-                                       |(SNES_ADDR[22]))
-                : 1'b0);
-
-assign IS_SAVERAM = ((MAPPER == 3'b000 || MAPPER == 3'b010 || MAPPER == 3'b110 || MAPPER == 3'b111) ? (!SNES_ADDR[22]
-                                           & SNES_ADDR[21:20]                                           
-                                           & &SNES_ADDR[14:13]
-                                           & !SNES_ADDR[15]
-                                           & SNES_CS
-                                           )
-/*                               LoROM:   SRAM @ Bank 0x70-0x7d, 0xf0-0xfd
-                                          Offset 0000-7fff TODO: 0000-ffff for
-                                          small ROMs */
-                    :(MAPPER == 3'b001) ? (&SNES_ADDR[22:20]
-                                           & (SNES_ADDR[19:16] < 4'b1110)
-                                           & !SNES_ADDR[15]
-                                           & !SNES_CS)
-                    : 1'b0);
+/* HiROM:   SRAM @ Bank 0x30-0x3f, 0xb0-0xbf
+            Offset 6000-7fff */
 
-assign SRAM_ADDR_FULL = (MODE) ? MCU_ADDR
-                          : ((MAPPER == 3'b000) ?
-                              (IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK)
-                                          : ({1'b0, SNES_ADDR[22:0]} & ROM_MASK))
-                            :(MAPPER == 3'b001) ? 
-                              (IS_SAVERAM ? 24'hE00000 + (SNES_ADDR[14:0] & SAVERAM_MASK)
-                                          : ({2'b00, SNES_ADDR[22:16], SNES_ADDR[14:0]} & ROM_MASK))
-                            :(MAPPER == 3'b010) ?
-                              (IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK)
-                                          : ({1'b0, !SNES_ADDR[23], SNES_ADDR[21:0]} & ROM_MASK))
-                            :(MAPPER == 3'b110) ?
-                              (IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK)
-                                          : (SNES_ADDR[15] ? ({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]})
-                                                           : ({2'b10, SNES_ADDR[23], SNES_ADDR[21:16], SNES_ADDR[14:0]})))
-                            :(MAPPER == 3'b111) ?
-                              (IS_SAVERAM ? 24'hFF0000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK)
-                                          : (({1'b0, SNES_ADDR[22:0]} & ROM_MASK) + 24'hE00000))
-                            : 24'b0);
+assign IS_ROM = ((!SNES_ADDR[22] & SNES_ADDR[15])
+                 |(SNES_ADDR[22]));
 
-assign ROM_ADDR = SRAM_ADDR_FULL[23:1];
+assign IS_SAVERAM = (!SNES_ADDR[22]
+                         & &SNES_ADDR[21:20]
+                         & &SNES_ADDR[14:13]
+                         & !SNES_ADDR[15]
+                        );
 
-assign ROM_SEL = 1'b0; // (MODE) ? CS_ARRAY[SRAM_BANK] : IS_SAVERAM ? 4'b1000 : CS_ARRAY[SRAM_BANK];
+assign SRAM_SNES_ADDR = (IS_SAVERAM
+                             ? 24'hFF0000 + ((SNES_ADDR[14:0] - 15'h6000)
+                                             & SAVERAM_MASK)
+                             : (({1'b0, SNES_ADDR[22:0]} & ROM_MASK)
+                                + 24'hE00000)
+                         );
+								 
+assign ROM_ADDR = SRAM_SNES_ADDR;
 
-assign ROM_ADDR0 = SRAM_ADDR_FULL[0];
-//488888
-assign msu_enable = (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2000));
+assign ROM_SEL = 1'b0;
 
 endmodule

+ 2 - 3
verilog/sd2sneslite/data.v

@@ -36,8 +36,7 @@ module data(
       input MCU_OVR,
       input ROM_ADDR0,
 		output [7:0] MSU_DATA_IN,
-		input [7:0] MSU_DATA_OUT,
-		input msu_enable
+		input [7:0] MSU_DATA_OUT
     );
 
 reg [7:0] SNES_IN_MEM;
@@ -49,7 +48,7 @@ wire [7:0] FROM_ROM_BYTE;
 
 assign MSU_DATA_IN = SNES_DATA;
 
-assign SNES_DATA = SNES_READ ? 8'bZ : (!MCU_OVR ? 8'h00 : (msu_enable ? MSU_DATA_OUT : SNES_OUT_MEM));
+assign SNES_DATA = SNES_READ ? 8'bZ : (!MCU_OVR ? 8'h00 : SNES_OUT_MEM);
 
 assign FROM_ROM_BYTE = (ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8]);
 

+ 1 - 1
verilog/sd2sneslite/dcm.v

@@ -37,7 +37,7 @@ module my_dcm (
       .CLKFX_DIVIDE(1),   // Can be any integer from 1 to 32
       .CLKFX_MULTIPLY(4), // Can be any integer from 2 to 32
       .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature
-      .CLKIN_PERIOD(44.289),  // Specify period of input clock
+      .CLKIN_PERIOD(41.667),  // Specify period of input clock
       .CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE
       .CLK_FEEDBACK("NONE"),  // Specify clock feedback of NONE, 1X or 2X
       .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or

+ 25 - 16
verilog/sd2sneslite/main.ucf

@@ -1,5 +1,20 @@
 NET "CLKIN" TNM_NET = "CLKIN";
-TIMESPEC TS_CLKIN = PERIOD "CLKIN" 22.579 MHz HIGH 50 %;
+TIMESPEC TS_CLKIN = PERIOD "CLKIN" 24 MHz HIGH 50 %;
+//TIMESPEC TS_CLKIN = PERIOD "CLKIN" 21.5 MHz HIGH 50 %;
+
+NET "p113_out" IOSTANDARD = LVCMOS33;
+NET "p113_out" LOC = P113;
+
+
+NET "SPI_SCK" LOC = P71;
+NET "SPI_SCK" CLOCK_DEDICATED_ROUTE = FALSE;
+NET "SPI_SCK" TNM_NET = "SPI_SCK";
+TIMESPEC TS_SPI_SCK = PERIOD "SPI_SCK" 48MHz HIGH 50 %;
+
+NET "SPI_SCK" IOSTANDARD = LVCMOS33;
+NET "SPI_SCK" DRIVE = 8;
+NET "SPI_SCK" PULLUP;
+
 NET "SNES_CS" IOSTANDARD = LVCMOS33;
 NET "SNES_READ" IOSTANDARD = LVCMOS33;
 NET "SNES_WRITE" IOSTANDARD = LVCMOS33;
@@ -61,6 +76,10 @@ NET "MCU_OVR" LOC = P92;
 NET "MCU_OVR" IOSTANDARD = LVCMOS33;
 NET "MCU_OVR" DRIVE = 8;
 
+NET "MCU_RDY" LOC = P83;
+NET "MCU_RDY" IOSTANDARD = LVCMOS33;
+NET "MCU_RDY" DRIVE = 8;
+
 
 NET "ROM_ADDR[0]" LOC = P166;
 
@@ -236,10 +255,6 @@ NET "ROM_BLE" LOC = P156;
 NET "ROM_BLE" IOSTANDARD = LVCMOS33;
 NET "ROM_BLE" DRIVE = 8;
 
-NET "IRQ_DIR" LOC = P113;
-NET "IRQ_DIR" IOSTANDARD = LVCMOS33;
-NET "IRQ_DIR" DRIVE = 8;
-
 
 NET "ROM_DATA[0]" LOC = P176;
 
@@ -415,10 +430,12 @@ NET "SNES_ADDR[9]" IOSTANDARD = LVCMOS33;
 NET "SNES_ADDR[9]" DRIVE = 8;
 
 
-NET "SNES_CPU_CLK" LOC = P94;
+NET "SNES_CPU_CLK" LOC = P95;
 NET "SNES_CS" LOC = P116;
 NET "SNES_DATABUS_DIR" LOC = P111;
 NET "SNES_DATABUS_OE" LOC = P109;
+NET "SNES_DATABUS_DIR" DRIVE = 8;
+NET "SNES_DATABUS_OE" DRIVE = 8;
 
 
 NET "SNES_DATA[0]" IOSTANDARD = LVCMOS33;
@@ -442,7 +459,7 @@ NET "SNES_DATA[7]" DRIVE = 8;
 NET "SNES_IRQ" LOC = P114;
 NET "SNES_READ" LOC = P115;
 NET "SNES_REFRESH" LOC = P155;
-NET "SNES_WRITE" LOC = P95;
+NET "SNES_WRITE" LOC = P94;
 
 NET "SPI_MISO" LOC = P72;
 
@@ -458,14 +475,6 @@ NET "SPI_MOSI" IOSTANDARD = LVCMOS33;
 NET "SPI_MOSI" DRIVE = 8;
 
 
-NET "SPI_SCK" LOC = P71;
-
-
-NET "SPI_SCK" IOSTANDARD = LVCMOS33;
-NET "SPI_SCK" DRIVE = 8;
-NET "SPI_SCK" PULLUP;
-
-
 NET "SPI_SS" LOC = P68;
 
 
@@ -512,4 +521,4 @@ NET "SD_DAT[2]" IOSTANDARD = LVCMOS33;
 NET "SD_DAT[3]" IOSTANDARD = LVCMOS33;
 
 NET "SNES_SYSCLK" LOC = P180;
-NET "SNES_SYSCLK" IOSTANDARD = LVCMOS33;
+NET "SNES_SYSCLK" IOSTANDARD = LVCMOS33;

+ 312 - 426
verilog/sd2sneslite/main.v

@@ -19,58 +19,67 @@
 //
 //////////////////////////////////////////////////////////////////////////////////
 module main(
-   /* input clock */
-    input CLKIN,
-    
-   /* SNES signals */
-    input [23:0] SNES_ADDR,
-    input SNES_READ,
-    input SNES_WRITE,
-    input SNES_CS,
-    inout [7:0] SNES_DATA,
-    input SNES_CPU_CLK,
-    input SNES_REFRESH,
-    inout SNES_IRQ,
-    output SNES_DATABUS_OE,
-    output SNES_DATABUS_DIR,
-    output IRQ_DIR,
-	 input SNES_SYSCLK,
-
-   /* SRAM signals */
-    inout [15:0] ROM_DATA,
-    output [22:0] ROM_ADDR,
-    output ROM_CE,
-    output ROM_OE,
-    output ROM_WE,
-    output ROM_BHE,
-    output ROM_BLE,
-
-   /* MCU signals */
-    input SPI_MOSI,
-    inout SPI_MISO,
-    input SPI_SS,
-    inout SPI_SCK,
-    input MCU_OVR,
-	 
-	 output DAC_MCLK,
-	 output DAC_LRCK,
-	 output DAC_SDOUT,
-	 
-	/* SD signals */
-    input [3:0] SD_DAT,
-	 inout SD_CMD,
-	 inout SD_CLK
-	 
-   /* debug */
-   //output DCM_IN_STOPPED,
-   //output DCM_FX_STOPPED
-   //input DCM_RST
-    );
-	 
+  /* input clock */
+  input CLKIN,
+
+  /* SNES signals */
+  input [23:0] SNES_ADDR,
+  input SNES_READ,
+  input SNES_WRITE,
+  input SNES_CS,
+  inout [7:0] SNES_DATA,
+  input SNES_CPU_CLK,
+  input SNES_REFRESH,
+  output SNES_IRQ,
+  output SNES_DATABUS_OE,
+  output SNES_DATABUS_DIR,
+  input SNES_SYSCLK,
+
+  /* SRAM signals */
+  /* Bus 1: PSRAM, 128Mbit, 16bit, 70ns */
+  inout [15:0] ROM_DATA,
+  output [22:0] ROM_ADDR,
+  output ROM_CE,
+  output ROM_OE,
+  output ROM_WE,
+  output ROM_BHE,
+  output ROM_BLE,
+
+  /* Bus 2: SRAM, 4Mbit, 8bit, 45ns */
+  inout [7:0] RAM_DATA,
+  output [18:0] RAM_ADDR,
+  output RAM_CE,
+  output RAM_OE,
+  output RAM_WE,
+
+  /* MCU signals */
+  input SPI_MOSI,
+  inout SPI_MISO,
+  input SPI_SS,
+  inout SPI_SCK,
+  input MCU_OVR,
+  output MCU_RDY,
+  
+  output DAC_MCLK,
+  output DAC_LRCK,
+  output DAC_SDOUT,
+
+  /* SD signals */
+  input [3:0] SD_DAT,
+  inout SD_CMD,
+  inout SD_CLK,
+
+  /* debug */
+  output p113_out
+);
+
 assign DAC_MCLK = 1'b0;
 assign DAC_LRCK = 1'b0;
 assign DAC_SDOUT = 1'b0;
 
+assign SD_CMD = 1'bZ;
+assign SD_CLK = 1'bZ;
+
 wire [7:0] spi_cmd_data;
 wire [7:0] spi_param_data;
 wire [7:0] spi_input_data;
@@ -79,441 +88,318 @@ wire [2:0] spi_bit_cnt;
 wire [23:0] MCU_ADDR;
 wire [7:0] mcu_data_in;
 wire [7:0] mcu_data_out;
-wire [7:0] MCU_IN_DATA;
-wire [7:0] MCU_OUT_DATA;
 wire [3:0] MAPPER;
 wire [23:0] SAVERAM_MASK;
 wire [23:0] ROM_MASK;
-wire [7:0] SD_DMA_SRAM_DATA;
-wire [1:0] SD_DMA_TGT;
-wire [10:0] SD_DMA_PARTIAL_START;
-wire [10:0] SD_DMA_PARTIAL_END;
-
-wire [10:0] dac_addr;
-//wire [7:0] dac_volume;
-wire [7:0] msu_volumerq_out;
-wire [6:0] msu_status_out;
-wire [31:0] msu_addressrq_out;
-wire [15:0] msu_trackrq_out;
-wire [13:0] msu_write_addr;
-wire [13:0] msu_ptr_addr;
-wire [7:0] MSU_SNES_DATA_IN;
-wire [7:0] MSU_SNES_DATA_OUT;
-wire [5:0] msu_status_reset_bits;
-wire [5:0] msu_status_set_bits;
-
- 
-spi snes_spi(.clk(CLK2),
-             .MOSI(SPI_MOSI),
-             .MISO(SPI_MISO),
-             .SSEL(SPI_SS),
-             .SCK(SPI_SCK),
-             .cmd_ready(spi_cmd_ready),
-             .param_ready(spi_param_ready),
-             .cmd_data(spi_cmd_data),
-             .param_data(spi_param_data),
-             .endmessage(spi_endmessage),
-             .startmessage(spi_startmessage),
-             .input_data(spi_input_data),
-             .byte_cnt(spi_byte_cnt),
-             .bit_cnt(spi_bit_cnt)
+
+wire [23:0] MAPPED_SNES_ADDR;
+wire ROM_ADDR0;
+
+spi snes_spi(
+  .clk(CLK2),
+  .MOSI(SPI_MOSI),
+  .MISO(SPI_MISO),
+  .SSEL(SPI_SS),
+  .SCK(SPI_SCK),
+  .cmd_ready(spi_cmd_ready),
+  .param_ready(spi_param_ready),
+  .cmd_data(spi_cmd_data),
+  .param_data(spi_param_data),
+  .endmessage(spi_endmessage),
+  .startmessage(spi_startmessage),
+  .input_data(spi_input_data),
+  .byte_cnt(spi_byte_cnt),
+  .bit_cnt(spi_bit_cnt)
 );
 
+reg [7:0] MCU_DINr;
+wire [7:0] MCU_DOUT;
 
 mcu_cmd snes_mcu_cmd(
-    .clk(CLK2),
-    .cmd_ready(spi_cmd_ready),
-    .param_ready(spi_param_ready),
-    .cmd_data(spi_cmd_data),
-    .param_data(spi_param_data),
-    .mcu_mapper(MAPPER),
-    .mcu_sram_size(SRAM_SIZE),
-    .mcu_read(MCU_READ),
-    .mcu_write(MCU_WRITE),
-    .mcu_data_in(MCU_OUT_DATA),
-    .mcu_data_out(MCU_IN_DATA),
-    .spi_byte_cnt(spi_byte_cnt),
-    .spi_bit_cnt(spi_bit_cnt),
-    .spi_data_out(spi_input_data),
-    .addr_out(MCU_ADDR),
-    .endmessage(spi_endmessage),
-    .startmessage(spi_startmessage),
-    .saveram_mask_out(SAVERAM_MASK),
-    .rom_mask_out(ROM_MASK)
+  .clk(CLK2),
+  .cmd_ready(spi_cmd_ready),
+  .param_ready(spi_param_ready),
+  .cmd_data(spi_cmd_data),
+  .param_data(spi_param_data),
+  .mcu_sram_size(SRAM_SIZE),
+  .mcu_write(MCU_WRITE),
+  .mcu_data_in(MCU_DINr),
+  .mcu_data_out(MCU_DOUT),
+  .spi_byte_cnt(spi_byte_cnt),
+  .spi_bit_cnt(spi_bit_cnt),
+  .spi_data_out(spi_input_data),
+  .addr_out(MCU_ADDR),
+  .endmessage(spi_endmessage),
+  .startmessage(spi_startmessage),
+  .saveram_mask_out(SAVERAM_MASK),
+  .rom_mask_out(ROM_MASK),
+  .mcu_rrq(MCU_RRQ),
+  .mcu_wrq(MCU_WRQ),
+  .mcu_rq_rdy(MCU_RDY)
 );
 
 // dcm1: dfs 4x
-my_dcm snes_dcm(.CLKIN(CLKIN),
-                  .CLKFX(CLK2),
-                  .LOCKED(DCM_LOCKED),
-                  .RST(DCM_RST),
-                  .STATUS(DCM_STATUS)
-                );
-                
-assign DCM_RST=0;
+my_dcm snes_dcm(
+  .CLKIN(CLKIN),
+  .CLKFX(CLK2),
+  .LOCKED(DCM_LOCKED),
+  .RST(DCM_RST),
+  .STATUS(DCM_STATUS)
+);
 
-/*
-dcm_srl16 snes_dcm_resetter(.CLK(CLKIN),
-                              .Q(DCM_RST)
-                           );
-*/
-//wire DCM_FX_STOPPED = DCM_STATUS[2];
-//always @(posedge CLKIN) begin
-//   if(DCM_FX_STOPPED)
-//      DCM_RSTr <= 1'b1;
-//   else
-//      DCM_RSTr <= 1'b0;
-//end
-
-/*reg DO_DCM_RESET, DCM_RESETTING;
-reg DCM_RSTr;
-assign DCM_RST = DCM_RSTr;
-reg [2:0] DCM_RESET_CNT;
-initial DO_DCM_RESET = 1'b0;
-initial DCM_RESETTING = 1'b0;
-
-always @(posedge CLKIN) begin
-   if(!DCM_LOCKED && !DCM_RESETTING) begin
-      DCM_RSTr <= 1'b1;
-      DO_DCM_RESET <= 1'b1;
-      DCM_RESET_CNT <= 3'b0;
-   end else if (DO_DCM_RESET) begin
-      DCM_RSTr <= 1'b0;
-      DCM_RESET_CNT <= DCM_RESET_CNT + 1;
-   end
-end
+assign DCM_RST=0;
 
-always @(posedge CLKIN) begin
-   if (DO_DCM_RESET)
-      DCM_RESETTING <= 1'b1;
-   else if (DCM_RESET_CNT == 3'b110)
-      DCM_RESETTING <= 1'b0;
-end
-*/
-wire SNES_RW;
-reg [1:0] SNES_READr;
-reg [1:0] SNES_WRITEr;
-reg [1:0] SNES_CSr;
-reg [5:0] SNES_CPU_CLKr;
+reg [5:0] SNES_READr;
+reg [5:0] SNES_WRITEr;
+reg [12:0] SNES_CPU_CLKr;
 reg [5:0] SNES_RWr;
 reg [23:0] SNES_ADDRr;
-reg [23:0] SNES_ADDR_PREVr;
-reg [3:0] SNES_ADDRCHGr;
 
-wire SNES_READs = (SNES_READr == 2'b11);
-wire SNES_WRITEs = (SNES_WRITEr == 2'b11);
-wire SNES_CSs = (SNES_CSr == 2'b11);
-wire SNES_CPU_CLKs = SNES_CPU_CLK; // (SNES_CPU_CLKr == 2'b11);
-wire SNES_RW_start = (SNES_RWr == 6'b111110); // falling edge marks beginning of cycle
-wire SNES_cycle_start = (SNES_CPU_CLKr == 6'b000001);
-wire SNES_ADDRCHG = (SNES_ADDRr != SNES_ADDR_PREVr);
-wire SNES_addr_start = (SNES_ADDRCHGr[0] == 1'b1);
+wire SNES_RW = (SNES_READ & SNES_WRITE);
 
-assign SNES_RW = (SNES_READ & SNES_WRITE);
+wire SNES_RW_start = (SNES_RWr == 6'b111110); // falling edge marks beginning of cycle
+wire SNES_RD_start = (SNES_READr == 6'b111110);
+wire SNES_WR_start = (SNES_WRITEr == 6'b111110);
+wire SNES_cycle_start = (SNES_CPU_CLKr[5:0] == 6'b000001);
+wire SNES_cycle_end = (SNES_CPU_CLKr[5:0] == 6'b111110);
 
 always @(posedge CLK2) begin
-   SNES_READr <= {SNES_READr[0], SNES_READ};
-   SNES_WRITEr <= {SNES_WRITEr[0], SNES_WRITE};
-   SNES_CSr <= {SNES_CSr[0], SNES_CS};
-   SNES_CPU_CLKr <= {SNES_CPU_CLKr[4:0], SNES_CPU_CLK};
-   SNES_RWr <= {SNES_RWr[4:0], SNES_RW};
+  SNES_READr <= {SNES_READr[4:0], SNES_READ};
+  SNES_WRITEr <= {SNES_WRITEr[4:0], SNES_WRITE};
+  SNES_CPU_CLKr <= {SNES_CPU_CLKr[11:0], SNES_CPU_CLK};
+  SNES_RWr <= {SNES_RWr[4:0], SNES_RW};
 end
 
-reg ADDR_WRITE;
-
-//reg [23:0] SNES_ADDRr;
-//wire [23:0] SNES_ADDRw = SNES_ADDR;
-
 wire ROM_SEL;
 
 address snes_addr(
-    .CLK(CLK2),
-    .MAPPER(MAPPER),
-    .SNES_ADDR(SNES_ADDR),   // requested address from SNES
-    .SNES_CS(SNES_CS),            // "CART" pin from SNES (active low)
-    .ROM_ADDR(ROM_ADDR),  // Address to request from SRAM (active low)
-    .ROM_SEL(ROM_SEL),     // which SRAM unit to access
-    .MCU_OVR(MCU_OVR),            // enable MCU mode (active low)
-	 .MODE(MODE),               // MCU(1) or SNES(0) ("bus phase")
-    .IS_SAVERAM(IS_SAVERAM),
-    .IS_ROM(IS_ROM),
-    .MCU_ADDR(MCU_ADDR),
-    .ROM_ADDR0(ROM_ADDR0),
-    .SAVERAM_MASK(SAVERAM_MASK),
-    .ROM_MASK(ROM_MASK)
-    );
+  .CLK(CLK2),
+  .SNES_ADDR(SNES_ADDR), // requested address from SNES
+  .SNES_CS(SNES_CS),     // "CART" pin from SNES (active low)
+  .ROM_ADDR(MAPPED_SNES_ADDR),   // Address to request from SRAM (active low)
+  .ROM_SEL(ROM_SEL),     // which SRAM unit to access
+  .IS_SAVERAM(IS_SAVERAM),
+  .IS_ROM(IS_ROM),
+  .MCU_ADDR(MCU_ADDR),
+  .SAVERAM_MASK(SAVERAM_MASK),
+  .ROM_MASK(ROM_MASK)
+);
 
 wire SNES_READ_CYCLEw;
 wire SNES_WRITE_CYCLEw;
 wire MCU_READ_CYCLEw;
 wire MCU_WRITE_CYCLEw;
 
-data snes_data(.CLK(CLK2),
-      .SNES_READ(SNES_READ),
-      .SNES_WRITE(SNES_WRITE),
-      .MCU_READ(MCU_READ),
-      .MCU_WRITE(MCU_WRITE),
-      .SNES_DATA(SNES_DATA),
-      .ROM_DATA(ROM_DATA),
-      .MODE(MODE),
-      .SNES_DATA_TO_MEM(SNES_DATA_TO_MEM),
-      .MCU_DATA_TO_MEM(MCU_DATA_TO_MEM),
-      .ROM_DATA_TO_SNES_MEM(ROM_DATA_TO_SNES_MEM),
-      .ROM_DATA_TO_MCU_MEM(ROM_DATA_TO_MCU_MEM),
-      .MCU_OVR(MCU_OVR),
-      .MCU_IN_DATA(MCU_IN_DATA),
-      .MCU_OUT_DATA(MCU_OUT_DATA),
-      .ROM_ADDR0(ROM_ADDR0),
-		.MSU_DATA_IN(MSU_SNES_DATA_IN),
-		.MSU_DATA_OUT(MSU_SNES_DATA_OUT),
-		.msu_enable(msu_enable)
-      );
-      
 parameter MODE_SNES = 1'b0;
 parameter MODE_MCU = 1'b1;
 
-parameter STATE_0    = 14'b00000000000001;
-parameter STATE_1    = 14'b00000000000010;
-parameter STATE_2    = 14'b00000000000100;
-parameter STATE_3    = 14'b00000000001000;
-parameter STATE_4    = 14'b00000000010000;
-parameter STATE_5    = 14'b00000000100000;
-parameter STATE_6    = 14'b00000001000000;
-parameter STATE_7    = 14'b00000010000000;
-parameter STATE_8    = 14'b00000100000000;
-parameter STATE_9    = 14'b00001000000000;
-parameter STATE_10   = 14'b00010000000000;
-parameter STATE_11   = 14'b00100000000000;
-parameter STATE_12	= 14'b01000000000000;
-parameter STATE_IDLE = 14'b10000000000000;
-
-reg [13:0] STATE;
-reg [3:0] STATEIDX;
+parameter ST_IDLE         = 18'b000000000000000001;
+parameter ST_SNES_RD_ADDR = 18'b000000000000000010;
+parameter ST_SNES_RD_WAIT = 18'b000000000000000100;
+parameter ST_SNES_RD_END  = 18'b000000000000001000;
+parameter ST_SNES_WR_ADDR = 18'b000000000000010000;
+parameter ST_SNES_WR_WAIT1= 18'b000000000000100000;
+parameter ST_SNES_WR_DATA = 18'b000000000001000000;
+parameter ST_SNES_WR_WAIT2= 18'b000000000010000000;
+parameter ST_SNES_WR_END  = 18'b000000000100000000;
+parameter ST_MCU_RD_ADDR  = 18'b000000001000000000;
+parameter ST_MCU_RD_WAIT  = 18'b000000010000000000;
+parameter ST_MCU_RD_WAIT2 = 18'b000000100000000000;
+parameter ST_MCU_RD_END   = 18'b000001000000000000;
+parameter ST_MCU_WR_ADDR  = 18'b000010000000000000;
+parameter ST_MCU_WR_WAIT  = 18'b000100000000000000;
+parameter ST_MCU_WR_WAIT2 = 18'b001000000000000000;
+parameter ST_MCU_WR_END   = 18'b010000000000000000;
+
+parameter ROM_RD_WAIT = 4'h4;
+parameter ROM_RD_WAIT_MCU = 4'h5;
+parameter ROM_WR_WAIT1 = 4'h2;
+parameter ROM_WR_WAIT2 = 4'h3;
+parameter ROM_WR_WAIT_MCU = 4'h6;
+
+reg [17:0] STATE;
+initial STATE = ST_IDLE;
 
 reg [1:0] CYCLE_RESET;
 reg ROM_WE_MASK;
 reg ROM_OE_MASK;
 
-reg [13:0] ROM_WE_ARRAY [3:0];
-reg [13:0] ROM_OE_ARRAY [3:0];
-
-reg [13:0] SNES_DATA_TO_MEM_ARRAY[1:0];
-reg [13:0] MCU_DATA_TO_MEM_ARRAY[1:0];
-reg [13:0] ROM_DATA_TO_SNES_MEM_ARRAY[1:0];
-reg [13:0] ROM_DATA_TO_MCU_MEM_ARRAY[1:0];
-
-reg [13:0] MODE_ARRAY;
-
-reg SNES_READ_CYCLE;
-reg SNES_WRITE_CYCLE;
-reg MCU_READ_CYCLE;
-reg MCU_WRITE_CYCLE;
-reg MCU_SPI_WRITEONCE;
-reg MCU_SPI_READONCE;
-reg MCU_SPI_WRITE;
-reg MCU_SPI_READ;
-reg MCU_SPI_ADDR_INCREMENT;
-reg [7:0] MCU_DATA_IN;
-reg [3:0] MAPPER_BUF;
-
-reg SNES_DATABUS_OE_BUF;
-reg SNES_DATABUS_DIR_BUF;
-
-assign MODE = !MCU_OVR ? MODE_MCU : MODE_ARRAY[STATEIDX];
-
-initial begin
-   CYCLE_RESET = 2'b0;
-   
-   STATE = STATE_IDLE;
-   STATEIDX = 13;
-   ROM_WE_MASK = 1'b1;
-   ROM_OE_MASK = 1'b1;
-   SNES_READ_CYCLE = 1'b1;
-   SNES_WRITE_CYCLE = 1'b1;
-   MCU_READ_CYCLE = 1'b1;
-   MCU_WRITE_CYCLE = 1'b1;
-   MODE_ARRAY = 14'b0_000000_1111111;
-   
-   ROM_WE_ARRAY[2'b00] = 14'b1_000000_0000000;
-   ROM_WE_ARRAY[2'b01] = 14'b1_000000_1111111;
-   ROM_WE_ARRAY[2'b10] = 14'b1_111111_0000000;
-   ROM_WE_ARRAY[2'b11] = 14'b1_111111_1111111;
-
-   ROM_OE_ARRAY[2'b00] = 14'b1_111111_1111111;
-   ROM_OE_ARRAY[2'b01] = 14'b1_111111_0000000;
-   ROM_OE_ARRAY[2'b10] = 14'b0_000000_1111111;
-   ROM_OE_ARRAY[2'b11] = 14'b0_000000_0000000;
-   
-   SNES_DATA_TO_MEM_ARRAY[1'b0] = 14'b0_000100_0000000;  // SNES write
-   /* 13'b0001000000000 */
-   SNES_DATA_TO_MEM_ARRAY[1'b1] = 14'b0_000000_0000000;  // SNES read
-   
-   MCU_DATA_TO_MEM_ARRAY[1'b0] = 14'b1_111111_1111111;  // MCU write
-//   MCU_DATA_TO_MEM_ARRAY[1'b0] = 13'b0000000001000;  // MCU write
-
-   MCU_DATA_TO_MEM_ARRAY[1'b1] = 14'b0_000000_0000000;  // MCU read
-   
-   ROM_DATA_TO_SNES_MEM_ARRAY[1'b0] = 14'b0_000000_0000000;  // SNES write
-   ROM_DATA_TO_SNES_MEM_ARRAY[1'b1] = 14'b0_000010_0000000;  // SNES read
-   /* 13'b0000100000000; */
-   
-   ROM_DATA_TO_MCU_MEM_ARRAY[1'b0] = 14'b0_000000_0000000;  // MCU write
-   ROM_DATA_TO_MCU_MEM_ARRAY[1'b1] = 14'b0_000000_0000001;  // MCU read
-//   SRAM_DATA_TO_MCU_MEM_ARRAY[1'b1] = 13'b0000000000001;  // MCU read
-
-end 
-
-// falling edge of SNES /RD or /WR marks the beginning of a new cycle
-// SNES READ or WRITE always starts @posedge CLK !!
-// CPU cycle can be 6, 8 or 12 CLKIN cycles so we must satisfy
-// the minimum of 6 SNES cycles to get everything done.
-// we have 24 internal cycles to work with. (CLKIN * 4)
+reg [7:0] SNES_DINr;
+reg [7:0] ROM_DOUTr;
+
+assign SNES_DATA = (!SNES_READ) ? SNES_DINr : 8'bZ;
 
+reg [3:0] ST_MEM_DELAYr;
+reg MCU_RD_PENDr;
+reg MCU_WR_PENDr;
+reg [23:0] ROM_ADDRr;
+reg NEED_SNES_ADDRr;
 always @(posedge CLK2) begin
-	CYCLE_RESET <= {CYCLE_RESET[0], SNES_cycle_start};
+  if(SNES_cycle_end) NEED_SNES_ADDRr <= 1'b1;
+  else if(STATE & (ST_SNES_RD_END | ST_SNES_WR_END)) NEED_SNES_ADDRr <= 1'b0;
 end
 
+wire ASSERT_SNES_ADDR = SNES_CPU_CLK & NEED_SNES_ADDRr;
+
+assign ROM_ADDR  = (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1];
+assign ROM_ADDR0 = (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[0] : ROM_ADDRr[0];
+
+reg ROM_WEr;
+initial ROM_WEr = 1'b1;
+
+reg RQ_MCU_RDYr;
+initial RQ_MCU_RDYr = 1'b1;
+assign MCU_RDY = RQ_MCU_RDYr;
+
 always @(posedge CLK2) begin
-       MCU_READ_CYCLE <= MCU_READ;
-       MCU_WRITE_CYCLE <= MCU_WRITE;
-       if (SNES_cycle_start) begin
-           SNES_READ_CYCLE <= SNES_READ;
-           SNES_WRITE_CYCLE <= SNES_WRITE;
-           STATE <= STATE_0;
-           STATEIDX <= 12;
-       end else begin
-           case (STATE)
-              STATE_0: begin
-                 STATE <= STATE_1; STATEIDX <= 11;
-              end
-              STATE_1: begin
-                 STATE <= STATE_2; STATEIDX <= 10;
-              end
-              STATE_2: begin
-                 STATE <= STATE_3; STATEIDX <= 9;
-              end
-              STATE_3: begin
-                 STATE <= STATE_4; STATEIDX <= 8;
-              end
-              STATE_4: begin
-                 STATE <= STATE_5; STATEIDX <= 7;
-              end
-              STATE_5: begin
-                 STATE <= STATE_6; STATEIDX <= 6;
-              end
-              STATE_6: begin
-                 STATE <= STATE_7; STATEIDX <= 5;
-              end
-              STATE_7: begin
-                 STATE <= STATE_8; STATEIDX <= 4;
-              end
-              STATE_8: begin
-                 STATE <= STATE_9; STATEIDX <= 3;
-              end
-              STATE_9: begin
-                 STATE <= STATE_10; STATEIDX <= 2;
-              end
-              STATE_10: begin
-                 STATE <= STATE_11; STATEIDX <= 1;
-              end
-              STATE_11: begin
-                 STATE <= STATE_12; STATEIDX <= 0;
-              end
-				  STATE_12: begin
-				     STATE <= STATE_IDLE; STATEIDX <= 13;
-				  end
-              STATE_IDLE: begin
-                 STATE <= STATE_IDLE; STATEIDX <= 13;
-              end
-              default: begin
-                 STATE <= STATE_IDLE; STATEIDX <= 13;
-              end
-           endcase
-       end
+  if(MCU_RRQ) begin
+    MCU_RD_PENDr <= 1'b1;
+	 RQ_MCU_RDYr <= 1'b0;
+  end else if(MCU_WRQ) begin
+    MCU_WR_PENDr <= 1'b1;
+	 RQ_MCU_RDYr <= 1'b0;
+  end else if(STATE & (ST_MCU_RD_END | ST_MCU_WR_END)) begin
+    MCU_RD_PENDr <= 1'b0;
+	 MCU_WR_PENDr <= 1'b0;
+	 RQ_MCU_RDYr <= 1'b1;
+  end
 end
-/*
-always @(posedge CLK2) begin
 
-   case (STATE)   
-      STATE_9: begin
-         STATEIDX <= 9;
-      end
-      
-      STATE_0: begin
-         STATEIDX <= 8;
-      end
-      
-      STATE_1: begin
-         STATEIDX <= 7;
-      end
-      
-      STATE_2: begin
-         STATEIDX <= 6;
-      end
-      
-      STATE_3: begin
-         STATEIDX <= 5;
-      end
-      
-      STATE_4: begin
-         STATEIDX <= 4;
-      end
-      
-      STATE_5: begin
-         STATEIDX <= 3;
-      end
-      
-      STATE_6: begin
-         STATEIDX <= 2;
-      end
+reg snes_wr_cycle;
 
-      STATE_7: begin
-         STATEIDX <= 1;
+always @(posedge CLK2) begin
+  if(SNES_cycle_start) begin
+    STATE <= ST_SNES_RD_ADDR;
+  end else if(SNES_WR_start) begin
+    STATE <= ST_SNES_WR_ADDR;
+  end else begin
+    case(STATE)
+	   ST_IDLE: begin
+		  ROM_ADDRr <= MAPPED_SNES_ADDR;
+		  if(MCU_RD_PENDr) STATE <= ST_MCU_RD_ADDR;
+		  else if(MCU_WR_PENDr) STATE <= ST_MCU_WR_ADDR;
+        else STATE <= ST_IDLE;
+		end
+		ST_SNES_RD_ADDR: begin
+		  STATE <= ST_SNES_RD_WAIT;
+		  ST_MEM_DELAYr <= ROM_RD_WAIT;
+		end
+		ST_SNES_RD_WAIT: begin
+		  ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
+		  if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_RD_END;
+		  else STATE <= ST_SNES_RD_WAIT;
+		  if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0];
+		  else SNES_DINr <= ROM_DATA[15:8];
+		end
+		ST_SNES_RD_END: begin
+		  STATE <= ST_IDLE;
+		  if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0];
+		  else SNES_DINr <= ROM_DATA[15:8];
+		end
+      ST_SNES_WR_ADDR: begin
+        ROM_WEr <= (!IS_SAVERAM);
+        snes_wr_cycle <= 1'b1;
+		  STATE <= ST_SNES_WR_WAIT1;
+		  ST_MEM_DELAYr <= ROM_WR_WAIT1;
+		end
+		ST_SNES_WR_WAIT1: begin
+		  ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
+		  if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_DATA;
+		  else STATE <= ST_SNES_WR_WAIT1;
+		end
+		ST_SNES_WR_DATA: begin
+        ROM_DOUTr <= SNES_DATA;
+		  ST_MEM_DELAYr <= ROM_WR_WAIT2;
+		  STATE <= ST_SNES_WR_WAIT2;
+		end
+      ST_SNES_WR_WAIT2: begin
+		  ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
+		  if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_END;
+		  else STATE <= ST_SNES_WR_WAIT2;
+		end
+		ST_SNES_WR_END: begin
+		  STATE <= ST_IDLE;
+		  ROM_WEr <= 1'b1;
+		  snes_wr_cycle <= 1'b0;
+		end
+		ST_MCU_RD_ADDR: begin
+		  ROM_ADDRr <= MCU_ADDR;
+		  STATE <= ST_MCU_RD_WAIT;
+		  ST_MEM_DELAYr <= ROM_RD_WAIT_MCU;
+		end
+		ST_MCU_RD_WAIT: begin
+		  ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
+		  if(ST_MEM_DELAYr == 4'h0) begin
+		    STATE <= ST_MCU_RD_WAIT2;
+			 ST_MEM_DELAYr <= 4'h2;
+		  end
+		  else STATE <= ST_MCU_RD_WAIT;
+		  if(ROM_ADDR0) MCU_DINr <= ROM_DATA[7:0];
+		  else MCU_DINr <= ROM_DATA[15:8];
       end
-
-      STATE_8: begin
-         STATEIDX <= 0;
+		ST_MCU_RD_WAIT2: begin
+		  ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
+		  if(ST_MEM_DELAYr == 4'h0) begin
+		    STATE <= ST_MCU_RD_END;
+		  end else STATE <= ST_MCU_RD_WAIT2;
+		end
+		ST_MCU_RD_END: begin
+		  STATE <= ST_IDLE;
+		end
+		ST_MCU_WR_ADDR: begin
+		  ROM_ADDRr <= MCU_ADDR;
+		  STATE <= ST_MCU_WR_WAIT;
+		  ST_MEM_DELAYr <= ROM_WR_WAIT_MCU;
+		  ROM_DOUTr <= MCU_DOUT;
+		  ROM_WEr <= 1'b0;
+		end
+		ST_MCU_WR_WAIT: begin
+		  ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
+		  if(ST_MEM_DELAYr == 4'h0) begin
+          ROM_WEr <= 1'b1;
+		    STATE <= ST_MCU_WR_WAIT2;
+			 ST_MEM_DELAYr <= 4'h2;
+		  end
+		  else STATE <= ST_MCU_WR_WAIT;
       end
-      default:
-         STATEIDX <= 9;
-   endcase      
+		ST_MCU_WR_WAIT2: begin
+		  ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
+		  if(ST_MEM_DELAYr == 4'h0) begin
+		    STATE <= ST_MCU_WR_END;
+        end else STATE <= ST_MCU_WR_WAIT2;
+		end
+		ST_MCU_WR_END: begin
+		  STATE <= ST_IDLE;
+		end
+
+	 endcase
+  end
 end
-*/
-// When in MCU mode, enable SRAM_WE according to MCU programming
-// else enable SRAM_WE according to state&cycle
-assign ROM_WE = !MCU_OVR ? MCU_WRITE
-                          : ((!IS_SAVERAM & !MODE) | ROM_WE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX]);
 
-// When in MCU mode, enable SRAM_OE whenever not writing
-// else enable SRAM_OE according to state&cycle
-assign ROM_OE = !MCU_OVR ? MCU_READ 
-                          : ROM_OE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX];
+assign ROM_DATA[7:0] = ROM_ADDR0
+                       ?(!ROM_WE ? ROM_DOUTr : 8'bZ)
+                       :8'bZ;
+
+assign ROM_DATA[15:8] = ROM_ADDR0 ? 8'bZ
+                        :(!ROM_WE ? ROM_DOUTr : 8'bZ);
+                         
+assign ROM_WE = ROM_WEr | (ASSERT_SNES_ADDR & ~snes_wr_cycle);
+assign ROM_OE = 1'b0;
 
-assign ROM_CE = 1'b0; // !MCU_OVR ? (MCU_READ & MCU_WRITE) : ROM_SEL;
+assign ROM_CE = 1'b0;
 
 assign ROM_BHE = !ROM_WE ? ROM_ADDR0 : 1'b0;
 assign ROM_BLE = !ROM_WE ? !ROM_ADDR0 : 1'b0;
 
-//assign SRAM_BHE = SRAM_ADDR0;
-//assign SRAM_BLE = ~SRAM_ADDR0;
+assign SNES_DATABUS_OE = ((IS_ROM & SNES_CS)
+                          |(!IS_ROM & !IS_SAVERAM)
+                          |(SNES_READ & SNES_WRITE)
+                         );
 
-// dumb version
-//assign SRAM_OE = !MCU_ENA ? MCU_READ : SNES_READs;
-//assign SRAM_WE = !MCU_ENA ? MCU_WRITE : 1'b1;
-
-//assign SNES_DATABUS_OE = (!IS_SAVERAM & SNES_CS) | (SNES_READ & SNES_WRITE);
-assign SNES_DATABUS_OE = msu_enable ? 1'b0 : ((IS_ROM & SNES_CS) | (!IS_ROM & !IS_SAVERAM) | (SNES_READ & SNES_WRITE));
 assign SNES_DATABUS_DIR = !SNES_READ ? 1'b1 : 1'b0;
 
-assign SNES_DATA_TO_MEM = SNES_DATA_TO_MEM_ARRAY[SNES_WRITE_CYCLE][STATEIDX];
-assign MCU_DATA_TO_MEM = MCU_DATA_TO_MEM_ARRAY[MCU_WRITE_CYCLE][STATEIDX];
-
-assign ROM_DATA_TO_SNES_MEM = ROM_DATA_TO_SNES_MEM_ARRAY[SNES_WRITE_CYCLE][STATEIDX];
-assign ROM_DATA_TO_MCU_MEM = ROM_DATA_TO_MCU_MEM_ARRAY[MCU_WRITE_CYCLE][STATEIDX];
+assign SNES_IRQ = 1'b0;
 
-assign SNES_READ_CYCLEw = SNES_READ_CYCLE;
-assign SNES_WRITE_CYCLEw = SNES_WRITE_CYCLE;
-assign IRQ_DIR = 1'b0;
-assign SNES_IRQ = 1'bZ;
+assign p113_out = 1'b0;
 
 endmodule

+ 27 - 25
verilog/sd2sneslite/sd2sneslite.xise

@@ -9,44 +9,44 @@
     <!-- along with the project source files, is sufficient to open and    -->
     <!-- implement in ISE Project Navigator.                               -->
     <!--                                                                   -->
-    <!-- Copyright (c) 1995-2010 Xilinx, Inc.  All rights reserved. -->
+    <!-- Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved. -->
   </header>
 
-  <version xil_pn:ise_version="12.3" xil_pn:schema_version="2"/>
+  <version xil_pn:ise_version="13.2" xil_pn:schema_version="2"/>
 
   <files>
     <file xil_pn:name="address.v" xil_pn:type="FILE_VERILOG">
-      <association xil_pn:name="BehavioralSimulation"/>
-      <association xil_pn:name="Implementation"/>
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
+      <association xil_pn:name="Implementation" xil_pn:seqID="4"/>
     </file>
     <file xil_pn:name="spi.v" xil_pn:type="FILE_VERILOG">
-      <association xil_pn:name="BehavioralSimulation"/>
-      <association xil_pn:name="Implementation"/>
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
+      <association xil_pn:name="Implementation" xil_pn:seqID="1"/>
     </file>
     <file xil_pn:name="main.v" xil_pn:type="FILE_VERILOG">
-      <association xil_pn:name="BehavioralSimulation"/>
-      <association xil_pn:name="Implementation"/>
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="3"/>
+      <association xil_pn:name="Implementation" xil_pn:seqID="5"/>
     </file>
     <file xil_pn:name="dcm.v" xil_pn:type="FILE_VERILOG">
-      <association xil_pn:name="BehavioralSimulation"/>
-      <association xil_pn:name="Implementation"/>
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="4"/>
+      <association xil_pn:name="Implementation" xil_pn:seqID="3"/>
     </file>
     <file xil_pn:name="data.v" xil_pn:type="FILE_VERILOG">
-      <association xil_pn:name="BehavioralSimulation"/>
-      <association xil_pn:name="Implementation"/>
-    </file>
-    <file xil_pn:name="avr_cmd.v" xil_pn:type="FILE_VERILOG">
-      <association xil_pn:name="BehavioralSimulation"/>
-      <association xil_pn:name="Implementation"/>
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="5"/>
+      <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
     </file>
     <file xil_pn:name="main.ucf" xil_pn:type="FILE_UCF">
-      <association xil_pn:name="Implementation"/>
+      <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
+    </file>
+    <file xil_pn:name="mcu_cmd.v" xil_pn:type="FILE_VERILOG">
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="58"/>
+      <association xil_pn:name="Implementation" xil_pn:seqID="2"/>
     </file>
   </files>
 
   <properties>
     <property xil_pn:name="Add I/O Buffers" xil_pn:value="true" xil_pn:valueState="default"/>
-    <property xil_pn:name="Allow Logic Optimization Across Hierarchy" xil_pn:value="false" xil_pn:valueState="default"/>
+    <property xil_pn:name="Allow Logic Optimization Across Hierarchy" xil_pn:value="true" xil_pn:valueState="non-default"/>
     <property xil_pn:name="Allow SelectMAP Pins to Persist" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Allow Unexpanded Blocks" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Allow Unmatched LOC Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
@@ -99,7 +99,7 @@
     <property xil_pn:name="Do Not Escape Signal and Instance Names in Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Done (Output Events)" xil_pn:value="Default (4)" xil_pn:valueState="default"/>
     <property xil_pn:name="Drive Done Pin High" xil_pn:value="false" xil_pn:valueState="default"/>
-    <property xil_pn:name="Enable BitStream Compression" xil_pn:value="true" xil_pn:valueState="non-default"/>
+    <property xil_pn:name="Enable BitStream Compression" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Enable Cyclic Redundancy Checking (CRC)" xil_pn:value="true" xil_pn:valueState="default"/>
     <property xil_pn:name="Enable Debugging of Serial Mode BitStream" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Enable Hardware Co-Simulation" xil_pn:value="false" xil_pn:valueState="default"/>
@@ -157,12 +157,14 @@
     <property xil_pn:name="JTAG Pin TDI" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
     <property xil_pn:name="JTAG Pin TDO" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
     <property xil_pn:name="JTAG Pin TMS" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
-    <property xil_pn:name="Keep Hierarchy" xil_pn:value="No" xil_pn:valueState="default"/>
+    <property xil_pn:name="Keep Hierarchy" xil_pn:value="Yes" xil_pn:valueState="non-default"/>
     <property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/>
     <property xil_pn:name="Last Applied Goal" xil_pn:value="Balanced" xil_pn:valueState="default"/>
     <property xil_pn:name="Last Applied Strategy" xil_pn:value="Xilinx Default (unlocked)" xil_pn:valueState="default"/>
     <property xil_pn:name="Last Unlock Status" xil_pn:value="false" xil_pn:valueState="default"/>
+    <property xil_pn:name="Launch SDK after Export" xil_pn:value="true" xil_pn:valueState="default"/>
     <property xil_pn:name="Library for Verilog Sources" xil_pn:value="" xil_pn:valueState="default"/>
+    <property xil_pn:name="Load glbl" xil_pn:value="true" xil_pn:valueState="default"/>
     <property xil_pn:name="Logical Shifter Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
     <property xil_pn:name="Manual Implementation Compile Order" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Map Effort Level" xil_pn:value="High" xil_pn:valueState="default"/>
@@ -180,8 +182,8 @@
     <property xil_pn:name="Number of Clock Buffers" xil_pn:value="8" xil_pn:valueState="default"/>
     <property xil_pn:name="Number of Paths in Error/Verbose Report" xil_pn:value="3" xil_pn:valueState="default"/>
     <property xil_pn:name="Number of Paths in Error/Verbose Report Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
-    <property xil_pn:name="Optimization Effort" xil_pn:value="Normal" xil_pn:valueState="default"/>
-    <property xil_pn:name="Optimization Goal" xil_pn:value="Speed" xil_pn:valueState="default"/>
+    <property xil_pn:name="Optimization Effort" xil_pn:value="High" xil_pn:valueState="non-default"/>
+    <property xil_pn:name="Optimization Goal" xil_pn:value="Area" xil_pn:valueState="non-default"/>
     <property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Area" xil_pn:valueState="default"/>
     <property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Other Bitgen Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
@@ -205,7 +207,7 @@
     <property xil_pn:name="Overwrite Compiled Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Pack I/O Registers into IOBs" xil_pn:value="Auto" xil_pn:valueState="default"/>
     <property xil_pn:name="Pack I/O Registers/Latches into IOBs" xil_pn:value="Off" xil_pn:valueState="default"/>
-    <property xil_pn:name="Package" xil_pn:value="pq208" xil_pn:valueState="default"/>
+    <property xil_pn:name="Package" xil_pn:value="pq208" xil_pn:valueState="non-default"/>
     <property xil_pn:name="Perform Advanced Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Perform Advanced Analysis Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Perform Timing-Driven Packing and Placement" xil_pn:value="false" xil_pn:valueState="default"/>
@@ -221,9 +223,8 @@
     <property xil_pn:name="Power Reduction Par" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Preferred Language" xil_pn:value="Verilog" xil_pn:valueState="default"/>
     <property xil_pn:name="Priority Encoder Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/>
-    <property xil_pn:name="Produce Advanced Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
-    <property xil_pn:name="Project Description" xil_pn:value="lite (bootstrap) configware for embedding into MCU firmware. For showing status messages even with no configware loaded from SD card" xil_pn:valueState="non-default"/>
+    <property xil_pn:name="Project Description" xil_pn:value="" xil_pn:valueState="default"/>
     <property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/>
     <property xil_pn:name="RAM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
     <property xil_pn:name="RAM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
@@ -291,6 +292,7 @@
     <property xil_pn:name="Trim Unconnected Signals" xil_pn:value="true" xil_pn:valueState="default"/>
     <property xil_pn:name="Tristate On Configuration Pulse Width" xil_pn:value="0" xil_pn:valueState="default"/>
     <property xil_pn:name="Unused IOB Pins" xil_pn:value="Pull Down" xil_pn:valueState="default"/>
+    <property xil_pn:name="Use 64-bit PlanAhead on 64-bit Systems" xil_pn:value="true" xil_pn:valueState="default"/>
     <property xil_pn:name="Use Clock Enable" xil_pn:value="Yes" xil_pn:valueState="default"/>
     <property xil_pn:name="Use Custom Project File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
     <property xil_pn:name="Use Custom Project File Post-Map" xil_pn:value="false" xil_pn:valueState="default"/>

+ 80 - 57
verilog/sd2sneslite/spi.v

@@ -19,25 +19,23 @@
 //
 
 //////////////////////////////////////////////////////////////////////////////////
-module spi(input clk,
-           input SCK,
-           input MOSI,
-           inout MISO,
-           input SSEL,
-           output cmd_ready,
-           output param_ready,
-           output [7:0] cmd_data,
-           output [7:0] param_data,
-           output endmessage,
-           output startmessage,
-           input [7:0] input_data,
-           output [31:0] byte_cnt,
-           output [2:0] bit_cnt
-
-// SD "DMA" extension           
-           /*input sd_dma_sck,
-           input sd_dma_ovr*/);
-           
+module spi(
+  input clk,
+  input SCK,
+  input MOSI,
+  inout MISO,
+  input SSEL,
+  output cmd_ready,
+  output param_ready,
+  output [7:0] cmd_data,
+  output [7:0] param_data,
+  output endmessage,
+  output startmessage,
+  input [7:0] input_data,
+  output [31:0] byte_cnt,
+  output [2:0] bit_cnt
+);
+
 reg [7:0] cmd_data_r;
 reg [7:0] param_data_r;
 
@@ -68,46 +66,71 @@ reg byte_received;  // high when a byte has been received
 reg [7:0] byte_data_received;
 
 assign bit_cnt = bitcnt;
-
+/*
 always @(posedge clk)
 begin
-   if(~SSEL_active) begin
-     bitcnt <= 3'b000;
-   end
-   else if(SCK_risingedge) begin
-      bitcnt <= bitcnt + 3'b001;
-      // shift received data into the register
-      byte_data_received <= {byte_data_received[6:0], MOSI_data};
-   end
+  if(~SSEL_active) begin
+    bitcnt <= 3'b000;
+  end
+  else if(SCK_risingedge) begin
+    bitcnt <= bitcnt + 3'b001;
+    // shift received data into the register
+    byte_data_received <= {byte_data_received[6:0], MOSI_data};
+  end
+end
+*/
+
+always @(posedge SCK) begin
+  if(SSEL) bitcnt <= 3'b000;
+  else begin
+    bitcnt <= bitcnt + 3'b001;
+	 byte_data_received <= {byte_data_received[6:0], MOSI};
+  end
+  if(~SSEL && bitcnt==3'b111) byte_received <= 1'b1;
+  else byte_received <= 1'b0;
 end
 
-always @(posedge clk) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);
+//always @(posedge clk)
+//  byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);
+
+reg [1:0] byte_received_r;
+always @(posedge clk) byte_received_r <= {byte_received_r[0], byte_received};
+wire byte_received_sync = (byte_received_r == 2'b01);
 
 always @(posedge clk) begin
-   if(~SSEL_active)
-      byte_cnt_r <= 16'h0000;    
-   else if(byte_received) begin
-      byte_cnt_r <= byte_cnt_r + 16'h0001;
-   end
+  if(~SSEL_active)
+    byte_cnt_r <= 16'h0000;
+  else if(byte_received_sync) begin
+    byte_cnt_r <= byte_cnt_r + 16'h0001;
+  end
 end
 
 reg [7:0] byte_data_sent;
 
-always @(posedge clk) begin
-   if(SSEL_active) begin
-     if(SSEL_startmessage)
-       byte_data_sent <= 8'h5A;  // dummy byte
-     else
-     if(SCK_fallingedge) begin
-       if(bitcnt==3'b000)
-         byte_data_sent <= input_data; // after that, we send whatever we get
-       else
-         byte_data_sent <= {byte_data_sent[6:0], 1'b0};
-     end
-   end
+/*always @(posedge clk) begin
+  if(SSEL_active) begin
+    if(SSEL_startmessage)
+      byte_data_sent <= 8'h5A;  // dummy byte
+    else
+      if(SCK_fallingedge) begin
+        if(bitcnt==3'b000)
+          byte_data_sent <= input_data; // after that, we send whatever we get
+        else
+          byte_data_sent <= {byte_data_sent[6:0], 1'b0};
+      end
+  end
+end
+*/
+always @(negedge SCK) begin
+  if(~SSEL) begin
+    if(bitcnt==3'b000)
+	   byte_data_sent <= input_data;
+	 else
+	   byte_data_sent <= {byte_data_sent[6:0], 1'b0};
+  end
 end
 
-assign MISO = SSEL_active ? byte_data_sent[7] : 1'bZ;  // send MSB first
+assign MISO = ~SSEL ? input_data[7-bitcnt] /*byte_data_sent[7]*/ : 1'bZ;  // send MSB first
 
 reg cmd_ready_r;
 reg param_ready_r;
@@ -119,23 +142,23 @@ assign cmd_data = cmd_data_r;
 assign param_data = param_data_r;
 assign byte_cnt = byte_cnt_r;
 
-always @(posedge clk) cmd_ready_r2 = byte_received && byte_cnt_r == 32'h0;
-always @(posedge clk) param_ready_r2 = byte_received && byte_cnt_r > 32'h0;
+always @(posedge clk) cmd_ready_r2 = byte_received_sync && byte_cnt_r == 32'h0;
+always @(posedge clk) param_ready_r2 = byte_received_sync && byte_cnt_r > 32'h0;
 
 // fill registers
 always @(posedge clk) begin
-   if (SSEL_startmessage)
-      cmd_data_r <= 8'h00;
-   else if(cmd_ready_r2)
-      cmd_data_r <= byte_data_received;
-   else if(param_ready_r2)
-      param_data_r <= byte_data_received;
+  if (SSEL_startmessage)
+    cmd_data_r <= 8'h00;
+  else if(cmd_ready_r2)
+    cmd_data_r <= byte_data_received;
+  else if(param_ready_r2)
+    param_data_r <= byte_data_received;
 end
 
 // delay ready signals by one clock (why did I do this again...)
 always @(posedge clk) begin
-   cmd_ready_r <= cmd_ready_r2;
-   param_ready_r <= param_ready_r2;
+  cmd_ready_r <= cmd_ready_r2;
+  param_ready_r <= param_ready_r2;
 end
 
 endmodule