summaryrefslogtreecommitdiff
path: root/src/main.c
blob: bef94b1a9318097ed3fadd38a2440ea6b1ecbaac (plain)
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;
}