aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-05-19 14:26:16 -0400
committerB. Watson <urchlay@slackware.uk>2024-05-19 14:26:16 -0400
commita076240e441bf4b7e7f4f29cbfbb9fb2d3336c09 (patch)
treeb967a6b5118803abba9f6e5afc9a79d69ba0f147
parentbbffe594b2f9a42bd98e4e9de6dae65a2008e54e (diff)
downloadbw-atari8-tools-a076240e441bf4b7e7f4f29cbfbb9fb2d3336c09.tar.gz
unprotbas: implement -v option, fix doc about line 32768.
-rw-r--r--unprotbas.123
-rw-r--r--unprotbas.c36
-rw-r--r--unprotbas.rst23
3 files changed, 37 insertions, 45 deletions
diff --git a/unprotbas.1 b/unprotbas.1
index f770079..ff8cd36 100644
--- a/unprotbas.1
+++ b/unprotbas.1
@@ -35,12 +35,12 @@ unprotbas \- Unprotect LIST-protected Atari 8-bit BASIC programs
unprotbas [\fB\-v\fP] [\fB\-f\fP] [\fB\-n\fP] [\fB\-g\fP] \fBinput\-file\fP \fBoutput\-file\fP
.SH DESCRIPTION
.sp
-\fBunprotbas\fP modifies LIST\-protected Atari 8\-bit BASIC programs,
+\fBunprotbas\fP modifies a LIST\-protected Atari 8\-bit BASIC program,
creating a new non\-protected copy. See \fBDETAILS\fP, below, to
understand how the protection and unprotection works.
.sp
-\fBinput\-file\fP must be a tokenized Atari BASIC program. Use \fI\-\fP to
-read from standard input.
+\fBinput\-file\fP must be a tokenized (SAVEd) Atari BASIC program. Use
+\fI\-\fP to read from standard input.
.sp
\fBoutput\-file\fP will be the unprotected tokenized BASIC program. If it
already exists, it will be overwritten. Use \fI\-\fP to write to standard
@@ -55,14 +55,15 @@ will be treated as options.
.INDENT 0.0
.TP
.B \fB\-v\fP
-Verbose operation. TODO: it\(aqs always verbose right now...
+Verbose operation.
.TP
.B \fB\-f\fP
Force the variable name table to be rebuilt, even if it looks OK.
+This option cannot be combined with \fB\-n\fP\&.
.TP
.B \fB\-n\fP
Don\(aqt rebuild the variable table (only fix the line pointers, if
-needed).
+needed). This option cannot be combined with \fB\-f\fP\&.
.TP
.B \fB\-g\fP
Remove any "garbage" data from the end of the file. By default,
@@ -150,11 +151,6 @@ generates only one\- and two\-character variable names, so the rebuilt
table might be smaller.
.TP
.B Bad next\-line pointer
-Generally, this is done with line number 32768. Yes, this line
-number is outside the range BASIC accepts... but BASIC uses it
-internally for immediate\-mode commands. And when SAVE or CSAVE are
-executed, this line gets saved, too.
-.sp
Every line of tokenized BASIC contains a line length byte, which
BASIC uses as a pointer to the next line of code. Before printing
the READY prompt, BASIC iterates over every line of code in the
@@ -171,10 +167,9 @@ use the RUN command with a filename, and if the program ever exits
(due to END, STOP, an error, or the Break key), BASIC will get stuck
again.
.sp
-This doesn\(aqt \fIhave\fP to be done with line 32768. Any line of code
-that doesn\(aqt have to be traversed at runtime would work (in other
-words, a regular line whose line number is higher than any code that
-ever gets executed, usually the last line in the file).
+This doesn\(aqt \fIhave\fP to be done with the last line in the
+program. The "poisoned" line could be followed by more lines of
+code, though they could never actually execute.
.sp
Line 32100 in the example above does this job, taking advantage of
the STMCUR pointer used by BASIC, which holds the address of the
diff --git a/unprotbas.c b/unprotbas.c
index 02263ca..0b11e0e 100644
--- a/unprotbas.c
+++ b/unprotbas.c
@@ -58,7 +58,7 @@ void die(const char *msg) {
/* read entire file into memory */
int readfile(void) {
int got = fread(data, 1, 65535, input_file);
- fprintf(stderr, "read %d bytes\n", got);
+ if(verbose) fprintf(stderr, "read %d bytes\n", got);
fclose(input_file);
return got;
}
@@ -90,7 +90,7 @@ void read_header(void) {
codestart = stmtab - STM_OFFSET - (vntp - 256);
vnstart = vntp - 256 + 14;
vvstart = vvtp - 256 + 14;
- dump_header_vars();
+ if(verbose) dump_header_vars();
}
void set_header_vars(void) {
@@ -167,7 +167,7 @@ int fixcode(void) {
offset = data[pos + 2];
/* fprintf(stderr, "pos %d, line #%d, offset %d\n", pos, lineno, offset); */
if(offset < 6) {
- fprintf(stderr, "Found invalid offset %d (<6) at line %d\n", offset, lineno);
+ if(verbose) fprintf(stderr, "Found invalid offset %d (<6) at line %d\n", offset, lineno);
offset += fixline(pos);
result++;
}
@@ -178,10 +178,10 @@ int fixcode(void) {
if(lineno == 32768) break;
}
- fprintf(stderr, "End program pos $%04x/%d\n", pos, pos);
+ if(verbose) fprintf(stderr, "End program pos $%04x/%d\n", pos, pos);
if(filelen > pos) {
- fprintf(stderr, "trailing garbage at EOF, %d bytes, %s\n",
+ if(verbose) fprintf(stderr, "trailing garbage at EOF, %d bytes, %s\n",
filelen - pos, (keepgarbage ? "keeping" : "removing"));
if(!keepgarbage) filelen = pos;
}
@@ -233,7 +233,7 @@ int vntable_ok(void) {
int vp, bad;
if(vntp == vntd) {
- fprintf(stderr, "No variables\n");
+ if(verbose) fprintf(stderr, "No variables\n");
return 1;
}
@@ -345,7 +345,7 @@ void adjust_vntable_size(int oldsize, int newsize) {
int move_by;
if(oldsize != newsize) {
move_by = newsize - oldsize;
- fprintf(stderr, "need %d bytes for vntable, have %d, moving VVTP by %d to %04x\n",
+ if(verbose) fprintf(stderr, "need %d bytes for vntable, have %d, moving VVTP by %d to %04x\n",
newsize, oldsize, move_by, vvtp + move_by);
move_code(move_by);
}
@@ -473,26 +473,28 @@ int main(int argc, char **argv) {
if(!keepvars) {
if(fixvars()) {
was_protected = 1;
- fprintf(stderr, "Variable names replaced\n");
+ if(verbose) fprintf(stderr, "Variable names replaced\n");
} else {
- fprintf(stderr, "Variable names were already OK\n");
+ if(verbose) fprintf(stderr, "Variable names were already OK\n");
}
}
if(fixcode()) {
- fprintf(stderr, "Fixed invalid offset in code\n");
+ if(verbose) fprintf(stderr, "Fixed invalid offset in code\n");
was_protected = 1;
} else {
- fprintf(stderr, "No invalid offsets\n");
+ if(verbose) fprintf(stderr, "No invalid offsets\n");
}
- if(was_protected)
- fprintf(stderr, "Program was protected.\n");
- else
- fprintf(stderr, "Program was NOT protected.\n");
+ if(verbose) {
+ if(was_protected)
+ fprintf(stderr, "Program was protected.\n");
+ else
+ fprintf(stderr, "Program was NOT protected.\n");
+ }
if(checkonly) {
- fprintf(stderr, "Check-only mode; no output written.\n");
+ if(verbose) fprintf(stderr, "Check-only mode; no output written.\n");
if(was_protected)
return 0;
else
@@ -501,7 +503,7 @@ int main(int argc, char **argv) {
int got = fwrite(data, 1, filelen, output_file);
fclose(output_file);
- fprintf(stderr, "wrote %d bytes\n", got);
+ if(verbose) fprintf(stderr, "wrote %d bytes\n", got);
return 0;
}
diff --git a/unprotbas.rst b/unprotbas.rst
index daf391f..dfd3f5a 100644
--- a/unprotbas.rst
+++ b/unprotbas.rst
@@ -16,12 +16,12 @@ unprotbas [**-v**] [**-f**] [**-n**] [**-g**] **input-file** **output-file**
DESCRIPTION
===========
-**unprotbas** modifies LIST-protected Atari 8-bit BASIC programs,
+**unprotbas** modifies a LIST-protected Atari 8-bit BASIC program,
creating a new non-protected copy. See **DETAILS**, below, to
understand how the protection and unprotection works.
-**input-file** must be a tokenized Atari BASIC program. Use *-* to
-read from standard input.
+**input-file** must be a tokenized (SAVEd) Atari BASIC program. Use
+*-* to read from standard input.
**output-file** will be the unprotected tokenized BASIC program. If it
already exists, it will be overwritten. Use *-* to write to standard
@@ -37,14 +37,15 @@ To use filenames beginning with *-*, write them as *./-file*, or they
will be treated as options.
**-v**
- Verbose operation. TODO: it's always verbose right now...
+ Verbose operation.
**-f**
Force the variable name table to be rebuilt, even if it looks OK.
+ This option cannot be combined with **-n**.
**-n**
Don't rebuild the variable table (only fix the line pointers, if
- needed).
+ needed). This option cannot be combined with **-f**.
**-g**
Remove any "garbage" data from the end of the file. By default,
@@ -124,11 +125,6 @@ Variable name table scrambling
table might be smaller.
Bad next-line pointer
- Generally, this is done with line number 32768. Yes, this line
- number is outside the range BASIC accepts... but BASIC uses it
- internally for immediate-mode commands. And when SAVE or CSAVE are
- executed, this line gets saved, too.
-
Every line of tokenized BASIC contains a line length byte, which
BASIC uses as a pointer to the next line of code. Before printing
the READY prompt, BASIC iterates over every line of code in the
@@ -145,10 +141,9 @@ Bad next-line pointer
(due to END, STOP, an error, or the Break key), BASIC will get stuck
again.
- This doesn't *have* to be done with line 32768. Any line of code
- that doesn't have to be traversed at runtime would work (in other
- words, a regular line whose line number is higher than any code that
- ever gets executed, usually the last line in the file).
+ This doesn't *have* to be done with the last line in the
+ program. The "poisoned" line could be followed by more lines of
+ code, though they could never actually execute.
Line 32100 in the example above does this job, taking advantage of
the STMCUR pointer used by BASIC, which holds the address of the