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, <nemesis@icequake.net>
#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);
}
Attachment:
signature.asc
Description: Digital signature