Compare commits
7 Commits
04f0fe2c7b
...
45b8993cdd
Author | SHA1 | Date | |
---|---|---|---|
![]() |
45b8993cdd | ||
![]() |
5cc21f3a6f | ||
![]() |
caba72b134 | ||
![]() |
3a7dc09389 | ||
![]() |
c824ad0989 | ||
![]() |
de0686edb7 | ||
![]() |
8581e53373 |
14
Makefile
14
Makefile
@ -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
|
||||
|
||||
|
||||
|
||||
|
20
src/config.h
20
src/config.h
@ -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
203
src/cpu.c
@ -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() {
|
||||
|
@ -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 */
|
||||
|
78
src/main.c
78
src/main.c
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
|
26
src/video.c
26
src/video.c
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user