On Sun, Apr 25, 2004 at 11:57:28PM -0500, Ryan Underwood wrote: > > I think I'll be doing some footwork on this one.
I wrote a quick program to parse out the microcode from the XFree86 mga_ucode.h files. From here a disassembler can be written if we can ever figure out the op codes. The DDK says that they are 64-bits wide and 64-bit aligned. It seems that might be incorrect though. There are a lot of "dupes" if you examine the values at a width of 32-bits. -- Ryan Underwood, <[EMAIL PROTECTED]>
#include <stdlib.h> #include <stdio.h> #include <errno.h> #include "warp_opcodes.h" #define OPCODE_SIZE 8 /* Parse the XFree86 MGA ucodes and generate a source listing. */ static inline int whitespace(char c) { return (c == '\n' || c == '\r' || c == ' ' || c == '\t'); } static char *slurp(char *src, char *what) { char *p = src; int i; while (p[0] != what[0]) { p++; if (*p == '\0') return src; } for (i = 0; what[i] != '\0'; i++) { if (p[i] != what[i]) { i--; break; } } src = p + i; return src; } static int disassemble_warp(int *ip, unsigned char *opcode) { int i; char buf[5]; printf("%x:\t", *ip); /* for now just print op */ for (i = 0; i < OPCODE_SIZE; i++) { printf("%2x ", opcode[i]); } printf("\n"); *ip += OPCODE_SIZE; return 1; } int main(int argc, char**argv) { FILE *inp; char *filebuf, *p; int done = 0; int error = 0; int size; if (argc < 2) { fprintf(stderr, "Need an argument; a filename or '-' for stdin.\n"); exit(EXIT_FAILURE); } /* if (argv[1][0] == '-') { fprintf(stderr, "Reading from standard input...\n"); inp = stdin; } else { */ if ((inp = fopen(argv[1], "r")) == NULL) { perror("fopen"); exit(EXIT_FAILURE); } fprintf(stderr, "Reading from file %s...\n", argv[1]); /* } */ if (fseek(inp, 0, SEEK_END) == -1) { perror("fseek"); exit(EXIT_FAILURE); } if ((size = ftell(inp)) == -1) { perror("ftell"); exit(EXIT_FAILURE); } if (fseek(inp, 0, SEEK_SET) == -1) { perror("fseek"); exit(EXIT_FAILURE); } filebuf = (char*)malloc(size+1); if (filebuf == NULL) { perror("malloc"); exit(EXIT_FAILURE); } fread(filebuf, size, 1, inp); if (ferror(inp)) { perror("fread"); error = 1; goto cleanup; } if (fclose(inp) == EOF) { perror("fclose"); } filebuf[size] = '\0'; p = filebuf; char cur_vname[255]; int vname_next = 0; int data_next = 0; while (!done && *p != '\0') { while (whitespace(*p)) p++; if (vname_next) { if (*p == '*') { /* declared as pointer */ p++; } char *q; q = slurp(p, " "); strncpy(cur_vname, p, q-p); cur_vname[q-p] = '\0'; fprintf(stderr, "Parsing variable %s...\n", cur_vname); p = q; p = slurp(p, "{"); vname_next = 0; data_next = 1; continue; } if (data_next) { int ip = 0; unsigned char cur_op[OPCODE_SIZE]; int index = 0; printf("%s:\n", cur_vname); while (*p != '}') { if (whitespace(*p)) { p++; continue; } if (*p == ',') { p++; continue; } if (strncmp(p, "0x", 2) == 0) { /* next component is ready */ int i; long int val = strtol(p, &p, 16); if (errno) { perror("strtol"); goto cleanup; } cur_op[index] = (unsigned char)val; index++; if (index == OPCODE_SIZE) { index = 0; if (!disassemble_warp(&ip, cur_op)) { fprintf(stderr, "Error disassembly:\n"); for (i = 0; i < OPCODE_SIZE; i++) { fprintf(stderr, "%x", cur_op[i]); } fprintf(stderr, "\n"); } } } else { char err[50+1]; strncpy(err, p, 50); err[50] = '\0'; fprintf(stderr, "Malformed input at:\n%s\n", err); error = 1; goto cleanup; } } data_next = 0; p = slurp(p, "}"); p = slurp(p, ";"); printf("\n"); } if (strncmp(p, "/*", 2) == 0) { /* start comment */ fprintf(stderr, "slurping a comment\n"); p = slurp(p, "*/"); continue; } else if ((strncmp(p, "static ", sizeof("static")) == 0) || strncmp(p, "unsigned ", sizeof("unsigned")) == 0) { p = slurp(p, " "); continue; } else if (strncmp(p, "char ", sizeof("char")) == 0) { vname_next = 1; p = slurp(p, " "); continue; } else { /* advance */ // fprintf(stderr, "advancing\n"); p++; } } cleanup: free(filebuf); if (error) { fprintf(stderr, "Errors were encountered.\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
signature.asc
Description: Digital signature