1
0
mirror of https://github.com/pevans/erc-c.git synced 2024-12-13 15:33:17 +00:00

First commit

This commit is contained in:
Peter Evans 2017-11-21 23:24:51 -06:00
commit 237d5e3cb6
14 changed files with 306 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.swp
build

19
CMakeLists.txt Normal file
View File

@ -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)

0
build/.gitkeep Normal file
View File

11
include/log.h Normal file
View File

@ -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

18
include/vm_screen.h Normal file
View File

@ -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

21
include/vm_segment.h Normal file
View File

@ -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

5
sources.cmake Normal file
View File

@ -0,0 +1,5 @@
set(emp_sources
log.c
vm_screen.c
vm_segment.c
)

34
src/log.c Normal file
View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
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);
}

27
src/main.c Normal file
View File

@ -0,0 +1,27 @@
#include <stdio.h>
#include <stdlib.h>
#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");
}

42
src/vm_screen.c Normal file
View File

@ -0,0 +1,42 @@
#include <stdlib.h>
#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
}

104
src/vm_segment.c Normal file
View File

@ -0,0 +1,104 @@
#include <stdlib.h>
#include <string.h>
#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]));
}

18
tests/CMakeLists.txt Normal file
View File

@ -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)

0
tests/build/.gitkeep Normal file
View File

5
tests/main.c Normal file
View File

@ -0,0 +1,5 @@
#include <criterion/criterion.h>
Test(simple, test) {
cr_assert(0, "Hello!");
}