summaryrefslogtreecommitdiff
path: root/emu
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-11-22 20:38:51 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-11-22 20:38:51 +0100
commit6c3401b8a2ce7a2dfe21a253f840f286088b1921 (patch)
treef49b1bba8b10c3b3681927764cd795e7af4ad9e5 /emu
parent052899e196c6a2660651b9896ceed3313e7d0bac (diff)
download6502-6c3401b8a2ce7a2dfe21a253f840f286088b1921.tar.gz
6502-6c3401b8a2ce7a2dfe21a253f840f286088b1921.tar.bz2
more work on emulator
Diffstat (limited to 'emu')
-rw-r--r--emu/6502.c10
-rw-r--r--emu/6502.h6
-rw-r--r--emu/README4
-rw-r--r--emu/emu.c13
-rw-r--r--emu/emul.c117
-rw-r--r--emu/emul.h30
6 files changed, 170 insertions, 10 deletions
diff --git a/emu/6502.c b/emu/6502.c
index 0bb1993..8b24901 100644
--- a/emu/6502.c
+++ b/emu/6502.c
@@ -76,9 +76,9 @@ void cpu_6502_write_word( cpu_6502_t *cpu, uint16_t addr, uint16_t data )
cpu->memory->write( cpu->memory, addr + 1, ( data && 0x00FF ) );
}
-void cpu_6502_run( cpu_6502_t *cpu )
+void cpu_6502_run( cpu_6502_t *cpu, int steps )
{
- while( true ) {
+ for( int i = 0; i < steps; i++ ) {
cpu_6502_step( cpu );
}
}
@@ -138,7 +138,7 @@ static bool is_carry( cpu_6502_t *cpu )
void cpu_6502_print_state( cpu_6502_t *cpu, uint8_t opcode )
{
- fprintf( stderr, "PC: %04X SP: 01%02X PS: %02X %c%c-%c%c%c%c%c A: %02X X: %02X Y: %02X OP: %02X\n",
+ fprintf( stderr, "PC: %04X SP: 01%02X PS: %02X %c%c-%c%c%c%c%c A: %02X X: %02X Y: %02X OP: %02X steps: %d\n",
cpu->PC, cpu->SP, cpu->PS,
is_negative( cpu ) ? 'N' : 'n',
is_overflow( cpu ) ? 'V' : 'v',
@@ -147,7 +147,7 @@ void cpu_6502_print_state( cpu_6502_t *cpu, uint8_t opcode )
is_interrupt( cpu ) ? 'I' : 'i',
is_zero( cpu ) ? 'Z' : 'z',
is_carry( cpu ) ? 'C' : 'c',
- cpu->A, cpu->X, cpu->Y, opcode );
+ cpu->A, cpu->X, cpu->Y, opcode, cpu->steps );
}
static void update_negative_and_sign( cpu_6502_t *cpu, uint8_t x )
@@ -253,4 +253,6 @@ void cpu_6502_step( cpu_6502_t *cpu )
fprintf( stderr, "ERROR: Illegal opcode %02X at PC %04X\n", opcode, cpu->PC );
exit( EXIT_FAILURE );
}
+
+ cpu->steps++;
}
diff --git a/emu/6502.h b/emu/6502.h
index 1af25bc..b5ab14a 100644
--- a/emu/6502.h
+++ b/emu/6502.h
@@ -16,6 +16,8 @@ typedef struct
struct memory_t *memory;
bool debug;
+
+ int steps;
} cpu_6502_t;
enum {
@@ -50,11 +52,11 @@ void cpu_6502_push_byte( cpu_6502_t *cpu, uint8_t data );
void cpu_6502_push_word( cpu_6502_t *cpu, uint16_t data );
uint8_t cpu_6502_pop_byte( cpu_6502_t *cpu );
uint16_t cpu_6502_pop_word( cpu_6502_t *cpu );
-void cpu_6502_run( cpu_6502_t *cpu );
+void cpu_6502_run( cpu_6502_t *cpu, int steps );
+void cpu_6502_step( cpu_6502_t *cpu );
void cpu_6502_print_state( cpu_6502_t *cpu, uint8_t opcode );
void cpu_6502_print_memory( cpu_6502_t *cpu, uint16_t base, uint8_t size );
void cpu_6502_print_stack( cpu_6502_t *cpu );
void cpu_6502_print_zerop_page( cpu_6502_t *cpu );
-void cpu_6502_step( cpu_6502_t *cpu );
#endif
diff --git a/emu/README b/emu/README
new file mode 100644
index 0000000..fc23a5d
--- /dev/null
+++ b/emu/README
@@ -0,0 +1,4 @@
+emulator for homebrew 6502 based on ben eater ben6502
+
+gcc -DWITH_GUI -I/usr/include/SDL2 -lSDL2 -g -Wall -Os -o emu emu.c 6502.c memory.c emul.c
+
diff --git a/emu/emu.c b/emu/emu.c
index fbd9bb7..7d5c37c 100644
--- a/emu/emu.c
+++ b/emu/emu.c
@@ -6,16 +6,23 @@
int main( int argc, char *argv[] )
{
+ emul_t emul;
cpu_6502_t cpu;
memory_t memory;
-
+
memory_init( &memory );
memory_load( &memory, ROM_START, ROM_SIZE, "./rom.bin" );
cpu_6502_init( &cpu, &memory );
- cpu.debug = true;
+ //cpu.debug = true;
cpu_6502_reset( &cpu );
- cpu_6502_run( &cpu );
+ emul_init( &emul, &cpu, &memory );
+ emul.gui = true;
+ emul_start( &emul );
+
+ emul_run( &emul );
+
+ emul_free( &emul );
exit( EXIT_SUCCESS );
}
diff --git a/emu/emul.c b/emu/emul.c
new file mode 100644
index 0000000..dc7453b
--- /dev/null
+++ b/emu/emul.c
@@ -0,0 +1,117 @@
+#include "emul.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void emul_init( emul_t *emul, cpu_6502_t *cpu, memory_t *memory )
+{
+ emul->cpu = cpu;
+ emul->memory = memory;
+ emul->gui = false;
+}
+
+void emul_start( emul_t *emul )
+{
+ if( emul->gui ) {
+#ifdef WITH_GUI
+ int rt = SDL_Init( SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO );
+ if( rt < 0 ) {
+ fprintf( stderr, "ERROR: SDL_Init failed: %s\n", SDL_GetError( ) );
+ exit( EXIT_FAILURE );
+ }
+ atexit( SDL_Quit );
+ SDL_ShowCursor( SDL_ENABLE );
+
+ int display = -1;
+ SDL_Rect display_rect;
+ for( int i = 0; i < SDL_GetNumVideoDisplays( ); i++ ) {
+ SDL_Rect rect;
+ if( SDL_GetDisplayBounds( i, &rect ) == 0 ) {
+ fprintf( stderr, "INFO: display %d has dimensions %dx%d\n",
+ i, rect.w, rect.h );
+ display = i;
+ display_rect = rect;
+ } else {
+ fprintf( stderr, "ERROR: SDL_GetDisplayBounds failed: %s\n", SDL_GetError( ) );
+ exit( EXIT_FAILURE );
+ }
+ }
+ if( display < 0 ) {
+ fprintf( stderr, "ERROR: no video display found\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ emul->window = SDL_CreateWindow( "6502 emu",
+ SDL_WINDOWPOS_UNDEFINED_DISPLAY( display ),
+ SDL_WINDOWPOS_UNDEFINED_DISPLAY( display ),
+ 600, 250, 0 );
+ if( emul->window == NULL ) {
+ fprintf( stderr, "ERROR: SDL_CreateWindow failed: %s\n", SDL_GetError( ) );
+ exit( EXIT_FAILURE );
+ }
+
+ emul->renderer = SDL_CreateRenderer( emul->window, -1, 0 );
+ if( emul->renderer == NULL ) {
+ fprintf( stderr, "ERROR: SDL_Renderer failed: %s\n", SDL_GetError( ) );
+ exit( EXIT_FAILURE );
+ }
+
+ SDL_ShowWindow( emul->window );
+ SDL_SetRenderDrawColor( emul->renderer, 0, 0, 0, 255 );
+ SDL_RenderClear( emul->renderer );
+
+ emul->background_image = SDL_LoadBMP( "../other/breadboard.bmp" );
+ emul->background_texture = SDL_CreateTextureFromSurface( emul->renderer, emul->background_image );
+ SDL_RenderCopy( emul->renderer, emul->background_texture, NULL, NULL );
+
+ SDL_RenderPresent( emul->renderer );
+#else
+ fprintf( stderr, "WARN: gui enabled and not compiled with WITH_GUI (SDL2)\n" );
+#endif
+ }
+}
+
+void emul_run( emul_t *emul )
+{
+#ifdef WITH_GUI
+ if( emul->gui ) {
+ SDL_Event event;
+ bool done = false;
+ while( !done ) {
+ uint32_t frame_start = SDL_GetTicks( );
+
+ SDL_PollEvent( &event );
+
+ switch( event.type ) {
+ case SDL_QUIT:
+ done = true;
+ break;
+ }
+
+ cpu_6502_run( emul->cpu, CPU_FREQUENCY / DISPLAY_FPS );
+
+ cpu_6502_print_state( emul->cpu, 0 );
+ SDL_RenderCopy( emul->renderer, emul->background_texture, NULL, NULL );
+ SDL_RenderPresent( emul->renderer );
+
+ uint32_t frame_end = SDL_GetTicks( );
+ int delay = frame_start + 1000 / DISPLAY_FPS - frame_end;
+ if( delay > 0 ) {
+ SDL_Delay( delay );
+ }
+ }
+ } else {
+ cpu_6502_run( emul->cpu, 100 );
+ }
+#else
+ cpu_6502_run( emul->cpu, 100 );
+#endif
+}
+
+void emul_free( emul_t *emul )
+{
+ SDL_DestroyTexture( emul->background_texture );
+ SDL_FreeSurface( emul->background_image );
+ SDL_DestroyRenderer( emul->renderer );
+ SDL_DestroyWindow( emul->window );
+}
diff --git a/emu/emul.h b/emu/emul.h
index cefa020..131cd4c 100644
--- a/emu/emul.h
+++ b/emu/emul.h
@@ -1,9 +1,37 @@
#ifndef EMUL_H
#define EMUL_H
+#include "6502.h"
+#include "memory.h"
+
+#include <stdbool.h>
+
+#ifdef WITH_GUI
+#include <SDL.h>
+#endif
+
enum {
ROM_START = 0xF800,
- ROM_SIZE = 2048
+ ROM_SIZE = 2048,
+ CPU_FREQUENCY = 1000000,
+ DISPLAY_FPS = 25
};
+typedef struct emul_t {
+ cpu_6502_t *cpu;
+ memory_t *memory;
+ bool gui;
+#ifdef WITH_GUI
+ SDL_Window *window;
+ SDL_Renderer *renderer;
+ SDL_Surface *background_image;
+ SDL_Texture *background_texture;
+#endif
+} emul_t;
+
+void emul_init( emul_t *emul, cpu_6502_t *cpu, memory_t *memory );
+void emul_start( emul_t *emul );
+void emul_run( emul_t *emul );
+void emul_free( emul_t *emul );
+
#endif