-
Notifications
You must be signed in to change notification settings - Fork 0
/
memory.c
94 lines (80 loc) · 3.04 KB
/
memory.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <stdlib.h>
#include <stdio.h>
#include "memory.h"
#include "cpu.h"
#include "logging.h"
static const byte stack_top = 0xFF; /*The address at the top of the stack*/
static const byte stack_bottom = 0x00; /*The address at the bottom of the stack*/
static const word fixed_high = 0x0100; /*Fixed high byte added to stack pointer for stack access*/
static const word intenal_stack_top = fixed_high + stack_top; /*The actual top memory address of the stack*/
static const word intenal_stack_bottom = fixed_high + stack_bottom; /*The actual bottom memory address of the stack*/
static int stack_rollback = 0; /*Flag for stack wrapping*/
struct memory* init_memory(void){
struct memory *mem = malloc(sizeof(*mem));
if (mem != NULL){
return mem;
}
else{
/*Handle error if needed*/
return NULL;
}
}
void free_memory(struct memory** mem){
free((*mem));
(*mem) = NULL;
}
/*
The following bound checking is quite redundant,
and will only fail if something changes the stack referencing
values, but it will be kept as is for the moment
*/
extern void stack_push(struct CPU* cpu, struct memory* mem, byte data, unsigned long long *cycles){
if ((fixed_high + cpu->SP) >= intenal_stack_bottom && (fixed_high + cpu->SP) <= intenal_stack_top){
CPU_dec_cycles(cycles, 1);
if (cpu->SP == stack_bottom) stack_rollback++;
mem->cell[fixed_high + cpu->SP] = data;
cpu->SP--;
}
else{
exit_and_save_status(cpu, OUFOFBOUNDSSTACK);
}
}
extern byte stack_pop(struct CPU* cpu, struct memory* mem, unsigned long long *cycles){
if ((fixed_high + cpu->SP) >= intenal_stack_bottom && (fixed_high + cpu->SP) <= intenal_stack_top){
CPU_dec_cycles(cycles, 1);
if(cpu->SP == stack_top && stack_rollback == 0){
printf("Stack is empty\n"); /*Left here for debugging purposes to be removed later*/
}
else{
cpu->SP++;
byte data = mem->cell[fixed_high + cpu->SP];
mem->cell[fixed_high + cpu->SP] = 0;
return data;
}
}
else{
exit_and_save_status(cpu, OUFOFBOUNDSSTACK);
}
}
extern void operate_addr(struct CPU *cpu, struct memory* mem, word addr, enum operations oper, unsigned long long *cycles){
if (addr >= 0 && addr < sizeof(mem->cell)){
CPU_dec_cycles(cycles, 1);
switch(oper){
case DEC:
mem->cell[addr]--;
break;
case INC:
mem->cell[addr]++;
break;
case LSH:
mem->cell[addr] <<= 1;
break;
case RSH:
mem->cell[addr] >>= 1;
break;
}
}
else{
exit_and_save_status(cpu, OUTOFBOUNDSMEM);
}
}