119 lines
2.9 KiB
C
119 lines
2.9 KiB
C
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <assert.h>
|
||
|
#include <unistd.h>
|
||
|
#include "interpreter/interpreter.h"
|
||
|
#include "interpreter/core_methods.h"
|
||
|
#include "method_dispatcher/method_dispatcher.h"
|
||
|
|
||
|
size_t copy_cache(uint16_t * cache
|
||
|
, uint16_t offset
|
||
|
, size_t cache_size
|
||
|
, void * cache_function_data);
|
||
|
|
||
|
bci_core_method_t core_methods[22] = {
|
||
|
(bci_core_method_t) bci_cm_ldi
|
||
|
, (bci_core_method_t) bci_cm_ld
|
||
|
, (bci_core_method_t) bci_cm_st
|
||
|
, (bci_core_method_t) bci_cm_inc
|
||
|
, (bci_core_method_t) bci_cm_dec
|
||
|
, (bci_core_method_t) bci_cm_add
|
||
|
, (bci_core_method_t) bci_cm_sub
|
||
|
, (bci_core_method_t) bci_cm_mul
|
||
|
, (bci_core_method_t) bci_cm_div
|
||
|
, (bci_core_method_t) bci_cm_gt
|
||
|
, (bci_core_method_t) bci_cm_ge
|
||
|
, (bci_core_method_t) bci_cm_lt
|
||
|
, (bci_core_method_t) bci_cm_le
|
||
|
, (bci_core_method_t) bci_cm_eq
|
||
|
, (bci_core_method_t) bci_cm_not
|
||
|
, (bci_core_method_t) bci_cm_jmp
|
||
|
, (bci_core_method_t) bci_cm_cjmp
|
||
|
, (bci_core_method_t) bci_cm_call
|
||
|
, (bci_core_method_t) bci_cm_ccall
|
||
|
, (bci_core_method_t) bci_cm_ret
|
||
|
, (bci_core_method_t) bci_cm_cl
|
||
|
, (bci_core_method_t) bci_cm_stop
|
||
|
};
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
FILE * program = fopen("code.bin", "r");
|
||
|
if(!program)
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
uint16_t program_size;
|
||
|
read(fileno(program), &program_size, 2);
|
||
|
|
||
|
dispatch_tree_t tree = dispatch_tree_t_new();
|
||
|
dispatch_tree_autoinserter_t inserter = dispatch_tree_autoinserter_t_new(tree);
|
||
|
for(i = 0; i < 22; i++)
|
||
|
{
|
||
|
dispatch_tree_autoinserter_t_insert(inserter, core_methods[i]);
|
||
|
}
|
||
|
|
||
|
machine_state_t state = machine_state_t_new(
|
||
|
program
|
||
|
, program_size
|
||
|
, 1024
|
||
|
, 512
|
||
|
, copy_cache
|
||
|
, tree);
|
||
|
|
||
|
char status = machine_state_t_exec(state);
|
||
|
|
||
|
printf("######## STATUS ##############\n");
|
||
|
printf("state->error = 0x%x\n", state->error);
|
||
|
printf("state->shutdown_reg = 0x%x\n", state->shutdown_reg);
|
||
|
printf("state->status_reg = 0x%x\n", state->status_reg);
|
||
|
printf("state->program_counter = 0x%x\n", state->program_counter);
|
||
|
printf("######## REGISTERS ###########\n");
|
||
|
for(i = 0; i < BCI_CORE_NUM_REG; i++)
|
||
|
{
|
||
|
printf("\t[%d] = 0x%x\n", i, state->data_reg[i]);
|
||
|
}
|
||
|
// printf("####### MEMORY ###############\n");
|
||
|
// for(i = 0; i < 512; i++)
|
||
|
// {
|
||
|
// printf("\t[%d] = 0x%x\n", i, state->memory[i]);
|
||
|
// }
|
||
|
|
||
|
machine_state_t_del(state);
|
||
|
fclose(program);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
size_t copy_cache(uint16_t * cache
|
||
|
, uint16_t offset
|
||
|
, size_t cache_size
|
||
|
, void * cache_function_data)
|
||
|
{
|
||
|
FILE * program_file = (FILE *) cache_function_data;
|
||
|
size_t did_read = 0;
|
||
|
|
||
|
fseek(program_file, (offset + 1) * 2, 0);
|
||
|
did_read = read(fileno(program_file), cache, cache_size * 2);
|
||
|
|
||
|
if(did_read == 0 || did_read > cache_size)
|
||
|
{
|
||
|
// This is an actual error.
|
||
|
return 0;
|
||
|
}
|
||
|
if(did_read < cache_size && offset == 0)
|
||
|
{
|
||
|
// We just hit EOF, but that is not a problem,
|
||
|
// our program is just smaller than the cache.
|
||
|
int i;
|
||
|
for(i = did_read; i < cache_size; i++)
|
||
|
{
|
||
|
cache[i] = 0;
|
||
|
}
|
||
|
return cache_size;
|
||
|
}
|
||
|
|
||
|
return did_read / 2;
|
||
|
}
|