Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module gd_emu (
- CLK50M,
- gd_data, gd_addr, gd_rd_n, gd_wr_n, gd_dma_ack_n, gd_dma_rq, gd_int_rq, gd_iordy, gd_cs, gd_rst_n, // GD-Rom stuff.
- gd_cdlrck, gd_cdda_clk, gd_cdbck, gd_cdda_data, gd_cdda_emph, // CDDA stuff.
- RST_KEY_n, dc_rst_n,
- SRAM_ADDR,
- SRAM_DATA,
- SRAM_CS_n,
- SRAM_OE_n,
- SRAM_WE_n,
- SRAM_UB_n,
- SRAM_LB_n,
- SDRAM_CLK,//connected to the clk port of SDRAM
- SDRAM_CKE,//connected to the cke port of SDRAM
- SDRAM_CS_n,//connected to the CS_n port of SDRAM
- SDRAM_RAS_n,//connected to the RAS_n port of SDRAM
- SDRAM_CAS_n,//connected to the CAS_n port of SDRAM
- SDRAM_WE_n,//connected to the WE_n port of SDRAM
- SDRAM_DQM,//connected to the LDQM port of SDRAM
- SDRAM_BA,//connected to the BA port of SDRAM
- SDRAM_ADDR,//connected to the ADDR port of SDRAM
- SDRAM_DQ,//connected to the DQ port of SDRAM
- SD_CS_n, SD_CLK, SD_DATA_IN, SD_DATA_OUT,
- SEG_S, SEG,
- LED0,
- AUD_I2C_SCK,
- AUD_I2C_DAT,
- AUD_BCLK,
- AUD_DACLRC,
- AUD_DACDAT,
- AUD_MCLK,
- USB_TXE_n, USB_RXF_n, USB_RD_n, USB_WR, USB_DATA,
- gd_state);
- input wire CLK50M; // Master clock input
- input RST_KEY_n;
- output dc_rst_n = RST_KEY_n_buf; // Connect RST_KEY_n button to Dreamcast Reset!
- output [3:0] SEG_S;
- output [7:0] SEG;
- output wire LED0;
- output wire AUD_I2C_SCK;
- inout wire AUD_I2C_DAT;
- input wire AUD_BCLK;
- input wire AUD_DACLRC;
- output wire AUD_DACDAT;
- output reg AUD_MCLK;
- input wire USB_TXE_n;
- input wire USB_RXF_n;
- output wire USB_RD_n;
- output wire USB_WR;
- inout wire [7:0] USB_DATA;
- // SRAM pins...
- output wire SRAM_CS_n = 1'b0; // Might as well assert all of these...
- output wire SRAM_UB_n = 1'b0;
- output wire SRAM_LB_n = 1'b0;
- output wire [18:0] SRAM_ADDR;
- output wire SRAM_OE_n;
- output wire SRAM_WE_n;
- inout wire [15:0] SRAM_DATA;
- // SDRAM pins...
- output SDRAM_CLK;
- output SDRAM_CKE;
- output SDRAM_CS_n;
- output SDRAM_RAS_n;
- output SDRAM_CAS_n;
- output SDRAM_WE_n;
- output [1: 0] SDRAM_DQM;
- output [1 :0] SDRAM_BA;
- output [12:0] SDRAM_ADDR;
- inout [15:0] SDRAM_DQ;
- // SD interface pins and regs...
- output SD_CS_n;
- output SD_CLK;
- input SD_DATA_IN;
- output SD_DATA_OUT;
- reg trig_block_read;
- // GD Interface pins and regs...
- reg gd_wr_n_1, gd_wr_n_2; // Flip-flops for detecting async edges.
- reg gd_rd_n_1, gd_rd_n_2;
- wire gd_wr_rising = gd_wr_n_1 & ~gd_wr_n_2;
- wire gd_rd_rising = gd_rd_n_1 & ~gd_rd_n_2;
- wire gd_wr_falling = ~gd_wr_n_1 & gd_wr_n_2;
- wire gd_rd_falling = ~gd_rd_n_1 & gd_rd_n_2;
- input wire gd_rst_n/* synthesis noprune */;
- input wire [1:0] gd_cs/* synthesis noprune */;
- input wire [2:0] gd_addr/* synthesis noprune */;
- input wire gd_rd_n/* synthesis noprune */;
- input wire gd_wr_n/* synthesis noprune */;
- input wire gd_dma_ack_n/* synthesis noprune */; // Need this signal so we can drive the output buffer during DMA transfers.
- reg [15:0] gd_data_write/* synthesis noprune */;
- reg rom_route; // ROM route (route reply ROM output directly to GD-ROM data input).
- // Mux for routing data from either the reply ROM, or from internally generated data.
- wire [15:0] gd_data_out = rom_route ? reply_rom_data : gd_data_write;
- // Address decoder for register READS...
- // The top byte is set to 0xFF for all 8-bit regs (this is what the Dreamcast does).
- wire [15:0] gd_reg_mux = ({gd_cs, gd_addr} == 5'b11000) ? sector_data : // DMA Channel !
- ({gd_cs, gd_addr} == 5'b010xx) ? 16'bz : // High-Z
- ({gd_cs, gd_addr} == 5'b0110x) ? 16'bz : // High-Z
- ({gd_cs, gd_addr} == 5'b01110) ? {8'hff, gd_status_reg} : // ALTSTATUS reg (same read as status reg).
- ({gd_cs, gd_addr} == 5'b01111) ? 16'bz : // Drive Address (not used?)
- ({gd_cs, gd_addr} == 5'b10000) ? gd_data_out : // Data reg
- ({gd_cs, gd_addr} == 5'b10001) ? {8'hff, gd_error_reg} : // Error reg
- ({gd_cs, gd_addr} == 5'b10010) ? {8'hff, gd_intreason_reg} : // IntReason reg
- ({gd_cs, gd_addr} == 5'b10011) ? {8'hff, gd_secnumber_reg} : // SecNumber reg / LBA0
- ({gd_cs, gd_addr} == 5'b10100) ? {8'hff, gd_bytecount_low} : // BYTCLLO reg / LBA1
- ({gd_cs, gd_addr} == 5'b10101) ? {8'hff, gd_bytecount_high} : // BYTCLHI reg / LBA2
- ({gd_cs, gd_addr} == 5'b10110) ? {8'hff, gd_drivesel_reg} : // Drivesel reg / LBA3
- ({gd_cs, gd_addr} == 5'b10111) ? {8'hff, gd_status_reg} : // Status reg
- 16'hzz/* synthesis noprune */; // Else, High-Z
- // Note: Forcing Output Enable when "gd_dma_ack_n" is low (DC should have setup the DMA path before this happens!).
- // wire gd_oe = ((!gd_cs[1] || !gd_cs[0]) || !gd_dma_ack_n) && !gd_rd_n/* synthesis noprune */;
- wire gd_oe = (!gd_cs[1] || !gd_cs[0]) && !gd_rd_n || !gd_dma_ack_n/* synthesis noprune */; // TESTING !! Force OE when !gd_dma_ack_n.
- reg gd_int_rq_reg;
- // reg gd_dma_rq_reg;
- reg [8:0] cdda_clk_div; // Divider to generate "cdbck" and "cdlrck" from "cdda_clk_pll".
- // Note: Anything which is normally an OUTPUT from GD-ROM -> Dreamcast is made an inout (bi-dir), so we
- // can change the lines below for either Spy mode (GD-ROM drive is plugged in - high-z for monitoring only),
- // or Emu mode (FPGA output regs are routed to the Dreamcast).
- // inout wire gd_cdda_clk = 1'bz/* synthesis noprune */; // Spy mode !!
- // inout wire gd_cdbck = 1'bz/* synthesis noprune */; // Spy mode !!
- // inout wire gd_cdlrck = 1'bz/* synthesis noprune */; // Spy mode !!
- // inout wire gd_cdda_data = 1'bz/* synthesis noprune */; // Spy mode !!
- // inout wire gd_cdda_emph = 1'bz/* synthesis noprune */; // Spy mode !!
- // inout wire gd_dma_rq = 1'bz/* synthesis noprune */; // Spy mode !!
- // inout wire gd_int_rq = 1'bz/* synthesis noprune */; // Spy mode !!
- // inout wire gd_iordy = 1'bz/* synthesis noprune */; // Spy mode !!
- // inout wire [15:0] gd_data = 16'bz/* synthesis noprune */; // Spy mode !!
- // AICA needs "cdda_clk" (~33.8688MHz), or DC won't start up!...
- inout wire gd_cdda_clk = cdda_clk_pll; // Emu mode (GD-ROM drive MUST be unplugged first!)
- inout wire gd_cdbck = cdda_clk_div[3]; // Emu mode (GD-ROM drive MUST be unplugged first!)
- inout wire gd_cdlrck = cdda_clk_div[8]; // Emu mode (GD-ROM drive MUST be unplugged first!)
- inout wire gd_cdda_data = 1'b0; // Emu mode (GD-ROM drive MUST be unplugged first!)
- inout wire gd_cdda_emph = 1'b0; // Emu mode (GD-ROM drive MUST be unplugged first!)
- inout wire gd_dma_rq = cont_dma_rq; // Emu mode (GD-ROM drive MUST be unplugged first!)
- inout wire gd_int_rq = gd_int_rq_reg; // Emu mode (GD-ROM drive MUST be unplugged first!)
- inout wire gd_iordy = 1'b1; // Emu mode (GD-ROM drive MUST be unplugged first!)
- inout wire [15:0] gd_data = gd_oe ? gd_reg_mux : 16'bz; // Emu mode (GD-ROM drive MUST be unplugged first!)
- // reg [9:0] gd_pio_state;
- reg [9:0] gd_dma_state;
- reg [9:0] gd_reply_state;
- output reg [9:0] gd_state/* synthesis noprune */;
- reg [15:0] ata_cmd_count/* synthesis noprune */;// VERY handy for SignalTap debugging!
- reg [15:0] packet_cmd_count/* synthesis noprune */;// VERY handy for SignalTap debugging!
- // GD-Rom ATA regs...
- reg [7:0] gd_ata_cmd;
- reg [7:0] gd_bytecount_low;
- reg [7:0] gd_bytecount_high;
- reg [7:0] gd_drivesel_reg;
- reg [7:0] gd_features_reg/* synthesis noprune */; // LSB indicates next data transfer is via DMA !
- reg [7:0] gd_status_reg;
- reg [7:0] gd_error_reg;
- reg [7:0] gd_seccount_reg;
- reg [7:0] gd_intreason_reg;
- reg [7:0] gd_secnumber_reg;
- // GD-Rom Packet regs...
- reg [15:0] packet_1/* synthesis noprune */; // TODO - Maybe start WORD count from zero next time. :)
- reg [15:0] packet_2/* synthesis noprune */;
- reg [15:0] packet_3/* synthesis noprune */;
- reg [15:0] packet_4/* synthesis noprune */;
- reg [15:0] packet_5/* synthesis noprune */;
- reg [15:0] packet_6/* synthesis noprune */;
- wire [7:0] packet_0b = packet_1[7:0]/* synthesis noprune */;
- wire [7:0] packet_1b = packet_1[15:8]/* synthesis noprune */;
- wire [7:0] packet_2b = packet_2[7:0]/* synthesis noprune */;
- wire [7:0] packet_3b = packet_2[15:8]/* synthesis noprune */;
- wire [7:0] packet_4b = packet_3[7:0]/* synthesis noprune */;
- wire [7:0] packet_5b = packet_3[15:8]/* synthesis noprune */;
- wire [7:0] packet_6b = packet_4[7:0]/* synthesis noprune */;
- wire [7:0] packet_7b = packet_4[15:8]/* synthesis noprune */;
- wire [7:0] packet_8b = packet_5[7:0]/* synthesis noprune */;
- wire [7:0] packet_9b = packet_5[15:8]/* synthesis noprune */;
- wire [7:0] packet_10b = packet_6[7:0]/* synthesis noprune */;
- wire [7:0] packet_11b = packet_6[15:8]/* synthesis noprune */;
- reg [11:0] gd_sector_type/* synthesis noprune */; // No point wasting bits! (OzOnE).
- reg [31:0] gd_start_sector;
- reg [31:0] gd_sector_count/* synthesis noprune */; // Warning - not to be confused with the ATA "gd_seccount_reg"!
- // Note: Using "gd_secnumber_reg" to store DiscFormat and GD_status codes. OzOnE.
- reg [3:0] gd_discformat; // Only using nibble!
- reg [3:0] cdda_repeats; // Only using nibble!
- reg [23:0] cdda_curraddr; // Using full three bytes together (need to part select when needed). OzOnE.
- reg [7:0] stat [0:9]; // Array of bytes for sending REQ_STAT reply.
- reg [7:0] resp [0:9]; // Array of bytes for sending REQ_ERROR reply.
- reg [7:0] mode [0:31]; // Array of bytes for storing REQ_MODE / SET_MODE info.
- reg [9:0] reply_rom_addr;
- reg toc_density/* synthesis noprune */;
- reg [3:0] scd_format;
- reg [15:0] alloc_length/* synthesis noprune */;
- reg [15:0] byte_count/* synthesis noprune */;
- // GD-Rom ATA Commands
- parameter ATA_NOP = 8'h00;
- parameter ATA_SOFT_RESET = 8'h08;
- parameter ATA_EXEC_DIAG = 8'h90;
- parameter ATA_SPI_PACKET = 8'hA0;
- parameter ATA_IDENTIFY_DEV = 8'hA1;
- parameter ATA_SET_FEATURES = 8'hEF;
- // GD-Rom SPI (Sega Packet Interface) Commands
- parameter SPI_TEST_UNIT = 8'h00;
- parameter SPI_REQ_STAT = 8'h10;
- parameter SPI_REQ_MODE = 8'h11;
- parameter SPI_SET_MODE = 8'h12;
- parameter SPI_REQ_ERROR = 8'h13;
- parameter SPI_GET_TOC = 8'h14;
- parameter SPI_REQ_SES = 8'h15;
- parameter SPI_CD_OPEN = 8'h16;
- parameter SPI_CD_PLAY = 8'h20;
- parameter SPI_CD_SEEK = 8'h21;
- parameter SPI_CD_SCAN = 8'h22;
- parameter SPI_CD_READ = 8'h30;
- parameter SPI_CD_READ2 = 8'h31;
- parameter SPI_GET_SCD = 8'h40;
- // Using nibbles for status! OzOnE.
- parameter GD_BUSY = 4'h0; // State transition
- parameter GD_PAUSE = 4'h1; // Pause
- parameter GD_STANDBY = 4'h2; // Standby (drive stop)
- parameter GD_PLAY = 4'h3; // CD playback
- parameter GD_SEEK = 4'h4; // Seeking
- parameter GD_SCAN = 4'h5; // Scanning
- parameter GD_OPEN = 4'h6; // Tray is open
- parameter GD_NODISC = 4'h7; // No disc
- parameter GD_RETRY = 4'h8; // Read retry in progress (option)
- parameter GD_ERROR = 4'h9; // Reading of disc TOC failed (state does not allow access)
- always @(posedge cdda_clk_pll) cdda_clk_div <= cdda_clk_div + 9'd1;
- reg RST_KEY_n_buf;
- always @(posedge CLK50M) RST_KEY_n_buf <= RST_KEY_n;
- reg gd_rst_n_2;
- reg gd_rst_n_1;
- wire gd_rst_n_buf = (gd_rst_n_2 || gd_rst_n_1 || gd_rst_n); // "gd_rst_n_buf" LOW when "gd_rst_n" AND both regs are low (smooth out glitches).
- // Dependent on whether "gd_rst_n" goes low for three or more clocks though!!
- always @(posedge CLK50M) begin
- gd_rst_n_1 <= gd_rst_n; // Update edge regs on every clock.
- gd_rst_n_2 <= gd_rst_n_1;
- end
- initial begin
- // gd_oe <= 1'b0;
- rom_route <= 1'b0;
- gd_state <= 10'd0;
- gd_ata_cmd <= 8'h00;
- // gd_dma_rq_reg <= 1'b0; // De-assert GD DMA Request !
- reply_rom_addr <= 10'h000;
- gd_dma_state <= 10'd0;
- gd_status_reg <= 8'h00; // SPI Doc says to set these on reset (gd_status_reg must be 0x00 == RESET!).
- // gd_error_reg <= 8'h01;
- gd_error_reg <= 8'h00;
- gd_seccount_reg <= 8'h01;
- gd_secnumber_reg <= 8'h00; // Set to zero!!
- gd_bytecount_low <= 8'h14;
- gd_bytecount_high <= 8'hEB;
- gd_drivesel_reg <= 8'h00;
- gd_intreason_reg <= 8'h00;
- gd_int_rq_reg <= 1'b0;
- gd_sector_type <= 12'd0;
- gd_start_sector <= 32'd0;
- gd_sector_count <= 32'd0;
- // gd_secnumber_reg <= 8'h86; // <- Top nibble is DiscFormat, bottom nibble is unit status...
- // Set to GD-ROM and leave tray open for now (TESTING).
- // gd_secnumber_reg <= 8'h06; // <- Top nibble is DiscFormat, bottom nibble is unit status...
- // Set to CD-DA (default / no disk) and leave tray open for now (TESTING).
- ata_cmd_count <= 16'd0;
- packet_cmd_count <= 16'd0;
- packet_1 <= 16'h0000;
- packet_2 <= 16'h0000;
- packet_3 <= 16'h0000;
- packet_4 <= 16'h0000;
- packet_5 <= 16'h0000;
- packet_6 <= 16'h0000;
- trig_block_read <= 1'b0; // De-assert block read trigger (for SD Card reading).
- end
- always @(posedge CLK50M or negedge gd_rst_n)
- if (!gd_rst_n) begin
- // gd_oe <= 1'b0;
- rom_route <= 1'b0;
- cdda_repeats <= 4'd0;
- gd_dma_state <= 10'd0;
- gd_ata_cmd <= 8'h00;
- // gd_dma_rq_reg <= 1'b0; // De-assert GD DMA Request !
- reply_rom_addr <= 10'h000;
- gd_status_reg <= 8'h00; // SPI Doc says to set these on reset (gd_status_reg must be 0x00 == RESET!).
- // gd_error_reg <= 8'h01;
- gd_error_reg <= 8'h00;
- gd_seccount_reg <= 8'h01;
- gd_secnumber_reg <= 8'h00; // Set to zero!!
- gd_bytecount_low <= 8'h14;
- gd_bytecount_high <= 8'hEB;
- gd_drivesel_reg <= 8'h00;
- gd_intreason_reg <= 8'h00;
- gd_int_rq_reg <= 1'b0;
- gd_sector_type <= 12'd0;
- gd_start_sector <= 32'd0;
- gd_sector_count <= 32'd0;
- // gd_secnumber_reg <= 8'h86; // <- Top nibble is DiscFormat, bottom nibble is unit status...
- // Set to GD-ROM and leave tray open for now (TESTING).
- // gd_secnumber_reg <= 8'h07; // <- Top nibble is DiscFormat, bottom nibble is unit status...
- // Set to CD-DA (default DiscFormat for no disk?) and GD_NODISC state.
- // "DiscFormat" top nibble...
- // 0 == CD-DA.
- // 1 == CD-ROM.
- // 2 == CD-ROM XA, CD Extra
- // 3 == CD-I
- // 8 == GD-ROM. <- IMPORTANT - MSB is set, NOT bit 6!!
- // "Unit Status" bottom nibble...
- // GD_BUSY 0x00 // State transition
- // GD_PAUSE 0x01 // Pause
- // GD_STANDBY 0x02 // Standby (drive stop)
- // GD_PLAY 0x03 // CD playback
- // GD_SEEK 0x04 // Seeking
- // GD_SCAN 0x05 // Scanning
- // GD_OPEN 0x06 // Tray is open
- // GD_NODISC 0x07 // No disc
- // GD_RETRY 0x08 // Read retry in progress (option)
- // GD_ERROR 0x09 // Reading of disc TOC failed (state does not allow access)
- /*
- // nullDC original mode settings...
- {mode[1],mode[0]} <= 16'h0000;
- {mode[3],mode[2]} <= 16'h0000; // Byte 2 is the "CD-ROM Speed" value. 0=MAX, 1=STANDARD, 2=x2, 3=x4, 4=x6, 5=x8, 6=x10, 7=x12.
- {mode[5],mode[4]} <= 16'hB400; // Word [4:5] is the DEFAULT Standby timeout value. 0x00B4 == 180 seconds = only 3 minutes!
- {mode[7],mode[6]} <= 16'h0019;
- {mode[9],mode[8]} <= 16'h0800;
- {mode[11],mode[10]} <= 16'h4553;
- {mode[13],mode[12]} <= 16'h2020;
- {mode[15],mode[14]} <= 16'h2020;
- {mode[17],mode[16]} <= 16'h2020;
- {mode[19],mode[18]} <= 16'h6552;
- {mode[21],mode[20]} <= 16'h2076;
- {mode[23],mode[22]} <= 16'h2E36;
- // {mode[25],mode[24]} <= 16'h3334; // TESTING - Change it to this...
- {mode[25],mode[24]} <= 16'h3234; // <- To reflect the mode from my DC. OzOnE.
- {mode[27],mode[26]} <= 16'h3939;
- {mode[29],mode[28]} <= 16'h3430;
- {mode[31],mode[30]} <= 16'h3830;
- */
- // My modified mode settings (for Crazy Taxi)...
- {mode[1],mode[0]} <= 16'h0000;
- {mode[3],mode[2]} <= 16'h0000;
- {mode[5],mode[4]} <= 16'h100E; // <- Only this appears different from the nullDC Mode words.
- // Word [4:5] is the Standby timeout value. 0x0E10 == 3600 seconds = 60 minutes!
- {mode[7],mode[6]} <= 16'h0019;
- {mode[9],mode[8]} <= 16'h0800;
- {mode[11],mode[10]} <= 16'h4553;
- {mode[13],mode[12]} <= 16'h2020;
- {mode[15],mode[14]} <= 16'h2020;
- {mode[17],mode[16]} <= 16'h2020;
- {mode[19],mode[18]} <= 16'h6552;
- {mode[21],mode[20]} <= 16'h2076;
- {mode[23],mode[22]} <= 16'h2E36;
- {mode[25],mode[24]} <= 16'h3334; // TESTING - Change it to this...
- // {mode[25],mode[24]} <= 16'h3234; // <- To reflect the mode from my DC. OzOnE.
- {mode[27],mode[26]} <= 16'h3939;
- {mode[29],mode[28]} <= 16'h3430;
- {mode[31],mode[30]} <= 16'h3830;
- ata_cmd_count <= 16'd0;
- packet_cmd_count <= 16'd0;
- packet_1 <= 16'h0000;
- packet_2 <= 16'h0000;
- packet_3 <= 16'h0000;
- packet_4 <= 16'h0000;
- packet_5 <= 16'h0000;
- packet_6 <= 16'h0000;
- trig_block_read <= 1'b0; // De-assert block read trigger (for SD Card reading).
- end
- else begin
- gd_wr_n_1 <= gd_wr_n; // Update edge regs on every clock.
- gd_wr_n_2 <= gd_wr_n_1;
- gd_rd_n_1 <= gd_rd_n;
- gd_rd_n_2 <= gd_rd_n_1;
- // Handle reg READS... (now using address decoder above for reg reads, but still need to clear interrupt)...
- // ALTSTATUS also reads "gd_status_reg" (assigned above), but Interrupt is NOT cleared.
- if ({gd_cs, gd_addr} == 5'b10111 && gd_rd_falling) begin // READ from STATUS reg.
- gd_int_rq_reg <= 1'b0; // Clear interrupt on status read.
- end
- // if ({gd_cs, gd_addr} == 5'b10011 && gd_rd_falling) begin // READ from SECNUM reg.
- // if (gd_secnumber_reg[3:0] == GD_PLAY) gd_secnumber_reg[3:0] <= GD_PAUSE; // If PREVIOUS CD_READ set to PLAY, set back to PAUSE!
- // end
- // Handle reg WRITES...
- if ({gd_cs, gd_addr} == 5'b10001 && gd_wr_rising) begin // WRITE to "gd_features_reg".
- gd_features_reg <= gd_data[7:0];
- end
- if ({gd_cs, gd_addr} == 5'b10010 && gd_wr_rising) begin // WRITE to "gd_seccount_reg".
- gd_seccount_reg <= gd_data[7:0];
- end
- // Write to secnumber not possible apparently? OzOnE (nullDC source said).
- /* if (gd_cs == 2'd2 && gd_addr == 3'd3 && gd_wr_rising) begin // WRITE to "gd_secnumber_reg".
- gd_secnumber_reg <= gd_data[7:0];
- end */
- if ({gd_cs, gd_addr} == 5'b10100 && gd_wr_rising) begin // WRITE to "gd_bytecount_low" reg.
- gd_bytecount_low <= gd_data[7:0];
- end
- if ({gd_cs, gd_addr} == 5'b10101 && gd_wr_rising) begin // WRITE to "gd_bytecount_high" reg.
- gd_bytecount_high <= gd_data[7:0];
- end
- if ({gd_cs, gd_addr} == 5'b10110 && gd_wr_rising) begin // WRITE to "gd_drivesel" reg. Is this even needed??
- gd_drivesel_reg <= gd_data[7:0];
- end
- if ({gd_cs, gd_addr} == 5'b01110 && gd_wr_rising) begin // WRITE to DRIVECTRL reg.
- if (gd_data[7:0] == ATA_SOFT_RESET) gd_state <= 1; // If 0x08 is written to DRIVECTRL reg, bring out of reset state.
- end
- if ({gd_cs, gd_addr} == 5'b10111 && gd_wr_rising) begin // WRITE to COMMAND reg. (need this here, as soft reset can be written at any time!)
- if (gd_data[7:0] == ATA_SOFT_RESET) gd_state <= 1; // If 0x08 is written to DRIVECTRL reg, bring out of reset state.
- end
- case (gd_state)
- 0: begin // RESET state (wait for Soft Reset cmd in COMMAND or DRIVECTRL reg, above).
- gd_status_reg <= 8'h00;
- end
- 1: begin // "gds_waitcmd" (wait for ATA command).
- trig_block_read <= 1'b0; // Clear SD-to-DC DMA trigger !
- gd_status_reg[6] <= 1'b1; // Set DRDY bit - Can accept an ATA cmd :)
- gd_status_reg[7] <= 1'b0; // Clear BSY bit - Not currently accessing the command block.
- gd_status_reg[3] <= 1'b0; // Clear DRQ.
- gd_status_reg[4] <= 1'b1; // Set DSC bit (Seek complete) TESTING !!
- if (gd_cs == 2'd2 && gd_addr == 3'd7 && gd_wr_rising) begin // WRITE to COMMAND reg.
- gd_ata_cmd <= gd_data[7:0];
- // "gds_procata"
- // gd_status_reg[6] <= 1'b0; // Clear DRDY bit - Can't accept another ATA cmd (while processing).
- gd_status_reg[7] <= 1'b1; // Set BSY bit - Accessing the command block.
- ata_cmd_count <= ata_cmd_count + 16'd1;
- gd_state <= 10'd2; // Parse ATA command!
- end
- end
- 2: begin
- //Any ata cmd clears these bits , unless aborted/error :p
- gd_error_reg[2] <= 1'b0; // Clear ABRT bit.
- gd_status_reg[0] <= 1'b0; // Clear CHECK bit.
- case (gd_ata_cmd)
- ATA_NOP: begin
- gd_error_reg[2] <= 1'b1; // SET the ABORT bit.
- //Error.Sense=0x00; //fixme ?
- gd_status_reg[7] <= 1'b0; // Clear the BUSY bit.
- gd_status_reg[0] <= 1'b1; // SET the CHECK bit.
- gd_int_rq_reg <= 1'b1; // Raise an int!
- gd_state <= 10'd1;
- end
- ATA_SOFT_RESET: begin // Do "gd_reset" stuff, just does "gd_setdisc" to grab disc type,
- // it then sets the correct status and updates the secnumber reg with the status.
- gd_secnumber_reg <= 8'h80; // Set DiscFormat to GD-ROM, set unit Status to 0 (GD_BUSY!).
- gd_state <= 10'd1; // Then, just goes to "gds_waitcmd" (state 1).
- end
- ATA_EXEC_DIAG: gd_state <= 10'd1; // (Unimplemented in nullDC). OzOnE
- ATA_SPI_PACKET: begin // PACKET command! (Sega type, duh!)
- // Do "gds_waitpacket" stuff...
- gd_intreason_reg[0] <= 1'b1; // Set CoD
- gd_status_reg[7] <= 1'b0; // Clear BSY bit.
- gd_intreason_reg[1] <= 1'b0; // Clear IO int bit.
- gd_status_reg[3] <= 1'b1; // Set DRQ (ready for command packet transfer).
- // gd_int_rq_reg <= 1'b1; // ATA can optionally raise the interrupt ... (nullDC doesn't raise an int).
- if (gd_addr == 3'd0 && gd_wr_rising) begin // If in DATA reg on RISING edge of "gd_wr_n"...
- packet_1 <= gd_data; // Grab packet WORD 1.
- packet_cmd_count <= packet_cmd_count + 16'd1;
- gd_state <= 10'd3;
- end
- end
- ATA_IDENTIFY_DEV: begin
- reply_rom_addr <= packet_2b / 2; // Start reply ROM address at "reply_a1" offset + requested start offset.
- // (WORD addressed! - divide by two).
- byte_count <= 16'd0; // Zero the byte count.
- alloc_length <= {8'h00, packet_4b}; // (Bytes).
- gd_bytecount_high <= 8'h00;
- gd_bytecount_low <= packet_4b;
- gds_pio_send_data(); // Int, to start transfer. "When preparations are complete...".
- gd_state <= 10'd10; // Generate 0xa1 reply from ROM (will go back to idle after transfer).
- end
- ATA_SET_FEATURES: begin // Not to be confused with a write to "gd_features_reg"!
- gd_error_reg[2] <= 1'b0; // Clear ABRT error bit - Command was not aborted ;) [hopefully ...]
- //status : Clear DRDY , DSC , DF , CHECK <- Not sure if DRDY is supposed to be set here? OzOnE.
- //DRDY is set on state change
- // gd_status_reg[4] <= 1'b0; // Clear DSC status bit.
- gd_status_reg[5] <= 1'b0; // Clear DF status bit.
- gd_status_reg[0] <= 1'b0; // Clear CHECK status bit.
- gd_int_rq_reg <= 1'b1; //??? Raise int (I think? This is what nullDC source does, OzOnE).
- gd_state <= 10'd1; // Back to "gds_waitcmd" (state 1).
- end
- default: gd_state <= 10'd1; // Unhandled ATA command, back to idle.
- endcase
- end
- 3: if (gd_addr == 3'd0 && gd_wr_rising) begin
- packet_2 <= gd_data; // Grab packet WORD 2.
- gd_state <= 10'd4;
- end
- 4: if (gd_addr == 3'd0 && gd_wr_rising) begin
- packet_3 <= gd_data; // Grab packet WORD 3.
- gd_state <= 10'd5;
- end
- 5: if (gd_addr == 3'd0 && gd_wr_rising) begin
- packet_4 <= gd_data; // Grab packet WORD 4.
- gd_state <= 10'd6;
- end
- 6: if (gd_addr == 3'd0 && gd_wr_rising) begin
- packet_5 <= gd_data[7:0]; // Grab packet WORD 5.
- gd_state <= 10'd7;
- end
- 7: if (gd_addr == 3'd0 && gd_wr_rising) begin
- packet_6 <= gd_data[7:0]; // Grab packet WORD 6.
- gd_state <= 10'd8;
- end
- // ***** PARSE the SPI (Sega Packet Interface) command packet *****
- // *****
- 8: begin
- // (Similar stage to "gd_process_spi_cmd()" in nullDC source.)
- gd_status_reg[0] <= 1'b0; // Clear CHECK bit.
- // Do "gds_procpacket" bit settings first!...
- // 6. After last packet word is received - DRQ is cleared, BUSY bit is set.
- gd_status_reg[3] <= 1'b0; // Clear DRQ (no data req <= shouldn't this be RDY bit, OzOnE?
- gd_status_reg[7] <= 1'b1; // Set BSY bit - Accessing command block to process command (no ATA commands while processing).
- case (packet_0b) // <- (byte addressing starts at zero!)
- SPI_TEST_UNIT: begin
- gd_secnumber_reg[7:4] <= 4'h8; // Set to GD-ROM DiscFormat type. (OzOnE).
- gd_secnumber_reg[3:0] <= GD_BUSY; // Drive is ready! (nullDC).
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- // (No data to send for "TEST_UNIT").
- end
- SPI_REQ_STAT: begin // *** TODO - "gd_status" stuff! ***
- stat[0] <= {4'h0, gd_secnumber_reg[3:0]}; // Status is low nibble (force top bits to zero).
- stat[1] <= {gd_secnumber_reg[7:4], cdda_repeats}; // Top nibble is "DiscFormat" - forcing to GD-ROM after 0x71 check. (libGDR normally grabs it. OzOnE)
- stat[2] <= 8'h04; // ? This is what nullDC does?
- stat[3] <= 8'd02; // TNO
- stat[4] <= 8'd00; // X
- // stat[5] <= cdda_curraddr[23:16]; // Current FAD (MSB?)
- // stat[6] <= cdda_curraddr[15:8]; // Current FAD
- // stat[7] <= cdda_curraddr[7:0]; // Current FAD (LSB?)
- // NOTE: The CF Card version pauses at the normal CD FAD!! (maybe it pauses at the GD FAD only for GD-Audio ???)...
- stat[5] <= 8'h00; // Current FAD (MSB?) Default FAD for a CD - drive pauses at 2 second, 0 frames (75 FPS, so 150 = 0x96).
- stat[6] <= 8'h00; // Current FAD
- stat[7] <= 8'h96; // Current FAD (LSB?)
- // stat[5] <= 8'h00; // Current FAD (MSB?) Default FAD for GD! - drive pauses at 10 mins, 2 secs, 0 frames (75 FPS, so 45150 = 0xB05E).
- // stat[6] <= 8'hB0; // Current FAD
- // stat[7] <= 8'h5E; // Current FAD (LSB?)
- stat[8] <= 8'd00; // Max Read Error Retry Times.
- stat[9] <= 8'd00; // All bits zeros.
- // DiscFormat...
- // 0 == CD-DA.
- // 1 == CD-ROM.
- // 2 == CD-ROM XA, CD Extra
- // 3 == CD-I
- // 8 == GD-ROM.
- byte_count <= 16'd0; // Zero the byte count.
- alloc_length <= {8'h00, packet_4b}; // (Bytes).
- gd_bytecount_high <= 8'h00;
- gd_bytecount_low <= packet_4b;
- gds_pio_send_data(); // Int, to start transfer. "When preparations are complete...".
- gd_state <= 10'd13; // Generate REQ_STAT reply.
- end
- SPI_REQ_MODE: begin
- reply_rom_addr <= (10'h50 + packet_2b) / 2; // Start reply ROM address at "reply_11" offset + requested start offset.
- // (WORD addressed! - divide by two).
- byte_count <= 16'd0; // Zero the byte count.
- alloc_length <= {8'h00, packet_4b}; // (Bytes).
- gd_bytecount_high <= 8'h00;
- gd_bytecount_low <= packet_4b;
- gds_pio_send_data(); // Int, to start transfer. "When preparations are complete...".
- gd_state <= 10'd15; // Generate 0x11 reply from ROM (will go back to idle after transfer).
- end
- SPI_SET_MODE: begin
- byte_count <= 16'd0; // Zero the byte count.
- alloc_length <= {8'h00, packet_4b}; // (Bytes).
- // When preparations are complete, the following steps are carried out at the device.
- //(1) Number of bytes to be read is set in "Byte Count" register.
- gd_bytecount_high <= 8'h00;
- gd_bytecount_low <= packet_4b;
- //(2) IO bit is set and CoD bit is cleared.
- gd_intreason_reg[1] <= 1'b0; // Clear IO bit. <- MUST be cleared for transfer from GD -> DC !!
- gd_intreason_reg[0] <= 1'b0; // Clear CoD bit.
- //(3) DRQ bit is set, BSY bit is cleared.
- gd_status_reg[3] <= 1'b1; // Set DRQ bit.
- gd_status_reg[7] <= 1'b0; // Clear BUSY bit.
- //(4) INTRQ is set, and a host interrupt is issued.
- gd_int_rq_reg <= 1'b1;
- gd_status_reg[6] <= 1'b1; // Set DRDY bit (spy log!)
- gd_state <= 10'd16; // Wait for the data, then write it to the mode info regs...
- end
- SPI_REQ_ERROR: begin
- resp[0] <= 8'hF0;
- resp[1] <= 8'h00;
- resp[2] <= gd_secnumber_reg[3:0] == GD_BUSY ? 2:0; //sense (if "secnumber.status" == GD_BUSY, then resp[2] <= 2, else 0). phew!
- resp[3] <= 8'h00;
- resp[4] <= 8'h00; //Command Specific Information
- resp[5] <= 8'h00; //Command Specific Information
- resp[6] <= 8'h00; //Command Specific Information
- resp[7] <= 8'h00; //Command Specific Information
- resp[8] <= 8'h00; //Additional Sense Code
- resp[9] <= 8'h00; //Additional Sense Code Qualifier
- byte_count <= 16'd0; // Zero the byte count.
- alloc_length <= {8'h00, packet_4b}; // (Bytes).
- gd_bytecount_high <= 8'h00;
- gd_bytecount_low <= packet_4b;
- gd_status_reg[0] <= 1'b0; // TESTING !! Assuming it clears the CHECK bit after checking the error? OzOnE.
- gds_pio_send_data(); // Int, to start transfer. "When preparations are complete...".
- gd_state <= 10'd12; // Generate REQ_ERROR reply.
- end
- SPI_GET_TOC: begin // *** TODO - Handle both density TOC types! ***
- toc_density <= packet_1b[0]; // Request TOC from Single-density area (0) or Double-density area (1), LSB of packet_1b!
- byte_count <= 16'd0; // Zero the byte count.
- alloc_length <= {packet_3b, packet_4b}; // Allocation length in bytes (from WORD), usually 0x198 (408 bytes) for the TOC.
- gd_bytecount_high <= packet_3b;
- gd_bytecount_low <= packet_4b;
- gds_pio_send_data(); // Int, to start transfer. "When preparations are complete...".
- gd_state <= 10'd9; // Generate TOC reply (will go back to idle after transfer).
- end
- 8'h70: begin
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end
- 8'h71: begin // Security check?
- reply_rom_addr <= 10'h70 / 2; // Set reply ROM start address directly (WORD addressed! - divide by two).
- byte_count <= 16'd0; // Zero the byte count.
- alloc_length <= 16'h3f4; // Set reply 0x71 alloc length directly (1012 bytes).
- gd_bytecount_high <= 8'h03;
- gd_bytecount_low <= 8'hf4;
- // if (gd_secnumber_reg[7:4] == 4'h8) // If "DiscFormat" == GD-ROM type...
- gd_secnumber_reg[7:4] <= 4'h8; // TESTING !! - Force to GD-ROM disk type at this point. OzOnE.
- gd_secnumber_reg[3:0] <= GD_PAUSE;
- // else
- // gd_secnumber_reg[3:0] <= GD_STANDBY;
- gds_pio_send_data(); // Int, to start transfer. "When preparations are complete...".
- gd_state <= 10'd10; // Generate 0x71 reply from ROM (will go back to idle after transfer).
- end
- SPI_REQ_SES: begin
- byte_count <= 16'd0; // Zero the byte count.
- alloc_length <= {8'h00, packet_4b}; // (Bytes).
- gd_bytecount_high <= 8'h00;
- gd_bytecount_low <= packet_4b;
- gds_pio_send_data(); // Int, to start transfer. "When preparations are complete...".
- gd_state <= 10'd11; // Generate "Session" data reply (will go back to idle after transfer).
- end
- SPI_CD_OPEN: begin // (Unimplemented in nullDC, but still sends status back). OzOnE
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end
- SPI_CD_PLAY: begin
- gds_procpacketdone(); // CD-DA stuff unhandled atm !! OzOnE.
- end
- SPI_CD_SEEK: begin
- gds_procpacketdone(); // CD-DA stuff unhandled atm !! OzOnE.
- end
- SPI_CD_SCAN: begin // (Unimplemented in nullDC, but still sends status back). OzOnE
- gds_procpacketdone(); // CD-DA stuff unhandled atm !! OzOnE.
- end
- SPI_CD_READ: begin
- if (packet_1b[7]==1 && packet_1b[6]==1 && packet_1b[5]==1 && packet_1b[3:1]==3 && packet_1b[4]==0) gd_sector_type <= 12'd2340;
- else gd_sector_type <= 12'd2048;
- if (packet_1b[0]) begin // If "parameter type" == 1 (MSF)...
- gd_start_sector <= (packet_2b*60*75<<16) | (packet_3b*75<<8) | (packet_4b[2]);
- end else
- gd_start_sector <= {packet_2b, packet_3b, packet_4b};
- gd_sector_count <= {packet_8b, packet_9b, packet_10b};
- gd_status_reg[4] <= 1'b1; // Set DSC (Seek Complete) status bit. (Spy Log)
- // if (gd_features_reg[0] == 1) gd_state <= 15; // TODO - Handle PIO as well as DMA from SD to DC! ***
- // else gd_state <= 10'd16; // (It looks like all CD READs are done via DMA anyway.)
- // gd_dma_state <= 10'd1; // Kick-off the DMA transfer!
- // gd_state <= 10'd1;
- if (block_dma_done) begin
- trig_block_read <= 1'b0;
- gd_status_reg[4] <= 1'b1; // Set DSC bit (Seek complete) TESTING !!
- gds_procpacketdone(); // If DMA finished, assert an Int, then go back to Idle (gd_state 1).
- end
- else trig_block_read <= 1'b1;
- end
- SPI_CD_READ2: begin // (Unimplemented in nullDC, but still sends status back). OzOnE
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end
- SPI_GET_SCD: begin
- scd_format <= packet_1b[3:0];
- byte_count <= 16'd0; // Zero the byte count.
- alloc_length <= {packet_3b, packet_4b}; // Allocation length in bytes (from WORD).
- gd_bytecount_high <= packet_3b;
- gd_bytecount_low <= packet_4b;
- gds_pio_send_data(); // Int, to start transfer. "When preparations are complete...".
- gd_state <= 10'd14; // <- *** TODO - No actual subcode data sent back yet! ***
- end
- default: gd_state <= 10'd1; // Unhandled SPI command, back to idle.
- endcase // endcase for "packet" parse!
- end
- // Generate TOC reply.
- 9: if (toc_density == 1'b0) begin // Request was for Single-Density TOC!
- // Generate Single-Density TOC...
- if ({gd_cs, gd_addr} == 5'b10000) begin // If in DATA reg...
- case (byte_count)
- 0: gd_data_write <= 16'h0041; // Track 1 == (Data track, control bit 4) (Sub Q indicates pos, adr bit 0).
- 2: gd_data_write <= 16'h9600; // Start FAD of track 1 is 0x0096 (FAD 150, so LBA 0).
- 4: gd_data_write <= 16'h0001; // Track 2 == (Audio track, no control bits) (Sub Q indicates pos, adr bit 0).
- 6: gd_data_write <= 16'hEE02; // Start FAD of track 2 is 0x02EE (FAD 750, so LBA 600).
- // All "0xFFFF's" in between are sent by default case!
- 396: gd_data_write <= 16'h0141; // Start track (1) Data.
- 398: gd_data_write <= 16'h0000;
- 400: gd_data_write <= 16'h0201; // End track (2) Audio.
- 402: gd_data_write <= 16'h0000;
- 404: gd_data_write <= 16'h0001; // Lead out.
- 406: gd_data_write <= 16'h2C1A; // 0x1A2C (FAD 6700, so LBA 6850 decimal)
- default: gd_data_write <= 16'hffff; // All other words are 0xFFFF (important!).
- endcase
- if (gd_rd_rising) byte_count <= byte_count + 16'd2; // Increment in WORDS!
- if (byte_count >= alloc_length) gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end // end for "if in DATA reg" - byte_count incrementing MUST be in here!
- end
- else begin // Else, Request was for Double-Density TOC!...
- // Generate Double-Density TOC...
- if ({gd_cs, gd_addr} == 5'b10000) begin // If in DATA reg...
- case (byte_count) // The following TOC is taken from the Crazy Taxi (PAL) original GD...
- 0: gd_data_write <= 16'hFFFF; // Definitely sends 0xFFFF's first?
- 2: gd_data_write <= 16'hFFFF;
- 4: gd_data_write <= 16'hFFFF;
- 6: gd_data_write <= 16'hFFFF;
- 8: gd_data_write <= 16'h0041; // Data track (top nibble 4 == DATA track)...
- 10: gd_data_write <= 16'h5EB0; // FAD 0x00B05E (45150, so LBA 45000).
- // All "0xFFFF's" in between are sent by default case!
- 396: gd_data_write <= 16'h0341; // Start track (3).
- 398: gd_data_write <= 16'h0000;
- 400: gd_data_write <= 16'h0341; // End track (3).
- 402: gd_data_write <= 16'h0000;
- 404: gd_data_write <= 16'h0841; // Lead out.
- 406: gd_data_write <= 16'hB461; // FAD 0x0861B4 (549300, so LBA 549150 decimal)
- default: gd_data_write <= 16'hffff; // All other words are 0xFFFF (important!).
- endcase
- if (gd_rd_rising) byte_count <= byte_count + 16'd2; // Increment in WORDS!
- if (byte_count >= alloc_length) gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end // end for "if in DATA reg" - byte_count incrementing MUST be in here!
- end // end for "else begin" (request Double-Density TOC).
- 10: begin // Generate "ATA_IDENTIFY_DEV (0xa1)" or "SPI_REQ_MODE (0x11)" or Security 0x71 reply (from ROM).
- if ({gd_cs, gd_addr} == 5'b10000) rom_route <= 1'b1; // ONLY start routing the Reply ROM --> "gd_data" when DATA reg is first read!
- if (rom_route == 1'b1 && gd_rd_rising) begin // If GD is accessing the data reg...
- reply_rom_addr <= reply_rom_addr + 10'd1; // Increment ROM address (ROM is WORD addressed!)
- byte_count <= byte_count + 16'd2; // Increment byte count (in WORDS)!
- end
- if (byte_count >= alloc_length) begin
- rom_route <= 1'b0; // Disable Reply ROM --> "gd_data" route.
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end
- end
- 11: begin // Generate SPI_REQ_SES reply.
- if ({gd_cs, gd_addr} == 5'b10000) begin // If in DATA reg...
- // "packet_2b" contains the read offset!
- case (packet_2b + byte_count)
- 0: gd_data_write <= {12'h000, gd_secnumber_reg[3:0]}; // CD Status - Is this good enough as a status? OzOnE
- 2: gd_data_write <= 16'h0803; // Starting TNO (Track NO?) = 3
- 4: gd_data_write <= 16'hB461; // Lead out / Starting FAD = 0x0861B4 (549300, so LBA 549150 decimal)
- default: gd_data_write <= 16'h0000; // All other words are 0x0000.
- endcase
- if (gd_rd_rising) byte_count <= byte_count + 16'd2; // Increment in WORDS!
- if (byte_count >= alloc_length) begin
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end
- end // end for "if in DATA reg" - byte_count incrementing MUST be in here!
- end
- 12: begin // Generate SPI_REQ_ERROR reply.
- if ({gd_cs, gd_addr} == 5'b10000) begin // If in DATA reg...
- // No read offset apparently? OzOnE.
- gd_data_write <= {resp[byte_count+1], resp[byte_count]};// Need to build a WORD.
- if (gd_rd_rising) byte_count <= byte_count + 16'd2; // Increment in WORDS!
- if (byte_count >= alloc_length) begin
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end
- end // end for "if in DATA reg" - byte_count incrementing MUST be in here!
- end
- 13: begin // Generate SPI_REQ_STAT reply.
- if ({gd_cs, gd_addr} == 5'b10000) begin // If in DATA reg...
- // "packet_2b" contains the read offset!
- gd_data_write <= {stat[packet_2b + byte_count+1], stat[packet_2b + byte_count]};// Need to build a WORD.
- if (gd_rd_rising) byte_count <= byte_count + 16'd2; // Increment in WORDS!
- if (byte_count >= alloc_length) begin
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end
- end // end for "if in DATA reg" - byte_count incrementing MUST be in here!
- end
- 14: begin // Generate SPI_GET_SCD reply.
- // *** TODO - Generate this properly from RAW sector data ! ***
- // TODO - "sec_format" contains the format type (nibble), handle it!
- if ({gd_cs, gd_addr} == 5'b10000) begin // If in DATA reg...
- case (byte_count)
- 0: gd_data_write <= 16'h1500; // Audio status (0x15 == "No audio status information") / reserved.
- 2: gd_data_write <= 16'h6400; // Subcode data length. Byte 3 is LSB apparently!
- default: gd_data_write <= 16'h0000; // All other words are 0x0000. ** TODO !! **
- endcase
- if (gd_rd_rising) byte_count <= byte_count + 16'd2; // Increment in WORDS!
- if (byte_count >= alloc_length) begin
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end
- end // end for "if in DATA reg" - byte_count incrementing MUST be in here!
- end
- 15: begin // Generate SPI_REQ_MODE
- if ({gd_cs, gd_addr} == 5'b10000) begin // If in DATA reg...
- // "packet_2b" contains the READ offset!
- gd_data_write <= {mode[packet_2b + byte_count+1], mode[packet_2b + byte_count]};// Need to build a WORD.
- if (gd_rd_rising) byte_count <= byte_count + 16'd2; // Increment in WORDS!
- if (byte_count >= alloc_length) begin
- gds_procpacketdone(); // Send status back (goes back to idle afterwards).
- end
- end // end for "if in DATA reg" - byte_count incrementing MUST be in here!
- end
- 16: begin // Receive SPI_SET_MODE data and update mode storage regs...
- if (gd_cs == 2'd2 && gd_addr == 3'd0 && gd_wr_rising) begin // If in DATA reg on RISING edge of "gd_wr_n"...
- // "packet_2b" contains the WRITE offset!
- //mode[packet_2b + byte_count+1] <= gd_data[15:8]; mode[packet_2b + byte_count] <= gd_data[7:0];
- byte_count <= byte_count + 16'd2; // Increment in WORDS!
- end // end for "if in DATA reg" - byte_count incrementing MUST be in here!
- // gd_bytecount_high <= byte_count[15:8];
- // gd_bytecount_low <= byte_count[7:0];
- if (byte_count >= alloc_length) begin
- // CF Card version...
- // "gds_pio_send_data"...
- //(2) IO bit is set and CoD bit is cleared.
- gd_intreason_reg[1] <= 1'b1; // Set IO bit.
- gd_intreason_reg[0] <= 1'b0; // Clear CoD bit.
- //(3) DRQ bit is set, BSY bit is cleared.
- gd_status_reg[3] <= 1'b0; // Clear DRQ bit. <- special case for SET_MODE ! (All data received, clear DRQ).
- gd_status_reg[7] <= 1'b1; // Set BUSY bit. <- special case for SET_MODE ! (DC needs to see busy bit at least once afterwards).
- //(4) INTRQ is set, and a host interrupt is issued.
- gd_int_rq_reg <= 1'b1;
- gd_state <= 10'd17;
- end
- end
- 17: if (gd_cs == 2'd2 && gd_addr == 3'd7 && gd_rd_rising) begin // After STAT / CMD reg is read at least once...
- //if (gd_cs == 2'd1 && gd_addr == 3'd6 && gd_rd_rising) begin // After ALTSTAT reg is read at least once...
- gd_int_rq_reg <= 1'b0; // Clear INTRQ!
- gd_state <= 10'd1; // Go back to IDLE (will clear the BUSY bit for us).
- end
- default: gd_state <= 10'd1; // Shouldn't ever get a wrong state here, but just in case.
- endcase
- case (gd_dma_state)
- 0: begin // IDLE state (do nothing until main "gd_state" sets "gd_dma_state" to 1...
- end
- 1: begin
- trig_block_read <= 1'b1;
- gd_dma_state <= 10'd2;
- end
- 2: if (block_dma_done) begin
- trig_block_read <= 1'b0;
- gd_status_reg[4] <= 1'b1; // Set DSC bit (Seek complete) TESTING !!
- gds_procpacketdone(); // If DMA finished, assert an Int, then go back to Idle (gd_state 1).
- gd_dma_state <= 10'd0; // Go back to Idle DMA state.
- end
- default: gd_dma_state <= 10'd0;
- endcase
- end // For "end else begin" main process.
- task gds_pio_send_data;
- begin
- // When preparations are complete, the following steps are carried out at the device.
- //(1) Number of bytes to be read is set in "Byte Count" register.
- // gd_bytecount_high <= alloc_length[15:8]; // <- Doesn't work because alloc_length is usually in the same time slot!
- // gd_bytecount_low <= alloc_length[7:0]; // (Now setting "gd_bytecount" stuff directly before calling this task). OzOnE.
- //(2) IO bit is set and CoD bit is cleared.
- gd_intreason_reg[1] <= 1'b1; // Set IO bit (Device -> Host).
- gd_intreason_reg[0] <= 1'b0; // Clear CoD bit (we have DATA to transfer).
- //(3) DRQ bit is set, BSY bit is cleared.
- gd_status_reg[3] <= 1'b1; // Set DRQ bit (preparations for data transfer are complete).
- gd_status_reg[7] <= 1'b0; // Clear BUSY bit (command block can be accessed). Should probably clear this at "gd_state" 1? OzOnE.
- //(4) INTRQ is set, and a host interrupt is issued.
- gd_int_rq_reg <= 1'b1;
- end
- endtask
- task gds_procpacketdone;
- begin
- // "Send status" - Done with transferring REQ data.
- // "gds_procpacketdone". Also does "gio_pio_end", because it only clears DRQ (done below anyway)..
- // 7. When the device is ready to send the status, it writes the
- // final status (IO, CoD, DRDY set, BSY, DRQ cleared) to the "Status" register before making INTRQ valid.
- // After checking INTRQ, the host reads the "Status" register to check the completion status.
- //Set IO, CoD, DRDY
- gd_intreason_reg[1] <= 1'b1; // Set IO bit (Device -> Host).
- gd_intreason_reg[0] <= 1'b1; // Set CoD bit (int reason was a COMMAND).
- gd_status_reg[6] <= 1'b1; // Set DRDY bit (drive is able to respond to ATA command?).
- //Clear DRQ,BSY
- gd_status_reg[3] <= 1'b0; // Clear DRQ bit (don't have any data to transfer).
- gd_status_reg[7] <= 1'b0; // Clear BUSY bit (command block can be accessed). Should probably clear this at "gd_state" 1? OzOnE.
- //Make INTRQ valid
- gd_int_rq_reg <= 1'b1;
- gd_state <= 10'd1; // Back to idle (wait for next ATA command).
- end
- endtask
- /*wire SYSCLK;
- wire SDRAM_CLK_100M;
- wire cdda_clk_pll;
- // Main PLL. "SYSCLK" is 100MHz, "SDRAM _CLK_100M" is 100MHZ + 5ns phase shift, "cdda_clk_pll" is roughly 33.8688MHz (44100 * 768).
- PLL_50M_100M PLL_50M_100M_inst (
- .inclk0 (CLK50M),
- .c0 (SYSCLK),
- .c1 (SDRAM_CLK_100M),
- .c2 (cdda_clk_pll)
- ); */
- wire SYSCLK;
- wire CLK24M;
- wire cdda_clk_pll;
- // Main PLL. "SYSCLK" is 100MHz, "CLK24M" is 24MHz for DAC MCLK, "cdda_clk_pll" is roughly 33.8688MHz (44100 * 768).
- PLL_50M_100M PLL_50M_100M_inst (
- .inclk0 (CLK50M),
- .c0 (SYSCLK),
- .c1 (CLK24M),
- .c2 (cdda_clk_pll)
- );
- wire [15:0] reply_rom_data/* synthesis noprune */;
- reply_rom reply_rom_inst (
- .address (reply_rom_addr),
- .clock (CLK50M),
- .q (reply_rom_data)
- );
- wire [15:0] sector_data;
- wire cont_dma_rq;
- wire block_dma_done;
- control control_inst (
- .SYSCLK (CLK50M),
- .SDRAM_CLK_100M (CLK50M), // TESTING!! Using SYSCLK instead of SDRAM_CLK_100M, 'cos I'm using the PLL for CLK24M!
- .RST_n (gd_rst_n),
- .gd_sector_type (gd_sector_type),
- .gd_start_sector (gd_start_sector),
- .gd_sector_count (gd_sector_count),
- .trig_block_read (trig_block_read),
- .block_dma_done (block_dma_done),
- .sector_data (sector_data),
- .cont_dma_rq (cont_dma_rq),
- .gd_dma_ack_n (gd_dma_ack_n),
- .gd_rd_n (gd_rd_n),
- .SRAM_ADDR (SRAM_ADDR),
- .SRAM_OE_n (SRAM_OE_n),
- .SRAM_WE_n (SRAM_WE_n),
- .SRAM_DATA (SRAM_DATA),
- .SDRAM_CLK (SDRAM_CLK), //connected to the clk port of SDRAM
- .SDRAM_CKE (SDRAM_CKE), //connected to the cke port of SDRAM
- .SDRAM_CS_n (SDRAM_CS_n), //connected to the CS_n port of SDRAM
- .SDRAM_RAS_n (SDRAM_RAS_n), //connected to the RAS_n port of SDRAM
- .SDRAM_CAS_n (SDRAM_CAS_n), //connected to the CAS_n port of SDRAM
- .SDRAM_WE_n (SDRAM_WE_n), //connected to the WE_n port of SDRAM
- .SDRAM_DQM (SDRAM_DQM), //connected to the LDQM port of SDRAM
- .SDRAM_BA (SDRAM_BA), //connected to the BA port of SDRAM
- .SDRAM_ADDR (SDRAM_ADDR), //connected to the ADDR port of SDRAM
- .SDRAM_DQ (SDRAM_DQ), //connected to the DQ port of SDRAM
- .SD_CS_n (SD_CS_n),
- .SD_CLK (SD_CLK),
- .SD_DATA_IN (SD_DATA_IN),
- .SD_DATA_OUT (SD_DATA_OUT),
- .AUD_BCLK(AUD_BCLK),
- .AUD_DACLRC(AUD_DACLRC),
- .AUD_DACDAT(AUD_DACDAT),
- .SEG_S(SEG_S),
- .SEG(SEG),
- .USB_TXE_n(USB_TXE_n),
- .USB_RXF_n(USB_RXF_n),
- .USB_RD_n(USB_RD_n),
- .USB_WR(USB_WR),
- .USB_DATA(USB_DATA),
- .error(LED0)
- );
- WM8731_config WM8731_config_inst (
- .CLK50M(CLK50M),
- .RST_n(gd_rst_n),
- .AUD_I2C_SCK(AUD_I2C_SCK),
- .AUD_I2C_DAT(AUD_I2C_DAT)
- );
- always @ (posedge CLK24M) AUD_MCLK <= ~AUD_MCLK;
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment