Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

Commit

Permalink
Finished test cast for push instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
mattixtech committed Aug 4, 2018
1 parent 7d2bddd commit 54bdb90
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 51 deletions.
60 changes: 60 additions & 0 deletions src/io/load.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
*/

#include <stdint.h>
#include <stdio.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <memory.h>

#include "../util/util.h"
#include "../vm/vm.h"

/**
Expand All @@ -23,4 +28,59 @@ void load_program(uint32_t program[], int size, uint32_t *destination)
destination[i] = program[i];
flash_allocated++;
}
}

/**
* Load the file into program array that can be copied to flash.
*
* @param file_name the file name to load
*/
int load_file(const char *file_name)
{
// TODO: This is all first pass, seems to be working but can probably be
// cleaned up
int fd;
uint8_t buf;

FILE *fp = fopen(file_name, "r");

if (fp == NULL)
return 1;

fseek(fp, 0L, SEEK_END);
long sz = ftell(fp);
fseek(fp, 0, SEEK_SET);

if ((fd = open(file_name, O_RDONLY)) < 0)
return 1;

uint8_t file_bytes[sz];
memset(file_bytes, 0, sizeof(file_bytes));

int i = 0;
while (read(fd, &buf, 1) > 0)
{
file_bytes[i++] = buf;
}

uint32_t program[(sz + INSTRUCTION_SIZE - 1) / INSTRUCTION_SIZE];
memset(program, 0, sizeof(program));
int count = 0;

for (int j = 0; j < sz; j += 4)
{
// Only part of the flash memory is instructions. What follows is
// arbitrary data and does not necessarily fit in a 4 byte instruction.
// We will put it in one anyway and just 0-out the excess.
uint8_t instr_type = file_bytes[j];
uint8_t instr_mode = (j + 1) < sz ? file_bytes[j + 1] : (uint8_t) 0;
uint8_t instr_d1 = (j + 2) < sz ? file_bytes[j + 2] : (uint8_t) 0;
uint8_t instr_d2 = (j + 3) < sz ? file_bytes[j + 3] : (uint8_t) 0;
program[count++] = create_instruction(instr_type, instr_mode,
instr_d1, instr_d2);
}

load_program(program, sizeof(program) / sizeof(program[0]), flash);

return 0;
}
1 change: 1 addition & 0 deletions src/io/load.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@

#ifndef LOAD_H
#define LOAD_H
int load_file(const char *);
void load_program(uint32_t program[], int size, uint32_t *destination);
#endif
21 changes: 18 additions & 3 deletions src/mbvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
#include <string.h>

#include "instructions/instructions.h"
#include "io/load.h"
#include "system/system.h"
#include "util/util.h"
#include "vm/vm.h"

static const char *file_name;

/**
* Check the command line arguments.
*
Expand All @@ -32,9 +35,15 @@ int parse_args(int argc, const char *argv[])
}

// Turn on debugging if -d switch was provided as command line arg
if (argc > 1)
if (argc > 2)
{
if (strcmp(argv[1], "-d") == 0)
{
debugging = 1;
file_name = argv[2];
}
}else
file_name = argv[1];

return 0;
}
Expand All @@ -55,8 +64,14 @@ int main(int argc, const char *argv[])
// TODO: Take VM init values as command line arguments
allocate_vm(DEFAULT_RAM_SIZE, DEFAULT_FLASH_SIZE, NUM_REGISTERS,
REGISTER_SIZE, DEFAULT_STACK_SIZE);
// TODO: load in the program specified via command line
load_test_app();

// Load from the file
if (0 != load_file(file_name))
{
printf("ERROR: Failed to open file '%s'.", file_name);
return 1;
}

// Pass the program to the virtual machine and begin executing
exec_program();
// Free all the memory we allocated
Expand Down
17 changes: 12 additions & 5 deletions src/system/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,12 @@ int exec(uint32_t programCode)
*/
uint32_t get_dword(uint8_t *loc, uint32_t image_addr)
{
uint32_t b0 = loc[image_addr + 0] << 24;
uint32_t b1 = loc[image_addr + 1] << 16;
uint32_t b2 = loc[image_addr + 2] << 8;
uint32_t b3 = loc[image_addr + 3];
uint32_t b3 = loc[image_addr + 0] << 24;
uint32_t b2 = loc[image_addr + 1] << 16;
uint32_t b1 = loc[image_addr + 2] << 8;
uint32_t b0 = loc[image_addr + 3];

return 0x00000000 | b0 | b1 | b2 | b3;
// return *(uint32_t *) (loc + image_addr);
}

/**
Expand Down Expand Up @@ -130,6 +129,14 @@ void disp_image(uint32_t *image, int blocks)
i * INSTRUCTION_SIZE, image[i], chars[3], chars[2], chars[1],
chars[0]);
}

puts("{");

// TODO: Loop duplication...
for (int i = 0; i < blocks; i++)
printf("\t" FORMAT_HEX_4_BYTE "\n", image[i]);

puts("}");
}
}

Expand Down
24 changes: 0 additions & 24 deletions src/util/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,3 @@ uint32_t create_instruction(uint8_t instr, uint8_t mode,

return instruction;
}

/**
* Load a hardcoded test program.
*/
void load_test_app()
{
// Hello world...
uint32_t program[] =
{
create_instruction(INSTR_LOAD, MODE_IMMEDIATE_B, EMPTY_BYTE,
0x10),
create_instruction(INSTR_STORE, MODE_REGISTER, EMPTY_BYTE,
0x09),
create_instruction(ADV_INSTR_PRINT, MODE_EXTRA, EMPTY_BYTE,
EMPTY_BYTE),
create_instruction(INSTR_EXIT, EMPTY_BYTE, EMPTY_BYTE,
EMPTY_BYTE),
0x68656C6C, // The string 'hello world\n'
0x6F20776F,
0x726C640A};

// Load it
load_program(program, sizeof(program) / sizeof(program[0]), flash);
}
1 change: 0 additions & 1 deletion src/util/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@
#define UTIL_H
uint32_t create_instruction(uint8_t instr, uint8_t mode, uint8_t d1,
uint8_t d2);
void load_test_app();
#endif
Binary file added test_programs/hello_world
Binary file not shown.
156 changes: 151 additions & 5 deletions tests/instructions/test_instructions.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,172 @@ void test_instr_push()
DUMMY_VALUE_8));
CU_ASSERT(DUMMY_VALUE_8 == pop());
deallocate();

// MODE_IMMEDIATE_W
allocate();
exec(create_instruction(INSTR_PUSH, MODE_IMMEDIATE_W, DUMMY_VALUE_8,
DUMMY_VALUE_8));
CU_ASSERT(DUMMY_VALUE_16 == pop());
deallocate();

// MODE_DATA_32
allocate();
*((uint32_t *) (ram + INSTRUCTION_SIZE)) = DUMMY_VALUE_32;
exec(create_instruction(INSTR_PUSH, MODE_DATA_32, EMPTY_BYTE,
EMPTY_BYTE));
CU_ASSERT(DUMMY_VALUE_32 == pop());
deallocate();

// The instruction locations for the successive instructions after our push
// to help with addressing and indirection
const int NEXT_INSTR = INSTRUCTION_SIZE;
const int NEXT2_INSTR = INSTRUCTION_SIZE * 2;
const int NEXT3_INSTR = INSTRUCTION_SIZE * 3;

// MODE_DATA_32_ADDR
allocate();
// *((uint32_t *)(ram + INSTRUCTION_SIZE)) = INSTRUCTION_SIZE * 2;
// *((uint32_t *) (ram + (INSTRUCTION_SIZE * 2))) = DUMMY_VALUE_32;
// exec(create_instruction(INSTR_PUSH, MODE_DATA_32_ADDR, EMPTY_BYTE,
// EMPTY_BYTE));
// CU_ASSERT(DUMMY_VALUE_32 == pop());
// Store address 2*instr in the next instruction (ram[instr])
store_dword(ram, NEXT_INSTR, NEXT2_INSTR);
// Store a dummy value in ram[instr*2]
store_dword(ram, NEXT2_INSTR, DUMMY_VALUE_32);
exec(create_instruction(INSTR_PUSH, MODE_DATA_32_ADDR, EMPTY_BYTE,
EMPTY_BYTE));
CU_ASSERT(DUMMY_VALUE_32 == pop());
deallocate();

// MODE_DATA_32_ADDR_W
allocate();
// Store address 2*instr in the next instruction (ram[instr])
store_dword(ram, NEXT_INSTR, NEXT2_INSTR);
// Store a dummy value in ram[instr*2]
store_word(ram, NEXT2_INSTR, DUMMY_VALUE_16);
exec(create_instruction(INSTR_PUSH, MODE_DATA_32_ADDR_W, EMPTY_BYTE,
EMPTY_BYTE));
CU_ASSERT(DUMMY_VALUE_16 == pop());
deallocate();

// MODE_DATA_32_ADDR_B
allocate();
// Store address 2*instr in the next instruction (ram[instr])
store_dword(ram, NEXT_INSTR, NEXT2_INSTR);
// Store a dummy value in ram[instr*2]
store_byte(ram, NEXT2_INSTR, DUMMY_VALUE_8);
exec(create_instruction(INSTR_PUSH, MODE_DATA_32_ADDR_B, EMPTY_BYTE,
EMPTY_BYTE));
CU_ASSERT(DUMMY_VALUE_8 == pop());
deallocate();

// MODE_DATA_32_INDR
allocate();
// Store address 2*instr in the next instruction (ram[instr])
store_dword(ram, NEXT_INSTR, NEXT2_INSTR);
// Store address 3*instr in ram[instr*2]
store_dword(ram, NEXT2_INSTR, NEXT3_INSTR);
// Store a dummy value in ram[instr*4]
store_dword(ram, NEXT3_INSTR, DUMMY_VALUE_32);
exec(create_instruction(INSTR_PUSH, MODE_DATA_32_INDR, EMPTY_BYTE,
EMPTY_BYTE));
CU_ASSERT(DUMMY_VALUE_32 == pop());
deallocate();

// MODE_DATA_32_INDR_W
allocate();
// Store address 2*instr in the next instruction (ram[instr])
store_dword(ram, NEXT_INSTR, NEXT2_INSTR);
// Store address 3*instr in ram[instr*2]
store_dword(ram, NEXT2_INSTR, NEXT3_INSTR);
// Store a dummy value in ram[instr*4]
store_word(ram, NEXT3_INSTR, DUMMY_VALUE_16);
exec(create_instruction(INSTR_PUSH, MODE_DATA_32_INDR_W, EMPTY_BYTE,
EMPTY_BYTE));
CU_ASSERT(DUMMY_VALUE_16 == pop());
deallocate();

// MODE_DATA_32_INDR_B
allocate();
// Store address 2*instr in the next instruction (ram[instr])
store_dword(ram, NEXT_INSTR, NEXT2_INSTR);
// Store address 3*instr in ram[instr*2]
store_dword(ram, NEXT2_INSTR, NEXT3_INSTR);
// Store a dummy value in ram[instr*4]
store_byte(ram, NEXT3_INSTR, DUMMY_VALUE_8);
exec(create_instruction(INSTR_PUSH, MODE_DATA_32_INDR_B, EMPTY_BYTE,
EMPTY_BYTE));
CU_ASSERT(DUMMY_VALUE_8 == pop());
deallocate();

// MODE_REGISTER
allocate();
r[TEST_REGISTER] = DUMMY_VALUE_32;
exec(create_instruction(INSTR_PUSH, MODE_REGISTER, EMPTY_BYTE,
TEST_REGISTER));
CU_ASSERT(DUMMY_VALUE_32 == pop());
deallocate();

// MODE_REGISTER_ADDR
allocate();
// Point register to next instruction
r[TEST_REGISTER] = NEXT_INSTR;
// Store the dummy value in that next instruction
store_dword(ram, NEXT_INSTR, DUMMY_VALUE_32);
exec(create_instruction(INSTR_PUSH, MODE_REGISTER_ADDR, EMPTY_BYTE,
TEST_REGISTER));
CU_ASSERT(DUMMY_VALUE_32 == pop());
deallocate();

// MODE_REGISTER_ADDR_W
allocate();
// Point register to next instruction
r[TEST_REGISTER] = NEXT_INSTR;
// Store the dummy value in that next instruction
store_word(ram, NEXT_INSTR, DUMMY_VALUE_16);
exec(create_instruction(INSTR_PUSH, MODE_REGISTER_ADDR_W, EMPTY_BYTE,
TEST_REGISTER));
CU_ASSERT(DUMMY_VALUE_16 == pop());
deallocate();

// MODE_REGISTER_ADDR_B
allocate();
// Point register to next instruction
r[TEST_REGISTER] = NEXT_INSTR;
// Store the dummy value in that next instruction
store_byte(ram, NEXT_INSTR, DUMMY_VALUE_8);
exec(create_instruction(INSTR_PUSH, MODE_REGISTER_ADDR_B, EMPTY_BYTE,
TEST_REGISTER));
CU_ASSERT(DUMMY_VALUE_8 == pop());
deallocate();

// MODE_REGISTER_INDR
allocate();
// Point register to next instruction
r[TEST_REGISTER] = NEXT_INSTR;
store_dword(ram, NEXT_INSTR, NEXT2_INSTR);
store_dword(ram, NEXT2_INSTR, DUMMY_VALUE_32);
exec(create_instruction(INSTR_PUSH, MODE_REGISTER_INDR, EMPTY_BYTE,
TEST_REGISTER));
CU_ASSERT(DUMMY_VALUE_32 == pop());
deallocate();

// MODE_REGISTER_INDR_W
allocate();
// Point register to next instruction
r[TEST_REGISTER] = NEXT_INSTR;
store_dword(ram, NEXT_INSTR, NEXT2_INSTR);
store_word(ram, NEXT2_INSTR, DUMMY_VALUE_16);
exec(create_instruction(INSTR_PUSH, MODE_REGISTER_INDR_W, EMPTY_BYTE,
TEST_REGISTER));
CU_ASSERT(DUMMY_VALUE_16 == pop());
deallocate();

// MODE_REGISTER_INDR_B
allocate();
// Point register to next instruction
r[TEST_REGISTER] = NEXT_INSTR;
store_dword(ram, NEXT_INSTR, NEXT2_INSTR);
store_byte(ram, NEXT2_INSTR, DUMMY_VALUE_8);
exec(create_instruction(INSTR_PUSH, MODE_REGISTER_INDR_B, EMPTY_BYTE,
TEST_REGISTER));
CU_ASSERT(DUMMY_VALUE_8 == pop());
deallocate();
}

Expand Down
1 change: 1 addition & 0 deletions tests/instructions/test_instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define DUMMY_VALUE_8 0xAB
#define DUMMY_VALUE_16 0xABAB
#define DUMMY_VALUE_32 0xABABABAB
#define TEST_REGISTER 5
int init_instructions_test_suite();
int clean_instructions_test_suite();
void test_instr_exit();
Expand Down
Loading

0 comments on commit 54bdb90

Please sign in to comment.