161 lines
5.1 KiB
C
161 lines
5.1 KiB
C
#include "../includes/disass.h"
|
|
#include <stdlib.h>
|
|
|
|
const unsigned char* Image;
|
|
const unsigned char COPYMASKREG = 0x20;
|
|
const unsigned char COPYMASKADD = 0xA0;
|
|
const unsigned char ADDMASK = 0x40;
|
|
const unsigned char SUBMASK = 0x60;
|
|
const unsigned char CMPMASK = 0x80;
|
|
|
|
const unsigned char REGMASK = 0x00;//0x18; //0001 1000
|
|
const unsigned char CONSTMASK = 0x08; //0000 1000
|
|
const unsigned char ADDRESSMASK = 0x10; //0001 0000
|
|
|
|
int IsRegisterPattern(unsigned char pattern, char* lexeme);
|
|
void GetParameter(unsigned char instruction, char* text);
|
|
|
|
void Disassemble(unsigned char image[HIGHMEMORY]) {
|
|
Image = image;
|
|
int position = image[0] + image[1];
|
|
int end = image[2] + image[3];
|
|
|
|
char* parameter1 = calloc(32, sizeof(char));
|
|
char* parameter2 = calloc(32, sizeof(char));
|
|
|
|
unsigned char instruction = image[position];
|
|
|
|
while(end > position) {
|
|
unsigned char masked = instruction & 0xE0;
|
|
|
|
if (masked) {
|
|
IsRegisterPattern(instruction & 0x07, parameter1);
|
|
unsigned char parameterType = instruction & 0x18;
|
|
|
|
if (parameterType == REGMASK) {
|
|
IsRegisterPattern(Image[position + 1], parameter2);
|
|
position += 2;
|
|
} else if (parameterType == CONSTMASK) {
|
|
snprintf(parameter2, sizeof(char) * 31, "%d", Image[position + 1] + Image[position + 2]);
|
|
position += 3;
|
|
}
|
|
else if (parameterType == ADDRESSMASK) {
|
|
snprintf(parameter2, sizeof(char) * 31, "[%#04X]", Image[position + 1] + Image[position + 2]);
|
|
position += 3;
|
|
}
|
|
|
|
//If the top bits are set
|
|
if (masked == COPYMASKREG) {
|
|
printf("COPY %s, %s\n", parameter1, parameter2);
|
|
}
|
|
else if (masked == COPYMASKADD) {
|
|
printf("COPY %s, %s\n", parameter2, parameter1);
|
|
}
|
|
else if (masked == ADDMASK) {
|
|
printf("ADD %s, %s\n", parameter1, parameter2);
|
|
}
|
|
else if (masked == SUBMASK) {
|
|
printf("SUB %s, %s\n", parameter1, parameter2);
|
|
}
|
|
else if (masked == CMPMASK) {
|
|
printf("CMP %s, %s\n", parameter1, parameter2);
|
|
}
|
|
else {
|
|
fprintf(stderr, "[Error] Unknown opcode %#02X\n", masked);
|
|
exit(1);
|
|
}
|
|
}
|
|
else {
|
|
int parameter = Image[position + 1] + Image[position + 2];
|
|
|
|
switch(instruction) {
|
|
case 0:
|
|
printf("NOP\n");
|
|
position++;
|
|
break;
|
|
case 1:
|
|
printf("JZ [%#04X]\n", parameter);
|
|
position += 3;
|
|
break;
|
|
case 2:
|
|
printf("INT %d\n", parameter);
|
|
position += 3;
|
|
break;
|
|
case 3:
|
|
printf("YLD\n");
|
|
position++;
|
|
break;
|
|
case 4:
|
|
printf("RET\n");
|
|
position++;
|
|
break;
|
|
case 5:
|
|
printf("CALL [%#04X]\n", parameter);
|
|
position += 3;
|
|
break;
|
|
case 6:
|
|
printf("JMP [%#04X]\n", parameter);
|
|
position += 3;
|
|
break;
|
|
case 7:
|
|
printf("IN %d\n", parameter);
|
|
position += 3;
|
|
break;
|
|
case 8:
|
|
printf("OUT %d\n", parameter);
|
|
position += 3;
|
|
break;
|
|
default:
|
|
position++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
instruction = Image[position];
|
|
|
|
memset(parameter1, '\0', sizeof(char) * 32);
|
|
memset(parameter2, '\0', sizeof(char) * 32);
|
|
}
|
|
}
|
|
|
|
int IsRegisterPattern(unsigned char pattern, char* lexeme) {
|
|
if (pattern > 8) {
|
|
lexeme[0] = '\0';
|
|
return 0;
|
|
}
|
|
//The registers' bit patterns are zero indexed, so 'r1' is '000'
|
|
//but 'r8' is '111' and so forth.
|
|
pattern++;
|
|
|
|
lexeme[0] = 'r';
|
|
lexeme[1] = pattern | 0x30;
|
|
lexeme[2] = '\0';
|
|
|
|
return 1;
|
|
}
|
|
/*
|
|
//REG XXX0 0XXX
|
|
//Constant XXX0 1XXX
|
|
//Address XXX1 0XXX
|
|
NOP - 0000 0000 NOP
|
|
JZ - 0000 0001 JZ Address
|
|
INT - 0000 0010 INT Constant
|
|
YLD - 0000 0011 YLD
|
|
RET - 0000 0100 RET
|
|
CALL - 0000 0101 CALL Address
|
|
JMP - 0000 0110 JMP Address
|
|
IN - 0000 0111 IN Constant
|
|
OUT - 0000 1000 OUT Constant
|
|
COPY - 0010 0XXX COPY REG, REG
|
|
- 0010 1XXX COPY REG, Constant
|
|
- 0011 0XXX COPY REG, Address
|
|
- 1010 0XXX COPY Address, REG
|
|
- 1010 1XXX COPY Address, Constant
|
|
- 1011 0XXX COPY Address, Address
|
|
ADD - 0100 0XXX ADD REG, REG
|
|
- 0100 1XXX ADD REG, Constant
|
|
SUB - 0110 0XXX SUB REG, REG
|
|
- 0110 1XXX SUB REG, Constant
|
|
CMP - 1000 0XXX CMP REG, REG
|
|
- 1000 1XXX CMP REG, Constant
|
|
- 1001 0XXX CMP REG, Address */ |