diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | a8eol.1 | 4 | ||||
-rw-r--r-- | a8utf8.1 | 4 | ||||
-rw-r--r-- | atascii.7 | 4 | ||||
-rw-r--r-- | atr2xfd.1 | 4 | ||||
-rw-r--r-- | atrsize.1 | 4 | ||||
-rw-r--r-- | axe.1 | 4 | ||||
-rw-r--r-- | bas.c | 2 | ||||
-rw-r--r-- | blob2c.1 | 4 | ||||
-rw-r--r-- | blob2xex.1 | 4 | ||||
-rw-r--r-- | cart2xex.1 | 4 | ||||
-rw-r--r-- | dasm2atasm.1 | 4 | ||||
-rw-r--r-- | dumpbas.1 | 267 | ||||
-rw-r--r-- | dumpbas.c | 160 | ||||
-rw-r--r-- | dumpbas.rst | 163 | ||||
-rw-r--r-- | fenders.1 | 4 | ||||
-rw-r--r-- | manftr.rst | 2 | ||||
-rw-r--r-- | rom2cart.1 | 4 | ||||
-rw-r--r-- | unmac65.1 | 4 | ||||
-rw-r--r-- | unprotbas.1 | 4 | ||||
-rw-r--r-- | xex.5 | 4 | ||||
-rw-r--r-- | xex1to2.1 | 4 | ||||
-rw-r--r-- | xexamine.1 | 4 | ||||
-rw-r--r-- | xexcat.1 | 4 | ||||
-rw-r--r-- | xexsplit.1 | 4 | ||||
-rw-r--r-- | xfd2atr.1 | 4 |
26 files changed, 659 insertions, 23 deletions
@@ -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: @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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."); } @@ -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), @@ -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), @@ -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 @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), @@ -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), |