diff options
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | a8eol.1 | 3 | ||||
| -rw-r--r-- | a8utf8.1 | 3 | ||||
| -rw-r--r-- | atascii.7 | 3 | ||||
| -rw-r--r-- | atr2xfd.1 | 3 | ||||
| -rw-r--r-- | atrsize.1 | 3 | ||||
| -rw-r--r-- | axe.1 | 3 | ||||
| -rw-r--r-- | bas.c | 105 | ||||
| -rw-r--r-- | bas.h | 24 | ||||
| -rw-r--r-- | blob2c.1 | 3 | ||||
| -rw-r--r-- | blob2xex.1 | 3 | ||||
| -rw-r--r-- | cart2xex.1 | 3 | ||||
| -rw-r--r-- | dasm2atasm.1 | 3 | ||||
| -rw-r--r-- | dumpbas.1 | 3 | ||||
| -rw-r--r-- | dumpbas.c | 112 | ||||
| -rw-r--r-- | fenders.1 | 3 | ||||
| -rw-r--r-- | manftr.rst | 1 | ||||
| -rw-r--r-- | rom2cart.1 | 3 | ||||
| -rw-r--r-- | unmac65.1 | 3 | ||||
| -rw-r--r-- | unprotbas.1 | 3 | ||||
| -rw-r--r-- | vxrefbas.1 | 113 | ||||
| -rw-r--r-- | vxrefbas.c | 95 | ||||
| -rw-r--r-- | vxrefbas.rst | 57 | ||||
| -rw-r--r-- | xex.5 | 3 | ||||
| -rw-r--r-- | xex1to2.1 | 3 | ||||
| -rw-r--r-- | xexamine.1 | 3 | ||||
| -rw-r--r-- | xexcat.1 | 3 | ||||
| -rw-r--r-- | xexsplit.1 | 3 | ||||
| -rw-r--r-- | xfd2atr.1 | 3 | 
29 files changed, 552 insertions, 24 deletions
| @@ -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: @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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; +	} +} @@ -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; @@ -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), @@ -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), @@ -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), @@ -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), @@ -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 @@ -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), @@ -28,6 +28,7 @@ SEE ALSO  **rom2cart**\(1),   **unmac65**\(1),  **unprotbas**\(1), +**vxrefbas**\(1),  **xexamine**\(1),   **xexcat**\(1),   **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 "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), @@ -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 <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <time.h> + +#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 @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), | 
