even more fixes, and some work on assembly
This commit is contained in:
parent
7b40907e6a
commit
ffc77bef9f
@ -171,14 +171,14 @@ AsmLabelArray *GenerateLabels(AsmInstructionArray *assembly)
|
|||||||
if (cSize == mSize)
|
if (cSize == mSize)
|
||||||
{
|
{
|
||||||
mSize += ARRAY_SNAP_SIZE;
|
mSize += ARRAY_SNAP_SIZE;
|
||||||
labels->labels = reallc(labels->labels, mSize);
|
labels->labels = realloc(labels->labels, mSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assembly->instruction[0].label[0] == '\0')
|
if (assembly->instruction[0].label[0] == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
labels->labels[cSize].location = i;
|
labels->labels[cSize].location = i;
|
||||||
strcpy(&labels->labels[cSize].label, &assembly->instruction[0].label);
|
strcpy(labels->labels[cSize].label, assembly->instruction[0].label);
|
||||||
|
|
||||||
cSize++;
|
cSize++;
|
||||||
}
|
}
|
||||||
@ -189,7 +189,29 @@ AsmLabelArray *GenerateLabels(AsmInstructionArray *assembly)
|
|||||||
return labels;
|
return labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t *BinaryInstructionToBin(BinaryInstruction instruction)
|
||||||
|
{
|
||||||
|
uint16_t *bin = malloc(sizeof(uint16_t) * 3);
|
||||||
|
|
||||||
|
bin[0] = instruction.instruction +
|
||||||
|
(instruction.arg1Info << 12) +
|
||||||
|
(instruction.arg2Info << 14);
|
||||||
|
|
||||||
|
bin[1] = instruction.arg1;
|
||||||
|
bin[2] = instruction.arg2;
|
||||||
|
|
||||||
|
return bin;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t *CompileAsembly(AsmInstructionArray *assembly, AsmLabelArray *labels)
|
uint16_t *CompileAsembly(AsmInstructionArray *assembly, AsmLabelArray *labels)
|
||||||
{
|
{
|
||||||
|
uint16_t *ret = malloc(sizeof(uint16_t) * UINT16_MAX);
|
||||||
|
uint16_t cSize = 0, mSize = ARRAY_SNAP_SIZE;
|
||||||
|
|
||||||
|
for (int i = 0; i < assembly->length; i++)
|
||||||
|
{
|
||||||
|
BinaryInstruction binaryIns;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define ASM_ASSEMBLER_H
|
#define ASM_ASSEMBLER_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "asm_const.h"
|
#include "asm_const.h"
|
||||||
|
|
||||||
#define ARRAY_SNAP_SIZE 32
|
#define ARRAY_SNAP_SIZE 32
|
||||||
@ -12,6 +13,6 @@ char *FindNextSpaceChar(char *data, bool careAboutNull);
|
|||||||
|
|
||||||
AsmInstructionArray *InterpretAssembly(char *data);
|
AsmInstructionArray *InterpretAssembly(char *data);
|
||||||
AsmLabelArray *GenerateLabels(AsmInstructionArray *assembly);
|
AsmLabelArray *GenerateLabels(AsmInstructionArray *assembly);
|
||||||
BinaryInstructionArray *CompileAsembly(AsmInstructionArray *assembly);
|
uint16_t *CompileAsembly(AsmInstructionArray *assembly, AsmLabelArray *labels);
|
||||||
|
|
||||||
#endif
|
#endif
|
4
build.sh
4
build.sh
@ -1,5 +1,5 @@
|
|||||||
mkdir ./bin
|
mkdir ./bin
|
||||||
clang -O2 -o ./bin/r16emu ./emu/main.c ./emu/cpu/instruction.c ./emu/cpu/ram.c ./emu/cpu/register.c ./emu/cpu/stack.c ./lib/carg-parse/carg-parse.c
|
clang -O2 -o ./bin/r16e ./emu/main.c ./emu/cpu/instruction.c ./emu/cpu/ram.c ./emu/cpu/register.c ./emu/cpu/stack.c ./lib/carg-parse/carg-parse.c
|
||||||
echo "built emulator"
|
echo "built emulator"
|
||||||
clang -O2 -o ./bin/r16asm ./asm/main.c ./asm/assembler.c ./lib/carg-parse/carg-parse.c
|
clang -O2 -o ./bin/r16a ./asm/main.c ./asm/assembler.c ./lib/carg-parse/carg-parse.c
|
||||||
echo "built assemblor"
|
echo "built assemblor"
|
@ -3,18 +3,21 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
void LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info,
|
bool LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info,
|
||||||
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2,
|
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2,
|
||||||
r16_int arg1Val, r16_int arg2Val)
|
r16_int arg1Val, r16_int arg2Val)
|
||||||
{
|
{
|
||||||
|
#ifdef LOG_INSTRUCTION_DATA
|
||||||
char *hReadIns = CpuInstructionsHumanReadable[instruction],
|
char *hReadIns = CpuInstructionsHumanReadable[instruction],
|
||||||
*hReadA1I = ArgumentInfoHumanReadable[arg1Info],
|
*hReadA1I = ArgumentInfoHumanReadable[arg1Info],
|
||||||
*hReadA2I = ArgumentInfoHumanReadable[arg1Info],
|
*hReadA2I = ArgumentInfoHumanReadable[arg2Info],
|
||||||
*actArg1 = malloc(sizeof(char) * 32),
|
actArg1[32] = { 0 }, actArg2[32] = { 0 },
|
||||||
*actArg2 = malloc(sizeof(char) * 32),
|
hReadA1[32] = { 0 }, hReadA2[32] = { 0 };
|
||||||
*hReadA1 = malloc(sizeof(char) * 32),
|
|
||||||
*hReadA2 = malloc(sizeof(char) * 32);
|
|
||||||
|
|
||||||
sprintf(actArg1, "0x%X", arg1Val.u);
|
sprintf(actArg1, "0x%X", arg1Val.u);
|
||||||
sprintf(actArg2, "0x%X", arg2Val.u);
|
sprintf(actArg2, "0x%X", arg2Val.u);
|
||||||
@ -22,15 +25,13 @@ void LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info,
|
|||||||
switch (arg1Info)
|
switch (arg1Info)
|
||||||
{
|
{
|
||||||
case value:
|
case value:
|
||||||
free(hReadA1);
|
hReadA1[0] = '~';
|
||||||
hReadA1 = "~";
|
|
||||||
break;
|
break;
|
||||||
case valueInRam:
|
case valueInRam:
|
||||||
sprintf(hReadA1, "0x%X", arg1.u);
|
sprintf(hReadA1, "0x%X", arg1.u);
|
||||||
break;
|
break;
|
||||||
case valueInRegister:
|
case valueInRegister:
|
||||||
free(hReadA1);
|
strncpy(hReadA1, CpuRegistersHumanReadable[arg1.u], 31);
|
||||||
hReadA1 = CpuRegistersHumanReadable[arg1.u];
|
|
||||||
break;
|
break;
|
||||||
case pointerInRegister:
|
case pointerInRegister:
|
||||||
sprintf(hReadA1, "%s ~ 0x%X", CpuRegistersHumanReadable[arg1.u], GetRegister(arg1.u).u);
|
sprintf(hReadA1, "%s ~ 0x%X", CpuRegistersHumanReadable[arg1.u], GetRegister(arg1.u).u);
|
||||||
@ -40,15 +41,13 @@ void LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info,
|
|||||||
switch (arg2Info)
|
switch (arg2Info)
|
||||||
{
|
{
|
||||||
case value:
|
case value:
|
||||||
free(hReadA2);
|
hReadA2[0] = '~';
|
||||||
hReadA2 = "~";
|
|
||||||
break;
|
break;
|
||||||
case valueInRam:
|
case valueInRam:
|
||||||
sprintf(hReadA2, "0x%X", arg2.u);
|
sprintf(hReadA2, "0x%X", arg2.u);
|
||||||
break;
|
break;
|
||||||
case valueInRegister:
|
case valueInRegister:
|
||||||
free(hReadA2);
|
strncpy(hReadA2, CpuRegistersHumanReadable[arg2.u], 31);
|
||||||
hReadA2 = CpuRegistersHumanReadable[arg2.u];
|
|
||||||
break;
|
break;
|
||||||
case pointerInRegister:
|
case pointerInRegister:
|
||||||
sprintf(hReadA2, "%s ~ 0x%X", CpuRegistersHumanReadable[arg2.u], GetRegister(arg2.u).u);
|
sprintf(hReadA2, "%s ~ 0x%X", CpuRegistersHumanReadable[arg2.u], GetRegister(arg2.u).u);
|
||||||
@ -58,10 +57,10 @@ void LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info,
|
|||||||
printf("%s :: (%s) %s -> %s, (%s) %s -> %s\n",
|
printf("%s :: (%s) %s -> %s, (%s) %s -> %s\n",
|
||||||
hReadIns, hReadA1I, hReadA1, actArg1, hReadA2I, hReadA2, actArg2);
|
hReadIns, hReadA1I, hReadA1, actArg1, hReadA2I, hReadA2, actArg2);
|
||||||
|
|
||||||
free(actArg1);
|
return true;
|
||||||
free(actArg2);
|
#else
|
||||||
free(hReadA1);
|
return false;
|
||||||
free(hReadA2);
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
r16_int GetArgVal(ArgumentInfo argInfo, r16_int arg)
|
r16_int GetArgVal(ArgumentInfo argInfo, r16_int arg)
|
||||||
@ -91,101 +90,72 @@ void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info,
|
|||||||
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2)
|
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2)
|
||||||
{
|
{
|
||||||
r16_int actArg1, actArg2;
|
r16_int actArg1, actArg2;
|
||||||
|
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
||||||
|
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
||||||
|
|
||||||
switch (instruction)
|
switch (instruction)
|
||||||
{
|
{
|
||||||
case HLT:
|
case HLT:
|
||||||
printf("\nprogram HALTED!\n");
|
printf("\nprogram HALTED!\n");
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, (r16_int){ 0 }, (r16_int){ 0 });
|
|
||||||
exit(0);
|
exit(0);
|
||||||
case ADD:
|
case ADD:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
SetRegister(ACU, (r16_int){ actArg1.s + actArg2.s });
|
SetRegister(ACU, (r16_int){ actArg1.s + actArg2.s });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case SUB:
|
case SUB:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
SetRegister(ACU, (r16_int){ actArg1.s - actArg2.s });
|
SetRegister(ACU, (r16_int){ actArg1.s - actArg2.s });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case MUL:
|
case MUL:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
SetRegister(ACU, (r16_int){ actArg1.s * actArg2.s });
|
SetRegister(ACU, (r16_int){ actArg1.s * actArg2.s });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case DIV:
|
case DIV:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
if (actArg2.s == 0)
|
if (actArg2.s == 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "DIV by 0\n");
|
fprintf(stderr, "DIV by 0\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
SetRegister(ACU, (r16_int){ actArg1.s / actArg2.s });
|
SetRegister(ACU, (r16_int){ actArg1.s / actArg2.s });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case LBS:
|
case LBS:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
SetRegister(ACU, (r16_int){ actArg1.s << actArg2.s });
|
SetRegister(ACU, (r16_int){ actArg1.s << actArg2.s });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case RBS:
|
case RBS:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
SetRegister(ACU, (r16_int){ actArg1.s >> actArg2.s });
|
SetRegister(ACU, (r16_int){ actArg1.s >> actArg2.s });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case BAN:
|
case BAN:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
SetRegister(ACU, (r16_int){ actArg1.u & actArg2.u });
|
SetRegister(ACU, (r16_int){ actArg1.u & actArg2.u });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case BOR:
|
case BOR:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
SetRegister(ACU, (r16_int){ actArg1.u | actArg2.u });
|
SetRegister(ACU, (r16_int){ actArg1.u | actArg2.u });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case BXO:
|
case BXO:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
SetRegister(ACU, (r16_int){ actArg1.u ^ actArg2.u });
|
SetRegister(ACU, (r16_int){ actArg1.u ^ actArg2.u });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case BNO:
|
case BNO:
|
||||||
actArg1 = GetArgVal(arg1Info, arg1);
|
|
||||||
SetRegister(ACU, (r16_int){ ~ actArg1.u });
|
SetRegister(ACU, (r16_int){ ~ actArg1.u });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, (r16_int){ 0 });
|
|
||||||
break;
|
break;
|
||||||
case PUS:
|
case PUS:
|
||||||
actArg1 = GetArgVal(arg1Info, arg1);
|
|
||||||
StackPush(actArg1);
|
StackPush(actArg1);
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, (r16_int){ 0 });
|
|
||||||
break;
|
break;
|
||||||
case POP:
|
case POP:
|
||||||
SetRegister(ACU, StackPop());
|
SetRegister(ACU, StackPop());
|
||||||
break;
|
break;
|
||||||
case JMP:
|
case JMP:
|
||||||
SetRegister(PC, GetArgVal(arg1Info, arg1));
|
SetRegister(PC, GetArgVal(arg1Info, arg1));
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, (r16_int){ 0 }, (r16_int){ 0 });
|
|
||||||
break;
|
break;
|
||||||
case JEQ:
|
case JEQ:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
if (actArg2.u == GetRegister(ACU).u)
|
if (actArg2.u == GetRegister(ACU).u)
|
||||||
SetRegister(PC, actArg1);
|
SetRegister(PC, actArg1);
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case JNZ:
|
case JNZ:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
if (actArg2.s != 0)
|
if (actArg2.s != 0)
|
||||||
SetRegister(PC, actArg1);
|
SetRegister(PC, actArg1);
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
case CAL:
|
case CAL:
|
||||||
actArg1 = GetArgVal(arg1Info, arg1);
|
|
||||||
StackPush(GetRegister(PC));
|
StackPush(GetRegister(PC));
|
||||||
SetRegister(PC, actArg1);
|
SetRegister(PC, actArg1);
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, (r16_int){ 0 });
|
|
||||||
break;
|
break;
|
||||||
case RET:
|
case RET:
|
||||||
SetRegister(PC, StackPop());
|
SetRegister(PC, StackPop());
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, (r16_int){ 0 }, (r16_int){ 0 });
|
|
||||||
break;
|
break;
|
||||||
case REG: // TODO
|
case REG: // TODO
|
||||||
case INT: // TODO
|
case INT: // TODO
|
||||||
@ -193,21 +163,16 @@ void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info,
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
case INP:
|
case INP:
|
||||||
SetRegister(ACU, (r16_int){ getchar() });
|
SetRegister(ACU, (r16_int){ getchar() });
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, (r16_int){ 0 }, (r16_int){ 0 });
|
|
||||||
break;
|
break;
|
||||||
case OUT:
|
case OUT:
|
||||||
actArg1 = GetArgVal(arg1Info, arg1);
|
|
||||||
putchar((char)(GetArgVal(arg1Info, arg1).u));
|
putchar((char)(GetArgVal(arg1Info, arg1).u));
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, (r16_int){ 0 });
|
|
||||||
break;
|
break;
|
||||||
case DIN: // TODO
|
case DIN: // TODO
|
||||||
case DOT: // TODO
|
case DOT: // TODO
|
||||||
fprintf(stderr, "DISK NOT IMPLEMENTED YET\n");
|
fprintf(stderr, "DISK NOT IMPLEMENTED YET\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
case MOV:
|
case MOV:
|
||||||
GetAllArgVal(arg1Info, arg2Info, arg1, arg2, &actArg1, &actArg2);
|
|
||||||
SetValue(actArg1, actArg2);
|
SetValue(actArg1, actArg2);
|
||||||
LogInstructionData(instruction, arg1Info, arg2Info, arg1, arg2, actArg1, actArg2);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,11 +5,14 @@
|
|||||||
#include "./ram.h"
|
#include "./ram.h"
|
||||||
#include "./register.h"
|
#include "./register.h"
|
||||||
#include "./stack.h"
|
#include "./stack.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info,
|
#define LOG_INSTRUCTION_DATA
|
||||||
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2);
|
|
||||||
void LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info,
|
bool LogInstructionData(CpuInstructions instruction, ArgumentInfo arg1Info,
|
||||||
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2,
|
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2,
|
||||||
r16_int arg1Val, r16_int arg2Val);
|
r16_int arg1Val, r16_int arg2Val);
|
||||||
|
void ExecuteInstruction(CpuInstructions instruction, ArgumentInfo arg1Info,
|
||||||
|
ArgumentInfo arg2Info, r16_int arg1, r16_int arg2);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -16,3 +16,10 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ErrorHandle(int exitCode, char *exitMessage)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s", exitMessage);
|
||||||
|
|
||||||
|
exit(exitCode);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user