aboutsummaryrefslogtreecommitdiff
path: root/dumpbas.c
diff options
context:
space:
mode:
Diffstat (limited to 'dumpbas.c')
-rw-r--r--dumpbas.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/dumpbas.c b/dumpbas.c
new file mode 100644
index 0000000..b7607ea
--- /dev/null
+++ b/dumpbas.c
@@ -0,0 +1,160 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "bas.h"
+
+int startlineno = 0;
+int endlineno = 32768;
+
+/* dump tokens for each line in a BASIC program. easier to read than
+ a plain hex dump. */
+void print_help(void) {
+ fprintf(stderr, "Usage: %s [-v] [-s start-lineno] [-e end-lineno] <inputfile>\n", self);
+}
+
+unsigned short getlineno(char opt, const char *arg) {
+ int lineno;
+ char *e;
+
+ lineno = (int)strtol(arg, &e, 10);
+
+ if(*e) {
+ fprintf(stderr, "%s: Invalid line number for -%c option: %s is not a number.\n",
+ self, opt, arg);
+ exit(1);
+ }
+
+ if(lineno < 0 || lineno > 32767) {
+ fprintf(stderr, "%s: Invalid line number for -%c option: %d > 32767.\n",
+ self, opt, lineno);
+ exit(1);
+ }
+
+ return ((unsigned short)lineno);
+}
+
+void parse_args(int argc, char **argv) {
+ int opt;
+
+ while( (opt = getopt(argc, argv, "vs:e:l:")) != -1) {
+ switch(opt) {
+ case 'v': verbose = 1; break;
+ case 's': startlineno = getlineno(opt, optarg); break;
+ case 'e': endlineno = getlineno(opt, optarg); break;
+ case 'l': startlineno = getlineno(opt, optarg);
+ endlineno = startlineno; break;
+ default:
+ print_help();
+ exit(1);
+ }
+ }
+
+ if(optind >= argc)
+ die("No input file given (use - for stdin).");
+ else
+ open_input(argv[optind]);
+}
+
+void print_atascii(unsigned char c) {
+ if(c & 0x80) {
+ putchar('|');
+ c &= 0x7f;
+ }
+
+ if(c < 32) {
+ putchar('^');
+ c += 0x40;
+ }
+
+ if(c == 0x7f)
+ printf("del");
+ else
+ putchar(c);
+ 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;
+
+ set_self(*argv);
+ parse_general_args(argc, argv, print_help);
+ parse_args(argc, 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;
+ }
+ }
+ }
+
+ putchar('\n');
+ }
+
+ if(lineno == endlineno) break;
+ pos = nextpos;
+ }
+
+ return 0;
+}