aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--listamsb.118
-rw-r--r--listamsb.c66
-rw-r--r--listamsb.rst16
3 files changed, 92 insertions, 8 deletions
diff --git a/listamsb.1 b/listamsb.1
index a21fb5a..a80a17d 100644
--- a/listamsb.1
+++ b/listamsb.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 "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.
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 <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.