/
mix.c
217 lines (172 loc) · 4.36 KB
/
mix.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
* mix.c
* Implements a MIX machine as described in "mix.h"
* Main program takes a MIX program to run from the command line.
* The MIX machine is initialized, and the program is ran (if possible).
*/
#include "mix.h"
#include "mix_opcodes.h"
#include <malloc.h>
#include <stdio.h>
/* MIX constant values. */
// Sign bit possible values.
const mix_byte PLUS = 0;
const mix_byte MINUS = 1;
// Comparison possible values.
const mix_byte LESS = 0;
const mix_byte EQUAL = 1;
const mix_byte GREATER = 2;
// Overflow indicator possible values.
const mix_byte NO_OVERFLOW = 0;
const mix_byte OVERFLOW = 1;
// Memory size, in words.
const int MEM_SIZE = 4000;
/* Backend MIX function declarations. */
// Initialize machine state on startup.
void startup_init(mix_pt);
// Initialize machine registers.
void reg_init(mix_pt);
// Create and initialize memory.
void mem_init(mix_pt);
// Release memory.
void shutdown(mix_pt);
// Clear a machine word.
void clear_word(word_pt);
// Clear machine index registers.
void clear_index_regs(mix_pt);
// Clear a machine half-word.
void clear_half_word(half_word_pt);
// Run MIX program.
int run(mix_pt, char*);
/* MIX backend function definitions. */
/*
* Startup initialization of a MIX machine.
* Sets condition and overflow bits, clears registers,
* and creates and initializes memory.
* param machine - MIX machine to initialize.
*/
void startup_init(mix_pt machine)
{
printf("Starting MIX machine...\n");
// Set the status bits for the comparison bit and overflow bit to:
// EQUAL and NO_OVERFLOW, repectively.
machine->condition = EQUAL;
machine->overflow = NO_OVERFLOW;
// Initialize registers to +0.
reg_init(machine);
// Create and initialize memory.
mem_init(machine);
}
/*
* Register initialization of a MIX machine.
* Clears all registers to +0.
* param machine - MIX machine whos registers are to be initialized.
*/
void reg_init(mix_pt machine)
{
printf("--Initializing registers...\n");
// Clear the A and X word registers.
clear_word(&machine->A);
clear_word(&machine->X);
// Clear the index registers.
clear_index_regs(machine);
// Clear the jump register.
clear_half_word(&machine->J);
}
/*
* Clear a MIX machine word to +0.
* param w - Word to clear.
*/
void clear_word(word_pt w)
{
w->sign = PLUS;
int i;
for(i = 1; i < NUM_WORD_BYTES; ++i)
{
w->byte[i] = 0;
}
}
/*
* Clear the index registers of a MIX machine.
* param machine - MIX machine whos index registers are to be cleared.
*/
void clear_index_regs(mix_pt machine)
{
clear_half_word(&machine->I1);
clear_half_word(&machine->I2);
clear_half_word(&machine->I3);
clear_half_word(&machine->I4);
clear_half_word(&machine->I5);
clear_half_word(&machine->I6);
}
/*
* Clear a MIX machine half-word to +0.
* param hw - Half word clear.
*/
void clear_half_word(half_word_pt hw)
{
hw->sign = PLUS;
int i;
for(i = 0; i < NUM_HALF_WORD_BYTES; ++i)
{
hw->byte[i] = 0;
}
}
/*
* Initialize MIX memory.
* param machine - MIX machine whos memory is to be initialized.
*/
void mem_init(mix_pt machine)
{
printf("--Initializing memory...\n");
// Allocate MIX memory.
machine->mem = (word_pt) calloc(MEM_SIZE, sizeof(word));
}
/*
* Release MIX memory.
* param machine - MIX machine to be shutdown.
*/
void shutdown(mix_pt machine)
{
printf("Shutting down MIX machine...\n");
// Free MIX memory.
free(machine->mem);
}
/*
* Run the given program on the MIX machine given.
* param machine - MIX machine.
* param program - MIX program.
*/
int run(mix_pt machine, char* file)
{
FILE* program;
if(!(program = fopen(file, "r")))
{
printf("Unable to open file: %s\n", file);
return -1;
}
printf("Running program %s...\n", file);
fclose(program);
return 0;
}
/*
* Main entry point into the program.
* Runs a MIX program file given in the command line arguments.
* param argc - Number of command line arguments.
* param argv - Command line arguments.
* Argument 0: This program's name (probably mix.exe).
* Argument 1: MIX program to run.
*/
int main(int argc, char** argv)
{
if(argc < 2)
{
printf("Usage: expected a MIX machine program file name");
return -1;
}
mix machine;
startup_init(&machine);
int result = run(&machine, argv[1]);
shutdown(&machine);
return result;
}