227 lines
8.4 KiB
C
Executable file
227 lines
8.4 KiB
C
Executable file
/*
|
|
This code is part of the EIPA Platform
|
|
|
|
This code contains the implementations for all the functions related to the target code (binary) generation
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "../header/common.h"
|
|
#include "../header/target_code_generator.h"
|
|
|
|
__uint32_t get_target_instruction(__uint8_t opcode, __uint8_t use_adress, __uint32_t adress)
|
|
{
|
|
// stores the value of the instructions
|
|
__uint32_t instruction = 0;
|
|
|
|
// move the opcode bytes to the left of the instruction
|
|
instruction = instruction | (unsigned)opcode << (28);
|
|
|
|
if (!use_adress)
|
|
{
|
|
return instruction;
|
|
}
|
|
if (adress >= MAX_MEMORY)
|
|
{
|
|
return 0;
|
|
}
|
|
// store the adress without modifing the opcode
|
|
instruction = instruction | adress;
|
|
|
|
return instruction;
|
|
}
|
|
|
|
int gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
|
|
{
|
|
// stores which token we are currently looking at
|
|
unsigned int token_index = 0;
|
|
|
|
// stores which instruction we are currently looking at
|
|
unsigned int instruction_index = 0;
|
|
|
|
while (tokens[token_index][0] != EOF)
|
|
{
|
|
if (strcmp(tokens[token_index], ";") == 0)
|
|
{
|
|
// indice of a new instruction
|
|
instruction_index++;
|
|
}
|
|
else if (strcmp(tokens[token_index], "INP") == 0)
|
|
{
|
|
// Stores the Adress accociated with this operation
|
|
__uint32_t adress;
|
|
|
|
// The address of the instructon is stored at the next token. Read that
|
|
token_index++;
|
|
sscanf(tokens[token_index], "%d", &adress);
|
|
|
|
target_code[instruction_index] = get_target_instruction(INSTR_INP, 1, adress);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "OUT") == 0)
|
|
{
|
|
// Stores the Adress accociated with this operation
|
|
__uint32_t adress;
|
|
|
|
// The address of the instructon is stored at the next token. Read that
|
|
token_index++;
|
|
sscanf(tokens[token_index], "%d", &adress);
|
|
|
|
target_code[instruction_index] = get_target_instruction(INSTR_OUT, 1, adress);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "LDA") == 0)
|
|
{
|
|
// Stores the Adress accociated with this operation
|
|
__uint32_t adress;
|
|
|
|
// The address of the instructon is stored at the next token. Read that
|
|
token_index++;
|
|
sscanf(tokens[token_index], "%d", &adress);
|
|
|
|
target_code[instruction_index] = get_target_instruction(INSTR_LDA, 1, adress);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "STA") == 0)
|
|
{
|
|
// Stores the Adress accociated with this operation
|
|
__uint32_t adress;
|
|
|
|
// The address of the instructon is stored at the next token. Read that
|
|
token_index++;
|
|
sscanf(tokens[token_index], "%d", &adress);
|
|
|
|
target_code[instruction_index] = get_target_instruction(INSTR_STA, 1, adress);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "INC") == 0)
|
|
{
|
|
target_code[instruction_index] = get_target_instruction(INSTR_INC, 0, 0);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "DEC") == 0)
|
|
{
|
|
target_code[instruction_index] = get_target_instruction(INSTR_DEC, 0, 0);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "JPP") == 0)
|
|
{
|
|
|
|
// Stores the Adress accociated with this operation
|
|
__uint32_t adress;
|
|
|
|
// The address of the instructon is stored at the next token. Read that
|
|
token_index++;
|
|
sscanf(tokens[token_index], "%d", &adress);
|
|
|
|
target_code[instruction_index] = get_target_instruction(INSTR_JPP, 1, adress);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "JPZ") == 0)
|
|
{
|
|
// Stores the Adress accociated with this operation
|
|
__uint32_t adress;
|
|
|
|
// The address of the instructon is stored at the next token. Read that
|
|
token_index++;
|
|
sscanf(tokens[token_index], "%d", &adress);
|
|
|
|
target_code[instruction_index] = get_target_instruction(INSTR_JPZ, 1, adress);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "JPN") == 0)
|
|
{
|
|
// Stores the Adress accociated with this operation
|
|
__uint32_t adress;
|
|
|
|
// The address of the instructon is stored at the next token. Read that
|
|
token_index++;
|
|
sscanf(tokens[token_index], "%d", &adress);
|
|
|
|
target_code[instruction_index] = get_target_instruction(INSTR_JPN, 1, adress);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "JPU") == 0)
|
|
{
|
|
// Stores the Adress accociated with this operation
|
|
__uint32_t adress;
|
|
|
|
// The address of the instructon is stored at the next token. Read that
|
|
token_index++;
|
|
sscanf(tokens[token_index], "%d", &adress);
|
|
|
|
target_code[instruction_index] = get_target_instruction(INSTR_JPU, 1, adress);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
else if (strcmp(tokens[token_index], "EOJ") == 0)
|
|
{
|
|
target_code[instruction_index] = get_target_instruction(INSTR_EOJ, 0, 0);
|
|
if (target_code[instruction_index] == 0)
|
|
{
|
|
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
|
|
return EOVERFLOW;
|
|
}
|
|
}
|
|
|
|
token_index++;
|
|
}
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
void print_target_code(__uint32_t *target_code)
|
|
{
|
|
int instruction_index = 0;
|
|
while (target_code[instruction_index] != 0)
|
|
{
|
|
int i = 0;
|
|
for (i = (sizeof(target_code[instruction_index]) * 8) - 1; i >= 0; i--)
|
|
{
|
|
putchar(target_code[instruction_index] & (1u << i) ? '1' : '0');
|
|
}
|
|
printf("\n");
|
|
instruction_index++;
|
|
}
|
|
}
|