aboutsummaryrefslogtreecommitdiff
path: root/unprotbas.1
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-05-17 05:09:45 -0400
committerB. Watson <urchlay@slackware.uk>2024-05-17 05:09:45 -0400
commit96af9bc891987f6fcc560a6e403c5ada541d8699 (patch)
tree6bdd20a1fdd7f31316d14fb5e233718b48713522 /unprotbas.1
parentd4064b55a7ddbb002ef80dbc0db60cd0d95cb1cd (diff)
downloadbw-atari8-tools-96af9bc891987f6fcc560a6e403c5ada541d8699.tar.gz
unprotbas: added; blob2xex: tweak docs.
Diffstat (limited to 'unprotbas.1')
-rw-r--r--unprotbas.1213
1 files changed, 213 insertions, 0 deletions
diff --git a/unprotbas.1 b/unprotbas.1
new file mode 100644
index 0000000..92e6b66
--- /dev/null
+++ b/unprotbas.1
@@ -0,0 +1,213 @@
+.\" 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 "UNPROTBAS" 1 "2024-05-17" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.SH NAME
+unprotbas \- Unprotect LIST-protected Atari 8-bit BASIC programs
+.SH SYNOPSIS
+.sp
+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,
+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.
+.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
+output, but \fB[TODO]\fP \fBunprotbas\fP will refuse to write to standard
+output if it\(aqs a terminal (since tokenized BASIC is binary data and
+may confuse the terminal).
+.SH OPTIONS
+.INDENT 0.0
+.TP
+.B \fB\-v\fP
+Verbose operation.
+.TP
+.B \fB\-f\fP
+Force the variable name table to be rebuilt, even if it looks OK.
+.TP
+.B \fB\-n\fP
+Don\(aqt rebuild the variable table (only fix the line pointers, if
+needed).
+.TP
+.B \fB\-g\fP
+Remove any "garbage" data from the end of the file. By default,
+it\(aqs left as\-is, in case it\(aqs actually data used by the program.
+.UNINDENT
+.SH EXIT STATUS
+.sp
+Exit status is zero for success, non\-zero for failure.
+.SH DETAILS
+.sp
+In the Atari BASIC world, it\(aqs possible to create a SAVEd (tokenized)
+program that can be RUN from disk (\fBRUN "D:FILE.BAS"\fP) but if
+it\(aqs LOADed, it will either crash the BASIC interpreter, or LIST
+as gibberish. This is known as LIST\-protection. Such programs are
+generally released to the world in protected form; the author
+privately keeps an unprotected copy so he can modify it. In
+later days, collections such as the Holmes Archive contain many
+LIST\-protected programs, for which the unprotected version was never
+released.
+.sp
+One example of LIST\-protection, taken from \fIMapping the Atari\fP (the
+\fBSTMCUR\fP entry in the memory map) looks like:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+32000 FOR VARI=PEEK(130)+PEEK(131)*256 TO PEEK(132)+PEEK(133)*256:POKE VARI,155:NEXT VARI
+32100 POKE PEEK(138)+PEEK(139)*256+2,0:SAVE "D:filename":NEW
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+To use, add the 2 lines of code to your program, then execute them
+with \fBGOTO 32000\fP in immediate mode.
+.sp
+This illustrates both types of protection, which can be (and usually
+are) applied to the same program:
+.INDENT 0.0
+.TP
+.B Variable name table scrambling
+BASIC has specific rules on what are and aren\(aqt considered legal
+variable names, which are enforced by the tokenization process,
+at program entry time. However, it doesn\(aqt use the variable names
+at runtime, when the tokenized file is interpreted.
+.sp
+Replacing the variable names with binary gibberish will render the
+program LIST\-proof, either replacing every variable name with the
+same control character, or causing LIST to display a long string of
+binary garbage for each variable name... but the program will still
+RUN correctly. Note that the original variable names are \fIgone\fP,
+and cannot be recovered.
+.sp
+Line 32000 in the example above does this job, replacing every
+variable name with the EOL character (155).
+.sp
+\fBunprotbas\fP detects a scrambled variable name table, and builds
+a new one that\(aqs valid. However, since there are no real variable
+names in the program, the recovery process just invents new ones,
+named A through Z, A1 through A9, B1 through B9, etc, etc. It\(aqll
+require human intelligence to figure out what each variable is for,
+since the names are meaningless.
+.sp
+The \fBoutput\-file\fP may be larger than the \fBinput\-file\fP was, since
+some types of variable\-name scrambling shrink the variable name
+table to the minimum size (one byte per name); the rebuilt table
+will be larger.
+.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
+program, using the next\-line pointers, in order to delete any
+existing line 32768 (the previous immediate mode command). If any
+line\(aqs pointer is set to zero, that means it points to itself.
+.sp
+When BASIC tries to traverse a line of code that points to itself as
+"next" line, it will get stuck in an infinite loop. This not only
+prevents LIST, it actually prevents any immediate mode command:
+after LOADing such a file, \fInothing\fP will work (even pressing RESET
+won\(aqt get you out of it). The only way to use such a program is to
+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).
+.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
+line of tokenized code currently being executed.
+.sp
+\fBunprotbas\fP fixes this simply by calculating what the pointer
+should be (based on the tokens in the line) and changing it. No
+information is lost by doing this.
+.UNINDENT
+.sp
+One more thing \fBunprotbas\fP can do is remove extra data from the end
+of the file. It\(aqs possible for BASIC files to contain extra data that
+occurs after the end of the program. Some programs use this as a way
+to load arbitrary binary data into memory along with the program; for
+other programs, the extra data is truly garbage (e.g. an EOF character
+if the file came from a CP/M system, or padding to a block size if a
+dumb implementation of XMODEM was used to transfer the file).
+.sp
+Normally, such "garbage" doesn\(aqt hurt anything. BASIC ignores it. Or
+it normally does... if you suspect it\(aqs causing a problem, you can
+remove it with the \fB\-g\fP option. If removing the "garbage" causes the
+program to fail to run, it wasn\(aqt garbage! \fBunprotbas\fP doesn\(aqt
+remove extra data by default, to be on the safe side.
+.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),
+\fBf2toxex\fP(1),
+\fBfenders\fP(1),
+\fBrom2cart\fP(1),
+\fBunmac65\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.
+.