mirror of
https://github.com/digarok/gsplus.git
synced 2024-09-27 16:55:48 +00:00
debugger - add toolcall and GS/OS call recognition to the disassembler.
This commit is contained in:
parent
a65833d6d8
commit
9589abfda7
@ -140,6 +140,8 @@ add_executable(GSplus WIN32 MACOSX_BUNDLE
|
||||
$<$<BOOL:${WIN32}>:win32.rc>
|
||||
$<$<BOOL:${APPLE}>:assets/gsp_icon.icns>
|
||||
$<$<BOOL:${APPLE}>:assets/GSBug.Templates>
|
||||
$<$<BOOL:${APPLE}>:assets/Tools.text>
|
||||
$<$<BOOL:${APPLE}>:assets/GSOS.text>
|
||||
$<$<BOOL:${APPLE}>:fix_mac_menu.m>
|
||||
)
|
||||
|
||||
@ -152,6 +154,8 @@ SET_SOURCE_FILES_PROPERTIES(
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(
|
||||
assets/GSBug.Templates
|
||||
assets/Tools.text
|
||||
assets/GSOS.text
|
||||
PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
|
120
src/assets/GSOS.text
Normal file
120
src/assets/GSOS.text
Normal file
@ -0,0 +1,120 @@
|
||||
; ProDOS 16 Calls.
|
||||
0001 CREATE
|
||||
0002 DESTROY
|
||||
0004 CHANGE_PATH
|
||||
0005 SET_FILE_INFO
|
||||
0006 GET_FILE_INFO
|
||||
0008 VOLUME
|
||||
0009 SET_PREFIX
|
||||
000A GET_PREFIX
|
||||
000B CLEAR_BACKUP_BIT
|
||||
0010 OPEN
|
||||
0011 NEWLINE
|
||||
0012 READ
|
||||
0013 WRITE
|
||||
0014 CLOSE
|
||||
0015 FLUSH
|
||||
0016 SET_MARK
|
||||
0017 GET_MARK
|
||||
0018 SET_EOF
|
||||
0019 GET_EOF
|
||||
001A SET_LEVEL
|
||||
001B GET_LEVEL
|
||||
001C GET_DIR_ENTRY
|
||||
0020 GET_DEV_NUM
|
||||
0021 GET_LAST_DEV
|
||||
0022 READ_BLOCK
|
||||
0023 WRITE_BLOCK
|
||||
0024 FORMAT
|
||||
0025 ERASE_DISK
|
||||
0027 GET_NAME
|
||||
0028 GET_BOOT_VOL
|
||||
0029 QUIT
|
||||
002A GET_VERSION
|
||||
002C D_INFO
|
||||
0031 ALLOC_INTERRUPT
|
||||
0032 DEALLOCATE_INTERRUPT
|
||||
; ORCA/Shell calls.
|
||||
0101 Get_LInfo
|
||||
0102 Set_LInfo
|
||||
0103 Get_Lang
|
||||
0104 Set_Lang
|
||||
0105 Error
|
||||
0106 Set_Variable
|
||||
0107 Version
|
||||
0108 Read_Indexed
|
||||
0109 Init_Wildcard
|
||||
010A Next_Wildcard
|
||||
010B Read_Variable
|
||||
010C ChangeVector
|
||||
010D Execute
|
||||
010E FastFile
|
||||
010F Direction
|
||||
0110 Redirect
|
||||
0113 Stop
|
||||
0114 ExpandDevices
|
||||
0115 UnsetVariable
|
||||
0116 Export
|
||||
0117 PopVariables
|
||||
0118 PushVariables
|
||||
0119 SetStopFlag
|
||||
011A ConsoleOut
|
||||
011B SetIODevices
|
||||
011C GetIODevices
|
||||
011D GetCommand
|
||||
; GS/OS Calls.
|
||||
2001 Create
|
||||
2002 Destroy
|
||||
2003 OSShutdown
|
||||
2004 ChangePath
|
||||
2005 SetFileInfo
|
||||
2006 GetFileInfo
|
||||
2007 JudgeName
|
||||
2008 Volume
|
||||
2009 SetPrefix
|
||||
200A GetPrefix
|
||||
200B ClearBackup
|
||||
200C SetSysPrefs
|
||||
200D Null
|
||||
200E ExpandPath
|
||||
200F GetSysPrefs
|
||||
2010 Open
|
||||
2011 NewLine
|
||||
2012 Read
|
||||
2013 Write
|
||||
2014 Close
|
||||
2015 Flush
|
||||
2016 SetMark
|
||||
2017 GetMark
|
||||
2018 SetEOF
|
||||
2019 GetEOF
|
||||
201A SetLevel
|
||||
201B GetLevel
|
||||
201C GetDirEntry
|
||||
201D BeginSession
|
||||
201E EndSession
|
||||
201F SessionStatus
|
||||
2020 GetDevNumber
|
||||
2024 Format
|
||||
2025 EraseDisk
|
||||
2026 ResetCache
|
||||
2027 GetName
|
||||
2028 GetBootvol
|
||||
2029 Quit
|
||||
202A GetVersion
|
||||
202B GetFSTInfo
|
||||
202C DInfo
|
||||
202D DStatus
|
||||
202E DControl
|
||||
202F DRead
|
||||
2030 DWrite
|
||||
2031 BindInt
|
||||
2032 UnbindInt
|
||||
2033 FSTSpecific
|
||||
2034 AddNotifyProc
|
||||
2035 DelNotifyProc
|
||||
2036 DRename
|
||||
2037 GetStdRefNum
|
||||
2038 GetRefNum
|
||||
2039 GetRefInfo
|
||||
203A SetStdRefNum
|
1460
src/assets/Tools.text
Normal file
1460
src/assets/Tools.text
Normal file
File diff suppressed because it is too large
Load Diff
@ -44,8 +44,10 @@ static word32 g_prev_stack_bank = 0;
|
||||
|
||||
|
||||
static int g_templates_loaded = 0;
|
||||
extern void debug_load_template(const char *path);
|
||||
extern void debug_load_templates(const char *path);
|
||||
extern word32 debug_apply_template(word32 address, const char *name);
|
||||
extern void debug_load_tools(const char *path, unsigned vector);
|
||||
extern const char *debug_tool_name(unsigned, unsigned vector);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <mach-o/dyld.h>
|
||||
@ -267,42 +269,90 @@ word32 do_stack(word32 address, unsigned bank) {
|
||||
|
||||
}
|
||||
|
||||
word32 do_list(word32 address, int *psr_ptr, int lines) {
|
||||
struct disasm_cookie {
|
||||
unsigned psr;
|
||||
unsigned x;
|
||||
};
|
||||
|
||||
static int is_jsl_e10000(word32 address) {
|
||||
return get_memory_c(address, 0) == 0x22 &&
|
||||
get_memory24_c(address + 1, 0) == 0xe10000;
|
||||
}
|
||||
|
||||
static int is_jsl_e10008(word32 address) {
|
||||
return get_memory_c(address, 0) == 0x22 &&
|
||||
get_memory24_c(address + 1, 0) == 0xe10008;
|
||||
}
|
||||
static int is_jsl_e100a8(word32 address) {
|
||||
return get_memory_c(address, 0) == 0x22 &&
|
||||
get_memory24_c(address + 1, 0) == 0xe100a8;
|
||||
}
|
||||
|
||||
|
||||
static int is_jsl_e100b0(word32 address) {
|
||||
return get_memory_c(address, 0) == 0x22 &&
|
||||
get_memory24_c(address + 1, 0) == 0xe100b0;
|
||||
}
|
||||
|
||||
static int is_jsr_bf00(word32 address) {
|
||||
return get_memory_c(address, 0) == 0x20 &&
|
||||
get_memory16_c(address + 1, 0) == 0xbf00;
|
||||
}
|
||||
|
||||
static int g_disasm_psr;
|
||||
|
||||
word32 do_list(word32 address, int lines) {
|
||||
|
||||
unsigned char buffer2[32];
|
||||
char buffer[32];
|
||||
int psr = *psr_ptr;
|
||||
|
||||
const char *opcode_string;
|
||||
|
||||
unsigned opcode;
|
||||
unsigned dtype;
|
||||
unsigned operand;
|
||||
|
||||
word32 pc;
|
||||
int i;
|
||||
int args;
|
||||
int n;
|
||||
|
||||
while (lines--) {
|
||||
|
||||
int bsize = 0;
|
||||
pc = address;
|
||||
|
||||
opcode = get_memory_c(address++, 0);
|
||||
dtype = disasm_types[opcode];
|
||||
args = dtype >> 8;
|
||||
|
||||
buffer2[bsize++] = opcode;
|
||||
opcode_string = disasm_opcodes[opcode];
|
||||
|
||||
switch (args) {
|
||||
case 4:
|
||||
args = psr & 0x20 ? 1 : 2;
|
||||
args = g_disasm_psr & 0x20 ? 1 : 2;
|
||||
break;
|
||||
case 5:
|
||||
args = psr & 0x10 ? 1 : 2;
|
||||
args = g_disasm_psr & 0x10 ? 1 : 2;
|
||||
break;
|
||||
}
|
||||
operand = 0;
|
||||
switch(args) {
|
||||
case 1:
|
||||
operand = get_memory_c(address, 0);
|
||||
buffer2[bsize++] = operand;
|
||||
break;
|
||||
case 2:
|
||||
operand = get_memory16_c(address, 0);
|
||||
buffer2[bsize++] = operand;
|
||||
buffer2[bsize++] = operand >> 8;
|
||||
break;
|
||||
case 3:
|
||||
operand = get_memory24_c(address, 0);
|
||||
buffer2[bsize++] = operand;
|
||||
buffer2[bsize++] = operand >> 8;
|
||||
buffer2[bsize++] = operand >> 16;
|
||||
break;
|
||||
}
|
||||
address += args;
|
||||
@ -319,91 +369,141 @@ word32 do_list(word32 address, int *psr_ptr, int lines) {
|
||||
sprintf(buffer, "$%04x,y", operand);
|
||||
break;
|
||||
|
||||
case ABSIND:
|
||||
sprintf(buffer,"($%04x)",operand );
|
||||
break;
|
||||
case ABSXIND:
|
||||
sprintf(buffer,"($%04x,x)",operand );
|
||||
break;
|
||||
case IMPLY:
|
||||
break;
|
||||
case ACCUM:
|
||||
break;
|
||||
case IMMED:
|
||||
sprintf(buffer,"#$%0*x",args * 2, operand);
|
||||
break;
|
||||
case JUST8:
|
||||
sprintf(buffer,"$%02x",operand);
|
||||
break;
|
||||
case DLOC:
|
||||
sprintf(buffer,"$%02x",operand);
|
||||
break;
|
||||
case DLOCX:
|
||||
sprintf(buffer,"$%02x,x",operand);
|
||||
break;
|
||||
case DLOCY:
|
||||
sprintf(buffer,"$%02x,y",operand);
|
||||
break;
|
||||
case ABSLONG:
|
||||
sprintf(buffer,"$%06x",operand);
|
||||
break;
|
||||
case ABSLONGX:
|
||||
sprintf(buffer,"$%06x,x",operand);
|
||||
break;
|
||||
case DLOCIND:
|
||||
sprintf(buffer,"($%02x)",operand);
|
||||
break;
|
||||
case DLOCINDY:
|
||||
sprintf(buffer,"($%02x),y",operand);
|
||||
break;
|
||||
case DLOCXIND:
|
||||
sprintf(buffer,"($%02x,x)",operand);
|
||||
break;
|
||||
case DLOCBRAK:
|
||||
sprintf(buffer,"[$%02x]",operand);
|
||||
break;
|
||||
case DLOCBRAKY:
|
||||
sprintf(buffer,"[$%02x],y",operand);
|
||||
break;
|
||||
case DISP8:
|
||||
sprintf(buffer,"$%04x",
|
||||
(address+(int8_t)operand) & 0xffff);
|
||||
break;
|
||||
case DISP8S:
|
||||
sprintf(buffer,"$%02x,s",operand);
|
||||
break;
|
||||
case DISP8SINDY:
|
||||
sprintf(buffer,"($%02x,s),y",operand);
|
||||
break;
|
||||
case DISP16:
|
||||
sprintf(buffer,"$%04x",
|
||||
(address+(int16_t)(operand)) & 0xffff);
|
||||
break;
|
||||
case MVPMVN:
|
||||
sprintf(buffer,"$%02x,$%02x",operand & 0xff,operand >> 8);
|
||||
break;
|
||||
case SEPVAL:
|
||||
psr |= operand;
|
||||
sprintf(buffer,"#$%02x",operand);
|
||||
break;
|
||||
case REPVAL:
|
||||
psr &= ~operand;
|
||||
sprintf(buffer,"#$%02x",operand);
|
||||
break;
|
||||
case ABSIND:
|
||||
sprintf(buffer,"($%04x)",operand );
|
||||
break;
|
||||
case ABSXIND:
|
||||
sprintf(buffer,"($%04x,x)",operand );
|
||||
break;
|
||||
case IMPLY:
|
||||
break;
|
||||
case ACCUM:
|
||||
break;
|
||||
case IMMED:
|
||||
sprintf(buffer,"#$%0*x",args * 2, operand);
|
||||
break;
|
||||
case JUST8:
|
||||
sprintf(buffer,"$%02x",operand);
|
||||
break;
|
||||
case DLOC:
|
||||
sprintf(buffer,"$%02x",operand);
|
||||
break;
|
||||
case DLOCX:
|
||||
sprintf(buffer,"$%02x,x",operand);
|
||||
break;
|
||||
case DLOCY:
|
||||
sprintf(buffer,"$%02x,y",operand);
|
||||
break;
|
||||
case ABSLONG:
|
||||
sprintf(buffer,"$%06x",operand);
|
||||
break;
|
||||
case ABSLONGX:
|
||||
sprintf(buffer,"$%06x,x",operand);
|
||||
break;
|
||||
case DLOCIND:
|
||||
sprintf(buffer,"($%02x)",operand);
|
||||
break;
|
||||
case DLOCINDY:
|
||||
sprintf(buffer,"($%02x),y",operand);
|
||||
break;
|
||||
case DLOCXIND:
|
||||
sprintf(buffer,"($%02x,x)",operand);
|
||||
break;
|
||||
case DLOCBRAK:
|
||||
sprintf(buffer,"[$%02x]",operand);
|
||||
break;
|
||||
case DLOCBRAKY:
|
||||
sprintf(buffer,"[$%02x],y",operand);
|
||||
break;
|
||||
case DISP8:
|
||||
sprintf(buffer,"$%04x",
|
||||
(address+(int8_t)operand) & 0xffff);
|
||||
break;
|
||||
case DISP8S:
|
||||
sprintf(buffer,"$%02x,s",operand);
|
||||
break;
|
||||
case DISP8SINDY:
|
||||
sprintf(buffer,"($%02x,s),y",operand);
|
||||
break;
|
||||
case DISP16:
|
||||
sprintf(buffer,"$%04x",
|
||||
(address+(int16_t)(operand)) & 0xffff);
|
||||
break;
|
||||
case MVPMVN:
|
||||
sprintf(buffer,"$%02x,$%02x",operand & 0xff,operand >> 8);
|
||||
break;
|
||||
case SEPVAL:
|
||||
case REPVAL:
|
||||
sprintf(buffer,"#$%02x",operand);
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%02x/%04x: %s %-10s",
|
||||
pc >> 16, pc & 0xffff,
|
||||
disasm_opcodes[opcode], buffer);
|
||||
/* todo -- special case for ldx #xxxx, jsl $e10000 */
|
||||
/* todo -- special case for GS/OS calls */
|
||||
/* todo -- special case for P8 MLI calls */
|
||||
|
||||
printf("%02x", opcode);
|
||||
for(i = 0 ; i < args; ++i) {
|
||||
printf(" %02x", operand & 0xff);
|
||||
operand >>= 8;
|
||||
switch (opcode) {
|
||||
case 0xe2: /* sep */
|
||||
g_disasm_psr|= operand;
|
||||
break;
|
||||
case 0xc2: /* rep */
|
||||
g_disasm_psr &= ~operand;
|
||||
break;
|
||||
case 0xfb: /* xce */
|
||||
g_disasm_psr |= 0x0130;
|
||||
break;
|
||||
case 0xa2: /* ldx # */
|
||||
if (is_jsl_e10000(address)) {
|
||||
/* tool call ... */
|
||||
const char *name = debug_tool_name(operand, 0xe10000);
|
||||
if (name) {
|
||||
opcode_string = name;
|
||||
buffer[0] = 0;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
buffer2[bsize++] = get_memory_c(address++, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xae: /* ldx ... */
|
||||
case 0xbe:
|
||||
case 0xa6:
|
||||
case 0xb6:
|
||||
case 0xfa: /* plx */
|
||||
case 0xaa: /* tax */
|
||||
case 0xba: /* tsx */
|
||||
case 0xbb: /* tyx */
|
||||
case 0xca: /* dex */
|
||||
case 0xe8: /* inx */
|
||||
break;
|
||||
case 0x22: /* jsl */
|
||||
if (operand == 0xe100a8) {
|
||||
/* inline GS/OS call? */
|
||||
unsigned num = get_memory16_c(address, 0);
|
||||
const char *name = debug_tool_name(num, operand);
|
||||
if (name) {
|
||||
opcode_string = name;
|
||||
unsigned parms = get_memory24_c(address + 2, 0);
|
||||
sprintf(buffer, "$%06x", parms);
|
||||
|
||||
for (i = 0; i < 6; ++i) {
|
||||
buffer2[bsize++] = get_memory_c(address++, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
n = printf("%02x/%04x: %s %s",
|
||||
pc >> 16, pc & 0xffff,
|
||||
opcode_string, buffer);
|
||||
for(; n < 40; ++n) putchar(' ');
|
||||
|
||||
for(i = 0; i < bsize; ++i) {
|
||||
printf(" %02x", buffer2[i]);
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
*psr_ptr = psr;
|
||||
return address;
|
||||
}
|
||||
|
||||
@ -729,24 +829,26 @@ void delete_bp(int type, word32 addr) {
|
||||
static void do_help(void) {
|
||||
|
||||
fputs(
|
||||
" * Print registers\n"
|
||||
" reg=value Assign register (a,x,y,etc)\n"
|
||||
" reset Reset computer\n"
|
||||
" quit exit debugger\n"
|
||||
" s single step\n"
|
||||
" g go\n"
|
||||
" bp List PC breakpoints\n"
|
||||
" mp List memory breakpoints\n"
|
||||
" * Print registers\n"
|
||||
" reg=value Assign register (a,x,y,etc)\n"
|
||||
" reset Reset computer\n"
|
||||
" quit Exit debugger\n"
|
||||
" s Single step\n"
|
||||
" g Go\n"
|
||||
" bp List PC breakpoints\n"
|
||||
" mp List memory breakpoints\n"
|
||||
"\n"
|
||||
" [address];l List\n"
|
||||
" [address];h Hexdump\n"
|
||||
" [address];bp Set PC breakpoint\n"
|
||||
" [address];bp- Remove PC breakpoint\n"
|
||||
" [address];mp Set memory breakpoint\n"
|
||||
" [address];mp- Remove memory breakpoint\n"
|
||||
" [address];l List\n"
|
||||
" [address];h Hexdump\n"
|
||||
" [address];bp Set PC breakpoint\n"
|
||||
" [address];bp- Remove PC breakpoint\n"
|
||||
" [address];mp Set memory breakpoint\n"
|
||||
" [address];mp- Remove memory breakpoint\n"
|
||||
" [address]\\temp name Display template\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"Address = 12/3456, 123456, or 1234\n",
|
||||
"Address = 12/3456, 123456, or 1234\n"
|
||||
"Register = %%a, %%x, %%y, %%pc, etc\n",
|
||||
stdout);
|
||||
}
|
||||
|
||||
@ -757,8 +859,8 @@ static int parse_command(const char *cp) {
|
||||
|
||||
|
||||
/* TODO:
|
||||
pc++ EOL -> skip current instruction
|
||||
! -> mini assembler mode.
|
||||
require 2 successive ^Ds to exit
|
||||
*/
|
||||
|
||||
const char *YYCURSOR = cp;
|
||||
@ -946,8 +1048,7 @@ command:
|
||||
}
|
||||
|
||||
(";l" | "l") eol {
|
||||
int psr = engine.psr;
|
||||
g_prev_address = do_list(addr, &psr, 20);
|
||||
g_prev_address = do_list(addr, 20);
|
||||
return 0;
|
||||
}
|
||||
";h" eol {
|
||||
@ -1027,15 +1128,25 @@ int debug_shell(int code) {
|
||||
int c;
|
||||
char *cp;
|
||||
|
||||
int psr = engine.psr;
|
||||
|
||||
if (!g_templates_loaded) {
|
||||
char *path;
|
||||
g_templates_loaded = 1;
|
||||
|
||||
path = get_resource_path("GSBug.Templates");
|
||||
debug_load_template(path);
|
||||
free(path);
|
||||
if (path) {
|
||||
debug_load_templates(path);
|
||||
free(path);
|
||||
}
|
||||
path = get_resource_path("Tools.text");
|
||||
if (path) {
|
||||
debug_load_tools(path, 0xe10000);
|
||||
free(path);
|
||||
}
|
||||
path = get_resource_path("GSOS.text");
|
||||
if (path) {
|
||||
debug_load_tools(path, 0xe100a8);
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1061,11 +1172,12 @@ int debug_shell(int code) {
|
||||
/* halt_printf */
|
||||
}
|
||||
|
||||
do_list(engine.kpc, &psr, 1);
|
||||
|
||||
g_prev_stack_address = engine.stack;
|
||||
g_prev_stack_bank = engine.kpc & 0xff0000;
|
||||
g_prev_address = engine.kpc;
|
||||
g_disasm_psr = engine.psr;
|
||||
do_list(engine.kpc, 1);
|
||||
|
||||
for(;;) {
|
||||
cp = x_readline("> ");
|
||||
|
@ -16,6 +16,7 @@
|
||||
re2c:yyfill:enable = 0;
|
||||
eol = "\x00";
|
||||
ws = [ \t\r\n];
|
||||
x = [0-9a-fA-F];
|
||||
*/
|
||||
|
||||
|
||||
@ -142,7 +143,7 @@ next:
|
||||
}
|
||||
|
||||
|
||||
void debug_load_template(const char *path) {
|
||||
void debug_load_templates(const char *path) {
|
||||
FILE *f;
|
||||
char buffer[1024];
|
||||
int ok;
|
||||
@ -312,3 +313,160 @@ word32 debug_apply_template(word32 address, const char *name) {
|
||||
fputc('\n', stdout);
|
||||
return address;
|
||||
}
|
||||
|
||||
/* nifty list */
|
||||
/*
|
||||
* format:
|
||||
* fffx ... header comments
|
||||
* xxxx name ; p8 mli calls
|
||||
* *
|
||||
* xxxx name ; p16/gsos calls
|
||||
* *
|
||||
* xxxx name ; tool calls
|
||||
* *
|
||||
* xxxx name ; user tool calls
|
||||
* *
|
||||
* xxxx name ; e1 vectors
|
||||
* *
|
||||
* xxxx name ; e0 vectors
|
||||
* *
|
||||
* xxxx name ; softswitch/f8 rom
|
||||
* *
|
||||
* xxxx name ; 01 vectors
|
||||
* *
|
||||
* xxxx name ; nifty list service calls
|
||||
* *
|
||||
* xxxx name ; resource types
|
||||
* *
|
||||
* xxxx name ; error codes
|
||||
* *
|
||||
* xxxx name ; HC IIgs callbacks
|
||||
* *
|
||||
* xxxx name ; request codes
|
||||
* *
|
||||
*
|
||||
*/
|
||||
|
||||
struct tool {
|
||||
char *name;
|
||||
unsigned number;
|
||||
unsigned vector;
|
||||
};
|
||||
|
||||
struct tool *tools = NULL;
|
||||
int tool_count = 0;
|
||||
int tool_alloc = 0;
|
||||
|
||||
static void add_tool(struct tool *t) {
|
||||
if (tool_count == tool_alloc) {
|
||||
size_t size = (tool_alloc + 1024) * sizeof(struct tool);
|
||||
void *tmp = realloc(tools, size);
|
||||
if (!tmp) return;
|
||||
tools = tmp;
|
||||
tool_alloc += 1024;
|
||||
}
|
||||
tools[tool_count++] = *t;
|
||||
}
|
||||
|
||||
static word32 to_hex(const char *iter, const char *end) {
|
||||
word32 rv = 0;
|
||||
while(iter != end) {
|
||||
char c = *iter++;
|
||||
rv <<= 4;
|
||||
if (isdigit(c)) rv |= c - '0';
|
||||
else rv |= (c | 0x20) - 'a' + 10;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int tool_compare(const void *a, const void *b) {
|
||||
const struct tool *aa = a;
|
||||
const struct tool *bb = b;
|
||||
|
||||
int rv = (int)aa->vector - (int)bb->vector;
|
||||
if (rv == 0)
|
||||
rv = (int)aa->number - (int)bb->number;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
static int tool_search(const void *a, const void *b) {
|
||||
const struct tool *aa = a;
|
||||
const struct tool *bb = b;
|
||||
|
||||
int rv = (int)aa->vector - (int)bb->vector
|
||||
if (rv == 0)
|
||||
rv = (int)aa->number - (int)bb->number;
|
||||
return rv;
|
||||
}
|
||||
*/
|
||||
|
||||
void debug_load_tools(const char *path, unsigned vector) {
|
||||
|
||||
FILE *f;
|
||||
char buffer[1024];
|
||||
unsigned line = 0;
|
||||
const char *YYMARKER = NULL;
|
||||
const char *YYCTXMARKER = NULL;
|
||||
|
||||
|
||||
f = fopen(path, "r");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Unable to load %s: %s\n", path, strerror(errno));
|
||||
return;
|
||||
}
|
||||
for (line = 1;;++line) {
|
||||
const char *start;
|
||||
const char *end;
|
||||
struct tool tool = { 0, 0, vector };
|
||||
|
||||
const char *cp = fgets(buffer, sizeof(buffer), f);
|
||||
if (!cp) break;
|
||||
|
||||
start = cp;
|
||||
/*!re2c
|
||||
[\r\n\x00] { continue; }
|
||||
";" { continue; }
|
||||
* {
|
||||
fprintf(stderr, "%s:%d: Bad line: %s", path, line, buffer);
|
||||
continue;
|
||||
}
|
||||
x{4} / ws { goto ok; }
|
||||
*/
|
||||
ok:
|
||||
end = cp;
|
||||
tool.number = to_hex(start, end);
|
||||
while (isspace(*cp)) ++cp;
|
||||
|
||||
start = cp;
|
||||
for(;;) {
|
||||
/*!re2c
|
||||
"" / (eol | ws) { break; }
|
||||
* { continue; }
|
||||
*/
|
||||
}
|
||||
end = cp;
|
||||
if (end > start) {
|
||||
int l = end - start;
|
||||
|
||||
/* add a leading _ */
|
||||
tool.name = malloc(l + 2);
|
||||
tool.name[0] = '_';
|
||||
strncpy(tool.name + 1, start, l);
|
||||
tool.name[l + 2] = 0;
|
||||
add_tool(&tool);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
qsort(tools, tool_count, sizeof(struct tool), tool_compare);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
const char *debug_tool_name(unsigned number, unsigned vector) {
|
||||
struct tool tmp = { 0, number, vector };
|
||||
struct tool *t = bsearch(&tmp, tools, tool_count, sizeof(struct tool), tool_compare);
|
||||
if (t) return t->name;
|
||||
return NULL;
|
||||
}
|
Loading…
Reference in New Issue
Block a user