aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--a8xd.114
-rw-r--r--a8xd.c134
-rw-r--r--a8xd.rst12
3 files changed, 108 insertions, 52 deletions
diff --git a/a8xd.1 b/a8xd.1
index 69d3534..3b67077 100644
--- a/a8xd.1
+++ b/a8xd.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 "A8XD" 1 "2024-06-30" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "A8XD" 1 "2024-07-01" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
a8xd \- Atari 8-bit ATASCII-aware hex dump
.SH SYNOPSIS
@@ -67,16 +67,16 @@ Without \fIinfile\fP, or if \fIinfile\fP is \fB\-\fP, \fBa8xd\fP reads from stan
.TP
.B \-a
ANTIC mode: treat the input as screen bytes (aka "internal codes")
-rather than ATASCII. Can usefully be combined with \fB\-g\fP\&.
+rather than ATASCII. Can usefully be combined with \fB\-g\fP or \fB\-f\fP\&.
+.TP
+.B \-f
+Like \fB\-g\fP, but using the top half of the character set. This is
+what you\(aqd see on the Atari with \fIGRAPHICS 1:POKE 756,226\fP\&.
.TP
.B \-g
-Graphics mode. Changes the character codes and colorization so it
+Graphics mode. Changes the printed characters and colorization so it
looks like \fIGRAPHICS 1\fP (or 2) on the Atari.
.TP
-.B \-G
-\fINot yet implemeted\fP\&. Like \fB\-g\fP, but using the top half of the character set. This is
-what you\(aqd see on the Atari with \fIGRAPHICS 1:POKE 756,226\fP\&.
-.TP
.B \-i
Print XL/XE International Character Set conversions instead of ATASCII.
.UNINDENT
diff --git a/a8xd.c b/a8xd.c
index f887d05..1a48312 100644
--- a/a8xd.c
+++ b/a8xd.c
@@ -14,6 +14,15 @@
#define UC_WORD_FMT "%04X"
#define UC_BYTE_FMT "%02X"
+/* colors. don't use black or white: one or the other is likely
+ the terminal's text color already.
+ don't use blue because it's hard to read. */
+#define C_RED 1
+#define C_GREEN 2
+#define C_YELLOW 3
+#define C_PURPLE 5
+#define C_CYAN 6
+
/* translation table (see atables.c), choices are
ata2utf, ics2utf, or magazine. */
const char **table = ata2utf;
@@ -31,7 +40,7 @@ const char *byte_format = LC_BYTE_FMT;
/* command line options change these. */
int verbose = 0, color = 1, disp_offset = 0, maxlen = 0;
int seek_whence = 0, seekpos = 0, filepos = 0, limit = 0;
-int graphics = 0, screencodes = 0;
+int graphics = 0, screencodes = 0, high_font = 0;
const char *self;
@@ -49,7 +58,7 @@ void die(const char *msg) {
}
void print_help(void) {
- printf("Usage:\n %s [-a] [-g] [-i] [-l limit] [-m] [-o offset] [-s [-]seek] [-u] [-v] [file]\n", self);
+ printf("Usage:\n %s [-a] [-f] [-g] [-i] [-l limit] [-m] [-o offset] [-s [-]seek] [-u] [-v] [file]\n", self);
printf(" -a: Input is ANTIC screencodes (default is ATASCII).\n");
printf(" -g: GR.1/2 style colorization.\n");
printf(" -i: Input is XL intl charset (default is ATASCII).\n");
@@ -128,32 +137,50 @@ FILE *open_input(const char *file) {
return input;
}
+int get_text_color(unsigned char c) {
+ unsigned char c7 = c & 0x7f;
+
+ if(c == 0 || c == 0x9b) {
+ return C_RED;
+ } else if((c7 >= 0x1b && c7 <= 0x1f) || (c7 >= 0x7d)) {
+ /* cursor control characters:
+ - 0x1b (esc)
+ - 0x1c-0x1f (arrows), 0x9c-0x9f
+ - 0x7d/0xf3 (cls, bell)
+ - 0x7e, 0xfe (delete line, char)
+ - 0x7f, 0xff (tab, insert char)
+ */
+ return C_PURPLE;
+ } else if(c7 < 32 || c7 == 0x60 || c7 == 0x7b) {
+ return C_YELLOW;
+ } else {
+ return C_GREEN;
+ }
+}
+
+int get_graphics_color(unsigned char c) {
+ if(c < 0x20)
+ return C_GREEN;
+ else if(c >= 0x20 && c < 0x60)
+ return C_YELLOW;
+ else if(c >= 0x60 && c < 0x80)
+ return C_GREEN;
+ else if(c >= 0x80 && c < 0xa0)
+ return C_RED;
+ else if(c >= 0xa0 && c < 0xe0)
+ return C_CYAN;
+ else /* c >= 0xe0 */
+ return C_RED;
+}
+
char *get_color(unsigned char c) {
int color;
- unsigned char c7 = c & 0x7f;
static char outbuf[32];
if(graphics) {
- if(c < 0x20)
- color = 2;
- else if(c >= 0x20 && c < 0x60)
- color = 3;
- else if(c >= 0x60 && c < 0x80)
- color = 2;
- else if(c >= 0x80 && c < 0xa0)
- color = 1;
- else if(c >= 0xa0 && c < 0xe0)
- color = 6; /* cyan (blue is too dark on most terminals) */
- else /* c >= 0xe0 */
- color = 1;
+ color = get_graphics_color(c);
} else {
- if(c == 0 || c == 0x9b) {
- color = 1; /* red */
- } else if(c7 < 32 || c7 == 0x60 || c7 == 0x7b || c7 == 0x7d || c7 == 0x7e || c7 == 0x7f) {
- color = 3; /* yellow/orange */
- } else {
- color = 2; /* green */
- }
+ color = get_text_color(c);
}
if(color) {
@@ -171,16 +198,22 @@ char *get_color(unsigned char c) {
$60-$7F get displayed in green, as $40-$5F.
for $80-$FF, same thing, but green is red, and orange is blue.
*/
-char *get_graphics(unsigned char c) {
- static char result[2];
+unsigned char get_graphics(unsigned char c) {
c &= 0x7f;
if(c < 0x20)
c += 0x20;
else if(c >= 0x60)
c -= 0x20;
- result[0] = c;
- result[1] = 0;
- return result;
+ return c;
+}
+
+unsigned char get_high_graphics(unsigned char c) {
+ c &= 0x7f;
+ if(c >= 0x20 && c < 0x40)
+ c -= 0x20;
+ else if(c >= 0x40)
+ c += 0x20;
+ return c;
}
unsigned char screen2ata(unsigned char c) {
@@ -231,6 +264,19 @@ void seek_input(FILE *input) {
}
}
+void append_str_f(char *buf, int *pos, const char *fmt, const char *str) {
+ *pos += sprintf(buf + *pos, fmt, str);
+}
+
+void append_str(char *buf, int *pos, const char *str) {
+ append_str_f(buf, pos, "%s", str);
+}
+
+void append_hex(char *buf, int *pos, const unsigned char byte) {
+ *pos += sprintf(buf + *pos, byte_format, byte);
+}
+
+
void dump_line(const unsigned char *buf, int len) {
char hex[1024], asc[1024];
int hpos = 0, apos = 0, count = len;
@@ -247,23 +293,32 @@ void dump_line(const unsigned char *buf, int len) {
inv = !graphics && (c & 0x80);
if(screencodes) c = screen2ata(c);
- if(color) hpos += sprintf(hex + hpos, "%s", get_color(c));
- if(inv) hpos += sprintf(hex + hpos, "%s", inverse_on);
- hpos += sprintf(hex + hpos, byte_format, *buf); /* *buf here, not c! */
- if(color || inv) hpos += sprintf(hex + hpos, "%s", color_off);
- hex[hpos++] = ' ';
- if(count - len == 7) hex[hpos++] = ' ';
+ hpos += printf("%s", get_color(c));
+ if(inv) hpos += printf("%s", inverse_on);
+ hpos += printf(byte_format, *buf); /* *buf here, not c! */
+ if(color || inv) hpos += printf("%s", color_off);
+ putchar(' ');
+ hpos++;
+ if(count - len == 7) {
+ putchar(' ');
+ hpos++;
+ }
- if(color) apos += sprintf(asc + apos, "%s", get_color(c));
- if(inv) apos += sprintf(asc + apos, "%s", inverse_on);
- apos += sprintf(asc + apos, "%s", (graphics ? get_graphics(c) : table[c & 0x7f]));
- if(color || inv) apos += sprintf(asc + apos, "%s", color_off);
+ if(color) append_str(asc, &apos, get_color(c));
+ if(inv) append_str(asc, &apos, inverse_on);
+ if(graphics) {
+ if(high_font)
+ c = get_high_graphics(c);
+ else
+ c = get_graphics(c);
+ }
+ apos += sprintf(asc + apos, "%s", table[c & 0x7f]);
+ if(color || inv) append_str(asc, &apos, color_off);
filepos++;
buf++;
len--;
}
- printf("%s", hex);
/* what shall we use to fill the empty spaces? */
if(count < 8) putchar(' ');
@@ -316,7 +371,7 @@ int main(int argc, char **argv) {
exit(0);
}
- while( (opt = getopt(argc, argv, "vhimus:o:l:ga")) != -1) {
+ while( (opt = getopt(argc, argv, "vhimus:o:l:gaf")) != -1) {
switch(opt) {
case 'v': verbose = 1; break;
case 'h': print_help(); exit(0); break;
@@ -328,6 +383,7 @@ int main(int argc, char **argv) {
case 'l': limit = parse_limit_arg(optarg); break;
case 'g': graphics = 1; break;
case 'a': screencodes = 1; break;
+ case 'f': graphics = high_font = 1; break;
default: print_help(); exit(1); break;
}
}
diff --git a/a8xd.rst b/a8xd.rst
index c8730c6..71d3855 100644
--- a/a8xd.rst
+++ b/a8xd.rst
@@ -43,16 +43,16 @@ OPTIONS
-a
ANTIC mode: treat the input as screen bytes (aka "internal codes")
- rather than ATASCII. Can usefully be combined with **-g**.
+ rather than ATASCII. Can usefully be combined with **-g** or **-f**.
+
+-f
+ Like **-g**, but using the top half of the character set. This is
+ what you'd see on the Atari with *GRAPHICS 1:POKE 756,226*.
-g
- Graphics mode. Changes the character codes and colorization so it
+ Graphics mode. Changes the printed characters and colorization so it
looks like *GRAPHICS 1* (or 2) on the Atari.
--G
- *Not yet implemeted*. Like **-g**, but using the top half of the character set. This is
- what you'd see on the Atari with *GRAPHICS 1:POKE 756,226*.
-
-i
Print XL/XE International Character Set conversions instead of ATASCII.