summaryrefslogtreecommitdiffstats
path: root/memedit.y
diff options
context:
space:
mode:
Diffstat (limited to 'memedit.y')
-rw-r--r--memedit.y360
1 files changed, 360 insertions, 0 deletions
diff --git a/memedit.y b/memedit.y
new file mode 100644
index 0000000..07edb13
--- /dev/null
+++ b/memedit.y
@@ -0,0 +1,360 @@
+/* FPGAedit */
+
+%{
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+extern int errno;
+extern FILE *fhan;
+extern int debug;
+
+typedef struct variable {
+ struct variable *next;
+ char *name;
+ int val;
+} variable;
+
+int in_line = 0;
+#define LINELEN 16
+int write_len;
+variable *vlist;
+
+void set_variable (char *param, int val);
+int get_variable (char *param);
+void hex_output (int offset, int len, int count);
+void print_help (void);
+
+extern void yyerror (const char *s);
+extern int zzlex (void);
+int yylex (void);
+%}
+
+%union {
+long val;
+char *tptr;
+}
+
+%left <val> NUM
+%left <val> ADD
+%left <val> SUB
+%left <val> MUL
+%left <val> DIV
+%left <val> NEG
+%left <val> MOD
+%left <val> RSHIFT
+%left <val> LSHIFT
+%left <val> OBRA
+%left <val> CBRA
+%left <tptr> NAME
+%left <val> OPEN
+%left <val> CLOSE
+%left <val> MD
+%left <val> MM
+%left <val> EQ
+%left <val> AT
+%token <val> EXIT
+%token <val> HELP
+%right <val> CR
+
+%type <val> num
+
+%% /* FPGAedit Grammar */
+
+input: /* empty */
+ | input line
+;
+
+line: CR
+ | open CR
+ | close CR
+ | EXIT CR { exit(EXIT_SUCCESS); }
+ | HELP CR { print_help(); }
+ | NAME CR { printf ("%s = %d\n", $1, get_variable($1)); free($1); }
+ | mem CR { printf ("\n"); }
+ | NAME EQ num CR { set_variable ($1, $3); free($1); }
+ | NAME EQ MD num CR {
+ if (fhan)
+ {
+ if (fseek (fhan, $4, SEEK_SET) == -1)
+ printf ("set offset %ld failed\n", $4);
+ else
+ {
+ unsigned int c = 0;
+
+ fread(&c, $3, 1, fhan);
+ set_variable ($1, c);
+ free($1);
+ }
+ }
+ else printf ("please open file\n");
+ }
+ | error
+;
+
+open: OPEN { printf ("open <filename>\n"); }
+ | OPEN NAME {
+ if (fhan) fclose (fhan);
+ fhan = fopen($2, "r+");
+ if (!fhan)
+ printf ("open >%s< failed\n%s\n", $2, strerror(errno));
+ free ($2);
+ }
+;
+
+close: CLOSE {
+ if (fhan) {
+ fclose (fhan); fhan = NULL;
+ }
+ }
+;
+
+mem: MD {
+ if (fhan) hex_output (ftell (fhan), $1, 0);
+ else printf ("please open file\n");
+ }
+ | MD num { hex_output ($2, $1, 0); }
+ | MD num num { hex_output ($2, $1, ($3 - 1)/16); }
+ | MD AT num {
+ if (fhan)
+ {
+ if (fseek (fhan, $3, SEEK_SET) == -1)
+ printf ("set offset %ld failed\n", $3);
+ else
+ {
+ unsigned int c = 0;
+
+ fread(&c, $1, 1, fhan);
+ hex_output (c, $1, 0);
+ }
+ }
+ else printf ("please open file\n");
+ }
+ | MD AT num num {
+ if (fhan)
+ {
+ if (fseek (fhan, $3, SEEK_SET) == -1)
+ printf ("set offset %ld failed\n", $3);
+ else
+ {
+ unsigned int c = 0;
+
+ fread(&c, $1, 1, fhan);
+ hex_output (c, $1, $4);
+ }
+ }
+ else printf ("please open file\n");
+ }
+ | MM { printf ("mm <offset> <value1> [<value2> ...]\n"); }
+ | mm exp
+;
+
+mm: MM { write_len = $1; if (debug > 3) printf ("write_len = %d\n", write_len);}
+;
+
+exp: num {
+ if (fhan) {
+ long offset;
+
+ if (fseek (fhan, $1, SEEK_SET) == -1)
+ printf ("set offset %ld failed\n", $1);
+ else {
+ offset = ftell (fhan);
+ if (offset%write_len) {
+ offset -= offset%write_len;
+ printf ("alligned to 0x%08lx\n",
+ offset);
+ fseek (fhan, offset, SEEK_SET);
+ }
+ printf ("new values:");
+ if (offset%(LINELEN*4))
+ printf ("0x%08lx", offset);
+ }
+ }
+ else printf ("please open file\n");
+ }
+ | exp num {
+ unsigned int c;
+ long offset;
+
+ c = $2;
+ if (debug > 3) printf ("write_len = %d\nc = 0x%0x\n",
+ write_len, c);
+
+ if (fhan) {
+ offset = ftell (fhan);
+ if (offset%LINELEN) printf (" ");
+ else printf ("\n0x%08lx ", offset);
+ fwrite (&c, write_len, 1, fhan);
+ fflush (fhan);
+ fseek(fhan, -write_len, SEEK_CUR);
+ fread(&c, write_len, 1, fhan);
+ switch (write_len) {
+ case 1: c &= 0xff; printf ("%02x", c); break;
+ case 2: c &= 0xffff; printf ("%04x", c); break;
+ case 4: printf ("%08x", c); break;
+ }
+ }
+ else if (debug > 3) printf ("fhan == NULL\n");
+ }
+;
+
+num: NUM
+ | num ADD num { $$ = $1 + $3; if (debug > 3) printf ("ADD: %ld\n", $$); }
+ | num SUB num { $$ = $1 - $3; if (debug > 3) printf ("SUB: %ld\n", $$); }
+ | num MUL num { $$ = $1 * $3; if (debug > 3) printf ("MUL: %ld\n", $$); }
+ | num DIV num { $$ = $1 / $3; if (debug > 3) printf ("DIV: %ld\n", $$); }
+ | num MOD num { $$ = $1 % $3; if (debug > 3) printf ("MOD: %ld\n", $$); }
+ | num RSHIFT num { $$ = $1 >> $3; if (debug > 3) printf ("RSHIFT: %ld\n", $$); }
+ | num LSHIFT num { $$ = $1 << $3; if (debug > 3) printf ("LSHIFT: %ld\n", $$); }
+ | OBRA num CBRA { $$ = $2; if (debug > 3) printf ("BRA: %ld\n", $$); }
+ | NAME { $$ = get_variable ($1); if (debug > 3) printf ("VAR: %ld\n", $$); free($1); }
+;
+
+%%
+void print_help (void) {
+ printf ("\n");
+ printf ("open <file> open a file\n");
+ printf ("close close currently opened file\n");
+ printf ("exit, quit quit\n");
+ printf ("help show this help text\n");
+ printf ("\n");
+ printf ("md [[@]<start> [<end>]] mem display from current position\n");
+ printf (" or from <start> to <end>\n");
+ printf ("mm <offset> <val1> .. <valN> modify from value <offset>\n");
+ printf ("<var> = <expr> set variable <var> to <expr>\n");
+ printf ("<var> print variable <var>\n");
+ printf ("\n");
+ printf ("<var1> add <var2> add variables\n");
+ printf ("<var1> sub <var2> substract variables\n");
+ printf ("<var1> mul <var2> multiplicate variables\n");
+ printf ("<var1> div <var2> divide variables\n");
+ printf ("<var1> rshift <var2> shift (or >>)\n");
+ printf ("<var1> lshift <var2> shift (or >> or shift)\n");
+ printf ("\n");
+ printf ("Variables can be entered as decimals (without prefix), hex (prefixed with 0x)\n");
+ printf ("oct (0o) or bin (0b). For mm and md byte, word and long word access can be \n");
+ printf ("enabled with .b, .w and .l\n");
+ printf ("\n");
+}
+
+void set_variable (char *param, int val) {
+ variable *l, *tmp;
+
+ if (strncmp (param, "debug", 5) == 0) {
+ debug = val;
+ printf ("debug = %d\n", debug);
+ return;
+ }
+
+ if (debug > 3) printf ("param = >%s<\n", param);
+
+ for (l = vlist; l; l = l->next) {
+ if (debug > 3) printf ("l->name = >%s<\n", l->name);
+ if (strcmp (l->name, param) == 0) {
+ l->val = val;
+ return;
+ }
+ }
+
+ tmp = calloc (1, sizeof(variable));
+ if (!tmp) {
+ printf ("no mem for variable %s!\n", param);
+ return;
+ }
+
+ tmp->name = calloc(1 + strlen(param), sizeof(char));
+ if (!tmp->name) {
+ printf ("no mem for variable %s!\n", param);
+ free(tmp);
+ return;
+ }
+ strcpy(tmp->name, param);
+ tmp->val = val;
+ tmp->next = vlist;
+
+ vlist = tmp;
+}
+
+int get_variable (char *param) {
+ int v = 0;
+ variable *l;
+
+ if (debug > 3) printf ("param = >%s<\n", param);
+
+ for (l = vlist; l; l = l->next) {
+ if (debug > 3) printf ("l->name = >%s<\n", l->name);
+ if (strcmp (l->name, param) == 0) {
+ v = l->val;
+ break;
+ }
+ }
+ return v;
+}
+
+void hex_output (int offset, int len, int count) {
+ unsigned int c;
+ int i=0, j, t;
+ unsigned char linebuf[LINELEN];
+
+ if (!fhan) {
+ printf ("please open file\n");
+ return;
+ }
+
+ if (fseek (fhan, offset, SEEK_SET) != 0) {
+ printf ("set offset %d failed\n", offset);
+ return;
+ }
+
+ for (t = 0; t <= count; t++) {
+ unsigned int *lineint = (unsigned int *)linebuf;
+ unsigned short *lineshort = (unsigned short *)linebuf;
+
+ printf ("%08x: ", offset + t*LINELEN);
+ switch (len) {
+ case 1:
+ for (i = 0; i < LINELEN; i++) {
+ c = 0;
+ if (fread (&c, 1, 1, fhan) != 1) break;
+ printf ("%02x ", c);
+ linebuf[i] = c;
+ }
+ break;
+ case 2:
+ for (i = 0; i < LINELEN; i+=2) {
+ c = 0;
+ if (fread (&c, 2, 1, fhan) != 1) break;
+ printf ("%04x ", c);
+ *lineshort++ = c;
+ }
+ break;
+
+ case 4:
+ for (i = 0; i < LINELEN; i+=4) {
+ c = 0;
+ if (fread (&c, 4, 1, fhan) != 1) break;
+ printf ("%08x ", c);
+ *lineint++ = c;
+ }
+ break;
+ }
+
+ for (j = 0; j < i; j++) {
+ if(isprint(linebuf[j]))
+ printf("%c",linebuf[j]);
+ else
+ printf(".");
+ }
+ printf ("\n");
+ if(i < LINELEN)
+ return;
+ }
+}
+
+int yylex (void) {
+ in_line++;
+ return zzlex ();
+}