From 739758781030f107f260f587a4f9c1e8bdf70f58 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Sat, 8 Jun 2024 13:12:23 -0400 Subject: dumpbas: clean up code, work on doc. --- dumpbas.c | 160 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 99 insertions(+), 61 deletions(-) (limited to 'dumpbas.c') diff --git a/dumpbas.c b/dumpbas.c index b7607ea..2888b52 100644 --- a/dumpbas.c +++ b/dumpbas.c @@ -77,10 +77,58 @@ void print_atascii(unsigned char c) { putchar('/'); } +/* REM, DATA, ERROR lines are terminated by $9B, a real EOL, not + the BASIC token. Since they're strings, print them in ASCII too. */ +int handle_text_stmt(int pos) { + unsigned char c; + + do { + c = program[pos]; + print_atascii(c); + printf("%02x ", c); + pos++; + } while(c != 0x9b); + + return pos; +} + +int handle_cmd(int pos) { + unsigned char tok = program[pos]; + + printf("!%02x ", tok); + switch(tok) { + case CMD_REM: + case CMD_DATA: + case CMD_ERROR: + return handle_text_stmt(pos + 1); + default: + return pos + 1; + } +} + +void handle_string(int pos) { + int i, len; + len = program[pos + 1]; + printf("$%02x =%02x \"", program[pos], len); + for(i = pos; i < pos + len; i++) { + unsigned char c = program[i + 2]; + print_atascii(c); + printf("%02x%c", c, (i == (pos + len - 1) ? '"' : ' ')); + } + putchar(' '); +} + +void handle_num(int pos) { + int i; + printf("#%02x [", program[pos]); + for(i = 0; i < 6; i++) + printf("%02x%c", program[pos + 1 + i], (i == 5 ? ']' : ' ')); + putchar(' '); +} + /* sorry, this is horrid, more like assembly than C. */ int main(int argc, char **argv) { - int pos, nextpos, offset, soffset, lineno, cmd, i, end; - int numcount = 0, start_string = 0, end_string = 0; + int linepos, nextpos, offset, soffset, lineno, pos, end, tok; set_self(*argv); parse_general_args(argc, argv, print_help); @@ -89,71 +137,61 @@ int main(int argc, char **argv) { readfile(); parse_header(); - pos = codestart; - while(pos < filelen) { - lineno = getword(pos); - offset = program[pos + 2]; - nextpos = pos + offset; - - if(lineno >= startlineno) { - printf("%5d@%04x (%02x %02x): ^%02x ", lineno, pos, program[pos], program[pos + 1], offset); - - i = pos + 3; - while(i < nextpos) { - soffset = program[i]; - end = pos + soffset; - while(i < end) { - printf("\n >%02x ", program[i]); /* offset */ - i++; - cmd = 1; - while(i < end) { - if(cmd) { - putchar('!'); - } else if(program[i] == 0x0e && program[i - 1] != 0x0f && (i < start_string || i > end_string)) { - putchar('#'); - numcount = 7; - } else if(program[i] == 0x0f) { - putchar('$'); - start_string = i + 2; - end_string = start_string + program[i + 1]; - } - - if(numcount == 6) - putchar('['); - - if(i == start_string) - putchar('"'); - - if(i == (start_string - 1)) - putchar('='); - - if(i >= start_string && i < end_string) - print_atascii(program[i]); - - printf("%02x", program[i]); - if(i == (end - 1) && program[i] == 0x14) - putchar(':'); - - if(numcount) { - if(--numcount == 0) - putchar(']'); - } - - i++; - if(i == end_string) - putchar('"'); - - putchar(' '); - cmd = 0; + linepos = codestart; + while(linepos < filelen) { /* loop over lines */ + lineno = getword(linepos); + offset = program[linepos + 2]; + nextpos = linepos + offset; + + if(offset < 6) + die("Can't dump a protected program, unprotect it first."); + + if(lineno < startlineno) { + linepos = nextpos; + continue; + } + + /* line header */ + printf("%5d@%04x (%02x %02x): ^%02x ", + lineno, linepos, program[linepos], program[linepos + 1], offset); + + pos = linepos + 3; + while(pos < nextpos) { /* loop over statements within a line */ + soffset = program[pos]; + end = linepos + soffset; + + while(pos < end) { /* loop over tokens within a statement */ + printf("\n >%02x ", program[pos++]); /* offset */ + pos = handle_cmd(pos++); /* 1st token is the command */ + + while(pos < end) { /* loop over operators */ + tok = program[pos]; + switch(tok) { + case OP_NUMCONST: + handle_num(pos); + pos += 7; + break; + case OP_STRCONST: + handle_string(pos); + pos += program[pos + 1] + 2; + break; + default: + printf("%02x", program[pos]); + if(pos == (end - 1) && tok == OP_EOS) + putchar(':'); + else + putchar(' '); + pos++; + break; } } } - - putchar('\n'); } + putchar('\n'); + if(lineno == endlineno) break; - pos = nextpos; + linepos = nextpos; } return 0; -- cgit v1.2.3