aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--a8eol.14
-rw-r--r--a8utf8.14
-rw-r--r--atascii.74
-rw-r--r--atr2xfd.14
-rw-r--r--atrsize.14
-rw-r--r--axe.14
-rw-r--r--bas.c2
-rw-r--r--blob2c.14
-rw-r--r--blob2xex.14
-rw-r--r--cart2xex.14
-rw-r--r--dasm2atasm.14
-rw-r--r--dumpbas.1267
-rw-r--r--dumpbas.c160
-rw-r--r--dumpbas.rst163
-rw-r--r--fenders.14
-rw-r--r--manftr.rst2
-rw-r--r--rom2cart.14
-rw-r--r--unmac65.14
-rw-r--r--unprotbas.14
-rw-r--r--xex.54
-rw-r--r--xex1to2.14
-rw-r--r--xexamine.14
-rw-r--r--xexcat.14
-rw-r--r--xexsplit.14
-rw-r--r--xfd2atr.14
26 files changed, 659 insertions, 23 deletions
diff --git a/Makefile b/Makefile
index 97bdcdd..76c767d 100644
--- a/Makefile
+++ b/Makefile
@@ -16,9 +16,9 @@ CC=gcc
CFLAGS=-Wall $(COPT) -ansi -D_GNU_SOURCE -DVERSION=\"$(VERSION)\"
# BINS and SCRIPTS go in $BINDIR, DOCS go in $DOCDIR
-BINS=a8eol xfd2atr atr2xfd blob2c cart2xex fenders xexsplit xexcat atrsize rom2cart unmac65 axe blob2xex xexamine xex1to2 unprotbas protbas
+BINS=a8eol xfd2atr atr2xfd blob2c cart2xex fenders xexsplit xexcat atrsize rom2cart unmac65 axe blob2xex xexamine xex1to2 unprotbas protbas renumbas dumpbas
SCRIPTS=dasm2atasm a8utf8
-MANS=a8eol.1 xfd2atr.1 atr2xfd.1 blob2c.1 cart2xex.1 fenders.1 xexsplit.1 xexcat.1 atrsize.1 rom2cart.1 unmac65.1 axe.1 dasm2atasm.1 a8utf8.1 blob2xex.1 xexamine.1 xex1to2.1 unprotbas.1 protbas.1
+MANS=a8eol.1 xfd2atr.1 atr2xfd.1 blob2c.1 cart2xex.1 fenders.1 xexsplit.1 xexcat.1 atrsize.1 rom2cart.1 unmac65.1 axe.1 dasm2atasm.1 a8utf8.1 blob2xex.1 xexamine.1 xex1to2.1 unprotbas.1 protbas.1 renumbas.1 dumpbas.1
MAN5S=xex.5
MAN7S=atascii.7
DOCS=README.txt equates.inc *.dasm LICENSE ksiders/atr.txt
@@ -53,6 +53,10 @@ unprotbas: bas.o
protbas: bas.o
+renumbas: bas.o
+
+dumpbas: bas.o
+
bas.o: bas.c bas.h
subdirs:
diff --git a/a8eol.1 b/a8eol.1
index 0a7ce29..5aca5dc 100644
--- a/a8eol.1
+++ b/a8eol.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 "A8EOL" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "A8EOL" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
a8eol \- convert Atari 8-bit text files to/from UNIX/Windows/Mac
.\" RST source for a8eol(1) man page. Convert with:
@@ -470,9 +470,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/a8utf8.1 b/a8utf8.1
index 3a3f0bd..6e57a98 100644
--- a/a8utf8.1
+++ b/a8utf8.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 "A8UTF8" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "A8UTF8" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
a8utf8 \- Convert Atari 8-bit text to UTF-8 encoded Unicode.
.\" RST source for a8utf8(1) man page. Convert with:
@@ -101,9 +101,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/atascii.7 b/atascii.7
index 21728a4..a555547 100644
--- a/atascii.7
+++ b/atascii.7
@@ -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 "ATASCII" 7 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "ATASCII" 7 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
atascii \- Atari 8-bit character set
.\" RST source for atascii(7) man page. Convert with:
@@ -2161,9 +2161,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/atr2xfd.1 b/atr2xfd.1
index 2e2b4d2..ad6e217 100644
--- a/atr2xfd.1
+++ b/atr2xfd.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 "ATR2XFD" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "ATR2XFD" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
atr2xfd \- Convert an Atari 8-bit ATR disk image to a raw (XFD) image
.\" RST source for atr2xfd(1) man page. Convert with:
@@ -190,9 +190,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/atrsize.1 b/atrsize.1
index b756001..04b5b55 100644
--- a/atrsize.1
+++ b/atrsize.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 "ATRSIZE" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "ATRSIZE" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
atrsize \- Change the size of an Atari 8-bit ATR disk image, or create a blank ATR image
.\" RST source for atrsize(1) man page. Convert with:
@@ -204,9 +204,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/axe.1 b/axe.1
index 8ea527e..4504c96 100644
--- a/axe.1
+++ b/axe.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 "AXE" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "AXE" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
axe \- ATR/XFD Editor
.\" RST source for axe(1) man page. Convert with:
@@ -145,9 +145,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/bas.c b/bas.c
index 230032c..e90d96c 100644
--- a/bas.c
+++ b/bas.c
@@ -217,7 +217,7 @@ FILE *open_file(const char *name, const char *mode) {
}
void open_input(const char *name) {
- if(!name) {
+ if(!name || strcmp(name, "-") == 0) {
if(isatty(fileno(stdin))) {
die("Can't read binary data from the terminal.");
}
diff --git a/blob2c.1 b/blob2c.1
index c1afaf8..97ef227 100644
--- a/blob2c.1
+++ b/blob2c.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 "BLOB2C" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "BLOB2C" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
blob2c \- Create C source and header files from a binary file
.\" RST source for blob2c(1) man page. Convert with:
@@ -125,9 +125,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/blob2xex.1 b/blob2xex.1
index ac149ce..4524cd4 100644
--- a/blob2xex.1
+++ b/blob2xex.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 "BLOB2XEX" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "BLOB2XEX" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
blob2xex \- Create Atari 8-bit executables from arbitrary data
.\" RST source for blob2xex(1) man page. Convert with:
@@ -216,9 +216,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/cart2xex.1 b/cart2xex.1
index ffa7818..adadec1 100644
--- a/cart2xex.1
+++ b/cart2xex.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 "CART2XEX" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "CART2XEX" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
cart2xex \- Convert an Atari 8-bit ROM cartridge image to a binary load file
.\" RST source for cart2xex(1) man page. Convert with:
@@ -235,9 +235,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/dasm2atasm.1 b/dasm2atasm.1
index 7e8e0fc..e51c1f5 100644
--- a/dasm2atasm.1
+++ b/dasm2atasm.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 "DASM2ATASM" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "DASM2ATASM" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
dasm2atasm \- Convert 6502 assembly source from dasm syntax to atasm or ca65 syntax.
.\" RST source for dasm2atasm(1) man page. Convert with:
@@ -232,9 +232,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/dumpbas.1 b/dumpbas.1
new file mode 100644
index 0000000..9da3e11
--- /dev/null
+++ b/dumpbas.1
@@ -0,0 +1,267 @@
+.\" 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 "DUMPBAS" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.SH NAME
+dumpbas \- Formatted hexdump for tokenized Atari 8-bit BASIC files
+.SH SYNOPSIS
+.sp
+dumpbas [\fB\-v\fP] [\fB\-l\fP \fIlineno\fP] [\fB\-s\fP \fIstart\-lineno\fP] [\fB\-e\fP \fIend\-lineno\fP] \fIinput\-file\fP
+.SH DESCRIPTION
+.sp
+\fBdumpbas\fP reads a tokenized Atari 8\-bit BASIC program and prints a
+formatted hexdump on standard output. The formatting groups the hex bytes
+by line and statement, and includes special characters to mark different
+types of token (see \fBFORMATTING\fP, below).
+.sp
+\fBdumpbas\fP does not detokenize BASIC programs or dump information
+about variable names/values. Use \fBchkbas\fP(1) for that. This tool is
+intended to help the user learn about the tokenized BASIC format, or
+as an aid for developing/debugging other tools that process tokenized
+files. It\(aqs an alternative to looking at raw hex dumps.
+.sp
+It\(aqs assumed the user has at least some knowledge of BASIC\(aqs tokenized
+SAVE format. The \fBAtari BASIC Sourcebook\fP is a good starting point
+for learning the tokenized format.
+.SH OPTIONS
+.SS General Options
+.INDENT 0.0
+.TP
+.B \fB\-\-help\fP
+Print usage message and exit.
+.TP
+.B \fB\-\-version\fP
+Print version number and exit.
+.TP
+.B \fB\-v\fP
+Verbose operation. When displaying a number in verbose mode, it will
+be prefixed with \fI$\fP if it\(aqs in hex, or no prefix for decimal.
+.UNINDENT
+.SS Dump Options
+.INDENT 0.0
+.TP
+.B \fB\-s\fP \fIstart\-lineno\fP
+Don\(aqt dump lines before \fBstart\-lineno\fP\&. Default: \fI0\fP\&.
+.TP
+.B \fB\-e\fP \fIend\-lineno\fP
+Don\(aqt dump lines after \fBstart\-lineno\fP\&. Default: \fI32768\fP\&.
+.TP
+.B \fB\-l\fP \fIlineno\fP
+Only dump one line. This is exactly equivalent to "\fB\-s\fP \fInum\fP \fB\-e\fP \fInum\fP".
+.UNINDENT
+.SH FORMATTING
+.sp
+Every byte in the file is displayed in hex. However, they are grouped by line
+and statement, and certain tokens get marker characters to help keep track
+of what they\(aqre for. Strings are displayed in both hex and ASCII. Floating
+point constants are displayed as 6 hex bytes with square brackets around them.
+.sp
+If \fBdumpbas\fP is run on the following program:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+10 ? "HOW MANY TIMES";:INPUT N
+20 FOR I=1 TO N
+30 ? "HELLO ";:? I;"/";N:NEXT I
+40 REM WAIT FOR KEY
+50 POKE 764,255
+60 ? "PRESS ANY KEY"
+70 IF PEEK(764)=255 THEN 70
+80 POKE 764,255:GOTO 10
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+\fBNote:\fP The "PRESS ANY KEY" was entered in inverse video.
+.sp
+\&...it produces the following output:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+ 10@0021 (0a 00): ^1b
+ >17 !28 $0f =0e "H/48 O/4f W/57 /20 M/4d A/41 N/4e Y/59 /20 T/54 I/49 M/4d E/45 S/53" 15 14:
+ >1b !02 80 16
+ 20@003c (14 00): ^11
+ >11 !08 81 2d #0e [40 01 00 00 00 00] 19 80 16
+ 30@004d (1e 00): ^1d
+ >0f !28 $0f =06 "H/48 E/45 L/4c L/4c O/4f /20" 15 14:
+ >19 !28 81 15 $0f =01 "//2f" 15 80 14:
+ >1d !09 81 16
+ 40@006a (28 00): ^12
+ >12 !00 57 41 49 54 20 46 4f 52 20 4b 45 59 9b
+ 50@007c (32 00): ^15
+ >15 !1f #0e [41 07 64 00 00 00] 12 #0e [41 02 55 00 00 00] 16
+ 60@0091 (3c 00): ^15
+ >15 !28 $0f =0d "|P/d0 |R/d2 |E/c5 |S/d3 |S/d3 | /a0 |A/c1 |N/ce |Y/d9 | /a0 |K/cb |E/c5 |Y/d9" 16
+ 70@00a6 (46 00): ^20
+ >20 !07 46 3a #0e [41 07 64 00 00 00] 2c 22 #0e [41 02 55 00 00 00] 1b #0e [40 70 00 00 00 00] 16
+ 80@00c6 (50 00): ^1f
+ >15 !1f #0e [41 07 64 00 00 00] 12 #0e [41 02 55 00 00 00] 14:
+ >1f !0a #0e [40 10 00 00 00 00] 16
+32768@00e5 (00 80): ^0f
+ >0f !19 $0f =07 "H/48 :/3a B/42 ./2e B/42 A/41 S/53" 16
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.SS Line header
+.sp
+Each line number begins with the line number (decimal) and offset from
+the start of the file (hex), followed by the 2 hex bytes for the line
+number in parentheses, followed by the line length (hex, preceded by
+^). From the example:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+10@0021 (0a 00): ^1b
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+The line number is \fI10\fP, the file offset is \fI0021\fP\&. The \fI0a 00\fP are 10 again, in
+hex, LSB first. The \fI^1b\fP is the line length.
+.SS Statements
+.sp
+Each statement within the line is displayed separately. Line 10\(aqs first statement:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+>17 !28 $0f =0e "H/48 O/4f W/57 /20 M/4d A/41 N/4e Y/59 /20 T/54 I/49 M/4d E/45 S/53" 15 14:
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+This looks cryptic, but it includes a lot of information.
+.INDENT 0.0
+.IP \(bu 2
+\fI>\fP is the marker for the statement offset (\fI17\fP).
+.IP \(bu 2
+\fI!\fP marks a command token (unmarked tokens are operator
+tokens). \fI28\fP is the token for \fB?\fP (short form of PRINT, which has a
+separate token).
+.IP \(bu 2
+\fI$\fP marks the string\-constant token (\fI0f\fP).
+.IP \(bu 2
+\fI=\fP marks the string length byte (\fI0e\fP).
+.IP \(bu 2
+The string itself is printed inside double quotes, with each character in
+both ASCII and hex (e.g. \fIH/48\fP).
+.IP \(bu 2
+The \fI15\fP is unmarked. It\(aqs the semicolon after the string.
+.IP \(bu 2
+There\(aqs a \fI:\fP at the end of the line (after the \fI14\fP, which is the end\-of\-statement
+token).
+.UNINDENT
+.sp
+Line 10\(aqs second statement:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+>1b !02 80 16
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+The \fI80\fP is a token for a variable (variable tokens always have bit 7 set, so they\(aqre
+always >= 80 hex). The \fI16\fP is the end\-of\-line token.
+.sp
+Line 20\(aqs first statement has an example of a floating point constant:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+#0e [40 01 00 00 00 00]
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.IP \(bu 2
+\fI#\fP marks the token for a FP constant.
+.IP \(bu 2
+The actual 6\-byte constant is surrounded with \fI[\fP and \fI]\fP\&.
+.IP \(bu 2
+The last token is \fI16\fP, which is BASIC\(aqs end\-of\-line token.
+.UNINDENT
+.SH EXIT STATUS
+.sp
+0 for success, 1 for failure.
+.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),
+\fBdumpbas\fP(1),
+\fBf2toxex\fP(1),
+\fBfenders\fP(1),
+\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
+\fBrom2cart\fP(1),
+\fBunmac65\fP(1),
+\fBunprotbas\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.
+.
diff --git a/dumpbas.c b/dumpbas.c
new file mode 100644
index 0000000..b7607ea
--- /dev/null
+++ b/dumpbas.c
@@ -0,0 +1,160 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "bas.h"
+
+int startlineno = 0;
+int endlineno = 32768;
+
+/* dump tokens for each line in a BASIC program. easier to read than
+ a plain hex dump. */
+void print_help(void) {
+ fprintf(stderr, "Usage: %s [-v] [-s start-lineno] [-e end-lineno] <inputfile>\n", self);
+}
+
+unsigned short getlineno(char opt, const char *arg) {
+ int lineno;
+ char *e;
+
+ lineno = (int)strtol(arg, &e, 10);
+
+ if(*e) {
+ fprintf(stderr, "%s: Invalid line number for -%c option: %s is not a number.\n",
+ self, opt, arg);
+ exit(1);
+ }
+
+ if(lineno < 0 || lineno > 32767) {
+ fprintf(stderr, "%s: Invalid line number for -%c option: %d > 32767.\n",
+ self, opt, lineno);
+ exit(1);
+ }
+
+ return ((unsigned short)lineno);
+}
+
+void parse_args(int argc, char **argv) {
+ int opt;
+
+ while( (opt = getopt(argc, argv, "vs:e:l:")) != -1) {
+ switch(opt) {
+ case 'v': verbose = 1; break;
+ case 's': startlineno = getlineno(opt, optarg); break;
+ case 'e': endlineno = getlineno(opt, optarg); break;
+ case 'l': startlineno = getlineno(opt, optarg);
+ endlineno = startlineno; break;
+ default:
+ print_help();
+ exit(1);
+ }
+ }
+
+ if(optind >= argc)
+ die("No input file given (use - for stdin).");
+ else
+ open_input(argv[optind]);
+}
+
+void print_atascii(unsigned char c) {
+ if(c & 0x80) {
+ putchar('|');
+ c &= 0x7f;
+ }
+
+ if(c < 32) {
+ putchar('^');
+ c += 0x40;
+ }
+
+ if(c == 0x7f)
+ printf("del");
+ else
+ putchar(c);
+ putchar('/');
+}
+
+/* sorry, this is horrid, more like assembly than C. */
+int main(int argc, char **argv) {
+ int pos, nextpos, offset, soffset, lineno, cmd, i, end;
+ int numcount = 0, start_string = 0, end_string = 0;
+
+ set_self(*argv);
+ parse_general_args(argc, argv, print_help);
+ parse_args(argc, argv);
+
+ readfile();
+ parse_header();
+
+ pos = codestart;
+ while(pos < filelen) {
+ lineno = getword(pos);
+ offset = program[pos + 2];
+ nextpos = pos + offset;
+
+ if(lineno >= startlineno) {
+ printf("%5d@%04x (%02x %02x): ^%02x ", lineno, pos, program[pos], program[pos + 1], offset);
+
+ i = pos + 3;
+ while(i < nextpos) {
+ soffset = program[i];
+ end = pos + soffset;
+ while(i < end) {
+ printf("\n >%02x ", program[i]); /* offset */
+ i++;
+ cmd = 1;
+ while(i < end) {
+ if(cmd) {
+ putchar('!');
+ } else if(program[i] == 0x0e && program[i - 1] != 0x0f && (i < start_string || i > end_string)) {
+ putchar('#');
+ numcount = 7;
+ } else if(program[i] == 0x0f) {
+ putchar('$');
+ start_string = i + 2;
+ end_string = start_string + program[i + 1];
+ }
+
+ if(numcount == 6)
+ putchar('[');
+
+ if(i == start_string)
+ putchar('"');
+
+ if(i == (start_string - 1))
+ putchar('=');
+
+ if(i >= start_string && i < end_string)
+ print_atascii(program[i]);
+
+ printf("%02x", program[i]);
+ if(i == (end - 1) && program[i] == 0x14)
+ putchar(':');
+
+ if(numcount) {
+ if(--numcount == 0)
+ putchar(']');
+ }
+
+ i++;
+ if(i == end_string)
+ putchar('"');
+
+ putchar(' ');
+ cmd = 0;
+ }
+ }
+ }
+
+ putchar('\n');
+ }
+
+ if(lineno == endlineno) break;
+ pos = nextpos;
+ }
+
+ return 0;
+}
diff --git a/dumpbas.rst b/dumpbas.rst
new file mode 100644
index 0000000..8b116c3
--- /dev/null
+++ b/dumpbas.rst
@@ -0,0 +1,163 @@
+=======
+dumpbas
+=======
+
+-------------------------------------------------------
+Formatted hexdump for tokenized Atari 8-bit BASIC files
+-------------------------------------------------------
+
+.. include:: manhdr.rst
+
+SYNOPSIS
+========
+dumpbas [**-v**] [**-l** *lineno*] [**-s** *start-lineno*] [**-e** *end-lineno*] *input-file*
+
+DESCRIPTION
+===========
+**dumpbas** reads a tokenized Atari 8-bit BASIC program and prints a
+formatted hexdump on standard output. The formatting groups the hex bytes
+by line and statement, and includes special characters to mark different
+types of token (see **FORMATTING**, below).
+
+**dumpbas** does not detokenize BASIC programs or dump information
+about variable names/values. Use **chkbas**\(1) for that. This tool is
+intended to help the user learn about the tokenized BASIC format, or
+as an aid for developing/debugging other tools that process tokenized
+files. It's an alternative to looking at raw hex dumps.
+
+It's assumed the user has at least some knowledge of BASIC's tokenized
+SAVE format. The **Atari BASIC Sourcebook** is a good starting point
+for learning the tokenized format.
+
+OPTIONS
+=======
+
+General Options
+---------------
+**--help**
+ Print usage message and exit.
+
+**--version**
+ Print version number and exit.
+
+**-v**
+ Verbose operation. When displaying a number in verbose mode, it will
+ be prefixed with *$* if it's in hex, or no prefix for decimal.
+
+Dump Options
+------------
+**-s** *start-lineno*
+ Don't dump lines before **start-lineno**. Default: *0*.
+
+**-e** *end-lineno*
+ Don't dump lines after **start-lineno**. Default: *32768*.
+
+**-l** *lineno*
+ Only dump one line. This is exactly equivalent to "**-s** *num* **-e** *num*".
+
+FORMATTING
+==========
+Every byte in the file is displayed in hex. However, they are grouped by line
+and statement, and certain tokens get marker characters to help keep track
+of what they're for. Strings are displayed in both hex and ASCII. Floating
+point constants are displayed as 6 hex bytes with square brackets around them.
+
+If **dumpbas** is run on the following program::
+
+ 10 ? "HOW MANY TIMES";:INPUT N
+ 20 FOR I=1 TO N
+ 30 ? "HELLO ";:? I;"/";N:NEXT I
+ 40 REM WAIT FOR KEY
+ 50 POKE 764,255
+ 60 ? "PRESS ANY KEY"
+ 70 IF PEEK(764)=255 THEN 70
+ 80 POKE 764,255:GOTO 10
+
+**Note:** The "PRESS ANY KEY" was entered in inverse video.
+
+...it produces the following output::
+
+ 10@0021 (0a 00): ^1b
+ >17 !28 $0f =0e "H/48 O/4f W/57 /20 M/4d A/41 N/4e Y/59 /20 T/54 I/49 M/4d E/45 S/53" 15 14:
+ >1b !02 80 16
+ 20@003c (14 00): ^11
+ >11 !08 81 2d #0e [40 01 00 00 00 00] 19 80 16
+ 30@004d (1e 00): ^1d
+ >0f !28 $0f =06 "H/48 E/45 L/4c L/4c O/4f /20" 15 14:
+ >19 !28 81 15 $0f =01 "//2f" 15 80 14:
+ >1d !09 81 16
+ 40@006a (28 00): ^12
+ >12 !00 57 41 49 54 20 46 4f 52 20 4b 45 59 9b
+ 50@007c (32 00): ^15
+ >15 !1f #0e [41 07 64 00 00 00] 12 #0e [41 02 55 00 00 00] 16
+ 60@0091 (3c 00): ^15
+ >15 !28 $0f =0d "|P/d0 |R/d2 |E/c5 |S/d3 |S/d3 | /a0 |A/c1 |N/ce |Y/d9 | /a0 |K/cb |E/c5 |Y/d9" 16
+ 70@00a6 (46 00): ^20
+ >20 !07 46 3a #0e [41 07 64 00 00 00] 2c 22 #0e [41 02 55 00 00 00] 1b #0e [40 70 00 00 00 00] 16
+ 80@00c6 (50 00): ^1f
+ >15 !1f #0e [41 07 64 00 00 00] 12 #0e [41 02 55 00 00 00] 14:
+ >1f !0a #0e [40 10 00 00 00 00] 16
+ 32768@00e5 (00 80): ^0f
+ >0f !19 $0f =07 "H/48 :/3a B/42 ./2e B/42 A/41 S/53" 16
+
+Line header
+-----------
+Each line number begins with the line number (decimal) and offset from
+the start of the file (hex), followed by the 2 hex bytes for the line
+number in parentheses, followed by the line length (hex, preceded by
+^). From the example::
+
+ 10@0021 (0a 00): ^1b
+
+The line number is *10*, the file offset is *0021*. The *0a 00* are 10 again, in
+hex, LSB first. The *^1b* is the line length.
+
+Statements
+----------
+Each statement within the line is displayed separately. Line 10's first statement::
+
+ >17 !28 $0f =0e "H/48 O/4f W/57 /20 M/4d A/41 N/4e Y/59 /20 T/54 I/49 M/4d E/45 S/53" 15 14:
+
+This looks cryptic, but it includes a lot of information.
+
+- *>* is the marker for the statement offset (*17*).
+
+- *!* marks a command token (unmarked tokens are operator
+ tokens). *28* is the token for **?** (short form of PRINT, which has a
+ separate token).
+
+- *$* marks the string-constant token (*0f*).
+
+- *=* marks the string length byte (*0e*).
+
+- The string itself is printed inside double quotes, with each character in
+ both ASCII and hex (e.g. *H/48*).
+
+- The *15* is unmarked. It's the semicolon after the string.
+
+- There's a *:* at the end of the line (after the *14*, which is the end-of-statement
+ token).
+
+Line 10's second statement::
+
+ >1b !02 80 16
+
+The *80* is a token for a variable (variable tokens always have bit 7 set, so they're
+always >= 80 hex). The *16* is the end-of-line token.
+
+Line 20's first statement has an example of a floating point constant::
+
+ #0e [40 01 00 00 00 00]
+
+- *#* marks the token for a FP constant.
+
+- The actual 6-byte constant is surrounded with *[* and *]*.
+
+- The last token is *16*, which is BASIC's end-of-line token.
+
+EXIT STATUS
+===========
+
+0 for success, 1 for failure.
+
+.. include:: manftr.rst
diff --git a/fenders.1 b/fenders.1
index 5bcd3a2..a733a31 100644
--- a/fenders.1
+++ b/fenders.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 "FENDERS" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "FENDERS" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
fenders \- Install Fenders 3-sector loader in boot sectors of an ATR image
.\" RST source for fenders(1) man page. Convert with:
@@ -279,9 +279,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/manftr.rst b/manftr.rst
index e412fd9..3f4ca62 100644
--- a/manftr.rst
+++ b/manftr.rst
@@ -20,9 +20,11 @@ SEE ALSO
**blob2xex**\(1),
**cart2xex**\(1),
**dasm2atasm**\(1),
+**dumpbas**\(1),
**f2toxex**\(1),
**fenders**\(1),
**protbas**\(1),
+**renumbas**\(1),
**rom2cart**\(1),
**unmac65**\(1),
**unprotbas**\(1),
diff --git a/rom2cart.1 b/rom2cart.1
index ec91561..f02c593 100644
--- a/rom2cart.1
+++ b/rom2cart.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 "ROM2CART" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "ROM2CART" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
rom2cart \- Convert a raw ROM image to an Atari800 CART image, or vice versa
.\" RST source for rom2cart(1) man page. Convert with:
@@ -248,9 +248,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/unmac65.1 b/unmac65.1
index c5ce47c..834e5b1 100644
--- a/unmac65.1
+++ b/unmac65.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 "UNMAC65" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "UNMAC65" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
unmac65 \- Detokenize Atari 8-bit Mac/65 SAVEd files.
.\" RST source for unmac65(1) man page. Convert with:
@@ -380,9 +380,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/unprotbas.1 b/unprotbas.1
index 06e8af7..c464b12 100644
--- a/unprotbas.1
+++ b/unprotbas.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 "UNPROTBAS" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "UNPROTBAS" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
unprotbas \- Unprotect LIST-protected Atari 8-bit BASIC programs
.SH SYNOPSIS
@@ -347,9 +347,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/xex.5 b/xex.5
index 14b6883..ee955ea 100644
--- a/xex.5
+++ b/xex.5
@@ -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 "XEX" 5 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "XEX" 5 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
xex \- Atari 8-bit executable file format.
.\" RST source for xex(5) man page. Convert with:
@@ -307,9 +307,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/xex1to2.1 b/xex1to2.1
index a9468cd..aebc0be 100644
--- a/xex1to2.1
+++ b/xex1to2.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 "XEX1TO2" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "XEX1TO2" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
xex1to2 \- Convert an Atari DOS 1.0 executable to a standard Atari executable
.\" RST source for xex1to2(1) man page. Convert with:
@@ -81,9 +81,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/xexamine.1 b/xexamine.1
index 83963b6..f26a92b 100644
--- a/xexamine.1
+++ b/xexamine.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 "XEXAMINE" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "XEXAMINE" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
xexamine \- Show information on Atari 8-bit executables (XEX)
.\" RST source for xexamine(1) man page. Convert with:
@@ -139,9 +139,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/xexcat.1 b/xexcat.1
index 686a463..e3467bc 100644
--- a/xexcat.1
+++ b/xexcat.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 "XEXCAT" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "XEXCAT" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
xexcat \- Concatenate Atari 8-bit executables (XEX) into a single XEX file.
.\" RST source for xexcat(1) man page. Convert with:
@@ -199,9 +199,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/xexsplit.1 b/xexsplit.1
index ec232a5..e2d69b5 100644
--- a/xexsplit.1
+++ b/xexsplit.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 "XEXSPLIT" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "XEXSPLIT" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
xexsplit \- Split a multi-segment Atari 8-bit executable (XEX) into multiple single-segment files.
.\" RST source for xexsplit(1) man page. Convert with:
@@ -192,9 +192,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),
diff --git a/xfd2atr.1 b/xfd2atr.1
index 091dc15..fdc0255 100644
--- a/xfd2atr.1
+++ b/xfd2atr.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 "XFD2ATR" 1 "2024-06-03" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "XFD2ATR" 1 "2024-06-07" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
xfd2atr \- Convert an Atari 8-bit XFD (raw) disk image to an ATR image.
.\" RST source for xfd2atr(1) man page. Convert with:
@@ -120,9 +120,11 @@ Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\
\fBblob2xex\fP(1),
\fBcart2xex\fP(1),
\fBdasm2atasm\fP(1),
+\fBdumpbas\fP(1),
\fBf2toxex\fP(1),
\fBfenders\fP(1),
\fBprotbas\fP(1),
+\fBrenumbas\fP(1),
\fBrom2cart\fP(1),
\fBunmac65\fP(1),
\fBunprotbas\fP(1),