diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 31 | ||||
-rw-r--r-- | src/apple.c | 22 | ||||
-rw-r--r-- | src/apple.h | 4 | ||||
-rw-r--r-- | src/main.c | 136 | ||||
-rw-r--r-- | src/video/interface.h | 1 | ||||
-rw-r--r-- | src/video/mode.c | 29 | ||||
-rw-r--r-- | src/video/ncurses.c | 66 | ||||
-rw-r--r-- | src/video/sdl.c | 59 |
8 files changed, 244 insertions, 104 deletions
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(); @@ -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() +{ + + +} |