diff --git a/build.sh b/build.sh index 196ab45..e630d35 100755 --- a/build.sh +++ b/build.sh @@ -90,9 +90,10 @@ build_fpga () { else if [ "$DEBUG_ENABLED" = true ]; then quartus_sh --set VERILOG_MACRO="DEBUG" ./SummerCart64.qpf + else + quartus_sh --set -remove VERILOG_MACRO="DEBUG" ./SummerCart64.qpf fi quartus_sh --flow compile ./SummerCart64.qpf - quartus_sh --set -remove VERILOG_MACRO="DEBUG" ./SummerCart64.qpf fi popd > /dev/null diff --git a/fw/rtl/SummerCart64.sv b/fw/rtl/SummerCart64.sv index cb164c7..4fa55c3 100644 --- a/fw/rtl/SummerCart64.sv +++ b/fw/rtl/SummerCart64.sv @@ -70,6 +70,8 @@ module SummerCart64 ( .dd_interrupt(dd_interrupt) ); + if_cpu_ram cpu_ram (); + system system_inst ( .sys(sys) ); @@ -89,6 +91,7 @@ module SummerCart64 ( .si(si), .flash(flash), .dd(dd), + .cpu_ram(cpu_ram), .n64_pi_alel(i_n64_pi_alel), .n64_pi_aleh(i_n64_pi_aleh), @@ -117,6 +120,7 @@ module SummerCart64 ( .si(si), .flash(flash), .dd(dd), + .cpu_ram(cpu_ram), .gpio_o(gpio_o), .gpio_i(gpio_i), diff --git a/fw/rtl/cpu/cpu_ram.sv b/fw/rtl/cpu/cpu_ram.sv index fae5dd9..62c7af7 100644 --- a/fw/rtl/cpu/cpu_ram.sv +++ b/fw/rtl/cpu/cpu_ram.sv @@ -1,10 +1,36 @@ +interface if_cpu_ram (); + + logic write; + logic [12:0] address; + logic [15:0] rdata; + logic [15:0] wdata; + + modport cpu ( + input write, + input address, + output rdata, + input wdata + ); + + modport external ( + output write, + output address, + input rdata, + output wdata + ); + +endinterface + + module cpu_ram ( if_system.sys sys, - if_cpu_bus bus + if_cpu_bus bus, + if_cpu_ram.cpu cpu_ram ); logic [3:0][7:0] ram [0:4095]; - logic [31:0] q; + logic [31:0] q_cpu; + logic [31:0] q_external; always_ff @(posedge sys.clk) begin bus.ack <= 1'b0; @@ -14,14 +40,15 @@ module cpu_ram ( end always_comb begin + cpu_ram.rdata = cpu_ram.address[0] ? q_external[31:16] : q_external[15:0]; bus.rdata = 32'd0; if (bus.ack) begin - bus.rdata = q; + bus.rdata = q_cpu; end end - always_ff @(posedge sys.clk) begin - q <= ram[bus.address[13:2]]; + always_ff @(posedge sys.clk) begin + q_cpu <= ram[bus.address[13:2]]; if (bus.request) begin if (bus.wmask[0]) ram[bus.address[13:2]][0] <= bus.wdata[7:0]; if (bus.wmask[1]) ram[bus.address[13:2]][1] <= bus.wdata[15:8]; @@ -30,4 +57,17 @@ module cpu_ram ( end end + always_ff @(posedge sys.clk) begin + q_external <= ram[cpu_ram.address[12:1]]; + if (cpu_ram.write) begin + if (cpu_ram.address[0]) begin + ram[cpu_ram.address[12:1]][2] <= cpu_ram.wdata[7:0]; + ram[cpu_ram.address[12:1]][3] <= cpu_ram.wdata[15:8]; + end else begin + ram[cpu_ram.address[12:1]][0] <= cpu_ram.wdata[7:0]; + ram[cpu_ram.address[12:1]][1] <= cpu_ram.wdata[15:8]; + end + end + end + endmodule diff --git a/fw/rtl/cpu/cpu_soc.sv b/fw/rtl/cpu/cpu_soc.sv index 7a15039..95e5053 100644 --- a/fw/rtl/cpu/cpu_soc.sv +++ b/fw/rtl/cpu/cpu_soc.sv @@ -7,6 +7,7 @@ module cpu_soc ( if_si.cpu si, if_flash.cpu flash, if_dd.cpu dd, + if_cpu_ram.cpu cpu_ram, input [7:0] gpio_i, output [7:0] gpio_o, @@ -38,7 +39,8 @@ module cpu_soc ( cpu_ram cpu_ram_inst ( .sys(sys), - .bus(bus.at[sc64::ID_CPU_RAM].device) + .bus(bus.at[sc64::ID_CPU_RAM].device), + .cpu_ram(cpu_ram) ); cpu_flash cpu_flash_inst ( diff --git a/fw/rtl/n64/n64_cfg.sv b/fw/rtl/n64/n64_cfg.sv index 486d343..b26e970 100644 --- a/fw/rtl/n64/n64_cfg.sv +++ b/fw/rtl/n64/n64_cfg.sv @@ -1,7 +1,8 @@ module n64_cfg ( if_system sys, if_n64_bus bus, - if_config.n64 cfg + if_config.n64 cfg, + if_cpu_ram.external cpu_ram ); typedef enum bit [3:0] { @@ -23,24 +24,32 @@ module n64_cfg ( e_state state; always_comb begin + cpu_ram.write = bus.request && bus.write && bus.address[14]; + cpu_ram.address = bus.address[13:1]; + cpu_ram.wdata = {bus.wdata[7:0], bus.wdata[15:8]}; + bus.rdata = 16'd0; if (bus.ack) begin - case (bus.address[3:1]) - R_SR: bus.rdata = { - cfg.cpu_ready, - cfg.cpu_busy, - 1'b0, - cfg.cmd_error, - 12'd0 - }; - R_COMMAND: bus.rdata = {8'd0, cfg.cmd}; - R_DATA_0_H: bus.rdata = cfg.data[0][31:16]; - R_DATA_0_L: bus.rdata = cfg.data[0][15:0]; - R_DATA_1_H: bus.rdata = cfg.data[1][31:16]; - R_DATA_1_L: bus.rdata = cfg.data[1][15:0]; - R_VERSION_H: bus.rdata = sc64::SC64_VER[31:16]; - R_VERSION_L: bus.rdata = sc64::SC64_VER[15:0]; - endcase + if (bus.address[14]) begin + bus.rdata = {cpu_ram.rdata[7:0], cpu_ram.rdata[15:8]}; + end else if (!(&bus.address[13:4])) begin + case (bus.address[3:1]) + R_SR: bus.rdata = { + cfg.cpu_ready, + cfg.cpu_busy, + 1'b0, + cfg.cmd_error, + 12'd0 + }; + R_COMMAND: bus.rdata = {8'd0, cfg.cmd}; + R_DATA_0_H: bus.rdata = cfg.data[0][31:16]; + R_DATA_0_L: bus.rdata = cfg.data[0][15:0]; + R_DATA_1_H: bus.rdata = cfg.data[1][31:16]; + R_DATA_1_L: bus.rdata = cfg.data[1][15:0]; + R_VERSION_H: bus.rdata = sc64::SC64_VER[31:16]; + R_VERSION_L: bus.rdata = sc64::SC64_VER[15:0]; + endcase + end end end @@ -59,7 +68,7 @@ module n64_cfg ( if (bus.request) begin state <= S_WAIT; bus.ack <= 1'b1; - if (bus.write) begin + if (bus.write && (!(&bus.address[14:4]))) begin case (bus.address[3:1]) R_COMMAND: begin cfg.cmd <= bus.wdata[7:0]; diff --git a/fw/rtl/n64/n64_pi.sv b/fw/rtl/n64/n64_pi.sv index 239628c..407e9e7 100644 --- a/fw/rtl/n64/n64_pi.sv +++ b/fw/rtl/n64/n64_pi.sv @@ -282,11 +282,6 @@ module n64_pi ( n64_pi_address_valid <= 1'b0; end end - if (cfg_selected) begin - if (|n64_pi_ad_input[15:4]) begin - n64_pi_address_valid <= 1'b0; - end - end end end diff --git a/fw/rtl/n64/n64_soc.sv b/fw/rtl/n64/n64_soc.sv index 2f1a1a4..722ce28 100644 --- a/fw/rtl/n64/n64_soc.sv +++ b/fw/rtl/n64/n64_soc.sv @@ -7,6 +7,7 @@ module n64_soc ( if_si.si si, if_flash.memory flash, if_dd dd, + if_cpu_ram.external cpu_ram, input n64_pi_alel, input n64_pi_aleh, @@ -90,7 +91,8 @@ module n64_soc ( n64_cfg n64_cfg_inst ( .sys(sys), .bus(bus.at[sc64::ID_N64_CFG].device), - .cfg(cfg) + .cfg(cfg), + .cpu_ram(cpu_ram) ); endmodule diff --git a/sw/n64/src/exception.c b/sw/n64/src/exception.c index 09e6324..b5114ea 100644 --- a/sw/n64/src/exception.c +++ b/sw/n64/src/exception.c @@ -113,7 +113,7 @@ static const vi_regs_t vi_config[] = {{ .V_INTR = 0x000003FF, .CURR_LINE = 0x00000000, .TIMING = 0x03E52239, - .V_SYNC = 0x0000020D, + .V_SYNC = 0x0000020C, .H_SYNC = 0x00000C15, .H_SYNC_LEAP = 0x0C150C15, .H_LIMITS = 0x006C02EC, diff --git a/sw/n64/src/io.h b/sw/n64/src/io.h index 94d7818..e6897cf 100644 --- a/sw/n64/src/io.h +++ b/sw/n64/src/io.h @@ -229,6 +229,9 @@ typedef struct { io32_t SR_CMD; io32_t DATA[2]; io32_t VERSION; + io32_t __padding[4092]; + io32_t CPU_RAM[3840]; + io32_t BUFFER[256]; } sc64_regs_t; #define SC64_BASE (0x1FFF0000UL) diff --git a/sw/n64/src/sc64.c b/sw/n64/src/sc64.c index a065784..c82589b 100644 --- a/sw/n64/src/sc64.c +++ b/sw/n64/src/sc64.c @@ -35,179 +35,40 @@ bool sc64_perform_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) { return error; } -uint32_t sc64_get_config (cfg_id_t id) { +uint32_t sc64_query_config (cfg_id_t id) { uint32_t args[2] = { id, 0 }; uint32_t result[2]; sc64_perform_cmd(SC64_CMD_QUERY, args, result); return result[1]; } -void sc64_set_config (cfg_id_t id, uint32_t value) { +void sc64_change_config (cfg_id_t id, uint32_t value) { uint32_t args[2] = { id, value }; sc64_perform_cmd(SC64_CMD_CONFIG, args, NULL); } void sc64_get_info (sc64_info_t *info) { - // info->dd_enabled = (bool) sc64_get_config(CFG_ID_DD_ENABLE); - // info->is_viewer_enabled = (bool) sc64_get_config(CFG_ID_IS_VIEWER_ENABLE); - // info->save_type = (save_type_t) sc64_get_config(CFG_ID_SAVE_TYPE); - info->cic_seed = (uint16_t) sc64_get_config(CFG_ID_CIC_SEED); - info->tv_type = (tv_type_t) sc64_get_config(CFG_ID_TV_TYPE); - // info->save_location = (io32_t *) (0x10000000 | sc64_get_config(CFG_ID_SAVE_OFFEST)); - // info->ddipl_location = (io32_t *) (0x10000000 | sc64_get_config(CFG_ID_DDIPL_OFFEST)); - info->boot_mode = (boot_mode_t) sc64_get_config(CFG_ID_BOOT_MODE); + info->cic_seed = (uint16_t) sc64_query_config(CFG_ID_CIC_SEED); + info->tv_type = (tv_type_t) sc64_query_config(CFG_ID_TV_TYPE); + info->boot_mode = (boot_mode_t) sc64_query_config(CFG_ID_BOOT_MODE); } -// void sc64_wait_usb_rx_ready (uint32_t *type, uint32_t *length) { -// uint32_t result[2]; -// do { -// sc64_perform_cmd(SC64_CMD_DEBUG_RX_READY, NULL, result); -// } while (result[0] == 0 && result[1] == 0); -// *type = result[0]; -// *length = result[1]; -// } - -// void sc64_wait_usb_rx_busy (void) { -// uint32_t result[2]; -// do { -// sc64_perform_cmd(SC64_CMD_DEBUG_RX_BUSY, NULL, result); -// } while (result[0]); -// } - -// void sc64_usb_rx_data (io32_t *address, uint32_t length) { -// uint32_t args[2] = { (uint32_t) (address), ALIGN(length, 2) }; -// sc64_perform_cmd(SC64_CMD_DEBUG_RX_DATA, args, NULL); -// } - -// void sc64_wait_usb_tx_ready (void) { -// uint32_t result[2]; -// do { -// sc64_perform_cmd(SC64_CMD_DEBUG_TX_READY, NULL, result); -// } while (!result[0]); -// } - -// void sc64_usb_tx_data (io32_t *address, uint32_t length) { -// uint32_t args[2] = { (uint32_t) (address), ALIGN(length, 2) }; -// sc64_perform_cmd(SC64_CMD_DEBUG_TX_DATA, args, NULL); -// } - -// void sc64_debug_write (uint8_t type, const void *data, uint32_t len) { -// char *dma = "DMA@"; -// char *cmp = "CMPH"; - -// io32_t *sdram = (io32_t *) (SC64_DEBUG_WRITE_ADDRESS); - -// uint8_t *src = (uint8_t *) (data); -// uint32_t tmp; -// io32_t *dst = sdram; - -// uint32_t copy_length = ALIGN(len, 4); - -// sc64_wait_usb_tx_ready(); - -// bool writable = sc64_get_config(CFG_ID_SDRAM_WRITABLE); -// bool sdram_switched = sc64_get_config(CFG_ID_SDRAM_SWITCH); - -// if (!writable) { -// sc64_set_config(CFG_ID_SDRAM_WRITABLE, true); -// } -// if (!sdram_switched) { -// sc64_set_config(CFG_ID_SDRAM_SWITCH, true); -// } - -// pi_io_write(dst++, *((uint32_t *) (dma))); -// pi_io_write(dst++, (type << 24) | len); - -// while (src < ((uint8_t *) (data + copy_length))) { -// tmp = ((*src++) << 24); -// tmp |= ((*src++) << 16); -// tmp |= ((*src++) << 8); -// tmp |= ((*src++) << 0); -// pi_io_write(dst++, tmp); -// if (dst >= (io32_t *) ((void *) (sdram) + SC64_DEBUG_MAX_SIZE)) { -// sc64_usb_tx_data(sdram, (dst - sdram) * sizeof(uint32_t)); -// sc64_wait_usb_tx_ready(); -// dst = sdram; -// } -// } - -// pi_io_write(dst++, *((uint32_t *) (cmp))); - -// if (!writable) { -// sc64_set_config(CFG_ID_SDRAM_WRITABLE, false); -// } -// if (!sdram_switched) { -// sc64_set_config(CFG_ID_SDRAM_SWITCH, false); -// } - -// sc64_usb_tx_data(sdram, (dst - sdram) * sizeof(uint32_t)); -// } - -// void sc64_debug_fsd_read (const void *data, uint32_t sector, uint32_t count) { -// uint32_t type; -// uint32_t length; - -// io32_t *sdram = (io32_t *) (SC64_DEBUG_READ_ADDRESS); - -// io32_t *src = sdram; -// uint32_t tmp; -// uint8_t *dst = (uint8_t *) (data); - -// uint32_t read_length = count * 512; - -// sc64_debug_write(SC64_DEBUG_ID_FSD_SECTOR, §or, 4); -// sc64_debug_write(SC64_DEBUG_ID_FSD_READ, &read_length, 4); -// sc64_wait_usb_rx_ready(&type, &length); -// sc64_usb_rx_data(sdram, length); -// sc64_wait_usb_rx_busy(); - -// uint32_t copy_length = ALIGN(length, 4); - -// bool sdram_switched = sc64_get_config(CFG_ID_SDRAM_SWITCH); - -// if (!sdram_switched) { -// sc64_set_config(CFG_ID_SDRAM_SWITCH, true); -// } - -// for (int i = 0; i < copy_length; i += 4) { -// tmp = pi_io_read(src++); -// *dst++ = (tmp >> 24); -// *dst++ = (tmp >> 16); -// *dst++ = (tmp >> 8); -// *dst++ = (tmp & 0xFF); -// } - -// if (!sdram_switched) { -// sc64_set_config(CFG_ID_SDRAM_SWITCH, false); -// } -// } - -// void sc64_debug_fsd_write (const void *data, uint32_t sector, uint32_t count) { -// sc64_debug_write(SC64_DEBUG_ID_FSD_SECTOR, §or, 4); -// sc64_debug_write(SC64_DEBUG_ID_FSD_WRITE, data, count * 512); -// } - -// void sc64_init_is_viewer (void) { -// sc64_set_config(CFG_ID_SDRAM_WRITABLE, true); -// pi_io_write(&ISV->ID, 0); -// } - -sc64_storage_error_t sc64_storage_read(sc64_storage_type_t storage_type, const void *buff, uint32_t sector, uint32_t count) { - return SC64_STORAGE_ERROR; +void sc64_uart_put_char (char c) { +#ifdef DEBUG + uint32_t args[2] = { (uint32_t) (c), 0 }; + sc64_perform_cmd(SC64_CMD_UART_PUT, args, NULL); +#endif } void sc64_uart_print_string (const char *text) { -#ifdef DEBUG - uint32_t args[2] = { 0, 0 }; while (*text != '\0') { - args[0] = (uint32_t) (*text++); - sc64_perform_cmd(SC64_CMD_UART_PUT, args, NULL); + sc64_uart_put_char (*text++); } -#endif } void sc64_init (void) { while (!sc64_check_presence()); sc64_wait_cpu_ready(); - sc64_set_config(CFG_ID_SDRAM_SWITCH, true); + sc64_change_config(CFG_ID_SDRAM_SWITCH, true); + sc64_uart_print_string("\033c"); } diff --git a/sw/n64/src/sc64.h b/sw/n64/src/sc64.h index 1b9e1f9..7bb17f7 100644 --- a/sw/n64/src/sc64.h +++ b/sw/n64/src/sc64.h @@ -4,30 +4,15 @@ #include #include -// #include #include "io.h" -#define SC64_CMD_CONFIG ('C') #define SC64_CMD_QUERY ('Q') -// #define SC64_CMD_DEBUG_RX_DATA ('E') -// #define SC64_CMD_DEBUG_RX_READY ('A') -// #define SC64_CMD_DEBUG_RX_BUSY ('F') -// #define SC64_CMD_DEBUG_TX_DATA ('D') -// #define SC64_CMD_DEBUG_TX_READY ('S') +#define SC64_CMD_CONFIG ('C') #define SC64_CMD_UART_PUT ('Z') #define SC64_VERSION_2 (0x53437632) -// #define SC64_DEBUG_WRITE_ADDRESS (0x13FF8000UL) -// #define SC64_DEBUG_READ_ADDRESS (0x13FF0000UL) -// #define SC64_DEBUG_MAX_SIZE (32 * 1024) - -// #define SC64_DEBUG_ID_TEXT (0x01) -// #define SC64_DEBUG_ID_FSD_READ (0xF1) -// #define SC64_DEBUG_ID_FSD_WRITE (0xF2) -// #define SC64_DEBUG_ID_FSD_SECTOR (0xF3) - typedef enum { CFG_ID_SCR, @@ -50,15 +35,19 @@ typedef enum { CFG_ID_IS_VIEWER_ENABLE, } cfg_id_t; -// typedef enum { -// SAVE_TYPE_NONE = 0, -// SAVE_TYPE_EEPROM_4K = 1, -// SAVE_TYPE_EEPROM_16K = 2, -// SAVE_TYPE_SRAM = 3, -// SAVE_TYPE_FLASHRAM = 4, -// SAVE_TYPE_SRAM_BANKED = 5, -// SAVE_TYPE_FLASHRAM_PKST2 = 6, -// } save_type_t; +typedef enum { + SAVE_TYPE_NONE = 0, + SAVE_TYPE_EEPROM_4K = 1, + SAVE_TYPE_EEPROM_16K = 2, + SAVE_TYPE_SRAM = 3, + SAVE_TYPE_FLASHRAM = 4, + SAVE_TYPE_SRAM_BANKED = 5, + SAVE_TYPE_FLASHRAM_PKST2 = 6, +} save_type_t; + +typedef enum { + CIC_SEED_UNKNOWN = 0xFFFF, +} cic_seed_t; typedef enum { TV_TYPE_PAL = 0, @@ -67,10 +56,6 @@ typedef enum { TV_TYPE_UNKNOWN = 3, } tv_type_t; -typedef enum { - CIC_SEED_UNKNOWN = 0xFFFF, -} cic_seed_t; - typedef enum { BOOT_MODE_MENU_SD = 0, BOOT_MODE_MENU_USB = 1, @@ -80,46 +65,21 @@ typedef enum { } boot_mode_t; typedef struct { - // bool dd_enabled; - // bool is_viewer_enabled; - // save_type_t save_type; boot_mode_t boot_mode; uint16_t cic_seed; tv_type_t tv_type; - // io32_t *save_location; - // io32_t *ddipl_location; } sc64_info_t; -typedef enum { - SC64_STORAGE_TYPE_SD, - SC64_STORAGE_TYPE_USB, -} sc64_storage_type_t; - -typedef enum { - SC64_STORAGE_OK, - SC64_STORAGE_ERROR, -} sc64_storage_error_t; - - bool sc64_check_presence (void); void sc64_wait_cpu_ready (void); bool sc64_wait_cpu_busy (void); bool sc64_perform_cmd (uint8_t cmd, uint32_t *args, uint32_t *result); -uint32_t sc64_get_config (cfg_id_t id); -void sc64_set_config (cfg_id_t id, uint32_t value); +uint32_t sc64_query_config (cfg_id_t id); +void sc64_change_config (cfg_id_t id, uint32_t value); void sc64_get_info (sc64_info_t *info); -// void sc64_wait_usb_rx_ready (uint32_t *type, uint32_t *length); -// void sc64_wait_usb_rx_busy (void); -// void sc64_usb_rx_data (io32_t *address, uint32_t length); -// void sc64_wait_usb_tx_ready (void); -// void sc64_usb_tx_data (io32_t *address, uint32_t length); -// void sc64_debug_write (uint8_t type, const void *data, uint32_t len); -// void sc64_debug_fsd_read (const void *data, uint32_t sector, uint32_t count); -// void sc64_debug_fsd_write (const void *data, uint32_t sector, uint32_t count); -// void sc64_init_is_viewer (void); +void sc64_uart_put_char (char c); void sc64_uart_print_string (const char *text); -sc64_storage_error_t sc64_storage_read(sc64_storage_type_t storage_type, const void *buff, uint32_t sector, uint32_t count); void sc64_init (void); diff --git a/sw/riscv/SC64.ld b/sw/riscv/SC64.ld index 8b3874a..69d4601 100644 --- a/sw/riscv/SC64.ld +++ b/sw/riscv/SC64.ld @@ -1,5 +1,6 @@ MEMORY { - ram (rwx) : org = 0x00000000, len = 16k + ram (rwx) : org = 0x00000000, len = 15k + buffer (rw) : org = 0x00003C00, len = 1k rom (rx) : org = 0x10010000, len = 26k } @@ -44,6 +45,10 @@ SECTIONS { _ebss = .; } > ram + .buffer : { + *(.buffer) + } > buffer + __global_pointer$ = MIN(_ssdata + 0x800, MAX(_sdata + 0x800, _ebss - 0x800)); __stack_pointer$ = ORIGIN(ram) + LENGTH(ram); } diff --git a/sw/riscv/src/cfg.c b/sw/riscv/src/cfg.c index 19a11ec..ce65b07 100644 --- a/sw/riscv/src/cfg.c +++ b/sw/riscv/src/cfg.c @@ -247,7 +247,7 @@ void cfg_init (void) { set_save_type(SAVE_TYPE_NONE); CFG->DDIPL_OFFSET = DEFAULT_DDIPL_OFFSET; - CFG->SCR = CFG_SCR_CPU_READY | CFG_SCR_SDRAM_SWITCH; + CFG->SCR = CFG_SCR_CPU_READY; p.cic_seed = 0xFFFF; p.tv_type = 0x03;