Hey guys,
After a couple hours of coding all 255 Opcodes for the 8080, I ran into a little problem.
The tutorial for this Disassembler is here - http://www.emulator101.com.s3-website-us-east-1.amazonaws.com/disassembler-pt-1/
I think what is used in the tutorial is pure C, but me being used to C++ I've tried converting it.
My first issue is this line of code from the tutorial.
|
unsigned char *code = codebuffer[pc]
|
I think the missing semicolon is obviously a typo, but without the ampersand before the codebuffer I get the message:
Error: A value of type 'unsigned char' cannot be used to initialize an entity of type 'unsigned char*'
If I put the ampersand in
|
unsigned char *code = &codebuffer[pc]
|
I have no red lines or error.
I'm not sure if the issue is this, probably not but I thought I would mention it just in case.
My main concern is that the function for writing the values in the memory is printf, but instead I am using cout.
When I drag the compiled 8080 assembly into the program, I get some strange output.
The formatting seems okay, one instruction per line due to this switch statement
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
int Disassemble8080Op(unsigned char *codebuffer, int pc)
{
unsigned char *code = codebuffer[pc];
opbytes = 1;
cout << hex << *code << "\t";
switch(*code)
{
case 0x00:cout << "NOP"; break;
case 0x01:cout << "LXI B," << code[2] << code[1]; opbytes = 3; break;
case 0x02:cout << "STAX B"; break;
case 0x03:cout << "INX B"; break;
case 0x04:cout << "INR B"; break;
case 0x05:cout << "DCR B"; break;
case 0x06:cout << "MVI B," << code[1]; opbytes = 2; break;
case 0x07:cout << "RLC"; break;
case 0x08:cout << "NOP"; break;
case 0x09:cout << "DAD B"; break;
case 0x0A:cout << "LDAX B"; break;
case 0x0B:cout << "DCX B"; break;
case 0x0C:cout << "INR C"; break;
case 0x0D:cout << "DCR C"; break;
case 0x0E:cout << "MVI C," << code[1]; opbytes = 2; break;
case 0x0F:cout << "RRC"; break;
....
case 0xF0:cout << "RP"; break;
case 0xF1:cout << "POP PSW"; break;
case 0xF2:cout << "JP"; opbytes = 3; break;
case 0xF3:cout << "DI"; break;
case 0xF4:cout << "CP"; opbytes = 3; break;
case 0xF5:cout << "PUSH PSW"; break;
case 0xF6:cout << "ORI" << code[1]; break;
case 0xF7:cout << "RST 6"; break;
case 0xF8:cout << "RM"; break;
case 0xF9:cout << "SPHL"; break;
case 0xFA:cout << "JM " << code[2] << code[1]; opbytes = 3; break;
case 0xFB:cout << "EI"; break;
case 0xFC:cout << "CM " << code[2] << code[1]; opbytes = 3; break;
case 0xFD:cout << "NOP"; break;
case 0xFE:cout << "CPI" << code[1]; opbytes = 2; break;
case 0xFF:cout << "RST 7"; break;
}
cout << "\n";
return opbytes;
}
|
I think I've canceled the problem out to be the
|
cout << code[1] << code[2];
|
Rather than it printing out the values of each byte, it is printing out the characters instead. I did a warm up project for this yesterday where I cam across the same thing, however I solved it somehow, using static_cast<void*> but I've tried doing that today but I guess I'm putting it in the wrong place in code? I'm not sure..any help would be appreciated.
Here is the full program with a condensed switch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
#include <iostream>
#include <iomanip>
#include <stdio.h>
using std::cout;
using std::hex;
int opbytes;
int Disassemble8080Op(unsigned char *codebuffer, int pc)
{
unsigned char *code = codebuffer[pc];
opbytes = 1;
cout << hex << *code << "\t";
switch(*code)
{
case 0x00:cout << "NOP"; break;
case 0x01:cout << "LXI B," << code[2] << code[1]; opbytes = 3; break;
case 0x02:cout << "STAX B"; break;
case 0x03:cout << "INX B"; break;
case 0x04:cout << "INR B"; break;
case 0x05:cout << "DCR B"; break;
case 0x06:cout << "MVI B," << code[1]; opbytes = 2; break;
case 0x07:cout << "RLC"; break;
case 0x08:cout << "NOP"; break;
case 0x09:cout << "DAD B"; break;
case 0x0A:cout << "LDAX B"; break;
case 0x0B:cout << "DCX B"; break;
case 0x0C:cout << "INR C"; break;
case 0x0D:cout << "DCR C"; break;
case 0x0E:cout << "MVI C," << code[1]; opbytes = 2; break;
case 0x0F:cout << "RRC"; break;
}
cout << "\n";
return opbytes;
}
int main(int argc, char** argv)
{
FILE *f= fopen(argv[1], "rb");
if (f==NULL)
{
printf("error: Couldn't open %s\n", argv[1]);
exit(1);
}
//Get the file size and read it into a memory buffer
fseek(f, 0L, SEEK_END);
int fsize = ftell(f);
fseek(f, 0L, SEEK_SET);
unsigned char *buffer = new unsigned char[fsize];
fread(buffer, fsize, 1, f);
fclose(f);
int pc = 0;
while (pc < fsize)
{
pc += Disassemble8080Op(buffer, pc);
}
delete buffer;
std::cin.get();
return 0;
}
|