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
|
#include "apple.h"
#include "video/interface.h"
#include <unistd.h>
#include "cpu/6502.h"
#include "string.h"
#define HelpPrintout "\
Usage: apple-c [ options ]\n\
An Apple-I emulator written in C.\n\
\n\
Options:\n\
-m, --memory [NUM] Set RAM memory size to NUM pages; one page is 1024 bytes.\n\
Value must be between 4-64. 4 is the default.\n\
-t, --terminal Use ncurses (terminal) display mode. Default mode.\n\
-g, --graphical Use SDL (graphical) display mode.\n\
-i, --information Turn information overlay (default off).\n\
-l, --logging Toggle logging of computer state every cycle (default off).\n\
"
int main(int argc, char* argv[]) {
int print_info = 0;
int logging = 0;
int memory = 4;
//
// ARGUMENT PARSING
//
for (int i = 1; i < argc; i++) {
// Help
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
// Print help and terminate straight away.
printf(HelpPrintout);
exit(0);
}
// Memory
if (!strcmp(argv[i], "-m") || !strcmp(argv[i], "--memory")) {
// Increment i, and check bounds.
if (++i >= argc) {
printf("Memory argument not set.\n");
exit(1);
}
// If able, get next argument, and set memory to it.
else {
memory = strtol(argv[i], NULL, 10);
if ((4 > memory) || (memory > 64)) {
printf("Invalid value for setting memory.\n");
exit(1);
}
}
goto SkipIteration;
}
// Display
if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--terminal")) {
SetDisplayMode(0);
goto SkipIteration;
}
if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--graphical")) {
SetDisplayMode(1);
goto SkipIteration;
}
// Logging
if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--information")) {
logging = 1;
goto SkipIteration;
}
// Information Display
if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "--information")) {
print_info = 1;
goto SkipIteration;
}
printf("Unrecognized arguments.\n");
exit(1);
SkipIteration:
}
//
// EMULATION
//
AppleOn(memory);
DisplayInit();
FILE *Log;
if (logging) {
Log = fopen("log/log.raw", "w+");
}
int Time = 0;
while(1) {
// Computing
CallInstructionTable();
// Logging
if (logging) {
if (Time >= 0x2000)
// Stop logging after an arbitrary amount of time, so as to not create a huge file.
fclose(Log);
else {
fprintf(Log,
"%04x : %04x : %02x : %02x : %02x : %c%c_%c%c%c%c%c : %02x\n",
Time, PC, acc, X, Y,
GetFlag(flag_N) ? 'N':'.' ,
GetFlag(flag_V) ? 'V':'.' ,
GetFlag(flag_B) ? 'B':'.' ,
GetFlag(flag_D) ? 'D':'.' ,
GetFlag(flag_I) ? 'I':'.' ,
GetFlag(flag_Z) ? 'Z':'.' ,
GetFlag(flag_C) ? 'C':'.' ,
S);
fflush(Log);
Time++;
}
}
// Display information
if (print_info) {
PrintInfo();
}
}
DisplayClose();
return 0;
}
|