Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module gd_emu (mclock,
- gd_data, gd_addr, gd_rd_n, gd_wr_n, gd_dma_rq, gd_dma_ack, gd_int_rq, gd_iordy, gd_cs, gd_rst, // GD-Rom stuff.
- gd_cdlrck, gd_cdda_clk, gd_cdbck, // CDDA stuff (missing CDSD atm).
- cf_data, cf_addr, cf_rd_n, cf_wr_n, cf_dma_rq, cf_dma_ack, // Onboard IDE / CF Card.
- led);
- input wire mclock; // Master clock input
- reg [15:0] cf_data_write;
- inout [15:0] cf_data; // Hard drive / CF card data port (bidir).
- assign cf_data = !cf_wr_n ? cf_data_write : 16'bz; // Output data to IDE when "cf_wr_n" is low.
- // (force to High-Z if "cf_rd_n" is low too).
- output reg [2:0] cf_addr; // IDE address bits.
- // output reg [1:0] cf_cs; // IDE "Chip-Select" bits. NOTE: The MSB is labelled CS3 on many specs!
- // (Note: CS pins are hard-tied on Nemesis board. OzOnE).
- output reg cf_rd_n; // IDE Read (active low).
- output reg cf_wr_n; // IDE Write (active low).
- input cf_dma_rq; // IDE DMA ReQuest input.
- output reg cf_dma_ack; // IDE DMA ACKnowledge output.
- reg [23:0] cf_hold_time; // (for holding Read or Write pin state for a set time).
- // reg gd_rd_n_1, gd_rd_n_2;
- // reg gd_wr_n_1, gd_wr_n_2;
- // reg gd_rst_1, gd_rst_2;
- reg [15:0] gd_data_write;
- inout wire [15:0] gd_data/* synthesis noprune */;
- assign gd_data = 16'bz; // !! GD-Rom drive Spy mode !!
- // inout wire gd_data = !gd_wr_n ? gd_data_write : 16'bz; // !! GD-Rom emu mode !!
- reg gd_wr_n_1; // Flip-flops for detecting edges.
- reg gd_wr_n_2;
- reg gd_rd_n_1;
- reg 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;
- input wire [2:0] gd_addr/* synthesis noprune */; // !! GD-Rom drive Spy mode !!
- input wire gd_rd_n/* synthesis noprune */;
- input wire gd_wr_n/* synthesis noprune */;
- input wire gd_dma_rq/* synthesis noprune */;
- input wire gd_dma_ack/* synthesis noprune */;
- input wire gd_int_rq/* synthesis noprune */;
- input wire gd_iordy/* synthesis noprune */;
- input wire [1:0] gd_cs/* synthesis noprune */;
- input wire gd_rst/* synthesis noprune */;
- input wire gd_cdlrck/* synthesis noprune */;
- input wire gd_cdda_clk/* synthesis noprune */;
- input wire gd_cdbck/* synthesis noprune */;
- output wire led = !gd_dma_ack;
- reg [7:0] cf_sec_count;
- reg [31:0] cf_lba;
- wire [7:0] cf_lba3 = cf_lba[31:24] | 8'hE0; // Need to BITWISE OR the top LBA byte with 0xE0 (use 0xE0 mask to select MASTER drive).
- wire [7:0] cf_lba2 = cf_lba[23:16];
- wire [7:0] cf_lba1 = cf_lba[15:8];
- wire [7:0] cf_lba0 = cf_lba[7:0];
- reg [7:0] cf_wordcount;
- reg [9:0] gd_state;
- reg [15:0] ata_cmd;
- reg [15:0] gd_ata_cmd;
- reg [15:0] packet_1/* synthesis noprune */;
- 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/* synthesis noprune */;
- reg [31:0] gd_sector_count/* synthesis noprune */;
- reg [3:0] gd_status; // Only using nibble!
- 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] gd_stat [0:9]; // Array of bytes for sending status back.
- reg [9:0] reply_rom_addr;
- reg toc_density/* synthesis noprune */;
- reg [15:0] toc_bytes/* synthesis noprune */;
- reg [15:0] toc_byte_count/* synthesis noprune */;
- // 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;
- // SPI Packet 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;
- initial begin
- gd_state <= 10'd0;
- ata_cmd <= 8'h0;
- // led <= 1'b0;
- reply_rom_addr <= 10'h00;
- cf_addr <= 3'h00; // Zero IDE address (not really necessary).
- // cf_cs <= 2'b10; // IDE CS3 = HIGH, IDE CS1 = LOW (tied on Nemesis board anyway)
- cf_dma_ack <= 1'b1; // De-assert DMA ACKnowledge (active low).
- cf_rd_n <= 1'b1; // De-assert IDE Read at power up!
- cf_wr_n <= 1'b1; // De-assert IDE WRite at power up!
- end
- always @(posedge mclock) begin
- gd_wr_n_1 <= gd_wr_n;
- gd_wr_n_2 <= gd_wr_n_1;
- gd_rd_n_1 <= gd_rd_n;
- gd_rd_n_2 <= gd_rd_n_1;
- case (gd_state)
- 0: if (gd_addr == 3'd7 && gd_wr_rising) begin // If in COMMAND reg on RISING edge of "gd_wr_n"...
- gd_ata_cmd <= gd_data;
- gd_state <= 10'd2;
- end
- // 1: gd_state <= 10'd2; // Spare.
- 2: begin
- case (gd_ata_cmd[7:0])
- ATA_NOP: gd_state <= 10'd0; // Unhandled? (as yet). OzOnE
- ATA_SOFT_RESET: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- ATA_EXEC_DIAG: gd_state <= 10'd0; // Unhandled (as yet) - not implemented on nullDC anyway. OzOnE
- ATA_SPI_PACKET: // PACKET command! (Sega type, duh!)
- 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.
- gd_state <= 10'd3;
- end
- ATA_IDENTIFY_DEV: gd_state <= 10'd0; // Unhandled (as yet) - don't think it ever gets called by my DC BIOS? OzOnE
- ATA_SET_FEATURES: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- default: gd_state <= 10'd0; // 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
- 8: begin // ** Process SPI (Sega) command packet **
- case (packet_0b) // <- (byte addressing starts at zero!)
- SPI_TEST_UNIT: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_REQ_STAT: begin
- gd_stat[0] <= {4'b0, gd_status}; // Status is low nibble (force top bits to zero).
- gd_stat[1] <= {gd_discformat, cdda_repeats};
- gd_stat[2] <= 8'h04; // ? This is what nullDC does?
- gd_stat[3] <= 8'd02; // TNO
- gd_stat[4] <= 8'd00; // X
- gd_stat[5] <= cdda_curraddr[23:16]; // Current FAD (MSB?)
- gd_stat[6] <= cdda_curraddr[15:8]; // Current FAD
- gd_stat[7] <= cdda_curraddr[7:0]; // Current FAD (LSB?)
- gd_stat[8] <= 8'd00; // Max Read Error Retry Times.
- gd_stat[9] <= 8'd00; // All bits zeros.
- // *** TODO - SORT OUT PIO WORD OUTPUT !! ***
- gd_state <= 10'd0;
- end
- SPI_REQ_MODE: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_SET_MODE: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_REQ_ERROR: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_GET_TOC: begin
- toc_density <= packet_1b[0]; // Request TOC from Single-density area (0) or Double-density area (1).
- toc_bytes <= {packet_3b, packet_4b}; // Allocation length in bytes, usually 0x198 (408 bytes).
- gd_state <= 10'd0;
- end
- 8'h70: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- 8'h71: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_REQ_SES: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_CD_OPEN: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_CD_PLAY: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_CD_SEEK: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_CD_SCAN: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- 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<<16) | (packet_3b<<8) | (packet_4b);
- gd_sector_count = (packet_8b<<16) | (packet_9b<<8) | (packet_10b);
- gd_state <= 10'd0;
- end
- SPI_CD_READ2: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- SPI_GET_SCD: gd_state <= 10'd0; // Unhandled (as yet). OzOnE
- default: gd_state <= 10'd0; // Unhandled SPI command, back to idle.
- endcase
- end
- default: gd_state <= 10'd0; // Shouldn't ever get a wrong state here, but just in case.
- endcase
- end
- wire [15:0] reply_rom_data;
- reply_rom reply_rom_inst (
- .address ( reply_rom_addr ),
- .clock ( mclock ),
- .q ( reply_rom_data )
- );
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement