diff options
author | B. Watson <urchlay@slackware.uk> | 2025-02-26 04:27:04 -0500 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2025-02-26 04:27:04 -0500 |
commit | 7663d7e3f35daa07900557faa5a1e83fbbcdadb0 (patch) | |
tree | 6041da577c262182968af596394ae83adc354bfa | |
parent | d0c008b68a7e2a12308a888e918d7467998260a9 (diff) | |
download | bw-atari8-tools-7663d7e3f35daa07900557faa5a1e83fbbcdadb0.tar.gz |
listamsb: sanity check end-of-line addresses.
-rw-r--r-- | listamsb.1 | 18 | ||||
-rw-r--r-- | listamsb.c | 66 | ||||
-rw-r--r-- | listamsb.rst | 16 |
3 files changed, 92 insertions, 8 deletions
@@ -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 "LISTAMSB" 1 "2025-02-25" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "LISTAMSB" 1 "2025-02-26" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME listamsb \- List the source of a tokenized Atari Microsoft BASIC program .SH SYNOPSIS @@ -116,6 +116,22 @@ unexpected EOF, file truncated? A tokenized AMSB file always ends with three null bytes (\fI$00\fP). This file doesn\(aqt. Probably the rest of the file is missing. .IP \(bu 2 +line \fIN\fP: EOL address \fIA\fP too (low|high) +.sp +Each line begins with the address of the next line. If the address +is below \fI$0700\fP, it\(aqs below the minimum value of \fIMEMLO\fP, which +is impossible. If it\(aqs above \fI$bc1f\fP, it would be in the display +list, screen memory, or OS ROM (also impossible). File is +corrupt, or not an AMSB file. +.IP \(bu 2 +line \fIN\fP: EOL address \fIA\fP <= previous \fIB\fP +.sp +Corrupt file, or not an AMSB file. +.IP \(bu 2 +line \fIN\fP EOL address doesn\(aqt match actual line length \fIL\fP +.sp +Same as above: corrupt, or not AMSB. +.IP \(bu 2 line number out of order .sp Probably means the file is corrupted, or isn\(aqt really an AMSB file. @@ -5,18 +5,24 @@ #include "amsbtok.h" +/* this should always be defined in <stdio.h>, 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; diff --git a/listamsb.rst b/listamsb.rst index acf3718..37eb0ea 100644 --- a/listamsb.rst +++ b/listamsb.rst @@ -100,6 +100,22 @@ continues processing. A tokenized AMSB file always ends with three null bytes (*$00*\). This file doesn't. Probably the rest of the file is missing. +- line *N*: EOL address *A* too (low|high) + + Each line begins with the address of the next line. If the address + is below *$0700*, it's below the minimum value of *MEMLO*, which + is impossible. If it's above *$bc1f*, it would be in the display + list, screen memory, or OS ROM (also impossible). File is + corrupt, or not an AMSB file. + +- line *N*: EOL address *A* <= previous *B* + + Corrupt file, or not an AMSB file. + +- line *N* EOL address doesn't match actual line length *L* + + Same as above: corrupt, or not AMSB. + - line number out of order Probably means the file is corrupted, or isn't really an AMSB file. |