mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-21 21:49:15 +01:00
extended ROM and ISV fixes
This commit is contained in:
parent
dbf4b5e3c8
commit
2cc618b268
@ -429,7 +429,8 @@ module mcu_top (
|
||||
|
||||
REG_CFG_SCR: begin
|
||||
reg_rdata <= {
|
||||
21'd0,
|
||||
20'd0,
|
||||
n64_scb.rom_extended_enabled,
|
||||
n64_scb.eeprom_16k_mode,
|
||||
n64_scb.eeprom_enabled,
|
||||
n64_scb.ddipl_enabled,
|
||||
@ -638,6 +639,7 @@ module mcu_top (
|
||||
if (reset) begin
|
||||
mcu_int <= 1'b0;
|
||||
sd_scb.clock_mode <= 2'd0;
|
||||
n64_scb.rom_extended_enabled <= 1'b0;
|
||||
n64_scb.eeprom_16k_mode <= 1'b0;
|
||||
n64_scb.eeprom_enabled <= 1'b0;
|
||||
n64_scb.dd_enabled <= 1'b0;
|
||||
@ -695,6 +697,7 @@ module mcu_top (
|
||||
|
||||
REG_CFG_SCR: begin
|
||||
{
|
||||
n64_scb.rom_extended_enabled,
|
||||
n64_scb.eeprom_16k_mode,
|
||||
n64_scb.eeprom_enabled,
|
||||
n64_scb.ddipl_enabled,
|
||||
@ -706,7 +709,7 @@ module mcu_top (
|
||||
n64_scb.rom_write_enabled,
|
||||
bootloader_skip,
|
||||
n64_scb.bootloader_enabled
|
||||
} <= reg_wdata[10:0];
|
||||
} <= reg_wdata[11:0];
|
||||
end
|
||||
|
||||
REG_CFG_DATA_0: begin
|
||||
|
@ -214,10 +214,12 @@ module n64_pi (
|
||||
end
|
||||
end
|
||||
|
||||
if (n64_pi_dq_in >= 16'h1400 && n64_pi_dq_in < 16'h14E0) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_NONE;
|
||||
mem_offset <= (-32'h1400_0000) + FLASH_OFFSET;
|
||||
if (n64_scb.rom_extended_enabled) begin
|
||||
if (n64_pi_dq_in >= 16'h1400 && n64_pi_dq_in < 16'h14E0) begin
|
||||
read_port <= PORT_MEM;
|
||||
write_port <= PORT_NONE;
|
||||
mem_offset <= (-32'h1400_0000) + FLASH_OFFSET;
|
||||
end
|
||||
end
|
||||
|
||||
if (n64_scb.cfg_unlock) begin
|
||||
|
@ -6,6 +6,7 @@ interface n64_scb ();
|
||||
logic bootloader_enabled;
|
||||
logic rom_write_enabled;
|
||||
logic rom_shadow_enabled;
|
||||
logic rom_extended_enabled;
|
||||
logic sram_enabled;
|
||||
logic sram_banked;
|
||||
logic flashram_enabled;
|
||||
@ -57,6 +58,7 @@ interface n64_scb ();
|
||||
output bootloader_enabled,
|
||||
output rom_write_enabled,
|
||||
output rom_shadow_enabled,
|
||||
output rom_extended_enabled,
|
||||
output sram_enabled,
|
||||
output sram_banked,
|
||||
output flashram_enabled,
|
||||
@ -94,6 +96,7 @@ interface n64_scb ();
|
||||
input bootloader_enabled,
|
||||
input rom_write_enabled,
|
||||
input rom_shadow_enabled,
|
||||
input rom_extended_enabled,
|
||||
input sram_enabled,
|
||||
input sram_banked,
|
||||
input flashram_enabled,
|
||||
|
@ -23,6 +23,7 @@ typedef enum {
|
||||
CFG_ID_DD_DISK_STATE,
|
||||
CFG_ID_BUTTON_STATE,
|
||||
CFG_ID_BUTTON_MODE,
|
||||
CFG_ID_ROM_EXTENDED_ENABLE,
|
||||
} cfg_id_t;
|
||||
|
||||
typedef enum {
|
||||
@ -211,6 +212,9 @@ bool cfg_query (uint32_t *args) {
|
||||
case CFG_ID_BUTTON_MODE:
|
||||
args[1] = button_get_mode();
|
||||
break;
|
||||
case CFG_ID_ROM_EXTENDED_ENABLE:
|
||||
args[1] = (scr & CFG_SCR_ROM_EXTENDED_ENABLED);
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@ -273,6 +277,9 @@ bool cfg_update (uint32_t *args) {
|
||||
case CFG_ID_BUTTON_MODE:
|
||||
button_set_mode(args[1]);
|
||||
break;
|
||||
case CFG_ID_ROM_EXTENDED_ENABLE:
|
||||
cfg_change_scr_bits(CFG_SCR_ROM_EXTENDED_ENABLED, args[1]);
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
@ -56,95 +56,98 @@ typedef enum {
|
||||
} fpga_reg_t;
|
||||
|
||||
|
||||
#define FPGA_ID (0x64)
|
||||
#define FPGA_ID (0x64)
|
||||
|
||||
#define FPGA_MAX_MEM_TRANSFER (1024)
|
||||
#define FPGA_MAX_MEM_TRANSFER (1024)
|
||||
|
||||
#define USB_STATUS_RXNE (1 << 0)
|
||||
#define USB_STATUS_TXE (1 << 1)
|
||||
#define USB_STATUS_RXNE (1 << 0)
|
||||
#define USB_STATUS_TXE (1 << 1)
|
||||
|
||||
#define MEM_SCR_START (1 << 0)
|
||||
#define MEM_SCR_STOP (1 << 1)
|
||||
#define MEM_SCR_DIRECTION (1 << 2)
|
||||
#define MEM_SCR_BUSY (1 << 3)
|
||||
#define MEM_SCR_LENGTH_BIT (4)
|
||||
#define MEM_SCR_START (1 << 0)
|
||||
#define MEM_SCR_STOP (1 << 1)
|
||||
#define MEM_SCR_DIRECTION (1 << 2)
|
||||
#define MEM_SCR_BUSY (1 << 3)
|
||||
#define MEM_SCR_LENGTH_BIT (4)
|
||||
|
||||
#define STATUS_BUTTON (1 << 0)
|
||||
#define STATUS_SD_INSERTED (1 << 1)
|
||||
#define STATUS_CFG_PENDING (1 << 2)
|
||||
#define STATUS_BUTTON (1 << 0)
|
||||
#define STATUS_SD_INSERTED (1 << 1)
|
||||
#define STATUS_CFG_PENDING (1 << 2)
|
||||
|
||||
#define USB_SCR_FIFO_FLUSH (1 << 0)
|
||||
#define USB_SCR_RXNE (1 << 1)
|
||||
#define USB_SCR_TXE (1 << 2)
|
||||
#define USB_SCR_RESET_PENDING (1 << 3)
|
||||
#define USB_SCR_RESET_ACK (1 << 4)
|
||||
#define USB_SCR_WRITE_FLUSH (1 << 5)
|
||||
#define USB_SCR_FIFO_FLUSH (1 << 0)
|
||||
#define USB_SCR_RXNE (1 << 1)
|
||||
#define USB_SCR_TXE (1 << 2)
|
||||
#define USB_SCR_RESET_PENDING (1 << 3)
|
||||
#define USB_SCR_RESET_ACK (1 << 4)
|
||||
#define USB_SCR_WRITE_FLUSH (1 << 5)
|
||||
|
||||
#define DMA_SCR_START (1 << 0)
|
||||
#define DMA_SCR_STOP (1 << 1)
|
||||
#define DMA_SCR_DIRECTION (1 << 2)
|
||||
#define DMA_SCR_BUSY (1 << 3)
|
||||
#define DMA_SCR_START (1 << 0)
|
||||
#define DMA_SCR_STOP (1 << 1)
|
||||
#define DMA_SCR_DIRECTION (1 << 2)
|
||||
#define DMA_SCR_BUSY (1 << 3)
|
||||
|
||||
#define CFG_SCR_BOOTLOADER_ENABLED (1 << 0)
|
||||
#define CFG_SCR_BOOTLOADER_SKIP (1 << 1)
|
||||
#define CFG_SCR_ROM_WRITE_ENABLED (1 << 2)
|
||||
#define CFG_SCR_ROM_SHADOW_ENABLED (1 << 3)
|
||||
#define CFG_SCR_SRAM_ENABLED (1 << 4)
|
||||
#define CFG_SCR_SRAM_BANKED (1 << 5)
|
||||
#define CFG_SCR_FLASHRAM_ENABLED (1 << 6)
|
||||
#define CFG_SCR_DD_ENABLED (1 << 7)
|
||||
#define CFG_SCR_DDIPL_ENABLED (1 << 8)
|
||||
#define CFG_SCR_EEPROM_ENABLED (1 << 9)
|
||||
#define CFG_SCR_EEPROM_16K (1 << 10)
|
||||
#define CFG_SCR_BOOTLOADER_ENABLED (1 << 0)
|
||||
#define CFG_SCR_BOOTLOADER_SKIP (1 << 1)
|
||||
#define CFG_SCR_ROM_WRITE_ENABLED (1 << 2)
|
||||
#define CFG_SCR_ROM_SHADOW_ENABLED (1 << 3)
|
||||
#define CFG_SCR_SRAM_ENABLED (1 << 4)
|
||||
#define CFG_SCR_SRAM_BANKED (1 << 5)
|
||||
#define CFG_SCR_FLASHRAM_ENABLED (1 << 6)
|
||||
#define CFG_SCR_DD_ENABLED (1 << 7)
|
||||
#define CFG_SCR_DDIPL_ENABLED (1 << 8)
|
||||
#define CFG_SCR_EEPROM_ENABLED (1 << 9)
|
||||
#define CFG_SCR_EEPROM_16K (1 << 10)
|
||||
#define CFG_SCR_ROM_EXTENDED_ENABLED (1 << 11)
|
||||
|
||||
#define CFG_CMD_DONE (1 << 0)
|
||||
#define CFG_CMD_ERROR (1 << 1)
|
||||
#define CFG_CMD_IRQ (1 << 2)
|
||||
#define CFG_CMD_DONE (1 << 0)
|
||||
#define CFG_CMD_ERROR (1 << 1)
|
||||
#define CFG_CMD_IRQ (1 << 2)
|
||||
|
||||
#define FLASHRAM_SCR_DONE (1 << 0)
|
||||
#define FLASHRAM_SCR_PENDING (1 << 1)
|
||||
#define FLASHRAM_SCR_PAGE_BIT (2)
|
||||
#define FLASHRAM_SCR_PAGE_MASK (0x3FF << FLASHRAM_SCR_PAGE_BIT)
|
||||
#define FLASHRAM_SCR_SECTOR_OR_ALL (1 << 12)
|
||||
#define FLASHRAM_SCR_WRITE_OR_ERASE (1 << 13)
|
||||
#define FLASHRAM_SCR_DONE (1 << 0)
|
||||
#define FLASHRAM_SCR_PENDING (1 << 1)
|
||||
#define FLASHRAM_SCR_PAGE_BIT (2)
|
||||
#define FLASHRAM_SCR_PAGE_MASK (0x3FF << FLASHRAM_SCR_PAGE_BIT)
|
||||
#define FLASHRAM_SCR_SECTOR_OR_ALL (1 << 12)
|
||||
#define FLASHRAM_SCR_WRITE_OR_ERASE (1 << 13)
|
||||
|
||||
#define FLASH_SCR_BUSY (1 << 0)
|
||||
#define FLASH_SCR_BUSY (1 << 0)
|
||||
|
||||
#define RTC_SCR_PENDING (1 << 0)
|
||||
#define RTC_SCR_DONE (1 << 1)
|
||||
#define RTC_SCR_MAGIC (0x52544300)
|
||||
#define RTC_SCR_MAGIC_MASK (0xFFFFFF00)
|
||||
#define RTC_SCR_PENDING (1 << 0)
|
||||
#define RTC_SCR_DONE (1 << 1)
|
||||
#define RTC_SCR_MAGIC (0x52544300)
|
||||
#define RTC_SCR_MAGIC_MASK (0xFFFFFF00)
|
||||
|
||||
#define SD_SCR_CLOCK_MODE_OFF (0 << 0)
|
||||
#define SD_SCR_CLOCK_MODE_400KHZ (1 << 0)
|
||||
#define SD_SCR_CLOCK_MODE_25MHZ (2 << 0)
|
||||
#define SD_SCR_CLOCK_MODE_50MHZ (3 << 0)
|
||||
#define SD_SCR_CLOCK_MODE_OFF (0 << 0)
|
||||
#define SD_SCR_CLOCK_MODE_400KHZ (1 << 0)
|
||||
#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_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)
|
||||
#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)
|
||||
|
||||
#define SWAP32(x) ((x & 0xFF) << 24 | (x & 0xFF00) << 8 | (x & 0xFF0000) >> 8 | (x & 0xFF000000) >> 24)
|
||||
|
||||
|
||||
uint8_t fpga_id_get (void);
|
||||
|
@ -4,7 +4,8 @@
|
||||
#include "usb.h"
|
||||
|
||||
|
||||
#define ISV_READ_POINTER_ADDRESS (0x03FF0014)
|
||||
#define ISV_READ_POINTER_ADDRESS (0x03FF0004)
|
||||
#define ISV_WRITE_POINTER_ADDRESS (0x03FF0014)
|
||||
#define ISV_BUFFER_ADDRESS (0x03FF0020)
|
||||
#define ISV_BUFFER_SIZE ((64 * 1024) - 0x20)
|
||||
|
||||
@ -18,24 +19,28 @@ struct process {
|
||||
static struct process p;
|
||||
|
||||
|
||||
static uint32_t isv_get_read_pointer (void) {
|
||||
uint32_t read_pointer;
|
||||
fpga_mem_read(ISV_READ_POINTER_ADDRESS, 4, (uint8_t *) (&read_pointer));
|
||||
return (
|
||||
(read_pointer & 0x000000FF) << 24 |
|
||||
(read_pointer & 0x0000FF00) << 8 |
|
||||
(read_pointer & 0x00FF0000) >> 8 |
|
||||
(read_pointer & 0xFF000000) >> 24
|
||||
);
|
||||
static void isv_set_pointer (uint32_t address, uint32_t data) {
|
||||
data = SWAP32(data);
|
||||
fpga_mem_write(address, 4, (uint8_t *) (&data));
|
||||
}
|
||||
|
||||
static uint32_t isv_get_pointer (uint32_t address) {
|
||||
uint32_t data;
|
||||
fpga_mem_read(address, 4, (uint8_t *) (&data));
|
||||
return SWAP32(data);
|
||||
}
|
||||
|
||||
static void isv_update_read_pointer (void) {
|
||||
isv_set_pointer(ISV_READ_POINTER_ADDRESS, p.current_read_pointer);
|
||||
}
|
||||
|
||||
|
||||
void isv_set_enabled (bool enabled) {
|
||||
uint32_t read_pointer = 0;
|
||||
if (enabled) {
|
||||
p.enabled = true;
|
||||
p.current_read_pointer = 0;
|
||||
fpga_mem_write(ISV_READ_POINTER_ADDRESS, 4, (uint8_t *) (&read_pointer));
|
||||
isv_set_pointer(ISV_READ_POINTER_ADDRESS, 0);
|
||||
isv_set_pointer(ISV_WRITE_POINTER_ADDRESS, 0);
|
||||
} else {
|
||||
p.enabled = false;
|
||||
}
|
||||
@ -51,20 +56,26 @@ void isv_init (void) {
|
||||
|
||||
void isv_process (void) {
|
||||
if (p.enabled) {
|
||||
uint32_t read_pointer = isv_get_read_pointer();
|
||||
if (read_pointer < ISV_BUFFER_SIZE && read_pointer != p.current_read_pointer) {
|
||||
bool wrap = read_pointer < p.current_read_pointer;
|
||||
uint32_t write_pointer = isv_get_pointer(ISV_WRITE_POINTER_ADDRESS);
|
||||
|
||||
uint32_t length = ((wrap ? ISV_BUFFER_SIZE : read_pointer) - p.current_read_pointer);
|
||||
uint32_t offset = ISV_BUFFER_ADDRESS + p.current_read_pointer;
|
||||
if (p.current_read_pointer == write_pointer) {
|
||||
return;
|
||||
}
|
||||
if (write_pointer >= ISV_BUFFER_SIZE) {
|
||||
return;
|
||||
}
|
||||
|
||||
usb_tx_info_t packet_info;
|
||||
usb_create_packet(&packet_info, PACKET_CMD_ISV_OUTPUT);
|
||||
packet_info.dma_length = length;
|
||||
packet_info.dma_address = offset;
|
||||
if (usb_enqueue_packet(&packet_info)) {
|
||||
p.current_read_pointer = wrap ? 0 : read_pointer;
|
||||
}
|
||||
bool wrap = write_pointer < p.current_read_pointer;
|
||||
uint32_t length = (wrap ? ISV_BUFFER_SIZE : write_pointer) - p.current_read_pointer;
|
||||
uint32_t offset = ISV_BUFFER_ADDRESS + p.current_read_pointer;
|
||||
|
||||
usb_tx_info_t packet_info;
|
||||
usb_create_packet(&packet_info, PACKET_CMD_ISV_OUTPUT);
|
||||
packet_info.dma_length = length;
|
||||
packet_info.dma_address = offset;
|
||||
packet_info.done_callback = isv_update_read_pointer;
|
||||
if (usb_enqueue_packet(&packet_info)) {
|
||||
p.current_read_pointer = wrap ? 0 : write_pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,6 +199,8 @@ class SC64:
|
||||
FIRMWARE = 0x0200_0000
|
||||
DDIPL = 0x03BC_0000
|
||||
SAVE = 0x03FE_0000
|
||||
EXTENDED = 0x0400_0000
|
||||
BOOTLOADER = 0x04E0_0000
|
||||
SHADOW = 0x04FE_0000
|
||||
|
||||
class __Length(IntEnum):
|
||||
@ -208,6 +210,8 @@ class SC64:
|
||||
EEPROM = (2 * 1024)
|
||||
DDIPL = (4 * 1024 * 1024)
|
||||
SAVE = (128 * 1024)
|
||||
EXTENDED = (14 * 1024 * 1024)
|
||||
BOOTLOADER = (1920 * 1024)
|
||||
SHADOW = (128 * 1024)
|
||||
|
||||
class __SaveLength(IntEnum):
|
||||
@ -233,6 +237,7 @@ class SC64:
|
||||
DD_DISK_STATE = 11
|
||||
BUTTON_STATE = 12
|
||||
BUTTON_MODE = 13
|
||||
ROM_EXTENDED_ENABLE = 14
|
||||
|
||||
class __UpdateError(IntEnum):
|
||||
OK = 0
|
||||
@ -283,7 +288,7 @@ class SC64:
|
||||
EEPROM_16K = 2
|
||||
SRAM = 3
|
||||
FLASHRAM = 4
|
||||
SRAM_X3 = 5
|
||||
SRAM_3X = 5
|
||||
|
||||
class CICSeed(IntEnum):
|
||||
ALECK = 0xAC
|
||||
@ -333,11 +338,20 @@ class SC64:
|
||||
if ((address + length) > (self.__Address.FLASH + self.__Length.FLASH)):
|
||||
raise ValueError('Flash erase address or length outside of possible range')
|
||||
erase_block_size = self.__get_config(self.__CfgId.FLASH_ERASE_BLOCK)
|
||||
if ((address % erase_block_size != 0) or (length % erase_block_size != 0)):
|
||||
raise ValueError('Flash erase address or length not aligned to block size')
|
||||
if (address % erase_block_size != 0):
|
||||
raise ValueError('Flash erase address not aligned to block size')
|
||||
for offset in range(address, address + length, erase_block_size):
|
||||
self.__set_config(self.__CfgId.FLASH_ERASE_BLOCK, offset)
|
||||
|
||||
def __program_flash(self, address: int, data: bytes):
|
||||
program_chunk_size = (128 * 1024)
|
||||
if (self.__read_memory(address, len(data)) != data):
|
||||
self.__erase_flash_region(address, len(data))
|
||||
for offset in range(0, len(data), program_chunk_size):
|
||||
self.__write_memory(address + offset, data[offset:offset + program_chunk_size])
|
||||
if (self.__read_memory(address, len(data)) != data):
|
||||
raise ConnectionException('Flash memory program failure')
|
||||
|
||||
def reset_state(self) -> None:
|
||||
self.__set_config(self.__CfgId.ROM_WRITE_ENABLE, False)
|
||||
self.__set_config(self.__CfgId.ROM_SHADOW_ENABLE, False)
|
||||
@ -350,6 +364,7 @@ class SC64:
|
||||
self.__set_config(self.__CfgId.DD_DRIVE_TYPE, self.__DDDriveType.RETAIL)
|
||||
self.__set_config(self.__CfgId.DD_DISK_STATE, self.__DDDiskState.EJECTED)
|
||||
self.__set_config(self.__CfgId.BUTTON_MODE, self.__ButtonMode.NONE)
|
||||
self.__set_config(self.__CfgId.ROM_EXTENDED_ENABLE, False)
|
||||
self.set_cic_parameters()
|
||||
|
||||
def get_state(self):
|
||||
@ -368,24 +383,29 @@ class SC64:
|
||||
'dd_disk_state': self.__DDDiskState(self.__get_config(self.__CfgId.DD_DISK_STATE)),
|
||||
'button_state': bool(self.__get_config(self.__CfgId.BUTTON_STATE)),
|
||||
'button_mode': self.__ButtonMode(self.__get_config(self.__CfgId.BUTTON_MODE)),
|
||||
'rom_extended_enable': bool(self.__get_config(self.__CfgId.ROM_EXTENDED_ENABLE)),
|
||||
}
|
||||
|
||||
def upload_rom(self, data: bytes, use_shadow: bool=True):
|
||||
def download_memory(self) -> bytes:
|
||||
return self.__read_memory(self.__Address.SDRAM, self.__Length.SDRAM + self.__Length.FLASH)
|
||||
|
||||
def upload_rom(self, data: bytes, use_shadow: bool=True) -> None:
|
||||
rom_length = len(data)
|
||||
if (rom_length > self.__Length.SDRAM):
|
||||
if (rom_length > (self.__Length.SDRAM + self.__Length.EXTENDED)):
|
||||
raise ValueError('ROM size too big')
|
||||
sdram_length = rom_length
|
||||
sdram_length = self.__Length.SDRAM
|
||||
shadow_enabled = use_shadow and rom_length > (self.__Length.SDRAM - self.__Length.SHADOW)
|
||||
extended_enabled = rom_length > self.__Length.SDRAM
|
||||
if (shadow_enabled):
|
||||
sdram_length = (self.__Length.SDRAM - self.__Length.SHADOW)
|
||||
shadow_length = rom_length - sdram_length
|
||||
if (self.__read_memory(self.__Address.SHADOW, shadow_length) != data[sdram_length:]):
|
||||
self.__erase_flash_region(self.__Address.SHADOW, self.__Length.SHADOW)
|
||||
self.__write_memory(self.__Address.SHADOW, data[sdram_length:])
|
||||
if (self.__read_memory(self.__Address.SHADOW, shadow_length) != data[sdram_length:]):
|
||||
raise ConnectionException('Shadow ROM program failure')
|
||||
self.__write_memory(self.__Address.SDRAM, data[:sdram_length])
|
||||
shadow_data = data[sdram_length:sdram_length + self.__Length.SHADOW]
|
||||
self.__program_flash(self.__Address.SHADOW, shadow_data)
|
||||
self.__set_config(self.__CfgId.ROM_SHADOW_ENABLE, shadow_enabled)
|
||||
if (extended_enabled):
|
||||
extended_data = data[self.__Length.SDRAM:]
|
||||
self.__program_flash(self.__Address.EXTENDED, extended_data)
|
||||
self.__set_config(self.__CfgId.ROM_EXTENDED_ENABLE, extended_enabled)
|
||||
self.__write_memory(self.__Address.SDRAM, data[:sdram_length])
|
||||
|
||||
def upload_ddipl(self, data: bytes) -> None:
|
||||
if (len(data) > self.__Length.DDIPL):
|
||||
@ -615,8 +635,8 @@ if __name__ == '__main__':
|
||||
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('--rtc', action='store_true', help='update clock in SC64 to system time')
|
||||
parser.add_argument('--rom', help='upload ROM from specified file')
|
||||
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)')
|
||||
parser.add_argument('--rom', help='upload ROM from specified file')
|
||||
parser.add_argument('--save-type', type=SC64.SaveType, action=EnumAction, help='set save type')
|
||||
parser.add_argument('--save', help='upload save from specified file')
|
||||
parser.add_argument('--backup-save', help='download save and write it to specified file')
|
||||
@ -624,6 +644,7 @@ if __name__ == '__main__':
|
||||
parser.add_argument('--disk', action='append', help='path to 64DD disk (.ndd format), can be specified multiple times')
|
||||
parser.add_argument('--isv', action='store_true', help='enable IS-Viewer64 support')
|
||||
parser.add_argument('--debug', action='store_true', help='run debug loop (required for 64DD and IS-Viewer64)')
|
||||
parser.add_argument('--download-memory', help='download whole memory space and write it to specified file')
|
||||
|
||||
if (len(sys.argv) <= 1):
|
||||
parser.print_help()
|
||||
@ -706,6 +727,12 @@ if __name__ == '__main__':
|
||||
print('Downloading save... ', end='', flush=True)
|
||||
f.write(sc64.download_save())
|
||||
print('done')
|
||||
|
||||
if (args.download_memory):
|
||||
with open(args.download_memory, 'wb+') as f:
|
||||
print('Downloading memory... ', end='', flush=True)
|
||||
f.write(sc64.download_memory())
|
||||
print('done')
|
||||
except ValueError as e:
|
||||
print(f'\nValue error: {e}')
|
||||
except ConnectionException as e:
|
||||
|
Loading…
Reference in New Issue
Block a user