Compare commits

..

7 Commits

Author SHA1 Message Date
0xmac
45b8993cdd Tweaked Input args and other stuff 2025-01-30 09:18:43 +01:00
0xmac
5cc21f3a6f Added 65c02 Instructions NEEDS TESTING! 2025-01-30 09:18:26 +01:00
0xmac
caba72b134 Updated events to support dynamic window resize 2025-01-30 09:18:08 +01:00
0xmac
3a7dc09389 Updated Help and Preamble message 2025-01-30 09:17:50 +01:00
0xmac
c824ad0989 Added window resize function 2025-01-30 09:17:09 +01:00
0xmac
de0686edb7 Updated to support propper video scaling 2025-01-30 09:16:50 +01:00
0xmac
8581e53373 Made Makefile more modular 2025-01-30 09:15:29 +01:00
7 changed files with 259 additions and 99 deletions

View File

@ -1,9 +1,10 @@
.ONESHELL:
CC=gcc
O=2
CFLAGS=`sdl2-config --cflags` `sdl2-config --libs`
PREFIX=$(HOME)/.local
CC = gcc
O = 3
CFLAGS = `sdl2-config --cflags` `sdl2-config --libs`
PREFIX = $(HOME)/.local
SRC = main.c
all: ls7emulator
@ -13,7 +14,7 @@ clean:
ls7emulator:
cd src
$(CC) main.c -o ls7emulator $(CFLAGS) -O$(O)
$(CC) $(SRC) -o ls7emulator $(CFLAGS) -O$(O)
rm ../bin -rf
mkdir ../bin
cd ../bin
@ -24,3 +25,6 @@ install: ls7emulator
mkdir -p $(PREFIX)/bin
install bin/ls7emulator $(PREFIX)/bin/ls7emulator
cp bin/ls7emulator /usr/bin/ls7emulator

View File

@ -10,24 +10,28 @@
#define ROMLOC 0xC000 /* ROM Page Location */
#define BACKCOLOR sfBlack
#define SCREEN_WIDTH 768
#define SCREEN_HEIGHT 512
#define SDL_X_SIZE 768
#define SDL_Y_SIZE 512
#define SDL_X_SIZE 384
#define SDL_Y_SIZE 256
#define PREAMBLE "LS7 Emulator by Gabriel Weingardt.\nLicense: GPL v.3+\n\n"
#define PREAMBLE "LS7 Emulator by Gabriel Weingardt.\n\
License: GPL v.3+\n\
See: https://git.weingardt.dev/0xmac/LS7-Emulator\n\n"
#define HELP "Usage: LS7Emulator [options] ... [file]\n\n\
Options: Type Default Desc\n\
--help Show this menu\n\
--help-keys Show emulator key functions\n\
--cpuspeed [int] 100000 CPU Speed given in Herz. KHz and MHz annotations like 1KHz are supported\n\
--scale [float] 2.0 Set the starting scale of the video output\n\
--resizeable Make the window resizable\n\
--singlestep Enable singlestepping with the 'F8' key\n\
--reload-program Reload the binary file when CPU is reset\n\
--randomize Randomize Computer and video RAM on reset\n\
\n\
--cpuspeed [int] 1MHz CPU Speed given in Herz. KHz and MHz formats like 1KHz are supported\n\
--scale [float] 1 Set the starting scale of the video output\n\
--clocksteps [int] 1 Set the clock cycles cycled by a singlestep\n\
--snapshot [string] Import a CPU snapshot\n\
--fps [float] 30 Set the SDL FPS rate\n\
--enable-reload Reload the binary file when CPU is reset\n\
--script [string] Execute a script when CPU is being reset (helpful for development)\n\
\n"
#define HELPKEYS "\

203
src/cpu.c
View File

@ -1,7 +1,7 @@
/* Fake6502 CPU emulator core v1.1 *******************
* (c)2011-2013 Mike Chambers *
* *
* Modified by Gabriel Weingardt *
* Modified for 65c02 by Gabriel Weingardt *
*****************************************************/
#include <stdint.h>
@ -130,6 +130,10 @@ static void zp() { //zero-page
ea = (uint16_t)read6502((uint16_t)pc++);
}
static void izp() { // zero-page indirect (new 65c02 instruction)
}
static void zpx() { //zero-page,X
ea = ((uint16_t)read6502((uint16_t)pc++) + (uint16_t)x) & 0xFF; //zero-page wraparound
}
@ -201,6 +205,16 @@ static void indy() { // (indirect),Y
}
}
// new 65c02 address mode
static void aii() { // absolute indexed indirect
uint16_t eahelp, eahelp2;
eahelp = ((uint16_t)read6502(pc) | ((uint16_t)read6502(pc+1) << 8)) + x;
eahelp2 = (eahelp & 0xFF00) | ((eahelp + 1) & 0x00FF); //replicate 6502 page-boundary wraparound bug
ea = (uint16_t)read6502(eahelp) | ((uint16_t)read6502(eahelp2) << 8);
pc += 2;
}
static uint16_t getvalue() {
if (addrtable[opcode] == acc) return((uint16_t)a);
else return((uint16_t)read6502(ea));
@ -336,6 +350,37 @@ static void bvs() {
}
}
static void bra() { // new 65c02 instruction
oldpc = pc;
pc += reladdr;
if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
else clockticks6502++;
}
static void bbr() { // new 65c02 instruction
uint8_t testval = 1;
for (int i = 0; i < ((opcode & 0b01110000) >> 4); i++) testval = testval << 1;
if (!(a & testval)) {
oldpc = pc;
pc += reladdr;
if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
else clockticks6502++;
}
}
static void bbs() { // new 65c02 instruction
uint8_t testval = 1;
for (int i = 0; i < ((opcode & 0b01110000) >> 4); i++) testval = testval << 1;
if (a & testval) {
oldpc = pc;
pc += reladdr;
if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
else clockticks6502++;
}
}
static void clc() {
clearcarry();
}
@ -522,9 +567,18 @@ static void pha() {
}
static void php() {
push8(status | FLAG_BREAK);
push8(status);
}
static void phy() { // new 65c02 instruction
push8(y);
}
static void phx() { // new 65c02 instruction
push8(x);
}
static void pla() {
a = pull8();
@ -536,6 +590,21 @@ static void plp() {
status = pull8() | FLAG_CONSTANT;
}
static void ply() { // new 65c02 instruction
y = pull8();
zerocalc(y);
signcalc(y);
}
static void plx() { // new 65c02 instruction
a = pull8();
zerocalc(x);
signcalc(x);
}
static void rol() {
value = getvalue();
result = (value << 1) | (status & FLAG_CARRY);
@ -608,6 +677,10 @@ static void sty() {
putvalue(y);
}
static void stz() { // new 65c02 instruction
putvalue(0);
}
static void tax() {
x = a;
@ -647,44 +720,88 @@ static void tya() {
signcalc(a);
}
static void (*addrtable[256])() = {
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
/* 0 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, abso, /* 0 */
/* 1 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 1 */
/* 2 */ abso, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, abso, /* 2 */
/* 3 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 3 */
/* 4 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, abso, /* 4 */
/* 5 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 5 */
/* 6 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, ind, abso, abso, abso, /* 6 */
/* 7 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 7 */
/* 8 */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, abso, /* 8 */
/* 9 */ rel, indy, imp, indy, zpx, zpx, zpy, zpy, imp, absy, imp, absy, absx, absx, absy, absy, /* 9 */
/* A */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, abso, /* A */
/* B */ rel, indy, imp, indy, zpx, zpx, zpy, zpy, imp, absy, imp, absy, absx, absx, absy, absy, /* B */
/* C */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, abso, /* C */
/* D */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* D */
/* E */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, abso, /* E */
/* F */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx /* F */
};
static void trb() { // new 65c02 instruction
value = getvalue();
result = value & ~a;
zerocalc(result);
putvalue(result);
}
static void tsb() { // new 65c02 instruction
value = getvalue();
result = value | a;
zerocalc(result);
putvalue(result);
}
static void rmb() { // new 65c02 instruction
uint8_t testval = 1;
for (int i = 0; i < ((opcode & 0b01110000) >> 4); i++) testval = testval << 1;
value = getvalue();
result = value & ~testval;
putvalue(result);
}
static void smb() { // new 65c02 instruction
uint8_t testval = 1;
for (int i = 0; i < ((opcode & 0b01110000) >> 4); i++) testval = testval << 1;
value = getvalue();
result = value | testval;
putvalue(result);
}
static void wai() { // new 65c02 instruction
// implement later
}
static void stp() { // new 65c02 instruction
// implement later
}
static void (*optable[256])() = {
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
/* 0 */ brk, ora, nop, nop, nop, ora, asl, nop, php, ora, asl, nop, nop, ora, asl, nop, /* 0 */
/* 1 */ bpl, ora, nop, nop, nop, ora, asl, nop, clc, ora, nop, nop, nop, ora, asl, nop, /* 1 */
/* 2 */ jsr, and, nop, nop, bit, and, rol, nop, plp, and, rol, nop, bit, and, rol, nop, /* 2 */
/* 3 */ bmi, and, nop, nop, nop, and, rol, nop, sec, and, nop, nop, nop, and, rol, nop, /* 3 */
/* 4 */ rti, eor, nop, nop, nop, eor, lsr, nop, pha, eor, lsr, nop, jmp, eor, lsr, nop, /* 4 */
/* 5 */ bvc, eor, nop, nop, nop, eor, lsr, nop, cli, eor, nop, nop, nop, eor, lsr, nop, /* 5 */
/* 6 */ rts, adc, nop, nop, nop, adc, ror, nop, pla, adc, ror, nop, jmp, adc, ror, nop, /* 6 */
/* 7 */ bvs, adc, nop, nop, nop, adc, ror, nop, sei, adc, nop, nop, nop, adc, ror, nop, /* 7 */
/* 8 */ nop, sta, nop, nop, sty, sta, stx, nop, dey, nop, txa, nop, sty, sta, stx, nop, /* 8 */
/* 9 */ bcc, sta, nop, nop, sty, sta, stx, nop, tya, sta, txs, nop, nop, sta, nop, nop, /* 9 */
/* A */ ldy, lda, ldx, nop, ldy, lda, ldx, nop, tay, lda, tax, nop, ldy, lda, ldx, nop, /* A */
/* B */ bcs, lda, nop, nop, ldy, lda, ldx, nop, clv, lda, tsx, nop, ldy, lda, ldx, nop, /* B */
/* C */ cpy, cmp, nop, nop, cpy, cmp, dec, nop, iny, cmp, dex, nop, cpy, cmp, dec, nop, /* C */
/* D */ bne, cmp, nop, nop, nop, cmp, dec, nop, cld, cmp, nop, nop, nop, cmp, dec, nop, /* D */
/* E */ cpx, sbc, nop, nop, cpx, sbc, inc, nop, inx, sbc, nop, sbc, cpx, sbc, inc, nop, /* E */
/* F */ beq, sbc, nop, nop, nop, sbc, inc, nop, sed, sbc, nop, nop, nop, sbc, inc, nop /* F */
/* 0 */ brk, ora, nop, nop, tsb, ora, asl, rmb, php, ora, asl, nop, tsb, ora, asl, bbr, /* 0 */
/* 1 */ bpl, ora, ora, nop, trb, ora, asl, rmb, clc, ora, inc, nop, trb, ora, asl, bbr, /* 1 */
/* 2 */ jsr, and, nop, nop, bit, and, rol, rmb, plp, and, rol, nop, bit, and, rol, bbr, /* 2 */
/* 3 */ bmi, and, and, nop, bit, and, rol, rmb, sec, and, dec, nop, bit, and, rol, bbr, /* 3 */
/* 4 */ rti, eor, nop, nop, nop, eor, lsr, rmb, pha, eor, lsr, nop, jmp, eor, lsr, bbr, /* 4 */
/* 5 */ bvc, eor, eor, nop, nop, eor, lsr, rmb, cli, eor, phy, nop, nop, eor, lsr, bbr, /* 5 */
/* 6 */ rts, adc, nop, nop, stz, adc, ror, rmb, pla, adc, ror, nop, jmp, adc, ror, bbr, /* 6 */
/* 7 */ bvs, adc, adc, nop, stz, adc, ror, rmb, sei, adc, ply, nop, jmp, adc, ror, bbr, /* 7 */
/* 8 */ bra, sta, nop, nop, sty, sta, stx, smb, dey, bit, txa, nop, sty, sta, stx, bbs, /* 8 */
/* 9 */ bcc, sta, sta, nop, sty, sta, stx, smb, tya, sta, txs, nop, stz, sta, stz, bbs, /* 9 */
/* A */ ldy, lda, ldx, nop, ldy, lda, ldx, smb, tay, lda, tax, nop, ldy, lda, ldx, bbs, /* A */
/* B */ bcs, lda, lda, nop, ldy, lda, ldx, smb, clv, lda, tsx, nop, ldy, lda, ldx, bbs, /* B */
/* C */ cpy, cmp, nop, nop, cpy, cmp, dec, smb, iny, cmp, dex, wai, cpy, cmp, dec, bbs, /* C */
/* D */ bne, cmp, cmp, nop, nop, cmp, dec, smb, cld, cmp, phx, stp, nop, cmp, dec, bbs, /* D */
/* E */ cpx, sbc, nop, nop, cpx, sbc, inc, smb, inx, sbc, nop, sbc, cpx, sbc, inc, bbs, /* E */
/* F */ beq, sbc, sbc, nop, nop, sbc, inc, smb, sed, sbc, plx, nop, nop, sbc, inc, bbs /* F */
};
static void (*addrtable[256])() = {
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
/* 0 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, rel, /* 0 */
/* 1 */ rel, indy, izp, indy, zp, zpx, zpx, zp, imp, absy, acc, absy, abso, absx, absx, rel, /* 1 */
/* 2 */ abso, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, rel, /* 2 */
/* 3 */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, acc, absy, absx, absx, absx, rel, /* 3 */
/* 4 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, rel, /* 4 */
/* 5 */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, imp, absy, absx, absx, absx, rel, /* 5 */
/* 6 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, ind, abso, abso, rel, /* 6 */
/* 7 */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, imp, absy, aii, absx, absx, rel, /* 7 */
/* 8 */ rel, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, rel, /* 8 */
/* 9 */ rel, indy, izp, indy, zpx, zpx, zpy, zp, imp, absy, imp, absy, abso, absx, absx, rel, /* 9 */
/* A */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, rel, /* A */
/* B */ rel, indy, izp, indy, zpx, zpx, zpy, zp, imp, absy, imp, absy, absx, absx, absy, rel, /* B */
/* C */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imp, abso, abso, abso, rel, /* C */
/* D */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, imp, imp, absx, absx, absx, rel, /* D */
/* E */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, rel, /* E */
/* F */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, imp, absy, absx, absx, absx, rel /* F */
};
static const uint32_t ticktable[256] = {
@ -716,10 +833,14 @@ void nmi6502() {
}
void irq6502() {
push16(pc);
push8(status);
status |= FLAG_INTERRUPT;
pc = (uint16_t)read6502(0xFFFE) | ((uint16_t)read6502(0xFFFF) << 8);
// only initiate interrupts when interrupt flag is cleared
if (!(status & FLAG_INTERRUPT)){
push16(pc);
push8(status);
status |= FLAG_INTERRUPT;
pc = (uint16_t)read6502(0xFFFE) | ((uint16_t)read6502(0xFFFF) << 8);
}
}
void step6502() {

View File

@ -20,6 +20,7 @@ extern void step6502();
extern void updateRenderStates();
extern void scanKeyboard();
extern void clearScreen(uint32_t[], uint32_t);
extern void sdlResize();
static SDL_Scancode currentKey = SDL_SCANCODE_UNKNOWN;
static SDL_Event event;
@ -65,11 +66,13 @@ void pollEvents(){
case SDL_SCANCODE_F6: /* Scale -- */
clearScreen(renderMemory, 0x000000FF);
if (displayScale > 1) displayScale--;
break;
sdlResize();
break;
case SDL_SCANCODE_F7: /* Scale ++ */
clearScreen(renderMemory, 0x000000FF);
displayScale++;
sdlResize();
break;
case SDL_SCANCODE_F8: /* CPU Singlestep */

View File

@ -1,4 +1,6 @@
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_video.h>
#include <ctype.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@ -9,8 +11,8 @@
#include "config.h"
/* Preset Values */
static float displayScale = 2;
static int cpuSpeed = 100000; // 100 kHz
static float displayScale = 1;
static int cpuSpeed = 1000000; // 1 MHz
static int singleStep = 0;
static int clockSteps = 1;
@ -28,6 +30,7 @@ uint8_t showDebug = 0;
uint8_t fpsCount = 0;
uint8_t displayMmap = 0;
uint8_t documentReload = 0;
uint8_t randomize = 0;
uint8_t fpsStore = 60;
uint8_t FPS = 30;
@ -36,12 +39,11 @@ uint8_t cpuHealth;
unsigned long cpuTicks = 0;
unsigned long tickTrigger = 0;
char debugString[512];
char snapshotFile[32];
char *reloadExecute;
char *inputFile;
char *displaySpeed;
int openFile(){
FILE *file = fopen(inputFile, "rb");
@ -61,25 +63,52 @@ int openFile(){
}
void resetSystem(){
srand((unsigned)time(NULL));
if (randomize) {
for (int i = 0; i < RAMSIZE + 1; i++) ram[i] = rand();
}
initVideo();
updateVideo();
reset6502();
}
void fetchArgs(int argc, char *argv[]){
printf(PREAMBLE);
int parseFormat(char *format){
float retVal = 0;
int i = 0;
for (;isdigit(format[i]) || format[i] == '.'; i++);
char tmp = format[i];
format[i] = 0;
retVal = atof(format);
format[i] = tmp;
if (!strcasecmp((format + i), "hz"));
else if (!strcasecmp((format + i), "khz")) retVal *= 1000;
else if (!strcasecmp((format + i), "mhz")) retVal *= 1000000;
else {
printf("\"%s\" is not a supported format\nSupported formats include: Hz, KHz and MHz\n", (format + i));
exit(EXIT_FAILURE);
}
return (int)retVal;
}
void fetchArgs(int argc, char *argv[]){
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]);
if (!strcmp(argv[i], "--help")) { printf(PREAMBLE); printf(HELP); exit(0); }
else if (!strcmp(argv[i], "--help-keys")) { printf(PREAMBLE); printf(HELPKEYS); exit(0); }
else if (!strcmp(argv[i], "--cpuspeed")) { cpuSpeed = parseFormat(argv[++i]); displaySpeed = 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 if (!strcmp(argv[i], "--fps")) FPS = atoi(argv[++i]);
else if (!strcmp(argv[i], "--reload-program")) documentReload = 1;
else if (!strcmp(argv[i], "--script")) reloadExecute = argv[++i];
else if (!strcmp(argv[i], "--resizable")) WINMODE |= SDL_WINDOW_RESIZABLE;
else if (!strcmp(argv[i], "--randomize")) randomize = 1;
else {
inputFile = argv[i];
if (openFile()){
@ -90,6 +119,7 @@ void fetchArgs(int argc, char *argv[]){
}
}
int main(int argc, char *argv[]){
fetchArgs(argc, argv);
initWindow();
@ -129,34 +159,32 @@ int main(int argc, char *argv[]){
if (halt) {
drawString("!CPU Haltet!", renderMemory,
SDL_X_SIZE, 0x000000FF, time(NULL) % 2 ? 0xAAAAAAFF : 0xFFFFFFFF, 16, vStack, 2);
SDL_X_SIZE, 0x000000FF, time(NULL) % 2 ? 0xAAAAAAFF : 0xFFFFFFFF, 16, vStack, 1);
vStack += (FONT_HEIGHT * 2 * 2);
vStack += (FONT_HEIGHT * 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);
SDL_X_SIZE, 0x000000FF, 0xAAAAAAFF, 16, vStack, 1);
vStack += (FONT_HEIGHT * 4 * 2);
vStack += (FONT_HEIGHT * 4);
sprintf(debugString, "CPU: %d%%", cpuHealth);
sprintf(debugString, "CPU: %d%% @ %s", cpuHealth, displaySpeed);
drawString(debugString, renderMemory,
SDL_X_SIZE, 0x000000FF, time(NULL) % 2 ? 0xAAAAAAFF : cpuHealth < 10 ?
0xFF0000FF : cpuHealth < 50 ? 0xFFFF00FF : 0xAAAAAAFF, 16, vStack, 2);
0xFF0000FF : cpuHealth < 50 ? 0xFFFF00FF : 0xAAAAAAFF, 16, vStack, 1);
vStack += (FONT_HEIGHT * 2 * 2);
vStack += (FONT_HEIGHT * 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);
drawString(debugString, renderMemory, SDL_X_SIZE, 0x000000FF, 0xAAAAAAFF, 16, vStack, 1);
vStack += (FONT_HEIGHT * 6 * 2);
vStack += (FONT_HEIGHT * 6);
} if (showHelp) {
drawString(HELPKEYS, renderMemory, SDL_X_SIZE, 0x000000FF, 0xAAAAAAFF, 16, vStack, 2);
drawString(HELPKEYS, renderMemory, SDL_X_SIZE, 0x000000FF, 0xAAAAAAFF, 16, vStack, 1);
vStack += (FONT_HEIGHT * 2 * 2);
vStack += (FONT_HEIGHT * 2);
}
if (SDL_UpdateTexture(texture, NULL, renderMemory, (sizeof(uint32_t) * SDL_X_SIZE))) {
fprintf(stderr, "Could not update SDL texture: %s.\n", SDL_GetError());

View File

@ -1,7 +1,11 @@
#include <SDL2/SDL.h>
#include <SDL2/SDL_video.h>
#include "config.h"
#include "font.h"
extern float displayScale;
int WINMODE = 0;
static SDL_Window *window;
static SDL_Renderer *renderer;
static SDL_Texture *texture;
@ -16,7 +20,7 @@ void initWindow(){
window = SDL_CreateWindow("LS7 Emulator",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT, 0);
SDL_X_SIZE, SDL_Y_SIZE, WINMODE);
if (window == NULL){
printf("Fatal! Could not create SDL Window: %s\n", SDL_GetError());
exit(EXIT_FAILURE);
@ -30,7 +34,7 @@ void initWindow(){
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STREAMING,
SCREEN_WIDTH, SCREEN_HEIGHT);
SDL_X_SIZE, SDL_Y_SIZE);
if (texture == NULL){
printf("Fatal! Could not create SDL Texture: %s\n", SDL_GetError());
exit(EXIT_FAILURE);
@ -42,6 +46,10 @@ void initWindow(){
}
}
void sdlResize(){
SDL_SetWindowSize(window, SDL_X_SIZE * displayScale, SDL_Y_SIZE * displayScale);
}
void clearScreen(uint32_t pixels[], uint32_t color){
for (uint32_t i = 0; i < SDL_X_SIZE * SDL_Y_SIZE; i++) pixels[i] = color;
}

View File

@ -6,6 +6,7 @@
#define LOWCOLOR 96
extern float displayScale;
extern uint8_t randomize;
/* Public Variables */
int8_t videoModified;
@ -50,8 +51,9 @@ void initVideo(){
videoMode = 0x01;
updatePalette();
/* Fill VRAM with random values, just for fun */
for (int i = 0; i < 0x8000; i++) videoMemory[i] = rand();
if (randomize) {
for (int i = 0; i < 0x8000; i++) videoMemory[i] = rand();
}
}
void writeVideo(){
@ -86,26 +88,16 @@ void setPixels(uint8_t x, uint8_t y){
videoColorValue = videoMemory[(y * 128) + (x | 0x40)];
}
// Snipping out the upper 8 colors
// videoColorValue &= 0x77;
for (uint8_t i = 0; i < 8; i++){
if (displayScale == 1){
renderMemory[(y * SDL_X_SIZE) + ((x * 8) + i)] = (videoValue & (128 >> i)) ? videoColorIndex[((videoColorValue & 0xF0) >> 4)] : videoColorIndex[(videoColorValue & 0x0F)];
} else {
for (uint8_t _x = 0; _x < displayScale; _x++){
for (uint8_t _y = 0; _y < displayScale; _y++){
renderMemory[(((y * (int)displayScale) + _y) * SDL_X_SIZE) + ((((x * (int)displayScale) * 8) + (i * (int)displayScale)) + _x)] = (videoValue & (128 >> i)) ? videoColorIndex[((videoColorValue & 0xF0) >> 4)] : videoColorIndex[(videoColorValue & 0x0F)];
}
}
}
renderMemory[(y * SDL_X_SIZE) + ((x * 8) + i)] =
(videoValue & (128 >> i)) ?
videoColorIndex[((videoColorValue & 0xF0) >> 4)] :
videoColorIndex[(videoColorValue & 0x0F)];
}
}
void updateVideo(){
if (videoModified){
//sfVertexArray_clear(renderArray);
if (videoModified){
for (uint16_t y = 0; y < 256; y++){
for (uint8_t x = 0; x < 48; x++){
setPixels(x, (uint8_t)y);