-
-
Save Arnot/791dded64711c081c34edf415fdec3a1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#define STACK_MIN_SIZE 32 | |
union Datum { | |
uint8_t lo, hi; | |
uint16_t uint; | |
}; | |
typedef union Datum datum; | |
/******************** | |
* Memory areas | |
********************/ | |
// 15-bit addressed main memory | |
datum main_mem[32768]; | |
// Registers | |
datum reg[8]; | |
// Stack | |
struct Stack { | |
int* data; | |
int size; | |
int max_size; | |
} stack; | |
uint16_t read_block(FILE* p) | |
{ | |
char lo, hi; | |
lo = fgetc(p); | |
hi = fgetc(p); | |
return (hi << 8) | lo; | |
} | |
int stack_init() | |
{ | |
stack.size = 0; | |
stack.data = malloc(STACK_MIN_SIZE*sizeof(*stack.data)); | |
if (stack.data != NULL) { | |
stack.max_size = STACK_MIN_SIZE; | |
return 0; | |
} else { | |
stack.max_size = 0; | |
return 1; | |
} | |
} | |
void stack_destroy() | |
{ | |
free(stack.data); | |
stack.max_size = 0; | |
stack.size = 0; | |
} | |
int stack_push(int value) | |
{ | |
int* new_data; | |
// resize stack if size exceeds max_size | |
if (stack.size == stack.max_size) { | |
printf("Growing stack..\n"); | |
new_data = realloc(stack.data, stack.max_size*2 * sizeof(*stack.data)); | |
if (new_data == NULL) { | |
printf("Failed to grow stack.\n"); | |
return 1; | |
} | |
stack.data = new_data; | |
stack.max_size = stack.max_size*2; | |
} | |
stack.data[stack.size] = value; | |
stack.size++; | |
return 0; | |
} | |
int stack_pop() | |
{ | |
int *new_data; | |
int ret = 0; | |
if (stack.size > 0) { | |
ret = stack.data[stack.size - 1]; | |
stack.size--; | |
} | |
if (stack.size < stack.max_size/2 && stack.size >= STACK_MIN_SIZE) { | |
printf("Shrinking stack..\n"); | |
new_data = realloc(stack.data, stack.max_size/2 * sizeof(*stack.data)); | |
if (new_data == NULL) { | |
printf("Failed to shrink stack.\n"); | |
return ret; // TODO: Error handling? ret is still valid.. | |
} | |
stack.data = new_data; | |
stack.max_size = stack.max_size/2; | |
} | |
return ret; | |
} | |
void stack_print() | |
{ | |
int i; | |
for (i = 0; i < stack.size; i++) | |
printf("%d ", stack.data[i]); | |
printf("\n"); | |
} | |
int main(int argc, char* argv[]) | |
{ | |
int i; | |
unsigned long cycle_count; | |
FILE* program; | |
int halted = 0; | |
uint16_t opcode; | |
char a, b; | |
char lo, hi; | |
cycle_count = 0; | |
if (stack_init() != 0) { | |
printf("Failed to initialize stack.\n"); | |
return 1; | |
} | |
if (argc < 2) { | |
printf("Too little command line arguments\n"); | |
return 1; | |
} | |
program = fopen(argv[1], "rb"); | |
if (program == NULL) { | |
printf("Couldn't open challenge.bin for reading\n"); | |
exit(1); | |
} | |
while (!halted) { | |
cycle_count++; | |
opcode = read_block(program); | |
switch (opcode) { | |
// halt | |
case 0: //printf("\nhalt\n"); | |
halted = 1; | |
break; | |
//out | |
case 19: //printf("\nout\n"); | |
a = read_block(program); | |
printf("%c", a); | |
break; | |
// noop | |
case 21: //printf("\nnoop\n"); | |
break; | |
default: printf("\nUnidentified opcode or EOF, halting\n"); | |
halted = 1; | |
break; | |
} | |
} | |
printf("Cycle count = %lu\n", cycle_count); | |
fclose(program); | |
stack_destroy(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment