aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--listbas.c171
-rw-r--r--tokens.c135
-rw-r--r--tokens.h4
4 files changed, 314 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 8847086..c3cd9ee 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ CC=gcc
CFLAGS=-Wall $(COPT) -ansi -D_GNU_SOURCE -DVERSION=\"$(VERSION)\"
# BINS and SCRIPTS go in $BINDIR, DOCS go in $DOCDIR
-BINS=a8eol atr2xfd atrsize axe blob2c blob2xex cart2xex cxrefbas dumpbas fenders protbas renumbas rom2cart unmac65 unprotbas vxrefbas xex1to2 xexamine xexcat xexsplit xfd2atr
+BINS=a8eol atr2xfd atrsize axe blob2c blob2xex cart2xex cxrefbas dumpbas fenders protbas renumbas rom2cart unmac65 unprotbas vxrefbas xex1to2 xexamine xexcat xexsplit xfd2atr listbas
SCRIPTS=dasm2atasm a8utf8
MANS=a8eol.1 xfd2atr.1 atr2xfd.1 blob2c.1 cart2xex.1 fenders.1 xexsplit.1 xexcat.1 atrsize.1 rom2cart.1 unmac65.1 axe.1 dasm2atasm.1 a8utf8.1 blob2xex.1 xexamine.1 xex1to2.1 unprotbas.1 protbas.1 renumbas.1 dumpbas.1 vxrefbas.1 cxrefbas.1
MAN5S=xex.5
@@ -61,6 +61,9 @@ vxrefbas: bas.o
cxrefbas: bas.o bcdfp.o linetab.o
+listbas: listbas.c bas.o bcdfp.o tokens.o
+ $(CC) $(CFLAGS) -o listbas listbas.c bas.o bcdfp.o tokens.o -lm
+
bas.o: bas.c bas.h
subdirs:
diff --git a/listbas.c b/listbas.c
new file mode 100644
index 0000000..6469009
--- /dev/null
+++ b/listbas.c
@@ -0,0 +1,171 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <math.h>
+
+#include "bas.h"
+#include "bcdfp.h"
+#include "tokens.h"
+
+int immediate = 0;
+
+void print_help(void) {
+ printf("Usage: %s [-v] [-i] <inputfile>\n", self);
+}
+
+void parse_args(int argc, char **argv) {
+ int opt;
+
+ while( (opt = getopt(argc, argv, "vi")) != -1) {
+ switch(opt) {
+ case 'v': verbose = 1; break;
+ case 'i': immediate = 1; break;
+ default:
+ print_help();
+ exit(1);
+ }
+ }
+
+ if(optind >= argc)
+ die("No input file given (use - for stdin).");
+ else
+ open_input(argv[optind]);
+}
+
+double bcd2double(const unsigned char *num) {
+ double result = 0, sign;
+ int exp, i;
+
+ exp = *num;
+ if(!exp) {
+ return 0.0;
+ }
+
+ sign = (exp & 0x80 ? -1.0 : 1.0);
+ exp &= 0x7f;
+ exp -= 0x40;
+
+ for(i = 1; i < 6; i++) {
+ result *= 100.0;
+ result += bcd2int(num[i]);
+ }
+
+ result *= pow(100, exp - 4);
+ result *= sign;
+
+ return result;
+}
+
+void print_number(unsigned int pos) {
+ printf("%G", bcd2double(program + pos));
+}
+
+void print_string(unsigned int pos, unsigned int len) {
+ putchar('"');
+ while(len--) putchar(program[pos++]);
+ putchar('"');
+}
+
+CALLBACK(print_lineno) {
+ printf("%d ", lineno);
+}
+
+CALLBACK(print_cmd) {
+ int bad;
+ const char *name;
+
+ if(tok == CMD_ILET) return;
+
+ if(tok > last_command) {
+ bad = 1;
+ } else if( (name = commands[tok]) ) {
+ bad = 0;
+ } else {
+ bad = 1;
+ }
+
+ if(bad)
+ printf("(bad cmd token $%02x)", tok);
+ else
+ printf("%s ", name);
+}
+
+CALLBACK(print_op) {
+ int bad;
+ const char *name;
+
+ switch(tok) {
+ case OP_NUMCONST:
+ print_number(pos + 1);
+ return;
+ case OP_STRCONST:
+ print_string(pos + 2, program[pos + 1]);
+ return;
+ case OP_EOL:
+ return;
+ default: break;
+ }
+
+
+ if(tok > last_operator) {
+ bad = 1;
+ } else if( (name = operators[tok]) ) {
+ bad = 0;
+ } else {
+ bad = 1;
+ }
+
+ if(bad)
+ printf("(bad op token $%02x)", tok);
+ else
+ printf("%s", name);
+}
+
+CALLBACK(print_varname) {
+ int i, count;
+ unsigned char c;
+
+ tok &= 0x7f;
+ for(i = vnstart, count = 0; count < tok; i++) {
+ if(program[i] & 0x80) count++;
+ }
+ while(1) {
+ c = program[i++];
+ putchar(c & 0x7f);
+ if(c & 0x80) break;
+ }
+}
+
+CALLBACK(print_text) {
+ while(program[pos] != 0x9b) putchar(program[pos++]);
+}
+
+CALLBACK(print_newline) {
+ putchar('\n');
+}
+
+void list(void) {
+ on_start_line = print_lineno;
+ on_cmd_token = print_cmd;
+ on_exp_token = print_op;
+ on_var_token = print_varname;
+ on_end_line = print_newline;
+ on_text = print_text;
+ walk_code(0, 32767 + immediate);
+}
+
+int main(int argc, char **argv) {
+ set_self(*argv);
+ parse_general_args(argc, argv, print_help);
+ parse_args(argc, argv);
+
+ readfile();
+ parse_header();
+
+ list();
+
+ return 0;
+}
diff --git a/tokens.c b/tokens.c
new file mode 100644
index 0000000..08cf48a
--- /dev/null
+++ b/tokens.c
@@ -0,0 +1,135 @@
+const char *commands[] = {
+ "REM",
+ "DATA",
+ "INPUT",
+ "COLOR",
+ "LIST",
+ "ENTER",
+ "LET",
+ "IF",
+ "FOR",
+ "NEXT",
+ "GOTO",
+ "GO TO",
+ "GOSUB",
+ "TRAP",
+ "BYE",
+ "CONT",
+ "COM",
+ "CLOSE",
+ "CLR",
+ "DEG",
+ "DIM",
+ "END",
+ "NEW",
+ "OPEN",
+ "LOAD",
+ "SAVE",
+ "STATUS",
+ "NOTE",
+ "POINT",
+ "XIO",
+ "ON",
+ "POKE",
+ "PRINT",
+ "RAD",
+ "READ",
+ "RESTORE",
+ "RETURN",
+ "RUN",
+ "STOP",
+ "POP",
+ "?",
+ "GET",
+ "PUT",
+ "GRAPHICS",
+ "PLOT",
+ "POSITION",
+ "DOS",
+ "DRAWTO",
+ "SETCOLOR",
+ "LOCATE",
+ "SOUND",
+ "LPRINT",
+ "CSAVE",
+ "CLOAD",
+ "", /* implied LET */
+ "ERROR -"
+};
+
+const unsigned short last_command = (sizeof(commands) / sizeof(char *)) - 1;
+
+const char *operators[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+ ",",
+ "$",
+ ":",
+ ";",
+ "", /* $16, EOL */
+ " GOTO ",
+ " GOSUB ", /* $18 */
+ " TO ",
+ " STEP ",
+ " THEN ",
+ "#",
+ "<=",
+ "<>",
+ ">=",
+ "<", /* $20 */
+ ">",
+ "=",
+ "^",
+ "*",
+ "+",
+ "-",
+ "/",
+ " NOT ", /* $28 */
+ " OR ",
+ " AND ",
+ "(",
+ ")",
+ "=",
+ "=",
+ "<=",
+ "<>", /* $30 */
+ ">=",
+ "<",
+ ">",
+ "=",
+ "+",
+ "-",
+ "(",
+ "", /* $38, redunant for arrays */
+ "", /* $39, ditto */
+ "(",
+ "(",
+ ",",
+ "STR$",
+ "CHR$",
+ "USR",
+ "ASC", /* $40 */
+ "VAL",
+ "LEN",
+ "ADR",
+ "ATN",
+ "COS",
+ "PEEK",
+ "SIN",
+ "RND", /* $48 */
+ "FRE",
+ "EXP",
+ "LOG",
+ "CLOG",
+ "SQR",
+ "SGN",
+ "ABS",
+ "INT", /* $50 */
+ "PADDLE",
+ "STICK",
+ "PTRIG",
+ "STRIG" /* $54 */
+};
+
+const unsigned short last_operator = (sizeof(operators) / sizeof(char *)) - 1;
diff --git a/tokens.h b/tokens.h
new file mode 100644
index 0000000..265122e
--- /dev/null
+++ b/tokens.h
@@ -0,0 +1,4 @@
+extern const char *commands[];
+extern const char *operators[];
+extern const unsigned short last_command;
+extern const unsigned short last_operator;