home *** CD-ROM | disk | FTP | other *** search
- /* fv is a binary file editor written by Chris Hooper (cdh@mtu.edu)
- * on 6-2-91 and has gone through many revisions since then.
- * Much inspiration was given by Bill Moore, the first real user!
- *
- * Author: CHRISTOPHER D HOOPER
- *
- * fv source Copyright (c) 1992 - 1998 Chris Hooper
- *
- * Modification and redistribution is strictly prohibited.
- * Sale of this software above media cost is prohibited.
- *
- * Except for above two restrictions, this software may be used for
- * any purpose, commercial or private.
- *
- * Disclaimer: This product is fit for no use, foreign or domestic.
- * Use implies knowledge you intend to destroy something.
- */
-
- #include <stdio.h>
- #include <curses.h>
- #include "main.h"
- #include "screen.h"
- #include "io.h"
-
- #include "pcurses.h"
-
- #ifdef LINT
- # include "lint.h"
- #endif
-
- int (*xaddstr)();
- int (*xmove)();
- int (*xdelwin)();
- int (*xrefresh)();
- int (*xtouchwin)();
- int (*xstandout)();
- int (*xstandend)();
- int (*xclrtoeol)();
- int (*xclrtobot)();
- int (*xclear)();
- int (*xaddch)();
- int (*xgetch)();
- WINDOW *(*xnewwin)();
-
- WINDOW *main_window; /* main display window */
- WINDOW *status_window; /* lower single row status window */
- int status_line;
- extern int zmode;
- extern int Zmode;
- extern ulong cursor_address;
- ulong inbuf_size;
- uchar ascii[256]; /* ascii translation map */
- uchar zmodes[] = ". _~!@#$%^&*";
- char *hex = "0123456789abcdef"; /* hexadecimal translation map */
- char *divmsg[] = {
- " ", " 2", " 4", " 8", " 16", " 32", " 64", " 128", " 256", " 512",
- " 1K", " 2K", " 4K", " 8K", " 16K", " 32K", " 64K", "128K", "256K", "512K",
- " 1M", " 2M", " 4M", " 8M", " 16M", " 32M", " 64M", "128M", "256M", "512M"
- };
-
- int curses_up = 0;
- static void strhex8();
- static void strhex32();
-
- void show_addr(address)
- ulong address;
- {
- register int index;
- ulong temp;
-
- status_range(address, address + buf_size);
-
- #if defined(CURSES_UPDATE_BUG)
- /* evil hack because curses for Linux is broken */
- xclear(stdscr);
- xmove(stdscr, 0, 0);
- xclrtobot(stdscr);
- xtouchwin(main_window);
- xtouchwin(status_window);
- #endif
-
- if (swapbytes | Swapbytes | SWAPBYTES) {
- if (chdis) {
- #ifdef CHAR_COLOR
- wattron(main_window, CHAR_COLOR);
- #endif
- temp = addis * 10 + wpline * 9 * wdis;
- for (index = 0; index < buf_size; index++) {
- if (index % cpline == 0)
- xmove(main_window, index / cpline, temp);
- if (index < inbuf_size)
- xaddch_filt(buffer[index ^ Swapbytes ^ SWAPBYTES]);
- else
- xaddch(main_window, ' ');
- }
- }
-
- for (index = 0; index < (buf_size + 3) / 4; index++) {
- if (addis && ((index % wpline) == 0)) {
- #ifdef ADDR_COLOR
- wattron(main_window, ADDR_COLOR);
- #endif
- xmove(main_window, index / wpline, 0);
- if (index >= (inbuf_size + 3) / 4)
- xaddstr(main_window, " ");
- else {
- if (divmod2)
- temp = (index * 4 + address) &
- ((1 << divisor2) - 1);
- else
- temp = (index * 4 + address) >> divisor2;
-
- if (wdismode)
- sprintf(out_string, "%8d: ", (int) temp);
- else
- sprintf(out_string, "%08x: ", (int) temp);
- xaddstr(main_window, out_string);
- }
- }
- if (wdis) {
- #ifdef WORD_COLOR
- wattron(main_window, WORD_COLOR);
- #endif
- xmove(main_window, index / wpline, addis * 10 +
- (index % wpline) * 9 * wdis);
- if (index < (inbuf_size + 3) / 4)
- switch (wdismode) {
- case 0: /* hex */
- strhex32(out_string, swap32(ibuffer[index ^ (SWAPBYTES | swapbytes) >> 2]));
- out_string[8] = ' ';
- out_string[9] = '\0';
- xaddstr(main_window, out_string);
- break;
- case 1: /* decimal */
- sprintf(out_string, "%8d ", (int)
- swap32(ibuffer[index ^ (swapbytes | SWAPBYTES) >> 2]));
- out_string[9] = '\0';
- xaddstr(main_window, out_string);
- break;
- case 2: /* float */
- (void) sprintf(out_string, "%-9f ",
- *((float *) &ibuffer[index]));
- out_string[9] = '\0';
- xaddstr(main_window, out_string);
- break;
- case 3: /* double */
- if ((index & 1) == 0) {
- (void) sprintf(out_string, "%-17f ",
- *((double *) &ibuffer[index]));
- out_string[17] = '\0';
- xaddstr(main_window, out_string);
- }
- break;
- }
- else
- xaddstr(main_window, " ");
- }
- }
- } else {
- if (chdis) {
- #ifdef CHAR_COLOR
- wattron(main_window, CHAR_COLOR);
- #endif
- temp = addis * 10 + wpline * 9 * wdis;
- for (index = 0; index < buf_size; index++) {
- if (index % cpline == 0)
- xmove(main_window, index / cpline, temp);
- if (index < inbuf_size)
- xaddch_filt(buffer[index]);
- else
- xaddch(main_window, ' ');
- }
- }
-
- for (index = 0; index < (buf_size + 3) / 4; index++) {
- if (addis && ((index % wpline) == 0)) {
- #ifdef ADDR_COLOR
- wattron(main_window, ADDR_COLOR);
- #endif
- xmove(main_window, index / wpline, 0);
- if (index >= (inbuf_size + 3) / 4)
- xaddstr(main_window, " ");
- else {
- if (divmod2)
- temp = (index * 4 + address) &
- ((1 << divisor2) - 1);
- else
- temp = (index * 4 + address) >> divisor2;
-
- if (wdismode)
- sprintf(out_string, "%8d: ", (int) temp);
- else
- sprintf(out_string, "%08x: ", (int) temp);
- xaddstr(main_window, out_string);
- }
- }
- if (wdis) {
- #ifdef WORD_COLOR
- wattron(main_window, WORD_COLOR);
- #endif
- xmove(main_window, index / wpline, addis * 10 + (index % wpline) * 9 * wdis);
- if (index < (inbuf_size + 3) / 4)
- switch (wdismode) {
- case 0:
- strhex32(out_string, ibuffer[index]);
- out_string[8] = ' ';
- out_string[9] = '\0';
- xaddstr(main_window, out_string);
- break;
- case 1:
- (void) sprintf(out_string, "%8d ", (uint) ibuffer[index]);
- out_string[8] = '\0';
- xaddstr(main_window, out_string);
- break;
- case 2:
- (void) sprintf(out_string, "%-9f ",
- *((float *) &ibuffer[index]));
- out_string[8] = '\0';
- xaddstr(main_window, out_string);
- break;
- case 3:
- if ((index & 1) == 0) {
- (void) sprintf(out_string, "%-17f ",
- *((double *) &ibuffer[index]));
- out_string[17] = '\0';
- xaddstr(main_window, out_string);
- }
- break;
- }
- else
- xaddstr(main_window, " ");
- }
- }
- }
- if (!kbuffer_size)
- xrefresh(main_window);
-
- #ifdef NO_COLOR
- wattrset(main_window, 0);
- #endif
- }
-
- void init()
- {
- init_ascii();
-
- if (noscreen) {
- wpline = 8;
- cpline = 32;
- buf_size = 8192;
- #ifdef HUGE_BUFFER
- wpline *= 8;
- cpline *= 8;
- buf_size *= 8;
- #endif
- return;
- }
-
- #if defined(COLOR_CURSES) && defined(Amiga)
- start_color();
- #endif
-
- #ifdef OS9
- if (initscr() == 0)
- LINES = 0;
- #else
- initscr();
- #endif
-
- #if defined(COLOR_CURSES) && !defined(Amiga)
- start_color();
- #endif
-
- if (LINES == 0)
- error_exit("Curses initialization failed.");
-
- curses_up = 1;
- #if defined(COLOR_CURSES)
- /* COLOR 1-7 RED GRN BLUE 1-1000 */
- init_color(WORD_COLOR, 900, 900, 200); /* word disp is yellow */
- init_color(CHAR_COLOR, 900, 900, 900); /* char disp is white */
- init_color(ADDR_COLOR, 420, 920, 840); /* address column is cyan */
- init_color(STAT_COLOR, 1000, 240, 80); /* status area is red */
- init_color(CRSR_COLOR, 688, 859, 984); /* cursor color is blue */
- #endif
-
- #ifdef Dynix
- raw();
- #else
- cbreak();
- #endif
- noecho();
- nonl();
- wclear(stdscr);
- wrefresh(stdscr);
-
- wpline = (COLS - addis * 10 - 1) / (9 * wdis + chdis * 4);
- cpline = wpline << 2;
- buf_size = (LINES - 1) * cpline;
-
- status_line = LINES - 1;
-
- main_window = xnewwin(LINES - 1, COLS, status_line ? 0 : 1, 0);
- status_window = xnewwin(1, COLS, status_line, 0);
-
- #if defined(Solaris2) || defined(Amiga) || defined(SYSV)
- keypad(stdscr, TRUE);
- keypad(main_window, TRUE);
- #endif
-
- #ifdef STAT_COLOR
- wattrset(status_window, STAT_COLOR);
- #endif
-
- #if defined(Solaris2) || defined(Amiga) || defined(SYSV)
- leaveok(main_window, TRUE);
- #endif
- leaveok(status_window, TRUE);
-
- status_mode();
- }
-
- void de_init()
- {
- if (!curses_up)
- return;
-
- wclear(stdscr);
- wrefresh(stdscr);
- echo();
- nl();
- endwin();
- curses_up = 0;
- }
-
- void update_cursor(mode)
- int mode;
- {
- int index;
- int row;
- int offset;
- int ioffset;
- int column;
- int icoffset;
-
- if (noscreen)
- return;
-
- if (mode == ON) {
- #ifdef CRSR_COLOR
- wattrset(main_window, CRSR_COLOR);
- #endif
- xstandout(main_window);
- } else
- xstandend(main_window);
-
- offset = ALIGNED(cursor_address - view_address);
-
- if (chdis) {
- #ifdef CHAR_COLOR
- if (mode == OFF)
- wattron(main_window, CHAR_COLOR);
- #endif
- for (index = 0; index < alignment; index++) {
- ioffset = (offset + index) ^ Swapbytes;
- xmove(main_window, ioffset / cpline, addis * 10 +
- wpline * 9 * wdis + (ioffset % cpline));
- xaddch_filt(buffer[(offset + index) ^ SWAPBYTES]);
- }
- }
-
-
- if (wdis) {
- #ifdef WORD_COLOR
- if (mode == OFF)
- wattron(main_window, WORD_COLOR);
- #endif
- ioffset = offset ^ swapbytes;
-
- if (alignment == 8)
- icoffset = (ioffset % cpline) & ~3;
- else
- icoffset = ALIGNED(ioffset % cpline);
-
- column = (icoffset >> 2) + (icoffset << 1) + addis * 10;
- row = ioffset / cpline;
-
- xmove(main_window, row, column);
- switch (wdismode) {
- case 0: /* hex */
- if (alignment == 1)
- strhex8(out_string, (ulong) buffer[offset ^ SWAPBYTES]);
- else if (alignment == 2)
- if (swapbytes & 1) {
- #ifdef LITTLE_ENDIAN
- strhex8(out_string + 2, (ulong) buffer[offset ^ SWAPBYTES]);
- #endif
- strhex8(out_string, (ulong) buffer[(offset + 1) ^ SWAPBYTES]);
- #ifndef LITTLE_ENDIAN
- strhex8(out_string + 2, (ulong) buffer[offset ^ SWAPBYTES]);
- #endif
- } else {
- #ifdef LITTLE_ENDIAN
- strhex8(out_string + 2, (ulong) buffer[(offset + 1) ^ SWAPBYTES]);
- #endif
- strhex8(out_string, (ulong) buffer[offset ^ SWAPBYTES]);
- #ifndef LITTLE_ENDIAN
- strhex8(out_string + 2, (ulong) buffer[(offset + 1) ^ SWAPBYTES]);
- #endif
- }
- else if (alignment == 4)
- strhex32(out_string,
- swap32(ibuffer[(offset ^ SWAPBYTES) >> 2]));
- else { /* alignment == 8 */
- strhex32(out_string,
- swap32(ibuffer[(offset ^ SWAPBYTES) >> 2]));
- offset += 4;
- ioffset = offset ^ swapbytes;
- if (ioffset < buf_size) {
- xaddstr(main_window, out_string);
- icoffset = (ioffset % cpline) & ~3;
- column = (icoffset >> 2) + (icoffset << 1) +
- addis * 10;
- row = ioffset / cpline;
- xmove(main_window, row, column);
- strhex32(out_string,
- swap32(ibuffer[(offset ^ SWAPBYTES) >> 2]));
- }
- }
- break;
- case 1: /* integer */
- (void) sprintf(out_string, "%8d", (int)
- swap32(ibuffer[(ioffset ^ SWAPBYTES) >> 2]));
- out_string[8] = '\0';
- break;
- case 2: /* float */
- (void) sprintf(out_string, "%-8f",
- *((float *) &ibuffer[offset >> 2]));
- if (strlen(out_string) > 8) {
- if (mode == ON)
- out_string[7] = '*';
- out_string[8] = '\0';
- }
- break;
- case 3: /* double */
- (void) sprintf(out_string, "%-17f",
- *((double *) &ibuffer[offset >> 2]));
- if (strlen(out_string) > 17) {
- if (mode == ON)
- out_string[16] = '*';
- out_string[17] = '\0';
- }
- break;
- }
-
- xaddstr(main_window, out_string);
- }
-
- if (mode == ON) {
- #ifdef NO_COLOR
- wattrset(main_window, 0);
- #endif
- xstandend(main_window);
- }
- }
-
-
- void init_ascii()
- {
- uchar dot;
- int index;
-
- dot = zmodes[zmode];
-
- ascii[0] = zmodes[Zmode];
-
- for (index = 1; index < 32; index++)
- ascii[index] = dot;
-
- ascii['\011'] = ' ';
- ascii['\012'] = ' ';
- ascii['\015'] = ' ';
-
- for (; index < 128; index++)
- ascii[index] = index;
-
- #ifdef SHOW_EXTASCII
- for (; index < 161; index++)
- ascii[index] = dot;
-
- do {
- index++;
- ascii[index] = index;
- } while (index < 255);
- #else
- for (index = 127; index <= 255; index++)
- ascii[index] = dot;
- #endif
- }
-
- void status_range(range1, range2)
- ulong range1;
- ulong range2;
- {
- char out_string[32];
-
- if (noscreen)
- return;
-
- if (COLS < 28)
- return;
-
- leaveok(status_window, FALSE);
-
- if (divmod) {
- range1 &= ((1 << divisor) - 1);
- range2 &= ((1 << divisor) - 1);
- xstandout(status_window);
- } else {
- range1 >>= divisor;
- range2 >>= divisor;
- }
- xmove(status_window, 0, COLS - 21);
- xaddstr(status_window, divmsg[divisor]);
- if (divmod && !divmod2)
- xstandend(status_window);
- else if (!divmod && divmod2)
- xstandout(status_window);
-
- xaddch(status_window, ' ');
- xaddstr(status_window, divmsg[divisor2]);
- if (divmod2)
- xstandend(status_window);
-
- xmove(status_window, 0, 19);
- xaddch(status_window, ' ');
- xmove(status_window, 0, 0);
- if (wdismode)
- sprintf(out_string, "[%8d-%8d]", (uint) range1, (uint) range2);
- else
- sprintf(out_string, "[%08x-%08x]", (uint) range1, (uint) range2);
- xaddstr(status_window, out_string);
-
- xrefresh(status_window);
-
- leaveok(status_window, TRUE);
- }
-
- void status_filename()
- {
- int len;
- int namelen;
- int tildes = 0;
- char *ptr = filename[filenum];
-
- if (COLS < 28)
- return;
-
- xmove(status_window, 0, 20);
- switch (wdismode) {
- case 0: /* hex */
- sprintf(out_string, "(%x of %x) ",
- (uint) cursor_address, (uint) fend);
- break;
- case 1: /* decimal */
- default: /* all other types */
- sprintf(out_string, "(%d of %d) ",
- (uint) cursor_address, (uint) fend);
- break;
- }
- len = strlen(out_string);
- namelen = strlen(ptr);
- while ((len + namelen + tildes > COLS - 42) && namelen) {
- tildes = 2;
- ptr++;
- namelen--;
- }
- xaddstr(status_window, out_string);
- if (tildes)
- xaddstr(status_window, "~~");
- xaddstr(status_window, ptr);
- xrefresh(status_window);
- }
-
-
- void status_mode()
- {
- if (noscreen)
- return;
-
- if (COLS < 18)
- return;
-
- xmove(status_window, 0, COLS - 11);
-
- if (Swapbytes | SWAPBYTES)
- xstandout(status_window);
- xaddch(status_window, " w?l???q w?l???q W?L???Q????????"[
- swapbytes | Swapbytes | SWAPBYTES | (swapmode << 3)]);
- if (Swapbytes | SWAPBYTES)
- xstandend(status_window);
-
- xaddch(status_window, '0' + alignment);
- if ((ronly | force_ronly) && !force_write)
- xaddstr(status_window, "R");
- else
- xaddstr(status_window, "W");
-
- xaddstr(status_window, " ");
-
- if (mode == STRING)
- xaddstr(status_window, "Str");
- else
- xaddstr(status_window, "Num");
- switch (wdismode) {
- case 0:
- xaddstr(status_window, "Hex");
- break;
- case 1:
- xaddstr(status_window, "Dec");
- break;
- case 2:
- xaddstr(status_window, "Flt");
- break;
- case 3:
- xaddstr(status_window, "Dbl");
- break;
- case 4:
- xaddstr(status_window, "Oct");
- break;
- }
-
- xtouchwin(status_window);
- xrefresh(status_window);
- }
-
-
- ulong swap32(x)
- ulong x;
- {
- if ((swapbytes | SWAPBYTES) == 0)
- return(x);
-
- if ((swapbytes | SWAPBYTES) > 1) /* long and quad */
- return((x >> 24) | (x << 24) |
- ((x << 8) & (255 << 16)) |
- ((x >> 8) & (255 << 8)));
-
- /* must be swap words */
- return(((x >> 8) & 0x00ff00ff) |
- ((x << 8) & 0xff00ff00));
- }
-
- int select_file()
- {
- char ch;
- int index;
- int count;
- int tlen;
- int current = filenum;
- static int lowest = 0;
-
- if (noscreen)
- return(filenum);
-
- leaveok(status_window, FALSE);
-
- do {
- xmove(status_window, 0, 0);
- xclrtoeol(status_window);
- xmove(status_window, 0, 0);
- xaddstr(status_window, "File: ");
- if (current < lowest)
- lowest = current;
- count = strlen(filename[current]) + 1;
- for (index = current - 1; index >= lowest; index--) {
- tlen = strlen(filename[index]) + 1;
- if (tlen + count > COLS - 6) {
- lowest = index + 1;
- break;
- } else
- count += tlen;
- }
-
- for (index = lowest; index < current; index++) {
- xaddstr(status_window, filename[index]);
- xaddch(status_window, ' ');
- }
- xstandout(status_window);
- xaddstr(status_window, filename[current]);
- xstandend(status_window);
-
- for (index = current + 1; index < filenames; index++) {
- tlen = strlen(filename[index]) + 1;
- if (tlen + count > COLS - 6)
- break;
- else {
- count += tlen;
- xaddch(status_window, ' ');
- xaddstr(status_window, filename[index]);
- }
- }
- xmove(status_window, 0, COLS - 1);
- xrefresh(status_window);
-
- ch = get_key();
- switch (ch) {
- case 'h': /* left one file */
- case 'k':
- case 'b':
- case 2: /* ^B */
- case 8: /* ^H - backspace */
- if (current > 0)
- current--;
- break;
- case 'l': /* right one file */
- case 'j':
- case 'f':
- case ' ': /* space */
- case 6: /* ^F */
- if (current < filenames - 1)
- current++;
- break;
- case 'q': /* quit without selecting */
- case 24: /* ^X */
- case 27: /* ESC */
- leaveok(status_window, TRUE);
- return(filenum);
- case 10: /* ^J */
- ch = 13; /* ^M */
- break;
- case '0':
- case '^':
- current = 0;
- break;
- case '$':
- current = filenames - 1;
- break;
- case '%':
- current = filenum;
- break;
- case 9: /* ^I - Tab */
- current = (current + 1) % filenames;
- break;
- case '?':
- help_me(4);
- xtouchwin(status_window);
- xrefresh(status_window);
- xtouchwin(main_window);
- xrefresh(main_window);
- break;
- case 12: /* ^L */
- xclear(stdscr);
- xmove(stdscr, 0, 0);
- xclrtobot(stdscr);
- xtouchwin(main_window);
- xtouchwin(status_window);
- xrefresh(stdscr);
- xrefresh(main_window);
- xrefresh(status_window);
- break;
- }
- } while (ch != 13); /* ^M selects */
-
- leaveok(status_window, TRUE);
-
- return(current);
- }
-
- int dummy()
- {
- return(0);
- }
-
-
- WINDOW *wdummy()
- {
- return(0);
- }
-
- int getdummy()
- {
- static last = 0;
-
- last = !last;
-
- if (last)
- return(27); /* ESC */
- else
- return(24); /* ^X */
- }
-
- void assign_dummy()
- {
- xaddstr = dummy;
- xmove = dummy;
- xdelwin = dummy;
- xrefresh = dummy;
- xtouchwin = dummy;
- xstandout = dummy;
- xstandend = dummy;
- xclrtoeol = dummy;
- xclrtobot = dummy;
- xclear = dummy;
- xaddch = dummy;
- xgetch = getdummy;
- xnewwin = wdummy;
- }
-
- void assign_curses()
- {
- xaddstr = lwaddstr;
- xmove = wmove;
- xdelwin = delwin;
- xrefresh = wrefresh;
- xtouchwin = touchwin;
- xstandout = lwstandout;
- xstandend = lwstandend;
- xclrtoeol = wclrtoeol;
- xclrtobot = wclrtobot;
- xclear = wclear;
- xaddch = lwaddch;
- xgetch = wgetch;
- xnewwin = newwin;
- }
-
- static void strhex8(optr, value)
- char *optr;
- ulong value;
- {
- optr[2] = '\0';
- optr[1] = hex[value & 15];
- value >>= 4;
- optr[0] = hex[value & 15];
- }
-
- static void strhex32(optr, value)
- char *optr;
- ulong value;
- {
- #ifdef LITTLE_ENDIAN
- value = (value >> 24) | (value << 24) |
- ((value << 8) & (255 << 16)) |
- ((value >> 8) & (255 << 8));
- #endif
- optr[8] = '\0';
- optr[7] = hex[value & 15];
- value >>= 4;
- optr[6] = hex[value & 15];
- value >>= 4;
- optr[5] = hex[value & 15];
- value >>= 4;
- optr[4] = hex[value & 15];
- value >>= 4;
- optr[3] = hex[value & 15];
- value >>= 4;
- optr[2] = hex[value & 15];
- value >>= 4;
- optr[1] = hex[value & 15];
- value >>= 4;
- optr[0] = hex[value & 15];
- }
-
- #ifdef OS9
- int wstandout(WINDOW *win)
- {
- return(wattron(win, W_STANDOUT));
- }
-
- int wstandend(WINDOW *win)
- {
- return(wattrset(win, 0));
- }
- #endif
-
- #if defined(Linux) || defined(FreeBSD)
- int lwaddstr(WINDOW *win, char *str)
- {
- return(waddstr(win, str));
- }
- #endif /* Linux || FreeBSD */
-
- #if defined(Win32)
- int lwclear(WINDOW *win)
- {
- return(wclear(win));
- }
-
- int lwaddch(WINDOW *win, chtype ch)
- {
- return(waddch(win, ch));
- }
-
- int ltouchwin(WINDOW *win)
- {
- return(touchwin(win));
- }
-
- int lwstandout(WINDOW *win)
- {
- return(wstandout(win));
- }
-
- int lwstandend(WINDOW *win)
- {
- return(wstandend(win));
- }
- #endif /* Win32 */
-