From 028b2a57446789fe7bafb8ab678c1f0f43b34645 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Fri, 7 Jun 2024 04:47:04 -0400 Subject: dumpbas: added. --- dumpbas.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 dumpbas.c (limited to 'dumpbas.c') 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 +#include +#include +#include +#include +#include + +#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] \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; +} -- cgit v1.2.3