diff --git a/fw/SummerCart64.qsf b/fw/SummerCart64.qsf index e50fbcf..bf158ab 100644 --- a/fw/SummerCart64.qsf +++ b/fw/SummerCart64.qsf @@ -19,7 +19,7 @@ # # Quartus Prime # Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition -# Date created = 16:40:13 August 18, 2021 +# Date created = 23:35:14 August 23, 2021 # # -------------------------------------------------------------------------- # # @@ -48,8 +48,8 @@ set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL set_global_assignment -name FLOW_ENABLE_POWER_ANALYZER ON set_global_assignment -name QSYS_FILE rtl/intel/flash/intel_flash.qsys set_global_assignment -name QSYS_FILE rtl/intel/snp/intel_snp.qsys -# set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo8.qip set_global_assignment -name QIP_FILE rtl/intel/fifo/intel_fifo_8.qip +set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip set_global_assignment -name QIP_FILE rtl/intel/pll/intel_pll.qip set_global_assignment -name SDC_FILE SummerCart64.sdc set_global_assignment -name SIGNALTAP_FILE stp.stp @@ -71,6 +71,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bootloader.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bus.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_cfg.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi_fifo.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_sdram.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_soc.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/SummerCart64.sv @@ -302,6 +303,23 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top # end ENTITY(SummerCart64) # ------------------------ -set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip +# ------------------------------ +# start ENTITY(altera_gpio_lite) + + # Project-Wide Assignments + # ======================== + +# end ENTITY(altera_gpio_lite) +# ---------------------------- + +# ----------------------------- +# start ENTITY(intel_gpio_ddro) + + # Project-Wide Assignments + # ======================== + +# end ENTITY(intel_gpio_ddro) +# --------------------------- +set_global_assignment -name SIGNALTAP_FILE output_files/signaltap.stp set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/fw/cpu/controller/main.c b/fw/cpu/controller/main.c index 7361943..e1c42d8 100644 --- a/fw/cpu/controller/main.c +++ b/fw/cpu/controller/main.c @@ -67,6 +67,10 @@ __NAKED__ int main (void) { GPIO_OE = (1 << 0); GPIO_O = 0; // (1 << 0); + CFG_SCR |= CFG_SCR_SRAM_EN | CFG_SCR_SDRAM_SWITCH | CFG_SCR_DD_EN; + CFG_DD_OFFSET = 0;//0x3BE0000; + CFG_SAVE_OFFSET = 0x3FE0000; + DMA_SCR = DMA_SCR_STOP; USB_SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_TX; @@ -156,6 +160,19 @@ __NAKED__ int main (void) { CFG_SCR &= ~CFG_SCR_SDRAM_SWITCH; } } + if (cmd == 'D') { + print_02hex(arg1 >> 24); + print_02hex(arg1 >> 16); + print_02hex(arg1 >> 8); + print_02hex(arg1 >> 0); + print(" "); + print_02hex(arg2 >> 24); + print_02hex(arg2 >> 16); + print_02hex(arg2 >> 8); + print_02hex(arg2 >> 0); + print("\r\n"); + } + print("\r\n"); CFG_RESPONSE = 0; } } diff --git a/fw/cpu/controller/rtc.c b/fw/cpu/controller/rtc.c index f7350b7..8157715 100644 --- a/fw/cpu/controller/rtc.c +++ b/fw/cpu/controller/rtc.c @@ -14,7 +14,7 @@ static const uint8_t rtc_bit_mask[7] = { static uint8_t i2c_is_busy (void) { - return (I2C_SR & I2C_SR_BUSY); + return (I2C_SCR & I2C_SCR_BUSY); } static void i2c_wait_busy (void) { @@ -22,22 +22,22 @@ static void i2c_wait_busy (void) { } static uint8_t i2c_has_ack (void) { - return (I2C_SR & I2C_SR_ACK); + return (I2C_SCR & I2C_SCR_ACK); } static void i2c_start (void) { i2c_wait_busy(); - I2C_SR = I2C_SR_START; + I2C_SCR = I2C_SCR_START; } static void i2c_stop (void) { i2c_wait_busy(); - I2C_SR = I2C_SR_STOP; + I2C_SCR = I2C_SCR_STOP; } static uint8_t i2c_write (uint8_t data) { i2c_wait_busy(); - I2C_SR = 0; + I2C_SCR = 0; I2C_DR = data; i2c_wait_busy(); return i2c_has_ack(); @@ -45,7 +45,7 @@ static uint8_t i2c_write (uint8_t data) { static void i2c_read (uint8_t *data, uint8_t cfg) { i2c_wait_busy(); - I2C_SR = cfg; + I2C_SCR = cfg; I2C_DR = 0xFF; i2c_wait_busy(); *data = I2C_DR; @@ -74,7 +74,7 @@ static uint8_t i2c_rx (uint8_t address, uint8_t *data, size_t length) { i2c_start(); result |= i2c_write(RTC_ADDR | I2C_ADDR_READ); for (size_t i = 0; i < length; i++) { - i2c_read(data++, (i == (length - 1)) ? 0 : I2C_SR_MACK); + i2c_read(data++, (i == (length - 1)) ? 0 : I2C_SCR_MACK); } i2c_stop(); diff --git a/fw/cpu/controller/sys.h b/fw/cpu/controller/sys.h index e4ef89d..fe5c0a2 100644 --- a/fw/cpu/controller/sys.h +++ b/fw/cpu/controller/sys.h @@ -6,60 +6,78 @@ #include -#define __NAKED__ __attribute__((naked)) +#define __NAKED__ __attribute__((naked)) -typedef volatile uint8_t * io8_t; -typedef volatile uint32_t * io32_t; +typedef volatile uint8_t * io8_t; +typedef volatile uint32_t * io32_t; -#define RAM (*((io32_t) 0x00000000)) -#define BOOTLOADER (*((io32_t) 0x10000000)) -#define GPIO (*((io32_t) 0x20000000)) -#define GPIO_O (*((io8_t) 0x20000000)) -#define GPIO_I (*((io8_t) 0x20000001)) -#define GPIO_OE (*((io8_t) 0x20000002)) -#define I2C_SR (*((io8_t) 0x30000000)) -#define I2C_DR (*((io8_t) 0x30000004)) -#define USB_SCR (*((io8_t) 0x40000000)) -#define USB_DR (*((io8_t) 0x40000004)) -#define UART_SCR (*((io8_t) 0x50000000)) -#define UART_DR (*((io8_t) 0x50000004)) -#define DMA_SCR (*((io8_t) 0x60000000)) -#define DMA_MADDR (*((io32_t) 0x60000004)) -#define DMA_ID_LEN (*((io32_t) 0x60000008)) -#define SDRAM (*((io32_t) 0x68000000)) -#define CFG_SCR (*((io32_t) 0x70000000)) -#define CFG_DD_OFFSET (*((io32_t) 0x70000004)) -#define CFG_SAVE_OFFSET (*((io32_t) 0x70000008)) -#define CFG_COMMAND (*((io8_t) 0x7000000C)) -#define CFG_ARG_1 (*((io32_t) 0x70000010)) -#define CFG_ARG_2 (*((io32_t) 0x70000014)) -#define CFG_RESPONSE (*((io32_t) 0x70000018)) +#define RAM (*((io32_t) 0x00000000)) -#define I2C_SR_START (1 << 0) -#define I2C_SR_STOP (1 << 1) -#define I2C_SR_MACK (1 << 2) -#define I2C_SR_ACK (1 << 3) -#define I2C_SR_BUSY (1 << 4) -#define I2C_ADDR_READ (1 << 0) -#define USB_SCR_RXNE (1 << 0) -#define USB_SCR_TXE (1 << 1) -#define USB_SCR_FLUSH_RX (1 << 2) -#define USB_SCR_FLUSH_TX (1 << 3) +#define BOOTLOADER (*((io32_t) 0x10000000)) -#define UART_SCR_RXNE (1 << 0) -#define UART_SCR_TXE (1 << 1) -#define DMA_SCR_START (1 << 0) -#define DMA_SCR_STOP (1 << 1) -#define DMA_SCR_DIR (1 << 2) -#define DMA_SCR_BUSY (1 << 3) +#define GPIO (*((io32_t) 0x20000000)) +#define GPIO_O (*((io8_t) 0x20000000)) +#define GPIO_I (*((io8_t) 0x20000001)) +#define GPIO_OE (*((io8_t) 0x20000002)) -#define DMA_ID_USB (0) -#define DMA_ID_SD (1) -#define CFG_SCR_CPU_BUSY (1 << 30) -#define CFG_SCR_SDRAM_SWITCH (1 << 0) +#define I2C_SCR (*((io8_t) 0x30000000)) +#define I2C_DR (*((io8_t) 0x30000004)) + +#define I2C_SCR_START (1 << 0) +#define I2C_SCR_STOP (1 << 1) +#define I2C_SCR_MACK (1 << 2) +#define I2C_SCR_ACK (1 << 3) +#define I2C_SCR_BUSY (1 << 4) +#define I2C_ADDR_READ (1 << 0) + + +#define USB_SCR (*((io8_t) 0x40000000)) +#define USB_DR (*((io8_t) 0x40000004)) + +#define USB_SCR_RXNE (1 << 0) +#define USB_SCR_TXE (1 << 1) +#define USB_SCR_FLUSH_RX (1 << 2) +#define USB_SCR_FLUSH_TX (1 << 3) + + +#define UART_SCR (*((io8_t) 0x50000000)) +#define UART_DR (*((io8_t) 0x50000004)) + +#define UART_SCR_RXNE (1 << 0) +#define UART_SCR_TXE (1 << 1) + + +#define DMA_SCR (*((io8_t) 0x60000000)) +#define DMA_MADDR (*((io32_t) 0x60000004)) +#define DMA_ID_LEN (*((io32_t) 0x60000008)) + +#define DMA_SCR_START (1 << 0) +#define DMA_SCR_STOP (1 << 1) +#define DMA_SCR_DIR (1 << 2) +#define DMA_SCR_BUSY (1 << 3) + + +#define SDRAM (*((io32_t) 0x68000000)) + + +#define CFG_SCR (*((io32_t) 0x70000000)) +#define CFG_DD_OFFSET (*((io32_t) 0x70000004)) +#define CFG_SAVE_OFFSET (*((io32_t) 0x70000008)) +#define CFG_COMMAND (*((io8_t) 0x7000000C)) +#define CFG_ARG_1 (*((io32_t) 0x70000010)) +#define CFG_ARG_2 (*((io32_t) 0x70000014)) +#define CFG_RESPONSE (*((io32_t) 0x70000018)) + +#define CFG_SCR_SDRAM_SWITCH (1 << 0) +#define CFG_SCR_SDRAM_WRITABLE (1 << 1) +#define CFG_SCR_DD_EN (1 << 2) +#define CFG_SCR_SRAM_EN (1 << 3) +#define CFG_SCR_FLASHRAM_EN (1 << 4) +#define CFG_SCR_CPU_BUSY (1 << 30) +#define CFG_SCR_CPU_RUNNING (1 << 31) #endif diff --git a/fw/rtl/n64/n64_cfg.sv b/fw/rtl/n64/n64_cfg.sv index d6b903c..fec81c7 100644 --- a/fw/rtl/n64/n64_cfg.sv +++ b/fw/rtl/n64/n64_cfg.sv @@ -42,6 +42,7 @@ module n64_cfg ( S_IDLE: begin if (bus.request) begin state <= S_WAIT; + bus.ack <= 1'b1; if (bus.write) begin case (bus.address[4:1]) // ... @@ -65,7 +66,6 @@ module n64_cfg ( end S_WAIT: begin - bus.ack <= 1'b1; state <= S_IDLE; end endcase diff --git a/fw/rtl/n64/n64_pi.sv b/fw/rtl/n64/n64_pi.sv index d7023e5..3f84d50 100644 --- a/fw/rtl/n64/n64_pi.sv +++ b/fw/rtl/n64/n64_pi.sv @@ -10,6 +10,57 @@ module n64_pi ( inout [15:0] n64_pi_ad ); + // FIFOs + + logic read_fifo_flush; + + logic read_fifo_full; + logic read_fifo_write; + logic [15:0] read_fifo_wdata; + + logic read_fifo_empty; + logic read_fifo_read; + logic [15:0] read_fifo_rdata; + + n64_pi_fifo read_fifo_inst ( + .sys(sys), + + .flush(read_fifo_flush), + + .full(read_fifo_full), + .write(read_fifo_write), + .wdata(read_fifo_wdata), + + .empty(read_fifo_empty), + .read(read_fifo_read), + .rdata(read_fifo_rdata) + ); + + logic write_fifo_flush; + + logic write_fifo_full; + logic write_fifo_write; + logic [15:0] write_fifo_wdata; + + logic write_fifo_empty; + logic write_fifo_read; + logic [15:0] write_fifo_rdata; + + n64_pi_fifo write_fifo_inst ( + .sys(sys), + + .flush(write_fifo_flush), + + .full(write_fifo_full), + .write(write_fifo_write), + .wdata(write_fifo_wdata), + + .empty(write_fifo_empty), + .read(write_fifo_read), + .rdata(write_fifo_rdata) + ); + + // Control signals input synchronization logic [2:0] n64_pi_alel_ff; @@ -28,7 +79,6 @@ module n64_pi ( logic pi_aleh; logic pi_alel; logic pi_read; - logic pi_read_delayed; logic pi_write; always_comb begin @@ -36,10 +86,10 @@ module n64_pi ( pi_aleh = n64_pi_aleh_ff[2]; pi_alel = n64_pi_alel_ff[2]; pi_read = n64_pi_read_ff[1]; - pi_read_delayed = n64_pi_read_ff[2]; pi_write = n64_pi_write_ff[2]; end + // PI bus state and event generator typedef enum bit [1:0] { @@ -68,20 +118,22 @@ module n64_pi ( logic alel_op; logic read_op; logic write_op; + logic end_op; always_comb begin aleh_op = !pi_reset && last_pi_mode != PI_MODE_HIGH && pi_mode == PI_MODE_HIGH; alel_op = !pi_reset && last_pi_mode == PI_MODE_HIGH && pi_mode == PI_MODE_LOW; read_op = !pi_reset && pi_mode == PI_MODE_VALID && last_read && !pi_read; write_op = !pi_reset && pi_mode == PI_MODE_VALID && last_write && !pi_write; + end_op = !pi_reset && last_pi_mode == PI_MODE_VALID && pi_mode != PI_MODE_VALID; end + // Input and output data sampling logic [15:0] n64_pi_ad_input; logic [15:0] n64_pi_ad_output; logic [15:0] n64_pi_ad_output_data; - logic [15:0] n64_pi_ad_output_data_buffer; logic n64_pi_ad_output_enable; logic n64_pi_ad_output_enable_data; @@ -91,38 +143,65 @@ module n64_pi ( always_comb begin n64_pi_ad = n64_pi_ad_output_enable ? n64_pi_ad_output : 16'hZZZZ; - n64_pi_ad_output_enable_data = !pi_reset && pi_mode == PI_MODE_VALID && n64_pi_address_valid && !pi_read_delayed; + n64_pi_ad_output_enable_data = !pi_reset && pi_mode == PI_MODE_VALID && n64_pi_address_valid && !n64_pi_read_ff[2]; end always_ff @(posedge sys.clk) begin n64_pi_ad_input <= n64_pi_ad; n64_pi_ad_output <= n64_pi_ad_output_data; n64_pi_ad_output_enable <= n64_pi_ad_output_enable_data; - if (read_op) begin - n64_pi_ad_output_data <= n64_pi_ad_output_data_buffer; - end - if (pending_operation && bus.ack) begin - n64_pi_ad_output_data <= bus.rdata; + end + + logic wait_for_read_fifo; + logic wait_for_write_fifo; + + always_comb begin + read_fifo_write = bus.ack && !bus.write; + read_fifo_wdata = bus.rdata; + + write_fifo_wdata = n64_pi_ad_input; + end + + always_ff @(posedge sys.clk) begin + read_fifo_read <= 1'b0; + write_fifo_write <= 1'b0; + + if (sys.reset || sys.n64_hard_reset) begin + wait_for_read_fifo <= 1'b0; + wait_for_write_fifo <= 1'b0; + end else begin + if (read_op || wait_for_read_fifo) begin + if (read_fifo_empty) begin + wait_for_read_fifo <= 1'b1; + end else begin + n64_pi_ad_output_data <= read_fifo_rdata; + read_fifo_read <= 1'b1; + wait_for_read_fifo <= 1'b0; + end + end + if (write_op || wait_for_write_fifo) begin + if (write_fifo_full) begin + wait_for_write_fifo <= 1'b1; + end else begin + write_fifo_write <= 1'b1; + wait_for_write_fifo <= 1'b0; + end + end end end - // Internal bus controller - typedef enum bit [0:0] { - S_IDLE, - S_WAIT - } e_state; - - e_state state; - logic first_operation; + // Address decoding sc64::e_n64_id next_id; - logic [25:0] next_offset; + logic [31:0] next_offset; + logic sram_selected; always_ff @(posedge sys.clk) begin if (aleh_op) begin n64_pi_address_valid <= 1'b0; next_offset <= 32'd0; + sram_selected <= 1'b0; if (cfg.dd_enabled) begin if (n64_pi_ad_input == 16'h0500) begin n64_pi_address_valid <= 1'b1; @@ -131,20 +210,20 @@ module n64_pi ( if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin n64_pi_address_valid <= 1'b1; next_id <= sc64::ID_N64_SDRAM; - next_offset <= cfg.dd_offset; + next_offset <= cfg.dd_offset + 32'h0A00_0000; end end if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0802) begin if (cfg.sram_enabled) begin n64_pi_address_valid <= 1'b1; next_id <= sc64::ID_N64_SDRAM; - next_offset <= cfg.save_offset; + next_offset <= cfg.save_offset + 32'h0800_0000; + sram_selected <= 1'b1; end else if (cfg.flashram_enabled) begin n64_pi_address_valid <= 1'b1; next_id <= sc64::ID_N64_FLASHRAM; if (cfg.flashram_read_mode) begin - next_id <= sc64::ID_N64_SDRAM; - next_offset <= cfg.save_offset; + next_offset <= cfg.save_offset + 32'h0800_0000; end end end @@ -159,46 +238,81 @@ module n64_pi ( end end - always_ff @(posedge sys.clk) begin - if (sys.reset || sys.n64_hard_reset || sys.n64_soft_reset) begin - state <= S_IDLE; - bus.request <= 1'b0; - pending_operation <= 1'b0; - end else begin - case (state) - S_IDLE: begin - if (aleh_op) begin - bus.address[31:16] <= n64_pi_ad_input; - end - if (alel_op) begin - bus.address <= {bus.address[31:16], n64_pi_ad_input[15:1], 1'b0} + next_offset; - end - if (n64_pi_address_valid && (alel_op || read_op || write_op || pending_operation)) begin - state <= S_WAIT; - bus.id <= next_id; - bus.request <= 1'b1; - bus.write <= write_op || (pending_operation && pending_write); - if (!alel_op && !(first_operation && write_op)) begin - bus.address[31:1] <= bus.address[31:1] + 1'd1; - end - bus.wdata <= n64_pi_ad_input; - first_operation <= alel_op; - pending_operation <= 1'b0; - end - end - S_WAIT: begin - if (bus.ack) begin - state <= S_IDLE; - bus.request <= 1'b0; - n64_pi_ad_output_data_buffer <= bus.rdata; + // Bus controller + + logic can_read; + logic first_write_op; + logic load_starting_address; + sc64::e_n64_id starting_id; + logic [31:0] starting_address; + + always_ff @(posedge sys.clk) begin + read_fifo_flush <= 1'b0; + + write_fifo_read <= 1'b0; + + if (sys.reset || sys.n64_hard_reset) begin + bus.request <= 1'b0; + read_fifo_flush <= 1'b1; + write_fifo_flush <= 1'b1; + end else begin + write_fifo_flush <= starting_id == sc64::ID_N64_SDRAM && !cfg.sdram_writable && !sram_selected; + + if (aleh_op) begin + starting_address[31:16] <= n64_pi_ad_input; + end + + if (alel_op) begin + read_fifo_flush <= 1'b1; + can_read <= 1'b1; + first_write_op <= 1'b1; + load_starting_address <= 1'b1; + starting_id <= next_id; + starting_address <= {starting_address[31:16], n64_pi_ad_input[15:1], 1'b0} + next_offset; + end + + if (write_op) begin + can_read <= 1'b0; + if (first_write_op) begin + first_write_op <= 1'b0; + load_starting_address <= 1'b1; + end + end + + if (!bus.request) begin + if (!write_fifo_empty) begin + bus.request <= 1'b1; + bus.write <= 1'b1; + if (load_starting_address) begin + bus.id <= starting_id; + bus.address <= starting_address; + load_starting_address <= 1'b0; end - if (read_op || write_op) begin - pending_operation <= 1'b1; - pending_write <= write_op; + bus.wdata <= write_fifo_rdata; + write_fifo_read <= 1'b1; + end else if (!read_fifo_full && can_read) begin + bus.request <= 1'b1; + bus.write <= 1'b0; + if (load_starting_address) begin + bus.id <= starting_id; + if (starting_id == sc64::ID_N64_FLASHRAM && cfg.flashram_read_mode) begin + bus.id <= sc64::ID_N64_SDRAM; + end + bus.address <= starting_address; + load_starting_address <= 1'b0; end end - endcase + end else begin + if (bus.ack) begin + bus.request <= 1'b0; + bus.address <= bus.address + 2'd2; + end + end + + if (end_op) begin + can_read <= 1'b0; + end end end diff --git a/fw/rtl/n64/n64_pi_fifo.sv b/fw/rtl/n64/n64_pi_fifo.sv new file mode 100644 index 0000000..63dde9e --- /dev/null +++ b/fw/rtl/n64/n64_pi_fifo.sv @@ -0,0 +1,43 @@ +module n64_pi_fifo ( + if_system.sys sys, + + input flush, + + output full, + input write, + input [15:0] wdata, + + output empty, + input read, + output [15:0] rdata +); + + logic [15:0] fifo_mem [0:3]; + logic [2:0] fifo_wr_ptr; + logic [2:0] fifo_rd_ptr; + + logic empty_or_full; + + always_comb begin + rdata = fifo_mem[fifo_rd_ptr[1:0]]; + empty_or_full = fifo_wr_ptr[1:0] == fifo_rd_ptr[1:0]; + empty = empty_or_full && fifo_wr_ptr[2] == fifo_rd_ptr[2]; + full = empty_or_full && fifo_wr_ptr[2] != fifo_rd_ptr[2]; + end + + always_ff @(posedge sys.clk) begin + if (sys.reset || flush) begin + fifo_wr_ptr <= 3'd0; + fifo_rd_ptr <= 3'd0; + end else begin + if (write) begin + fifo_mem[fifo_wr_ptr[1:0]] <= wdata; + fifo_wr_ptr <= fifo_wr_ptr + 1'd1; + end + if (read) begin + fifo_rd_ptr <= fifo_rd_ptr + 1'd1; + end + end + end + +endmodule diff --git a/fw/rtl/n64/n64_soc.sv b/fw/rtl/n64/n64_soc.sv index b662183..f5f595f 100644 --- a/fw/rtl/n64/n64_soc.sv +++ b/fw/rtl/n64/n64_soc.sv @@ -54,6 +54,16 @@ module n64_soc ( .bus(bus.at[sc64::ID_N64_BOOTLOADER].device) ); + n64_dummy n64_flashram_inst ( + .sys(sys), + .bus(bus.at[sc64::ID_N64_FLASHRAM].device) + ); + + n64_dummy n64_ddregs_inst ( + .sys(sys), + .bus(bus.at[sc64::ID_N64_DDREGS].device) + ); + n64_cfg n64_cfg_inst ( .sys(sys), .bus(bus.at[sc64::ID_N64_CFG].device), @@ -61,3 +71,46 @@ module n64_soc ( ); endmodule + + +module n64_dummy ( + if_system.sys sys, + if_n64_bus bus +); + + typedef enum bit [0:0] { + S_IDLE, + S_WAIT + } e_state; + + e_state state; + + always_comb begin + bus.rdata = 16'h0000; + if (bus.ack) begin + bus.rdata = !bus.address[1] ? 16'h0180 : 16'h0000; + end + end + + always_ff @(posedge sys.clk) begin + bus.ack <= 1'b0; + + if (sys.reset) begin + state <= S_IDLE; + end else begin + case (state) + S_IDLE: begin + if (bus.request) begin + state <= S_WAIT; + bus.ack <= 1'b1; + end + end + + S_WAIT: begin + state <= S_IDLE; + end + endcase + end + end + +endmodule diff --git a/sw/bootloader/src/boot/boot.c b/sw/bootloader/src/boot/boot.c index 35a4e64..9761b77 100644 --- a/sw/bootloader/src/boot/boot.c +++ b/sw/bootloader/src/boot/boot.c @@ -33,7 +33,7 @@ cart_header_t *boot_load_cart_header(void) { } uint16_t boot_get_cic_seed(cart_header_t *cart_header) { - uint16_t cic_seed = crc32_to_cic_seed[3].cic_seed; + uint16_t cic_seed = crc32_to_cic_seed[7].cic_seed; uint32_t ipl3_crc32 = crc32_calculate(cart_header->boot_code, sizeof(cart_header->boot_code)); for (size_t i = 0; i < ARRAY_ITEMS(crc32_to_cic_seed); i++) { @@ -140,6 +140,11 @@ void boot(cart_header_t *cart_header, uint16_t cic_seed, tv_type_t tv_type) { gpr_regs[CPU_REG_SP] = CPU_ADDRESS_IN_REG(SP_MEM->imem[ARRAY_ITEMS(SP_MEM->imem) - 4]); gpr_regs[CPU_REG_RA] = CPU_ADDRESS_IN_REG(SP_MEM->imem[(os_tv_type == TV_PAL) ? 341 : 340]); + print_debug((uint32_t) gpr_regs[CPU_REG_T3], (uint32_t) gpr_regs[CPU_REG_S3]); + print_debug((uint32_t) gpr_regs[CPU_REG_S4], (uint32_t) gpr_regs[CPU_REG_S5]); + print_debug((uint32_t) gpr_regs[CPU_REG_S6], (uint32_t) gpr_regs[CPU_REG_S7]); + print_debug((uint32_t) gpr_regs[CPU_REG_SP], (uint32_t) gpr_regs[CPU_REG_RA]); + __asm__ ( ".set noat \n\t" ".set noreorder \n\t" diff --git a/sw/bootloader/src/main.c b/sw/bootloader/src/main.c index d5b1a76..0e1aee4 100644 --- a/sw/bootloader/src/main.c +++ b/sw/bootloader/src/main.c @@ -16,6 +16,19 @@ typedef struct sc64_cart_registers { #define SC64_CFG_SCR_CPU_BUSY (1 << 30) #define CMD_SDRAM_SWITCH 'S' +#define CMD_DEBUG 'D' + +void print_debug(uint32_t a1, uint32_t a2) { + + uint32_t scr = 0; + do { + scr = platform_pi_io_read(&SC64_CFG->SCR); + } while (scr & SC64_CFG_SCR_CPU_BUSY); + + platform_pi_io_write(&SC64_CFG->ARG[0], a1); + platform_pi_io_write(&SC64_CFG->ARG[1], a2); + platform_pi_io_write(&SC64_CFG->COMMAND, (uint32_t) CMD_DEBUG); +} int main(void) { OS_BOOT_CONFIG->tv_type = TV_NTSC; @@ -41,5 +54,7 @@ int main(void) { uint16_t cic_seed = boot_get_cic_seed(cart_header); tv_type_t tv_type = boot_get_tv_type(cart_header); + print_debug(cic_seed << 16 | (tv_type & 0x03), cart_header->pi_conf); + boot(cart_header, cic_seed, tv_type); }