Compare commits

...

12 Commits

Author SHA1 Message Date
0xmac
37cfca1482 Added build-in pixelfont 2025-01-23 11:30:41 +01:00
0xmac
f99d710a8b Added on-screen info rendering 2025-01-23 11:30:32 +01:00
0xmac
f1ff0606e7 Added Drawstring function 2025-01-23 11:29:49 +01:00
0xmac
e34798f749 Added Function-key functions 2025-01-23 11:29:30 +01:00
0xmac
8fba20844b Changed Formatting 2025-01-23 11:28:19 +01:00
0xmac
a640c1a764 Reworked rendering system and added dynamic colors 2025-01-23 11:27:49 +01:00
0xmac
0b6a27a5ce Updated README 2025-01-23 11:15:04 +01:00
0xmac
1d46a5338a Removed font.ttf 2025-01-23 11:14:57 +01:00
0xmac
95ba486684 Removed font.ttf reference from Makefile 2025-01-23 11:14:39 +01:00
0xmac
e281b5b767 Removed memory.h 2025-01-08 18:26:23 +01:00
0xmac
7e6edad7c1 Changed header file to extern 2025-01-08 18:26:04 +01:00
0xmac
016c1265e7 Removed memory.h 2025-01-08 18:25:09 +01:00
12 changed files with 357 additions and 150 deletions

View File

@ -19,7 +19,6 @@ ls7emulator:
cd ../bin cd ../bin
mv ../src/ls7emulator ./ mv ../src/ls7emulator ./
strip ls7emulator strip ls7emulator
cp ../src/assets/font.ttf ./
install: ls7emulator install: ls7emulator
mkdir -p $(PREFIX)/bin mkdir -p $(PREFIX)/bin

View File

@ -1,33 +1,52 @@
# LS7-Emulator # LS7-Emulator
Emulator for the LS7 Computer written in C Emulator for the LS7 Computer written in C and SDL
# ToDo ## ToDo
This is very much ~in progress~
- Adjust cpu.c for 65c02 Instructions - Adjust cpu.c for 65c02 Instructions
- video.c 16 color support
- video.c accent color support - video.c accent color support
- cpu snapshot load/save - CPU snapshot load/save
- Emulate VIA
- Build-in memory monitor - like wozmon
- Optimize video.c
# Usage ## Usage
Start the Program with `ls7emulator [OPTIONS]... [FILE]`. Start the Program with `ls7emulator [OPTIONS] ... [FILE]`.
A file has to be specified and **must** be exactly 16k in size. A file has to be specified and **must** be exactly 16k in size.
Preferably a 65c02 program. Preferably a 65c02 program.
# OPTIONS ## Options
Command-line options can be revealed by passing `--help` when starting the program.
## Hotkeys
# Hotkeys I'm still changing stuff, so this is probably bound to change.
# Building - F1 -> Exit emulator
- F2 -> Show hotkey help
- F3 -> Show debug menu
- F4 -> Halt CPU
- F5 -> Reset CPU
- F6 ->
- F7 ->
- F8 -> Single step CPU (if in singlestep mode)
- F9 -> Save computer snapshot
- F10 -> Show computer memory map
- F11 -> Send CPU NMI
- F12 -> Send CPU IRQ
## Building
The Program is so small, that I won't distribute a binary package. The Program is so small, that I won't distribute a binary package.
The `Makefile` provides the build utilities. Simply build it in a Unix based terminal with The `Makefile` provides the build utilities. Simply build it in a Unix based terminal with
`make` and to install it in /usr/bin `make install` as root `make` and to install it in /usr/bin `make install` as root
# Dependencies ## Build dependencies
- gcc - gcc
- sdl2 - sdl2

Binary file not shown.

View File

@ -10,15 +10,14 @@
#define ROMLOC 0xC000 /* ROM Page Location */ #define ROMLOC 0xC000 /* ROM Page Location */
#define BACKCOLOR sfBlack #define BACKCOLOR sfBlack
#define FPS 60 #define SCREEN_WIDTH 768
#define SCREEN_WIDTH 786
#define SCREEN_HEIGHT 512 #define SCREEN_HEIGHT 512
#define SDL_X_SIZE 786 #define SDL_X_SIZE 768
#define SDL_Y_SIZE 786 #define SDL_Y_SIZE 512
#define PREAMBLE "LS7 Emulator by Gabriel Weingardt.\nLicense: GPL v.3+\n\n" #define PREAMBLE "LS7 Emulator by Gabriel Weingardt.\nLicense: GPL v.3+\n\n"
#define HELP "Usage: LS7Emulator [options] file\n\n\ #define HELP "Usage: LS7Emulator [options] ... [file]\n\n\
Options: Type Default Desc\n\ Options: Type Default Desc\n\
--help Show this menu\n\ --help Show this menu\n\
--help-keys Show emulator key functions\n\ --help-keys Show emulator key functions\n\
@ -27,18 +26,20 @@ Options: Type Default Desc\n\
--singlestep Enable singlestepping with the 'F8' key\n\ --singlestep Enable singlestepping with the 'F8' key\n\
--clocksteps [int] 1 Set the clock cycles cycled by a singlestep\n\ --clocksteps [int] 1 Set the clock cycles cycled by a singlestep\n\
--snapshot [string] Import a CPU snapshot\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\
\n" \n"
#define HELPKEYS "\ #define HELPKEYS "\
F1 Exit emulator\n\ F1 Exit emulator\n\
F2 Show Key Help\n\ F2 Show Key Help\n\
F3 Show Debug Menu\n\ F3 Show Debug Menu\n\
F4 Halt CPU\n\ F4 Halt CPU\n\
F5 Reset CPU\n\ F5 Reset CPU\n\
F6 Scale--\n\ F6 Scale--\n\
F7 Scale++\n\ F7 Scale++\n\
F8 Single step CPU\n\ F8 Single step CPU\n\
F9 Save CPU snapshot\n\ F9 Save CPU snapshot\n\
F10 Load previous snapshot\n\ F10 Show Computer Memory Map\n\
F11 CPU NMI\n\ F11 Send CPU NMI\n\
F12 CPU IRQ\n\n" F12 Send CPU IRQ\n\n"

View File

@ -5,8 +5,9 @@
*****************************************************/ *****************************************************/
#include <stdint.h> #include <stdint.h>
#include "memory.h"
extern void write6502(uint16_t, uint8_t);
extern uint8_t read6502(uint16_t);
//6502 defines //6502 defines
#define FLAG_CARRY 0x01 #define FLAG_CARRY 0x01

View File

@ -6,13 +6,19 @@ extern float displayScale;
extern uint8_t halt; extern uint8_t halt;
extern uint8_t showDebug; extern uint8_t showDebug;
extern uint8_t showHelp; extern uint8_t showHelp;
extern uint8_t displayMmap;
extern uint8_t documentReload;
extern uint32_t renderMemory[];
extern int openFile();
extern void resetSystem(); extern void resetSystem();
extern void irq6502(); extern void irq6502();
extern void nmi6502(); extern void nmi6502();
extern void step6502(); extern void step6502();
extern void updateRenderStates(); extern void updateRenderStates();
extern void scanKeyboard(); extern void scanKeyboard();
extern void clearScreen(uint32_t[], uint32_t);
static SDL_Scancode currentKey = SDL_SCANCODE_UNKNOWN; static SDL_Scancode currentKey = SDL_SCANCODE_UNKNOWN;
static SDL_Event event; static SDL_Event event;
@ -43,14 +49,17 @@ void pollEvents(){
break; break;
case SDL_SCANCODE_F5: /* CPU Reset */ case SDL_SCANCODE_F5: /* CPU Reset */
if (documentReload) openFile();
resetSystem(); resetSystem();
break; break;
case SDL_SCANCODE_F6: /* Scale -- */ case SDL_SCANCODE_F6: /* Scale -- */
clearScreen(renderMemory, 0x000000FF);
if (displayScale > 1) displayScale--; if (displayScale > 1) displayScale--;
break; break;
case SDL_SCANCODE_F7: /* Scale ++ */ case SDL_SCANCODE_F7: /* Scale ++ */
clearScreen(renderMemory, 0x000000FF);
displayScale++; displayScale++;
break; break;
@ -61,7 +70,8 @@ void pollEvents(){
case SDL_SCANCODE_F9: /* CPU Save Snapshot */ case SDL_SCANCODE_F9: /* CPU Save Snapshot */
break; break;
case SDL_SCANCODE_F10: /* CPU Load recent or given snapshot */ case SDL_SCANCODE_F10: /* Show CPU Memory Map */
displayMmap = !displayMmap;
break; break;
case SDL_SCANCODE_F11: /* CPU NMI */ case SDL_SCANCODE_F11: /* CPU NMI */

106
src/font.h Normal file
View File

@ -0,0 +1,106 @@
// /home/xmac/Projects/Assembly/Kernel/assets/thin.bmf
// 8x8 Character Size
#include <stdint.h>
#define FONT_WIDTH 8
#define FONT_HEIGHT 8
const uint8_t typeface[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Char 20 ; 32
0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, //Char 21 ; 33
0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Char 22 ; 34
0x24, 0x24, 0x7E, 0x24, 0x7E, 0x24, 0x24, 0x00, //Char 23 ; 35
0x10, 0x3C, 0x40, 0x38, 0x04, 0x78, 0x10, 0x00, //Char 24 ; 36
0x44, 0x48, 0x08, 0x10, 0x20, 0x24, 0x44, 0x00, //Char 25 ; 37
0x10, 0x28, 0x10, 0x34, 0x58, 0x48, 0x34, 0x00, //Char 26 ; 38
0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Char 27 ; 39
0x18, 0x20, 0x40, 0x40, 0x40, 0x20, 0x18, 0x00, //Char 28 ; 40
0x18, 0x04, 0x02, 0x02, 0x02, 0x04, 0x18, 0x00, //Char 29 ; 41
0x48, 0x30, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, //Char 2A ; 42
0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, //Char 2B ; 43
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, //Char 2C ; 44
0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, //Char 2D ; 45
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, //Char 2E ; 46
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, //Char 2F ; 47
0x38, 0x44, 0x4C, 0x54, 0x64, 0x44, 0x38, 0x00, //Char 30 ; 48
0x10, 0x30, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, //Char 31 ; 49
0x38, 0x44, 0x04, 0x18, 0x20, 0x40, 0x7C, 0x00, //Char 32 ; 50
0x38, 0x44, 0x04, 0x18, 0x04, 0x44, 0x38, 0x00, //Char 33 ; 51
0x0C, 0x14, 0x24, 0x44, 0x7C, 0x04, 0x04, 0x00, //Char 34 ; 52
0x7C, 0x40, 0x78, 0x04, 0x04, 0x44, 0x38, 0x00, //Char 35 ; 53
0x18, 0x20, 0x40, 0x78, 0x44, 0x44, 0x38, 0x00, //Char 36 ; 54
0x7C, 0x44, 0x04, 0x08, 0x10, 0x10, 0x10, 0x00, //Char 37 ; 55
0x38, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38, 0x00, //Char 38 ; 56
0x38, 0x44, 0x44, 0x3C, 0x04, 0x08, 0x30, 0x00, //Char 39 ; 57
0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, //Char 3A ; 58
0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, //Char 3B ; 59
0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x00, //Char 3C ; 60
0x00, 0x00, 0x7C, 0x00, 0x00, 0x7C, 0x00, 0x00, //Char 3D ; 61
0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, //Char 3E ; 62
0x38, 0x44, 0x04, 0x08, 0x10, 0x00, 0x10, 0x00, //Char 3F ; 63
0x78, 0x84, 0xB4, 0xBC, 0x80, 0x80, 0x7C, 0x00, //Char 40 ; 64
0x38, 0x44, 0x7C, 0x44, 0x44, 0x44, 0x44, 0x00, //Char 41 ; 65
0x78, 0x44, 0x78, 0x44, 0x44, 0x44, 0x78, 0x00, //Char 42 ; 66
0x38, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00, //Char 43 ; 67
0x78, 0x44, 0x44, 0x44, 0x44, 0x44, 0x78, 0x00, //Char 44 ; 68
0x7C, 0x40, 0x70, 0x40, 0x40, 0x40, 0x7C, 0x00, //Char 45 ; 69
0x7C, 0x40, 0x70, 0x40, 0x40, 0x40, 0x40, 0x00, //Char 46 ; 70
0x3C, 0x40, 0x5C, 0x44, 0x44, 0x44, 0x38, 0x00, //Char 47 ; 71
0x44, 0x44, 0x7C, 0x44, 0x44, 0x44, 0x44, 0x00, //Char 48 ; 72
0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, //Char 49 ; 73
0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x38, 0x00, //Char 4A ; 74
0x44, 0x48, 0x70, 0x48, 0x44, 0x44, 0x44, 0x00, //Char 4B ; 75
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7C, 0x00, //Char 4C ; 76
0x44, 0x6C, 0x54, 0x44, 0x44, 0x44, 0x44, 0x00, //Char 4D ; 77
0x44, 0x64, 0x54, 0x4C, 0x44, 0x44, 0x44, 0x00, //Char 4E ; 78
0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, //Char 4F ; 79
0x78, 0x44, 0x78, 0x40, 0x40, 0x40, 0x40, 0x00, //Char 50 ; 80
0x38, 0x44, 0x44, 0x44, 0x44, 0x48, 0x34, 0x00, //Char 51 ; 81
0x78, 0x44, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, //Char 52 ; 82
0x3C, 0x40, 0x38, 0x04, 0x04, 0x44, 0x38, 0x00, //Char 53 ; 83
0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, //Char 54 ; 84
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, //Char 55 ; 85
0x44, 0x44, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, //Char 56 ; 86
0x44, 0x44, 0x44, 0x44, 0x54, 0x6C, 0x44, 0x00, //Char 57 ; 87
0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0x44, 0x00, //Char 58 ; 88
0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, //Char 59 ; 89
0x7C, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7C, 0x00, //Char 5A ; 90
0x3C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x00, //Char 5B ; 91
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, //Char 5C ; 92
0x3C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x3C, 0x00, //Char 5D ; 93
0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, //Char 5E ; 94
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, //Char 5F ; 95
0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Char 60 ; 96
0x00, 0x00, 0x38, 0x04, 0x3C, 0x44, 0x3C, 0x00, //Char 61 ; 97
0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x78, 0x00, //Char 62 ; 98
0x00, 0x00, 0x38, 0x44, 0x40, 0x44, 0x38, 0x00, //Char 63 ; 99
0x04, 0x04, 0x34, 0x4C, 0x44, 0x44, 0x3C, 0x00, //Char 64 ; 100
0x00, 0x00, 0x38, 0x44, 0x7C, 0x40, 0x3C, 0x00, //Char 65 ; 101
0x18, 0x20, 0x78, 0x20, 0x20, 0x20, 0x20, 0x00, //Char 66 ; 102
0x00, 0x00, 0x3C, 0x44, 0x44, 0x3C, 0x04, 0x78, //Char 67 ; 103
0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0x00, //Char 68 ; 104
0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, //Char 69 ; 105
0x04, 0x00, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, //Char 6A ; 106
0x40, 0x40, 0x48, 0x50, 0x60, 0x50, 0x48, 0x00, //Char 6B ; 107
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x00, //Char 6C ; 108
0x00, 0x00, 0x68, 0x54, 0x54, 0x44, 0x44, 0x00, //Char 6D ; 109
0x00, 0x00, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, //Char 6E ; 110
0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, //Char 6F ; 111
0x00, 0x00, 0x58, 0x64, 0x44, 0x78, 0x40, 0x40, //Char 70 ; 112
0x00, 0x00, 0x34, 0x4C, 0x44, 0x3C, 0x04, 0x04, //Char 71 ; 113
0x00, 0x00, 0x58, 0x64, 0x40, 0x40, 0x40, 0x00, //Char 72 ; 114
0x00, 0x00, 0x3C, 0x40, 0x38, 0x04, 0x78, 0x00, //Char 73 ; 115
0x10, 0x38, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, //Char 74 ; 116
0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x3C, 0x00, //Char 75 ; 117
0x00, 0x00, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, //Char 76 ; 118
0x00, 0x00, 0x44, 0x44, 0x54, 0x54, 0x3C, 0x00, //Char 77 ; 119
0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, //Char 78 ; 120
0x00, 0x00, 0x44, 0x44, 0x44, 0x3C, 0x04, 0x78, //Char 79 ; 121
0x00, 0x00, 0x7C, 0x08, 0x10, 0x20, 0x7C, 0x00, //Char 7A ; 122
0x18, 0x20, 0x20, 0x40, 0x20, 0x20, 0x18, 0x00, //Char 7B ; 123
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, //Char 7C ; 124
0x18, 0x04, 0x04, 0x02, 0x04, 0x04, 0x18, 0x00, //Char 7D ; 125
0x32, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Char 7E ; 126
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Char 7F ; 127
};

View File

@ -1,3 +1,4 @@
#include <SDL2/SDL_render.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
@ -25,19 +26,23 @@ uint8_t halt = 0;
uint8_t showHelp = 0; uint8_t showHelp = 0;
uint8_t showDebug = 0; uint8_t showDebug = 0;
uint8_t fpsCount = 0; uint8_t fpsCount = 0;
uint8_t displayMmap = 0;
uint8_t documentReload = 0;
uint8_t fpsStore; uint8_t fpsStore = 60;
uint8_t FPS = 30;
uint8_t cpuHealth; uint8_t cpuHealth;
unsigned long cpuTicks = 0; unsigned long cpuTicks = 0;
unsigned long tickTrigger = 0; unsigned long tickTrigger = 0;
unsigned long renderTrigger = 0;
char debugString[255]; char debugString[512];
char snapshotFile[32];
char *inputFile;
int openFile(const char *inputFile){ int openFile(){
FILE *file = fopen(inputFile, "rb"); FILE *file = fopen(inputFile, "rb");
int retCode = 0; int retCode = 0;
@ -60,32 +65,23 @@ void resetSystem(){
reset6502(); reset6502();
} }
void writeHelp(int type){
if (!type) printf(HELP);
else printf(HELPKEYS);
exit(EXIT_SUCCESS);
}
void writePreamble() {
printf(PREAMBLE);
}
void fetchArgs(int argc, char *argv[]){ void fetchArgs(int argc, char *argv[]){
writePreamble(); printf(PREAMBLE);
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--help")) writeHelp(0); if (!strcmp(argv[i], "--help")) printf(HELP);
else if (!strcmp(argv[i], "--help-keys")) writeHelp(1); else if (!strcmp(argv[i], "--help-keys")) printf(HELPKEYS);
else if (!strcmp(argv[i], "--cpuspeed")) cpuSpeed = atoi(argv[++i]); 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], "--scale")) displayScale = atof(argv[++i]);
else if (!strcmp(argv[i], "--singlestep")) singleStep = 1; else if (!strcmp(argv[i], "--singlestep")) singleStep = 1;
else if (!strcmp(argv[i], "--clocksteps")) clockSteps = atoi(argv[++i]); else if (!strcmp(argv[i], "--clocksteps")) clockSteps = atoi(argv[++i]);
//else if (!strcmp(argv[i], "--snapshot")) snapshotFile = &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 { else {
if (openFile(argv[i])){ inputFile = argv[i];
printf("Unknown parameter or file '%s'\nTry '--help' for help\n", argv[i]); if (openFile()){
printf("%s: Unknown parameter or file '%s'\nTry '--help' for help\n", argv[0], argv[i]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -100,15 +96,14 @@ int main(int argc, char *argv[]){
resetSystem(); resetSystem();
while (1){ while (1){
SDL_Delay(32); SDL_Delay(1000.f / FPS);
pollEvents(); pollEvents();
fpsCount++; fpsCount++;
updateVideo(); updateVideo();
if (!singleStep && !halt){ if (!singleStep && !halt){
for (int i = 0; i < (cpuSpeed / FPS) * 2; i++) { for (int i = 0; i < ((float)cpuSpeed / (float)fpsStore); i++) {
step6502(); step6502();
cpuTicks++; cpuTicks++;
} }
@ -121,27 +116,60 @@ int main(int argc, char *argv[]){
cpuHealth = (uint8_t)((cpuTicks / (float)cpuSpeed) * 100.); cpuHealth = (uint8_t)((cpuTicks / (float)cpuSpeed) * 100.);
cpuTicks = 0; cpuTicks = 0;
fpsStore = fpsCount; fpsStore = fpsCount; fpsCount = 0;
fpsCount = 0;
/* Refresh entire video buffer */
videoModified = 1;
} }
/* Redraw entire screen every X seconds */
//if ((unsigned)time(NULL) > renderTrigger + 0){
renderTrigger = (unsigned)time(NULL);
if (SDL_UpdateTexture(texture, NULL, renderMemory, (sizeof(uint32_t) * SDL_X_SIZE))) { uint16_t vStack = 16;
fprintf(stderr, "Could not update SDL texture: %s.\n", SDL_GetError());
exit(EXIT_FAILURE); if (halt) {
} drawString("!CPU Haltet!", renderMemory,
if (SDL_RenderCopy(renderer, texture, NULL, NULL)) { SDL_X_SIZE, 0x000000FF, time(NULL) % 2 ? 0xAAAAAAFF : 0xFFFFFFFF, 16, vStack, 2);
fprintf(stderr, "Could not display SDL texture: %s.\n", SDL_GetError());
exit(EXIT_FAILURE); vStack += (FONT_HEIGHT * 2 * 2);
} } if (showDebug){
SDL_RenderPresent(renderer); 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; return EXIT_SUCCESS;
} }

View File

@ -1,5 +1,24 @@
#include <stdint.h> #include <stdint.h>
#include "memory.h" #include "config.h"
extern void scanKeyboard();
extern void writeVideo();
extern uint8_t readVideo();
extern uint8_t videoX;
extern uint8_t videoY;
extern uint8_t videoMode;
extern uint8_t videoA;
static int8_t ram[RAMSIZE + 1];
static int8_t rom[ROMSIZE + 1];
static uint8_t systemRegister;
static uint8_t keyboardResult;
uint8_t read6502(uint16_t address);
void write6502(uint16_t address, uint8_t value);
uint8_t read6502(uint16_t address){ uint8_t read6502(uint16_t address){
switch (address){ switch (address){

View File

@ -1,19 +0,0 @@
#include <stdint.h>
extern void scanKeyboard();
extern void writeVideo();
extern uint8_t readVideo();
extern uint8_t videoX;
extern uint8_t videoY;
extern uint8_t videoMode;
extern uint8_t videoA;
static int8_t ram[RAMSIZE + 1];
static int8_t rom[ROMSIZE + 1];
static uint8_t systemRegister;
static uint8_t keyboardResult;
uint8_t read6502(uint16_t address);
void write6502(uint16_t address, uint8_t value);

View File

@ -1,5 +1,6 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "config.h" #include "config.h"
#include "font.h"
static SDL_Window *window; static SDL_Window *window;
static SDL_Renderer *renderer; static SDL_Renderer *renderer;
@ -44,3 +45,30 @@ void initWindow(){
void clearScreen(uint32_t pixels[], uint32_t color){ void clearScreen(uint32_t pixels[], uint32_t color){
for (uint32_t i = 0; i < SDL_X_SIZE * SDL_Y_SIZE; i++) pixels[i] = color; for (uint32_t i = 0; i < SDL_X_SIZE * SDL_Y_SIZE; i++) pixels[i] = color;
} }
#define CHARMARGIN 0
void drawString(const char* string, uint32_t pixels[], uint16_t screenXsize, uint32_t foreground, uint32_t background, uint16_t x, uint16_t y, uint8_t scale){
uint16_t xCount = x;
uint16_t yCount = y;
for (int i = 0; string[i]; i++){
if (string[i] > 31 && string[i] < 127){
for (int _x = 0; _x < FONT_WIDTH * scale; _x++){
if (xCount + _x >= screenXsize){
xCount = x;
yCount += (FONT_HEIGHT + CHARMARGIN) * scale;
}
for (int _y = 0; _y < FONT_HEIGHT * scale; _y++){
uint8_t value = typeface[((string[i] - 32) * FONT_HEIGHT) + (_y / scale)] & (128 >> (_x / scale));
if (value && foreground != 0) pixels[(( yCount + _y) * screenXsize) + (xCount + _x)] = foreground;
else if (!value && background != 0) pixels[(( yCount + _y) * screenXsize) + (xCount + _x)] = background;
}
}
xCount += (FONT_WIDTH + CHARMARGIN) * scale;
} else if (string[i] == '\n'){
xCount = x;
yCount += (FONT_HEIGHT + CHARMARGIN) * scale;
}
}
}

View File

@ -1,5 +1,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include "config.h"
#define HIGHCOLOR 255
#define LOWCOLOR 96
extern float displayScale; extern float displayScale;
@ -13,24 +17,43 @@ uint8_t videoMode;
uint8_t videoA; uint8_t videoA;
/* Private Variables */ /* Private Variables */
static uint8_t videoRow;
static uint8_t videoValue; static uint8_t videoValue;
static uint8_t videoColorValue; static uint8_t videoColorValue;
static uint32_t videoColorIndex[] = { static uint32_t videoColorIndex[16];
0x000000FF,
0xFF0000FF,
0x00FF00FF,
0xFFFF00FF,
0x0000FFFF,
0xFF00FFFF,
0x00FFFFFF,
0xFFFFFFFF
};
static uint8_t videoMemory[0x8000]; static uint8_t videoMemory[0x8000];
static uint32_t renderMemory[(SDL_X_SIZE * SDL_Y_SIZE)]; uint32_t renderMemory[(SDL_X_SIZE * SDL_Y_SIZE)];
void updatePalette(){
uint8_t accentColors = videoMode & 0b11101110;
for (uint8_t i = 0; i < 16; i++){
uint32_t rawColor =
((i & 0b1) ?
HIGHCOLOR - (i & 0x8 ? 0 : LOWCOLOR) : 0) << 24 |
(((i & 0b10) ?
HIGHCOLOR - (i & 0x8 ? 0 : LOWCOLOR) : 0) << 16) |
(((i & 0b100) ?
HIGHCOLOR - (i & 0x8 ? 0 : LOWCOLOR) : 0) << 8) |
0x000000FF;
videoColorIndex[i] = rawColor;
}
}
void initVideo(){
videoModified = 1;
videoMode = 0x01;
updatePalette();
/* Fill VRAM with random values, just for fun */
for (int i = 0; i < 0x8000; i++) videoMemory[i] = rand();
}
void writeVideo(){ void writeVideo(){
videoMemory[videoX + (videoY * 128)] = videoA; videoMemory[videoX + (videoY * 128)] = videoA;
videoModified = 1; videoModified = 1;
@ -40,63 +63,55 @@ uint8_t readVideo(){
return videoMemory[videoX + (videoY * 128)]; return videoMemory[videoX + (videoY * 128)];
} }
void initVideo(){ void setPixels(uint8_t x, uint8_t y){
videoModified = 1; /* Check for Text or Graphics Mode */
videoMode = 0x01; if ((videoMode & 0x01) == 0){
/*
* Text Address Format
* 0bRRR1111AAAAAAAA
*
* R = row pins
* A = address
*/
for (int i = 0; i < 0x8000; i++) videoMemory[i] = rand(); /* Get text index value */
videoValue = videoMemory[(((y & 0xF8) >> 3) << 7) | x];
/* Index the value in font location */
videoValue = videoMemory[((y & 0x7) | 0b1111000) + (videoValue * 128)];
videoColorValue = videoMemory[(((y & 0xF8) >> 3) << 7) + (x | 0x40)];
}
else {
videoValue = videoMemory[(y * 128) + x];
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)];
}
}
}
}
} }
void updateVideo(){ void updateVideo(){
if (videoModified){ if (videoModified){
//sfVertexArray_clear(renderArray); //sfVertexArray_clear(renderArray);
for (uint8_t y = 0; y < 255; y++){ for (uint16_t y = 0; y < 256; y++){
videoRow = (int8_t)(y & 0x7);
for (uint8_t x = 0; x < 48; x++){ for (uint8_t x = 0; x < 48; x++){
setPixels(x, (uint8_t)y);
if ((videoMode & 0x01) == 0){
/*
* Text Address Format
* 0bRRR1111AAAAAAAA
*
* R = row pins
* A = address
*/
// Get text index value
videoValue = videoMemory[(((y & 0xF8) >> 3) << 7) | x];
// Index the value in font location
videoValue = videoMemory[(videoRow | 0b1111000) + (videoValue * 128)];
videoColorValue = videoMemory[(((y & 0xF8) >> 3) << 7) + (x | 0x40)];
}
else {
videoValue = videoMemory[(y * 128) + x];
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)];
}
}
}
}
} }
} }
videoModified = 0; videoModified = 0;
} }
} }