Added more instructions for the parser to emit and refactored the code in doing so.

This commit is contained in:
2022-08-28 15:37:56 -05:00
parent c2111e2b88
commit 0d3f8a460e
5 changed files with 141 additions and 74 deletions
+33 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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, ...) {