From 237d5e3cb63dbaff01316b3e0ce342975c8678f9 Mon Sep 17 00:00:00 2001 From: Peter Evans Date: Tue, 21 Nov 2017 23:24:51 -0600 Subject: [PATCH] First commit --- .gitignore | 2 + CMakeLists.txt | 19 ++++++++ build/.gitkeep | 0 include/log.h | 11 +++++ include/vm_screen.h | 18 ++++++++ include/vm_segment.h | 21 +++++++++ sources.cmake | 5 +++ src/log.c | 34 ++++++++++++++ src/main.c | 27 +++++++++++ src/vm_screen.c | 42 +++++++++++++++++ src/vm_segment.c | 104 +++++++++++++++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 18 ++++++++ tests/build/.gitkeep | 0 tests/main.c | 5 +++ 14 files changed, 306 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 build/.gitkeep create mode 100644 include/log.h create mode 100644 include/vm_screen.h create mode 100644 include/vm_segment.h create mode 100644 sources.cmake create mode 100644 src/log.c create mode 100644 src/main.c create mode 100644 src/vm_screen.c create mode 100644 src/vm_segment.c create mode 100644 tests/CMakeLists.txt create mode 100644 tests/build/.gitkeep create mode 100644 tests/main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5a1572 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.swp +build diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8eb0dba --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.9) + +# it me +project(emp) + +include(sources.cmake) + +foreach(src ${emp_sources}) + string(CONCAT relsrc src/ ${src}) + list(APPEND sources ${relsrc}) +endforeach(src) + +# our header files +include_directories(include /usr/local/include) + +link_directories(/usr/local/lib) + +# our bullshit +add_executable(emp ${sources} src/main.c) diff --git a/build/.gitkeep b/build/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/include/log.h b/include/log.h new file mode 100644 index 0000000..8611788 --- /dev/null +++ b/include/log.h @@ -0,0 +1,11 @@ +#ifndef _LOG_H_ +#define _LOG_H_ + +extern void log_write(int, const char *, ...); +extern void log_close(); +extern void log_open(); + +#define log_critical(...) log_write(0, __VA_ARGS__) +#define log_error(...) log_write(0, __VA_ARGS__) + +#endif diff --git a/include/vm_screen.h b/include/vm_screen.h new file mode 100644 index 0000000..2548cf6 --- /dev/null +++ b/include/vm_screen.h @@ -0,0 +1,18 @@ +#ifndef _VM_SCREEN_H_ +#define _VM_SCREEN_H_ + +typedef struct { + int color_red; + int color_green; + int color_blue; + int color_alpha; +} vm_screen_context; + +extern void vm_screen_draw_rect(vm_screen_context *, int, int, int, int); +extern vm_screen_context *vm_screen_new_context(); +extern void vm_screen_set_color(vm_screen_context *, int, int, int, int); + +#define vm_screen_draw_pixel(context, xpos, ypos) \ + vm_screen_draw_rect(context, xpos, ypos, 1, 1) + +#endif diff --git a/include/vm_segment.h b/include/vm_segment.h new file mode 100644 index 0000000..fd1e9ea --- /dev/null +++ b/include/vm_segment.h @@ -0,0 +1,21 @@ +#ifndef _VM_SEGMENT_H_ +#define _VM_SEGMENT_H_ + +#define VM_SEGMENT_TABLE_MAX 16 + +typedef uint8_t vm_segment_byte; + +typedef struct { + size_t size; + vm_segment_byte *memory; +} vm_segment; + +extern void vm_segment_copy(vm_segment *, vm_segment *, size_t, size_t, size_t); +extern vm_segment *vm_segment_create(size_t); +extern vm_segment_byte vm_segment_get(vm_segment *, size_t); +extern void vm_segment_set(vm_segment *, size_t, vm_segment_byte); + +#define vm_segment_bounds_check(segment, index) \ + (index == index % segment->size) + +#endif diff --git a/sources.cmake b/sources.cmake new file mode 100644 index 0000000..45e293f --- /dev/null +++ b/sources.cmake @@ -0,0 +1,5 @@ +set(emp_sources + log.c + vm_screen.c + vm_segment.c + ) diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..a26c427 --- /dev/null +++ b/src/log.c @@ -0,0 +1,34 @@ +#include +#include +#include + +static FILE *log_stream = NULL; + +void +log_open() +{ + log_stream = fopen("/tmp/emp.log", "w"); + if (log_stream == NULL) { + perror("Couldn't open log file (/tmp/emp.log)"); + exit(1); + } +} + +void +log_close() +{ + if (log_stream != NULL) { + fclose(log_stream); + } +} + +void +log_write(int level, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(log_stream, fmt, ap); + fprintf(log_stream, "\n"); + va_end(ap); +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..74b2339 --- /dev/null +++ b/src/main.c @@ -0,0 +1,27 @@ +#include +#include + +#include "log.h" + +static void +init() +{ + log_open(); +} + +static void +finish() +{ + log_close(); +} + +int +main(int argc, char **argv) +{ + init(); + + // When we exit, we want to wrap up a few loose ends. + atexit(finish); + + printf("Hello, world\n"); +} diff --git a/src/vm_screen.c b/src/vm_screen.c new file mode 100644 index 0000000..8186e70 --- /dev/null +++ b/src/vm_screen.c @@ -0,0 +1,42 @@ +#include + +#include "log.h" +#include "vm_screen.h" + +vm_screen_context * +vm_screen_new_context() +{ + vm_screen_context *context; + + context = (vm_screen_context *)malloc(sizeof(vm_screen_context)); + if (context == NULL) { + log_critical("Failed to allocate vm_screen_context"); + exit(1); + } + + vm_screen_set_color(context, 0, 0, 0, 0); + return context; +} + +void +vm_screen_set_color(vm_screen_context *context, + int red, + int green, + int blue, + int alpha) +{ + context->color_red = red; + context->color_green = green; + context->color_blue = blue; + context->color_alpha = alpha; +} + +void +vm_screen_draw_rect(vm_screen_context *context, + int xpos, + int ypos, + int xsize, + int ysize) +{ + // FIXME: NOOP +} diff --git a/src/vm_segment.c b/src/vm_segment.c new file mode 100644 index 0000000..e6c78a7 --- /dev/null +++ b/src/vm_segment.c @@ -0,0 +1,104 @@ +#include +#include + +#include "log.h" +#include "vm_segment.h" + +static vm_segment *seg_table[VM_SEGMENT_TABLE_MAX]; +static unsigned int seg_index = 0; + +vm_segment * +vm_segment_create(size_t size) +{ + vm_segment *seg; + + // Block us from attempting to allocate any memory beyond the + // maximum defined blocks. + if (seg_index >= VM_SEGMENT_TABLE_MAX) { + log_error("Attempted to allocate more segments than we allow"); + return NULL; + } + + // Allocate memory for the current memory segment. + seg = seg_table[seg_index] = + malloc(sizeof(vm_segment) * size); + + // Ack! We couldn't get the memory we wanted. Let's bail. + if (seg == NULL) { + log_critical("Couldn't allocate enough space for vm_segment"); + return NULL; + } + + // We want to increment the current segment index only after a + // _successful_ allocation. + seg_index++; + + return seg; +} + +void +vm_segment_set(vm_segment *segment, size_t index, vm_segment_byte value) +{ + // Some bounds checking. + if (!vm_segment_bounds_check(segment, index)) { + log_critical( + "Attempt to set segment index (%d) greater than bounds (%d)", + index, + segment->size); + + // We prefer to exit in this scenario, rather than try to + // "handle" it with an overflow, because we would rather a crash + // over ill-defined behavior. + exit(1); + } + + segment->memory[index] = value; +} + +vm_segment_byte +vm_segment_get(vm_segment *segment, size_t index) +{ + if (!vm_segment_bounds_check(segment, index)) { + log_critical( + "Attempt to set segment index (%d) greater than bounds (%d)", + index, + segment->size); + + // See vm_segment_set() for a justification of this behavior. + exit(1); + } + + return segment->memory[index]; +} + +void +vm_segment_copy(vm_segment *src, + vm_segment *dest, + size_t src_index, + size_t dest_index, + size_t length) +{ + if (src_index + length >= src->size) { + log_critical( + "Attempt to copy beyond bounds of vm_segment (%d + %d >= %d)", + src_index, + length, + src->size); + + exit(1); + } + + if (dest_index + length >= dest->size) { + log_critical( + "Attempt to copy beyond bounds of vm_segment (%d + %d >= %d)", + dest_index, + length, + dest->size); + + exit(1); + } + + memcpy(dest->memory + dest_index, + src->memory + src_index, + length * sizeof(src->memory[src_index])); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..ebc6d5d --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.9) + +project(emp-test) + +include_directories(../include /usr/local/include) + +link_directories(/usr/local/lib) + +include(../sources.cmake) + +foreach(src ${emp_sources}) + string(CONCAT relsrc ../src/ ${src}) + list(APPEND sources ${relsrc}) +endforeach(src) + +add_executable(emp-test ${sources} ./main.c) + +target_link_libraries(emp-test criterion) diff --git a/tests/build/.gitkeep b/tests/build/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/main.c b/tests/main.c new file mode 100644 index 0000000..c73e51d --- /dev/null +++ b/tests/main.c @@ -0,0 +1,5 @@ +#include + +Test(simple, test) { + cr_assert(0, "Hello!"); +}