Intel 8080 Disassembler

closed account (G30oGNh0)
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;
}
closed account (G30oGNh0)
Never mind, go it. Thanks for the help.
Topic archived. No new replies allowed.