mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 07:06:52 +01:00
UNFLoader style debug command line support
This commit is contained in:
parent
a94e4907f7
commit
faed6a7c4b
@ -413,7 +413,7 @@ void cfg_process (void) {
|
|||||||
usb_create_packet(&packet_info, PACKET_CMD_DEBUG_OUTPUT);
|
usb_create_packet(&packet_info, PACKET_CMD_DEBUG_OUTPUT);
|
||||||
packet_info.data_length = 4;
|
packet_info.data_length = 4;
|
||||||
packet_info.data[0] = args[1];
|
packet_info.data[0] = args[1];
|
||||||
packet_info.dma_length = args[1] & 0xFFFFFF;
|
packet_info.dma_length = (args[1] & 0xFFFFFF);
|
||||||
packet_info.dma_address = args[0];
|
packet_info.dma_address = args[0];
|
||||||
packet_info.done_callback = cfg_set_usb_output_ready;
|
packet_info.done_callback = cfg_set_usb_output_ready;
|
||||||
if (usb_enqueue_packet(&packet_info)) {
|
if (usb_enqueue_packet(&packet_info)) {
|
||||||
|
@ -308,6 +308,12 @@ class SC64:
|
|||||||
MPAL = 2
|
MPAL = 2
|
||||||
AUTO = 3
|
AUTO = 3
|
||||||
|
|
||||||
|
class __DebugDatatype(IntEnum):
|
||||||
|
TEXT = 1
|
||||||
|
RAWBINARY = 2
|
||||||
|
HEADER = 3
|
||||||
|
SCREENSHOT = 4
|
||||||
|
|
||||||
__debug_header: Optional[bytes] = None
|
__debug_header: Optional[bytes] = None
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
@ -391,6 +397,11 @@ class SC64:
|
|||||||
'dd_sd_mode': bool(self.__get_config(self.__CfgId.DD_SD_MODE)),
|
'dd_sd_mode': bool(self.__get_config(self.__CfgId.DD_SD_MODE)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def debug_send(self, datatype: __DebugDatatype, data: bytes) -> None:
|
||||||
|
if (len(data) > (8 * 1024 * 1024)):
|
||||||
|
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:
|
def download_memory(self) -> bytes:
|
||||||
return self.__read_memory(self.__Address.SDRAM, self.__Length.SDRAM + self.__Length.FLASH)
|
return self.__read_memory(self.__Address.SDRAM, self.__Length.SDRAM + self.__Length.FLASH)
|
||||||
|
|
||||||
@ -543,22 +554,24 @@ class SC64:
|
|||||||
|
|
||||||
def __handle_usb_packet(self, data: bytes) -> None:
|
def __handle_usb_packet(self, data: bytes) -> None:
|
||||||
header = self.__get_int(data[0:4])
|
header = self.__get_int(data[0:4])
|
||||||
datatype = ((header >> 24) & 0xFF)
|
datatype = self.__DebugDatatype((header >> 24) & 0xFF)
|
||||||
length = (header & 0xFFFFFF)
|
length = (header & 0xFFFFFF)
|
||||||
packet = data[4:]
|
packet = data[4:]
|
||||||
if (datatype == 0x01):
|
if (len(packet) != length):
|
||||||
|
print(f'Debug packet length and data length did not match')
|
||||||
|
elif (datatype == self.__DebugDatatype.TEXT):
|
||||||
print(packet.decode('UTF-8', errors='backslashreplace'), end='')
|
print(packet.decode('UTF-8', errors='backslashreplace'), end='')
|
||||||
elif (datatype == 0x02):
|
elif (datatype == self.__DebugDatatype.RAWBINARY):
|
||||||
filename = self.__generate_filename('binaryout', 'bin')
|
filename = self.__generate_filename('binaryout', 'bin')
|
||||||
with open(filename, 'wb+') as f:
|
with open(filename, 'wb+') as f:
|
||||||
f.write(packet)
|
f.write(packet)
|
||||||
print(f'Wrote {len(packet)} bytes to {filename}')
|
print(f'Wrote {len(packet)} bytes to {filename}')
|
||||||
elif (datatype == 0x03):
|
elif (datatype == self.__DebugDatatype.HEADER):
|
||||||
if (len(packet) == 16):
|
if (len(packet) == 16):
|
||||||
self.__debug_header = packet
|
self.__debug_header = packet
|
||||||
else:
|
else:
|
||||||
print(f'Size of header packet is invalid: {len(packet)}')
|
print(f'Size of header packet is invalid: {len(packet)}')
|
||||||
elif (datatype == 0x04):
|
elif (datatype == self.__DebugDatatype.SCREENSHOT):
|
||||||
filename = self.__generate_filename('screenshot', 'png')
|
filename = self.__generate_filename('screenshot', 'png')
|
||||||
if (self.__debug_header != None):
|
if (self.__debug_header != None):
|
||||||
header_datatype = self.__get_int(self.__debug_header[0:4])
|
header_datatype = self.__get_int(self.__debug_header[0:4])
|
||||||
@ -574,8 +587,39 @@ class SC64:
|
|||||||
print('Screenshot header data is invalid')
|
print('Screenshot header data is invalid')
|
||||||
else:
|
else:
|
||||||
print('Got screenshot packet without header data')
|
print('Got screenshot packet without header data')
|
||||||
|
|
||||||
|
def __handle_debug_input(self) -> None:
|
||||||
|
running = True
|
||||||
|
while (running):
|
||||||
|
try:
|
||||||
|
command = input()
|
||||||
|
if (len(command) > 0):
|
||||||
|
data = b''
|
||||||
|
datatype = self.__DebugDatatype.TEXT
|
||||||
|
if (command.count('@') != 2):
|
||||||
|
data += f'{command}\0'.encode()
|
||||||
else:
|
else:
|
||||||
print(f'Unhandled USB packet - datatype: [{datatype}], length: [{length}]')
|
start = command.index('@')
|
||||||
|
end = command.rindex('@')
|
||||||
|
filename = command[(start + 1):end]
|
||||||
|
if (len(filename) == 0):
|
||||||
|
raise FileNotFoundError
|
||||||
|
with open(filename, 'rb') as f:
|
||||||
|
file_data = f.read()
|
||||||
|
if (command.startswith('@') and command.endswith('@')):
|
||||||
|
datatype = self.__DebugDatatype.RAWBINARY
|
||||||
|
data += file_data
|
||||||
|
else:
|
||||||
|
data += f'{command[:start]}@{len(file_data)}@'.encode()
|
||||||
|
data += file_data
|
||||||
|
data += b'\0'
|
||||||
|
self.debug_send(datatype, data)
|
||||||
|
except ValueError as e:
|
||||||
|
print(f'Error: {e}')
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
print(f'Error: Cannot open file {e.filename}')
|
||||||
|
except EOFError:
|
||||||
|
running = False
|
||||||
|
|
||||||
def debug_loop(self, isv: bool=False, disks: Optional[list[str]]=None) -> None:
|
def debug_loop(self, isv: bool=False, disks: Optional[list[str]]=None) -> None:
|
||||||
dd = None
|
dd = None
|
||||||
@ -618,10 +662,12 @@ class SC64:
|
|||||||
print(f' - {os.path.basename(disk)}')
|
print(f' - {os.path.basename(disk)}')
|
||||||
print('Press button on SC64 device to cycle through provided disks')
|
print('Press button on SC64 device to cycle through provided disks')
|
||||||
|
|
||||||
print('Debug loop started, press Ctrl-C to exit')
|
print('\nDebug loop started, press Ctrl-C to exit\n')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while (True):
|
thread_input = Thread(target=self.__handle_debug_input, daemon=True)
|
||||||
|
thread_input.start()
|
||||||
|
while (thread_input.is_alive()):
|
||||||
packet = self.__link.get_packet()
|
packet = self.__link.get_packet()
|
||||||
if (packet != None):
|
if (packet != None):
|
||||||
(cmd, data) = packet
|
(cmd, data) = packet
|
||||||
@ -646,6 +692,8 @@ class SC64:
|
|||||||
print(f'64DD disk ejected - {os.path.basename(disks[current_image])}')
|
print(f'64DD disk ejected - {os.path.basename(disks[current_image])}')
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
finally:
|
||||||
|
print('\nDebug loop stopped\n')
|
||||||
|
|
||||||
if (dd and dd.loaded):
|
if (dd and dd.loaded):
|
||||||
self.__set_config(self.__CfgId.DD_DISK_STATE, self.__DDDiskState.EJECTED)
|
self.__set_config(self.__CfgId.DD_DISK_STATE, self.__DDDiskState.EJECTED)
|
||||||
|
Loading…
Reference in New Issue
Block a user