#include <SDL2/SDL_render.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <time.h> #include <string.h> #include <SDL2/SDL.h> #include "config.h" /* Preset Values */ static float displayScale = 2; static int cpuSpeed = 100000; // 100 kHz static int singleStep = 0; static int clockSteps = 1; #include "sdlinit.c" #include "events.c" #include "cpu.c" #include "memory.c" #include "video.c" #include "keyboard.c" //#include "via.c" uint8_t halt = 0; uint8_t showHelp = 0; uint8_t showDebug = 0; uint8_t fpsCount = 0; uint8_t displayMmap = 0; uint8_t documentReload = 0; uint8_t fpsStore = 60; uint8_t FPS = 30; uint8_t cpuHealth; unsigned long cpuTicks = 0; unsigned long tickTrigger = 0; char debugString[512]; char snapshotFile[32]; char *reloadExecute; char *inputFile; int openFile(){ FILE *file = fopen(inputFile, "rb"); int retCode = 0; if (file != NULL){ fseek(file, 0, SEEK_END); long filelen = ftell(file); rewind(file); if (fread(rom, filelen, 1, file) != 1) retCode = 1; } else retCode = 1; fclose(file); return retCode; } void resetSystem(){ initVideo(); updateVideo(); reset6502(); } void fetchArgs(int argc, char *argv[]){ printf(PREAMBLE); for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "--help")) printf(HELP); else if (!strcmp(argv[i], "--help-keys")) printf(HELPKEYS); else if (!strcmp(argv[i], "--cpuspeed")) cpuSpeed = atoi(argv[++i]); else if (!strcmp(argv[i], "--scale")) displayScale = atof(argv[++i]); else if (!strcmp(argv[i], "--singlestep")) singleStep = 1; else if (!strcmp(argv[i], "--clocksteps")) clockSteps = atoi(argv[++i]); //else if (!strcmp(argv[i], "--snapshot")) snapshotFile = &argv[i]; else if (!strcmp(argv[i], "--fps")) FPS = atoi(argv[++i]); else if (!strcmp(argv[i], "--enable-reload")) documentReload = 1; else if (!strcmp(argv[i], "--reload-execute")) reloadExecute = argv[++i]; else { inputFile = argv[i]; if (openFile()){ printf("%s: Unknown parameter or file '%s'\nTry '--help' for help\n", argv[0], argv[i]); exit(EXIT_FAILURE); } } } } int main(int argc, char *argv[]){ fetchArgs(argc, argv); initWindow(); clearScreen(renderMemory, 0x000000FF); resetSystem(); while (1){ SDL_Delay(1000.f / FPS); pollEvents(); fpsCount++; updateVideo(); if (!singleStep && !halt){ for (int i = 0; i < ((float)cpuSpeed / (float)fpsStore); i++) { step6502(); cpuTicks++; } irq6502(); } if ((unsigned)time(NULL) != tickTrigger){ tickTrigger = (unsigned)time(NULL); cpuHealth = (uint8_t)((cpuTicks / (float)cpuSpeed) * 100.); cpuTicks = 0; fpsStore = fpsCount; fpsCount = 0; /* Refresh entire video buffer */ videoModified = 1; } uint16_t vStack = 16; if (halt) { drawString("!CPU Haltet!", renderMemory, SDL_X_SIZE, 0x000000FF, time(NULL) % 2 ? 0xAAAAAAFF : 0xFFFFFFFF, 16, vStack, 2); vStack += (FONT_HEIGHT * 2 * 2); } if (showDebug){ sprintf(debugString, "LOADED BINARY: \"%s\"\nSCREENSIZE: %dx%d\nFPS: %d\nSCALE: %d", inputFile, SDL_X_SIZE, SDL_Y_SIZE, fpsStore, (int)displayScale); drawString(debugString, renderMemory, SDL_X_SIZE, 0x000000FF, 0xAAAAAAFF, 16, vStack, 2); vStack += (FONT_HEIGHT * 4 * 2); sprintf(debugString, "CPU: %d%%", cpuHealth); drawString(debugString, renderMemory, SDL_X_SIZE, 0x000000FF, time(NULL) % 2 ? 0xAAAAAAFF : cpuHealth < 10 ? 0xFF0000FF : cpuHealth < 50 ? 0xFFFF00FF : 0xAAAAAAFF, 16, vStack, 2); vStack += (FONT_HEIGHT * 2 * 2); } if (displayMmap){ sprintf(debugString, "RAM: $%04X - $%04X\nROM: $%04X - $%04X\nVIAADDRS: $%04X\nKBDADDRS: $%04X\nVIDADDRS: $%04X", RAMLOC, RAMLOC + RAMSIZE, ROMLOC, ROMLOC + ROMSIZE, VIAADDRS, KBDADDRS, VIDADDRS); drawString(debugString, renderMemory, SDL_X_SIZE, 0x000000FF, 0xAAAAAAFF, 16, vStack, 2); vStack += (FONT_HEIGHT * 6 * 2); } if (showHelp) { drawString(HELPKEYS, renderMemory, SDL_X_SIZE, 0x000000FF, 0xAAAAAAFF, 16, vStack, 2); vStack += (FONT_HEIGHT * 2 * 2); } if (SDL_UpdateTexture(texture, NULL, renderMemory, (sizeof(uint32_t) * SDL_X_SIZE))) { fprintf(stderr, "Could not update SDL texture: %s.\n", SDL_GetError()); exit(EXIT_FAILURE); } if (SDL_RenderCopy(renderer, texture, NULL, NULL)) { fprintf(stderr, "Could not display SDL texture: %s.\n", SDL_GetError()); exit(EXIT_FAILURE); } SDL_RenderPresent(renderer); } return EXIT_SUCCESS; }