mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-12-27 21:41:55 +01:00
dd basics
This commit is contained in:
parent
4812b0d59d
commit
47633e3f36
@ -2,11 +2,12 @@ module mcu_top (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
n64_scb.controller n64_scb,
|
||||
dd_scb.controller dd_scb,
|
||||
usb_scb.controller usb_scb,
|
||||
dma_scb.controller usb_dma_scb,
|
||||
sd_scb.controller sd_scb,
|
||||
dma_scb.controller sd_dma_scb,
|
||||
n64_scb.controller n64_scb,
|
||||
flash_scb.controller flash_scb,
|
||||
|
||||
fifo_bus.controller fifo_bus,
|
||||
@ -347,13 +348,20 @@ module mcu_top (
|
||||
REG_SD_DAT,
|
||||
REG_SD_DMA_ADDRESS,
|
||||
REG_SD_DMA_LENGTH,
|
||||
REG_SD_DMA_SCR
|
||||
REG_SD_DMA_SCR,
|
||||
REG_DD_SCR,
|
||||
REG_DD_CMD_DATA,
|
||||
REG_DD_HEAD_TRACK,
|
||||
REG_DD_SECTOR_INFO,
|
||||
REG_DD_DRIVE_ID
|
||||
} reg_address_e;
|
||||
|
||||
logic bootloader_skip;
|
||||
|
||||
assign n64_scb.cfg_version = 32'h53437632;
|
||||
|
||||
logic dd_bm_ack;
|
||||
|
||||
|
||||
// Register read logic
|
||||
|
||||
@ -529,6 +537,47 @@ module mcu_top (
|
||||
2'b00
|
||||
};
|
||||
end
|
||||
|
||||
REG_DD_SCR: begin
|
||||
reg_rdata <= {
|
||||
14'd0,
|
||||
dd_bm_ack,
|
||||
dd_scb.bm_micro_error,
|
||||
dd_scb.bm_transfer_c2,
|
||||
dd_scb.bm_transfer_data,
|
||||
dd_scb.bm_transfer_blocks,
|
||||
dd_scb.bm_transfer_mode,
|
||||
1'b0,
|
||||
dd_scb.bm_stop_pending,
|
||||
1'b0,
|
||||
dd_scb.bm_start_pending,
|
||||
dd_scb.disk_changed,
|
||||
dd_scb.disk_inserted,
|
||||
1'b0,
|
||||
dd_scb.bm_pending,
|
||||
1'b0,
|
||||
dd_scb.cmd_pending,
|
||||
1'b0,
|
||||
dd_scb.hard_reset
|
||||
};
|
||||
end
|
||||
|
||||
REG_DD_CMD_DATA: begin
|
||||
reg_rdata <= {8'd0, dd_scb.cmd, dd_scb.data};
|
||||
end
|
||||
|
||||
REG_DD_HEAD_TRACK: begin
|
||||
reg_rdata <= {18'd0, dd_scb.index_lock, dd_scb.head_track};
|
||||
end
|
||||
|
||||
REG_DD_SECTOR_INFO: begin
|
||||
reg_rdata <= {
|
||||
dd_scb.sectors_in_block,
|
||||
dd_scb.sector_size_full,
|
||||
dd_scb.sector_size,
|
||||
dd_scb.sector_num
|
||||
};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
@ -559,6 +608,13 @@ module mcu_top (
|
||||
|
||||
n64_scb.rtc_done <= 1'b0;
|
||||
|
||||
dd_scb.hard_reset_clear <= 1'b0;
|
||||
dd_scb.cmd_ready <= 1'b0;
|
||||
dd_scb.bm_start_clear <= 1'b0;
|
||||
dd_scb.bm_stop_clear <= 1'b0;
|
||||
dd_scb.bm_clear <= 1'b0;
|
||||
dd_scb.bm_ready <= 1'b0;
|
||||
|
||||
if (n64_scb.n64_nmi) begin
|
||||
n64_scb.bootloader_enabled <= !bootloader_skip;
|
||||
end
|
||||
@ -567,6 +623,10 @@ module mcu_top (
|
||||
flash_scb.erase_pending <= 1'b0;
|
||||
end
|
||||
|
||||
if (dd_scb.bm_interrupt_ack) begin
|
||||
dd_bm_ack <= 1'b1;
|
||||
end
|
||||
|
||||
if (reset) begin
|
||||
mcu_int <= 1'b0;
|
||||
sd_scb.clock_mode <= 2'd0;
|
||||
@ -582,6 +642,7 @@ module mcu_top (
|
||||
bootloader_skip <= 1'b0;
|
||||
n64_scb.bootloader_enabled <= 1'b1;
|
||||
flash_scb.erase_pending <= 1'b0;
|
||||
dd_bm_ack <= 1'b0;
|
||||
end else if (reg_write) begin
|
||||
case (address)
|
||||
REG_STATUS: begin end
|
||||
@ -701,6 +762,35 @@ module mcu_top (
|
||||
sd_dma_scb.start
|
||||
} <= reg_wdata[2:0];
|
||||
end
|
||||
|
||||
REG_DD_SCR: begin
|
||||
dd_scb.bm_clear <= reg_wdata[19];
|
||||
if (reg_wdata[18]) begin
|
||||
dd_bm_ack <= 1'b0;
|
||||
end
|
||||
dd_scb.bm_micro_error <= reg_wdata[16];
|
||||
dd_scb.bm_transfer_c2 <= reg_wdata[15];
|
||||
dd_scb.bm_transfer_data <= reg_wdata[14];
|
||||
dd_scb.bm_stop_clear <= reg_wdata[11];
|
||||
dd_scb.bm_start_clear <= reg_wdata[9];
|
||||
dd_scb.disk_changed <= reg_wdata[7];
|
||||
dd_scb.disk_inserted <= reg_wdata[6];
|
||||
dd_scb.bm_ready <= reg_wdata[5];
|
||||
dd_scb.cmd_ready <= reg_wdata[3];
|
||||
dd_scb.hard_reset_clear <= reg_wdata[1];
|
||||
end
|
||||
|
||||
REG_DD_CMD_DATA: begin
|
||||
dd_scb.cmd_data <= reg_wdata[15:0];
|
||||
end
|
||||
|
||||
REG_DD_HEAD_TRACK: begin
|
||||
{dd_scb.index_lock, dd_scb.head_track} <= reg_wdata[13:0];
|
||||
end
|
||||
|
||||
REG_DD_DRIVE_ID: begin
|
||||
dd_scb.drive_id <= reg_wdata[15:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
@ -1,3 +1,114 @@
|
||||
interface dd_scb ();
|
||||
|
||||
// N64 controlled regs
|
||||
|
||||
logic hard_reset;
|
||||
logic [15:0] data;
|
||||
logic [7:0] cmd;
|
||||
logic cmd_pending;
|
||||
logic cmd_interrupt;
|
||||
logic bm_start_pending;
|
||||
logic bm_stop_pending;
|
||||
logic bm_transfer_mode;
|
||||
logic bm_transfer_blocks;
|
||||
logic bm_pending;
|
||||
logic bm_interrupt;
|
||||
logic bm_interrupt_ack;
|
||||
logic [7:0] sector_num;
|
||||
logic [7:0] sector_size;
|
||||
logic [7:0] sector_size_full;
|
||||
logic [7:0] sectors_in_block;
|
||||
|
||||
|
||||
// CPU controlled regs
|
||||
|
||||
logic hard_reset_clear;
|
||||
logic [15:0] cmd_data;
|
||||
logic cmd_ready;
|
||||
logic bm_start_clear;
|
||||
logic bm_stop_clear;
|
||||
logic bm_transfer_c2;
|
||||
logic bm_transfer_data;
|
||||
logic bm_micro_error;
|
||||
logic bm_clear;
|
||||
logic bm_ready;
|
||||
logic disk_inserted;
|
||||
logic disk_changed;
|
||||
logic index_lock;
|
||||
logic [12:0] head_track;
|
||||
logic [15:0] drive_id;
|
||||
|
||||
modport controller (
|
||||
input hard_reset,
|
||||
input data,
|
||||
input cmd,
|
||||
input cmd_pending,
|
||||
input bm_start_pending,
|
||||
input bm_stop_pending,
|
||||
input bm_transfer_mode,
|
||||
input bm_transfer_blocks,
|
||||
input bm_pending,
|
||||
input bm_interrupt_ack,
|
||||
input sector_num,
|
||||
input sector_size,
|
||||
input sector_size_full,
|
||||
input sectors_in_block,
|
||||
|
||||
output hard_reset_clear,
|
||||
output cmd_data,
|
||||
output cmd_ready,
|
||||
output bm_start_clear,
|
||||
output bm_stop_clear,
|
||||
output bm_transfer_c2,
|
||||
output bm_transfer_data,
|
||||
output bm_micro_error,
|
||||
output bm_ready,
|
||||
output bm_clear,
|
||||
output disk_inserted,
|
||||
output disk_changed,
|
||||
output index_lock,
|
||||
output head_track,
|
||||
output drive_id
|
||||
);
|
||||
|
||||
modport dd (
|
||||
output hard_reset,
|
||||
output data,
|
||||
output cmd,
|
||||
output cmd_pending,
|
||||
output cmd_interrupt,
|
||||
output bm_start_pending,
|
||||
output bm_stop_pending,
|
||||
output bm_transfer_mode,
|
||||
output bm_transfer_blocks,
|
||||
output bm_pending,
|
||||
output bm_interrupt,
|
||||
output bm_interrupt_ack,
|
||||
output sector_num,
|
||||
output sector_size,
|
||||
output sector_size_full,
|
||||
output sectors_in_block,
|
||||
|
||||
input hard_reset_clear,
|
||||
input cmd_data,
|
||||
input cmd_ready,
|
||||
input bm_start_clear,
|
||||
input bm_stop_clear,
|
||||
input bm_transfer_c2,
|
||||
input bm_transfer_data,
|
||||
input bm_micro_error,
|
||||
input bm_clear,
|
||||
input bm_ready,
|
||||
input disk_inserted,
|
||||
input disk_changed,
|
||||
input index_lock,
|
||||
input head_track,
|
||||
input drive_id
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
module n64_dd (
|
||||
input clk,
|
||||
input reset,
|
||||
@ -5,232 +116,171 @@ module n64_dd (
|
||||
n64_reg_bus.dd reg_bus,
|
||||
|
||||
n64_scb.dd n64_scb,
|
||||
dd_scb.dd dd_scb,
|
||||
|
||||
output logic irq
|
||||
);
|
||||
|
||||
assign irq = 1'b0;
|
||||
const bit [10:0] MEM_C2_BUFFER = 11'h000;
|
||||
const bit [10:0] MEM_SECTOR_BUFFER = 11'h400;
|
||||
|
||||
// const bit [10:0] M_C2_BUFFER = 11'h000;
|
||||
// const bit [10:0] M_SECTOR_BUFFER = 11'h400;
|
||||
typedef enum bit [10:0] {
|
||||
REG_DATA = 11'h500,
|
||||
REG_CMD_SR = 11'h508,
|
||||
REG_TRK_CUR = 11'h50C,
|
||||
REG_BM_SCR = 11'h510,
|
||||
REG_RESET = 11'h520,
|
||||
REG_SEC_SIZ = 11'h528,
|
||||
REG_SEC_INFO = 11'h530,
|
||||
REG_ID = 11'h540
|
||||
} e_reg_id;
|
||||
|
||||
// typedef enum bit [10:0] {
|
||||
// R_DATA = 11'h500,
|
||||
// R_CMD_SR = 11'h508,
|
||||
// R_TRK_CUR = 11'h50C,
|
||||
// R_BM_SCR = 11'h510,
|
||||
// R_RESET = 11'h520,
|
||||
// R_SEC_SIZ = 11'h528,
|
||||
// R_SEC_INFO = 11'h530,
|
||||
// R_ID = 11'h540
|
||||
// } e_reg_id;
|
||||
typedef enum bit [3:0] {
|
||||
BM_CONTROL_START_BUFFER_MANAGER = 4'd15,
|
||||
BM_CONTROL_BUFFER_MANAGER_MODE = 4'd14,
|
||||
BM_CONTROL_BUFFER_MANAGER_RESET = 4'd12,
|
||||
BM_CONTROL_BLOCK_TRANSFER = 4'd9,
|
||||
BM_CONTROL_MECHANIC_INTERRUPT_RESET = 4'd8
|
||||
} e_bm_control_id;
|
||||
|
||||
// typedef enum bit [3:0] {
|
||||
// BM_CONTROL_START_BUFFER_MANAGER = 4'd15,
|
||||
// BM_CONTROL_BUFFER_MANAGER_MODE = 4'd14,
|
||||
// BM_CONTROL_BUFFER_MANAGER_RESET = 4'd12,
|
||||
// BM_CONTROL_BLOCK_TRANSFER = 4'd9,
|
||||
// BM_CONTROL_MECHANIC_INTERRUPT_RESET = 4'd8
|
||||
// } e_bm_control_id;
|
||||
always_comb begin
|
||||
reg_bus.rdata = 16'd0;
|
||||
if (reg_bus.address[10:8] == MEM_SECTOR_BUFFER[10:8]) begin
|
||||
reg_bus.rdata = n64_scb.dd_rdata;
|
||||
end else begin
|
||||
case (reg_bus.address[10:0])
|
||||
REG_DATA: reg_bus.rdata = dd_scb.data;
|
||||
REG_CMD_SR: reg_bus.rdata = {
|
||||
1'b0,
|
||||
dd_scb.bm_transfer_data,
|
||||
1'b0,
|
||||
dd_scb.bm_transfer_c2,
|
||||
1'b0,
|
||||
dd_scb.bm_interrupt,
|
||||
dd_scb.cmd_interrupt,
|
||||
dd_scb.disk_inserted,
|
||||
dd_scb.cmd_pending,
|
||||
dd_scb.hard_reset,
|
||||
1'b0,
|
||||
1'b0,
|
||||
1'b0,
|
||||
1'b0,
|
||||
1'b0,
|
||||
dd_scb.disk_changed
|
||||
};
|
||||
REG_TRK_CUR: reg_bus.rdata = {1'd0, {2{dd_scb.index_lock}}, dd_scb.head_track};
|
||||
REG_BM_SCR: reg_bus.rdata = {6'd0, dd_scb.bm_micro_error, 9'd0};
|
||||
REG_ID: reg_bus.rdata = dd_scb.drive_id;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// // typedef enum bit [0:0] {
|
||||
// // S_IDLE,
|
||||
// // S_WAIT
|
||||
// // } e_state;
|
||||
always_ff @(posedge clk) begin
|
||||
dd_scb.bm_interrupt_ack <= 1'b0;
|
||||
|
||||
// // e_state state;
|
||||
if (dd_scb.hard_reset_clear) begin
|
||||
dd_scb.hard_reset <= 1'b0;
|
||||
end
|
||||
if (dd_scb.cmd_ready) begin
|
||||
dd_scb.data <= dd_scb.cmd_data;
|
||||
dd_scb.cmd_pending <= 1'b0;
|
||||
dd_scb.cmd_interrupt <= 1'b1;
|
||||
end
|
||||
if (dd_scb.bm_start_clear) begin
|
||||
dd_scb.bm_start_pending <= 1'b0;
|
||||
end
|
||||
if (dd_scb.bm_stop_clear) begin
|
||||
dd_scb.bm_stop_pending <= 1'b0;
|
||||
end
|
||||
if (dd_scb.bm_clear) begin
|
||||
dd_scb.bm_pending <= 1'b0;
|
||||
end
|
||||
if (dd_scb.bm_ready) begin
|
||||
dd_scb.bm_interrupt <= 1'b1;
|
||||
end
|
||||
if (reg_bus.address[10:0] == (MEM_C2_BUFFER + ({dd_scb.sector_size[7:1], 1'b0} * 3'd4)) && reg_bus.read) begin
|
||||
dd_scb.bm_pending <= 1'b1;
|
||||
end
|
||||
if (reg_bus.address[10:0] == (MEM_SECTOR_BUFFER + {dd_scb.sector_size[7:1], 1'b0}) && (reg_bus.read || reg_bus.write)) begin
|
||||
dd_scb.bm_pending <= 1'b1;
|
||||
end
|
||||
if (reg_bus.address[10:0] == REG_CMD_SR && reg_bus.read) begin
|
||||
dd_scb.bm_interrupt <= 1'b0;
|
||||
dd_scb.bm_interrupt_ack <= 1'b1;
|
||||
end
|
||||
|
||||
// // always_comb begin
|
||||
// // dd.sector_address = bus.address[7:1];
|
||||
// // dd.sector_address_valid = bus.request && bus.address[11:8] == M_SECTOR_BUFFER[11:8];
|
||||
// // dd.sector_write = bus.write && dd.sector_address_valid;
|
||||
// // dd.sector_wdata = bus.wdata;
|
||||
// // end
|
||||
if (reset || n64_scb.n64_reset) begin
|
||||
dd_scb.hard_reset <= 1'b1;
|
||||
dd_scb.cmd_pending <= 1'b0;
|
||||
dd_scb.cmd_interrupt <= 1'b0;
|
||||
dd_scb.bm_start_pending <= 1'b0;
|
||||
dd_scb.bm_stop_pending <= 1'b0;
|
||||
dd_scb.bm_pending <= 1'b0;
|
||||
dd_scb.bm_interrupt <= 1'b0;
|
||||
end else if (reg_bus.write) begin
|
||||
case (reg_bus.address[10:0])
|
||||
REG_DATA: begin
|
||||
dd_scb.data <= reg_bus.wdata;
|
||||
end
|
||||
|
||||
// always_comb begin
|
||||
// bus.rdata = 16'd0;
|
||||
// if (bus.ack) begin
|
||||
// if (bus.address[10:8] == M_SECTOR_BUFFER[10:8]) begin
|
||||
// if (bus.address[1]) begin
|
||||
// bus.rdata = dd.sector_rdata[15:0];
|
||||
// end else begin
|
||||
// bus.rdata = dd.sector_rdata[31:16];
|
||||
// end
|
||||
// end else begin
|
||||
// case (bus.address[10:0])
|
||||
// R_DATA: bus.rdata = dd.data;
|
||||
// R_CMD_SR: bus.rdata = {
|
||||
// 1'b0,
|
||||
// dd.bm_transfer_data,
|
||||
// 1'b0,
|
||||
// dd.bm_transfer_c2,
|
||||
// 1'b0,
|
||||
// dd.bm_interrupt,
|
||||
// dd.cmd_interrupt,
|
||||
// dd.disk_inserted,
|
||||
// dd.cmd_pending,
|
||||
// dd.hard_reset,
|
||||
// 1'b0,
|
||||
// 1'b0,
|
||||
// 1'b0,
|
||||
// 1'b0,
|
||||
// 1'b0,
|
||||
// dd.disk_changed
|
||||
// };
|
||||
// R_TRK_CUR: bus.rdata = {1'd0, {2{dd.index_lock}}, dd.head_track};
|
||||
// R_BM_SCR: bus.rdata = {6'd0, dd.bm_micro_error, 9'd0};
|
||||
// R_ID: bus.rdata = {dd.drive_id};
|
||||
// default: bus.rdata = 16'd0;
|
||||
// endcase
|
||||
// end
|
||||
// end
|
||||
// end
|
||||
REG_CMD_SR: begin
|
||||
dd_scb.cmd <= reg_bus.wdata[7:0];
|
||||
dd_scb.cmd_pending <= 1'b1;
|
||||
end
|
||||
|
||||
// always_comb begin
|
||||
// reg_bus.rdata = 16'd0;
|
||||
// if (reg_bus.address[10:8] == M_SECTOR_BUFFER[10:8]) begin
|
||||
// end else begin
|
||||
// case (reg_bus.address[10:0])
|
||||
// R_DATA: reg_bus.rdata = dd.data;
|
||||
// R_CMD_SR: reg_bus.rdata = {
|
||||
// 1'b0,
|
||||
// dd.bm_transfer_data,
|
||||
// 1'b0,
|
||||
// dd.bm_transfer_c2,
|
||||
// 1'b0,
|
||||
// dd.bm_interrupt,
|
||||
// dd.cmd_interrupt,
|
||||
// dd.disk_inserted,
|
||||
// dd.cmd_pending,
|
||||
// dd.hard_reset,
|
||||
// 1'b0,
|
||||
// 1'b0,
|
||||
// 1'b0,
|
||||
// 1'b0,
|
||||
// 1'b0,
|
||||
// dd.disk_changed
|
||||
// };
|
||||
// R_TRK_CUR: reg_bus.rdata = {1'd0, {2{dd.index_lock}}, dd.head_track};
|
||||
// R_BM_SCR: reg_bus.rdata = {6'd0, dd.bm_micro_error, 9'd0};
|
||||
// R_ID: reg_bus.rdata = {dd.drive_id};
|
||||
// default: reg_bus.rdata = 16'd0;
|
||||
// endcase
|
||||
// end
|
||||
// end
|
||||
REG_BM_SCR: begin
|
||||
dd_scb.sector_num <= reg_bus.wdata[7:0];
|
||||
if (reg_bus.wdata[BM_CONTROL_START_BUFFER_MANAGER]) begin
|
||||
dd_scb.bm_start_pending <= 1'b1;
|
||||
dd_scb.bm_stop_pending <= 1'b0;
|
||||
dd_scb.bm_transfer_mode <= reg_bus.wdata[BM_CONTROL_BUFFER_MANAGER_MODE];
|
||||
dd_scb.bm_transfer_blocks <= reg_bus.wdata[BM_CONTROL_BLOCK_TRANSFER];
|
||||
end
|
||||
if (reg_bus.wdata[BM_CONTROL_BUFFER_MANAGER_RESET]) begin
|
||||
dd_scb.bm_start_pending <= 1'b0;
|
||||
dd_scb.bm_stop_pending <= 1'b1;
|
||||
dd_scb.bm_transfer_mode <= 1'b0;
|
||||
dd_scb.bm_transfer_blocks <= 1'b0;
|
||||
dd_scb.bm_pending <= 1'b0;
|
||||
dd_scb.bm_interrupt <= 1'b0;
|
||||
end
|
||||
if (reg_bus.wdata[BM_CONTROL_MECHANIC_INTERRUPT_RESET]) begin
|
||||
dd_scb.cmd_interrupt <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// always_ff @(posedge sys.clk) begin
|
||||
// bus.ack <= 1'b0;
|
||||
// dd.bm_interrupt_ack <= 1'b0;
|
||||
REG_RESET: begin
|
||||
if (reg_bus.wdata == 16'hAAAA) begin
|
||||
dd_scb.hard_reset <= 1'b1;
|
||||
dd_scb.cmd_pending <= 1'b0;
|
||||
dd_scb.cmd_interrupt <= 1'b0;
|
||||
dd_scb.bm_start_pending <= 1'b0;
|
||||
dd_scb.bm_stop_pending <= 1'b0;
|
||||
dd_scb.bm_pending <= 1'b0;
|
||||
dd_scb.bm_interrupt <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// if (dd.hard_reset_clear) begin
|
||||
// dd.hard_reset <= 1'b0;
|
||||
// end
|
||||
// if (dd.cmd_ready) begin
|
||||
// dd.data <= dd.cmd_data;
|
||||
// dd.cmd_pending <= 1'b0;
|
||||
// dd.cmd_interrupt <= 1'b1;
|
||||
// end
|
||||
// if (dd.bm_start_clear) begin
|
||||
// dd.bm_start_pending <= 1'b0;
|
||||
// end
|
||||
// if (dd.bm_stop_clear) begin
|
||||
// dd.bm_stop_pending <= 1'b0;
|
||||
// end
|
||||
// if (dd.bm_clear) begin
|
||||
// dd.bm_pending <= 1'b0;
|
||||
// end
|
||||
// if (dd.bm_ready) begin
|
||||
// dd.bm_interrupt <= 1'b1;
|
||||
// end
|
||||
// if (bus.real_address == (M_C2_BUFFER + ({dd.sector_size[7:1], 1'b0} * 3'd4)) && bus.read_op) begin
|
||||
// dd.bm_pending <= 1'b1;
|
||||
// end
|
||||
// if (bus.real_address == (M_SECTOR_BUFFER + {dd.sector_size[7:1], 1'b0}) && (bus.read_op || bus.write_op)) begin
|
||||
// dd.bm_pending <= 1'b1;
|
||||
// end
|
||||
// if (bus.real_address == (M_BASE + R_CMD_SR) && bus.read_op) begin
|
||||
// dd.bm_interrupt <= 1'b0;
|
||||
// dd.bm_interrupt_ack <= 1'b1;
|
||||
// end
|
||||
REG_SEC_SIZ: begin
|
||||
dd_scb.sector_size <= reg_bus.wdata[7:0];
|
||||
end
|
||||
|
||||
// if (sys.reset || sys.n64_hard_reset) begin
|
||||
// dd.hard_reset <= 1'b1;
|
||||
// dd.cmd_pending <= 1'b0;
|
||||
// dd.cmd_interrupt <= 1'b0;
|
||||
// dd.bm_start_pending <= 1'b0;
|
||||
// dd.bm_stop_pending <= 1'b0;
|
||||
// dd.bm_pending <= 1'b0;
|
||||
// dd.bm_interrupt <= 1'b0;
|
||||
// state <= S_IDLE;
|
||||
// end else begin
|
||||
// case (state)
|
||||
// S_IDLE: begin
|
||||
// if (bus.request) begin
|
||||
// state <= S_WAIT;
|
||||
// bus.ack <= 1'b1;
|
||||
// if (bus.write) begin
|
||||
// case (bus.address[10:0])
|
||||
// R_DATA: begin
|
||||
// dd.data <= bus.wdata;
|
||||
// end
|
||||
REG_SEC_INFO: begin
|
||||
dd_scb.sectors_in_block <= reg_bus.wdata[15:8];
|
||||
dd_scb.sector_size_full <= reg_bus.wdata[7:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// R_CMD_SR: begin
|
||||
// dd.cmd <= bus.wdata[7:0];
|
||||
// dd.cmd_pending <= 1'b1;
|
||||
// end
|
||||
|
||||
// R_BM_SCR: begin
|
||||
// dd.sector_num <= bus.wdata[7:0];
|
||||
// if (bus.wdata[BM_CONTROL_START_BUFFER_MANAGER]) begin
|
||||
// dd.bm_start_pending <= 1'b1;
|
||||
// dd.bm_stop_pending <= 1'b0;
|
||||
// dd.bm_transfer_mode <= bus.wdata[BM_CONTROL_BUFFER_MANAGER_MODE];
|
||||
// dd.bm_transfer_blocks <= bus.wdata[BM_CONTROL_BLOCK_TRANSFER];
|
||||
// end
|
||||
// if (bus.wdata[BM_CONTROL_BUFFER_MANAGER_RESET]) begin
|
||||
// dd.bm_start_pending <= 1'b0;
|
||||
// dd.bm_stop_pending <= 1'b1;
|
||||
// dd.bm_transfer_mode <= 1'b0;
|
||||
// dd.bm_transfer_blocks <= 1'b0;
|
||||
// dd.bm_pending <= 1'b0;
|
||||
// dd.bm_interrupt <= 1'b0;
|
||||
// end
|
||||
// if (bus.wdata[BM_CONTROL_MECHANIC_INTERRUPT_RESET]) begin
|
||||
// dd.cmd_interrupt <= 1'b0;
|
||||
// end
|
||||
// end
|
||||
|
||||
// R_RESET: begin
|
||||
// if (bus.wdata == 16'hAAAA) begin
|
||||
// dd.hard_reset <= 1'b1;
|
||||
// dd.cmd_pending <= 1'b0;
|
||||
// dd.cmd_interrupt <= 1'b0;
|
||||
// dd.bm_start_pending <= 1'b0;
|
||||
// dd.bm_stop_pending <= 1'b0;
|
||||
// dd.bm_pending <= 1'b0;
|
||||
// dd.bm_interrupt <= 1'b0;
|
||||
// end
|
||||
// end
|
||||
|
||||
// R_SEC_SIZ: begin
|
||||
// dd.sector_size <= bus.wdata[7:0];
|
||||
// end
|
||||
|
||||
// R_SEC_INFO: begin
|
||||
// dd.sectors_in_block <= bus.wdata[15:8];
|
||||
// dd.sector_size_full <= bus.wdata[7:0];
|
||||
// end
|
||||
// endcase
|
||||
// end
|
||||
// end
|
||||
// end
|
||||
|
||||
// S_WAIT: begin
|
||||
// state <= S_IDLE;
|
||||
// end
|
||||
// endcase
|
||||
// end
|
||||
// end
|
||||
always_comb begin
|
||||
irq = dd_scb.cmd_interrupt || dd_scb.bm_interrupt;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
n64_scb.dd_write = reg_bus.write && reg_bus.address[10:8] == MEM_SECTOR_BUFFER[10:8];
|
||||
n64_scb.dd_address = {2'b00, reg_bus.address[7:1]};
|
||||
n64_scb.dd_wdata = reg_bus.wdata;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -2,9 +2,10 @@ module n64_top (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
mem_bus.controller mem_bus,
|
||||
|
||||
n64_scb n64_scb,
|
||||
dd_scb.dd dd_scb,
|
||||
|
||||
mem_bus.controller mem_bus,
|
||||
|
||||
input n64_reset,
|
||||
input n64_nmi,
|
||||
@ -52,6 +53,7 @@ module n64_top (
|
||||
.reg_bus(reg_bus),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
.dd_scb(dd_scb),
|
||||
|
||||
.irq(n64_dd_irq)
|
||||
);
|
||||
|
@ -52,6 +52,7 @@ module top (
|
||||
logic reset;
|
||||
|
||||
n64_scb n64_scb ();
|
||||
dd_scb dd_scb ();
|
||||
usb_scb usb_scb ();
|
||||
dma_scb usb_dma_scb ();
|
||||
sd_scb sd_scb ();
|
||||
@ -86,6 +87,7 @@ module top (
|
||||
.reset(reset),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
.dd_scb(dd_scb),
|
||||
.usb_scb(usb_scb),
|
||||
.usb_dma_scb(usb_dma_scb),
|
||||
.sd_scb(sd_scb),
|
||||
@ -113,6 +115,7 @@ module top (
|
||||
.reset(reset),
|
||||
|
||||
.n64_scb(n64_scb),
|
||||
.dd_scb(dd_scb),
|
||||
|
||||
.mem_bus(n64_mem_bus),
|
||||
|
||||
|
@ -16,6 +16,7 @@ SRC_FILES = \
|
||||
startup.S \
|
||||
cfg.c \
|
||||
cic.c \
|
||||
dd.c \
|
||||
flash.c \
|
||||
flashram.c \
|
||||
fpga.c \
|
||||
|
@ -141,7 +141,7 @@ void cfg_update (uint32_t *args) {
|
||||
change_scr_bits(CFG_SCR_ROM_SHADOW_ENABLED, args[1]);
|
||||
break;
|
||||
case CFG_ID_DD_ENABLE:
|
||||
change_scr_bits(CFG_SCR_DD_ENABLED, args[1]);
|
||||
change_scr_bits(CFG_SCR_DD_ENABLED | CFG_SCR_DDIPL_ENABLED, args[1]);
|
||||
break;
|
||||
case CFG_ID_ISV_ENABLE:
|
||||
break;
|
||||
|
115
sw/controller/src/dd.c
Normal file
115
sw/controller/src/dd.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "fpga.h"
|
||||
#include "rtc.h"
|
||||
|
||||
|
||||
#define DD_DRIVE_ID_RETAIL (0x0003)
|
||||
#define DD_DRIVE_ID_DEVELOPMENT (0x0004)
|
||||
#define DD_VERSION_RETAIL (0x0114)
|
||||
|
||||
|
||||
typedef enum {
|
||||
DD_CMD_SEEK_READ = 0x01,
|
||||
DD_CMD_SEEK_WRITE = 0x02,
|
||||
DD_CMD_CLEAR_DISK_CHANGE = 0x08,
|
||||
DD_CMD_CLEAR_RESET_STATE = 0x09,
|
||||
DD_CMD_READ_VERSION = 0x0A,
|
||||
DD_CMD_SET_DISK_TYPE = 0x0B,
|
||||
DD_CMD_REQUEST_STATUS = 0x0C,
|
||||
DD_CMD_SET_RTC_YEAR_MONTH = 0x0F,
|
||||
DD_CMD_SET_RTC_DAY_HOUR = 0x10,
|
||||
DD_CMD_SET_RTC_MINUTE_SECOND = 0x11,
|
||||
DD_CMD_GET_RTC_YEAR_MONTH = 0x12,
|
||||
DD_CMD_GET_RTC_DAY_HOUR = 0x13,
|
||||
DD_CMD_GET_RTC_MINUTE_SECOND = 0x14,
|
||||
DD_CMD_READ_PROGRAM_VERSION = 0x1B,
|
||||
} dd_cmd_t;
|
||||
|
||||
|
||||
static rtc_time_t time;
|
||||
|
||||
|
||||
void dd_init (void) {
|
||||
fpga_reg_set(REG_DD_SCR, 0);
|
||||
fpga_reg_set(REG_DD_HEAD_TRACK, 0);
|
||||
fpga_reg_set(REG_DD_DRIVE_ID, DD_DRIVE_ID_RETAIL);
|
||||
}
|
||||
|
||||
|
||||
void dd_process (void) {
|
||||
uint32_t scr = fpga_reg_get(REG_DD_SCR);
|
||||
|
||||
if (scr & DD_SCR_HARD_RESET) {
|
||||
fpga_reg_set(REG_DD_SCR, scr & ~(DD_SCR_DISK_CHANGED));
|
||||
fpga_reg_set(REG_DD_HEAD_TRACK, 0);
|
||||
}
|
||||
|
||||
if (scr & DD_SCR_CMD_PENDING) {
|
||||
uint32_t cmd_data = fpga_reg_get(REG_DD_CMD_DATA);
|
||||
uint8_t cmd = (cmd_data >> 16) & 0xFF;
|
||||
uint16_t data = cmd_data & 0xFFFF;
|
||||
fpga_reg_set(REG_DD_CMD_DATA, data);
|
||||
|
||||
switch (cmd) {
|
||||
case DD_CMD_CLEAR_DISK_CHANGE:
|
||||
fpga_reg_set(REG_DD_SCR, scr & ~(DD_SCR_DISK_CHANGED));
|
||||
break;
|
||||
|
||||
case DD_CMD_CLEAR_RESET_STATE:
|
||||
fpga_reg_set(REG_DD_SCR, scr & ~(DD_SCR_DISK_CHANGED));
|
||||
fpga_reg_set(REG_DD_SCR, scr | DD_SCR_HARD_RESET_CLEAR);
|
||||
|
||||
break;
|
||||
|
||||
case DD_CMD_READ_VERSION:
|
||||
fpga_reg_set(REG_DD_CMD_DATA, DD_VERSION_RETAIL);
|
||||
break;
|
||||
|
||||
case DD_CMD_SET_DISK_TYPE:
|
||||
break;
|
||||
|
||||
case DD_CMD_REQUEST_STATUS:
|
||||
fpga_reg_set(REG_DD_CMD_DATA, 0);
|
||||
break;
|
||||
|
||||
case DD_CMD_SET_RTC_YEAR_MONTH:
|
||||
time.year = ((data >> 8) & 0xFF);
|
||||
time.month = (data & 0xFF);
|
||||
break;
|
||||
|
||||
case DD_CMD_SET_RTC_DAY_HOUR:
|
||||
time.day = ((data >> 8) & 0xFF);
|
||||
time.hour = (data & 0xFF);
|
||||
break;
|
||||
|
||||
case DD_CMD_SET_RTC_MINUTE_SECOND:
|
||||
time.minute = ((data >> 8) & 0xFF);
|
||||
time.second = (data & 0xFF);
|
||||
rtc_set_time(&time);
|
||||
break;
|
||||
|
||||
case DD_CMD_GET_RTC_YEAR_MONTH:
|
||||
fpga_reg_set(REG_DD_CMD_DATA, (time.year << 8) | time.month);
|
||||
break;
|
||||
|
||||
case DD_CMD_GET_RTC_DAY_HOUR:
|
||||
fpga_reg_set(REG_DD_CMD_DATA, (time.day << 8) | time.hour);
|
||||
break;
|
||||
|
||||
case DD_CMD_GET_RTC_MINUTE_SECOND:
|
||||
rtc_get_time(&time);
|
||||
fpga_reg_set(REG_DD_CMD_DATA, (time.minute << 8) | time.second);
|
||||
break;
|
||||
|
||||
case DD_CMD_READ_PROGRAM_VERSION:
|
||||
fpga_reg_set(REG_DD_CMD_DATA, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fpga_reg_set(REG_DD_SCR, scr | DD_SCR_CMD_READY);
|
||||
}
|
||||
}
|
9
sw/controller/src/dd.h
Normal file
9
sw/controller/src/dd.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef DD_H__
|
||||
#define DD_H__
|
||||
|
||||
|
||||
void dd_init (void);
|
||||
void dd_process (void);
|
||||
|
||||
|
||||
#endif
|
@ -46,6 +46,11 @@ typedef enum {
|
||||
REG_SD_DMA_ADDRESS,
|
||||
REG_SD_DMA_LENGTH,
|
||||
REG_SD_DMA_SCR,
|
||||
REG_DD_SCR,
|
||||
REG_DD_CMD_DATA,
|
||||
REG_DD_HEAD_TRACK,
|
||||
REG_DD_SECTOR_INFO,
|
||||
REG_DD_DRIVE_ID
|
||||
} fpga_reg_t;
|
||||
|
||||
|
||||
@ -115,6 +120,32 @@ typedef enum {
|
||||
#define SD_SCR_CLOCK_MODE_25MHZ (2 << 0)
|
||||
#define SD_SCR_CLOCK_MODE_50MHZ (3 << 0)
|
||||
|
||||
#define DD_SCR_HARD_RESET (1 << 0)
|
||||
#define DD_SCR_HARD_RESET_CLEAR (1 << 1)
|
||||
#define DD_SCR_CMD_PENDING (1 << 2)
|
||||
#define DD_SCR_CMD_READY (1 << 3)
|
||||
#define DD_SCR_BM_PENDING (1 << 4)
|
||||
#define DD_SCR_BM_READY (1 << 5)
|
||||
#define DD_SCR_DISK_INSERTED (1 << 6)
|
||||
#define DD_SCR_DISK_CHANGED (1 << 7)
|
||||
#define DD_SCR_BM_START (1 << 8)
|
||||
#define DD_SCR_BM_START_CLEAR (1 << 9)
|
||||
#define DD_SCR_BM_STOP (1 << 10)
|
||||
#define DD_SCR_BM_STOP_CLEAR (1 << 11)
|
||||
#define DD_SCR_BM_TRANSFER_MODE (1 << 12)
|
||||
#define DD_SCR_BM_TRANSFER_BLOCKS (1 << 13)
|
||||
#define DD_SCR_BM_TRANSFER_DATA (1 << 14)
|
||||
#define DD_SCR_BM_TRANSFER_C2 (1 << 15)
|
||||
#define DD_SCR_BM_MICRO_ERROR (1 << 16)
|
||||
#define DD_SCR_BM_ACK (1 << 17)
|
||||
#define DD_SCR_BM_ACK_CLEAR (1 << 18)
|
||||
#define DD_SCR_BM_CLEAR (1 << 19)
|
||||
|
||||
#define DD_TRACK_MASK (0x0FFF)
|
||||
#define DD_HEAD_MASK (0x1000)
|
||||
#define DD_HEAD_TRACK_MASK (DD_HEAD_MASK | DD_TRACK_MASK)
|
||||
#define DD_HEAD_TRACK_INDEX_LOCK (1 << 13)
|
||||
|
||||
|
||||
uint8_t fpga_id_get (void);
|
||||
uint32_t fpga_reg_get (fpga_reg_t reg);
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "dd.h"
|
||||
#include "cfg.h"
|
||||
#include "flashram.h"
|
||||
#include "fpga.h"
|
||||
@ -8,50 +9,16 @@
|
||||
void gvr_task (void) {
|
||||
while (fpga_id_get() != FPGA_ID);
|
||||
|
||||
dd_init();
|
||||
cfg_init();
|
||||
flashram_init();
|
||||
usb_init();
|
||||
|
||||
// fpga_reg_set(REG_SD_SCR, SD_SCR_CLOCK_MODE_25MHZ);
|
||||
|
||||
while (1) {
|
||||
dd_process();
|
||||
cfg_process();
|
||||
flashram_process();
|
||||
usb_process();
|
||||
rtc_process();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// while (1) {
|
||||
// while (fpga_reg_get(REG_STATUS) & STATUS_BUTTON);
|
||||
// fpga_reg_set(REG_FLASH_SCR, 0x00E00000UL);
|
||||
// while (!(fpga_reg_get(REG_STATUS) & STATUS_BUTTON));
|
||||
// }
|
||||
|
||||
// if (!(fpga_reg_get(REG_STATUS) & STATUS_BUTTON)) {
|
||||
// hw_gpio_set(GPIO_ID_LED);
|
||||
// fpga_reg_set(REG_FLASH_SCR, FLASH_SCR_ERASE_MODE);
|
||||
// for (int i = 0; i < ((2*1024)-128)*1024; i += 64*1024) {
|
||||
// fpga_mem_write(((64+14)*1024*1024) + i, 2, buffer);
|
||||
// }
|
||||
// fpga_reg_set(REG_FLASH_SCR, 0);
|
||||
// fpga_mem_read((64+14)*1024*1024, 2, buffer);
|
||||
// hw_gpio_reset(GPIO_ID_LED);
|
||||
// }
|
||||
// fpga_reg_set(REG_CFG_SCR, 0); //CFG_SCR_BOOTLOADER_ENABLED
|
||||
|
||||
// uint8_t buffer[2];
|
||||
|
||||
// fpga_mem_read(0*1024*1024, 16, buffer);
|
||||
// fpga_mem_read(64*1024*1024, 16, buffer);
|
||||
// fpga_mem_read(64*1024*1024 + 128, 16, buffer);
|
||||
// buffer[0] = 0x21;
|
||||
// buffer[1] = 0x37;
|
||||
// buffer[2] = 0x69;
|
||||
// buffer[3] = 0x42;
|
||||
// fpga_mem_write(((64 + 16)*1024*1024)-(128 * 1024), 4, buffer);
|
||||
// fpga_mem_read(((64 + 16)*1024*1024)-(128 * 1024)-8, 16, buffer);
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user