Added stuff. Fixed bug.
Data Pointer value now properly displayed in debug mode. Added conditional calls to match conditional branches.
This commit is contained in:
@@ -29,9 +29,13 @@ Instruction instruction_set[] = {
|
||||
{0x11, "BRQ"},
|
||||
{0x12, "BRA"},
|
||||
{0x13, "BRB"},
|
||||
{0x14, "CALL"},
|
||||
{0x15, "RET"},
|
||||
{0x16, "BRC"},
|
||||
{0x14, "BRC"},
|
||||
{0x17, "CALL"},
|
||||
{0x18, "CALLA"},
|
||||
{0x19, "CALLB"},
|
||||
{0x1A, "CALLQ"},
|
||||
{0x1B, "CALLCF"},
|
||||
{0x1F, "RET"},
|
||||
// Register Operations:
|
||||
{0x20, "RSTA"},
|
||||
{0x21, "RSTB"},
|
||||
|
||||
@@ -112,7 +112,7 @@ void populateOutputBuffers(intermediateElement *intermediateArray, int arraySize
|
||||
Program[(*programCount)++] = intermediateArray[i].byteValue;
|
||||
|
||||
// Check if it's a branch instruction.
|
||||
if (((intermediateArray[i].byteValue & 0xF0) == 0x10) && (intermediateArray[i].byteValue != 0x15)){
|
||||
if (((intermediateArray[i].byteValue & 0xF0) == 0x10) && (intermediateArray[i].byteValue != 0x1F)){
|
||||
if (intermediateArray[i + 1].type != LABEL) {
|
||||
fprintf(stderr, RED "Error: Branch without label.\n" RESET);
|
||||
printf("File: %s at line %d.\n", intermediateArray[i].fileName, intermediateArray[i].lineNumber);
|
||||
|
||||
+59
-32
@@ -31,6 +31,31 @@ void genericBranch(CPURegisters *cpu){
|
||||
cpu->ProgramCounter = DestinationAddress-1;
|
||||
}
|
||||
|
||||
void genericCall(CPURegisters *cpu){
|
||||
// Order, low byte, high byte
|
||||
cpu->Data[cpu->StackPointer] = cpu->ProgramCounter & 0xFF;
|
||||
cpu->StackPointer--;
|
||||
cpu->Data[cpu->StackPointer] = (cpu->ProgramCounter >> 8) & 0xFF;
|
||||
cpu->StackPointer--;
|
||||
// Push the Data Pointer to the Stack.
|
||||
// Order, low byte, high byte
|
||||
cpu->Data[cpu->StackPointer] = cpu->DataPointer & 0xFF;
|
||||
cpu->StackPointer--;
|
||||
cpu->Data[cpu->StackPointer] = (cpu->DataPointer >> 8) & 0xFF;
|
||||
cpu->StackPointer--;
|
||||
// Push Q to the Stack.
|
||||
cpu->Data[cpu->StackPointer] = cpu->Q;
|
||||
cpu->StackPointer--;
|
||||
// Push B to the Stack.
|
||||
cpu->Data[cpu->StackPointer] = cpu->B;
|
||||
cpu->StackPointer--;
|
||||
// Push A to the Stack.
|
||||
cpu->Data[cpu->StackPointer] = cpu->A;
|
||||
cpu->StackPointer--;
|
||||
// Perform a Generic Branch to the Address.
|
||||
genericBranch(cpu);
|
||||
}
|
||||
|
||||
uint8_t executeOperation(uint8_t Instruction, CPURegisters *cpu) {
|
||||
switch(Instruction) {
|
||||
// 0x - Arithmetic and Logic Operations.
|
||||
@@ -131,31 +156,41 @@ uint8_t executeOperation(uint8_t Instruction, CPURegisters *cpu) {
|
||||
}
|
||||
break;
|
||||
case 0x14:
|
||||
// CALL - Push the Program Counter to the Stack, and perform an immediate branch.
|
||||
// Order, low byte, high byte
|
||||
cpu->Data[cpu->StackPointer] = cpu->ProgramCounter & 0xFF;
|
||||
cpu->StackPointer--;
|
||||
cpu->Data[cpu->StackPointer] = (cpu->ProgramCounter >> 8) & 0xFF;
|
||||
cpu->StackPointer--;
|
||||
// Push the Data Pointer to the Stack.
|
||||
// Order, low byte, high byte
|
||||
cpu->Data[cpu->StackPointer] = cpu->DataPointer & 0xFF;
|
||||
cpu->StackPointer--;
|
||||
cpu->Data[cpu->StackPointer] = (cpu->DataPointer >> 8) & 0xFF;
|
||||
cpu->StackPointer--;
|
||||
// Push Q to the Stack.
|
||||
cpu->Data[cpu->StackPointer] = cpu->Q;
|
||||
cpu->StackPointer--;
|
||||
// Push B to the Stack.
|
||||
cpu->Data[cpu->StackPointer] = cpu->B;
|
||||
cpu->StackPointer--;
|
||||
// Push A to the Stack.
|
||||
cpu->Data[cpu->StackPointer] = cpu->A;
|
||||
cpu->StackPointer--;
|
||||
// Perform a Generic Branch to the Address.
|
||||
genericBranch(cpu);
|
||||
// BRC - Do an immediate branch if the Carry Flag is set.
|
||||
if (cpu->Status & 0x01) {
|
||||
genericBranch(cpu);
|
||||
} else {
|
||||
cpu->ProgramCounter+=2;
|
||||
}
|
||||
break;
|
||||
case 0x15:
|
||||
case 0x17:
|
||||
// CALL - Push the Program Counter to the Stack, and perform an immediate branch.
|
||||
genericCall(cpu);
|
||||
break;
|
||||
case 0x18:
|
||||
// CALLA
|
||||
if (cpu->A == 0) {
|
||||
genericCall(cpu);
|
||||
}
|
||||
break;
|
||||
case 0x19:
|
||||
// CALLB
|
||||
if (cpu->B == 0) {
|
||||
genericCall(cpu);
|
||||
}
|
||||
break;
|
||||
case 0x1A:
|
||||
// CALLQ
|
||||
if (cpu->Q == 0) {
|
||||
genericCall(cpu);
|
||||
}
|
||||
case 0x1B:
|
||||
// CALLCF
|
||||
if (cpu->Status & 0x01) {
|
||||
genericCall(cpu);
|
||||
}
|
||||
break;
|
||||
case 0x1F:
|
||||
// RET - Return from subroutine, restore the registers and set the Program Counter to the Return Address.
|
||||
// Pop A from the Stack.
|
||||
cpu->StackPointer++;
|
||||
@@ -179,14 +214,6 @@ uint8_t executeOperation(uint8_t Instruction, CPURegisters *cpu) {
|
||||
// Add 2 to the Program Counter to skip over the address when it returns.
|
||||
cpu->ProgramCounter += 2;
|
||||
break;
|
||||
case 0x16:
|
||||
// BRC - Do an immediate branch is the Carry Flag is set.
|
||||
if (cpu->Status & 0x01) {
|
||||
genericBranch(cpu);
|
||||
} else {
|
||||
cpu->ProgramCounter+=2;
|
||||
}
|
||||
break;
|
||||
//
|
||||
// 2x - Register Operations:
|
||||
//
|
||||
|
||||
@@ -51,6 +51,6 @@ void printRegisters(CPURegisters *cpu, uint8_t *Program, uint8_t *Data) {
|
||||
printf("A: 0x%02X\tB: 0x%02X\tQ: 0x%02X\tStatus: 0b%08b\n", cpu->A, cpu->B, cpu->Q, cpu->Status);
|
||||
printf("Program Counter: 0x%04X Current Instruction: 0x%02X (%s)\n", cpu->ProgramCounter, Program[cpu->ProgramCounter],getMnemonic(Program[cpu->ProgramCounter]));
|
||||
printf(" Data Pointer: 0x%04X Current Data Value: 0x%02X\n", cpu->DataPointer, Data[cpu->DataPointer]);
|
||||
printf(" Stack Pointer: 0x%04X Current Value: (0x%02X) (0x%02X)\n", Data[cpu->StackPointer], Data[cpu->StackPointer+1], Data[cpu->StackPointer+2]);
|
||||
printf(" Stack Pointer: 0x%04X Current Value: (0x%02X) (0x%02X)\n", cpu->StackPointer, Data[cpu->StackPointer+1], Data[cpu->StackPointer+2]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user