diff --git a/includes/disass.h b/includes/disass.h new file mode 100644 index 0000000..1d18a01 --- /dev/null +++ b/includes/disass.h @@ -0,0 +1,9 @@ +#ifndef DIASSEMBLER_H +#define DIASSEMBLER_H + +#include "parser.h" + +void Disassemble(unsigned char image[HIGHMEMORY]); + +#endif + diff --git a/includes/parser.h b/includes/parser.h index 90b7025..9dc1178 100644 --- a/includes/parser.h +++ b/includes/parser.h @@ -7,6 +7,8 @@ #include "token.h" #include "opcodes.h" -void ParseTokens(List*); +#define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF + +unsigned char* ParseTokens(List*); #endif \ No newline at end of file diff --git a/includes/token.h b/includes/token.h index 876ea13..78a6984 100644 --- a/includes/token.h +++ b/includes/token.h @@ -6,6 +6,8 @@ #include #include +#define REGISTEROFFSET 29 + typedef enum { PLUS, MINUS, diff --git a/misc/test.asm b/misc/test.asm index 5a59bf4..d870a1a 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -1,8 +1,8 @@ ;.org 0x100 ;.db msg "Hello, world!", 0 -;.db more_stuff "AAAA", 0 -copy r7, 45 -cmp r8, 45 +;.db more_stuff "AA", 0 +copy r7, 45 ; // +cmp r8, 45 ;1000 1111 ;copy r1, 45 ;//B0 = 10110000 ;copy 2, 45 diff --git a/src/disass.c b/src/disass.c new file mode 100644 index 0000000..506a67f --- /dev/null +++ b/src/disass.c @@ -0,0 +1,110 @@ +#include "../includes/disass.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, unsigned char lexeme[2]); + +void Disassemble(unsigned char image[HIGHMEMORY]) { + Image = image; + int position = 0; + unsigned char lexeme[3] = { 0 }; + unsigned char lexem2[8] = { 0 }; + + unsigned char instruction = image[position]; + + while(instruction != 0) { + //1110 0000 + unsigned char masked = instruction & 0xE0; + + if (masked) { + IsRegisterPattern(instruction & 0x07, lexeme); + unsigned char parameter = instruction & 0x18; + + if (!parameter) { + position++; + IsRegisterPattern(Image[position], lexem2); + } else if (parameter == CONSTMASK) { + + lexem2[0] = 4 >> Image[position] | 0x30; + lexem2[1] = Image[position] | 0x30; + position++; + } + else if (parameter == ADDRESSMASK) { + //snprintf(lexem2, sizeof lexem2, "%#04X", Image[position]); + lexem2[0] = 'X'; + } + + //If the top bits are set + if (masked & COPYMASKREG) { + printf("copy %s, %d\n", lexeme, Image[position]); + } + else if (masked & COPYMASKADD) { + printf("CMP1\n"); + } + else if (masked & ADDMASK) { + printf("CMP2\n"); + } + else if (masked & SUBMASK) { + printf("CMP3\n"); + } + else if (masked & CMPMASK) { + printf("CMP\n"); + } + else { + fprintf(stderr, "[Error] Unknown opcode %#02X\n", masked); + exit(1); + } + } + + instruction = Image[position++]; + + memset(lexem2, '\0', sizeof lexem2); + memset(lexeme, '\0', sizeof lexeme); + } +} + +int IsRegisterPattern(unsigned char pattern, unsigned char lexeme[2]) { + if (pattern > 8) 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; + return 1; +} +/* +//REG XXX0 0XXX 1010 1111 +//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 */ \ No newline at end of file diff --git a/src/main.c b/src/main.c index b74e6d4..187ef3c 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ #include "../includes/parser.h" #include "../includes/futil.h" #include "../includes/scanner.h" +#include "../includes/disass.h" int main(int argc, char* args[]) { if (argc == 1) { @@ -34,7 +35,8 @@ int main(int argc, char* args[]) { // if (t->type == LABEL) printf("* "); // } - ParseTokens(list); + unsigned char* image = ParseTokens(list); + Disassemble(image); free(source_code); } \ No newline at end of file diff --git a/src/opcodes.c b/src/opcodes.c index aff6387..72cfb11 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -19,9 +19,9 @@ Instruction instructions[OPCODECOUNT] = { unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType) { switch (type) { case COPY: - if (parameterOneType == Reg) return 0x20; //0b00100000; + if (parameterOneType & Reg) return 0x20; //0b00100000; - return 0xA0;////0b10100000; + return 0xA0;//0b10100000; case ADD: return 0x40;//0b01000000; case SUB: diff --git a/src/parser.c b/src/parser.c index 9106792..f97a4bc 100644 --- a/src/parser.c +++ b/src/parser.c @@ -4,12 +4,6 @@ #include #include -#ifndef HIGHMEMORY -#define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF -#endif - -//#define HEAPTOP HIGHMEMORY - typedef struct { Token* token; int address; @@ -24,7 +18,6 @@ struct intr { Symbol* CreateSymbol(Token* token, int address); const List* TokensList; int CurrentToken = 0; -//int HeapTop = HIGHMEMORY; void AddSymbol(Token*, int); void PrintSymbols(void); @@ -38,10 +31,10 @@ int ExpectTokenClass(int, ...); const Symbol* GetSymbol(char*); List* SymbolsTable; unsigned int ProgramCounter = 0; -char Memory[HIGHMEMORY]; +unsigned char Memory[HIGHMEMORY]; -void ParseTokens(List* tokens) { - if (!tokens) return; +unsigned char* ParseTokens(List* tokens) { + if (!tokens) return NULL; memset(Memory, 0, sizeof(Memory)); @@ -72,15 +65,17 @@ void ParseTokens(List* tokens) { AdvanceParser(); } - PrintSymbols(); + if (SymbolsTable->size > 0) PrintSymbols(); + DestroyList(SymbolsTable); - for(int i = 0; i < 32; i++) { - if (i != 0 && i % 3 == 0) printf("\n"); - printf("%02X ", Memory[i] & 0xFF); - } - printf("\n"); + // for(int i = 0; i < 33; i++) { + // if (i != 0 && i % 3 == 0) printf("\n"); + // printf("%02X ", Memory[i] & 0xFF); + // } + // printf("\n"); // printf("Program Counter: %d\n", ProgramCounter); //printf("Heap Top: %#06X\n", HeapTop); + return Memory; } void HandleAssemblerDirective(void) { @@ -132,9 +127,6 @@ void HandleAssemblerDirective(void) { } } -//REG XXX0 0XXX 1010 1111 -//Constant XXX0 1XXX -//Address XXX1 0XXX void HandleOperation(void) { const Instruction* inst = GetOpcodeDetails(PeekToken()->type); @@ -142,14 +134,12 @@ void HandleOperation(void) { AdvanceParser(); - printf("[%#05X] %s ", ProgramCounter, inst->lexeme); - Memory[ProgramCounter] = GetInstructionMask(inst->op, inst->parameter_one); ProgramCounter++; if (inst->parameter_one == None) { - printf("\n"); + //printf("\n"); return; } @@ -158,8 +148,8 @@ void HandleOperation(void) { if (inst->parameter_one & Reg) { //Encode the register number here. - Memory[ProgramCounter - 1] |= (PeekToken()->type - 29) & 0x07; - printf("%s ", PeekToken()->lexeme); + Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07; + //printf("%s ", PeekToken()->lexeme); } else if (inst->parameter_one & Address || inst->parameter_one & Constant) { if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { @@ -175,11 +165,11 @@ void HandleOperation(void) { Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; Memory[ProgramCounter + 1] = symbol->address & 0xFF; - printf("[%s@%#04X] ", PeekToken()->lexeme, symbol->address); + //printf("[%s@%#04X] ", PeekToken()->lexeme, symbol->address); } else if (PeekToken()->type == NUMBER) { Memory[ProgramCounter - 1] |= 0x08; //0b00001000; - printf("%s ", PeekToken()->lexeme); + //printf("%s ", PeekToken()->lexeme); } ProgramCounter += 2; @@ -189,7 +179,7 @@ void HandleOperation(void) { } if (inst->parameter_two == None) { - printf("\n"); + //printf("\n"); return; } @@ -213,11 +203,11 @@ void HandleOperation(void) { } if (inst->op == CMP) Memory[ProgramCounter - 1] |= 0x10;//0b00010000; - + Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; Memory[ProgramCounter + 1] = symbol->address & 0xFF; - printf("[%s@%#04X] ", PeekToken()->lexeme, symbol->address); + //printf("[%s@%#04X] ", PeekToken()->lexeme, symbol->address); } else if (PeekToken()->type == NUMBER) { Memory[ProgramCounter - 1] |= 0x08; //0b00001000; @@ -226,7 +216,7 @@ void HandleOperation(void) { Memory[ProgramCounter] = 2 >> *value & 0xFF; Memory[ProgramCounter + 1] = *value & 0xFF; - printf("%s ", PeekToken()->lexeme); + //printf("%s ", PeekToken()->lexeme); } ProgramCounter += 2; @@ -238,7 +228,7 @@ void HandleOperation(void) { printf("Inst %s (class: %x)\n", inst->lexeme, inst->parameter_two); } - printf("\n"); + //printf("\n"); } int ExpectTokenClass(int count, ...) {