From 0d3f8a460eaaf03abd3e519d3510bc7f78f7af7b Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Sun, 28 Aug 2022 15:37:56 -0500 Subject: [PATCH] Added more instructions for the parser to emit and refactored the code in doing so. --- includes/opcodes.h | 2 +- misc/test.asm | 6 +- src/disass.c | 37 ++++++++-- src/opcodes.c | 3 +- src/parser.c | 167 +++++++++++++++++++++++++++------------------ 5 files changed, 141 insertions(+), 74 deletions(-) diff --git a/includes/opcodes.h b/includes/opcodes.h index 611413b..c964cb1 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -4,7 +4,7 @@ #include #include "token.h" -#define OPCODECOUNT 11 +#define OPCODECOUNT 12 #define REGISTERCOUNT 8 typedef struct { diff --git a/misc/test.asm b/misc/test.asm index 75a82d2..71c01f2 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -2,7 +2,11 @@ ;.db msg "Hello, world!", 0 ;.db more_stuff "AA", 0 copy r7, 45 ; // -cmp r8, 41 ;1000 1111 +cmp r8, 45 ;1000 1111 +add r4, 30 +sub r1, 69 +int 20 +jz 45 ;copy r1, 45 ;//B0 = 10110000 ;copy 2, 45 diff --git a/src/disass.c b/src/disass.c index d123b79..383758b 100644 --- a/src/disass.c +++ b/src/disass.c @@ -32,15 +32,15 @@ void Disassemble(unsigned char image[HIGHMEMORY]) { if (masked) { IsRegisterPattern(instruction & 0x07, parameter1); - unsigned char parameter = instruction & 0x18; + unsigned char parameterType = instruction & 0x18; - if (!parameter) { + if (!parameterType) { IsRegisterPattern(Image[position], parameter2); - } else if (parameter == CONSTMASK) { + } else if (parameterType == CONSTMASK) { snprintf(parameter2, sizeof(char) * 31, "%d", Image[position + 1] + Image[position + 2]); position += 3; } - else if (parameter == ADDRESSMASK) { + else if (parameterType == ADDRESSMASK) { snprintf(parameter2, sizeof(char) * 31, "[%#04X]", Image[position + 1] + Image[position + 2]); position += 3; } @@ -66,6 +66,35 @@ void Disassemble(unsigned char image[HIGHMEMORY]) { 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", Image[position + 1] + Image[position + 2]); + position += 3; + break; + case 3: + printf("YLD\n"); + position++; + break; + case 4: + printf("RET\n"); + position++; + break; + default: + position++; + break; + } + } instruction = Image[position]; diff --git a/src/opcodes.c b/src/opcodes.c index 72cfb11..03e743a 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -13,7 +13,8 @@ Instruction instructions[OPCODECOUNT] = { { "cmp", CMP, Reg, Reg | Constant }, { "in", IN, Constant | Reg, None}, { "out", OUT, None, None}, - { "nop", NOP, None, None} + { "nop", NOP, None, None}, + { "jz", JZ, Address, None} }; unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType) { diff --git a/src/parser.c b/src/parser.c index 39442b3..cd54f1f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -127,31 +127,92 @@ void HandleAssemblerDirective(void) { } } +void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) { + Memory[ProgramCounter] = mask; + + ProgramCounter++; + + const Token* token = PeekToken(); + + if (token->token_class == Reg) { + Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07; + + AdvanceParser(); + } + else { + fprintf(stderr, "[Error] Line %d: Expected register operand.\n", token->line); + exit(1); + } + + token = PeekToken(); + + if (!Expect(1, COMMA)) { + fprintf(stderr, "[Error] Expected command one line %d.\n", token->line); + exit(1); + } + + token = PeekToken(); + + if (token->token_class == IDENTIFIER || token->token_class == LABEL) { + const Symbol* symbol = GetSymbol(token->lexeme); + + if (!symbol) { + fprintf(stderr, "[Error] Line %d: %s is undefined.\n", token->line, token->lexeme); + exit(1); + } + + Memory[ProgramCounter - 1] |= 0x10;//0b00010000; + + Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; + Memory[ProgramCounter + 1] = symbol->address & 0xFF; + + ProgramCounter += 2; + + AdvanceParser(); + } + else if (token->type == NUMBER) { + Memory[ProgramCounter - 1] |= 0x08; //0b00001000; + + int* value = PeekToken()->value; + + Memory[ProgramCounter] = 2 >> *value & 0xFF; + Memory[ProgramCounter + 1] = *value & 0xFF; + + ProgramCounter += 2; + + AdvanceParser(); + } else { + fprintf(stderr, "[Error] Expected operand, got %s\n", token->lexeme); + exit(1); + } +} + void HandleOperation(void) { const Instruction* inst = GetOpcodeDetails(PeekToken()->type); + const unsigned char registerBasedOpcodeMask = 0xE0; if (!inst) return; AdvanceParser(); - Memory[ProgramCounter] = GetInstructionMask(inst->op, inst->parameter_one); + //Memory[ProgramCounter] = GetInstructionMask(inst->op, inst->parameter_one); + unsigned char mask = GetInstructionMask(inst->op, inst->parameter_one); - ProgramCounter++; - - if (inst->parameter_one == None) { - //printf("\n"); + if (mask & registerBasedOpcodeMask) { + HandleRegisterBasedOpcode(Memory[ProgramCounter], mask); return; } - if (inst->parameter_one && PeekToken()->token_class > 0) { - //printf("Matched '%s'\n", PeekToken()->lexeme); + switch (mask) { + case 0: //NOP + Memory[ProgramCounter] = 0x00; + ProgramCounter++; + return; + case 1: //JZ + Memory[ProgramCounter] = 0x01; + + ProgramCounter++; - if (inst->parameter_one & Reg) { - //Encode the register number here. - 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) { const Symbol* symbol = GetSymbol(PeekToken()->lexeme); @@ -160,75 +221,47 @@ void HandleOperation(void) { exit(1); } - 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); - } - else if (PeekToken()->type == NUMBER) { - Memory[ProgramCounter - 1] |= 0x08; //0b00001000; - //printf("%s ", PeekToken()->lexeme); - } - - ProgramCounter += 2; - } - - AdvanceParser(); - } - - if (inst->parameter_two == None) { - //printf("\n"); - return; - } - - if (PeekToken()->type == COMMA) { - AdvanceParser(); - } else { - fprintf(stderr, "Expected comma at line %d\n", PeekToken()->line); - exit(666); - return; - } - - if (inst->parameter_two && PeekToken()->token_class > 0) { - //printf("Matched 2 '%s'\n", PeekToken()->lexeme); - if (inst->parameter_two & Address || inst->parameter_two & Constant) { - if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { - const Symbol* symbol = GetSymbol(PeekToken()->lexeme); - - if (!symbol) { - fprintf(stderr, "[Error] %s is undefined.\n", PeekToken()->lexeme); - exit(1); - } - - 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); } else if (PeekToken()->type == NUMBER) { - Memory[ProgramCounter - 1] |= 0x08; //0b00001000; int* value = PeekToken()->value; Memory[ProgramCounter] = 2 >> *value & 0xFF; Memory[ProgramCounter + 1] = *value & 0xFF; - //printf("%s ", PeekToken()->lexeme); + ProgramCounter += 2; + } + else { + fprintf(stderr, "[Error] Line: %d: Expected address after jump if zero (JZ) instruction.\n", ((Token*) TokensList->content[CurrentToken - 1])->line); + exit(1); } ProgramCounter += 2; - } - AdvanceParser(); - } else { - printf("Failed to match %s (class: %d)\n", PeekToken()->lexeme, PeekToken()->token_class); - printf("Inst %s (class: %x)\n", inst->lexeme, inst->parameter_two); + return; + case 2: //INT + Memory[ProgramCounter] = 0x02; + + ProgramCounter++; + + if (PeekToken()->type == NUMBER) { + int* value = PeekToken()->value; + + Memory[ProgramCounter] = 2 >> *value & 0xFF; + Memory[ProgramCounter + 1] = *value & 0xFF; + + ProgramCounter += 2; + } + else { + fprintf(stderr, "[Error] Line %d: Expected Interrupt vector.\n", PeekToken()->line); + exit(1); + } + + return; } - //printf("\n"); + return; } int ExpectTokenClass(int count, ...) {