From 5f437b6869759c4b564d5b41f9bc0d611697ddf1 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Mon, 29 Aug 2022 18:51:48 +0000 Subject: [PATCH] Both the assembler and the disassembler should now support all the instructions I've layed out thus far. --- includes/opcodes.h | 2 +- includes/token.h | 2 +- misc/test.asm | 7 ++- src/disass.c | 20 +++++++-- src/opcodes.c | 9 +++- src/parser.c | 109 +++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 133 insertions(+), 16 deletions(-) diff --git a/includes/opcodes.h b/includes/opcodes.h index c964cb1..366094f 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -4,7 +4,7 @@ #include #include "token.h" -#define OPCODECOUNT 12 +#define OPCODECOUNT 13 #define REGISTERCOUNT 8 typedef struct { diff --git a/includes/token.h b/includes/token.h index 78a6984..d353a88 100644 --- a/includes/token.h +++ b/includes/token.h @@ -28,7 +28,7 @@ typedef enum { DB, ORG, //Opcodes COPY, ADD, SUB, JZ, INT, YLD, RET, - CMP, NOP, JMP, IN, OUT, + CMP, NOP, JMP, CALL, IN, OUT, //Registers R1, R2, R3, R4, R5, R6, R7, R8 } TokenType; diff --git a/misc/test.asm b/misc/test.asm index 4a98417..27a86e8 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -1,12 +1,17 @@ ;.org 0x100 .db msg "Hello, world!", 0 -;.db more_stuff "AA", 0 +.db more_stuff "AA", 0 copy r7, msg ; // cmp r8, 45 ;1000 1111 add r4, 30 sub r1, 69 int 20 jz 45 +jmp msg +in 10 +call more_stuff +ret +yld ;copy r1, 45 ;//B0 = 10110000 ;copy 2, 45 diff --git a/src/disass.c b/src/disass.c index 1ccfd98..b694215 100644 --- a/src/disass.c +++ b/src/disass.c @@ -20,8 +20,6 @@ void Disassemble(unsigned char image[HIGHMEMORY]) { int position = image[0] + image[1]; int end = image[2] + image[3]; - printf("Start: %d and End: %d\n", position, end); - char* parameter1 = calloc(32, sizeof(char)); char* parameter2 = calloc(32, sizeof(char)); @@ -79,7 +77,7 @@ void Disassemble(unsigned char image[HIGHMEMORY]) { position += 3; break; case 2: - printf("INT %d\n", Image[position + 1] + Image[position + 2]); + printf("INT %d\n", parameter); position += 3; break; case 3: @@ -90,6 +88,22 @@ void Disassemble(unsigned char image[HIGHMEMORY]) { 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; diff --git a/src/opcodes.c b/src/opcodes.c index 03e743a..85c5a76 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -14,7 +14,8 @@ Instruction instructions[OPCODECOUNT] = { { "in", IN, Constant | Reg, None}, { "out", OUT, None, None}, { "nop", NOP, None, None}, - { "jz", JZ, Address, None} + { "jmp", JMP, Address, None}, + { "call", CALL, Address, None} }; unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType) { @@ -33,6 +34,12 @@ unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType) { return 0x01;//0b00000001; case INT: return 0x02; //0b00000010; + case YLD: + return 0x03; + case RET: + return 0x04; + case CALL: + return 0x05; case JMP: return 0x06;//0b00000110; case IN: diff --git a/src/parser.c b/src/parser.c index a0b0577..3b37d4d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -83,13 +83,13 @@ unsigned char* ParseTokens(List* tokens) { Heap[2] = 2 >> totalSize & 0xFF; Heap[3] = totalSize & 0xFF; - for(int i = 0; i < 33; i++) { - if (i != 0 && i % 3 == 0) printf("\n"); - printf("%02X ", Heap[i] & 0xFF); - } - printf("\n"); - printf("Program Counter: %d\n", ProgramCounter); - printf("Heap Top: %#06X\n", HeapTop); + // for(int i = 0; i < 33; i++) { + // if (i != 0 && i % 3 == 0) printf("\n"); + // printf("%02X ", Heap[i] & 0xFF); + // } + // printf("\n"); + // printf("Program Counter: %d\n", ProgramCounter); + // printf("Heap Top: %#06X\n", HeapTop); return Heap; } @@ -112,7 +112,7 @@ void HandleAssemblerDirective(void) { switch(identifier->type) { case STRING: - printf("[INFO] %s = '%s' (%#04X)\n", identifier->lexeme, identifier->lexeme, HeapTop); + //printf("[INFO] %s = '%s' (%#04X)\n", identifier->lexeme, identifier->lexeme, HeapTop); for(int i = 0; i < strlen(identifier->lexeme); i++) { //Memory[ProgramCounter + i] = PeekToken()->lexeme[i]; @@ -215,7 +215,6 @@ void HandleOperation(void) { AdvanceParser(); - //Memory[ProgramCounter] = GetInstructionMask(inst->op, inst->parameter_one); unsigned char mask = GetInstructionMask(inst->op, inst->parameter_one); if (mask & registerBasedOpcodeMask) { @@ -277,6 +276,98 @@ void HandleOperation(void) { ProgramCounter += 2; return; + case 3: //YLD + Memory[ProgramCounter] = 0x03; + + ProgramCounter++; + break; + case 4: //RET + Memory[ProgramCounter] = 0x04; + + ProgramCounter++; + break; + case 5: //CALL + Memory[ProgramCounter] = 0x05; + + ProgramCounter++; + + if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { + const Symbol* symbol = GetSymbol(PeekToken()->lexeme); + + if (!symbol) { + fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); + exit(1); + } + + Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; + Memory[ProgramCounter + 1] = symbol->address & 0xFF; + } + else { + fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line); + exit(1); + } + + ProgramCounter += 2; + break; + case 6: //JMP + Memory[ProgramCounter] = 0x06; + + ProgramCounter++; + + if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { + const Symbol* symbol = GetSymbol(PeekToken()->lexeme); + + if (!symbol) { + fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); + exit(1); + } + + Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; + Memory[ProgramCounter + 1] = symbol->address & 0xFF; + } + else { + fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line); + exit(1); + } + + ProgramCounter += 2; + break; + case 7: //IN + Memory[ProgramCounter] = 0x07; + + ProgramCounter++; + + if (PeekToken()->type == NUMBER) { + int* value = PeekToken()->value; + + Memory[ProgramCounter] = 2 >> *value & 0xFF; + Memory[ProgramCounter + 1] = *value & 0xFF; + } + else { + fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->line); + exit(1); + } + + ProgramCounter += 2; + break; + case 8: //OUT + Memory[ProgramCounter] = 0x08; + + ProgramCounter++; + + if (PeekToken()->type == NUMBER) { + int* value = PeekToken()->value; + + Memory[ProgramCounter] = 2 >> *value & 0xFF; + Memory[ProgramCounter + 1] = *value & 0xFF; + } + else { + fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->line); + exit(1); + } + + ProgramCounter += 2; + break; } return;