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