From 7663d7e3f35daa07900557faa5a1e83fbbcdadb0 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Wed, 26 Feb 2025 04:27:04 -0500 Subject: listamsb: sanity check end-of-line addresses. --- listamsb.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 7 deletions(-) (limited to 'listamsb.c') diff --git a/listamsb.c b/listamsb.c index 91e7d1c..b139dd5 100644 --- a/listamsb.c +++ b/listamsb.c @@ -5,18 +5,24 @@ #include "amsbtok.h" +/* this should always be defined in , but just in case... */ +#ifndef BUFSIZ +#define BUFSIZ 4096 +#endif + +/* range for one-byte tokens */ #define MIN_STD_TOK 0x80 /* END */ #define MAX_STD_TOK 0xf8 /* < */ +/* range for 2nd byte of two-byte tokens (1st is always 0xff) */ #define MIN_EXT_TOK 0xa3 /* SGN */ #define MAX_EXT_TOK 0xc5 /* STACK */ -#ifndef BUFSIZ -#define BUFSIZ 4096 -#endif - +/* good old Atari EOL character */ #define EOL 0x9b +/* every MS BASIC I ever saw had the same line number limit. it's + kind of arbitrary: why not allow the full range, up to 65535? */ #define MAX_LINENO 63999 /* a program bigger than this can't possibly fit into memory, @@ -31,6 +37,14 @@ #define MIN_PROGLEN 5 #define EMPTY_PROGLEN 2 +/* an EOL address below this has to be an error, since + this is the lowest MEMLO can ever be. */ +#define MIN_PTR 0x0700 + +/* an EOL address higher than this has to be an error, since + it would overlap the GR.0 display list or the ROMs at $c000 */ +#define MAX_PTR 0xbc1f + const char *self; char pipe_command[BUFSIZ + 1] = { "a8cat" }; @@ -121,12 +135,15 @@ void unknown_token(int lineno, unsigned char byte, int ext) { int next_line(void) { static int last_lineno = -1; - int ptr, lineno, was_ff, in_string; + static int last_ptr = -1; + int ptr, lineno, was_ff, in_string, offset, len; unsigned char byte; + offset = bytes_read; + /* pointer to last token on the line, offset by whatever MEMLO happened to be when the file was SAVEd. 0 means this is the - last line, otherwise we don't use its value. */ + last line. */ ptr = read_word(); if(!ptr) { if(verbose) @@ -136,7 +153,25 @@ int next_line(void) { lineno = read_word(); if(verbose) - fprintf(stderr, "found line number %d\n", lineno); + fprintf(stderr, "found line %d, offset %d, end-of-line %d\n", lineno, offset, ptr); + + if(ptr < MIN_PTR) { + fprintf(stderr, "%s: line %d: EOL address $%04x too low (<$%04x)\n", + self, lineno, ptr, MIN_PTR); + warnings++; + } else if(ptr >= MAX_PTR) { + fprintf(stderr, "%s: line %d: EOL address $%04x too high (>$%04x)\n", + self, lineno, ptr, MAX_PTR); + warnings++; + } + + if(last_ptr != -1) { + if(ptr <= last_ptr) { + fprintf(stderr, "%s: line %d: EOL address $%04x <= previous $%04x\n", + self, lineno, ptr, last_ptr); + warnings++; + } + } if(lineno <= last_lineno) { fprintf(stderr, "%s: line number out of order (%d <= %d)\n", @@ -214,6 +249,23 @@ int next_line(void) { } } + len = bytes_read - offset; + + if(verbose) { + fprintf(stderr, " line %d length: %d\n", lineno, len); + } + + if(last_ptr != -1) { + int plen = ptr - last_ptr; + if(len != plen) { + fprintf(stderr, "%s: line %d: EOL address doesn't match actual line length %d\n", + self, lineno, len); + warnings++; + } + } + + last_ptr = ptr; + putc(EOL, outfile); return 1; -- cgit v1.2.3