From c7b0b280339064ab1b673ab7767d0318b2e9b72a Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 29 Nov 2020 19:31:22 +0100 Subject: 7-segment display is now drawn --- emu/7seg.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ emu/7seg.h | 8 +++++ emu/CMakeLists.txt | 5 ++-- emu/bus.c | 1 + emu/device.c | 10 +++++++ emu/device.h | 13 +++++++++ emu/emu.c | 7 ++--- emu/emul.c | 22 ++++++++++++-- emu/emul.h | 1 + emu/memory.c | 1 + 10 files changed, 146 insertions(+), 8 deletions(-) (limited to 'emu') diff --git a/emu/7seg.c b/emu/7seg.c index 8a9ea1a..f4bc25e 100644 --- a/emu/7seg.c +++ b/emu/7seg.c @@ -1,10 +1,18 @@ #include "7seg.h" #include +#include + +#ifdef WITH_GUI + +#endif static device_vtable_t const seg7_vtable = { seg7_read, seg7_write, +#ifdef WITH_GUI + seg7_draw, +#endif seg7_deinit }; @@ -59,6 +67,84 @@ void seg7_write( void *obj, uint16_t addr, uint8_t data ) } } +#ifdef WITH_GUI + +enum { + NOF_DIGITS = 16, + NOF_SEGS = 7, + // direction of the segment (vertical or horizontal) + H = 0, + V = 1, + // segment positions in the segs array (bit) + A = 6, + B = 5, + C = 4, + D = 3, + E = 2, + F = 1, + G = 0 +}; + +static int segs[NOF_DIGITS] = { + 0x7E, 0x30, 0x6D, 0x79, 0x33, + 0x5B, 0x5F, 0x70, 0x7F, 0x7B, + 0x77, 0x1F, 0x4E, 0x3D, 0x4F, + 0x47 +}; + +static int x_pos[NOF_SEGS] = { + 5, 45, 45, 5, 5, 5 , 5 +}; + +static int y_pos[NOF_SEGS] = +{ + 5, 5, 45, 90, 45, 5, 45 +}; + +static int direction[NOF_SEGS] = +{ + H, V, V, H, V, V, H +}; + +static void printSegment( SDL_Renderer *renderer, int x, int y, int direction, bool enabled ) +{ + int r = 80; + + if( enabled ) { + r = 255; + } + + switch( direction ) { + case H: + boxRGBA( renderer, x-3, y-3, x+40, y+3, r, 0x00, 0x00, 0xFF ); + break; + + case V: + boxRGBA( renderer, x-3, y-3, x+3, y+40, r, 0x00, 0x00, 0xFF ); + break; + } +} + +static void printDigit( SDL_Renderer *renderer, int x, int y, int digit ) +{ + int v = ( 1 << 6 ); + for( int i = 0; i < 7; i++ ) { + printSegment( renderer, x + x_pos[i], y + y_pos[i], direction[i], v & segs[digit] ); + v >>= 1; + } +} + +void seg7_draw( void *obj, SDL_Renderer *renderer ) +{ + seg7_t *seg = (seg7_t *)obj; + + boxRGBA( renderer, 10, 10, 110, 110, 0x00, 0x00, 0x00, 0xFF ); + + printDigit( renderer, 10, 10, ( seg->latch & 0x00F0 ) >> 4 ); + printDigit( renderer, 60, 10, seg->latch & 0x000F ); +} +#endif + void seg7_deinit( void *obj ) { seg7_t *seg = (seg7_t *)obj; diff --git a/emu/7seg.h b/emu/7seg.h index 98c6908..4da0e1f 100644 --- a/emu/7seg.h +++ b/emu/7seg.h @@ -10,6 +10,11 @@ #include #include +#ifdef WITH_GUI +#include +#include +#endif + // VIA connected on PORTA to 3 wires leading to the 3 coupled 74HC595 // shift register which enable the ROM address lines to read the LED // segment data (cells 0-15 contain the encoded 7 segments of 16 hexdigits) @@ -45,6 +50,9 @@ void seg7_init( seg7_t *seg, uint16_t addr, bool initialize ); uint8_t seg7_read( void *obj, uint16_t addr ); void seg7_write( void *obj, uint16_t addr, uint8_t data ); +#ifdef WITH_GUI +void seg7_draw( void *obj, SDL_Renderer *renderer ); +#endif void seg7_deinit( void *obj ); #endif diff --git a/emu/CMakeLists.txt b/emu/CMakeLists.txt index 04b1788..33f02f5 100644 --- a/emu/CMakeLists.txt +++ b/emu/CMakeLists.txt @@ -35,9 +35,10 @@ ADD_GENGETOPT_FILES(SRC options.ggo) INCLUDE(FindPkgConfig) PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2) +PKG_SEARCH_MODULE(SDL2_GFX REQUIRED SDL2_gfx) -include_directories(${SDL2_INCLUDE_DIRS}) +include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS}) add_executable(emu ${SRC}) -target_link_libraries(emu ${SDL2_LIBRARIES}) +target_link_libraries(emu ${SDL2_LIBRARIES} ${SDL2_GFX_LIBRARIES}) diff --git a/emu/bus.c b/emu/bus.c index 5bbbcb1..68ec972 100644 --- a/emu/bus.c +++ b/emu/bus.c @@ -6,6 +6,7 @@ static device_vtable_t const bus_vtable = { bus_read, bus_write, + device_draw, bus_deinit }; diff --git a/emu/device.c b/emu/device.c index ecf3d2d..7ad2741 100644 --- a/emu/device.c +++ b/emu/device.c @@ -7,6 +7,9 @@ static device_vtable_t const device_vtable = { device_read, device_write, +#ifdef WITH_GUI + device_draw, +#endif device_deinit }; @@ -35,6 +38,13 @@ void device_write( void *obj, uint16_t addr, uint8_t data ) device->name, addr ); } +#ifdef WITH_GUI +void device_draw( void *obj, SDL_Renderer *renderer ) +{ + // ignore rendering of abstract device +} +#endif + void device_deinit( void *obj ) { device_t *device = (device_t *)obj; diff --git a/emu/device.h b/emu/device.h index ce2abad..41c430f 100644 --- a/emu/device.h +++ b/emu/device.h @@ -3,22 +3,35 @@ #include +#ifdef WITH_GUI +#include +#endif + struct device_t; typedef struct device_vtable_t { uint8_t (*read)( void *obj, uint16_t addr ); void (*write)( void *obj, uint16_t addr, uint8_t data ); +#ifdef WITH_GUI + void (*draw)( void *obj, SDL_Renderer *renderer ); +#endif void (*deinit)( void *obj ); } device_vtable_t; typedef struct device_t { device_vtable_t const *vtable; char *name; +#ifdef WITH_GUI + SDL_Renderer *renderer; +#endif } device_t; void device_init( device_t *device, const char *name ); uint8_t device_read( void *obj, uint16_t addr ); void device_write( void *obj, uint16_t addr, uint8_t data ); +#ifdef WITH_GUI +void device_draw( void *obj, SDL_Renderer *renderer ); +#endif void device_deinit( void *obj ); #endif diff --git a/emu/emu.c b/emu/emu.c index 53431c2..539c89b 100644 --- a/emu/emu.c +++ b/emu/emu.c @@ -68,12 +68,11 @@ int main( int argc, char *argv[] ) emul_init( &emul, &cpu, &bus, args_info.width_arg, args_info.height_arg ); if( args_info.gui_given ) { - if( args_info.debug_given ) { - fprintf( stderr, "ERROR: don't run debug and GUI together! Uses too many resources!\n" ); - exit( EXIT_SUCCESS ); - } emul.gui = true; } + if( args_info.debug_given ) { + emul.debug = true; + } emul_start( &emul ); cpu_6502_reset( &cpu ); diff --git a/emu/emul.c b/emu/emul.c index 602ce33..bf64d13 100644 --- a/emu/emul.c +++ b/emu/emul.c @@ -10,6 +10,7 @@ void emul_init( emul_t *emul, cpu_6502_t *cpu, bus_t *bus, int width, int height emul->gui = false; emul->width = width; emul->height = height; + emul->debug = false; } void emul_start( emul_t *emul ) @@ -63,7 +64,7 @@ void emul_start( emul_t *emul ) 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" ); @@ -83,6 +84,14 @@ void emul_run( emul_t *emul, int nof_steps ) SDL_PollEvent( &event ); switch( event.type ) { + case SDL_KEYDOWN: + switch( event.key.keysym.sym ) { + case SDLK_ESCAPE: + done = true; + break; + } + break; + case SDL_QUIT: done = true; break; @@ -90,8 +99,17 @@ void emul_run( emul_t *emul, int nof_steps ) cpu_6502_run( emul->cpu, CPU_FREQUENCY / DISPLAY_FPS ); - cpu_6502_print_state( emul->cpu, 0 ); + if( emul->debug ) { + cpu_6502_print_state( emul->cpu, 0 ); + } + SDL_RenderCopy( emul->renderer, emul->background_texture, NULL, NULL ); + + for( int i = 0; i < emul->bus->nof_devices; i++ ) { + device_t *device = emul->bus->devices[i].device; + device->vtable->draw( device, emul->renderer ); + } + SDL_RenderPresent( emul->renderer ); uint32_t frame_end = SDL_GetTicks( ); diff --git a/emu/emul.h b/emu/emul.h index 6945143..a0e6b5f 100644 --- a/emu/emul.h +++ b/emu/emul.h @@ -33,6 +33,7 @@ typedef struct emul_t { bool gui; int width; int height; + bool debug; #ifdef WITH_GUI SDL_Window *window; SDL_Renderer *renderer; diff --git a/emu/memory.c b/emu/memory.c index c3f49a4..e879edd 100644 --- a/emu/memory.c +++ b/emu/memory.c @@ -7,6 +7,7 @@ static device_vtable_t const memory_vtable = { memory_read, memory_write, + device_draw, memory_deinit }; -- cgit v1.2.3-54-g00ecf