From 6c3401b8a2ce7a2dfe21a253f840f286088b1921 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 22 Nov 2020 20:38:51 +0100 Subject: more work on emulator --- emu/emul.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 emu/emul.c (limited to 'emu/emul.c') 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 +#include + +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 ); +} -- cgit v1.2.3-54-g00ecf