diff --git a/sw/bootloader/src/fatfs/ffconf.h b/sw/bootloader/src/fatfs/ffconf.h index 6fde966..e448f4f 100644 --- a/sw/bootloader/src/fatfs/ffconf.h +++ b/sw/bootloader/src/fatfs/ffconf.h @@ -34,7 +34,7 @@ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ -#define FF_USE_FASTSEEK 1 +#define FF_USE_FASTSEEK 0 /* This option switches fast seek function. (0:Disable or 1:Enable) */ @@ -224,7 +224,7 @@ / System Configurations /---------------------------------------------------------------------------*/ -#define FF_FS_TINY 0 +#define FF_FS_TINY 1 /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) / At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. / Instead of private sector buffer eliminated from the file object, common sector diff --git a/sw/bootloader/src/sc64.c b/sw/bootloader/src/sc64.c index c8411ee..3203c27 100644 --- a/sw/bootloader/src/sc64.c +++ b/sw/bootloader/src/sc64.c @@ -19,6 +19,7 @@ typedef enum { SC64_CMD_SD_SECTOR_SET = 'I', SC64_CMD_SD_WRITE = 'S', SC64_CMD_SD_READ = 's', + SC64_CMD_DD_SD_DISK_INFO = 'D', } cmd_id_t; typedef enum { @@ -199,3 +200,11 @@ bool sc64_sd_read_sectors (uint32_t *address, uint32_t sector, uint32_t count) { } return sc64_execute_cmd(SC64_CMD_SD_READ, read_args, NULL); } + +bool sc64_dd_set_sd_disk_info (uint32_t *address, uint32_t count) { + uint32_t args[2] = { (uint32_t) (address), count }; + if (sc64_execute_cmd(SC64_CMD_DD_SD_DISK_INFO, args, NULL)) { + return true; + } + return false; +} diff --git a/sw/bootloader/src/sc64.h b/sw/bootloader/src/sc64.h index 9554cf8..92c16e7 100644 --- a/sw/bootloader/src/sc64.h +++ b/sw/bootloader/src/sc64.h @@ -29,6 +29,8 @@ typedef enum { CFG_ID_DD_DISK_STATE, CFG_ID_BUTTON_STATE, CFG_ID_BUTTON_MODE, + CFG_ID_ROM_EXTENDED_ENABLE, + CFG_ID_DD_SD_MODE, } cfg_id_t; typedef enum { @@ -109,6 +111,7 @@ bool sc64_sd_card_get_status (void); bool sc64_sd_card_get_info (uint32_t *address); bool sc64_sd_write_sectors (uint32_t *address, uint32_t sector, uint32_t count); bool sc64_sd_read_sectors (uint32_t *address, uint32_t sector, uint32_t count); +bool sc64_dd_set_sd_disk_info (uint32_t *address, uint32_t count); #endif diff --git a/sw/bootloader/src/test.c b/sw/bootloader/src/test.c index 76fc098..277e025 100644 --- a/sw/bootloader/src/test.c +++ b/sw/bootloader/src/test.c @@ -13,6 +13,8 @@ bool test_check (void) { } void test_execute (void) { + uint8_t card_info[32] __attribute__((aligned(8))); + display_init(NULL); display_printf("SC64 Test suite\n\n"); @@ -27,18 +29,25 @@ void test_execute (void) { while (1); } - uint8_t card_info[32] __attribute__((aligned(8))); - pi_dma_read((io32_t *) (SC64_BUFFERS->BUFFER), card_info, sizeof(card_info)); - display_printf("CSD: 0x"); + display_printf("SD Card registers:\n CSD: 0x"); for (int i = 0; i < 16; i++) { display_printf("%02X", card_info[i]); } - display_printf("\nCID: 0x"); + display_printf("\n CID: 0x"); for (int i = 16; i < 32; i++) { display_printf("%02X", card_info[i]); } + display_printf("\n "); + for (int i = 16; i < 32; i++) { + display_printf("%c ", card_info[i] >= ' ' ? card_info[i] : 0xFF); + } + + if (sc64_sd_card_deinit()) { + display_printf("SD card deinit error!\n"); + while (1); + } while (1); } diff --git a/sw/controller/src/button.c b/sw/controller/src/button.c index e2fbaf1..e8b67c1 100644 --- a/sw/controller/src/button.c +++ b/sw/controller/src/button.c @@ -1,5 +1,6 @@ #include #include "button.h" +#include "dd.h" #include "fpga.h" #include "usb.h" @@ -66,7 +67,7 @@ void button_process (void) { break; case BUTTON_MODE_DD_DISK_SWAP: - // TODO: implement 64DD disk swapping + dd_handle_button(); p.trigger = false; break; diff --git a/sw/controller/src/cfg.c b/sw/controller/src/cfg.c index 5c7adb9..f4a580c 100644 --- a/sw/controller/src/cfg.c +++ b/sw/controller/src/cfg.c @@ -25,6 +25,7 @@ typedef enum { CFG_ID_BUTTON_STATE, CFG_ID_BUTTON_MODE, CFG_ID_ROM_EXTENDED_ENABLE, + CFG_ID_DD_SD_MODE, } cfg_id_t; typedef enum { @@ -106,6 +107,12 @@ static bool cfg_translate_address (uint32_t *address, uint32_t length, bool with return false; } } + if (*address >= 0x1FFE2000 && *address < 0x1FFE2800) { + if ((*address + length) <= 0x1FFE2800) { + *address = *address - 0x1FFE2000 + 0x05002000; + return false; + } + } return true; } @@ -220,6 +227,9 @@ bool cfg_query (uint32_t *args) { case CFG_ID_ROM_EXTENDED_ENABLE: args[1] = (scr & CFG_SCR_ROM_EXTENDED_ENABLED); break; + case CFG_ID_DD_SD_MODE: + args[1] = dd_get_sd_mode(); + break; default: return true; } @@ -285,6 +295,9 @@ bool cfg_update (uint32_t *args) { case CFG_ID_ROM_EXTENDED_ENABLE: cfg_change_scr_bits(CFG_SCR_ROM_EXTENDED_ENABLED, args[1]); break; + case CFG_ID_DD_SD_MODE: + dd_set_sd_mode(args[1]); + break; default: return true; } @@ -457,6 +470,14 @@ void cfg_process (void) { return; } break; + + case 'D': + if (cfg_translate_address(&args[0], args[1], false)) { + cfg_set_error(CFG_ERROR_BAD_ADDRESS); + return; + } + dd_set_sd_disk_info(args[0], args[1]); + break; default: cfg_set_error(CFG_ERROR_UNKNOWN_CMD); diff --git a/sw/controller/src/dd.c b/sw/controller/src/dd.c index 614c736..0d0d3e0 100644 --- a/sw/controller/src/dd.c +++ b/sw/controller/src/dd.c @@ -3,13 +3,17 @@ #include "fpga.h" #include "hw.h" #include "rtc.h" +#include "sd.h" #include "usb.h" #define DD_SECTOR_MAX_SIZE (232) #define DD_BLOCK_DATA_SECTORS_NUM (85) -#define DD_BLOCK_BUFFER_ADDRESS (0x03BC0000UL - (DD_SECTOR_MAX_SIZE * DD_BLOCK_DATA_SECTORS_NUM)) +#define DD_BLOCK_BUFFER_SIZE (ALIGN(DD_SECTOR_MAX_SIZE * DD_BLOCK_DATA_SECTORS_NUM, SD_SECTOR_SIZE) + SD_SECTOR_SIZE) +#define DD_BLOCK_BUFFER_ADDRESS (0x03BC0000UL - DD_BLOCK_BUFFER_SIZE) #define DD_SECTOR_BUFFER_ADDRESS (0x05002800UL) +#define DD_SD_SECTOR_TABLE_SIZE (DD_BLOCK_BUFFER_SIZE / SD_SECTOR_SIZE) +#define DD_SD_MAX_DISKS (4) #define DD_DRIVE_ID_RETAIL (0x0003) #define DD_DRIVE_ID_DEVELOPMENT (0x0004) @@ -47,8 +51,7 @@ enum state { STATE_NEXT_BLOCK, }; - -typedef union sector_info { +typedef union { uint32_t full; struct { uint8_t sector_num; @@ -58,6 +61,11 @@ typedef union sector_info { }; } sector_info_t; +typedef struct { + uint32_t thb_table_address; + uint32_t sector_table_address; +} sd_disk_info_t; + struct process { enum state state; rtc_time_t time; @@ -73,7 +81,12 @@ struct process { sector_info_t sector_info; bool block_ready; bool block_valid; + uint32_t block_offset; dd_drive_type_t drive_type; + bool sd_mode; + uint8_t sd_current_disk; + sd_disk_info_t sd_disk_info[DD_SD_MAX_DISKS]; + uint32_t sd_sector_table[DD_SD_SECTOR_TABLE_SIZE]; }; @@ -87,28 +100,88 @@ static uint16_t dd_track_head_block (void) { return (track | head | block); } +static uint32_t dd_fill_sd_sector_table (uint32_t index) { + uint32_t tmp; + sd_disk_info_t info = p.sd_disk_info[p.sd_current_disk]; + uint32_t thb_entry_address = (info.thb_table_address + (index * sizeof(uint32_t))); + fpga_mem_read(thb_entry_address, sizeof(uint32_t), (uint8_t *) (&tmp)); + uint32_t start_offset = SWAP32(tmp); + if (start_offset == 0xFFFFFFFF) { + return 0; + } + p.block_offset = (start_offset % SD_SECTOR_SIZE); + uint32_t block_length = ((p.sector_info.sector_size + 1) * DD_BLOCK_DATA_SECTORS_NUM); + uint32_t end_offset = ((start_offset + block_length) - 1); // CHECK THIS + uint32_t starting_sector = (start_offset / SD_SECTOR_SIZE); + uint32_t sectors = (1 + ((end_offset / SD_SECTOR_SIZE) - starting_sector)); + for (int i = 0; i < sectors; i++) { + uint32_t sector_entry_address = info.sector_table_address + ((starting_sector + i) * sizeof(uint32_t)); + fpga_mem_read(sector_entry_address, sizeof(uint32_t), (uint8_t *) (&tmp)); + p.sd_sector_table[i] = SWAP32(tmp); + } + return sectors; +} + static bool dd_block_read_request (void) { - usb_tx_info_t packet_info; - usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST); - packet_info.data_length = 12; - packet_info.data[0] = 1; - packet_info.data[1] = DD_BLOCK_BUFFER_ADDRESS; - packet_info.data[2] = dd_track_head_block(); - p.block_ready = false; - return usb_enqueue_packet(&packet_info); + uint16_t index = dd_track_head_block(); + uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS; + + if (p.sd_mode) { + dd_set_block_ready(false); + uint32_t sectors = dd_fill_sd_sector_table(index); + if (sectors > 0) { + for (int i = 0; i < sectors; i++) { + if (sd_read_sectors(buffer_address, p.sd_sector_table[i], 1)) { + return true; + } + buffer_address += SD_SECTOR_SIZE; + } + dd_set_block_ready(true); + } + return true; + } else { + usb_tx_info_t packet_info; + usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST); + packet_info.data_length = 12; + packet_info.data[0] = 1; + packet_info.data[1] = buffer_address; + packet_info.data[2] = index; + p.block_ready = false; + p.block_offset = 0; + return usb_enqueue_packet(&packet_info); + } } static bool dd_block_write_request (void) { - usb_tx_info_t packet_info; - usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST); - packet_info.data_length = 12; - packet_info.data[0] = 2; - packet_info.data[1] = DD_BLOCK_BUFFER_ADDRESS; - packet_info.data[2] = dd_track_head_block(); - packet_info.dma_length = (p.sector_info.sector_size + 1) * DD_BLOCK_DATA_SECTORS_NUM; - packet_info.dma_address = DD_BLOCK_BUFFER_ADDRESS; - p.block_ready = false; - return usb_enqueue_packet(&packet_info); + uint32_t index = dd_track_head_block(); + uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS; + + if (p.sd_mode) { + dd_set_block_ready(false); + uint32_t sectors = dd_fill_sd_sector_table(index); + if (sectors > 0) { + for (int i = 0; i < sectors; i++) { + if (sd_write_sectors(buffer_address, p.sd_sector_table[i], 1)) { + return true; + } + buffer_address += SD_SECTOR_SIZE; + } + dd_set_block_ready(true); + } + return true; + } else { + usb_tx_info_t packet_info; + usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST); + packet_info.data_length = 12; + packet_info.data[0] = 2; + packet_info.data[1] = buffer_address; + packet_info.data[2] = index; + packet_info.dma_length = (p.sector_info.sector_size + 1) * DD_BLOCK_DATA_SECTORS_NUM; + packet_info.dma_address = buffer_address; + p.block_ready = false; + p.block_offset = 0; + return usb_enqueue_packet(&packet_info); + } } static void dd_set_cmd_response_ready (void) { @@ -168,6 +241,29 @@ void dd_set_disk_state (dd_disk_state_t state) { fpga_reg_set(REG_DD_SCR, scr); } +bool dd_get_sd_mode (void) { + return p.sd_mode; +} + +void dd_set_sd_mode (bool value) { + p.sd_mode = value; +} + +void dd_set_sd_disk_info (uint32_t address, uint32_t length) { + uint32_t tmp[2]; + p.sd_current_disk = 0; + for (int i = 0; i < 4; i++) { + fpga_mem_read(address, sizeof(tmp), (uint8_t *) (tmp)); + p.sd_disk_info[i].thb_table_address = SWAP32(tmp[0]); + p.sd_disk_info[i].sector_table_address = SWAP32(tmp[1]); + address += sizeof(tmp); + } +} + +void dd_handle_button (void) { + // TODO: disk swap +} + void dd_init (void) { fpga_reg_set(REG_DD_SCR, 0); fpga_reg_set(REG_DD_HEAD_TRACK, 0); @@ -178,6 +274,8 @@ void dd_init (void) { p.disk_spinning = false; p.bm_running = false; p.drive_type = DD_DRIVE_TYPE_RETAIL; + p.sd_mode = false; + p.sd_current_disk = 0; } void dd_process (void) { @@ -365,7 +463,7 @@ void dd_process (void) { case STATE_SECTOR_READ: fpga_mem_copy( - DD_BLOCK_BUFFER_ADDRESS + (p.current_sector * (p.sector_info.sector_size + 1)), + DD_BLOCK_BUFFER_ADDRESS + p.block_offset + (p.current_sector * (p.sector_info.sector_size + 1)), DD_SECTOR_BUFFER_ADDRESS, p.sector_info.sector_size + 1 ); @@ -377,7 +475,7 @@ void dd_process (void) { case STATE_SECTOR_WRITE: fpga_mem_copy( DD_SECTOR_BUFFER_ADDRESS, - DD_BLOCK_BUFFER_ADDRESS + (p.current_sector * (p.sector_info.sector_size + 1)), + DD_BLOCK_BUFFER_ADDRESS + p.block_offset + (p.current_sector * (p.sector_info.sector_size + 1)), p.sector_info.sector_size + 1 ); p.current_sector += 1; diff --git a/sw/controller/src/dd.h b/sw/controller/src/dd.h index ab0f624..0f8d833 100644 --- a/sw/controller/src/dd.h +++ b/sw/controller/src/dd.h @@ -17,11 +17,15 @@ typedef enum { } dd_disk_state_t; +void dd_set_block_ready (bool valid); dd_drive_type_t dd_get_drive_type (void); void dd_set_drive_type (dd_drive_type_t type); dd_disk_state_t dd_get_disk_state (void); void dd_set_disk_state (dd_disk_state_t state); -void dd_set_block_ready (bool valid); +bool dd_get_sd_mode (void); +void dd_set_sd_mode (bool value); +void dd_set_sd_disk_info (uint32_t address, uint32_t length); +void dd_handle_button (void); void dd_init (void); void dd_process (void); diff --git a/sw/controller/src/fpga.h b/sw/controller/src/fpga.h index b7dfe65..c656f6a 100644 --- a/sw/controller/src/fpga.h +++ b/sw/controller/src/fpga.h @@ -55,6 +55,7 @@ typedef enum { } fpga_reg_t; +#define ALIGN(value, align) (((value) + ((typeof(value))(align) - 1)) & ~((typeof(value))(align) - 1)) #define SWAP16(x) ((((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8)) #define SWAP32(x) (((x) & 0xFF) << 24 | ((x) & 0xFF00) << 8 | ((x) & 0xFF0000) >> 8 | ((x) & 0xFF000000) >> 24) diff --git a/sw/controller/src/sd.c b/sw/controller/src/sd.c index 318b70a..6a82406 100644 --- a/sw/controller/src/sd.c +++ b/sw/controller/src/sd.c @@ -6,7 +6,7 @@ #include "sd.h" -#define SD_BUFFER_ADDRESS (0x05000000UL) +#define SD_INIT_BUFFER_ADDRESS (0x05002800UL) #define CMD6_ARG_CHECK_HS (0x00FFFFF1UL) #define CMD6_ARG_SWITCH_HS (0x80FFFFF1UL) @@ -28,7 +28,10 @@ #define R7_SUPPLY_VOLTAGE_27_36_V (1 << 8) #define R7_CHECK_PATTERN (0xAA << 0) -#define SD_BLOCK_SIZE (512) +#define SWITCH_FUNCTION_CURRENT_LIMIT (SD_INIT_BUFFER_ADDRESS + 0) +#define SWITCH_FUNCTION_GROUP_1 (SD_INIT_BUFFER_ADDRESS + 12) +#define SWITCH_FUNCTION_GROUP_1_HS (1 << 1) + #define DAT_BLOCK_MAX_COUNT (256) @@ -166,7 +169,7 @@ static bool sd_acmd (uint8_t acmd, uint32_t arg, rsp_type_t rsp_type, void *rsp) } static void sd_dat_prepare (uint32_t address, uint32_t count, dat_mode_t mode) { - uint32_t length = (count * SD_BLOCK_SIZE); + uint32_t length = (count * SD_SECTOR_SIZE); uint32_t sd_dat = (((count - 1) << SD_DAT_BLOCKS_BIT) | SD_DAT_FIFO_FLUSH); uint32_t sd_dma_scr = DMA_SCR_START; @@ -209,7 +212,7 @@ static bool sd_dat_wait (uint16_t timeout) { bool sd_card_init (void) { uint32_t arg; uint32_t rsp; - uint16_t sd_function; + uint16_t tmp; if (p.card_initialized) { return false; @@ -289,7 +292,7 @@ bool sd_card_init (void) { return true; } - sd_dat_prepare(SD_BUFFER_ADDRESS, 1, DAT_READ); + sd_dat_prepare(SD_INIT_BUFFER_ADDRESS, 1, DAT_READ); if (sd_cmd(6, CMD6_ARG_CHECK_HS, RSP_R1, NULL)) { sd_dat_abort(); sd_card_deinit(); @@ -300,9 +303,14 @@ bool sd_card_init (void) { sd_card_deinit(); return true; } - fpga_mem_read(SD_BUFFER_ADDRESS + 12, 2, (uint8_t *) (&sd_function)); - if (SWAP16(sd_function) & (1 << 1)) { - sd_dat_prepare(SD_BUFFER_ADDRESS, 1, DAT_READ); + fpga_mem_read(SWITCH_FUNCTION_CURRENT_LIMIT, 2, (uint8_t *) (&tmp)); + if (SWAP16(tmp) == 0) { + sd_card_deinit(); + return true; + } + fpga_mem_read(SWITCH_FUNCTION_GROUP_1, 2, (uint8_t *) (&tmp)); + if (SWAP16(tmp) & SWITCH_FUNCTION_GROUP_1_HS) { + sd_dat_prepare(SD_INIT_BUFFER_ADDRESS, 1, DAT_READ); if (sd_cmd(6, CMD6_ARG_SWITCH_HS, RSP_R1, NULL)) { sd_dat_abort(); sd_card_deinit(); @@ -313,8 +321,8 @@ bool sd_card_init (void) { sd_card_deinit(); return true; } - fpga_mem_read(SD_BUFFER_ADDRESS + 12, 2, (uint8_t *) (&sd_function)); - if (SWAP16(sd_function) & (1 << 1)) { + fpga_mem_read(SWITCH_FUNCTION_GROUP_1, 2, (uint8_t *) (&tmp)); + if (SWAP16(tmp) & SWITCH_FUNCTION_GROUP_1_HS) { sd_set_clock(CLOCK_50MHZ); } } @@ -352,7 +360,7 @@ bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count) { } if (!p.card_type_block) { - sector *= SD_BLOCK_SIZE; + sector *= SD_SECTOR_SIZE; } while (count > 0) { @@ -365,14 +373,14 @@ bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count) { return true; } sd_dat_prepare(address, blocks, DAT_WRITE); - bool error = sd_dat_wait(1000); - sd_cmd(12, 0, RSP_R1b, NULL); - if (error) { + if (sd_dat_wait(1000)) { sd_dat_abort(); + sd_cmd(12, 0, RSP_R1b, NULL); return true; } - address += (blocks * SD_BLOCK_SIZE); - sector += (blocks * (p.card_type_block ? 1 : SD_BLOCK_SIZE)); + sd_cmd(12, 0, RSP_R1b, NULL); + address += (blocks * SD_SECTOR_SIZE); + sector += (blocks * (p.card_type_block ? 1 : SD_SECTOR_SIZE)); count -= blocks; } @@ -385,7 +393,7 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) { } if (!p.card_type_block) { - sector *= SD_BLOCK_SIZE; + sector *= SD_SECTOR_SIZE; } while (count > 0) { @@ -406,8 +414,8 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) { } return true; } - address += (blocks * SD_BLOCK_SIZE); - sector += (blocks * (p.card_type_block ? 1 : SD_BLOCK_SIZE)); + address += (blocks * SD_SECTOR_SIZE); + sector += (blocks * (p.card_type_block ? 1 : SD_SECTOR_SIZE)); count -= blocks; } diff --git a/sw/controller/src/sd.h b/sw/controller/src/sd.h index 5648d8d..54d8dd3 100644 --- a/sw/controller/src/sd.h +++ b/sw/controller/src/sd.h @@ -5,6 +5,9 @@ #include +#define SD_SECTOR_SIZE (512) + + bool sd_card_init (void); void sd_card_deinit (void); bool sd_card_get_status (void); diff --git a/sw/pc/dd64.py b/sw/pc/dd64.py index 2af1d6c..bd1e75b 100755 --- a/sw/pc/dd64.py +++ b/sw/pc/dd64.py @@ -185,6 +185,9 @@ class DD64Image: self.__file.close() self.__drive_type = None + def get_block_info_table(self) -> list[tuple[int, int]]: + return self.__block_info_table + def get_drive_type(self) -> str: return self.__drive_type @@ -222,6 +225,12 @@ if __name__ == '__main__': print(dd.read_block(track, head, block)[:4]) except BadBlockError: print(f'Bad ID block [track: {track}, head: {head}, block: {block}]') + if (len(sys.argv) >= 3): + with open(sys.argv[2], 'wb+') as f: + block_info_table = dd.get_block_info_table() + for block in block_info_table: + offset = 0xFFFFFFFF if block == None else block[0] + f.write(offset.to_bytes(4, byteorder='big')) dd.unload() else: print(f'[{sys.argv[0]}]: Expected disk image path as first argument') diff --git a/sw/pc/sc64.py b/sw/pc/sc64.py index 3c77c63..58c21a6 100755 --- a/sw/pc/sc64.py +++ b/sw/pc/sc64.py @@ -238,6 +238,7 @@ class SC64: BUTTON_STATE = 12 BUTTON_MODE = 13 ROM_EXTENDED_ENABLE = 14 + DD_SD_MODE = 15 class __UpdateError(IntEnum): OK = 0 @@ -364,6 +365,7 @@ class SC64: 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_config(self.__CfgId.DD_SD_MODE, False) self.set_cic_parameters() def get_state(self): @@ -383,6 +385,7 @@ class SC64: '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)), + 'dd_sd_mode': bool(self.__get_config(self.__CfgId.DD_SD_MODE)), } def download_memory(self) -> bytes: @@ -564,6 +567,7 @@ class SC64: break if (dd): self.__set_config(self.__CfgId.DD_MODE, self.__DDMode.FULL) + self.__set_config(self.__CfgId.DD_SD_MODE, False) self.__set_config(self.__CfgId.DD_DRIVE_TYPE, { 'retail': self.__DDDriveType.RETAIL, 'development': self.__DDDriveType.DEVELOPMENT