summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/Makefile31
-rw-r--r--src/apple.c22
-rw-r--r--src/apple.h4
-rw-r--r--src/main.c136
-rw-r--r--src/video/interface.h1
-rw-r--r--src/video/mode.c29
-rw-r--r--src/video/ncurses.c66
-rw-r--r--src/video/sdl.c59
9 files changed, 245 insertions, 104 deletions
diff --git a/.gitignore b/.gitignore
index cd54e16..ac7a094 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
apple-c*
+*~
diff --git a/src/Makefile b/src/Makefile
index c7bf2a8..1502ab7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,27 +1,21 @@
-SDL = -L/usr/lib -lSDL2
-
-OBJECTS_CPU = cpu/6502.o cpu/addressing.o cpu/instructions.o cpu/table.o
-
-BUILD_STATIC_LIBRARY = ar -rcs $@ $^
-
+# Executable Targets
+default: apple-c
-# Executable Targets
+apple-c: computer.a video.a
+ gcc -o ../$@ -lncurses -lSDL main.c $^
-default: computer.a video.a
- gcc -o ../apple-c -lncurses main.c $^
-test: computer.a video.a
- gcc -o ../test.out -lncurses test.c $^
+# Internal Static Libraries
+computer.a: cpu/6502.o cpu/addressing.o cpu/instructions.o cpu/table.o apple.o
+ ar -rcs $@ $^
-# Internal Libraries
+video.a: video/mode.o video/ncurses.o video/sdl.o
+ ar -rcs $@ $^
-computer.a: $(OBJECTS_CPU) apple.o
- $(BUILD_STATIC_LIBRARY)
-video.a: video/ncurses.o
- $(BUILD_STATIC_LIBRARY)
+# Object Files
*.o: *.c
gcc -c $^
@@ -30,7 +24,4 @@ video.a: video/ncurses.o
# Clean
clean:
- rm *.a
- rm *.o
- rm cpu/*.o
- rm video/*.o
+ rm *.a *.o cpu/*.o video/*.o ../apple-c*
diff --git a/src/apple.c b/src/apple.c
index e69cbf8..c8fbb61 100644
--- a/src/apple.c
+++ b/src/apple.c
@@ -1,5 +1,7 @@
#include"apple.h"
+int MemorySize;
+
// The Incredible Wozmon!
const byte ROM[256] = {
0xd8, 0x58, 0xa0, 0x7f, 0x8c, 0x12, 0xd0, 0xa9,
@@ -36,16 +38,20 @@ const byte ROM[256] = {
0x00, 0x00, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00
};
-void AppleOn() {
- Memory = calloc(MEMORY_SIZE, sizeof(byte));
+void AppleOn(const int memory) {
+ MemorySize = memory * 0x0100;
+ Memory = calloc(MemorySize, sizeof(byte));
InitInstructionTable();
- PC = 0xFF00;
+ AppleReset();
}
void AppleReset(){
- acc = 0; X = 0; Y = 0; P = 0; S = 0;
- state.cycles = 0; state.length = 0; state.address = 0; state.value = 0;
- PC = 0xFF00;
+ acc = 0;
+ X = 0;
+ Y = 0;
+ P = 0x20; // An unused bit exists which is always 'set'.
+ S = 0;
+ PC = 0xFF00;
//free(Memory);
//Memory = calloc(MEMORY_SIZE, sizeof(byte));
}
@@ -70,7 +76,7 @@ byte GetMemory(address x){
return ROM[0x00FF & x];
}
- if (x < MEMORY_SIZE)
+ if (x < MemorySize)
return Memory[x];
return -1;
@@ -83,7 +89,7 @@ void SetMemory(address x, byte y){
if (y & 0x80)
DisplayInput(y);
}
- if (x < MEMORY_SIZE) {
+ if (x < MemorySize) {
Memory[x] = y;
}
}
diff --git a/src/apple.h b/src/apple.h
index f7829e5..57c8fe6 100644
--- a/src/apple.h
+++ b/src/apple.h
@@ -4,8 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
-#define MEMORY_SIZE 0x0400
-
#define KBD 0xD010
#define KBD_CR 0xD011
#define DSP 0xD012
@@ -15,6 +13,6 @@
#define CR 0x8D
#define ESC 0x9B
-void AppleOn();
+void AppleOn(int memory);
void AppleReset();
byte UserInput();
diff --git a/src/main.c b/src/main.c
index f1dfada..bef94b1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,15 +2,105 @@
#include "video/interface.h"
#include <unistd.h>
#include "cpu/6502.h"
+#include "string.h"
-int main() {
+#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\
+"
- AppleOn();
+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 = fopen("log/log.raw", "w+");
+ FILE *Log;
+ if (logging) {
+ Log = fopen("log/log.raw", "w+");
+ }
+
int Time = 0;
while(1) {
@@ -18,27 +108,31 @@ int main() {
CallInstructionTable();
// 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++;
+ 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
- PrintInfo();
+ if (print_info) {
+ PrintInfo();
+ }
}
DisplayClose();
diff --git a/src/video/interface.h b/src/video/interface.h
index 16cc965..4597145 100644
--- a/src/video/interface.h
+++ b/src/video/interface.h
@@ -16,6 +16,5 @@ void DisplayClose();
// Display a character on the screen.
void DisplayInput(byte n);
-
// Print information on the video system.
void PrintInfo();
diff --git a/src/video/mode.c b/src/video/mode.c
new file mode 100644
index 0000000..81a314a
--- /dev/null
+++ b/src/video/mode.c
@@ -0,0 +1,29 @@
+#include "interface.h"
+
+int VideoMode;
+
+void SetDisplayMode(int x)
+{
+ if ((x == 0) || (x == 1)) {
+ VideoMode = x;
+ }
+ else {
+ printf("Failed to set video mode.");
+ }
+}
+
+void DisplayInit() {
+ VideoMode ? DisplayInit_SDL() : DisplayInit_Ncurses();
+}
+
+void DisplayClose() {
+ VideoMode ? DisplayClose_SDL() : DisplayClose_Ncurses();
+}
+
+void DisplayInput(byte n) {
+ VideoMode ? DisplayInput_SDL(n) : DisplayInput_Ncurses(n);
+}
+
+void PrintInfo() {
+ VideoMode ? PrintInfo_SDL() : PrintInfo_Ncurses();
+}
diff --git a/src/video/ncurses.c b/src/video/ncurses.c
index 3b22231..aafde9e 100644
--- a/src/video/ncurses.c
+++ b/src/video/ncurses.c
@@ -3,7 +3,6 @@
// Provides an in-terminal interface to the emulator.
#include<ncurses.h>
-#include"interface.h"
#include"../apple.h"
#include"../cpu/6502.h"
@@ -18,37 +17,8 @@ int vPosition = 0;
int vOffset = 0;
-void PrintInfo()
-{
- mvprintw(2, 43, " acc : %02x", acc);
- mvprintw(3, 43, " X : %02x", X );
- mvprintw(4, 43, " Y : %02x", Y );
- mvprintw(5, 43, " PC : %04x", PC);
- mvprintw(6, 43, " S : %02x", S );
- mvprintw(7, 43, "Flags : %c%c_%c%c%c%c%c",
- 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':'.'
- );
- mvprintw(2, 65, "Stack");
- int count = 3;
- for (int i = 0x1ff; i > 0x1e8; i--) {
- if (i == (0x1ff-S)) // Indicate the stack pointer!
- attron(A_REVERSE);
- mvprintw(count, 65, "%x : %x", i, GetMemory(i));
- attroff(A_REVERSE);
- count++;
- }
- refresh();
-}
-
-
-void DisplayInit()
+void DisplayInit_Ncurses()
{
// ncurses initialization functions.
initscr();
@@ -85,7 +55,7 @@ void DisplayInit()
-void DisplayClose()
+void DisplayClose_Ncurses()
{
free(VRAM);
curs_set(1);
@@ -94,7 +64,7 @@ void DisplayClose()
-void DisplayInput(byte n)
+void DisplayInput_Ncurses(byte n)
{
if (n == BS) {
return;
@@ -160,3 +130,33 @@ void DisplayInput(byte n)
mvwaddch(AppleWindow, TermY, TermX, '@' | A_BLINK);
wrefresh(AppleWindow);
}
+
+
+
+void PrintInfo_Ncurses()
+{
+ mvprintw(2, 43, " acc : %02x", acc);
+ mvprintw(3, 43, " X : %02x", X );
+ mvprintw(4, 43, " Y : %02x", Y );
+ mvprintw(5, 43, " PC : %04x", PC);
+ mvprintw(6, 43, " S : %02x", S );
+ mvprintw(7, 43, "Flags : %c%c_%c%c%c%c%c",
+ 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':'.'
+ );
+ mvprintw(2, 65, "Stack");
+ int count = 3;
+ for (int i = 0x1ff; i > 0x1e8; i--) {
+ if (i == (0x1ff-S)) // Indicate the stack pointer!
+ attron(A_REVERSE);
+ mvprintw(count, 65, "%x : %x", i, GetMemory(i));
+ attroff(A_REVERSE);
+ count++;
+ }
+ refresh();
+}
diff --git a/src/video/sdl.c b/src/video/sdl.c
index 7161a08..a0cb0af 100644
--- a/src/video/sdl.c
+++ b/src/video/sdl.c
@@ -2,8 +2,7 @@
// Implements interface.h
// Emulates the graphics of the Apple I computer with SDL.
-#include"interface.h"
-#include<SDL2/SDL.h>
+#include<SDL/SDL.h>
#define SCALE 2
@@ -15,24 +14,39 @@
#define MIN_WIDTH (40 * CHR_WIDTH) + 39*WIDTH_SPACE
#define MIN_HEIGHT (24 * CHR_HEIGHT)
-int TerminalInit(){
+
+
+SDL_Surface* MainWindow;
+SDL_Surface* Font;
+
+void PrintInfo_SDL()
+{
+
+
+}
+
+
+int DisplayInit_SDL()
+{
// INITIALIZATION
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
- SDL_Window* window = SDL_CreateWindow(
- "Apple C",
+ MainWindow = SDL_SetVideoMode(MIN_WIDTH*SCALE, MIN_HEIGHT*SCALE, 8, NULL);
+
+
+ /*= SDL_CreateWindow(
+ "apple-c",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
MIN_WIDTH * SCALE,
MIN_HEIGHT * SCALE,
SDL_WINDOW_SHOWN
- );
-
- SDL_Renderer* render = SDL_CreateRenderer(window, -1, 0);
- SDL_Surface* font_surface = SDL_LoadBMP("font.bmp");
- SDL_Texture* font_texture = SDL_CreateTextureFromSurface(render, font_surface);
- SDL_FreeSurface(font_surface);
+ );*/
+ Font = SDL_LoadBMP("font.bmp");
+
+ SDL_Surface* font_surface = SDL_LoadBMP("font.bmp");
+
SDL_Rect character = {
.x = 0,
.y = 0,
@@ -47,13 +61,22 @@ int TerminalInit(){
.h = CHR_HEIGHT * SCALE
};
- SDL_SetRenderDrawColor (render, 0, 0, 0, 255);
- SDL_RenderClear (render);
- SDL_RenderCopy (render, font_texture, &character, &draw_character);
- SDL_RenderPresent (render);
+ //SDL_SetRenderDrawColor (render, 0, 0, 0, 255);
+ //SDL_RenderClear (render);
+ //SDL_RenderCopy (render, font_texture, &character, &draw_character);
+ //SDL_RenderPresent (render);
+
+}
+void DisplayClose_SDL()
+{
+ SDL_FreeSurface(MainWindow);
+ SDL_FreeSurface(Font);
}
-void TerminalClose() {
- SDL_Quit();
-} \ No newline at end of file
+
+void DisplayInput_SDL()
+{
+
+
+}