From 9d1ce7321f27d47b76cba907127af777d6672188 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 13 Jun 2024 15:30:33 -0400 Subject: major surgery: callback API, port dumpbas to use callbacks, add vxrefbas. --- Makefile | 6 ++-- a8eol.1 | 3 +- a8utf8.1 | 3 +- atascii.7 | 3 +- atr2xfd.1 | 3 +- atrsize.1 | 3 +- axe.1 | 3 +- bas.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++- bas.h | 24 +++++++++++++ blob2c.1 | 3 +- blob2xex.1 | 3 +- cart2xex.1 | 3 +- dasm2atasm.1 | 3 +- dumpbas.1 | 3 +- dumpbas.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fenders.1 | 3 +- manftr.rst | 1 + rom2cart.1 | 3 +- unmac65.1 | 3 +- unprotbas.1 | 3 +- vxrefbas.1 | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vxrefbas.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ vxrefbas.rst | 57 ++++++++++++++++++++++++++++++ xex.5 | 3 +- xex1to2.1 | 3 +- xexamine.1 | 3 +- xexcat.1 | 3 +- xexsplit.1 | 3 +- xfd2atr.1 | 3 +- 29 files changed, 552 insertions(+), 24 deletions(-) create mode 100644 vxrefbas.1 create mode 100644 vxrefbas.c create mode 100644 vxrefbas.rst diff --git a/Makefile b/Makefile index e5f86f9..8bd3ebf 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,9 @@ 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 dumpbas fenders protbas renumbas rom2cart unmac65 unprotbas xex1to2 xexamine xexcat xexsplit xfd2atr +BINS=a8eol atr2xfd atrsize axe blob2c blob2xex cart2xex dumpbas fenders protbas renumbas rom2cart unmac65 unprotbas vxrefbas xex1to2 xexamine xexcat xexsplit xfd2atr 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 +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 MAN5S=xex.5 MAN7S=atascii.7 DOCS=README.txt equates.inc *.dasm LICENSE ksiders/atr.txt @@ -57,6 +57,8 @@ renumbas: bas.o dumpbas: bas.o +vxrefbas: bas.o + bas.o: bas.c bas.h subdirs: diff --git a/a8eol.1 b/a8eol.1 index 5aca5dc..a68ed2b 100644 --- a/a8eol.1 +++ b/a8eol.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "A8EOL" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "A8EOL" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME a8eol \- convert Atari 8-bit text files to/from UNIX/Windows/Mac .\" RST source for a8eol(1) man page. Convert with: @@ -478,6 +478,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/a8utf8.1 b/a8utf8.1 index 6e57a98..ada18ea 100644 --- a/a8utf8.1 +++ b/a8utf8.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "A8UTF8" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "A8UTF8" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME a8utf8 \- Convert Atari 8-bit text to UTF-8 encoded Unicode. .\" RST source for a8utf8(1) man page. Convert with: @@ -109,6 +109,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/atascii.7 b/atascii.7 index bda5be6..7032d78 100644 --- a/atascii.7 +++ b/atascii.7 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "ATASCII" 7 "2024-06-09" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "ATASCII" 7 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME atascii \- Atari 8-bit character set .\" RST source for atascii(7) man page. Convert with: @@ -2167,6 +2167,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/atr2xfd.1 b/atr2xfd.1 index ad6e217..e4a91e9 100644 --- a/atr2xfd.1 +++ b/atr2xfd.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "ATR2XFD" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "ATR2XFD" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME atr2xfd \- Convert an Atari 8-bit ATR disk image to a raw (XFD) image .\" RST source for atr2xfd(1) man page. Convert with: @@ -198,6 +198,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/atrsize.1 b/atrsize.1 index 04b5b55..f87edce 100644 --- a/atrsize.1 +++ b/atrsize.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "ATRSIZE" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "ATRSIZE" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME atrsize \- Change the size of an Atari 8-bit ATR disk image, or create a blank ATR image .\" RST source for atrsize(1) man page. Convert with: @@ -212,6 +212,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/axe.1 b/axe.1 index 4504c96..c0b658d 100644 --- a/axe.1 +++ b/axe.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "AXE" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "AXE" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME axe \- ATR/XFD Editor .\" RST source for axe(1) man page. Convert with: @@ -153,6 +153,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/bas.c b/bas.c index e90d96c..fc5517b 100644 --- a/bas.c +++ b/bas.c @@ -155,6 +155,10 @@ void adjust_vntable_size(int oldsize, int newsize) { } } +unsigned char get_vartype(unsigned char tok) { + return program[vvstart + (tok & 0x7f) * 8] >> 6; +} + /* return true if the variable name table is OK */ int vntable_ok(void) { int vp, bad; @@ -249,10 +253,109 @@ void open_output(const char *name) { output_file = open_file(name, "wb"); } -extern void set_self(const char *argv0) { +void set_self(const char *argv0) { char *p; self = argv0; p = strrchr(self, '/'); if(p) self = p + 1; } + +/* callbacks */ +CALLBACK_PTR(on_start_line); +CALLBACK_PTR(on_bad_line_length); +CALLBACK_PTR(on_end_line); +CALLBACK_PTR(on_start_stmt); +CALLBACK_PTR(on_end_stmt); +CALLBACK_PTR(on_cmd_token); +CALLBACK_PTR(on_text); +CALLBACK_PTR(on_exp_token); +CALLBACK_PTR(on_var_token); +CALLBACK_PTR(on_string_const); +CALLBACK_PTR(on_num_const); + +#define CALL(x) if(x) (*x)(lineno, pos, program[pos], end) + +void walk_code(unsigned int startlineno, unsigned int endlineno) { + int linepos, nextpos, offset, soffset, lineno, pos, end, tok; + + linepos = codestart; + while(linepos < filelen) { /* loop over lines */ + lineno = getword(linepos); + offset = program[linepos + 2]; + nextpos = linepos + offset; + + end = nextpos; + pos = linepos; + + if(offset < 6) { + CALL(on_bad_line_length); + offset = program[linepos + 2]; /* on_bad_line_length fixed it (we hope) */ + if(offset < 6) + die("Program is code-protected; unprotect it first."); + } + + if(lineno < startlineno) { + linepos = nextpos; + continue; + } + + CALL(on_start_line); + + pos = linepos + 3; + while(pos < nextpos) { /* loop over statements within a line */ + soffset = program[pos]; + end = linepos + soffset; + CALL(on_start_stmt); + + while(pos < end) { /* loop over tokens within a statement */ + pos++; + CALL(on_cmd_token); + switch(program[pos]) { + case CMD_REM: + case CMD_DATA: + case CMD_ERROR: + pos++; + CALL(on_text); + pos = end; + break; + default: + pos++; + break; + } + + while(pos < end) { /* loop over operators */ + tok = program[pos]; + switch(tok) { + case OP_NUMCONST: + CALL(on_exp_token); + pos++; + CALL(on_num_const); + pos += 6; + break; + case OP_STRCONST: + CALL(on_exp_token); + pos++; + CALL(on_string_const); + pos += program[pos] + 1; + break; + default: + if(tok & 0x80) { + CALL(on_var_token); + } else { + CALL(on_exp_token); + } + pos++; + break; + } + } + CALL(on_end_stmt); + } + } + + CALL(on_end_line); + + if(lineno >= endlineno) break; + linepos = nextpos; + } +} diff --git a/bas.h b/bas.h index 9d117cc..eb3f4e5 100644 --- a/bas.h +++ b/bas.h @@ -42,6 +42,10 @@ #define CMD_REM 0x00 #define CMD_DATA 0x01 #define CMD_ERROR 0x37 +#define CMD_FOR 0x08 +#define CMD_NEXT 0x09 +#define CMD_LET 0x06 +#define CMD_ILET 0x36 #define OP_GOTO 0x17 #define OP_GOSUB 0x18 #define OP_THEN 0x1b @@ -56,6 +60,26 @@ #define TYPE_ARRAY 1 #define TYPE_STRING 2 +/* callbacks */ +#define CALLBACK(x) void x(unsigned int lineno, unsigned int pos, unsigned int tok, unsigned int end) +#define CALLBACK_PTR(x) void (*x)(unsigned int lineno, unsigned int pos, unsigned int tok, unsigned int end) +#define walk_all_code() walk_code(0, 32768) + +void walk_code(unsigned int startlineno, unsigned int endlineno); +unsigned char get_vartype(unsigned char tok); + +extern CALLBACK_PTR(on_start_line); +extern CALLBACK_PTR(on_bad_line_length); +extern CALLBACK_PTR(on_end_line); +extern CALLBACK_PTR(on_start_stmt); +extern CALLBACK_PTR(on_end_stmt); +extern CALLBACK_PTR(on_cmd_token); +extern CALLBACK_PTR(on_text); +extern CALLBACK_PTR(on_exp_token); +extern CALLBACK_PTR(on_var_token); +extern CALLBACK_PTR(on_string_const); +extern CALLBACK_PTR(on_num_const); + /* BASIC 14-byte header values */ extern unsigned short lomem; extern unsigned short vntp; diff --git a/blob2c.1 b/blob2c.1 index 97ef227..fefda0e 100644 --- a/blob2c.1 +++ b/blob2c.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "BLOB2C" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "BLOB2C" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME blob2c \- Create C source and header files from a binary file .\" RST source for blob2c(1) man page. Convert with: @@ -133,6 +133,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/blob2xex.1 b/blob2xex.1 index 4524cd4..4a37c3b 100644 --- a/blob2xex.1 +++ b/blob2xex.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "BLOB2XEX" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "BLOB2XEX" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME blob2xex \- Create Atari 8-bit executables from arbitrary data .\" RST source for blob2xex(1) man page. Convert with: @@ -224,6 +224,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/cart2xex.1 b/cart2xex.1 index adadec1..c20e98f 100644 --- a/cart2xex.1 +++ b/cart2xex.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "CART2XEX" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "CART2XEX" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME cart2xex \- Convert an Atari 8-bit ROM cartridge image to a binary load file .\" RST source for cart2xex(1) man page. Convert with: @@ -243,6 +243,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/dasm2atasm.1 b/dasm2atasm.1 index e51c1f5..f37187a 100644 --- a/dasm2atasm.1 +++ b/dasm2atasm.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "DASM2ATASM" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "DASM2ATASM" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME dasm2atasm \- Convert 6502 assembly source from dasm syntax to atasm or ca65 syntax. .\" RST source for dasm2atasm(1) man page. Convert with: @@ -240,6 +240,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/dumpbas.1 b/dumpbas.1 index 5735023..f2fa471 100644 --- a/dumpbas.1 +++ b/dumpbas.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "DUMPBAS" 1 "2024-06-09" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "DUMPBAS" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME dumpbas \- Formatted hexdump for tokenized Atari 8-bit BASIC files .SH SYNOPSIS @@ -221,6 +221,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/dumpbas.c b/dumpbas.c index 2888b52..d5404d2 100644 --- a/dumpbas.c +++ b/dumpbas.c @@ -79,6 +79,7 @@ void print_atascii(unsigned char c) { /* 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; @@ -91,7 +92,24 @@ int handle_text_stmt(int pos) { return pos; } +*/ +CALLBACK(handle_text) { + unsigned char c; + + do { + c = program[pos]; + print_atascii(c); + printf("%02x ", c); + pos++; + } while(c != 0x9b); +} + +CALLBACK(handle_cmd) { + printf("!%02x ", tok); +} + +/* int handle_cmd(int pos) { unsigned char tok = program[pos]; @@ -105,7 +123,9 @@ int handle_cmd(int pos) { return pos + 1; } } +*/ +/* void handle_string(int pos) { int i, len; len = program[pos + 1]; @@ -117,7 +137,9 @@ void handle_string(int pos) { } putchar(' '); } +*/ +/* void handle_num(int pos) { int i; printf("#%02x [", program[pos]); @@ -125,8 +147,97 @@ void handle_num(int pos) { printf("%02x%c", program[pos + 1 + i], (i == 5 ? ']' : ' ')); putchar(' '); } +*/ + +CALLBACK(handle_op) { + switch(tok) { + case OP_EOS: + printf("%02x:", tok); + return; + case OP_NUMCONST: + putchar('#'); break; + case OP_STRCONST: + putchar('$'); break; + default: break; + } + printf("%02x ", tok); +} + +CALLBACK(handle_var) { + printf("%02x", tok); + switch(get_vartype(tok)) { + case TYPE_ARRAY: + putchar('('); break; + case TYPE_STRING: + putchar('$'); break; + default: break; + } + putchar(' '); +} + +CALLBACK(handle_string) { + int i, len; + len = program[pos]; + printf("=%02x \"", len); + for(i = pos; i < pos + len; i++) { + unsigned char c = program[i + 1]; + print_atascii(c); + printf("%02x%c", c, (i == (pos + len - 1) ? '"' : ' ')); + } + putchar(' '); +} + +CALLBACK(handle_num) { + int i; + putchar('['); + for(i = 0; i < 6; i++) + printf("%02x%c", program[pos + i], (i == 5 ? ']' : ' ')); + putchar(' '); +} + +CALLBACK(handle_start_line) { + printf("%5d @%04x (%02x %02x): ^%02x\n", + lineno, pos, program[pos], program[pos + 1], program[pos + 2]); +} + +CALLBACK(handle_end_line) { + putchar('\n'); +} + +CALLBACK(handle_start_stmt) { + printf(" >%02x ", tok); +} + +CALLBACK(handle_end_stmt) { + putchar('\n'); +} + +int main(int argc, char **argv) { + set_self(*argv); + parse_general_args(argc, argv, print_help); + parse_args(argc, argv); + + readfile(); + parse_header(); + + on_start_line = handle_start_line; + on_end_line = handle_end_line; + on_start_stmt = handle_start_stmt; + on_end_stmt = handle_end_stmt; + on_exp_token = handle_op; + on_cmd_token = handle_cmd; + on_num_const = handle_num; + on_string_const = handle_string; + on_text = handle_text; + on_var_token = handle_var; + + walk_code(startlineno, endlineno); + + return 0; +} /* sorry, this is horrid, more like assembly than C. */ +#if 0 int main(int argc, char **argv) { int linepos, nextpos, offset, soffset, lineno, pos, end, tok; @@ -196,3 +307,4 @@ int main(int argc, char **argv) { return 0; } +#endif diff --git a/fenders.1 b/fenders.1 index a733a31..44998ff 100644 --- a/fenders.1 +++ b/fenders.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "FENDERS" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "FENDERS" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME fenders \- Install Fenders 3-sector loader in boot sectors of an ATR image .\" RST source for fenders(1) man page. Convert with: @@ -287,6 +287,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/manftr.rst b/manftr.rst index 3f4ca62..ac50295 100644 --- a/manftr.rst +++ b/manftr.rst @@ -28,6 +28,7 @@ SEE ALSO **rom2cart**\(1), **unmac65**\(1), **unprotbas**\(1), +**vxrefbas**\(1), **xexamine**\(1), **xexcat**\(1), **xexsplit**\(1), diff --git a/rom2cart.1 b/rom2cart.1 index f02c593..83a3654 100644 --- a/rom2cart.1 +++ b/rom2cart.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "ROM2CART" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "ROM2CART" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME rom2cart \- Convert a raw ROM image to an Atari800 CART image, or vice versa .\" RST source for rom2cart(1) man page. Convert with: @@ -256,6 +256,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/unmac65.1 b/unmac65.1 index 834e5b1..6694892 100644 --- a/unmac65.1 +++ b/unmac65.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "UNMAC65" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "UNMAC65" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME unmac65 \- Detokenize Atari 8-bit Mac/65 SAVEd files. .\" RST source for unmac65(1) man page. Convert with: @@ -388,6 +388,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/unprotbas.1 b/unprotbas.1 index c464b12..9f4c8c5 100644 --- a/unprotbas.1 +++ b/unprotbas.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "UNPROTBAS" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "UNPROTBAS" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME unprotbas \- Unprotect LIST-protected Atari 8-bit BASIC programs .SH SYNOPSIS @@ -355,6 +355,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/vxrefbas.1 b/vxrefbas.1 new file mode 100644 index 0000000..19d9d6f --- /dev/null +++ b/vxrefbas.1 @@ -0,0 +1,113 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "VXREFBAS" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" +.SH NAME +vxrefbas \- Variable cross-reference for tokenized Atari 8-bit BASIC files +.SH SYNOPSIS +.sp +vxrefbas \fBinput\-file\fP +.SH DESCRIPTION +.sp +\fBvxrefbas\fP reads an Atari 8\-bit BASIC tokenized program and prints +a list of variables, each with a list of line numbers where the +variable is referenced. +.sp +Variables that aren\(aqt used by the program are listed as \fI(no references)\fP\&. +.sp +Each line number may be followed by one or more markers, which show the +type of variable access. +.INDENT 0.0 +.TP +.B \fB=\fP +The variable is assigned on this line, with \fILET\fP or "implied LET" (e.g. +\fIA=1\fP). +.TP +.B \fB{\fP +The variable is used as the control variable of a \fIFOR\fP loop on this line. +.TP +.B \fB}\fP +The variable is used in a \fINEXT\fP on this line. +.UNINDENT +.SH OPTIONS +.SS General Options +.INDENT 0.0 +.TP +.B \fB\-\-help\fP +Print usage message and exit. +.TP +.B \fB\-\-version\fP +Print version number and exit. +.TP +.B \fB\-v\fP +Verbose operation. When displaying a number in verbose mode, it will +be prefixed with \fI$\fP if it\(aqs in hex, or no prefix for decimal. +.UNINDENT +.SH EXIT STATUS +.sp +0 for success, 1 for failure. +.SH COPYRIGHT +.sp +WTFPL. See \fI\%http://www.wtfpl.net/txt/copying/\fP for details. +.SH AUTHOR +.INDENT 0.0 +.IP B. 3 +Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\&. +.UNINDENT +.SH SEE ALSO +.sp +\fBa8eol\fP(1), +\fBa8utf8\fP(1), +\fBatr2xfd\fP(1), +\fBatrsize\fP(1), +\fBaxe\fP(1), +\fBblob2c\fP(1), +\fBblob2xex\fP(1), +\fBcart2xex\fP(1), +\fBdasm2atasm\fP(1), +\fBdumpbas\fP(1), +\fBf2toxex\fP(1), +\fBfenders\fP(1), +\fBprotbas\fP(1), +\fBrenumbas\fP(1), +\fBrom2cart\fP(1), +\fBunmac65\fP(1), +\fBunprotbas\fP(1), +\fBvxrefbas\fP(1), +\fBxexamine\fP(1), +\fBxexcat\fP(1), +\fBxexsplit\fP(1), +\fBxfd2atr\fP(1), +\fBxex\fP(5), +\fBatascii\fP(7). +.sp +Any good Atari 8\-bit book: \fIDe Re Atari\fP, \fIThe Atari BASIC Reference +Manual\fP, the \fIOS Users\(aq Guide\fP, \fIMapping the Atari\fP, etc. +.\" Generated by docutils manpage writer. +. diff --git a/vxrefbas.c b/vxrefbas.c new file mode 100644 index 0000000..839b776 --- /dev/null +++ b/vxrefbas.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include + +#include "bas.h" + +int target_var, lastline, assign, is_for, is_next; +int refcounts[128]; + +void print_help(void) { + fprintf(stderr, "Usage: %s program.bas\n", self); + exit(0); +} + +CALLBACK(new_line) { + assign = is_for = is_next = 0; +} + +CALLBACK(end_line) { + if(lastline != lineno) return; + printf("%d%s%s%s ", + lineno, + assign ? "=" : "", + is_for ? "{": "", + is_next ? "}": ""); +} + +CALLBACK(new_command) { + if(program[pos + 1] == (target_var | 0x80)) { + if(tok == CMD_LET || tok == CMD_ILET) { + assign = 1; + } else if(tok == CMD_FOR) { + is_for = 1; + } else if(tok == CMD_NEXT) { + is_next = 1; + } + } +} + +CALLBACK(handle_var) { + if(lastline == lineno) return; + if((tok & 0x7f) == target_var) { + refcounts[target_var]++; + lastline = lineno; + } +} + +int main(int argc, char **argv) { + unsigned short pos; + unsigned short vnpos; + int unref = 0; + + set_self(*argv); + parse_general_args(argc, argv, print_help); + + open_input(argv[1]); + + readfile(); + parse_header(); + + on_var_token = handle_var; + on_start_line = new_line; + on_end_line = end_line; + on_cmd_token = new_command; + + target_var = 0; + vnpos = vnstart; + + for(pos = vvstart; pos < codestart; pos += 8) { + /* print the variable name */ + while(program[vnpos] < 0x80) + putchar(program[vnpos++]); + putchar(program[vnpos++] & 0x7f); + printf("/%02x: ", target_var | 0x80); + + lastline = -1; + walk_all_code(); + + if(!refcounts[target_var]) { + unref++; + printf("(no references)"); + } else { + printf("(%d)", refcounts[target_var]); + } + putchar('\n'); + + if(target_var++ == 128) break; + } + + printf(" %d variables, %d unreferenced.\n", target_var, unref); + return 0; +} diff --git a/vxrefbas.rst b/vxrefbas.rst new file mode 100644 index 0000000..b06deb5 --- /dev/null +++ b/vxrefbas.rst @@ -0,0 +1,57 @@ +======== +vxrefbas +======== + +-------------------------------------------------------------- +Variable cross-reference for tokenized Atari 8-bit BASIC files +-------------------------------------------------------------- + +.. include:: manhdr.rst + +SYNOPSIS +======== + +vxrefbas **input-file** + +DESCRIPTION +=========== +**vxrefbas** reads an Atari 8-bit BASIC tokenized program and prints +a list of variables, each with a list of line numbers where the +variable is referenced. + +Variables that aren't used by the program are listed as *(no references)*. + +Each line number may be followed by one or more markers, which show the +type of variable access. + +**=** + The variable is assigned on this line, with *LET* or "implied LET" (e.g. + *A=1*). + +**{** + The variable is used as the control variable of a *FOR* loop on this line. + +**}** + The variable is used in a *NEXT* on this line. + +OPTIONS +======= + +General Options +--------------- +**--help** + Print usage message and exit. + +**--version** + Print version number and exit. + +**-v** + Verbose operation. When displaying a number in verbose mode, it will + be prefixed with *$* if it's in hex, or no prefix for decimal. + +EXIT STATUS +=========== + +0 for success, 1 for failure. + +.. include:: manftr.rst diff --git a/xex.5 b/xex.5 index ee955ea..b67c6b4 100644 --- a/xex.5 +++ b/xex.5 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "XEX" 5 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "XEX" 5 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME xex \- Atari 8-bit executable file format. .\" RST source for xex(5) man page. Convert with: @@ -315,6 +315,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/xex1to2.1 b/xex1to2.1 index aebc0be..3d66d3d 100644 --- a/xex1to2.1 +++ b/xex1to2.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "XEX1TO2" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "XEX1TO2" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME xex1to2 \- Convert an Atari DOS 1.0 executable to a standard Atari executable .\" RST source for xex1to2(1) man page. Convert with: @@ -89,6 +89,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/xexamine.1 b/xexamine.1 index f26a92b..73031a8 100644 --- a/xexamine.1 +++ b/xexamine.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "XEXAMINE" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "XEXAMINE" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME xexamine \- Show information on Atari 8-bit executables (XEX) .\" RST source for xexamine(1) man page. Convert with: @@ -147,6 +147,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/xexcat.1 b/xexcat.1 index e3467bc..57069fb 100644 --- a/xexcat.1 +++ b/xexcat.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "XEXCAT" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "XEXCAT" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME xexcat \- Concatenate Atari 8-bit executables (XEX) into a single XEX file. .\" RST source for xexcat(1) man page. Convert with: @@ -207,6 +207,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/xexsplit.1 b/xexsplit.1 index e2d69b5..674dd22 100644 --- a/xexsplit.1 +++ b/xexsplit.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "XEXSPLIT" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "XEXSPLIT" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME xexsplit \- Split a multi-segment Atari 8-bit executable (XEX) into multiple single-segment files. .\" RST source for xexsplit(1) man page. Convert with: @@ -200,6 +200,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), diff --git a/xfd2atr.1 b/xfd2atr.1 index fdc0255..14e06ef 100644 --- a/xfd2atr.1 +++ b/xfd2atr.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "XFD2ATR" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "XFD2ATR" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME xfd2atr \- Convert an Atari 8-bit XFD (raw) disk image to an ATR image. .\" RST source for xfd2atr(1) man page. Convert with: @@ -128,6 +128,7 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\ \fBrom2cart\fP(1), \fBunmac65\fP(1), \fBunprotbas\fP(1), +\fBvxrefbas\fP(1), \fBxexamine\fP(1), \fBxexcat\fP(1), \fBxexsplit\fP(1), -- cgit v1.2.3