summaryrefslogtreecommitdiff
path: root/emu
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-11-29 19:31:22 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-11-29 19:31:22 +0100
commitc7b0b280339064ab1b673ab7767d0318b2e9b72a (patch)
treeb597ee3f3c36db401eccb5bca5e8d7f8a8db8485 /emu
parentaca930d803177cb6ea8ebadd77b6ef09ab2b5b49 (diff)
download6502-c7b0b280339064ab1b673ab7767d0318b2e9b72a.tar.gz
6502-c7b0b280339064ab1b673ab7767d0318b2e9b72a.tar.bz2
7-segment display is now drawn
Diffstat (limited to 'emu')
-rw-r--r--emu/7seg.c86
-rw-r--r--emu/7seg.h8
-rw-r--r--emu/CMakeLists.txt5
-rw-r--r--emu/bus.c1
-rw-r--r--emu/device.c10
-rw-r--r--emu/device.h13
-rw-r--r--emu/emu.c7
-rw-r--r--emu/emul.c22
-rw-r--r--emu/emul.h1
-rw-r--r--emu/memory.c1
10 files changed, 146 insertions, 8 deletions
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 <stdio.h>
+#include <stdbool.h>
+
+#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 <stdint.h>
#include <stdbool.h>
+#ifdef WITH_GUI
+#include <SDL.h>
+#include <SDL2_gfxPrimitives.h>
+#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 <stdint.h>
+#ifdef WITH_GUI
+#include <SDL.h>
+#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
};