[SC64][SW] Changed firmware version reporting

This commit is contained in:
Mateusz Faderewski 2023-02-20 18:17:09 +01:00
parent 56cdd3a709
commit 409ba28359
14 changed files with 142 additions and 152 deletions

View File

@ -5,7 +5,7 @@
- [SC64 registers](#sc64-registers)
- [`0x1FFF_0000`: **STATUS/COMMAND**](#0x1fff_0000-statuscommand)
- [`0x1FFF_0004`: **DATA0** and `0x1FFF_0008`: **DATA1**](#0x1fff_0004-data0-and-0x1fff_0008-data1)
- [`0x1FFF_000C`: **VERSION**](#0x1fff_000c-version)
- [`0x1FFF_000C`: **IDENTIFIER**](#0x1fff_000c-identifier)
- [`0x1FFF_0010`: **KEY**](#0x1fff_0010-key)
- [Command execution flow](#command-execution-flow)
@ -88,11 +88,11 @@ Protocol is command based with support for up to 256 diferrent commands and two
Support for interrupts is provided but currently no command relies on it, 64DD IRQ is handled separately.
| name | address | size | access | usage |
| ------------------ | ------------- | ------- | ------ | -------------------------------- |
| ------------------ | ------------- | ------- | ------ | ---------------------------------- |
| **STATUS/COMMAND** | `0x1FFF_0000` | 4 bytes | RW | Command execution and status |
| **DATA0** | `0x1FFF_0004` | 4 bytes | RW | Command argument/result 0 |
| **DATA1** | `0x1FFF_0008` | 4 bytes | RW | Command argument/result 1 |
| **VERSION** | `0x1FFF_000C` | 4 bytes | RW | Hardware version and IRQ clear |
| **IDENTIFIER** | `0x1FFF_000C` | 4 bytes | RW | Flashcart identifier and IRQ clear |
| **KEY** | `0x1FFF_0010` | 4 bytes | W | SC64 register access lock/unlock |
---
@ -121,11 +121,11 @@ Note: Result is valid only when command has executed and `CMD_BUSY` bit is reset
---
#### `0x1FFF_000C`: **VERSION**
#### `0x1FFF_000C`: **IDENTIFIER**
| name | bits | access | meaning |
| --------- | ------ | ------ | --------------------------------------------- |
| `VERSION` | [31:0] | RW | Hardware version (ASCII `SCv2`) and IRQ clear |
| ------------ | ------ | ------ | ------------------------------------------------- |
| `IDENTIFIER` | [31:0] | RW | Flashcart identifier (ASCII `SCv2`) and IRQ clear |
Note: Writing any value to this register will clear pending flashcart interrupt.

View File

@ -5,24 +5,24 @@
## USB commands
| id | name | arg0 | arg1 | data | response | description |
| --- | ---------------------- | ------------ | ------------ | ---- | ---------------- | --------------------------------------------------- |
| `v` | **HW_VERSION_GET** | --- | --- | --- | hw_version | Get HW version |
| `V` | **API_VERSION_GET** | --- | --- | --- | api_version | Get USB command API version |
| `R` | **STATE_RESET** | --- | --- | --- | --- | Reset entire flashcart state |
| `B` | **CIC_PARAMS_SET** | cic_params_0 | cic_params_1 | --- | --- | Set CIC disable/mode/seed/checksum |
| --- | ---------------------- | ------------ | ------------ | ---- | ---------------- | ------------------------------------------------------------- |
| `v` | **IDENTIFIER_GET** | --- | --- | --- | identifier | Get flashcart identifier `SCv2` |
| `V` | **VERSION_GET** | --- | --- | --- | version | Get flashcart firmware version |
| `R` | **STATE_RESET** | --- | --- | --- | --- | Reset flashcart state (CIC params and config options) |
| `B` | **CIC_PARAMS_SET** | cic_params_0 | cic_params_1 | --- | --- | Set CIC emulation parameters (disable/seed/checksum) |
| `c` | **CONFIG_GET** | config_id | --- | --- | current_value | Get config option |
| `C` | **CONFIG_SET** | config_id | new_value | --- | --- | Set config option |
| `a` | **SETTING_GET** | setting_id | --- | --- | current_value | Get persistent setting |
| `A` | **SETTING_SET** | setting_id | new_value | --- | --- | Set persistent setting |
| `a` | **SETTING_GET** | setting_id | --- | --- | current_value | Get persistent setting option |
| `A` | **SETTING_SET** | setting_id | new_value | --- | --- | Set persistent setting option |
| `t` | **TIME_GET** | --- | --- | --- | time | Get current RTC value |
| `T` | **TIME_SET** | time_0 | time_1 | --- | --- | Set RTC value |
| `T` | **TIME_SET** | time_0 | time_1 | --- | --- | Set new RTC value |
| `m` | **MEMORY_READ** | address | length | --- | data | Read data from specified memory address |
| `M` | **MEMORY_WRITE** | address | length | data | --- | Write data to specified memory address |
| `U` | **USB_WRITE** | type | length | data | N/A | Send data to be received by app running on N64 (no response!) |
| `D` | **DD_SET_BLOCK_READY** | success | --- | --- | --- | Notify flashcart about 64DD block readiness |
| `U` | **USB_WRITE** | type | length | data | N/A | Send data to be received by app running on N64 |
| `p` | **FLASH_WAIT_BUSY** | wait | --- | --- | erase_block_size | Wait until flash ready / Get flash block erase size |
| `P` | **FLASH_ERASE_BLOCK** | address | --- | --- | --- | Start flash block erase |
| `f` | **FIRMWARE_BACKUP** | address | --- | --- | status/length | Backup firmware to specified memory address |
| `F` | **FIRMWARE_UPDATE** | address | length | --- | status | Update firmware from specified memory address |
| `p` | **FLASH_WAIT_BUSY** | wait | --- | --- | erase_block_size | Wait until flash ready / get flash block erase size |
| `P` | **FLASH_ERASE_BLOCK** | address | --- | --- | --- | Start flash block erase |
| `?` | **DEBUG_GET** | --- | --- | --- | debug_data | Get internal FPGA debug info |
| `%` | **STACK_USAGE_GET** | --- | --- | --- | stack_usage | Get per task stack usage |

View File

@ -6,14 +6,14 @@
| id | name | arg0 | arg1 | rsp0 | rsp1 | description |
| --- | --------------------- | ---------- | ------------ | ---------------- | -------------- | -------------------------------------------------- |
| `v` | **HW_VERSION_GET** | --- | --- | hw_version | --- | Get HW version |
| `V` | **API_VERSION_GET** | --- | --- | api_version | --- | Get N64 command API version |
| `v` | **IDENTIFIER_GET** | --- | --- | identifier | --- | Get flashcart identifier `SCv2` |
| `V` | **VERSION_GET** | --- | --- | version | --- | Get flashcart firmware version |
| `c` | **CONFIG_GET** | config_id | --- | --- | current_value | Get config option |
| `C` | **CONFIG_SET** | config_id | new_value | --- | previous_value | Set config option and get previous value |
| `c` | **SETTING_GET** | setting_id | --- | --- | current_value | Get persistent setting option |
| `C` | **SETTING_SET** | setting_id | new_value | --- | --- | Set persistent setting option |
| `t` | **TIME_GET** | --- | --- | time_0 | time_1 | Get current RTC value |
| `T` | **TIME_SET** | time_0 | time_1 | --- | --- | Set RTC value |
| `T` | **TIME_SET** | time_0 | time_1 | --- | --- | Set new RTC value |
| `m` | **USB_READ** | pi_address | length | --- | --- | Receive data from USB to flashcart |
| `M` | **USB_WRITE** | pi_address | length/type | --- | --- | Send data from from flashcart to USB |
| `u` | **USB_READ_STATUS** | --- | --- | read_status/type | length | Get USB read status and type/length |
@ -27,4 +27,3 @@
| `K` | **FLASH_PROGRAM** | pi_address | length | --- | --- | Program flash with bytes loaded into data buffer |
| `p` | **FLASH_WAIT_BUSY** | wait | --- | erase_block_size | --- | Wait until flash ready / get block erase size |
| `P` | **FLASH_ERASE_BLOCK** | pi_address | --- | --- | --- | Start flash block erase |
| `?` | **DEBUG_GET** | --- | --- | debug_data_0 | debug_data_1 | Get internal FPGA debug info |

View File

@ -332,7 +332,7 @@ module mcu_top (
REG_CFG_DATA_0,
REG_CFG_DATA_1,
REG_CFG_CMD,
REG_CFG_VERSION,
REG_CFG_IDENTIFIER,
REG_FLASHRAM_SCR,
REG_FLASH_SCR,
REG_RTC_SCR,
@ -363,7 +363,7 @@ module mcu_top (
logic bootloader_skip;
assign n64_scb.cfg_version = 32'h53437632;
assign n64_scb.cfg_identifier = 32'h53437632;
logic dd_bm_ack;
@ -460,8 +460,8 @@ module mcu_top (
};
end
REG_CFG_VERSION: begin
reg_rdata <= n64_scb.cfg_version;
REG_CFG_IDENTIFIER: begin
reg_rdata <= n64_scb.cfg_identifier;
end
REG_FLASHRAM_SCR: begin

View File

@ -16,8 +16,8 @@ module n64_cfg (
REG_DATA_0_L,
REG_DATA_1_H,
REG_DATA_1_L,
REG_VERSION_H,
REG_VERSION_L,
REG_IDENTIFIER_H,
REG_IDENTIFIER_L,
REG_KEY_H,
REG_KEY_L
} e_reg;
@ -39,8 +39,8 @@ module n64_cfg (
REG_DATA_0_L: reg_bus.rdata = n64_scb.cfg_wdata[0][15:0];
REG_DATA_1_H: reg_bus.rdata = n64_scb.cfg_wdata[1][31:16];
REG_DATA_1_L: reg_bus.rdata = n64_scb.cfg_wdata[1][15:0];
REG_VERSION_H: reg_bus.rdata = n64_scb.cfg_version[31:16];
REG_VERSION_L: reg_bus.rdata = n64_scb.cfg_version[15:0];
REG_IDENTIFIER_H: reg_bus.rdata = n64_scb.cfg_identifier[31:16];
REG_IDENTIFIER_L: reg_bus.rdata = n64_scb.cfg_identifier[15:0];
REG_KEY_H: reg_bus.rdata = 16'd0;
REG_KEY_L: reg_bus.rdata = 16'd0;
endcase
@ -83,7 +83,7 @@ module n64_cfg (
REG_DATA_0_L: n64_scb.cfg_rdata[0][15:0] <= reg_bus.wdata;
REG_DATA_1_H: n64_scb.cfg_rdata[1][31:16] <= reg_bus.wdata;
REG_DATA_1_L: n64_scb.cfg_rdata[1][15:0] <= reg_bus.wdata;
REG_VERSION_H: irq <= 1'b0;
REG_IDENTIFIER_H: irq <= 1'b0;
REG_KEY_H, REG_KEY_L: begin
lock_sequence_counter <= lock_sequence_counter + 1'd1;
if (reg_bus.wdata != 16'hFFFF) begin

View File

@ -51,7 +51,7 @@ interface n64_scb ();
logic [7:0] cfg_cmd;
logic [31:0] cfg_rdata [0:1];
logic [31:0] cfg_wdata [0:1];
logic [31:0] cfg_version;
logic [31:0] cfg_identifier;
logic [15:0] save_count;
@ -94,7 +94,7 @@ interface n64_scb ();
input cfg_cmd,
input cfg_rdata,
output cfg_wdata,
output cfg_version,
output cfg_identifier,
input save_count,
@ -194,7 +194,7 @@ interface n64_scb ();
output cfg_cmd,
output cfg_rdata,
input cfg_wdata,
input cfg_version
input cfg_identifier
);
modport save_counter (

View File

@ -5,7 +5,7 @@
typedef struct {
io32_t SR_CMD;
io32_t DATA[2];
io32_t VERSION;
io32_t IDENTIFIER;
io32_t KEY;
} sc64_regs_t;
@ -16,7 +16,7 @@ typedef struct {
#define SC64_SR_CMD_ERROR (1 << 30)
#define SC64_SR_CPU_BUSY (1 << 31)
#define SC64_VERSION_2 (0x53437632)
#define SC64_V2_IDENTIFIER (0x53437632)
#define SC64_KEY_RESET (0x00000000UL)
#define SC64_KEY_UNLOCK_1 (0x5F554E4CUL)
@ -24,8 +24,8 @@ typedef struct {
#define SC64_KEY_LOCK (0xFFFFFFFFUL)
typedef enum {
SC64_CMD_HW_VERSION_GET = 'v',
SC64_CMD_API_VERSION_GET = 'V',
SC64_CMD_IDENTIFIER_GET = 'v',
SC64_CMD_VERSION_GET = 'V',
SC64_CMD_CONFIG_GET = 'c',
SC64_CMD_CONFIG_SET = 'C',
SC64_CMD_SETTING_GET = 'a',
@ -45,7 +45,6 @@ typedef enum {
SC64_CMD_FLASH_PROGRAM = 'K',
SC64_CMD_FLASH_WAIT_BUSY = 'p',
SC64_CMD_FLASH_ERASE_BLOCK = 'P',
SC64_CMD_DEBUG_GET = '?',
} cmd_id_t;
typedef enum {
@ -98,8 +97,8 @@ void sc64_lock (void) {
}
bool sc64_check_presence (void) {
uint32_t version = pi_io_read(&SC64_REGS->VERSION);
if (version == SC64_VERSION_2) {
uint32_t identifier = pi_io_read(&SC64_REGS->IDENTIFIER);
if (identifier == SC64_V2_IDENTIFIER) {
sc64_wait_cpu_busy();
return true;
}
@ -114,7 +113,7 @@ bool sc64_irq_pending (void) {
}
void sc64_irq_clear (void) {
pi_io_write(&SC64_REGS->VERSION, 0);
pi_io_write(&SC64_REGS->IDENTIFIER, 0);
}
uint32_t sc64_get_config (sc64_cfg_id_t id) {

View File

@ -221,8 +221,8 @@ static bool cfg_set_save_type (save_type_t save_type) {
}
uint32_t cfg_get_version (void) {
return fpga_reg_get(REG_CFG_VERSION);
uint32_t cfg_get_identifier (void) {
return fpga_reg_get(REG_CFG_IDENTIFIER);
}
bool cfg_query (uint32_t *args) {
@ -468,11 +468,11 @@ void cfg_process (void) {
switch (cmd) {
case 'v':
args[0] = cfg_get_version();
args[0] = cfg_get_identifier();
break;
case 'V':
args[0] = version_api(API_N64);
args[0] = version_firmware();
break;
case 'c':
@ -666,11 +666,6 @@ void cfg_process (void) {
}
break;
case '?':
args[0] = fpga_reg_get(REG_DEBUG_0);
args[1] = fpga_reg_get(REG_DEBUG_1);
break;
default:
cfg_set_error(CFG_ERROR_UNKNOWN_CMD);
return;

View File

@ -16,7 +16,7 @@ typedef enum {
} save_type_t;
uint32_t cfg_get_version (void);
uint32_t cfg_get_identifier (void);
bool cfg_query (uint32_t *args);
bool cfg_update (uint32_t *args);
bool cfg_query_setting (uint32_t *args);

View File

@ -28,7 +28,7 @@ typedef enum {
REG_CFG_DATA_0,
REG_CFG_DATA_1,
REG_CFG_CMD,
REG_CFG_VERSION,
REG_CFG_IDENTIFIER,
REG_FLASHRAM_SCR,
REG_FLASH_SCR,
REG_RTC_SCR,

View File

@ -160,14 +160,14 @@ static void usb_rx_process (void) {
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
p.response_info.data_length = 4;
p.response_info.data[0] = cfg_get_version();
p.response_info.data[0] = cfg_get_identifier();
break;
case 'V':
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
p.response_info.data_length = 4;
p.response_info.data[0] = version_api(API_USB);
p.response_info.data[0] = version_firmware();
break;
case 'R':
@ -247,12 +247,6 @@ static void usb_rx_process (void) {
}
break;
case 'D':
dd_set_block_ready(p.rx_args[0] == 0);
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
break;
case 'U':
if ((p.read_length > 0) && usb_dma_ready()) {
uint32_t length = (p.read_length > p.rx_args[1]) ? p.rx_args[1] : p.read_length;
@ -274,6 +268,28 @@ static void usb_rx_process (void) {
}
break;
case 'D':
dd_set_block_ready(p.rx_args[0] == 0);
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
break;
case 'p':
if (p.rx_args[0]) {
flash_wait_busy();
}
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
p.response_info.data_length = 4;
p.response_info.data[0] = FLASH_ERASE_BLOCK_SIZE;
break;
case 'P':
p.response_error = flash_erase_block(p.rx_args[0]);
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
break;
case 'f': {
bool rom_write_enable_restore = cfg_set_rom_write_enable(false);
p.response_info.data[0] = update_backup(p.rx_args[0], &p.response_info.data[1]);
@ -300,22 +316,6 @@ static void usb_rx_process (void) {
break;
}
case 'p':
if (p.rx_args[0]) {
flash_wait_busy();
}
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
p.response_info.data_length = 4;
p.response_info.data[0] = FLASH_ERASE_BLOCK_SIZE;
break;
case 'P':
p.response_error = flash_erase_block(p.rx_args[0]);
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;
break;
case '?':
p.rx_state = RX_STATE_IDLE;
p.response_pending = true;

View File

@ -1,17 +1,10 @@
#include "version.h"
#define VERSION_API_USB (2)
#define VERSION_API_N64 (2)
#define VERSION_MAJOR (2)
#define VERSION_MINOR (12)
uint32_t version_api (version_api_type_t type) {
switch (type) {
case API_USB:
return VERSION_API_USB;
case API_N64:
return VERSION_API_N64;
default:
return 0;
}
uint32_t version_firmware (void) {
return ((VERSION_MAJOR << 16) | (VERSION_MINOR));
}

View File

@ -5,13 +5,7 @@
#include <stdint.h>
typedef enum {
API_USB,
API_N64,
} version_api_type_t;
uint32_t version_api (version_api_type_t type);
uint32_t version_firmware (void);
#endif

View File

@ -200,6 +200,7 @@ class SC64:
FLASH = 0x0400_0000
BUFFER = 0x0500_0000
EEPROM = 0x0500_2000
END = 0x0500_297F
FIRMWARE = 0x0200_0000
DDIPL = 0x03BC_0000
SAVE = 0x03FE_0000
@ -321,7 +322,8 @@ class SC64:
SCREENSHOT = 4
GDB = 0xDB
__MIN_SUPPORTED_API_VERSION = 2
__SUPPORTED_MAJOR_VERSION = 2
__SUPPORTED_MINOR_VERSION = 12
__isv_line_buffer: bytes = b''
__debug_header: Optional[bytes] = None
@ -329,21 +331,24 @@ class SC64:
def __init__(self) -> None:
self.__link = SC64Serial()
version = self.__link.execute_cmd(cmd=b'v')
if (version != b'SCv2'):
raise ConnectionException('Unknown SC64 HW version')
identifier = self.__link.execute_cmd(cmd=b'v')
if (identifier != b'SCv2'):
raise ConnectionException('Unknown SC64 v2 identifier')
def __get_int(self, data: bytes) -> int:
return int.from_bytes(data[:4], byteorder='big')
def check_api_version(self) -> None:
def check_firmware_version(self) -> None:
try:
data = self.__link.execute_cmd(cmd=b'V')
version = self.__link.execute_cmd(cmd=b'V')
major = self.__get_int(version[0:2])
minor = self.__get_int(version[2:4])
if (major != self.__SUPPORTED_MAJOR_VERSION):
raise ConnectionException()
if (minor < self.__SUPPORTED_MINOR_VERSION):
raise ConnectionException()
except ConnectionException:
raise ConnectionException('Outdated SC64 API, please update firmware')
version = self.__get_int(data)
if (version < self.__MIN_SUPPORTED_API_VERSION):
raise ConnectionException('Unsupported SC64 API version, please update firmware')
raise ConnectionException(f'Unsupported SC64 version ({major}.{minor}), please update firmware')
def __set_config(self, config: __CfgId, value: int) -> None:
try:
@ -461,8 +466,10 @@ class SC64:
raise ValueError('Debug data size too big')
self.__link.execute_cmd(cmd=b'U', args=[datatype, len(data)], data=data, response=False)
def download_memory(self) -> bytes:
return self.__read_memory(self.__Address.MEMORY, self.__Length.MEMORY)
def download_memory(self, address: int, length: int) -> bytes:
if ((address < 0) or (length < 0) or ((address + length) > self.__Address.END)):
raise ValueError('Invalid address or length')
return self.__read_memory(address, length)
def upload_rom(self, data: bytes, use_shadow: bool=True) -> None:
rom_length = len(data)
@ -582,7 +589,7 @@ class SC64:
raise ConnectionException('Error while getting firmware backup')
return self.__read_memory(address, length)
def set_cic_parameters(self, seed: Optional[int]=None, disabled=False) -> tuple[int, int, bool]:
def update_cic_parameters(self, seed: Optional[int]=None, disabled=False) -> tuple[int, int, bool]:
if ((seed != None) and (seed < 0 or seed > 0xFF)):
raise ValueError('CIC seed outside of allowed values')
boot_mode = self.__get_config(self.__CfgId.BOOT_MODE)
@ -884,7 +891,7 @@ class SC64:
current_image = 0
next_image = 0
self.__set_config(self.__CfgId.ROM_WRITE_ENABLE, isv)
self.__set_config(self.__CfgId.ROM_WRITE_ENABLE, 1 if (isv != 0) else 0)
self.__set_config(self.__CfgId.ISV_ADDRESS, isv)
if (isv != 0):
print(f'IS-Viewer64 support set to [ENABLED] at ROM offset [0x{(isv):08X}]')
@ -992,16 +999,24 @@ if __name__ == '__main__':
disabled = bool(int(params[1])) if len(params) >= 2 else None
return (seed, disabled)
def download_memory_type(argument: str):
params = argument.split(',')
if (len(params) < 2 or len(params) > 3):
raise argparse.ArgumentError()
address = int(params[0], 0)
length = int(params[1], 0)
file = params[2] if len(params) >= 3 else 'sc64dump.bin'
return (address, length, file)
parser = argparse.ArgumentParser(description='SC64 control software')
parser.add_argument('--backup-firmware', metavar='file', help='backup SC64 firmware and write it to specified file')
parser.add_argument('--update-firmware', metavar='file', help='update SC64 firmware from specified file')
parser.add_argument('--update-bootloader', metavar='file', help='update SC64 bootloader (not recommended, use --update-firmware instead)')
parser.add_argument('--reset-state', action='store_true', help='reset SC64 internal state')
parser.add_argument('--print-state', action='store_true', help='print SC64 internal state')
parser.add_argument('--led-enabled', metavar='{true,false}', help='disable or enable LED I/O activity blinking')
parser.add_argument('--led-blink', metavar='{yes,no}', help='disable or enable LED I/O activity blinking')
parser.add_argument('--boot', type=SC64.BootMode, action=EnumAction, help='set boot mode')
parser.add_argument('--tv', type=SC64.TVType, action=EnumAction, help='force TV type to set value')
parser.add_argument('--cic', type=SC64.CICSeed, action=EnumAction, help='force CIC seed to set value')
parser.add_argument('--tv', type=SC64.TVType, action=EnumAction, help='force TV type to set value, not used when direct boot mode is enabled')
parser.add_argument('--cic', type=SC64.CICSeed, action=EnumAction, help='force CIC seed to set value, not used when direct boot mode is enabled')
parser.add_argument('--cic-params', metavar='seed,[disabled]', type=cic_params_type, help='set CIC emulation parameters')
parser.add_argument('--rtc', action='store_true', help='update clock in SC64 to system time')
parser.add_argument('--no-shadow', action='store_false', help='do not put last 128 kB of ROM inside flash memory (can corrupt non EEPROM saves)')
@ -1014,7 +1029,7 @@ if __name__ == '__main__':
parser.add_argument('--isv', type=lambda x: int(x, 0), default=0, help='enable IS-Viewer64 support at provided ROM offset')
parser.add_argument('--gdb', metavar='port', type=int, help='expose socket port for GDB debugging')
parser.add_argument('--debug', action='store_true', help='run debug loop')
parser.add_argument('--download-memory', metavar='file', help='download whole memory space and write it to specified file')
parser.add_argument('--download-memory', metavar='address,length,[file]', type=download_memory_type, help='download specified memory region and write it to file')
if (len(sys.argv) <= 1):
parser.print_help()
@ -1039,13 +1054,7 @@ if __name__ == '__main__':
sc64.update_firmware(f.read(), status_callback)
print('done')
sc64.check_api_version()
if (args.update_bootloader):
with open(args.update_bootloader, 'rb') as f:
print('Uploading Bootloader... ', end='', flush=True)
sc64.upload_bootloader(f.read())
print('done')
sc64.check_firmware_version()
if (args.reset_state):
sc64.reset_state()
@ -1059,10 +1068,10 @@ if __name__ == '__main__':
value = getattr(value, 'name')
print(f' {key}: {value}')
if (args.led_enabled != None):
value = (args.led_enabled == 'true')
sc64.set_led_enable(value)
print(f'LED blinking set to [{"ENABLED" if value else "DISABLED"}]')
if (args.led_blink):
blink = (args.led_blink == 'yes')
sc64.set_led_enable(blink)
print(f'LED blinking set to [{"ENABLED" if blink else "DISABLED"}]')
if (args.tv != None):
sc64.set_tv_type(args.tv)
@ -1085,6 +1094,12 @@ if __name__ == '__main__':
autodetected_save_type = sc64.autodetect_save_type(rom_data)
print('done')
if (args.ddipl):
with open(args.ddipl, 'rb') as f:
print('Uploading 64DD IPL... ', end='', flush=True)
sc64.upload_ddipl(f.read())
print('done')
if (args.save_type != None or autodetected_save_type != None):
save_type = args.save_type if args.save_type != None else autodetected_save_type
sc64.set_save_type(save_type)
@ -1096,26 +1111,20 @@ if __name__ == '__main__':
sc64.upload_save(f.read())
print('done')
if (args.ddipl):
with open(args.ddipl, 'rb') as f:
print('Uploading 64DD IPL... ', end='', flush=True)
sc64.upload_ddipl(f.read())
print('done')
if (args.boot != None):
sc64.set_boot_mode(args.boot)
print(f'Boot mode set to [{args.boot.name}]')
if (args.cic_params != None):
(seed, disabled) = args.cic_params
(seed, checksum, dd_mode) = sc64.set_cic_parameters(seed, disabled)
(seed, checksum, dd_mode) = sc64.update_cic_parameters(seed, disabled)
print('CIC parameters set to [', end='')
print(f'{"DISABLED" if disabled else "ENABLED"}, ', end='')
print(f'{"DDIPL" if dd_mode else "ROM"}, ', end='')
print(f'seed: 0x{seed:02X}, checksum: 0x{checksum:012X}', end='')
print(']')
else:
sc64.set_cic_parameters()
sc64.update_cic_parameters()
if (args.debug or args.isv or args.disk or args.gdb):
sc64.debug_loop(isv=args.isv, disks=args.disk, gdb_port=args.gdb)
@ -1126,10 +1135,11 @@ if __name__ == '__main__':
f.write(sc64.download_save())
print('done')
if (args.download_memory):
with open(args.download_memory, 'wb') as f:
if (args.download_memory != None):
(address, length, file) = args.download_memory
with open(file, 'wb') as f:
print('Downloading memory... ', end='', flush=True)
f.write(sc64.download_memory())
f.write(sc64.download_memory(address, length))
print('done')
except ValueError as e:
print(f'\nValue error: {e}')