From c8efadda955ad0f28336614d93479c2df0207a4b Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 7 Apr 2019 01:14:35 -0400 Subject: [PATCH 01/23] host fst fix reported in c.e.a2 - when dropping into p8, fst_shutdown is called. when returning to gs/os, fst_startup is NOT called. This effective unmounts the host file system, permanently, since it assumed fst_startup would get called again. fst_shutdown code now closes any open files but does not otherwise unmount. --- src/host_fst.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/host_fst.c b/src/host_fst.c index 425a7c1..40043e9 100644 --- a/src/host_fst.c +++ b/src/host_fst.c @@ -407,6 +407,10 @@ static char *get_path2(void) { } +/* + * shutdown is called when switching to p8. + * startup is ONLY called during initial boot. + */ static word32 fst_shutdown(void) { @@ -418,7 +422,7 @@ static word32 fst_shutdown(void) { free_fd(head); head = next; } - host_shutdown(); + //host_shutdown(); return 0; } @@ -426,6 +430,8 @@ static word32 fst_startup(void) { // if restart, close any previous files. fst_shutdown(); + host_shutdown(); + memset(&cookies, 0, sizeof(cookies)); return host_startup(); From 886a1a591af651d6819d481ad54fb62703995f1c Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 8 Apr 2019 23:56:59 -0400 Subject: [PATCH 02/23] move fatal_printf logging to glog.c file with other logging that does the same thing. --- src/glog.c | 49 +++++++++++++++++++++++++++-- src/glog.h | 4 +++ src/protos.h | 4 --- src/scc_socket_driver.c | 2 ++ src/sim65816.c | 70 ----------------------------------------- 5 files changed, 53 insertions(+), 76 deletions(-) diff --git a/src/glog.c b/src/glog.c index 55f7f01..856fca6 100644 --- a/src/glog.c +++ b/src/glog.c @@ -4,12 +4,20 @@ See COPYRIGHT.txt for Copyright information See LICENSE.txt for license (GPL v2) */ -#include -#include #include +#include +#include +#include +#include #include "glog.h" + +#define MAX_FATAL_LOGS 20 + +int g_fatal_log = 0; +char *g_fatal_log_strs[MAX_FATAL_LOGS]; + int glog(const char *s) { time_t timer; char buffer[26]; @@ -45,3 +53,40 @@ int glogf(const char *fmt, ...) { fputc('\n', stdout); return 0; } + + +int fatal_printf(const char *fmt, ...) { + static char buffer[4096]; + va_list ap; + int ret; + + va_start(ap, fmt); + + if(g_fatal_log < 0) { + g_fatal_log = 0; + } + + ret = vsnprintf(buffer, sizeof(buffer), fmt, ap); + + glog(buffer); + + if (g_fatal_log < MAX_FATAL_LOGS) { + g_fatal_log_strs[g_fatal_log++] = strdup(buffer); + } + + + va_end(ap); + return ret; +} + + + +void clear_fatal_logs() { + int i; + + for(i = 0; i < g_fatal_log; i++) { + free(g_fatal_log_strs[i]); + g_fatal_log_strs[i] = 0; + } + g_fatal_log = 0; +} \ No newline at end of file diff --git a/src/glog.h b/src/glog.h index db005c3..479403b 100644 --- a/src/glog.h +++ b/src/glog.h @@ -3,6 +3,10 @@ extern "C" { #endif int glog(const char *s); int glogf(const char *s, ...); + + int fatal_printf(const char *fmt, ...); + void clear_fatal_logs(void); + #ifdef __cplusplus } #endif diff --git a/src/protos.h b/src/protos.h index de2a0c0..e157e65 100644 --- a/src/protos.h +++ b/src/protos.h @@ -403,10 +403,6 @@ void do_wdm(word32 arg); void do_wai(void); void do_stp(void); void size_fail(int val, word32 v1, word32 v2); -int fatal_printf(const char *fmt, ...); -int gsport_vprintf(const char *fmt, va_list ap); -void must_write(int fd, char *bufptr, int len); -void clear_fatal_logs(void); char *gsplus_malloc_str(char *in_str); diff --git a/src/scc_socket_driver.c b/src/scc_socket_driver.c index 4fc3398..0625684 100644 --- a/src/scc_socket_driver.c +++ b/src/scc_socket_driver.c @@ -9,6 +9,8 @@ #include "defc.h" #include "scc.h" +#include "glog.h" + #include #include #include diff --git a/src/sim65816.c b/src/sim65816.c index 13dfe4c..70e18d3 100644 --- a/src/sim65816.c +++ b/src/sim65816.c @@ -209,11 +209,7 @@ int g_engine_doc_int = 0; int g_testing = 0; -#define MAX_FATAL_LOGS 20 -int g_debug_file_fd = -1; -int g_fatal_log = -1; -char *g_fatal_log_strs[MAX_FATAL_LOGS]; word32 stop_run_at; @@ -302,9 +298,6 @@ void sim65816_initglobals() { g_testing = 0; - g_debug_file_fd = -1; - g_fatal_log = -1; - g_25sec_cntr = 0; g_1sec_cntr = 0; @@ -2485,70 +2478,7 @@ void size_fail(int val, word32 v1, word32 v2) { halt_printf("Size failure, val: %08x, %08x %08x\n", val, v1, v2); } -int gsplus_vprintf(const char *fmt, va_list ap) { - char *bufptr, *buf2ptr; - int len; - int ret; - bufptr = (char*)malloc(4096); // OG Added Cast - ret = vsnprintf(bufptr, 4090, fmt, ap); - - // OG Display warning - printf("Warning:%s",bufptr); - - len = strlen(bufptr); - if(g_fatal_log >= 0 && g_fatal_log < MAX_FATAL_LOGS) { - buf2ptr = (char*)malloc(len+1); // OG Added Cast - memcpy(buf2ptr, bufptr, len+1); - g_fatal_log_strs[g_fatal_log++] = buf2ptr; - } - must_write(1, bufptr, len); - if(g_debug_file_fd >= 0) { - must_write(g_debug_file_fd, bufptr, len); - } - free(bufptr); - - return ret; -} - - -int fatal_printf(const char *fmt, ...) { - va_list ap; - int ret; - - va_start(ap, fmt); - - if(g_fatal_log < 0) { - g_fatal_log = 0; - } - ret = gsplus_vprintf(fmt, ap); - va_end(ap); - - return ret; -} - -void must_write(int fd, char *bufptr, int len) { - int ret; - while(len > 0) { - ret = write(fd, bufptr, len); - if(ret >= 0) { - len -= ret; - bufptr += ret; - } else if(errno != EAGAIN && errno != EINTR) { - return; // just get out - } - } -} - -void clear_fatal_logs() { - int i; - - for(i = 0; i < g_fatal_log; i++) { - free(g_fatal_log_strs[i]); - g_fatal_log_strs[i] = 0; - } - g_fatal_log = -1; -} char *gsplus_malloc_str(char *in_str) { char *str; From 9d6c9a4e6eb4f2cae86a06b324bde4869fb6ad74 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 9 Apr 2019 13:00:22 -0400 Subject: [PATCH 03/23] fatal_printf - show an alert immediately. win32 - actually show the alert. --- src/glog.c | 5 ++++- src/win_console.c | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/glog.c b/src/glog.c index 856fca6..4a66fcf 100644 --- a/src/glog.c +++ b/src/glog.c @@ -12,6 +12,7 @@ #include "glog.h" +extern int x_show_alert(int fatal, const char *str); #define MAX_FATAL_LOGS 20 @@ -70,10 +71,12 @@ int fatal_printf(const char *fmt, ...) { glog(buffer); + x_show_alert(1, buffer); + /* if (g_fatal_log < MAX_FATAL_LOGS) { g_fatal_log_strs[g_fatal_log++] = strdup(buffer); } - + */ va_end(ap); return ret; diff --git a/src/win_console.c b/src/win_console.c index e946445..81a417a 100644 --- a/src/win_console.c +++ b/src/win_console.c @@ -60,7 +60,11 @@ void x_dialog_create_gsport_conf(const char *str) { config_write_config_gsplus_file(); } -int x_show_alert(int is_fatal, const char *str) { +int x_show_alert(int is_fatal, const char *str) { + + if (str && *str) { + MessageBox(NULL, str, "GS+", is_fatal ? MB_ICONERROR : MB_ICONWARNING); + } return 0; } From 03fb088594b278301e373b1cbd5a439ce1e6bf1e Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Thu, 11 Apr 2019 19:38:29 -0400 Subject: [PATCH 04/23] eliminate the g_fatal_log array since fatal_printf() shows warning messages immediately. --- src/config.c | 4 --- src/fbdriver.c | 1 - src/glog.c | 26 ---------------- src/glog.h | 1 - src/macdriver_console.c | 68 ++++++++--------------------------------- src/scc_socket_driver.c | 1 - src/sim65816.c | 3 -- src/win_console.c | 5 +-- src/xdriver.c | 1 - 9 files changed, 13 insertions(+), 97 deletions(-) diff --git a/src/config.c b/src/config.c index 177e52f..2a3e07e 100644 --- a/src/config.c +++ b/src/config.c @@ -58,7 +58,6 @@ extern byte *g_rom_fc_ff_ptr; extern byte *g_rom_cards_ptr; extern double g_cur_dcycs; extern int g_rom_version; -extern int g_fatal_log; extern word32 g_adb_repeat_vbl; @@ -3223,9 +3222,6 @@ void config_control_panel() { g_cfg_slotdrive = -1; g_cfg_select_partition = -1; while(g_config_control_panel & !(halt_sim&HALT_WANTTOQUIT)) { - if(g_fatal_log > 0) { - x_show_alert(0, 0); - } cfg_home(); line = 1; cfg_printf("%s\n\n", menuptr[0].str); diff --git a/src/fbdriver.c b/src/fbdriver.c index b32abe1..a269ecf 100644 --- a/src/fbdriver.c +++ b/src/fbdriver.c @@ -421,7 +421,6 @@ void x_dialog_create_gsport_conf(const char *str) { int x_show_alert(int is_fatal, const char *str) { // Not implemented yet adb_all_keys_up(); - clear_fatal_logs(); return 0; } void x_toggle_status_lines(void) { diff --git a/src/glog.c b/src/glog.c index 4a66fcf..07bc368 100644 --- a/src/glog.c +++ b/src/glog.c @@ -14,11 +14,6 @@ extern int x_show_alert(int fatal, const char *str); -#define MAX_FATAL_LOGS 20 - -int g_fatal_log = 0; -char *g_fatal_log_strs[MAX_FATAL_LOGS]; - int glog(const char *s) { time_t timer; char buffer[26]; @@ -63,33 +58,12 @@ int fatal_printf(const char *fmt, ...) { va_start(ap, fmt); - if(g_fatal_log < 0) { - g_fatal_log = 0; - } - ret = vsnprintf(buffer, sizeof(buffer), fmt, ap); glog(buffer); x_show_alert(1, buffer); - /* - if (g_fatal_log < MAX_FATAL_LOGS) { - g_fatal_log_strs[g_fatal_log++] = strdup(buffer); - } - */ va_end(ap); return ret; } - - - -void clear_fatal_logs() { - int i; - - for(i = 0; i < g_fatal_log; i++) { - free(g_fatal_log_strs[i]); - g_fatal_log_strs[i] = 0; - } - g_fatal_log = 0; -} \ No newline at end of file diff --git a/src/glog.h b/src/glog.h index 479403b..4571297 100644 --- a/src/glog.h +++ b/src/glog.h @@ -5,7 +5,6 @@ extern "C" { int glogf(const char *s, ...); int fatal_printf(const char *fmt, ...); - void clear_fatal_logs(void); #ifdef __cplusplus } diff --git a/src/macdriver_console.c b/src/macdriver_console.c index 8e02f43..8b1ca03 100644 --- a/src/macdriver_console.c +++ b/src/macdriver_console.c @@ -79,19 +79,15 @@ extern int g_screen_mdepth; Ptr g_mac_fullscreen_state = 0; Rect g_main_window_saved_rect; -extern char *g_fatal_log_strs[]; -extern int g_fatal_log; - int x_show_alert(int is_fatal, const char *str) { DialogRef alert; DialogItemIndex out_item_hit; - CFStringRef cfstrref, cfstrref2; + CFStringRef cfstrref; CFStringRef okstrref; AlertStdCFStringAlertParamRec alert_param; OSStatus osstat; - char *bufptr, *buf2ptr; - int sum, len; - int i; + + if (!str || !*str) return 0; /* The dialog eats all events--including key-up events */ /* Call adb_all_keys_up() to prevent annoying key-repeat problems */ @@ -100,36 +96,14 @@ int x_show_alert(int is_fatal, const char *str) { /* auto-repeat will repeat the key, and the dialog re-appears...*/ adb_all_keys_up(); - sum = 20; - for(i = 0; i < g_fatal_log; i++) { - sum += strlen(g_fatal_log_strs[i]); - } - bufptr = (char*)malloc(sum); - buf2ptr = bufptr; - for(i = 0; i < g_fatal_log; i++) { - len = strlen(g_fatal_log_strs[i]); - len = MIN(len, sum); - len = MAX(len, 0); - memcpy(bufptr, g_fatal_log_strs[i], MIN(len, sum)); - bufptr += len; - bufptr[0] = 0; - sum = sum - len; - } - cfstrref = CFStringCreateWithCString(NULL, buf2ptr, + cfstrref = CFStringCreateWithCString(NULL, str, kCFStringEncodingMacRoman); - printf("buf2ptr: :%s:\n", buf2ptr); osstat = GetStandardAlertDefaultParams(&alert_param, kStdCFStringAlertVersionOne); - if(str) { - // Provide an extra option--create a file - cfstrref2 = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("Create ./%s"), str); - alert_param.otherText = cfstrref2; - } okstrref = CFSTR("Click OK to continue"); if(is_fatal) { okstrref = CFSTR("Click OK to exit GSplus"); @@ -138,12 +112,9 @@ int x_show_alert(int is_fatal, const char *str) { &alert_param, &alert); out_item_hit = -1; RunStandardAlert(alert, NULL, &out_item_hit); - printf("out_item_hit: %d\n", out_item_hit); - free(buf2ptr); - clear_fatal_logs(); /* free the fatal_log string memory */ + CFRelease(cfstrref); return (out_item_hit >= 3); - } @@ -159,28 +130,18 @@ pascal OSStatus quit_event_handler(EventHandlerCallRef call_ref, EventRef event, } void show_simple_alert(char *str1, char *str2, char *str3, int num) { - char buf[256]; + char buf[4096]; - g_fatal_log_strs[0] = gsplus_malloc_str(str1); - g_fatal_log_strs[1] = gsplus_malloc_str(str2); - g_fatal_log_strs[2] = gsplus_malloc_str(str3); - g_fatal_log = 3; - if(num != 0) { - snprintf(buf, 250, ": %d", num); - g_fatal_log_strs[g_fatal_log++] = gsplus_malloc_str(buf); + if (num) { + snprintf(buffer, sizeof(buffer), "%s%s%s: %d", str1, str2, str3, num); + } else { + snprintf(buffer, sizeof(buffer), "%s%s%s", str1, str2, str3); } - x_show_alert(0, 0); + x_show_alert(0, buf); } void x_dialog_create_gsport_conf(const char *str) { - char *path; - char tmp_buf[512]; - int ret; - - ret = x_show_alert(1, str); - if(ret) { - config_write_config_gsplus_file(); - } + config_write_config_gsplus_file(); } @@ -698,11 +659,6 @@ CantGetNibRef: void xdriver_end() { - printf("xdriver_end\n"); - - if(g_fatal_log >= 0) { - x_show_alert(1, 0); - } } diff --git a/src/scc_socket_driver.c b/src/scc_socket_driver.c index 0625684..db92142 100644 --- a/src/scc_socket_driver.c +++ b/src/scc_socket_driver.c @@ -224,7 +224,6 @@ void scc_socket_open_outgoing(int port, double dcycs) { #endif scc_socket_close_handle(sockfd); scc_socket_close(port, 1, dcycs); - x_show_alert(0, 0); return; } memcpy(&sa_in.sin_addr.s_addr, hostentptr->h_addr, diff --git a/src/sim65816.c b/src/sim65816.c index 70e18d3..16f0ed9 100644 --- a/src/sim65816.c +++ b/src/sim65816.c @@ -904,7 +904,6 @@ int gsplusmain(int argc, char **argv) { iwm_shut(); fixed_memory_ptrs_shut(); load_roms_shut_memory(); - clear_fatal_logs(); #if HAVE_RAWNET if (g_ethernet_enabled) { @@ -1084,8 +1083,6 @@ void setup_gsplus_file(char *outname, int maxlen, int ok_if_missing, int can_cre x_dialog_create_gsport_conf(*name_ptr); can_create_file = 0; - // But clear out the fatal_printfs first - clear_fatal_logs(); setup_gsplus_file(outname, maxlen, ok_if_missing, can_create_file, name_ptr); // It's one-level of recursion--it cannot loop since we // clear can_create_file. diff --git a/src/win_console.c b/src/win_console.c index 81a417a..f6004dc 100644 --- a/src/win_console.c +++ b/src/win_console.c @@ -63,6 +63,7 @@ void x_dialog_create_gsport_conf(const char *str) { int x_show_alert(int is_fatal, const char *str) { if (str && *str) { + adb_all_keys_up(); MessageBox(NULL, str, "GS+", is_fatal ? MB_ICONERROR : MB_ICONWARNING); } return 0; @@ -337,10 +338,6 @@ int main(int argc, char **argv) { size.cx, size.cy, NULL, NULL, GetModuleHandle(NULL), NULL); - printf("g_hwnd_main = %p, height = %d\n", hwnd, size.cx); - GetWindowRect(hwnd, &rect); - printf("...rect is: %ld, %ld, %ld, %ld\n", rect.left, rect.top, - rect.right, rect.bottom); #if 0 // Enable non-blocking, character-at-a-time console I/O. diff --git a/src/xdriver.c b/src/xdriver.c index de03155..0590315 100644 --- a/src/xdriver.c +++ b/src/xdriver.c @@ -254,7 +254,6 @@ int x_show_alert(int is_fatal, const char *str) { /* Not implemented yet */ adb_all_keys_up(); - clear_fatal_logs(); return 0; } From ac1b76753df6495c1dac99dbd32d32af25fb6525 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Apr 2019 17:41:46 -0400 Subject: [PATCH 05/23] mini assembler --- src/CMakeLists.txt | 8 + src/debug_miniasm.re2c | 730 +++++++++++++++++++++++++++++++++++++++++ src/debug_shell.re2c | 9 +- src/mnemonics.x | 92 ++++++ 4 files changed, 837 insertions(+), 2 deletions(-) create mode 100644 src/debug_miniasm.re2c create mode 100644 src/mnemonics.x diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3094893..6ae49e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,6 +119,13 @@ add_custom_command( MAIN_DEPENDENCY debug_sweet16.re2c ) +add_custom_command( + OUTPUT debug_miniasm.c + COMMAND re2c -W -o ${CMAKE_CURRENT_BINARY_DIR}/debug_miniasm.c "${CMAKE_CURRENT_SOURCE_DIR}/debug_miniasm.re2c" + MAIN_DEPENDENCY debug_miniasm.re2c +) + + if (WITH_STATIC) if(__CLANG__ OR __GCC__) #add_link_options(-static) # 3.13 @@ -175,6 +182,7 @@ add_executable(GSplus WIN32 MACOSX_BUNDLE debug_shell.c debug_template.c debug_sweet16.c + debug_miniasm.c $<$:debug.c> $<$:${host_fst_code}> diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c new file mode 100644 index 0000000..bab33b1 --- /dev/null +++ b/src/debug_miniasm.re2c @@ -0,0 +1,730 @@ + +#include +#include +#include +#include + + +#include "defc.h" + +extern int g_disasm_psr; + + +static uint32_t to_hex(const char *iter, const char *end) { + uint32_t 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 const char *ltrim(const char *cp) { + while (isspace(*cp)) ++cp; + return cp; +} + +/*!re2c + re2c:define:YYCTYPE = char; + re2c:yyfill:enable = 0; + eol = "\x00"; + ws = [ \t]; + x = [A-Fa-f0-9]; +*/ + + +/* address modes */ +/* INDIR_LONG_X present for +1/+2 symmetry */ +#define _x 1 +#define _y 2 +enum { + IMPLIED, + DP, DP_X, DP_Y, + ABS, ABS_X, ABS_Y, + ABS_LONG, ABS_LONG_X, ABS_LONG_Y, + INDIR, INDIR_X, INDIR_Y, + INDIR_LONG, INDIR_LONG_X, INDIR_LONG_Y, + SR, SR_Y, + IMMEDIATE, + RELATIVE, + INTERRUPT, + BLOCK, +}; + + +enum { + MNEMONIC_NONE, + #define x(a) a, + #include "mnemonics.x" + #undef x + MNEMONIC_LAST +}; + + +struct mnemonic_entry { + const char *name; + int value; + unsigned mnemonic; +}; +struct mnemonic_entry mnemonic_table[] = { + { NULL, 0 }, + #define x(a) { #a, (#a[0] << 16)| (#a[1] << 8) | (#a[2]), a }, + #include "mnemonics.x" + #undef x +}; + + + +struct cookie { + unsigned mnemonic; + unsigned mode; + unsigned size; + unsigned opcode; + unsigned operand; + unsigned pc; +}; + + + +struct opcode_entry { + unsigned mnemonic; + unsigned mode; + unsigned opcode; + unsigned size; /* of operand */ +}; + +/* 4 = 1/2 depending on M. 5 = 1/2 depending on X */ +struct opcode_entry opcode_table[] = { + + { ADC, INDIR_X , 0x61, 1 }, + { ADC, SR , 0x63, 1 }, + { ADC, DP , 0x65, 1 }, + { ADC, INDIR_LONG , 0x67, 1 }, + { ADC, IMMEDIATE , 0x69, 4 }, + { ADC, ABS , 0x6d, 2 }, + { ADC, ABS_LONG , 0x6f, 3 }, + { ADC, INDIR_Y , 0x71, 1 }, + { ADC, INDIR , 0x72, 1 }, + { ADC, SR_Y , 0x73, 1 }, + { ADC, DP_X , 0x75, 1 }, + { ADC, INDIR_LONG_Y, 0x77, 1 }, + { ADC, ABS_Y , 0x79, 2 }, + { ADC, ABS_X , 0x7d, 2 }, + { ADC, ABS_LONG_X , 0x7f, 3 }, + { AND, INDIR_X , 0x21, 1 }, + { AND, SR , 0x23, 1 }, + { AND, DP , 0x25, 1 }, + { AND, INDIR_LONG , 0x27, 1 }, + { AND, IMMEDIATE , 0x29, 4 }, + { AND, ABS , 0x2d, 2 }, + { AND, ABS_LONG , 0x2f, 3 }, + { AND, INDIR_Y , 0x31, 1 }, + { AND, INDIR , 0x32, 1 }, + { AND, SR_Y , 0x33, 1 }, + { AND, DP_X , 0x35, 1 }, + { AND, INDIR_LONG_Y, 0x37, 1 }, + { AND, ABS_Y , 0x39, 2 }, + { AND, ABS_X , 0x3d, 2 }, + { AND, ABS_LONG_X , 0x3f, 3 }, + { ASL, DP , 0x06, 1 }, + { ASL, IMPLIED , 0x0a, 0 }, + { ASL, ABS , 0x0e, 2 }, + { ASL, DP_X , 0x16, 1 }, + { ASL, ABS_X , 0x1e, 2 }, + { BCC, RELATIVE , 0x90, 1 }, + { BCS, RELATIVE , 0xb0, 1 }, + { BEQ, RELATIVE , 0xf0, 1 }, + { BIT, DP , 0x24, 1 }, + { BIT, ABS , 0x2c, 2 }, + { BIT, DP_X , 0x34, 1 }, + { BIT, ABS_X , 0x3c, 2 }, + { BIT, IMMEDIATE , 0x89, 4 }, + { BMI, RELATIVE , 0x30, 1 }, + { BNE, RELATIVE , 0xd0, 1 }, + { BPL, RELATIVE , 0x10, 1 }, + { BRA, RELATIVE , 0x80, 1 }, + /* brk dp, #imm */ + { BRK, INTERRUPT , 0x00, 1 }, { BRK, DP , 0x00, 1 }, { BRK, IMMEDIATE , 0x00, 1 }, + { BRL, RELATIVE , 0x82, 2 }, + { BVC, RELATIVE , 0x50, 1 }, + { BVS, RELATIVE , 0x70, 1 }, + { CLC, IMPLIED , 0x18, 0 }, + { CLD, IMPLIED , 0xd8, 0 }, + { CLI, IMPLIED , 0x58, 0 }, + { CLV, IMPLIED , 0xb8, 0 }, + { CMP, INDIR_X , 0xc1, 1 }, + { CMP, SR , 0xc3, 1 }, + { CMP, DP , 0xc5, 1 }, + { CMP, INDIR_LONG , 0xc7, 1 }, + { CMP, IMMEDIATE , 0xc9, 4 }, + { CMP, ABS , 0xcd, 2 }, + { CMP, ABS_LONG , 0xcf, 3 }, + { CMP, INDIR_Y , 0xd1, 1 }, + { CMP, INDIR , 0xd2, 1 }, + { CMP, SR_Y , 0xd3, 1 }, + { CMP, DP_X , 0xd5, 1 }, + { CMP, INDIR_LONG_Y, 0xd7, 1 }, + { CMP, ABS_Y , 0xd9, 2 }, + { CMP, ABS_X , 0xdd, 2 }, + { CMP, ABS_LONG_X , 0xdf, 3 }, + /* COP dp, #imm */ + { COP, INTERRUPT , 0x02, 1 }, { COP, DP , 0x02, 1 }, { COP, IMMEDIATE , 0x02, 1 }, + { CPX, IMMEDIATE , 0xe0, 5 }, + { CPX, DP , 0xe4, 1 }, + { CPX, ABS , 0xec, 2 }, + { CPY, IMMEDIATE , 0xc0, 5 }, + { CPY, DP , 0xc4, 1 }, + { CPY, ABS , 0xcc, 2 }, + { DEC, IMPLIED , 0x3a, 0 }, + { DEC, DP , 0xc6, 1 }, + { DEC, ABS , 0xce, 2 }, + { DEC, DP_X , 0xd6, 1 }, + { DEC, ABS_X , 0xde, 2 }, + { DEX, IMPLIED , 0xca, 0 }, + { DEY, IMPLIED , 0x88, 0 }, + { EOR, INDIR_X , 0x41, 1 }, + { EOR, SR , 0x43, 1 }, + { EOR, DP , 0x45, 1 }, + { EOR, INDIR_LONG , 0x47, 1 }, + { EOR, IMMEDIATE , 0x49, 4 }, + { EOR, ABS , 0x4d, 2 }, + { EOR, ABS_LONG , 0x4f, 3 }, + { EOR, INDIR_Y , 0x51, 1 }, + { EOR, INDIR , 0x52, 1 }, + { EOR, SR_Y , 0x53, 1 }, + { EOR, DP_X , 0x55, 1 }, + { EOR, INDIR_LONG_Y, 0x57, 1 }, + { EOR, ABS_Y , 0x59, 2 }, + { EOR, ABS_X , 0x5d, 2 }, + { EOR, ABS_LONG_X , 0x5f, 3 }, + { INC, IMPLIED , 0x1a, 0 }, + { INC, DP , 0xe6, 1 }, + { INC, ABS , 0xee, 2 }, + { INC, DP_X , 0xf6, 1 }, + { INC, ABS_X , 0xfe, 2 }, + { INX, IMPLIED , 0xe8, 0 }, + { INY, IMPLIED , 0xc8, 0 }, + { JML, ABS_LONG , 0x5c, 3 }, + { JML, INDIR_LONG , 0xdc, 2 }, + { JMP, ABS , 0x4c, 2 }, + { JMP, INDIR , 0x6c, 2 }, + { JMP, INDIR_X , 0x7c, 2 }, + { JSL, ABS_LONG , 0x22, 3 }, + { JSR, ABS , 0x20, 2 }, + { JSR, INDIR_X , 0xfc, 2 }, + { LDA, INDIR_X , 0xa1, 1 }, + { LDA, SR , 0xa3, 1 }, + { LDA, DP , 0xa5, 1 }, + { LDA, INDIR_LONG , 0xa7, 1 }, + { LDA, IMMEDIATE , 0xa9, 4 }, + { LDA, ABS , 0xad, 2 }, + { LDA, ABS_LONG , 0xaf, 3 }, + { LDA, INDIR_Y , 0xb1, 1 }, + { LDA, INDIR , 0xb2, 1 }, + { LDA, SR_Y , 0xb3, 1 }, + { LDA, DP_X , 0xb5, 1 }, + { LDA, INDIR_LONG_Y, 0xb7, 1 }, + { LDA, ABS_Y , 0xb9, 2 }, + { LDA, ABS_X , 0xbd, 2 }, + { LDA, ABS_LONG_X , 0xbf, 3 }, + { LDX, IMMEDIATE , 0xa2, 5 }, + { LDX, DP , 0xa6, 1 }, + { LDX, ABS , 0xae, 2 }, + { LDX, DP_Y , 0xb6, 1 }, + { LDX, ABS_Y , 0xbe, 2 }, + { LDY, IMMEDIATE , 0xa0, 5 }, + { LDY, DP , 0xa4, 1 }, + { LDY, ABS , 0xac, 2 }, + { LDY, DP_X , 0xb4, 1 }, + { LDY, ABS_X , 0xbc, 2 }, + { LSR, DP , 0x46, 1 }, + { LSR, IMPLIED , 0x4a, 0 }, + { LSR, ABS , 0x4e, 2 }, + { LSR, DP_X , 0x56, 1 }, + { LSR, ABS_X , 0x5e, 2 }, + { MVN, BLOCK , 0x54, 2 }, + { MVP, BLOCK , 0x44, 2 }, + { NOP, IMPLIED , 0xea, 0 }, + { ORA, INDIR_X , 0x01, 1 }, + { ORA, SR , 0x03, 1 }, + { ORA, DP , 0x05, 1 }, + { ORA, INDIR_LONG , 0x07, 1 }, + { ORA, IMMEDIATE , 0x09, 4 }, + { ORA, ABS , 0x0d, 2 }, + { ORA, ABS_LONG , 0x0f, 3 }, + { ORA, INDIR_Y , 0x11, 1 }, + { ORA, INDIR , 0x12, 1 }, + { ORA, SR_Y , 0x13, 1 }, + { ORA, DP_X , 0x15, 1 }, + { ORA, INDIR_LONG_Y, 0x17, 1 }, + { ORA, ABS_Y , 0x19, 2 }, + { ORA, ABS_X , 0x1d, 2 }, + { ORA, ABS_LONG_X , 0x1f, 3 }, + /* pea abs or pea #imm */ + { PEA, ABS , 0xf4, 2 }, { PEA, IMMEDIATE , 0xf4, 2 }, + /* pei (dp) or pei dp */ + { PEI, INDIR , 0xd4, 1 }, { PEI, DP , 0xd4, 1 }, + { PER, RELATIVE , 0x62, 2 }, + { PHA, IMPLIED , 0x48, 0 }, + { PHB, IMPLIED , 0x8b, 0 }, + { PHD, IMPLIED , 0x0b, 0 }, + { PHK, IMPLIED , 0x4b, 0 }, + { PHP, IMPLIED , 0x08, 0 }, + { PHX, IMPLIED , 0xda, 0 }, + { PHY, IMPLIED , 0x5a, 0 }, + { PLA, IMPLIED , 0x68, 0 }, + { PLB, IMPLIED , 0xab, 0 }, + { PLD, IMPLIED , 0x2b, 0 }, + { PLP, IMPLIED , 0x28, 0 }, + { PLX, IMPLIED , 0xfa, 0 }, + { PLY, IMPLIED , 0x7a, 0 }, + { REP, IMMEDIATE , 0xc2, 1 }, + { ROL, DP , 0x26, 1 }, + { ROL, IMPLIED , 0x2a, 0 }, + { ROL, ABS , 0x2e, 2 }, + { ROL, DP_X , 0x36, 1 }, + { ROL, ABS_X , 0x3e, 2 }, + { ROR, DP , 0x66, 1 }, + { ROR, IMPLIED , 0x6a, 0 }, + { ROR, ABS , 0x6e, 2 }, + { ROR, DP_X , 0x76, 1 }, + { ROR, ABS_X , 0x7e, 2 }, + { RTI, IMPLIED , 0x40, 0 }, + { RTL, IMPLIED , 0x6b, 0 }, + { RTS, IMPLIED , 0x60, 0 }, + { SBC, INDIR_X , 0xe1, 1 }, + { SBC, SR , 0xe3, 1 }, + { SBC, DP , 0xe5, 1 }, + { SBC, INDIR_LONG , 0xe7, 1 }, + { SBC, IMMEDIATE , 0xe9, 4 }, + { SBC, ABS , 0xed, 2 }, + { SBC, ABS_LONG , 0xef, 3 }, + { SBC, INDIR_Y , 0xf1, 1 }, + { SBC, INDIR , 0xf2, 1 }, + { SBC, SR_Y , 0xf3, 1 }, + { SBC, DP_X , 0xf5, 1 }, + { SBC, INDIR_LONG_Y, 0xf7, 1 }, + { SBC, ABS_Y , 0xf9, 2 }, + { SBC, ABS_X , 0xfd, 2 }, + { SBC, ABS_LONG_X , 0xff, 3 }, + { SEC, IMPLIED , 0x38, 0 }, + { SED, IMPLIED , 0xf8, 0 }, + { SEI, IMPLIED , 0x78, 0 }, + { SEP, IMMEDIATE , 0xe2, 1 }, + { STA, INDIR_X , 0x81, 1 }, + { STA, SR , 0x83, 1 }, + { STA, DP , 0x85, 1 }, + { STA, INDIR_LONG , 0x87, 1 }, + { STA, ABS , 0x8d, 2 }, + { STA, ABS_LONG , 0x8f, 3 }, + { STA, INDIR_Y , 0x91, 1 }, + { STA, INDIR , 0x92, 1 }, + { STA, SR_Y , 0x93, 1 }, + { STA, DP_X , 0x95, 1 }, + { STA, INDIR_LONG_Y, 0x97, 1 }, + { STA, ABS_Y , 0x99, 2 }, + { STA, ABS_X , 0x9d, 2 }, + { STA, ABS_LONG_X , 0x9f, 3 }, + { STP, IMPLIED , 0xdb, 0 }, + { STX, DP , 0x86, 1 }, + { STX, ABS , 0x8e, 2 }, + { STX, DP_Y , 0x96, 1 }, + { STY, DP , 0x84, 1 }, + { STY, ABS , 0x8c, 2 }, + { STY, DP_X , 0x94, 1 }, + { STZ, DP , 0x64, 1 }, + { STZ, DP_X , 0x74, 1 }, + { STZ, ABS , 0x9c, 2 }, + { STZ, ABS_X , 0x9e, 2 }, + { TAX, IMPLIED , 0xaa, 0 }, + { TAY, IMPLIED , 0xa8, 0 }, + { TCD, IMPLIED , 0x5b, 0 }, + { TCS, IMPLIED , 0x1b, 0 }, + { TDC, IMPLIED , 0x7b, 0 }, + { TRB, DP , 0x14, 1 }, + { TRB, ABS , 0x1c, 2 }, + { TSB, DP , 0x04, 1 }, + { TSB, ABS , 0x0c, 2 }, + { TSC, IMPLIED , 0x3b, 0 }, + { TSX, IMPLIED , 0xba, 0 }, + { TXA, IMPLIED , 0x8a, 0 }, + { TXS, IMPLIED , 0x9a, 0 }, + { TXY, IMPLIED , 0x9b, 0 }, + { TYA, IMPLIED , 0x98, 0 }, + { TYX, IMPLIED , 0xbb, 0 }, + { WAI, IMPLIED , 0xcb, 0 }, + { WDM, INTERRUPT , 0x42, 1 }, + { XBA, IMPLIED , 0xeb, 0 }, + { XCE, IMPLIED , 0xfb, 0 }, + +}; + + +/* generate an index of mnemonics to opcodes in the opcode_table */ +struct opcode_entry *opcode_table_index[MNEMONIC_LAST] = { 0 }; +static void init_table_index(void) { + unsigned i; + unsigned prev = 0; + + opcode_table_index[0] = &opcode_table[0]; + for (i = 1; i < sizeof(opcode_table) / sizeof(opcode_table[0]); ++i) { + if (opcode_table[i].mnemonic != prev) { + prev = opcode_table[i].mnemonic; + opcode_table_index[prev] = &opcode_table[i]; + } + } + opcode_table_index[++prev] = &opcode_table[i]; +} + + +static int find_opcode(struct cookie *cookie) { + + + unsigned mode = cookie->mode; + + const struct opcode_entry *iter = opcode_table_index[cookie->mnemonic]; + const struct opcode_entry *end = opcode_table_index[cookie->mnemonic + 1]; + + /* special case for relative */ + if (iter->mode == RELATIVE) { + + if (mode == DP || mode == ABS) { + cookie->mode = RELATIVE; + cookie->size = iter->size; + return cookie->opcode = iter->opcode; + } + return -1; + } + + for ( ; iter != end; ++iter) { + if (mode == iter->mode) break; + } + if (iter == end) return -1; + + cookie->size = iter->size; + if (iter->size == 4) { + cookie->size = g_disasm_psr & 0x20 ? 1 : 2; + } + if (iter->size == 5) { + cookie->size = g_disasm_psr & 0x10 ? 1 : 2; + } + + return cookie->opcode = iter->opcode; +} + + + + +static const char *parse_expr(const char *cp, struct cookie *cookie) { + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + if (!cp) return NULL; + + cookie->size = 0; + switch(*cp) { + case '|': ++cp; cookie->size = 2; break; + case '>': ++cp; cookie->size = 3; break; + case '<': ++cp; cookie->size = 1; break; + } + + /*!re2c + * { return NULL; } + '*' { + cookie->operand = cookie->pc; + if (!cookie->size) cookie->size = 2; + return YYCURSOR; + } + '*' [+-] x{1,4} { + int tmp = to_hex(cp + 2, YYCURSOR); + if (cp[1] == '-') tmp = -tmp; + cookie->operand = cookie->pc + tmp; + if (!cookie->size) cookie->size = 2; + return YYCURSOR; + } + + x{1,6} { + cookie->operand = to_hex(cp, YYCURSOR); + if (!cookie->size) cookie->size = ((YYCURSOR - cp + 1) & ~1)>>1; + return YYCURSOR; + } + + */ + +} + +static const char *parse_tail(const char *cp, struct cookie *cookie) { + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + if (!cp) return cp; + /*!re2c + "" { return cp; } + ',s' { cookie->mode = SR; return YYCURSOR; } + ',x' { cookie->mode += _x; return YYCURSOR; } + ',y' { cookie->mode += _y; return YYCURSOR; } + */ +} +static const char *parse_paren_tail(const char *cp, struct cookie *cookie) { + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + if (!cp) return cp; + /*!re2c + * { return NULL; } + ")" { return cp; } + "),y" { cookie->mode += _y; return YYCURSOR; } + ",x)" { cookie->mode += _x; return YYCURSOR; } + ",s),y" { cookie->mode = SR_Y; return YYCURSOR; } + */ + +} + +static const char *parse_bracket_tail(const char *cp, struct cookie *cookie) { + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + if (!cp) return cp; + /*!re2c + * { return NULL; } + "]" { return YYCURSOR; } + "],y" { cookie->mode += _y; return YYCURSOR; } + */ +} + +static int mnemonic_cmp(const void *a, const void *b) { + int key = (unsigned)(uintptr_t)a; + const struct mnemonic_entry *e = b; + return key - e->value; +} + + +static const char *parse_opcode(const char *cp, struct cookie *cookie) { + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + /* todo -- long m|x, short m|x, _toolcall */ + /*!re2c + * { return NULL; } + + [A-Za-z]{3} / (ws|eol) { + + uint32_t tmp = 0; + struct mnemonic_entry *e; + unsigned i; + + for (i = 0; i < 3; ++i) { tmp <<= 8; tmp |= (cp[i] & ~0x20); } + e = bsearch((void *)(uintptr_t)tmp, mnemonic_table, + sizeof(mnemonic_table) / sizeof(mnemonic_table[0]), + sizeof(mnemonic_table[0]), mnemonic_cmp); + if (!e) return NULL; + cookie->mnemonic = e->mnemonic; + cookie->mode = IMPLIED; + cookie->operand = 0; + cookie->size = 0; + return ltrim(YYCURSOR); + } + */ + +} + + + +static const char *parse_operand(const char *cp, struct cookie *cookie) { + + if (!cp) return NULL; + + + /* special case for MVN/MVP */ + if (cookie->mnemonic == MVN || cookie->mnemonic == MVP) { + + unsigned tmp; + cp = parse_expr(cp, cookie); + if (!cp) return NULL; + if (*cp++ != ',') return NULL; + tmp = cookie->operand & 0xff; + + cp = parse_expr(cp, cookie); + if (*cp && !isspace(*cp)) return NULL; + + cookie->mode = BLOCK; + cookie->operand &= 0xff; + cookie->operand |= tmp << 8; + cookie->size = 2; + return ltrim(cp); + } + /* special case for mli/gsos calls [?] */ + switch (*cp) { + + case '#': + cookie->mode = IMMEDIATE; + cp = parse_expr(cp + 1, cookie); + break; + case '(': + cookie->mode = INDIR; + cp = parse_expr(cp+1, cookie); + cp = parse_paren_tail(cp, cookie); + break; + case '[': + cookie->mode = INDIR_LONG; + cp = parse_expr(cp + 1, cookie); + cp = parse_bracket_tail(cp, cookie); + break; + default: + cookie->mode = ABS; + cp = parse_expr(cp, cookie); + switch(cookie->size) { + case 1: cookie->mode = DP; break; + case 3: cookie->mode = ABS_LONG; break; + } + cp = parse_tail(cp, cookie); + break; + } + + if (*cp && !isspace(*cp)) return NULL; + return ltrim(cp); +} + +extern uint32_t do_list(uint32_t address, int lines); +extern char *x_readline(const char *prompt); + +static int error(int offset, const char *msg) { + while (offset > 0) { fputc(' ', stderr); --offset; } + fputs(" ^", stderr); + fputs(msg, stderr); + fputc('\n', stderr); + return -1; +} + + +static const char *parse_pc(const char *cp, uint32_t *pc) { + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + if (isspace(*cp)) return ltrim(cp); + + /*!re2c + * { return NULL; } + x{4} ':' { + *pc &= 0xff0000; + *pc |= to_hex(cp, YYCURSOR - 1); + goto next; + } + x{6} ':' { + *pc = to_hex(cp, YYCURSOR - 1); + goto next; + } + + x{2} '/' x{4} ':' { + uint32_t tmp = to_hex(cp, cp + 2) << 16; + tmp |= to_hex(cp + 3, YYCURSOR - 1); + *pc = tmp; + goto next; + } + + */ + +next: + return ltrim(YYCURSOR); +} + + +static int parse_line(const char *cp, uint32_t *pc) { + + struct cookie cookie = { 0 }; + unsigned offset = 0; + uint32_t addr = *pc; + const char *start = cp; + unsigned i; + + + + cp = parse_pc(cp, &addr); + if (!cp) return error(0, "error"); + offset = cp - start; + + /* label only? */ + if (!*cp) { + *pc = addr; + return 0; + } + + /* address ... */ + cookie.pc = *pc; + + + cp = parse_opcode(cp, &cookie); + if (!cp) return error(offset, "bad opcode"); + offset = cp - start; + + + if (*cp) { + parse_operand(cp, &cookie); + if (!cp) return error(offset, "bad operand"); + //offset = cp - start; + } + + if (*cp) return error(offset, "bad operand"); + + if (find_opcode(&cookie) < 0) return error(offset, "invalid address mode"); + + /* clean up relative */ + if (cookie.mode == RELATIVE) { + int pc = (cookie.pc + 1 + cookie.size) & 0xffff; + int tmp = (int16_t)(cookie.operand & 0xffff); + int offset = tmp - pc; + if (cookie.size == 1) { + if (tmp < -128 || tmp > 127) return error(offset, "out of range"); + tmp &= 0xff; + } + else tmp &= 0xffff; + cookie.operand = tmp; + } + + + set_memory_c(addr, cookie.opcode, 0); + unsigned operand = cookie.operand; + for (i = 0; i < cookie.size; ++i) { + set_memory_c(addr, operand & 0xff, 0); + operand >>= 8; + } + + + fputs("\r\x1b[A\x1b[K", stdout); + do_list(addr, 1); + *pc = addr + 1 + cookie.size; + return 1; +} + + + + +uint32_t mini_asm_shell(uint32_t addr) { + static int init = 0; + if (!init) { + init_table_index(); + init = 1; + } + + for(;;) { + const char *cp = x_readline("!"); + if (!cp || !*cp) return addr; + + parse_line(cp, &addr); + + } +} + diff --git a/src/debug_shell.re2c b/src/debug_shell.re2c index ca5e096..1d2d651 100644 --- a/src/debug_shell.re2c +++ b/src/debug_shell.re2c @@ -420,7 +420,7 @@ static int is_jsr_bf00(word32 address) { get_memory16_c(address + 1, 0) == 0xbf00; } -static int g_disasm_psr; +int g_disasm_psr; static const char *get_inline_debug_name(word32 address) { static char buffer[256]; @@ -1434,7 +1434,12 @@ static int parse_command(const char *cp) { "!!" eol { extern uint32_t sweet16_asm_shell(uint32_t addr); - sweet16_asm_shell(0x300); + addr = sweet16_asm_shell(addr); + return 0; + } + "!" eol { + extern uint32_t mini_asm_shell(uint32_t addr); + addr = mini_asm_shell(addr); return 0; } diff --git a/src/mnemonics.x b/src/mnemonics.x new file mode 100644 index 0000000..2937508 --- /dev/null +++ b/src/mnemonics.x @@ -0,0 +1,92 @@ +x(ADC) +x(AND) +x(ASL) +x(BCC) +x(BCS) +x(BEQ) +x(BIT) +x(BMI) +x(BNE) +x(BPL) +x(BRA) +x(BRK) +x(BRL) +x(BVC) +x(BVS) +x(CLC) +x(CLD) +x(CLI) +x(CLV) +x(CMP) +x(COP) +x(CPX) +x(CPY) +x(DEC) +x(DEX) +x(DEY) +x(EOR) +x(INC) +x(INX) +x(INY) +x(JML) +x(JMP) +x(JSL) +x(JSR) +x(LDA) +x(LDX) +x(LDY) +x(LSR) +x(MVN) +x(MVP) +x(NOP) +x(ORA) +x(PEA) +x(PEI) +x(PER) +x(PHA) +x(PHB) +x(PHD) +x(PHK) +x(PHP) +x(PHX) +x(PHY) +x(PLA) +x(PLB) +x(PLD) +x(PLP) +x(PLX) +x(PLY) +x(REP) +x(ROL) +x(ROR) +x(RTI) +x(RTL) +x(RTS) +x(SBC) +x(SEC) +x(SED) +x(SEI) +x(SEP) +x(STA) +x(STP) +x(STX) +x(STY) +x(STZ) +x(TAX) +x(TAY) +x(TCD) +x(TCS) +x(TDC) +x(TRB) +x(TSB) +x(TSC) +x(TSX) +x(TXA) +x(TXS) +x(TXY) +x(TYA) +x(TYX) +x(WAI) +x(WDM) +x(XBA) +x(XCE) From 692c7deac1d3fa1905332aafd07379ae2188aaa9 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Apr 2019 18:29:44 -0400 Subject: [PATCH 06/23] allow PEA 12 --- src/debug_miniasm.re2c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index bab33b1..e79ffe1 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -263,7 +263,7 @@ struct opcode_entry opcode_table[] = { { ORA, ABS_X , 0x1d, 2 }, { ORA, ABS_LONG_X , 0x1f, 3 }, /* pea abs or pea #imm */ - { PEA, ABS , 0xf4, 2 }, { PEA, IMMEDIATE , 0xf4, 2 }, + { PEA, ABS , 0xf4, 2 }, { PEA, DP , 0xf4, 2 }, { PEA, IMMEDIATE , 0xf4, 2 }, /* pei (dp) or pei dp */ { PEI, INDIR , 0xd4, 1 }, { PEI, DP , 0xd4, 1 }, { PER, RELATIVE , 0x62, 2 }, From 860d8601a3a86c33853b584034119a8fccbc16ca Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Apr 2019 18:30:04 -0400 Subject: [PATCH 07/23] case insensitive --- src/debug_miniasm.re2c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index e79ffe1..384feda 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -479,10 +479,10 @@ static const char *parse_paren_tail(const char *cp, struct cookie *cookie) { if (!cp) return cp; /*!re2c * { return NULL; } - ")" { return cp; } - "),y" { cookie->mode += _y; return YYCURSOR; } - ",x)" { cookie->mode += _x; return YYCURSOR; } - ",s),y" { cookie->mode = SR_Y; return YYCURSOR; } + ')' { return YYCURSOR; } + '),y' { cookie->mode += _y; return YYCURSOR; } + ',x)' { cookie->mode += _x; return YYCURSOR; } + ',s),y' { cookie->mode = SR_Y; return YYCURSOR; } */ } @@ -496,8 +496,8 @@ static const char *parse_bracket_tail(const char *cp, struct cookie *cookie) { if (!cp) return cp; /*!re2c * { return NULL; } - "]" { return YYCURSOR; } - "],y" { cookie->mode += _y; return YYCURSOR; } + ']' { return YYCURSOR; } + '],y' { cookie->mode += _y; return YYCURSOR; } */ } From 79df8bf62eef1d7ba536198ac474cf74bf40007e Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Apr 2019 18:30:19 -0400 Subject: [PATCH 08/23] modifier parsing. --- src/debug_miniasm.re2c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index 384feda..f6627eb 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -426,10 +426,11 @@ static const char *parse_expr(const char *cp, struct cookie *cookie) { cookie->size = 0; switch(*cp) { - case '|': ++cp; cookie->size = 2; break; + case '|': ++cp; cookie->size = 2; break; case '>': ++cp; cookie->size = 3; break; case '<': ++cp; cookie->size = 1; break; } + YYCURSOR = cp; /*!re2c * { return NULL; } From c22c5172149273ab9d47ac3a1d3d2da9a5312077 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Apr 2019 18:32:12 -0400 Subject: [PATCH 09/23] fix relative calculation. --- src/debug_miniasm.re2c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index f6627eb..52329ff 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -663,8 +663,7 @@ static int parse_line(const char *cp, uint32_t *pc) { return 0; } - /* address ... */ - cookie.pc = *pc; + cookie.pc = addr; cp = parse_opcode(cp, &cookie); @@ -673,7 +672,7 @@ static int parse_line(const char *cp, uint32_t *pc) { if (*cp) { - parse_operand(cp, &cookie); + cp = parse_operand(cp, &cookie); if (!cp) return error(offset, "bad operand"); //offset = cp - start; } @@ -684,29 +683,29 @@ static int parse_line(const char *cp, uint32_t *pc) { /* clean up relative */ if (cookie.mode == RELATIVE) { - int pc = (cookie.pc + 1 + cookie.size) & 0xffff; - int tmp = (int16_t)(cookie.operand & 0xffff); + int pc = (addr + 1 + cookie.size) & 0xffff; + int tmp = cookie.operand & 0xffff; int offset = tmp - pc; if (cookie.size == 1) { - if (tmp < -128 || tmp > 127) return error(offset, "out of range"); - tmp &= 0xff; + if (offset < -128 || offset > 127) return error(offset, "out of range"); + offset &= 0xff; } - else tmp &= 0xffff; - cookie.operand = tmp; + else offset &= 0xffff; + cookie.operand = offset; } - set_memory_c(addr, cookie.opcode, 0); - unsigned operand = cookie.operand; + set_memory_c(addr++, cookie.opcode, 0); + unsigned operand = cookie.operand; for (i = 0; i < cookie.size; ++i) { - set_memory_c(addr, operand & 0xff, 0); + set_memory_c(addr++, operand & 0xff, 0); operand >>= 8; } fputs("\r\x1b[A\x1b[K", stdout); - do_list(addr, 1); - *pc = addr + 1 + cookie.size; + do_list(cookie.pc, 1); + *pc = addr; return 1; } From b561811394774628173ac1f5224384645e1c31e2 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Apr 2019 18:32:26 -0400 Subject: [PATCH 10/23] . --- src/debug_miniasm.re2c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index 52329ff..a549497 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -592,7 +592,7 @@ static const char *parse_operand(const char *cp, struct cookie *cookie) { cp = parse_tail(cp, cookie); break; } - + if (!cp) return NULL; if (*cp && !isspace(*cp)) return NULL; return ltrim(cp); } From 4c55800e2370da3d264e956f60b8329b5621d826 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Apr 2019 23:28:08 -0400 Subject: [PATCH 11/23] mini assembler - support for toolcalls. uses the Nifty List tool list. --- src/debug_miniasm.re2c | 38 ++++++++++++++++++++++++++ src/debug_template.re2c | 60 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index a549497..6667392 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -62,6 +62,12 @@ enum { MNEMONIC_LAST }; +enum { + TOOL_CALL = MNEMONIC_LAST, + GSOS_CALL, + MLI_CALL +}; + struct mnemonic_entry { const char *name; @@ -519,6 +525,24 @@ static const char *parse_opcode(const char *cp, struct cookie *cookie) { /*!re2c * { return NULL; } + '_' [A-Za-z] {0,16} / (ws|eol) { + + extern int lookup_tool_number(const char *name, unsigned vector); + + char name[20]; + int tool; + memcpy(name, cp, YYCURSOR - cp); + name[YYCURSOR - cp] = 0; + + tool = lookup_tool_number(name, 0xe10000); + if (tool <= 0) return NULL; + + cookie->mnemonic = TOOL_CALL; + cookie->operand = tool; + + return ltrim(YYCURSOR); + } + [A-Za-z]{3} / (ws|eol) { uint32_t tmp = 0; @@ -670,6 +694,19 @@ static int parse_line(const char *cp, uint32_t *pc) { if (!cp) return error(offset, "bad opcode"); offset = cp - start; + if (cookie.mnemonic == TOOL_CALL) { + if (*cp) return error(offset, "invalid address mode"); + if (g_disasm_psr & 0x30) return error(0, "8-bit m/x"); + + set_memory_c(addr++, 0xa2, 0); + set_memory_c(addr++, cookie.operand >> 0, 0); + set_memory_c(addr++, cookie.operand >> 8, 0); + set_memory_c(addr++, 0x22, 0); + set_memory_c(addr++, 0x00, 0); + set_memory_c(addr++, 0x00, 0); + set_memory_c(addr++, 0xe1, 0); + goto out; + } if (*cp) { cp = parse_operand(cp, &cookie); @@ -703,6 +740,7 @@ static int parse_line(const char *cp, uint32_t *pc) { } +out: fputs("\r\x1b[A\x1b[K", stdout); do_list(cookie.pc, 1); *pc = addr; diff --git a/src/debug_template.re2c b/src/debug_template.re2c index f9c6dee..80fb97d 100644 --- a/src/debug_template.re2c +++ b/src/debug_template.re2c @@ -409,6 +409,12 @@ struct tool *tools = NULL; int tool_count = 0; int tool_alloc = 0; + + +struct tool *tool_names = NULL; +int tool_name_count = 0; + + static void add_tool(struct tool *t) { if (tool_count == tool_alloc) { size_t size = (tool_alloc + 1024) * sizeof(struct tool); @@ -436,11 +442,20 @@ static int tool_compare(const void *a, const void *b) { const struct tool *bb = b; int rv = (int)aa->vector - (int)bb->vector; - if (rv == 0) - rv = (int)aa->number - (int)bb->number; + if (rv == 0) rv = (int)aa->number - (int)bb->number; return rv; } +static int tool_name_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 = strcasecmp(aa->name, bb->name); + return rv; +} + + /* nifty list */ /* * format: @@ -564,14 +579,51 @@ prefix: } + fclose(f); qsort(tools, tool_count, sizeof(struct tool), tool_compare); - fclose(f); + + /* name index for tools and gs/os calls */ + + int tmp = 0; + int i; + for (i = 0; i < tool_count; ++i) { + unsigned v = tools[i].vector; + if (v == 0xe10000 || v == 0xe100a8 || v == 0xbf00) + ++tmp; + } + if (!tmp) return; + tool_name_count = tmp; + tool_names = malloc(sizeof(struct tool) * tmp); + if (!tool_names) return; + tool_name_count = tmp; + tmp = 0; + for(i = 0; i < tool_count; ++i) { + unsigned v = tools[i].vector; + if (v == 0xe10000 || v == 0xe100a8 || v == 0xbf00) + tool_names[tmp++] = tools[i]; + } + qsort(tool_names, tool_name_count, sizeof(struct tool), tool_name_compare); } const char *debug_tool_name(unsigned number, unsigned vector) { + + if (!tool_count) return NULL; + 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; -} \ No newline at end of file +} + + +int lookup_tool_number(const char *name, unsigned vector) { + + if (!tool_name_count) return 0; + + struct tool tmp = { (char *)name, 0, vector}; + struct tool *t = bsearch(&tmp, tool_names, tool_name_count, sizeof(struct tool), tool_name_compare); + if (!t) return 0; + return t->number; +} + From bd534406108d76dba18fd4a2375107a3f80fe21c Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 15 Apr 2019 12:18:10 -0400 Subject: [PATCH 12/23] add BLT/BGE aliases. --- src/debug_miniasm.re2c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index 6667392..c30a0b4 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -68,7 +68,7 @@ enum { MLI_CALL }; - +#define CC3(a) ((a[0] << 16) | (a[1] << 8) | a[2]) struct mnemonic_entry { const char *name; int value; @@ -76,7 +76,7 @@ struct mnemonic_entry { }; struct mnemonic_entry mnemonic_table[] = { { NULL, 0 }, - #define x(a) { #a, (#a[0] << 16)| (#a[1] << 8) | (#a[2]), a }, + #define x(a) { #a, CC3(#a), a }, #include "mnemonics.x" #undef x }; @@ -553,6 +553,10 @@ static const char *parse_opcode(const char *cp, struct cookie *cookie) { e = bsearch((void *)(uintptr_t)tmp, mnemonic_table, sizeof(mnemonic_table) / sizeof(mnemonic_table[0]), sizeof(mnemonic_table[0]), mnemonic_cmp); + if (e == NULL) { + if (tmp == CC3("BLT")) e = &mnemonic_table[BCC]; + if (tmp == CC3("BGE")) e = &mnemonic_table[BCS]; + } if (!e) return NULL; cookie->mnemonic = e->mnemonic; cookie->mode = IMPLIED; From 67fc8b82ab8c1207e26ef2073ead072e4f0c75f0 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 15 Apr 2019 12:46:54 -0400 Subject: [PATCH 13/23] add JMP/JML, JSR/JSL aliases. --- src/debug_miniasm.re2c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index c30a0b4..c34e71b 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -212,12 +212,13 @@ struct opcode_entry opcode_table[] = { { INC, ABS_X , 0xfe, 2 }, { INX, IMPLIED , 0xe8, 0 }, { INY, IMPLIED , 0xc8, 0 }, - { JML, ABS_LONG , 0x5c, 3 }, + { JML, ABS_LONG , 0x5c, 3 }, { JML, ABS , 0x5c, 3 }, { JML, DP , 0x5c, 3 }, { JML, INDIR_LONG , 0xdc, 2 }, { JMP, ABS , 0x4c, 2 }, { JMP, INDIR , 0x6c, 2 }, { JMP, INDIR_X , 0x7c, 2 }, - { JSL, ABS_LONG , 0x22, 3 }, + { JMP, INDIR_LONG , 0xdc, 2 }, /* jml */ + { JSL, ABS_LONG , 0x22, 3 }, { JSL, ABS , 0x22, 3 }, { JSL, DP , 0x22, 3 }, { JSR, ABS , 0x20, 2 }, { JSR, INDIR_X , 0xfc, 2 }, { LDA, INDIR_X , 0xa1, 1 }, From 1afa610ab201a91c9522ec4d44843dc8f0c6ad30 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 15 Apr 2019 12:54:42 -0400 Subject: [PATCH 14/23] print current address/mx bits when entering the mini assembler. --- src/debug_miniasm.re2c | 6 ++++++ src/debug_sweet16.re2c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index c34e71b..e8b1dbd 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -762,6 +762,12 @@ uint32_t mini_asm_shell(uint32_t addr) { init = 1; } + printf("%02x/%04x: ; e=%d m=%d x=%d\n", + addr >> 16, addr & 0xffff, + g_disasm_psr & 0x0100 ? 1 : 0, + g_disasm_psr & 0x0020 ? 1 : 0, + g_disasm_psr & 0x0010 ? 1 : 0 + ); for(;;) { const char *cp = x_readline("!"); if (!cp || !*cp) return addr; diff --git a/src/debug_sweet16.re2c b/src/debug_sweet16.re2c index fcb716d..947b53e 100644 --- a/src/debug_sweet16.re2c +++ b/src/debug_sweet16.re2c @@ -389,7 +389,9 @@ extern char *x_readline(const char *prompt); uint32_t sweet16_asm_shell(uint32_t addr) { - + + printf("%02x/%04x:\n", addr >> 16, addr & 0xffff); + for(;;) { const char *cp = x_readline("!!"); if (!cp || !*cp) return addr; From 3ffa1d0e767e6e5abc9d89fd06d2031199b80231 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 15 Apr 2019 20:06:15 -0400 Subject: [PATCH 15/23] buffer overflow :( --- src/debug_miniasm.re2c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index e8b1dbd..48f0115 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -370,7 +370,7 @@ struct opcode_entry opcode_table[] = { /* generate an index of mnemonics to opcodes in the opcode_table */ -struct opcode_entry *opcode_table_index[MNEMONIC_LAST] = { 0 }; +struct opcode_entry *opcode_table_index[MNEMONIC_LAST+1] = { 0 }; static void init_table_index(void) { unsigned i; unsigned prev = 0; From 63275ee4ea3554676a6ba50f0eafa5edb7515f7c Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 15 Apr 2019 20:06:33 -0400 Subject: [PATCH 16/23] JMP/JSR 00 --- src/debug_miniasm.re2c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index 48f0115..ddd103c 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -214,12 +214,12 @@ struct opcode_entry opcode_table[] = { { INY, IMPLIED , 0xc8, 0 }, { JML, ABS_LONG , 0x5c, 3 }, { JML, ABS , 0x5c, 3 }, { JML, DP , 0x5c, 3 }, { JML, INDIR_LONG , 0xdc, 2 }, - { JMP, ABS , 0x4c, 2 }, + { JMP, ABS , 0x4c, 2 }, { JMP, DP , 0x4c, 2 }, { JMP, INDIR , 0x6c, 2 }, { JMP, INDIR_X , 0x7c, 2 }, { JMP, INDIR_LONG , 0xdc, 2 }, /* jml */ { JSL, ABS_LONG , 0x22, 3 }, { JSL, ABS , 0x22, 3 }, { JSL, DP , 0x22, 3 }, - { JSR, ABS , 0x20, 2 }, + { JSR, ABS , 0x20, 2 }, { JSR, DP , 0x20, 2 }, { JSR, INDIR_X , 0xfc, 2 }, { LDA, INDIR_X , 0xa1, 1 }, { LDA, SR , 0xa3, 1 }, From 25f5593a814bd72a39e4b35a024bf45e1e538f4d Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 15 Apr 2019 20:51:37 -0400 Subject: [PATCH 17/23] replace the old disassembler tables --- src/debug.c | 192 +++++++++----------------------- src/debug_shell.re2c | 197 +++++++++++++-------------------- src/disasm.c | 167 ++-------------------------- src/disasm.h | 37 ++----- src/opcodes.x | 256 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 403 insertions(+), 446 deletions(-) create mode 100644 src/opcodes.x diff --git a/src/debug.c b/src/debug.c index cb59451..06e6b00 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1267,163 +1267,75 @@ int do_dis_json(char *buf, word32 kpc, int accsize, int xsize, int op_provided, } switch(type) { - case ABS: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%04x",out,val); - break; - case ABSX: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%04x,X",out,val); - break; - case ABSY: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%04x,Y",out,val); - break; - case ABSLONG: - if(args != 3) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%06x",out,val); - break; - case ABSLONGX: - if(args != 3) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%06x,X",out,val); - break; - case ABSIND: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s ($%04x)",out,val); - break; - case ABSXIND: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s ($%04x,X)",out,val); - break; - case IMPLY: - if(args != 0) { - printf("arg # mismatch for opcode %x\n", opcode); - } + case IMPLIED: sprintf(buf_disasm,"%s",out); break; - case ACCUM: - if(args != 0) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s",out); - break; - case IMMED: - if(args == 1) { - sprintf(buf_disasm,"%s #$%02x",out,val); - } else if(args == 2) { - sprintf(buf_disasm,"%s #$%04x",out,val); - } else { - printf("arg # mismatch for opcode %x\n", opcode); - } - break; - case JUST8: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } + case DP: + case INTERRUPT: sprintf(buf_disasm,"%s $%02x",out,val); break; - case DLOC: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%02x",out,val); - break; - case DLOCX: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } + case DP_X: sprintf(buf_disasm,"%s $%02x,X",out,val); break; - case DLOCY: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } + case DP_Y: sprintf(buf_disasm,"%s $%02x,Y",out,val); break; - case DLOCIND: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s ($%02x)",out,val); + case ABS: + sprintf(buf_disasm,"%s $%04x",out,val); break; - case DLOCINDY: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s ($%02x),Y",out,val); + case ABS_X: + sprintf(buf_disasm,"%s $%04x,X",out,val); break; - case DLOCXIND: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s ($%02x,X)",out,val); + case ABS_Y: + sprintf(buf_disasm,"%s $%04x,Y",out,val); break; - case DLOCBRAK: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s [$%02x]",out,val); + case ABS_LONG: + sprintf(buf_disasm,"%s $%06x",out,val); break; - case DLOCBRAKY: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s [$%02x],y",out,val); + case ABS_LONG_X: + sprintf(buf_disasm,"%s $%06x,X",out,val); break; - case DISP8: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - signed_val = (signed char)val; + + case INDIR: + sprintf(buf_disasm,"%s ($%0*x)",out,args*2,val); + break; + case INDIR_X: + sprintf(buf_disasm,"%s ($%0*x,X)",out,args*2,val); + break; + case INDIR_Y: + sprintf(buf_disasm,"%s ($%0*x),Y",out,args*2,val); + break; + + case INDIR_LONG: + sprintf(buf_disasm,"%s [$%0*x]",out,args*2,val); + break; + case INDIR_LONG_Y: + sprintf(buf_disasm,"%s [$%0*x],Y",out,args*2,val); + break; + + case IMMED: + sprintf(buf_disasm,"%s #$%0*x",out, args*2, val); + break; + + case SR: + sprintf(buf_disasm,"%s $%02x,S",out,val); + break; + + case SR_Y: + sprintf(buf_disasm,"%s ($%02x,S),Y",out,val); + break; + + case RELATIVE: + signed_val = args == 1 ? (signed char)val : (signed short)val; + sprintf(buf_disasm,"%s $%04x",out, (word32)(kpc+(signed_val)) & 0xffff); break; - case DISP8S: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%02x,S",out,(word32)(byte)(val)); - break; - case DISP8SINDY: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s ($%02x,S),Y",out,(word32)(byte)(val)); - break; - case DISP16: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%04x", out, - (word32)(kpc+(signed)(word16)(val)) & 0xffff); - break; - case MVPMVN: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%02x,$%02x",out,val&0xff,val>>8); - break; - case SEPVAL: - case REPVAL: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s #$%02x",out,val); + + case BLOCK: + sprintf(buf_disasm,"%s $%02x,$%02x",out,val>>8, val&0xff); break; + default: printf("argument type: %d unexpected\n", type); break; diff --git a/src/debug_shell.re2c b/src/debug_shell.re2c index 1d2d651..2d01431 100644 --- a/src/debug_shell.re2c +++ b/src/debug_shell.re2c @@ -479,13 +479,14 @@ static const char *get_inline_debug_name(word32 address) { word32 do_list(word32 address, int lines) { unsigned char buffer2[32]; + char buffer3[32]; char buffer[32]; const char *opcode_string; const char *comment; unsigned opcode; - unsigned dtype; + unsigned mode; unsigned operand; word32 pc; @@ -500,8 +501,8 @@ word32 do_list(word32 address, int lines) { pc = address; opcode = get_memory_c(address++, 0); - dtype = disasm_types[opcode]; - args = dtype >> 8; + mode = disasm_types[opcode]; + args = mode >> 8; buffer2[bsize++] = opcode; opcode_string = disasm_opcodes[opcode]; @@ -536,89 +537,87 @@ word32 do_list(word32 address, int lines) { address += args; buffer[0] = 0; - switch(dtype & 0xff) { + uint32_t ea = 0; + switch(mode & 0xff) { case ABS: sprintf(buffer, "$%04x", operand); break; - case ABSX: + case ABS_X: sprintf(buffer, "$%04x,x", operand); break; - case ABSY: + case ABS_Y: 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: + case DP: sprintf(buffer,"$%02x",operand); break; - case DLOC: - sprintf(buffer,"$%02x",operand); - break; - case DLOCX: + case DP_X: sprintf(buffer,"$%02x,x",operand); break; - case DLOCY: + case DP_Y: sprintf(buffer,"$%02x,y",operand); break; - case ABSLONG: - sprintf(buffer,"$%06x",operand); - bank = operand >> 16; - if (bank == 0xe0 || bank == 0xe1 || bank == 0x01 || bank == 0xff) - comment = debug_tool_name(operand & 0xffff, bank); + + case ABS_LONG: + sprintf(buffer, "$%06x", operand); break; - case ABSLONGX: - sprintf(buffer,"$%06x,x",operand); - bank = operand >> 16; - if (bank == 0xe0 || bank == 0xe1 || bank == 0x01 || bank == 0xff) - comment = debug_tool_name(operand & 0xffff, bank); + case ABS_LONG_X: + sprintf(buffer, "$%06x,x", operand); break; - case DLOCIND: - sprintf(buffer,"($%02x)",operand); + case ABS_LONG_Y: + sprintf(buffer, "$%06x,y", operand); break; - case DLOCINDY: - sprintf(buffer,"($%02x),y",operand); + + + case INDIR: + sprintf(buffer,"($%0*x)", args * 2, operand ); break; - case DLOCXIND: - sprintf(buffer,"($%02x,x)",operand); + case INDIR_X: + sprintf(buffer,"($%0*x,x)", args * 2, operand ); break; - case DLOCBRAK: - sprintf(buffer,"[$%02x]",operand); + case INDIR_Y: + sprintf(buffer,"($%0*x),y", args * 2, operand ); break; - case DLOCBRAKY: - sprintf(buffer,"[$%02x],y",operand); + + case INDIR_LONG: + sprintf(buffer,"[$%0*x]", args * 2, operand ); break; - case DISP8: - sprintf(buffer,"$%04x", - (address+(int8_t)operand) & 0xffff); + case INDIR_LONG_X: + sprintf(buffer,"[$%0*x,x]", args * 2, operand ); break; - case DISP8S: - sprintf(buffer,"$%02x,s",operand); + case INDIR_LONG_Y: + sprintf(buffer,"[$%0*x],y", args * 2, operand ); break; - case DISP8SINDY: - sprintf(buffer,"($%02x,s),y",operand); + + case SR: + sprintf(buffer,"$%02x,s", operand ); break; - case DISP16: - sprintf(buffer,"$%04x", - (address+(int16_t)(operand)) & 0xffff); + + case SR_Y: + sprintf(buffer,"($%02x,s),y", operand ); break; - case MVPMVN: + + case IMMEDIATE: + sprintf(buffer,"#$%0*x",args * 2, operand); + break; + + case INTERRUPT: + sprintf(buffer,"$%02x",operand); + break; + + case BLOCK: sprintf(buffer,"$%02x,$%02x",operand >> 8, operand & 0xff); break; - case SEPVAL: - case REPVAL: - sprintf(buffer,"#$%02x",operand); + + case RELATIVE: + ea = address; + if (args == 1) ea += (int8_t)operand; + else ea += (int16_t)operand; + ea &= 0xffff; + sprintf(buffer,"$%04x", ea); + if (opcode == 0x62) ea = 0; /* per */ + else ea |= pc & 0xff0000; break; } @@ -628,7 +627,6 @@ word32 do_list(word32 address, int lines) { comment = debug_tool_name(pc & 0xffff, bank); } - uint32_t ea = 0; switch (opcode) { case 0xe2: /* sep */ g_disasm_psr|= operand; @@ -666,6 +664,7 @@ word32 do_list(word32 address, int lines) { break; #endif case 0x22: /* jsl */ + ea = operand; if (operand == 0xe100a8) { /* inline GS/OS call? */ unsigned num = get_memory16_c(address, 0); @@ -680,12 +679,11 @@ word32 do_list(word32 address, int lines) { buffer2[bsize++] = get_memory_c(address++, 0); } } - } else { - ea = operand; } break; case 0x20: /* jsr */ - if (operand == 0xbf00) { + ea = (operand | (address & 0xff0000)); + if (ea == 0x00bf00) { unsigned num = get_memory_c(address, 0); const char *name = debug_tool_name(num, operand); if (name) { @@ -697,34 +695,10 @@ word32 do_list(word32 address, int lines) { buffer2[bsize++] = get_memory_c(address++, 0); } } - } else { - ea = (operand | (address & 0xff0000)); } break; + /* relative ops have ea set above */ case 0x82: { - ea = address + (int16_t)operand; - ea &= 0xffff; - ea |= pc & 0xff0000; - - const char *name = get_inline_debug_name(pc); - /* start of an inline debug name? */ - if (name) { - opcode_string = name; - buffer[0] = 0; - - /* include the 0x77 71 magic bytes */ - for (i = 0; i < 2; ++i) { - buffer2[bsize++] = get_memory_c(address++, 0); - } - address = ea; - ea = 0; - } - break; - } - case 0x80: { - ea = address + (int8_t)operand; - ea &= 0xffff; - ea |= pc & 0xff0000; const char *name = get_inline_debug_name(pc); /* start of an inline debug name? */ @@ -743,41 +717,24 @@ word32 do_list(word32 address, int lines) { } - case 0x10: - case 0x30: - case 0x50: - case 0x70: - case 0x90: - case 0xb0: - case 0xd0: - case 0xf0: { - ea = address + (int8_t)operand; - ea &= 0xffff; - ea |= pc & 0xff0000; - break; - } + } + if (opcode == 0xc2 || opcode == 0xe2) { + if (!comment) { + comment = buffer3; + snprintf(buffer3, sizeof(buffer3), "e=%d m=%d x=%d", + g_disasm_psr & 0x0100 ? 1 : 0, + g_disasm_psr & 0x0020 ? 1 : 0, + g_disasm_psr & 0x0010 ? 1 : 0 + ); + } } if (ea && !comment) { comment = get_inline_debug_name(ea); } -#if 0 - n = printf("%02x/%04x: %s %s", - pc >> 16, pc & 0xffff, - opcode_string, buffer); - for(; n < 40; ++n) putchar(' '); - - for(i = 0; i < bsize; ++i) { - n += printf(" %02x", buffer2[i]); - } - if (comment) { - printf("%*s; %s", 60 - n, "", comment); - } - -#else /* 12/3456: 01 23 45 LDA #1 ; comment */ n = printf("%02x/%04x:", pc >> 16, pc & 0xffff); @@ -791,7 +748,7 @@ word32 do_list(word32 address, int lines) { while (n < 65) { fputc(' ', stdout); ++n; } printf("; %s", comment); } -#endif + fputc('\n', stdout); } @@ -820,8 +777,8 @@ word32 next_pc(void) { unsigned opcode = get_memory_c(pc++, 0); unsigned operand = 0; - unsigned dtype = disasm_types[opcode]; - unsigned args = dtype >> 8; + unsigned mode = disasm_types[opcode]; + unsigned args = mode >> 8; switch (args) { case 4: @@ -1451,8 +1408,8 @@ static int parse_command(const char *cp) { "%pc++" eol { /* todo */ unsigned opcode = get_memory_c(engine.kpc, 0); - unsigned dtype = disasm_types[opcode]; - unsigned args = dtype >> 8; + unsigned mode = disasm_types[opcode]; + unsigned args = mode >> 8; word32 tmp; switch (args) { diff --git a/src/disasm.c b/src/disasm.c index 91c0082..c190971 100644 --- a/src/disasm.c +++ b/src/disasm.c @@ -1,169 +1,16 @@ #include "disasm.h" + const char * const disasm_opcodes[256] = { - "BRK", "ORA", "COP", "ORA", "TSB", "ORA", "ASL", "ORA", /* 00-07 */ - "PHP", "ORA", "ASL", "PHD", "TSB", "ORA", "ASL", "ORA", /* 08-0f */ - "BPL", "ORA", "ORA", "ORA", "TRB", "ORA", "ASL", "ORA", /* 10-17 */ - "CLC", "ORA", "INC", "TCS", "TRB", "ORA", "ASL", "ORA", /* 18-1f */ - "JSR", "AND", "JSL", "AND", "BIT", "AND", "ROL", "AND", /* 20-27 */ - "PLP", "AND", "ROL", "PLD", "BIT", "AND", "ROL", "AND", /* 28-2f */ - "BMI", "AND", "AND", "AND", "BIT", "AND", "ROL", "AND", /* 30-37 */ - "SEC", "AND", "DEC", "TSC", "BIT", "AND", "ROL", "AND", /* 38-3f */ - "RTI", "EOR", "WDM", "EOR", "MVP", "EOR", "LSR", "EOR", /* 40-47 */ - "PHA", "EOR", "LSR", "PHK", "JMP", "EOR", "LSR", "EOR", /* 48-4f */ - "BVC", "EOR", "EOR", "EOR", "MVN", "EOR", "LSR", "EOR", /* 50-57 */ - "CLI", "EOR", "PHY", "TCD", "JMP", "EOR", "LSR", "EOR", /* 58-5f */ - "RTS", "ADC", "PER", "ADC", "STZ", "ADC", "ROR", "ADC", /* 60-67 */ - "PLA", "ADC", "ROR", "RTL", "JMP", "ADC", "ROR", "ADC", /* 68-6f */ - "BVS", "ADC", "ADC", "ADC", "STZ", "ADC", "ROR", "ADC", /* 70-77 */ - "SEI", "ADC", "PLY", "TDC", "JMP", "ADC", "ROR", "ADC", /* 78-7f */ - "BRA", "STA", "BRL", "STA", "STY", "STA", "STX", "STA", /* 80-87 */ - "DEY", "BIT", "TXA", "PHB", "STY", "STA", "STX", "STA", /* 88-8f */ - "BCC", "STA", "STA", "STA", "STY", "STA", "STX", "STA", /* 90-97 */ - "TYA", "STA", "TXS", "TXY", "STZ", "STA", "STZ", "STA", /* 98-9f */ - "LDY", "LDA", "LDX", "LDA", "LDY", "LDA", "LDX", "LDA", /* a0-a7 */ - "TAY", "LDA", "TAX", "PLB", "LDY", "LDA", "LDX", "LDA", /* a8-af */ - "BCS", "LDA", "LDA", "LDA", "LDY", "LDA", "LDX", "LDA", /* b0-b7 */ - "CLV", "LDA", "TSX", "TYX", "LDY", "LDA", "LDX", "LDA", /* b8-bf */ - "CPY", "CMP", "REP", "CMP", "CPY", "CMP", "DEC", "CMP", /* c0-c7 */ - "INY", "CMP", "DEX", "WAI", "CPY", "CMP", "DEC", "CMP", /* c8-cf */ - "BNE", "CMP", "CMP", "CMP", "PEI", "CMP", "DEC", "CMP", /* d0-d7 */ - "CLD", "CMP", "PHX", "STP", "JML", "CMP", "DEC", "CMP", /* d8-df */ - "CPX", "SBC", "SEP", "SBC", "CPX", "SBC", "INC", "SBC", /* e0-e7 */ - "INX", "SBC", "NOP", "XBA", "CPX", "SBC", "INC", "SBC", /* e8-ef */ - "BEQ", "SBC", "SBC", "SBC", "PEA", "SBC", "INC", "SBC", /* f0-f7 */ - "SED", "SBC", "PLX", "XCE", "JSR", "SBC", "INC", "SBC", /* f8-ff */ +#define x(a,b,c,d) #a, +#include "opcodes.x" +#undef x }; const unsigned disasm_types[256] = { - JUST8+0x100, DLOCXIND+0x100, /* 00-01 */ - JUST8+0x100, DISP8S+0x100, /* 02-03 */ - DLOC+0x100, DLOC+0x100, /* 04-05 */ - DLOC+0x100, DLOCBRAK+0x100, /* 06-07 */ - IMPLY+0x000, IMMED+0x400, /* 08-9 */ - ACCUM+0x000, IMPLY+0x000, /* 0a-b */ - ABS+0x200, ABS+0x200, /* c-d */ - ABS+0x200, ABSLONG+0x300, /* e-f */ - DISP8+0x100, DLOCINDY+0x100, /* 10-11 */ - DLOCIND+0x100, DISP8SINDY+0x100, /* 12-13 */ - DLOC+0x100, DLOCX+0x100, /* 14-15 */ - DLOCX+0x100, DLOCBRAKY+0x100, /* 16-17 */ - IMPLY+0x000, ABSY+0x200, /* 18-19 */ - ACCUM+0x000, IMPLY+0x000, /* 1a-1b */ - ABS+0x200, ABSX+0x200, /* 1c-1d */ - ABSX+0x200, ABSLONGX+0x300, /* 1e-1f */ - ABS+0x200, DLOCXIND+0x100, /* 20-21 */ - ABSLONG+0x300, DISP8S+0x100, /* 22-23 */ - DLOC+0x100, DLOC+0x100, /* 24-25 */ - DLOC+0x100, DLOCBRAK+0x100, /* 26-27 */ - IMPLY+0x000, IMMED+0x400, /* 28-29 */ - ACCUM+0x000, IMPLY+0x000, /* 2a-2b */ - ABS+0x200, ABS+0x200, /* 2c-2d */ - ABS+0x200, ABSLONG+0x300, /* 2e-2f */ - DISP8+0x100, DLOCINDY+0x100, /* 30-31 */ - DLOCIND+0x100, DISP8SINDY+0x100, /* 32-33 */ - DLOCX+0x100, DLOCX+0x100, /* 34-35 */ - DLOCX+0x100, DLOCBRAKY+0x100, /* 36-37 */ - IMPLY+0x000, ABSY+0x200, /* 38-39 */ - ACCUM+0x000, IMPLY+0x000, /* 3a-3b */ - ABSX+0x200, ABSX+0x200, /* 3c-3d */ - ABSX+0x200, ABSLONGX+0x300, /* 3e-3f */ - IMPLY+0x000, DLOCXIND+0x100, /* 40-41 */ - JUST8+0x100, DISP8S+0x100, /* 42-43 */ - MVPMVN+0x200, DLOC+0x100, /* 44-45 */ - DLOC+0x100, DLOCBRAK+0x100, /* 46-47 */ - IMPLY+0x000, IMMED+0x400, /* 48-49 */ - ACCUM+0x000, IMPLY+0x000, /* 4a-4b */ - ABS+0x200, ABS+0x200, /* 4c-4d */ - ABS+0x200, ABSLONG+0x300, /* 4e-4f */ - DISP8+0x100, DLOCINDY+0x100, /* 50-51 */ - DLOCIND+0x100, DISP8SINDY+0x100, /* 52-53 */ - MVPMVN+0x200, DLOCX+0x100, /* 54-55 */ - DLOCX+0x100, DLOCBRAKY+0x100, /* 56-57 */ - IMPLY+0x000, ABSY+0x200, /* 58-59 */ - IMPLY+0x000, IMPLY+0x000, /* 5a-5b */ - ABSLONG+0x300, ABSX+0x200, /* 5c-5d */ - ABSX+0x200, ABSLONGX+0x300, /* 5e-5f */ - IMPLY+0x000, DLOCXIND+0x100, /* 60-61 */ - DISP16+0x200, DISP8S+0x100, /* 62-63 */ - DLOC+0x100, DLOC+0x100, /* 64-65 */ - DLOC+0x100, DLOCBRAK+0x100, /* 66-67 */ - IMPLY+0x000, IMMED+0x400, /* 68-69 */ - ACCUM+0x000, IMPLY+0x000, /* 6a-6b */ - ABSIND+0x200, ABS+0x200, /* 6c-6d */ - ABS+0x200, ABSLONG+0x300, /* 6e-6f */ - DISP8+0x100, DLOCINDY+0x100, /* 70-71 */ - DLOCIND+0x100, DISP8SINDY+0x100, /* 72-73 */ - DLOCX+0x100, DLOCX+0x100, /* 74-75 */ - DLOCX+0x100, DLOCBRAKY+0x100, /* 76-77 */ - IMPLY+0x000, ABSY+0x200, /* 78-79 */ - IMPLY+0x000, IMPLY+0x000, /* 7a-7b */ - ABSXIND+0x200, ABSX+0x200, /* 7c-7d */ - ABSX+0x200, ABSLONGX+0x300, /* 7e-7f */ - DISP8+0x100, DLOCXIND+0x100, /* 80-81 */ - DISP16+0x200, DISP8S+0x100, /* 82-83 */ - DLOC+0x100, DLOC+0x100, /* 84-85 */ - DLOC+0x100, DLOCBRAK+0x100, /* 86-87 */ - IMPLY+0x000, IMMED+0x400, /* 88-89 */ - IMPLY+0x000, IMPLY+0x000, /* 8a-8b */ - ABS+0x200, ABS+0x200, /* 8c-8d */ - ABS+0x200, ABSLONG+0x300, /* 8e-8f */ - DISP8+0x100, DLOCINDY+0x100, /* 90-91 */ - DLOCIND+0x100, DISP8SINDY+0x100, /* 92-93 */ - DLOCX+0x100, DLOCX+0x100, /* 94-95 */ - DLOCY+0x100, DLOCBRAKY+0x100, /* 96-97 */ - IMPLY+0x000, ABSY+0x200, /* 98-99 */ - IMPLY+0x000, IMPLY+0x000, /* 9a-9b */ - ABS+0x200, ABSX+0x200, /* 9c-9d */ - ABSX+0x200, ABSLONGX+0x300, /* 9e-9f */ - IMMED+0x500, DLOCXIND+0x100, /* a0-a1 */ - IMMED+0x500, DISP8S+0x100, /* a2-a3 */ - DLOC+0x100, DLOC+0x100, /* a4-a5 */ - DLOC+0x100, DLOCBRAK+0x100, /* a6-a7 */ - IMPLY+0x000, IMMED+0x400, /* a8-a9 */ - IMPLY+0x000, IMPLY+0x000, /* aa-ab */ - ABS+0x200, ABS+0x200, /* ac-ad */ - ABS+0x200, ABSLONG+0x300, /* ae-af */ - DISP8+0x100, DLOCINDY+0x100, /* b0-b1 */ - DLOCIND+0x100, DISP8SINDY+0x100, /* b2-b3 */ - DLOCX+0x100, DLOCX+0x100, /* b4-b5 */ - DLOCY+0x100, DLOCBRAKY+0x100, /* b6-b7 */ - IMPLY+0x000, ABSY+0x200, /* b8-b9 */ - IMPLY+0x000, IMPLY+0x000, /* ba-bb */ - ABSX+0x200, ABSX+0x200, /* bc-bd */ - ABSY+0x200, ABSLONGX+0x300, /* be-bf */ - IMMED+0x500, DLOCXIND+0x100, /* c0-c1 */ - REPVAL+0x100, DISP8S+0x100, /* c2-c3 */ - DLOC+0x100, DLOC+0x100, /* c4-c5 */ - DLOC+0x100, DLOCBRAK+0x100, /* c6-c7 */ - IMPLY+0x000, IMMED+0x400, /* c8-c9 */ - IMPLY+0x000, IMPLY+0x000, /* ca-cb */ - ABS+0x200, ABS+0x200, /* cc-cd */ - ABS+0x200, ABSLONG+0x300, /* ce-cf */ - DISP8+0x100, DLOCINDY+0x100, /* d0-d1 */ - DLOCIND+0x100, DISP8SINDY+0x100, /* d2-d3 */ - DLOC+0x100, DLOCX+0x100, /* d4-d5 */ - DLOCX+0x100, DLOCBRAKY+0x100, /* d6-d7 */ - IMPLY+0x000, ABSY+0x200, /* d8-d9 */ - IMPLY+0x000, IMPLY+0x000, /* da-db */ - ABSIND+0x200, ABSX+0x200, /* dc-dd */ - ABSX+0x200, ABSLONGX+0x300, /* de-df */ - IMMED+0x500, DLOCXIND+0x100, /* e0-e1 */ - SEPVAL+0x100, DISP8S+0x100, /* e2-e3 */ - DLOC+0x100, DLOC+0x100, /* e4-e5 */ - DLOC+0x100, DLOCBRAK+0x100, /* e6-e7 */ - IMPLY+0x000, IMMED+0x400, /* e8-e9 */ - IMPLY+0x000, IMPLY+0x000, /* ea-eb */ - ABS+0x200, ABS+0x200, /* ec-ed */ - ABS+0x200, ABSLONG+0x300, /* ee-ef */ - DISP8+0x100, DLOCINDY+0x100, /* f0-f1 */ - DLOCIND+0x100, DISP8SINDY+0x100, /* f2-f3 */ - IMMED+0x200, DLOCX+0x100, /* f4-f5 */ - DLOCX+0x100, DLOCBRAKY+0x100, /* f6-f7 */ - IMPLY+0x000, ABSY+0x200, /* f8-f9 */ - IMPLY+0x000, IMPLY+0x000, /* fa-fb */ - ABSXIND+0x200, ABSX+0x200, /* fc-fd */ - ABSX+0x200, ABSLONGX+0x300, /* fe-ff */ +#define x(a,b,c,d) b + (d << 8), +#include "opcodes.x" +#undef x }; diff --git a/src/disasm.h b/src/disasm.h index 3c437fd..1636502 100644 --- a/src/disasm.h +++ b/src/disasm.h @@ -6,32 +6,17 @@ */ enum { - ABS = 1, - ABSX, - ABSY, - ABSIND, - ABSXIND, - IMPLY, - ACCUM, - IMMED, - JUST8, - DLOC, - DLOCX, - DLOCY, - ABSLONG, - ABSLONGX, - DLOCIND, - DLOCINDY, - DLOCXIND, - DLOCBRAK, - DLOCBRAKY, - DISP8, - DISP8S, - DISP8SINDY, - DISP16, - MVPMVN, - REPVAL, - SEPVAL + IMPLIED, + DP, DP_X, DP_Y, + ABS, ABS_X, ABS_Y, + ABS_LONG, ABS_LONG_X, ABS_LONG_Y, + INDIR, INDIR_X, INDIR_Y, + INDIR_LONG, INDIR_LONG_X, INDIR_LONG_Y, + SR, SR_Y, + IMMEDIATE, + RELATIVE, + INTERRUPT, + BLOCK, }; diff --git a/src/opcodes.x b/src/opcodes.x new file mode 100644 index 0000000..5bf1347 --- /dev/null +++ b/src/opcodes.x @@ -0,0 +1,256 @@ +x(BRK, INTERRUPT , 0x00, 1) +x(ORA, INDIR_X , 0x01, 1) +x(COP, INTERRUPT , 0x02, 1) +x(ORA, SR , 0x03, 1) +x(TSB, DP , 0x04, 1) +x(ORA, DP , 0x05, 1) +x(ASL, DP , 0x06, 1) +x(ORA, INDIR_LONG , 0x07, 1) +x(PHP, IMPLIED , 0x08, 0) +x(ORA, IMMEDIATE , 0x09, 4) +x(ASL, IMPLIED , 0x0a, 0) +x(PHD, IMPLIED , 0x0b, 0) +x(TSB, ABS , 0x0c, 2) +x(ORA, ABS , 0x0d, 2) +x(ASL, ABS , 0x0e, 2) +x(ORA, ABS_LONG , 0x0f, 3) +x(BPL, RELATIVE , 0x10, 1) +x(ORA, INDIR_Y , 0x11, 1) +x(ORA, INDIR , 0x12, 1) +x(ORA, SR_Y , 0x13, 1) +x(TRB, DP , 0x14, 1) +x(ORA, DP_X , 0x15, 1) +x(ASL, DP_X , 0x16, 1) +x(ORA, INDIR_LONG_Y, 0x17, 1) +x(CLC, IMPLIED , 0x18, 0) +x(ORA, ABS_Y , 0x19, 2) +x(INC, IMPLIED , 0x1a, 0) +x(TCS, IMPLIED , 0x1b, 0) +x(TRB, ABS , 0x1c, 2) +x(ORA, ABS_X , 0x1d, 2) +x(ASL, ABS_X , 0x1e, 2) +x(ORA, ABS_LONG_X , 0x1f, 3) +x(JSR, ABS , 0x20, 2) +x(AND, INDIR_X , 0x21, 1) +x(JSL, ABS_LONG , 0x22, 3) +x(AND, SR , 0x23, 1) +x(BIT, DP , 0x24, 1) +x(AND, DP , 0x25, 1) +x(ROL, DP , 0x26, 1) +x(AND, INDIR_LONG , 0x27, 1) +x(PLP, IMPLIED , 0x28, 0) +x(AND, IMMEDIATE , 0x29, 4) +x(ROL, IMPLIED , 0x2a, 0) +x(PLD, IMPLIED , 0x2b, 0) +x(BIT, ABS , 0x2c, 2) +x(AND, ABS , 0x2d, 2) +x(ROL, ABS , 0x2e, 2) +x(AND, ABS_LONG , 0x2f, 3) +x(BMI, RELATIVE , 0x30, 1) +x(AND, INDIR_Y , 0x31, 1) +x(AND, INDIR , 0x32, 1) +x(AND, SR_Y , 0x33, 1) +x(BIT, DP_X , 0x34, 1) +x(AND, DP_X , 0x35, 1) +x(ROL, DP_X , 0x36, 1) +x(AND, INDIR_LONG_Y, 0x37, 1) +x(SEC, IMPLIED , 0x38, 0) +x(AND, ABS_Y , 0x39, 2) +x(DEC, IMPLIED , 0x3a, 0) +x(TSC, IMPLIED , 0x3b, 0) +x(BIT, ABS_X , 0x3c, 2) +x(AND, ABS_X , 0x3d, 2) +x(ROL, ABS_X , 0x3e, 2) +x(AND, ABS_LONG_X , 0x3f, 3) +x(RTI, IMPLIED , 0x40, 0) +x(EOR, INDIR_X , 0x41, 1) +x(WDM, INTERRUPT , 0x42, 1) +x(EOR, SR , 0x43, 1) +x(MVP, BLOCK , 0x44, 2) +x(EOR, DP , 0x45, 1) +x(LSR, DP , 0x46, 1) +x(EOR, INDIR_LONG , 0x47, 1) +x(PHA, IMPLIED , 0x48, 0) +x(EOR, IMMEDIATE , 0x49, 4) +x(LSR, IMPLIED , 0x4a, 0) +x(PHK, IMPLIED , 0x4b, 0) +x(JMP, ABS , 0x4c, 2) +x(EOR, ABS , 0x4d, 2) +x(LSR, ABS , 0x4e, 2) +x(EOR, ABS_LONG , 0x4f, 3) +x(BVC, RELATIVE , 0x50, 1) +x(EOR, INDIR_Y , 0x51, 1) +x(EOR, INDIR , 0x52, 1) +x(EOR, SR_Y , 0x53, 1) +x(MVN, BLOCK , 0x54, 2) +x(EOR, DP_X , 0x55, 1) +x(LSR, DP_X , 0x56, 1) +x(EOR, INDIR_LONG_Y, 0x57, 1) +x(CLI, IMPLIED , 0x58, 0) +x(EOR, ABS_Y , 0x59, 2) +x(PHY, IMPLIED , 0x5a, 0) +x(TCD, IMPLIED , 0x5b, 0) +x(JML, ABS_LONG , 0x5c, 3) +x(EOR, ABS_X , 0x5d, 2) +x(LSR, ABS_X , 0x5e, 2) +x(EOR, ABS_LONG_X , 0x5f, 3) +x(RTS, IMPLIED , 0x60, 0) +x(ADC, INDIR_X , 0x61, 1) +x(PER, RELATIVE , 0x62, 2) +x(ADC, SR , 0x63, 1) +x(STZ, DP , 0x64, 1) +x(ADC, DP , 0x65, 1) +x(ROR, DP , 0x66, 1) +x(ADC, INDIR_LONG , 0x67, 1) +x(PLA, IMPLIED , 0x68, 0) +x(ADC, IMMEDIATE , 0x69, 4) +x(ROR, IMPLIED , 0x6a, 0) +x(RTL, IMPLIED , 0x6b, 0) +x(JMP, INDIR , 0x6c, 2) +x(ADC, ABS , 0x6d, 2) +x(ROR, ABS , 0x6e, 2) +x(ADC, ABS_LONG , 0x6f, 3) +x(BVS, RELATIVE , 0x70, 1) +x(ADC, INDIR_Y , 0x71, 1) +x(ADC, INDIR , 0x72, 1) +x(ADC, SR_Y , 0x73, 1) +x(STZ, DP_X , 0x74, 1) +x(ADC, DP_X , 0x75, 1) +x(ROR, DP_X , 0x76, 1) +x(ADC, INDIR_LONG_Y, 0x77, 1) +x(SEI, IMPLIED , 0x78, 0) +x(ADC, ABS_Y , 0x79, 2) +x(PLY, IMPLIED , 0x7a, 0) +x(TDC, IMPLIED , 0x7b, 0) +x(JMP, INDIR_X , 0x7c, 2) +x(ADC, ABS_X , 0x7d, 2) +x(ROR, ABS_X , 0x7e, 2) +x(ADC, ABS_LONG_X , 0x7f, 3) +x(BRA, RELATIVE , 0x80, 1) +x(STA, INDIR_X , 0x81, 1) +x(BRL, RELATIVE , 0x82, 2) +x(STA, SR , 0x83, 1) +x(STY, DP , 0x84, 1) +x(STA, DP , 0x85, 1) +x(STX, DP , 0x86, 1) +x(STA, INDIR_LONG , 0x87, 1) +x(DEY, IMPLIED , 0x88, 0) +x(BIT, IMMEDIATE , 0x89, 4) +x(TXA, IMPLIED , 0x8a, 0) +x(PHB, IMPLIED , 0x8b, 0) +x(STY, ABS , 0x8c, 2) +x(STA, ABS , 0x8d, 2) +x(STX, ABS , 0x8e, 2) +x(STA, ABS_LONG , 0x8f, 3) +x(BCC, RELATIVE , 0x90, 1) +x(STA, INDIR_Y , 0x91, 1) +x(STA, INDIR , 0x92, 1) +x(STA, SR_Y , 0x93, 1) +x(STY, DP_X , 0x94, 1) +x(STA, DP_X , 0x95, 1) +x(STX, DP_Y , 0x96, 1) +x(STA, INDIR_LONG_Y, 0x97, 1) +x(TYA, IMPLIED , 0x98, 0) +x(STA, ABS_Y , 0x99, 2) +x(TXS, IMPLIED , 0x9a, 0) +x(TXY, IMPLIED , 0x9b, 0) +x(STZ, ABS , 0x9c, 2) +x(STA, ABS_X , 0x9d, 2) +x(STZ, ABS_X , 0x9e, 2) +x(STA, ABS_LONG_X , 0x9f, 3) +x(LDY, IMMEDIATE , 0xa0, 5) +x(LDA, INDIR_X , 0xa1, 1) +x(LDX, IMMEDIATE , 0xa2, 5) +x(LDA, SR , 0xa3, 1) +x(LDY, DP , 0xa4, 1) +x(LDA, DP , 0xa5, 1) +x(LDX, DP , 0xa6, 1) +x(LDA, INDIR_LONG , 0xa7, 1) +x(TAY, IMPLIED , 0xa8, 0) +x(LDA, IMMEDIATE , 0xa9, 4) +x(TAX, IMPLIED , 0xaa, 0) +x(PLB, IMPLIED , 0xab, 0) +x(LDY, ABS , 0xac, 2) +x(LDA, ABS , 0xad, 2) +x(LDX, ABS , 0xae, 2) +x(LDA, ABS_LONG , 0xaf, 3) +x(BCS, RELATIVE , 0xb0, 1) +x(LDA, INDIR_Y , 0xb1, 1) +x(LDA, INDIR , 0xb2, 1) +x(LDA, SR_Y , 0xb3, 1) +x(LDY, DP_X , 0xb4, 1) +x(LDA, DP_X , 0xb5, 1) +x(LDX, DP_Y , 0xb6, 1) +x(LDA, INDIR_LONG_Y, 0xb7, 1) +x(CLV, IMPLIED , 0xb8, 0) +x(LDA, ABS_Y , 0xb9, 2) +x(TSX, IMPLIED , 0xba, 0) +x(TYX, IMPLIED , 0xbb, 0) +x(LDY, ABS_X , 0xbc, 2) +x(LDA, ABS_X , 0xbd, 2) +x(LDX, ABS_Y , 0xbe, 2) +x(LDA, ABS_LONG_X , 0xbf, 3) +x(CPY, IMMEDIATE , 0xc0, 5) +x(CMP, INDIR_X , 0xc1, 1) +x(REP, IMMEDIATE , 0xc2, 1) +x(CMP, SR , 0xc3, 1) +x(CPY, DP , 0xc4, 1) +x(CMP, DP , 0xc5, 1) +x(DEC, DP , 0xc6, 1) +x(CMP, INDIR_LONG , 0xc7, 1) +x(INY, IMPLIED , 0xc8, 0) +x(CMP, IMMEDIATE , 0xc9, 4) +x(DEX, IMPLIED , 0xca, 0) +x(WAI, IMPLIED , 0xcb, 0) +x(CPY, ABS , 0xcc, 2) +x(CMP, ABS , 0xcd, 2) +x(DEC, ABS , 0xce, 2) +x(CMP, ABS_LONG , 0xcf, 3) +x(BNE, RELATIVE , 0xd0, 1) +x(CMP, INDIR_Y , 0xd1, 1) +x(CMP, INDIR , 0xd2, 1) +x(CMP, SR_Y , 0xd3, 1) +x(PEI, INDIR , 0xd4, 1) +x(CMP, DP_X , 0xd5, 1) +x(DEC, DP_X , 0xd6, 1) +x(CMP, INDIR_LONG_Y, 0xd7, 1) +x(CLD, IMPLIED , 0xd8, 0) +x(CMP, ABS_Y , 0xd9, 2) +x(PHX, IMPLIED , 0xda, 0) +x(STP, IMPLIED , 0xdb, 0) +x(JML, INDIR_LONG , 0xdc, 2) +x(CMP, ABS_X , 0xdd, 2) +x(DEC, ABS_X , 0xde, 2) +x(CMP, ABS_LONG_X , 0xdf, 3) +x(CPX, IMMEDIATE , 0xe0, 5) +x(SBC, INDIR_X , 0xe1, 1) +x(SEP, IMMEDIATE , 0xe2, 1) +x(SBC, SR , 0xe3, 1) +x(CPX, DP , 0xe4, 1) +x(SBC, DP , 0xe5, 1) +x(INC, DP , 0xe6, 1) +x(SBC, INDIR_LONG , 0xe7, 1) +x(INX, IMPLIED , 0xe8, 0) +x(SBC, IMMEDIATE , 0xe9, 4) +x(NOP, IMPLIED , 0xea, 0) +x(XBA, IMPLIED , 0xeb, 0) +x(CPX, ABS , 0xec, 2) +x(SBC, ABS , 0xed, 2) +x(INC, ABS , 0xee, 2) +x(SBC, ABS_LONG , 0xef, 3) +x(BEQ, RELATIVE , 0xf0, 1) +x(SBC, INDIR_Y , 0xf1, 1) +x(SBC, INDIR , 0xf2, 1) +x(SBC, SR_Y , 0xf3, 1) +x(PEA, ABS , 0xf4, 2) +x(SBC, DP_X , 0xf5, 1) +x(INC, DP_X , 0xf6, 1) +x(SBC, INDIR_LONG_Y, 0xf7, 1) +x(SED, IMPLIED , 0xf8, 0) +x(SBC, ABS_Y , 0xf9, 2) +x(PLX, IMPLIED , 0xfa, 0) +x(XCE, IMPLIED , 0xfb, 0) +x(JSR, INDIR_X , 0xfc, 2) +x(SBC, ABS_X , 0xfd, 2) +x(INC, ABS_X , 0xfe, 2) +x(SBC, ABS_LONG_X , 0xff, 3) From 9cf84e82c6c664ab3ce0ea19ab3e48e92b01b768 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Thu, 18 Apr 2019 13:14:49 -0400 Subject: [PATCH 18/23] mini asm uses/sets prev_addr. --- src/debug_shell.re2c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug_shell.re2c b/src/debug_shell.re2c index 2d01431..ac24bfd 100644 --- a/src/debug_shell.re2c +++ b/src/debug_shell.re2c @@ -1391,12 +1391,12 @@ static int parse_command(const char *cp) { "!!" eol { extern uint32_t sweet16_asm_shell(uint32_t addr); - addr = sweet16_asm_shell(addr); + g_prev_address = sweet16_asm_shell(g_prev_address); return 0; } "!" eol { extern uint32_t mini_asm_shell(uint32_t addr); - addr = mini_asm_shell(addr); + g_prev_address = mini_asm_shell(g_prev_address); return 0; } From 13b78fb412462257aff4e289ef938c5ea5e06054 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Thu, 18 Apr 2019 13:15:13 -0400 Subject: [PATCH 19/23] add long/short support to assume m/x bits. --- src/debug_miniasm.re2c | 53 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index ddd103c..60c23ed 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -65,7 +65,8 @@ enum { enum { TOOL_CALL = MNEMONIC_LAST, GSOS_CALL, - MLI_CALL + MLI_CALL, + LONG_SHORT, }; #define CC3(a) ((a[0] << 16) | (a[1] << 8) | a[2]) @@ -422,7 +423,23 @@ static int find_opcode(struct cookie *cookie) { } +/* long m,x | mx | ai | i | a, etc */ +static const char *parse_mx(const char *cp, struct cookie *cookie) { + unsigned rv = 0; + char c; + for( ; c = *cp; ++cp) { + if (isspace(c)) break; + if (c == ',') continue; + c = toupper(c); + if (c == 'M' || c == 'A') rv |= 0x20; + else if (c == 'X' || c == 'I') rv |= 0x10; + else return NULL; + } + if (rv == 0) rv = 0x30; + cookie->operand = rv; + return ltrim(cp); +} static const char *parse_expr(const char *cp, struct cookie *cookie) { @@ -544,6 +561,18 @@ static const char *parse_opcode(const char *cp, struct cookie *cookie) { return ltrim(YYCURSOR); } + 'long' / (ws|eol) { + cookie->mnemonic = LONG_SHORT; + cookie->mode = 0; + return ltrim(YYCURSOR); + } + 'short' / (ws|eol) { + cookie->mnemonic = LONG_SHORT; + cookie->mode = 1; + return ltrim(YYCURSOR); + } + + [A-Za-z]{3} / (ws|eol) { uint32_t tmp = 0; @@ -713,6 +742,28 @@ static int parse_line(const char *cp, uint32_t *pc) { goto out; } + if (cookie.mnemonic == LONG_SHORT) { + + cp = parse_mx(cp, &cookie); + if (!cp || *cp) return error(offset, "bad operand"); + + if (cookie.mode == 0) { + g_disasm_psr &= ~cookie.operand; + g_disasm_psr &= ~0x0100; /* disable e */ + } else { + g_disasm_psr |= cookie.operand; + } + + fputs("\r\x1b[A\x1b[K", stdout); + printf("%02x/%04x: ; e=%d m=%d x=%d\n", + addr >> 16, addr & 0xffff, + g_disasm_psr & 0x0100 ? 1 : 0, + g_disasm_psr & 0x0020 ? 1 : 0, + g_disasm_psr & 0x0010 ? 1 : 0 + ); + return 1; + } + if (*cp) { cp = parse_operand(cp, &cookie); if (!cp) return error(offset, "bad operand"); From 379784c7572af1d0268d6db376c6db4169d95185 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Thu, 18 Apr 2019 21:58:28 -0400 Subject: [PATCH 20/23] add GS/OS, P16, P8 macro support. since nifty list uses the same names for all (with GS/P16/P8 prefixes which are stripped), P16 and P8 macros are more or less unavailable. --- src/debug_miniasm.re2c | 99 +++++++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 26 deletions(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index 60c23ed..de82264 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -91,6 +91,7 @@ struct cookie { unsigned opcode; unsigned operand; unsigned pc; + unsigned extra; }; @@ -392,6 +393,8 @@ static int find_opcode(struct cookie *cookie) { unsigned mode = cookie->mode; + if (cookie->mnemonic >= MNEMONIC_LAST) return -1; + const struct opcode_entry *iter = opcode_table_index[cookie->mnemonic]; const struct opcode_entry *end = opcode_table_index[cookie->mnemonic + 1]; @@ -427,7 +430,7 @@ static int find_opcode(struct cookie *cookie) { static const char *parse_mx(const char *cp, struct cookie *cookie) { unsigned rv = 0; char c; - for( ; c = *cp; ++cp) { + for( ; (c = *cp); ++cp) { if (isspace(c)) break; if (c == ',') continue; c = toupper(c); @@ -446,13 +449,14 @@ static const char *parse_expr(const char *cp, struct cookie *cookie) { const char *YYCURSOR = cp; const char *YYMARKER = NULL; const char *YYCTXMARKER = NULL; + unsigned mask = 0xffffff; if (!cp) return NULL; cookie->size = 0; switch(*cp) { - case '|': ++cp; cookie->size = 2; break; - case '>': ++cp; cookie->size = 3; break; - case '<': ++cp; cookie->size = 1; break; + case '<': ++cp; cookie->size = 1; mask = 0xff; break; + case '|': ++cp; cookie->size = 2; mask = 0xffff; break; + case '>': ++cp; cookie->size = 3; mask = 0xffffff; break; } YYCURSOR = cp; @@ -472,7 +476,7 @@ static const char *parse_expr(const char *cp, struct cookie *cookie) { } x{1,6} { - cookie->operand = to_hex(cp, YYCURSOR); + cookie->operand = to_hex(cp, YYCURSOR) & mask; if (!cookie->size) cookie->size = ((YYCURSOR - cp + 1) & ~1)>>1; return YYCURSOR; } @@ -539,7 +543,6 @@ static const char *parse_opcode(const char *cp, struct cookie *cookie) { const char *YYMARKER = NULL; const char *YYCTXMARKER = NULL; - /* todo -- long m|x, short m|x, _toolcall */ /*!re2c * { return NULL; } @@ -548,17 +551,22 @@ static const char *parse_opcode(const char *cp, struct cookie *cookie) { extern int lookup_tool_number(const char *name, unsigned vector); char name[20]; - int tool; + int i; + memcpy(name, cp, YYCURSOR - cp); name[YYCURSOR - cp] = 0; - tool = lookup_tool_number(name, 0xe10000); - if (tool <= 0) return NULL; + for (i = 0; i < 3; ++i) { + static unsigned vectors[] = { 0xe10000, 0xe100a8, 0xbf00 }; + static unsigned types[] = { TOOL_CALL, GSOS_CALL, MLI_CALL }; - cookie->mnemonic = TOOL_CALL; - cookie->operand = tool; - - return ltrim(YYCURSOR); + int tool = lookup_tool_number(name, vectors[i]); + if (tool <= 0) continue; + cookie->mnemonic = types[i]; + cookie->extra = tool; + return ltrim(YYCURSOR); + } + return NULL; } 'long' / (ws|eol) { @@ -728,19 +736,6 @@ static int parse_line(const char *cp, uint32_t *pc) { if (!cp) return error(offset, "bad opcode"); offset = cp - start; - if (cookie.mnemonic == TOOL_CALL) { - if (*cp) return error(offset, "invalid address mode"); - if (g_disasm_psr & 0x30) return error(0, "8-bit m/x"); - - set_memory_c(addr++, 0xa2, 0); - set_memory_c(addr++, cookie.operand >> 0, 0); - set_memory_c(addr++, cookie.operand >> 8, 0); - set_memory_c(addr++, 0x22, 0); - set_memory_c(addr++, 0x00, 0); - set_memory_c(addr++, 0x00, 0); - set_memory_c(addr++, 0xe1, 0); - goto out; - } if (cookie.mnemonic == LONG_SHORT) { @@ -772,6 +767,58 @@ static int parse_line(const char *cp, uint32_t *pc) { if (*cp) return error(offset, "bad operand"); + if (cookie.mnemonic == TOOL_CALL) { + if (cookie.mode != IMPLIED) return error(offset, "invalid address mode"); + if (g_disasm_psr & 0x30) return error(0, "8-bit m/x"); + + set_memory_c(addr++, 0xa2, 0); + set_memory_c(addr++, cookie.extra >> 0, 0); + set_memory_c(addr++, cookie.extra >> 8, 0); + set_memory_c(addr++, 0x22, 0); + set_memory_c(addr++, 0x00, 0); + set_memory_c(addr++, 0x00, 0); + set_memory_c(addr++, 0xe1, 0); + goto out; + } + + + + if (cookie.mnemonic == GSOS_CALL) { + if (cookie.mode != DP && cookie.mode != ABS && cookie.mode != ABS_LONG) + return error(offset, "invalid address mode"); + if (g_disasm_psr & 0x30) return error(0, "8-bit m/x"); + + set_memory_c(addr++, 0x22, 0); + set_memory_c(addr++, 0xa8, 0); + set_memory_c(addr++, 0x00, 0); + set_memory_c(addr++, 0xe1, 0); + set_memory_c(addr++, cookie.extra >> 0, 0); + set_memory_c(addr++, cookie.extra >> 8, 0); + set_memory_c(addr++, cookie.operand >> 0, 0); + set_memory_c(addr++, cookie.operand >> 8, 0); + set_memory_c(addr++, cookie.operand >> 16, 0); + set_memory_c(addr++, cookie.operand >> 24, 0); + + goto out; + } + + if (cookie.mnemonic == MLI_CALL) { + if (cookie.mode != DP && cookie.mode != ABS) + return error(offset, "invalid address mode"); + if ((g_disasm_psr & 0x30) != 0x30) return error(0, "16-bit m/x"); + if (addr >> 16) return error(0, "invalid bank"); + + set_memory_c(addr++, 0x20, 0); + set_memory_c(addr++, 0xbf, 0); + set_memory_c(addr++, 0x00, 0); + set_memory_c(addr++, cookie.extra >> 0, 0); + set_memory_c(addr++, cookie.operand >> 0, 0); + set_memory_c(addr++, cookie.operand >> 8, 0); + + goto out; + } + + if (find_opcode(&cookie) < 0) return error(offset, "invalid address mode"); /* clean up relative */ From 391681fb9609fb8c9a4f683624eef0759843061d Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 5 May 2019 16:59:24 -0400 Subject: [PATCH 21/23] pre-calculate mnemonic hashes. --- src/debug_miniasm.re2c | 12 +-- src/mnemonics.x | 184 ++++++++++++++++++++--------------------- 2 files changed, 98 insertions(+), 98 deletions(-) diff --git a/src/debug_miniasm.re2c b/src/debug_miniasm.re2c index de82264..b2fe5c6 100644 --- a/src/debug_miniasm.re2c +++ b/src/debug_miniasm.re2c @@ -56,7 +56,7 @@ enum { enum { MNEMONIC_NONE, - #define x(a) a, + #define x(a, b) a, #include "mnemonics.x" #undef x MNEMONIC_LAST @@ -69,7 +69,6 @@ enum { LONG_SHORT, }; -#define CC3(a) ((a[0] << 16) | (a[1] << 8) | a[2]) struct mnemonic_entry { const char *name; int value; @@ -77,7 +76,7 @@ struct mnemonic_entry { }; struct mnemonic_entry mnemonic_table[] = { { NULL, 0 }, - #define x(a) { #a, CC3(#a), a }, + #define x(a, b) { #a, b, a }, #include "mnemonics.x" #undef x }; @@ -536,7 +535,8 @@ static int mnemonic_cmp(const void *a, const void *b) { return key - e->value; } - +#define kBLT 0x424c54 +#define kBGE 0x424745 static const char *parse_opcode(const char *cp, struct cookie *cookie) { const char *YYCURSOR = cp; @@ -592,8 +592,8 @@ static const char *parse_opcode(const char *cp, struct cookie *cookie) { sizeof(mnemonic_table) / sizeof(mnemonic_table[0]), sizeof(mnemonic_table[0]), mnemonic_cmp); if (e == NULL) { - if (tmp == CC3("BLT")) e = &mnemonic_table[BCC]; - if (tmp == CC3("BGE")) e = &mnemonic_table[BCS]; + if (tmp == kBLT) e = &mnemonic_table[BCC]; + if (tmp == kBGE) e = &mnemonic_table[BCS]; } if (!e) return NULL; cookie->mnemonic = e->mnemonic; diff --git a/src/mnemonics.x b/src/mnemonics.x index 2937508..bb02bf7 100644 --- a/src/mnemonics.x +++ b/src/mnemonics.x @@ -1,92 +1,92 @@ -x(ADC) -x(AND) -x(ASL) -x(BCC) -x(BCS) -x(BEQ) -x(BIT) -x(BMI) -x(BNE) -x(BPL) -x(BRA) -x(BRK) -x(BRL) -x(BVC) -x(BVS) -x(CLC) -x(CLD) -x(CLI) -x(CLV) -x(CMP) -x(COP) -x(CPX) -x(CPY) -x(DEC) -x(DEX) -x(DEY) -x(EOR) -x(INC) -x(INX) -x(INY) -x(JML) -x(JMP) -x(JSL) -x(JSR) -x(LDA) -x(LDX) -x(LDY) -x(LSR) -x(MVN) -x(MVP) -x(NOP) -x(ORA) -x(PEA) -x(PEI) -x(PER) -x(PHA) -x(PHB) -x(PHD) -x(PHK) -x(PHP) -x(PHX) -x(PHY) -x(PLA) -x(PLB) -x(PLD) -x(PLP) -x(PLX) -x(PLY) -x(REP) -x(ROL) -x(ROR) -x(RTI) -x(RTL) -x(RTS) -x(SBC) -x(SEC) -x(SED) -x(SEI) -x(SEP) -x(STA) -x(STP) -x(STX) -x(STY) -x(STZ) -x(TAX) -x(TAY) -x(TCD) -x(TCS) -x(TDC) -x(TRB) -x(TSB) -x(TSC) -x(TSX) -x(TXA) -x(TXS) -x(TXY) -x(TYA) -x(TYX) -x(WAI) -x(WDM) -x(XBA) -x(XCE) +x(ADC, 0x414443) +x(AND, 0x414e44) +x(ASL, 0x41534c) +x(BCC, 0x424343) +x(BCS, 0x424353) +x(BEQ, 0x424551) +x(BIT, 0x424954) +x(BMI, 0x424d49) +x(BNE, 0x424e45) +x(BPL, 0x42504c) +x(BRA, 0x425241) +x(BRK, 0x42524b) +x(BRL, 0x42524c) +x(BVC, 0x425643) +x(BVS, 0x425653) +x(CLC, 0x434c43) +x(CLD, 0x434c44) +x(CLI, 0x434c49) +x(CLV, 0x434c56) +x(CMP, 0x434d50) +x(COP, 0x434f50) +x(CPX, 0x435058) +x(CPY, 0x435059) +x(DEC, 0x444543) +x(DEX, 0x444558) +x(DEY, 0x444559) +x(EOR, 0x454f52) +x(INC, 0x494e43) +x(INX, 0x494e58) +x(INY, 0x494e59) +x(JML, 0x4a4d4c) +x(JMP, 0x4a4d50) +x(JSL, 0x4a534c) +x(JSR, 0x4a5352) +x(LDA, 0x4c4441) +x(LDX, 0x4c4458) +x(LDY, 0x4c4459) +x(LSR, 0x4c5352) +x(MVN, 0x4d564e) +x(MVP, 0x4d5650) +x(NOP, 0x4e4f50) +x(ORA, 0x4f5241) +x(PEA, 0x504541) +x(PEI, 0x504549) +x(PER, 0x504552) +x(PHA, 0x504841) +x(PHB, 0x504842) +x(PHD, 0x504844) +x(PHK, 0x50484b) +x(PHP, 0x504850) +x(PHX, 0x504858) +x(PHY, 0x504859) +x(PLA, 0x504c41) +x(PLB, 0x504c42) +x(PLD, 0x504c44) +x(PLP, 0x504c50) +x(PLX, 0x504c58) +x(PLY, 0x504c59) +x(REP, 0x524550) +x(ROL, 0x524f4c) +x(ROR, 0x524f52) +x(RTI, 0x525449) +x(RTL, 0x52544c) +x(RTS, 0x525453) +x(SBC, 0x534243) +x(SEC, 0x534543) +x(SED, 0x534544) +x(SEI, 0x534549) +x(SEP, 0x534550) +x(STA, 0x535441) +x(STP, 0x535450) +x(STX, 0x535458) +x(STY, 0x535459) +x(STZ, 0x53545a) +x(TAX, 0x544158) +x(TAY, 0x544159) +x(TCD, 0x544344) +x(TCS, 0x544353) +x(TDC, 0x544443) +x(TRB, 0x545242) +x(TSB, 0x545342) +x(TSC, 0x545343) +x(TSX, 0x545358) +x(TXA, 0x545841) +x(TXS, 0x545853) +x(TXY, 0x545859) +x(TYA, 0x545941) +x(TYX, 0x545958) +x(WAI, 0x574149) +x(WDM, 0x57444d) +x(XBA, 0x584241) +x(XCE, 0x584345) From 718683dd8de4ca44475858fb9a8e59ab8aeedd22 Mon Sep 17 00:00:00 2001 From: ksherlock Date: Thu, 9 May 2019 11:08:36 -0400 Subject: [PATCH 22/23] Create mini-asm.md --- mini-asm.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 mini-asm.md diff --git a/mini-asm.md b/mini-asm.md new file mode 100644 index 0000000..1b5e953 --- /dev/null +++ b/mini-asm.md @@ -0,0 +1,43 @@ +GS+ Pro Extreme Max HD Performance Edition includes a sweet-16 mini assembler as well as a 65816 mini assembler. + +## Sweet-16 +From the Debug shell, enter `!!` to enter the sweet-16 mini asembler. + +Enter `^D` or a blank line to exit back to the debug shell. + +Lines consist of an optional address, an opcode, and operands. + +All numbers are hexadecimal. +The `*` operand is the current address/PC. +/- offsets may also be applied. + +Registers are named `R0`-`R15` (decimal). `ACC`, `PC` and `SR` aliases are also valid for `R0`, `R15`, and `R14`, respectively. + +### Examples + +0300: set R1, #0300 + ld @R1 + br *-3 + +## 65816 +From the Debug shell, enter `!` to enter the sweet-16 mini asembler. + +Enter `^D` or a blank line to exit back to the debug shell. + +Lines consist of an optional address, an opcode, and operands. + +All numbers are hexadecimal. +The `*` operand is the current address/PC. +/- offsets may also be applied. + +The M/X bits are automatically set via `REP`/`SEP` instructions. Additionally, the `long` and `short` directives +may be used to set them explicitly. + + long mx + short m + +Toolbox, GS/OS, ProDOS-16, and P8 MLI macros are auto generated from the NiftyList.Data file. + + _NewHandle + _OpenGS 123456 + + + From e8d6d17a1a320d4b70a52a8a17135b2e6418346a Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 2 Jun 2019 13:32:21 -0400 Subject: [PATCH 23/23] debugger - implement nifty list t command to lookup toolcall information. example: ] 0101t 0001 (04408e) TLBootInit() --- src/debug_shell.re2c | 66 +++++++++++++++++++++++++++++++++++++---- src/debug_template.re2c | 20 +++++++++---- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/debug_shell.re2c b/src/debug_shell.re2c index ac24bfd..1507225 100644 --- a/src/debug_shell.re2c +++ b/src/debug_shell.re2c @@ -50,7 +50,7 @@ static int g_templates_loaded = 0; extern void debug_load_templates(const char *path); extern word32 debug_apply_template(word32 address, const char *name); extern void debug_load_nifty(const char *path); -extern const char *debug_tool_name(unsigned, unsigned vector); +extern const char *debug_tool_name(unsigned number, unsigned vector, unsigned full); @@ -240,6 +240,57 @@ static void do_handle(word32 value, int action) { } +word32 tool_lookup(unsigned tool) { + enum { + TPtr = 0xe103c0, + UTPtr = 0xe103c4, + }; + + unsigned tn = tool & 0xff; + unsigned ix = (tool >> 8) & 0xff; + word32 ptr; + word32 count; + + ptr = get_memory32_c(TPtr, 0); + if (ptr == 0 || ptr > 0xffffff) return 0; + + count = get_memory32_c(ptr, 0); + if (count == 0 || count > 255 || count < tn) return 0; + ptr = get_memory32_c(ptr + tn * 4, 0); + if (ptr == 0 || ptr > 0xffffff) return 0; + + count = get_memory32_c(ptr, 0); + if (count == 0 || count > 255) return 0; + if (ix && ix > count) return 0; + + /* if ix == 0, list all tool calls in the set */ + /* otherwise, just the specific tool call */ + + /* todo -- also lookup tool name */ + word32 addr = 0; + const char *cp; + if (ix) { + unsigned n = tn + (ix << 8); + addr = get_memory24_c(ptr + ix * 4, 0); + if (addr) ++addr; + cp = debug_tool_name(n, 0xe10000, 1); + if (!cp) cp = "---unknown---"; + printf("%04x (%06x) %s\n", n, addr, cp); + } else { + for(ix = 1; ix < count; ++ix) { + unsigned n = tn + (ix << 8); + + addr = get_memory24_c(ptr + ix * 4, 0); + if (addr) ++addr; + cp = debug_tool_name(n, 0xe10000, 1); + if (!cp) cp = "---unknown---"; + printf("%04x (%06x) %s\n", n, addr, cp); + } + } + + return addr; +} + word32 do_hexdump(word32 address, int lines) { static char hex[] = "0123456789abcdef"; @@ -624,7 +675,7 @@ word32 do_list(word32 address, int lines) { if (!comment) { bank = pc >> 16; if (bank == 0xe0 || bank == 0xe1 || bank == 0x01 || bank == 0xff) - comment = debug_tool_name(pc & 0xffff, bank); + comment = debug_tool_name(pc & 0xffff, bank, 1); } switch (opcode) { @@ -640,7 +691,7 @@ word32 do_list(word32 address, int lines) { case 0xa2: /* ldx # */ if (is_jsl_e10000(address)) { /* tool call ... */ - const char *name = debug_tool_name(operand, 0xe10000); + const char *name = debug_tool_name(operand, 0xe10000, 0); if (name) { opcode_string = name; buffer[0] = 0; @@ -668,7 +719,7 @@ word32 do_list(word32 address, int lines) { if (operand == 0xe100a8) { /* inline GS/OS call? */ unsigned num = get_memory16_c(address, 0); - const char *name = debug_tool_name(num, operand); + const char *name = debug_tool_name(num, operand, 0); if (name) { comment = NULL; opcode_string = name; @@ -685,7 +736,7 @@ word32 do_list(word32 address, int lines) { ea = (operand | (address & 0xff0000)); if (ea == 0x00bf00) { unsigned num = get_memory_c(address, 0); - const char *name = debug_tool_name(num, operand); + const char *name = debug_tool_name(num, operand, 0); if (name) { opcode_string = name; unsigned parms = get_memory16_c(address + 1, 0); @@ -1666,6 +1717,11 @@ command: return 0; } + "t" { + g_prev_address = tool_lookup(addr & 0xffff); + return 0; + } + */ } diff --git a/src/debug_template.re2c b/src/debug_template.re2c index 80fb97d..569c248 100644 --- a/src/debug_template.re2c +++ b/src/debug_template.re2c @@ -401,6 +401,7 @@ word32 debug_apply_template(word32 address, const char *name) { struct tool { char *name; + char *fullname; unsigned number; unsigned vector; }; @@ -415,6 +416,7 @@ struct tool *tool_names = NULL; int tool_name_count = 0; + static void add_tool(struct tool *t) { if (tool_count == tool_alloc) { size_t size = (tool_alloc + 1024) * sizeof(struct tool); @@ -426,6 +428,7 @@ static void add_tool(struct tool *t) { tools[tool_count++] = *t; } + static word32 to_hex(const char *iter, const char *end) { word32 rv = 0; while(iter != end) { @@ -513,7 +516,7 @@ void debug_load_nifty(const char *path) { for (line = 1;;++line) { const char *start; const char *end; - struct tool tool = { 0, 0, vector }; + struct tool tool = { 0, 0, 0, vector }; const char *cp = fgets(buffer, sizeof(buffer), f); if (!cp) break; @@ -566,12 +569,15 @@ prefix: if (end > start) { int l = end - start; + + tool.fullname = NULL; if (vector > 0x0100) { /* add a leading _ */ tool.name = malloc(l + 2); tool.name[0] = '_'; strncpy(tool.name + 1, start, l); tool.name[l + 1] = 0; + tool.fullname = strdup(start); } else tool.name = strndup(start, l); add_tool(&tool); @@ -606,14 +612,15 @@ prefix: qsort(tool_names, tool_name_count, sizeof(struct tool), tool_name_compare); } -const char *debug_tool_name(unsigned number, unsigned vector) { +const char *debug_tool_name(unsigned number, unsigned vector, unsigned full) { if (!tool_count) return NULL; - struct tool tmp = { 0, number, vector }; + struct tool tmp = { 0, 0, number, vector }; struct tool *t = bsearch(&tmp, tools, tool_count, sizeof(struct tool), tool_compare); - if (t) return t->name; - return NULL; + if (!t) return NULL; + if (full && t->fullname) return t->fullname; + return t->name; } @@ -621,9 +628,10 @@ int lookup_tool_number(const char *name, unsigned vector) { if (!tool_name_count) return 0; - struct tool tmp = { (char *)name, 0, vector}; + struct tool tmp = { (char *)name, 0, 0, vector}; struct tool *t = bsearch(&tmp, tool_names, tool_name_count, sizeof(struct tool), tool_name_compare); if (!t) return 0; return t->number; } +