Added more instructions for the parser to emit and refactored the code in doing so.
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@
|
||||
#include <string.h>
|
||||
#include "token.h"
|
||||
|
||||
#define OPCODECOUNT 11
|
||||
#define OPCODECOUNT 12
|
||||
#define REGISTERCOUNT 8
|
||||
|
||||
typedef struct {
|
||||
|
||||
+5
-1
@@ -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
|
||||
|
||||
+33
-4
@@ -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];
|
||||
|
||||
|
||||
+2
-1
@@ -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) {
|
||||
|
||||
+100
-67
@@ -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, ...) {
|
||||
|
||||
Reference in New Issue
Block a user