From 012edc2ecfb3c77707adf1c26a192fd724a66594 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Sun, 30 Jun 2024 02:01:44 -0400 Subject: a8xd: add -g (GRAPHICS 1) option. --- a8xd.1 | 27 +++++++++++++++++++++++++- a8xd.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- a8xd.rst | 25 ++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 15 deletions(-) diff --git a/a8xd.1 b/a8xd.1 index 6e2f322..a02fc9e 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-29" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "A8XD" 1 "2024-06-30" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME a8xd \- Atari 8-bit ATASCII-aware hex dump .SH SYNOPSIS @@ -65,8 +65,16 @@ Without \fIinfile\fP, or if \fIinfile\fP is \fB\-\fP, \fBa8xd\fP reads from stan .SH OPTIONS .INDENT 0.0 .TP +.B \-a +ANTIC mode: treat the input as screen bytes. Can usefully be combined +with \fB\-g\fP\&. +.TP .B \-i Print XL/XE International Character Set conversions instead of ATASCII. +.TP +.B \-g +Graphics mode. Changes the colorization so it looks like \fIGRAPHICS 1\fP (or 2) +on the Atari. .UNINDENT .INDENT 0.0 .TP @@ -117,6 +125,23 @@ Show version number and exit. .UNINDENT .SH NOTES .sp +\fBa8xd\fP requires the terminal emulator to support UTF\-8 and use a +font with the necessary glyphs. The author has tested extensively +with \fBurxvt\fP(1) (aka \fBrxvt\-unicode\fP) and \fBxterm\fP(1), using +the \fIDeja Vu Sans Mono\fP, \fIJetBrains Mono\fP, \fILiberation Mono\fP, +and \fISymbola\fP fonts. Also \fBkitty\fP(1), \fBxfce4\-terminal\fP(1), +KDE/Plasma 5\(aqs \fBkonsole\fP(1), \fBgnome\-terminal\fP(1) 3.43.90, and +\fBst\fP(1) from suckless.org have been lightly tested and seem to work +fine. Even the Linux console works, except that you won\(aqt be able to +find a console font with all the necessary glyphs (I may create one +someday). +.sp +\fBa8xd\fP only supports terminals that use ANSI\-style escape sequences +for color and inverse video. This isn\(aqt much of a limitation, since +all modern X, Wayland, Mac, etc terminal emulators have support for +this... but it might annoy you if you\(aqre trying to use an Atari ST +with a VT52 emulator as a serial terminal. Sorry. +.sp \fBa8xd\fP supports a useful subset of \fBxxd\fP(1) options. The main things missing are: .INDENT 0.0 diff --git a/a8xd.c b/a8xd.c index 625152f..e543929 100644 --- a/a8xd.c +++ b/a8xd.c @@ -16,6 +16,7 @@ const char *byte_format = "%02x"; int verbose = 0, color = 1, disp_offset = 0, maxlen = 0; int seek_whence = 0, seekpos = 0, filepos = 0, limit = 0; +int graphics = 0; const char *self; @@ -110,12 +111,27 @@ char *get_color(unsigned char c) { unsigned char c7 = c & 0x7f; static char outbuf[32]; - 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 */ + 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; } else { - color = 2; + 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 */ + } } if(color) { @@ -127,6 +143,24 @@ char *get_color(unsigned char c) { return outbuf; } +/* in GR.1 or GR.2: + $00-$1F get displayed in green, as $20-$2F. + $20-$5F get displayed in orange, as themselves. + $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]; + c &= 0x7f; + if(c < 0x20) + c += 0x20; + else if(c >= 0x60) + c -= 0x20; + result[0] = c; + result[1] = 0; + return result; +} + void fake_seek(FILE *input) { char junkbuf[1024]; int pos = 0, chunksize; @@ -168,6 +202,7 @@ void seek_input(FILE *input) { void dump_line(const unsigned char *buf, int len) { char hex[1024], asc[1024]; int hpos = 0, apos = 0, count = len; + unsigned char c, inv; memset(hex, 0, sizeof(hex)); memset(asc, 0, sizeof(asc)); @@ -176,17 +211,20 @@ void dump_line(const unsigned char *buf, int len) { fputs(": ", stdout); while(len) { - if(color) hpos += sprintf(hex + hpos, "%s", get_color(*buf)); - if(*buf & 0x80) hpos += sprintf(hex + hpos, "%s", inverse_on); - hpos += sprintf(hex + hpos, byte_format, *buf); - if(color || *buf & 0x80) hpos += sprintf(hex + hpos, "%s", color_off); + c = *buf; + inv = !graphics && (c & 0x80); + + 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, c); + if(color || inv) hpos += sprintf(hex + hpos, "%s", color_off); hex[hpos++] = ' '; if(count - len == 7) hex[hpos++] = ' '; - if(color) apos += sprintf(asc + apos, "%s", get_color(*buf)); - if(*buf & 0x80) apos += sprintf(asc + apos, "%s", inverse_on); - apos += sprintf(asc + apos, "%s", table[*buf & 0x7f]); - if(color || *buf & 0x80) apos += sprintf(asc + apos, "%s", color_off); + 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); filepos++; buf++; @@ -245,7 +283,7 @@ int main(int argc, char **argv) { exit(0); } - while( (opt = getopt(argc, argv, "vhimus:o:l:")) != -1) { + while( (opt = getopt(argc, argv, "vhimus:o:l:g")) != -1) { switch(opt) { case 'v': verbose = 1; break; case 'h': print_help(); exit(0); break; @@ -255,6 +293,7 @@ int main(int argc, char **argv) { case 's': parse_seek_arg(optarg); break; case 'o': disp_offset = parse_offset_arg(optarg); break; case 'l': limit = parse_limit_arg(optarg); break; + case 'g': graphics = 1; break; default: print_help(); exit(1); break; } } diff --git a/a8xd.rst b/a8xd.rst index ec8868d..057ffbe 100644 --- a/a8xd.rst +++ b/a8xd.rst @@ -41,9 +41,17 @@ Without *infile*, or if *infile* is **-**, **a8xd** reads from standard input. OPTIONS ======= +-a + ANTIC mode: treat the input as screen bytes. Can usefully be combined + with **-g**. + -i Print XL/XE International Character Set conversions instead of ATASCII. +-g + Graphics mode. Changes the colorization so it looks like *GRAPHICS 1* (or 2) + on the Atari. + -l *len* Stop after dumping *len* bytes. *len* may be given in decimal or hex (with leading *0x* or *$*). @@ -84,6 +92,23 @@ OPTIONS NOTES ===== +**a8xd** requires the terminal emulator to support UTF-8 and use a +font with the necessary glyphs. The author has tested extensively +with **urxvt**\(1) (aka **rxvt-unicode**) and **xterm**\(1), using +the *Deja Vu Sans Mono*, *JetBrains Mono*, *Liberation Mono*, +and *Symbola* fonts. Also **kitty**\(1), **xfce4-terminal**\(1), +KDE/Plasma 5's **konsole**\(1), **gnome-terminal**\(1) 3.43.90, and +**st**\(1) from suckless.org have been lightly tested and seem to work +fine. Even the Linux console works, except that you won't be able to +find a console font with all the necessary glyphs (I may create one +someday). + +**a8xd** only supports terminals that use ANSI-style escape sequences +for color and inverse video. This isn't much of a limitation, since +all modern X, Wayland, Mac, etc terminal emulators have support for +this... but it might annoy you if you're trying to use an Atari ST +with a VT52 emulator as a serial terminal. Sorry. + **a8xd** supports a useful subset of **xxd**\(1) options. The main things missing are: -- cgit v1.2.3