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 <string.h>
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
#define OPCODECOUNT 11
|
#define OPCODECOUNT 12
|
||||||
#define REGISTERCOUNT 8
|
#define REGISTERCOUNT 8
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
+5
-1
@@ -2,7 +2,11 @@
|
|||||||
;.db msg "Hello, world!", 0
|
;.db msg "Hello, world!", 0
|
||||||
;.db more_stuff "AA", 0
|
;.db more_stuff "AA", 0
|
||||||
copy r7, 45 ; //
|
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 r1, 45 ;//B0 = 10110000
|
||||||
;copy 2, 45
|
;copy 2, 45
|
||||||
|
|||||||
+33
-4
@@ -32,15 +32,15 @@ void Disassemble(unsigned char image[HIGHMEMORY]) {
|
|||||||
|
|
||||||
if (masked) {
|
if (masked) {
|
||||||
IsRegisterPattern(instruction & 0x07, parameter1);
|
IsRegisterPattern(instruction & 0x07, parameter1);
|
||||||
unsigned char parameter = instruction & 0x18;
|
unsigned char parameterType = instruction & 0x18;
|
||||||
|
|
||||||
if (!parameter) {
|
if (!parameterType) {
|
||||||
IsRegisterPattern(Image[position], parameter2);
|
IsRegisterPattern(Image[position], parameter2);
|
||||||
} else if (parameter == CONSTMASK) {
|
} else if (parameterType == CONSTMASK) {
|
||||||
snprintf(parameter2, sizeof(char) * 31, "%d", Image[position + 1] + Image[position + 2]);
|
snprintf(parameter2, sizeof(char) * 31, "%d", Image[position + 1] + Image[position + 2]);
|
||||||
position += 3;
|
position += 3;
|
||||||
}
|
}
|
||||||
else if (parameter == ADDRESSMASK) {
|
else if (parameterType == ADDRESSMASK) {
|
||||||
snprintf(parameter2, sizeof(char) * 31, "[%#04X]", Image[position + 1] + Image[position + 2]);
|
snprintf(parameter2, sizeof(char) * 31, "[%#04X]", Image[position + 1] + Image[position + 2]);
|
||||||
position += 3;
|
position += 3;
|
||||||
}
|
}
|
||||||
@@ -66,6 +66,35 @@ void Disassemble(unsigned char image[HIGHMEMORY]) {
|
|||||||
exit(1);
|
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];
|
instruction = Image[position];
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -13,7 +13,8 @@ Instruction instructions[OPCODECOUNT] = {
|
|||||||
{ "cmp", CMP, Reg, Reg | Constant },
|
{ "cmp", CMP, Reg, Reg | Constant },
|
||||||
{ "in", IN, Constant | Reg, None},
|
{ "in", IN, Constant | Reg, None},
|
||||||
{ "out", OUT, None, None},
|
{ "out", OUT, None, None},
|
||||||
{ "nop", NOP, None, None}
|
{ "nop", NOP, None, None},
|
||||||
|
{ "jz", JZ, Address, None}
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType) {
|
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) {
|
void HandleOperation(void) {
|
||||||
const Instruction* inst = GetOpcodeDetails(PeekToken()->type);
|
const Instruction* inst = GetOpcodeDetails(PeekToken()->type);
|
||||||
|
const unsigned char registerBasedOpcodeMask = 0xE0;
|
||||||
|
|
||||||
if (!inst) return;
|
if (!inst) return;
|
||||||
|
|
||||||
AdvanceParser();
|
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 (mask & registerBasedOpcodeMask) {
|
||||||
|
HandleRegisterBasedOpcode(Memory[ProgramCounter], mask);
|
||||||
if (inst->parameter_one == None) {
|
|
||||||
//printf("\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->parameter_one && PeekToken()->token_class > 0) {
|
switch (mask) {
|
||||||
//printf("Matched '%s'\n", PeekToken()->lexeme);
|
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) {
|
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
|
||||||
const Symbol* symbol = GetSymbol(PeekToken()->lexeme);
|
const Symbol* symbol = GetSymbol(PeekToken()->lexeme);
|
||||||
|
|
||||||
@@ -160,75 +221,47 @@ void HandleOperation(void) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->op == CMP) Memory[ProgramCounter - 1] |= 0x10;//0b00010000;
|
|
||||||
|
|
||||||
Memory[ProgramCounter] = 2 >> symbol->address & 0xFF;
|
Memory[ProgramCounter] = 2 >> symbol->address & 0xFF;
|
||||||
Memory[ProgramCounter + 1] = 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) {
|
else if (PeekToken()->type == NUMBER) {
|
||||||
Memory[ProgramCounter - 1] |= 0x08; //0b00001000;
|
|
||||||
int* value = PeekToken()->value;
|
int* value = PeekToken()->value;
|
||||||
|
|
||||||
Memory[ProgramCounter] = 2 >> *value & 0xFF;
|
Memory[ProgramCounter] = 2 >> *value & 0xFF;
|
||||||
Memory[ProgramCounter + 1] = *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;
|
ProgramCounter += 2;
|
||||||
}
|
|
||||||
|
|
||||||
AdvanceParser();
|
return;
|
||||||
} else {
|
case 2: //INT
|
||||||
printf("Failed to match %s (class: %d)\n", PeekToken()->lexeme, PeekToken()->token_class);
|
Memory[ProgramCounter] = 0x02;
|
||||||
printf("Inst %s (class: %x)\n", inst->lexeme, inst->parameter_two);
|
|
||||||
|
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, ...) {
|
int ExpectTokenClass(int count, ...) {
|
||||||
|
|||||||
Reference in New Issue
Block a user