In article <68a2ec1b.0211171226.1e2897a6@posting.google.com>, Lazarus I. Long wrote: > >all i really need is something equivalent to the Apple II monitor >disassembler. simple, stupid and fast. not interactive, no smarts >about separating out data from code etc. Don't have such a beast, but it's conceptually pretty simple to make a 6502/65C02 disassembler given these specifications. It's a bit more work to do it for the 65816, but not much more if properly structured. Basically, have a function that will: 1. Iterate over each byte of the source data stream for number of bytes that you want to disassemble. This assumes the data stream has already been converted from ASCII to integers in-memory, if necessary. If already done, then no extra work is needed. 2. Do a hash table lookup for the first byte and determine if valid opcode 3. If not a valid opcode, try decode next byte in input data stream by incrementing input data pointer by 1 and go back to step 1. 4. If valid opcode, look up the opcode's info in a table to determine if 0, 1, or 2 data bytes will follow...and also fetch the opcode's ASCII mnemonic from the table (You probably do want to know the starting memory address and increment this as you go along in the iteration because some addressing modes are relative, such as a short branch which might specify that it's for '16 bytes earlier' rather than an absolute address. Ie: '30 E8' is BMI -18; 30 is BMI, and if value is > 80, aka high bit is set, is a negative number. FF minus E8 is 18. So 18 bytes back is target of branch.) 5. Print the decoded info 6. Skip the number of data bytes to start with next opcode 7. Go back to step 1 I'm not sure the best way to design an hash table, but I would probably do it as something like this: Allocate an array: opcodeTable[256] Each position in it represents a corresponding opcode number. For example, position 0 would be opcode number 0, position 1 would be opcode number 1, etc. If it's a valid opcode, set its value to be pointer to address of structure with data. If it's invalid opcode, set its value to be NULL. Then make a struct...something like: typedef struct { char * mnemonic; int numDataBytes; int addressingMode; } opcodeInfo; Then you could have a routine that allocates memory for each struct, and fill it out with appropriate values, then update the pointer in opcodeTable to point to it. enum { None = 0, Relative = 1, Absolute = 2 }; defineOpcode(0x90, "BCC", 1, Relative); would call a function that allocates memory for a new struct, fill it out, then stuff the pointer to struct in the 144th entry of the hash table (0..255, so 0x90 would be 145th position) For example: void defineOpcode(int opcode, char *mnemonic, int argCount, int addrMode) { newStruct = malloc(sizeof(struct opcodeInfo)); newStruct->mnemonic = mnemonic; newStruct->numDataBytes = argCount; newStruct->addressingMode = addrMode; opcodeTable[opcode] = newStruct; } defineOpcode(0x20, "JSR", 2, Absolute); defineOpcode(0xEA, "NOP", 0, None); If there's an invalid opcode, then easily handled with: opcodeTable[0xXX] = NULL; There's a flag bit in the struct to indicate if the opcode's data (if it has any) should be treated as relative or absolute. That'd help make decoding easier. Then the actual main loop checking would be simple... inputData is a ptr to the current byte in the input data if(opcodeTable[*inputData] != NULL) { opcodeDataPtr = opcodeTable[inputData]; opcodeMnemonic = opcodeDataPtr->mnemonic; opcodeDataCount = opcodeDataPtr->numDataBytes; /* decode stuff, depending on if 0, 1, or 2 data bytes */ decodeData(inputData, opcodeDataCount); /* print decoded info */ printDecodedInfo(...); /* next step will make it skip data bytes and start at */ /* next opcode to decode */ inputData += opcodeDataCount; } else { /* increment pointer to input data by one and try again */ /* in next trip around the loop */ inputData++; } I'm guessing that it's probably an hour's work to make that program. -Dan (email sent to original poster as a courtesy and posted to USENET.)