Files
assm-test/src/disass.c
T

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 */