aboutsummaryrefslogtreecommitdiff
path: root/dumpbas.c
diff options
context:
space:
mode:
Diffstat (limited to 'dumpbas.c')
-rw-r--r--dumpbas.c160
1 files changed, 99 insertions, 61 deletions
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;