This commit is contained in:
Polprzewodnikowy 2021-12-18 02:15:36 +01:00
parent ea01bba7ad
commit 3040b73062
4 changed files with 134 additions and 9 deletions

View File

@ -32,6 +32,7 @@ class SC64:
__CFG_ID_FLASH_READ = 11 __CFG_ID_FLASH_READ = 11
__CFG_ID_FLASH_PROGRAM = 12 __CFG_ID_FLASH_PROGRAM = 12
__CFG_ID_RECONFIGURE = 13 __CFG_ID_RECONFIGURE = 13
__CFG_ID_DD_SETTING = 14
__SC64_VERSION_V2 = 0x53437632 __SC64_VERSION_V2 = 0x53437632
@ -50,6 +51,11 @@ class SC64:
__DD_USER_SECTORS_IN_BLOCK = 85 __DD_USER_SECTORS_IN_BLOCK = 85
__DD_SETTING_DISK_EJECTED = 0
__DD_SETTING_DISK_INSERTED = 1
__DD_SETTING_DISK_CHANGED = 2
__DD_SETTING_DRIVE_RETAIL = 3
__DD_SETTING_DRIVE_DEVELOPMENT = 4
def __init__(self) -> None: def __init__(self) -> None:
self.__serial = None self.__serial = None
@ -364,6 +370,26 @@ class SC64:
self.__write_file_to_sdram(file, dd_ipl_offset, min_length=self.__DDIPL_ROM_LENGTH) self.__write_file_to_sdram(file, dd_ipl_offset, min_length=self.__DDIPL_ROM_LENGTH)
def set_dd_disk_state(self, state: int) -> None:
if (state == "ejected"):
self.__change_config(self.__CFG_ID_DD_SETTING, self.__DD_SETTING_DISK_EJECTED)
elif (state == "inserted"):
self.__change_config(self.__CFG_ID_DD_SETTING, self.__DD_SETTING_DISK_INSERTED)
elif (state == "changed"):
self.__change_config(self.__CFG_ID_DD_SETTING, self.__DD_SETTING_DISK_CHANGED)
else:
raise SC64Exception("DD disk state outside of supported values")
def set_dd_drive_type(self, type: str) -> None:
if (type == "retail"):
self.__change_config(self.__CFG_ID_DD_SETTING, self.__DD_SETTING_DRIVE_RETAIL)
elif (type == "development"):
self.__change_config(self.__CFG_ID_DD_SETTING, self.__DD_SETTING_DRIVE_DEVELOPMENT)
else:
raise SC64Exception("DD drive type outside of supported values")
def __debug_process_fsd_set_sector(self, data: bytes) -> None: def __debug_process_fsd_set_sector(self, data: bytes) -> None:
sector = int.from_bytes(data[0:4], byteorder='big') sector = int.from_bytes(data[0:4], byteorder='big')
if (self.__fsd_file): if (self.__fsd_file):
@ -383,7 +409,7 @@ class SC64:
self.__fsd_file.write(data) self.__fsd_file.write(data)
def __dd_track_offset(self, head_track: int, sector_size: int) -> int: def __dd_calculate_file_offset(self, head_track: int, starting_block: int) -> int:
# shamelessly stolen from MAME implementation, to be rewritten # shamelessly stolen from MAME implementation, to be rewritten
head = (head_track & 0x1000) >> 9 head = (head_track & 0x1000) >> 9
track = head_track & 0xFFF track = head_track & 0xFFF
@ -434,12 +460,27 @@ class SC64:
0x4149200 0x4149200
] ]
return ddStartOffset[dd_zone] + tr_off * sector_size * self.__DD_USER_SECTORS_IN_BLOCK * 2 ddZoneSecSize = [
232,
216,
208,
192,
176,
160,
144,
128,
216,
208,
192,
176,
160,
144,
128,
112
]
offset = ddStartOffset[dd_zone] + tr_off * ddZoneSecSize[dd_zone] * self.__DD_USER_SECTORS_IN_BLOCK * 2
def __dd_calculate_file_offset(self, head_track: int, starting_block: int, sector_size: int) -> int: offset += starting_block * self.__DD_USER_SECTORS_IN_BLOCK * ddZoneSecSize[dd_zone]
offset = self.__dd_track_offset(head_track, sector_size)
offset += starting_block * self.__DD_USER_SECTORS_IN_BLOCK * sector_size
return offset return offset
@ -449,8 +490,10 @@ class SC64:
starting_block = int.from_bytes(data[6:7], byteorder='little') starting_block = int.from_bytes(data[6:7], byteorder='little')
sector_size = int.from_bytes(data[7:8], byteorder='little') sector_size = int.from_bytes(data[7:8], byteorder='little')
block_data = None
if (self.__disk_file): if (self.__disk_file):
file_offset = self.__dd_calculate_file_offset(head_track, starting_block, sector_size) file_offset = self.__dd_calculate_file_offset(head_track, starting_block)
self.__disk_file.seek(file_offset) self.__disk_file.seek(file_offset)
if (transfer_mode): if (transfer_mode):
block_data = self.__disk_file.read(sector_size * self.__DD_USER_SECTORS_IN_BLOCK) block_data = self.__disk_file.read(sector_size * self.__DD_USER_SECTORS_IN_BLOCK)
@ -458,6 +501,7 @@ class SC64:
else: else:
block_data = self.__read_long(sector_size * self.__DD_USER_SECTORS_IN_BLOCK) block_data = self.__read_long(sector_size * self.__DD_USER_SECTORS_IN_BLOCK)
self.__disk_file.write(block_data) self.__disk_file.write(block_data)
print(f"{'R'if transfer_mode else 'W'} - H: {1 if (head_track & 0x2000) else 0} | T: {head_track & 0x1FFF} | S: {starting_block} = [{hex(int.from_bytes(block_data[0:4], byteorder='big'))}]")
else: else:
if (transfer_mode): if (transfer_mode):
self.__debug_write(self.__DEBUG_ID_DD_BLOCK, bytes(4)) self.__debug_write(self.__DEBUG_ID_DD_BLOCK, bytes(4))
@ -589,6 +633,7 @@ if __name__ == "__main__":
parser.add_argument("-q", default=None, action="store_true", required=False, help="start debug server") parser.add_argument("-q", default=None, action="store_true", required=False, help="start debug server")
parser.add_argument("-f", metavar="sd_path", default=None, required=False, help="path to disk or file for fake SD card emulation") parser.add_argument("-f", metavar="sd_path", default=None, required=False, help="path to disk or file for fake SD card emulation")
parser.add_argument("-k", metavar="disk_path", default=None, required=False, help="path to 64DD disk file") parser.add_argument("-k", metavar="disk_path", default=None, required=False, help="path to 64DD disk file")
parser.add_argument("-x", default=False, action="store_true", required=False, help="set 64DD drive type to development")
parser.add_argument("rom", metavar="rom_path", default=None, help="path to ROM file", nargs="?") parser.add_argument("rom", metavar="rom_path", default=None, help="path to ROM file", nargs="?")
if (len(sys.argv) <= 1): if (len(sys.argv) <= 1):
@ -614,6 +659,7 @@ if __name__ == "__main__":
debug_server = args.q debug_server = args.q
sd_file = args.f sd_file = args.f
disk_file = args.k disk_file = args.k
development_64dd = args.x
firmware_backup_file = "sc64firmware.bin.bak" firmware_backup_file = "sc64firmware.bin.bak"
@ -651,6 +697,14 @@ if __name__ == "__main__":
print(f"Setting 64DD emulation to [{'Enabled' if dd_enable else 'Disabled'}]") print(f"Setting 64DD emulation to [{'Enabled' if dd_enable else 'Disabled'}]")
sc64.set_dd_enable(dd_enable) sc64.set_dd_enable(dd_enable)
if (development_64dd):
print(f"Setting 64DD drive type to [Development]")
sc64.set_dd_drive_type("development" if development_64dd else "retail")
if (disk_file):
print(f"Setting 64DD disk state to [Inserted]")
sc64.set_dd_disk_state("inserted" if disk_file else "ejected")
if (rom_file): if (rom_file):
if (is_read): if (is_read):
if (rom_length > 0): if (rom_length > 0):
@ -679,6 +733,7 @@ if __name__ == "__main__":
print(f"Error: {e}") print(f"Error: {e}")
parser.exit(1) parser.exit(1)
except KeyboardInterrupt: except KeyboardInterrupt:
pass if (disk_file):
sc64.set_dd_disk_state("ejected")
finally: finally:
sys.stdout.write("\033[0m") sys.stdout.write("\033[0m")

View File

@ -1,4 +1,5 @@
#include "cfg.h" #include "cfg.h"
#include "dd.h"
#include "flash.h" #include "flash.h"
#include "joybus.h" #include "joybus.h"
#include "usb.h" #include "usb.h"
@ -31,6 +32,7 @@ enum cfg_id {
CFG_ID_FLASH_READ, CFG_ID_FLASH_READ,
CFG_ID_FLASH_PROGRAM, CFG_ID_FLASH_PROGRAM,
CFG_ID_RECONFIGURE, CFG_ID_RECONFIGURE,
CFG_ID_DD_SETTING,
}; };
enum save_type { enum save_type {
@ -50,6 +52,14 @@ enum boot_mode {
BOOT_MODE_DIRECT = 3, BOOT_MODE_DIRECT = 3,
}; };
enum dd_setting {
DD_SETTING_DISK_EJECTED,
DD_SETTING_DISK_INSERTED,
DD_SETTING_DISK_CHANGED,
DD_SETTING_DRIVE_RETAIL,
DD_SETTING_DRIVE_DEVELOPMENT,
};
struct process { struct process {
enum save_type save_type; enum save_type save_type;
@ -112,6 +122,26 @@ static void set_save_type (enum save_type save_type) {
CFG->SAVE_OFFSET = save_offset; CFG->SAVE_OFFSET = save_offset;
} }
static void set_dd_setting (enum dd_setting setting) {
switch (setting) {
case DD_SETTING_DISK_EJECTED:
dd_set_disk_state(DD_DISK_EJECTED);
break;
case DD_SETTING_DISK_INSERTED:
dd_set_disk_state(DD_DISK_INSERTED);
break;
case DD_SETTING_DISK_CHANGED:
dd_set_disk_state(DD_DISK_CHANGED);
break;
case DD_SETTING_DRIVE_RETAIL:
dd_set_drive_type_development(false);
break;
case DD_SETTING_DRIVE_DEVELOPMENT:
dd_set_drive_type_development(true);
break;
}
}
uint32_t cfg_get_version (void) { uint32_t cfg_get_version (void) {
return CFG->VERSION; return CFG->VERSION;
@ -164,6 +194,9 @@ void cfg_update (uint32_t *args) {
); );
} }
break; break;
case CFG_ID_DD_SETTING:
set_dd_setting(args[1]);
break;
} }
} }

View File

@ -152,8 +152,36 @@ static bool dd_block_write_done (void) {
} }
void dd_set_disk_state (disk_state_t disk_state) {
uint32_t scr = (DD->SCR & (~(DD_SCR_DISK_CHANGED | DD_SCR_DISK_INSERTED)));
switch (disk_state) {
case DD_DISK_EJECTED:
break;
case DD_DISK_INSERTED:
scr |= DD_SCR_DISK_INSERTED;
break;
case DD_DISK_CHANGED:
scr |= (DD_SCR_DISK_CHANGED | DD_SCR_DISK_INSERTED);
break;
}
DD->SCR = scr;
}
void dd_set_drive_type_development (bool value) {
if (value) {
DD->DRIVE_ID = DD_DRIVE_ID_DEVELOPMENT;
p.is_dev_disk = true;
} else {
DD->DRIVE_ID = DD_DRIVE_ID_RETAIL;
p.is_dev_disk = false;
}
}
void dd_init (void) { void dd_init (void) {
DD->SCR = DD_SCR_DISK_INSERTED; DD->SCR = 0;
DD->HEAD_TRACK = 0; DD->HEAD_TRACK = 0;
DD->DRIVE_ID = DD_DRIVE_ID_RETAIL; DD->DRIVE_ID = DD_DRIVE_ID_RETAIL;
p.state = STATE_IDLE; p.state = STATE_IDLE;

View File

@ -5,6 +5,15 @@
#include "sys.h" #include "sys.h"
typedef enum {
DD_DISK_EJECTED,
DD_DISK_INSERTED,
DD_DISK_CHANGED,
} disk_state_t;
void dd_set_disk_state (disk_state_t disk_state);
void dd_set_drive_type_development (bool value);
void dd_init (void); void dd_init (void);
void process_dd (void); void process_dd (void);