home *** CD-ROM | disk | FTP | other *** search
- /*
- * Hexidecimal screen editor:
- * NOTE: Must be compiled in SMALL model!
- *
- * Special Keys:
- * PgDn = Page forward
- * PgUp = Page backward
- * CTRL-PgUp = Goto start of file
- * CTRL-PgDn = Goto end of file
- * Home = Goto start of line
- * End = Goto end of line
- * Ins = Insert a byte at cursor location
- * Del = Delete a byte at cursor location
- * F1 = Toggle between HEX/ASCII editing
- * CTRL-Home = Redraw screen
- * F10/Keypad '+' = Enter command
- * F9/Keypad '-' = Re-execute last command
- * Commands:
- * G<xxxx> = Goto address xxxx
- * Q = Quit editor
- * QQ = Quit even if unsaved changes
- * W[file] = Write file
- * X[file] = Exit and write file
- * ?xx ... = Search for HEX byte pattern
- * /text... = Search for ASCII text
- *
- * Copyright 1983-1994 Dave Dunfield
- * All rights reserved
- *
- * Permission granted for personal (non-commercial) use only.
- *
- * Compile command: cc hexed -fops
- */
- #include <stdio.h>
- #include <video.h>
- #include <file.h>
-
- #define ALLOCATION 60001
-
- char cmdbuf[50], *cmdptr, searchbuf[50];
- /* Declare data buffer in two chunks, to prevent a negative size,
- which confuses MASM */
- unsigned char data[ALLOCATION/2], data1[ALLOCATION/2];
-
- /*
- * Skip to the next non-blank character
- */
- char skip()
- {
- while(*cmdptr == ' ')
- ++cmdptr;
- return *cmdptr;
- }
-
- main(argc, argv)
- unsigned argc;
- char *argv[];
-
- {
- int cursor;
- unsigned i, j, k, pos, size;
- unsigned char c, chr, mode, modified;
- HANDLE fh;
-
- cursor = pos = mode = modified = 0;
- if(argc<2)
- abort("\nUse: hexed <file>\n\nCopyright 1983-1994 Dave Dunfield\nAll rights reserved.\n");
-
-
- if(!(fh=open(argv[1], F_READ)))
- abort("HEXED: Cannot open input file\n");
-
- if((size = read(data, ALLOCATION, fh)) >= ALLOCATION)
- abort("HEXED: File to large\n");
-
- close(fh);
-
- vopen();
-
- draw: /* draw entire screen */
- vgotoxy(0,0);
- for(i=0; i<30; ++i) vputc('-');
- V_ATTR = REVERSE;
- putstr(" Hex-Ed Version 1.3 ");
- V_ATTR = NORMAL;
- for(i=0; i<30; ++i) vputc('-');
- vgotoxy(0,2);
- vprintf("File: %s",argv[1]);
- vgotoxy(59,2);
- vprintf("Size: %u, ($%04x)",size, size);
-
- redraw: /* re-draw text area of screen */
- for(i=0; i < 16; ++i) { /* for each line */
- vgotoxy(0, i+4);
- if(size <= (k=pos+(i*16)))
- break;
- vprintf("%04x ",k=pos+(i*16));
- for(j = k; j < (k+16) ; ++j) {
- if(j<size)
- vprintf(" %02x", data[j]);
- else {
- vcleol();
- break; } }
- vgotoxy(63,i+4);
- for(j = k; (j<(k+16)) && (j<size); ++j)
- putprint(data[j]); }
- vcleos();
-
- prompt:
- if(mode)
- vgotoxy(63 + cursor%16, 4 + cursor/16);
- else
- vgotoxy(7+3*(cursor%16), 4+cursor/16);
- switch(chr = vgetc()) {
- case _KUA : /* backup a line (16 bytes) */
- if((cursor = cursor - 16) < 0) {
- cursor += 16;
- case _KPU : /* backup a page (256 bytes) */
- if(pos > 255) {
- pos -= 256;
- goto redraw; }
- else if(pos) {
- pos = 0;
- goto redraw; } }
- break;
- case _KDA : /* advance a line (16 bytes) */
- if((cursor + pos + 16) >= size)
- break;
- if(cursor <= (255-16)) {
- cursor += 16;
- break; }
- case _KPD : /* advance a page (256 bytes) */
- if((pos+256) < size)
- pos += 256;
- if((pos + cursor) > size)
- cursor = size - pos - 1 ;
- goto redraw;
- case _KLA : /* backup one byte */
- if(cursor)
- --cursor;
- else if(pos) {
- --pos;
- goto redraw; }
- break;
- case _KRA : /* advance one byte */
- if(size <= (pos + ++cursor)) --cursor;
- else if(255 < cursor) {
- --cursor;
- if(pos < (size - 255)) ++pos;
- goto redraw; }
- break;
- case _CPD : /* goto end of file */
- if(size > 255) {
- cursor = 255;
- pos = size - 256; }
- else {
- cursor = size-1;
- pos = 0; }
- goto redraw;
- case _CPU : /* goto start of file */
- cursor = pos = 0;
- goto redraw;
- case _KEN : /* advance to end of field */
- cursor = (cursor & 0xff0) + 15;
- if(size <= cursor+pos)
- cursor = size - pos - 1;
- break;
- case _KHO : /* backup to beginning of field */
- cursor = cursor & 0xff0;
- break;
- case _K1 : /* swap editing field */
- mode = ~mode;
- break;
- case _CHO : /* re-draw the screen */
- vclscr();
- goto draw;
- case _KDL: /* Delete a byte */
- i = pos + cursor;
- while(i < size)
- data[i] = data[++i];
- if((pos + cursor) >= --size) {
- if(cursor)
- --cursor;
- else if(pos)
- --pos; }
- modified = -1;
- goto redraw;
- case _KIN: /* Insert a byte */
- i = pos + cursor;
- if(size < ALLOCATION) {
- chr = data[i];
- while(i < size) {
- c = data[++i];
- data[i] = chr;
- chr = c; }
- ++size; }
- modified = -1;
- goto redraw;
- case _K10 : /* execute line mode command */
- case _KKP :
- vgotoxy(0,22);
- vcleos();
- vputs("Command: ");
- i = 0;
- do {
- if((chr = vgetc()) == _KBS) {
- if (i) {
- putstr("\010 \010");
- --i; } }
- else if(chr < 128)
- vputc(cmdbuf[i++] = chr); }
- while((chr != _KKP) && (chr != _K10));
- cmdbuf[i] = 0;
- case _K9 : /* repeat last command */
- case _KKM :
- vgotoxy(0, 22);
- V_ATTR = REVERSE;
- putstr(cmdbuf);
- V_ATTR = NORMAL;
- vcleos();
- cmdptr = cmdbuf;
- switch(chr = toupper(skip())) {
- case 'G' : /* goto address */
- ++cmdptr;
- skip();
- i = 0;
- if((i = gethex()) == -1)
- break;
- cursor = 0;
- pos = (i<size) ? i : size;
- goto redraw;
- case '/' : /* Search for ASCII */
- i = 0;
- while(*++cmdptr)
- searchbuf[i++] = *cmdptr;
- if(!i)
- break;;
- goto do_search;
- case '?' : /* search for HEX */
- ++cmdptr;
- skip();
- i = 0;
- do
- searchbuf[i++] = j = gethex();
- while((j != -1) && skip());
- if(j == -1)
- break;
- do_search: j = pos + cursor + 1;
- while(!compare(searchbuf, data+j, i)) {
- if(++j >= size) {
- error("Not found");
- break; } }
- if(j < size) {
- if((cursor = j - pos) & 0xff00) {
- pos = j;
- cursor = 0;
- goto redraw; } }
- break;
- case 'X' : /* Exit and write file */
- case 'W' : /* write file */
- ++cmdptr;
- if(!skip())
- cmdptr = argv[1];
- if(fh=open(cmdptr, F_WRITE)) {
- write(data, size, fh);
- modified = 0;
- close(fh); }
- else {
- error("Can't open output file");
- break; }
- if(chr != 'X')
- break;
- case 'Q' : /* quit (Exit) */
- if(modified && (toupper(*(cmdptr+1)) != 'Q'))
- error("Unsaved changes, 'qq' to quit anyway");
- else {
- vclscr();
- exit(0); }
- break;
- case 0 : /* null command, do nothing */
- break;
- default:
- error("Unknown command"); }
- vgotoxy(0,22);
- vcleol();
- break;
- default:
- k = data[pos + cursor];
- if(mode) {
- data[pos+cursor] = k = chr;
- chr = modified = -1; }
- else {
- if(ishex(chr = toupper(chr))) {
- vputc(chr);
- if(chr > '9') chr -= 7;
- i = (chr-'0')*16;
- vputc('-');
- vputc('\b');
- if(ishex(chr=toupper(vgetc()))) {
- if(chr > '9') chr -= 7;
- data[pos+cursor] = k =(chr-'0') + i;
- chr = modified = -1; } } }
- vgotoxy(7+3*(cursor%16), 4+cursor/16);
- vprintf("%02x ",k);
- vgotoxy(63 + cursor%16, 4 + cursor/16);
- putprint(k);
- if(chr == -1) {
- if(size <= (pos + ++cursor)) --cursor;
- else if(cursor > 255) {
- if(pos < (size-256)) {
- pos += 256;
- cursor = 0; }
- else
- pos = size-(pos + cursor);
- goto redraw; } } }
- goto prompt;
- }
-
- /*
- * Test for a valid hexidecimal digit
- */
- ishex(chr)
- char chr;
- {
- return ((chr >= '0') && (chr <= '9')) || ((chr >= 'A') && (chr <= 'F'));
- }
-
- /*
- * Get a hex value from the input line
- */
- gethex()
- {
- register unsigned i;
- register char chr, flag;
-
- flag = i = 0;
- while(ishex(chr = toupper(*cmdptr))) {
- ++cmdptr;
- flag = -1;
- if(chr > '9')
- chr -= 7;
- i = (i*16) + (chr - '0'); }
- if(!flag) {
- error("Invalid HEX digit");
- return -1; }
- return i;
- }
-
- /*
- * Display a character in printable form.
- * Non-printable characters display as '.'
- */
- putprint(chr)
- char chr;
- {
- vputc(((chr >= ' ') && (chr < 0x7f)) ? chr : '.');
- }
-
- /*
- * Display an error message on the bottom line of the screen
- */
- error(string)
- char *string;
- { vgotoxy(0,23);
- V_ATTR = REVERSE;
- putstr(string);
- V_ATTR = NORMAL;
- vcleos();
- vputc(7);
- }
-
- /*
- * Compare two strings for the given length
- */
- compare(str1, str2, len)
- char *str1, *str2;
- int len;
- {
- while(len--) {
- if(*str1++ != *str2++)
- return 0; }
- return 1;
- }
-
- /*
- * Write a string to the output device
- */
- putstr(ptr)
- char *ptr;
- {
- register char c;
-
- while(c = *ptr++)
- vputc(c);
- }
-