summaryrefslogtreecommitdiff
path: root/emu
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-11-25 20:35:13 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-11-25 20:35:13 +0100
commit394c9fbb6cc243e46b32aa9e7221b0e6cadd4c13 (patch)
tree2a6cf365b703be3cdb78045890f84e2a3aa5e74c /emu
parent6c3401b8a2ce7a2dfe21a253f840f286088b1921 (diff)
download6502-394c9fbb6cc243e46b32aa9e7221b0e6cadd4c13.tar.gz
6502-394c9fbb6cc243e46b32aa9e7221b0e6cadd4c13.tar.bz2
some work on emulator, also added gengetopt and cmake support for it
Diffstat (limited to 'emu')
-rw-r--r--emu/6502.c40
-rw-r--r--emu/6502.h15
-rw-r--r--emu/7seg.c0
-rw-r--r--emu/7seg.h12
-rw-r--r--emu/CMakeLists.txt41
-rw-r--r--emu/cmake/find_gengetopt.cmake33
-rw-r--r--emu/emu.c24
-rw-r--r--emu/emul.c14
-rw-r--r--emu/options.ggo.in18
-rw-r--r--emu/version.h.in6
10 files changed, 192 insertions, 11 deletions
diff --git a/emu/6502.c b/emu/6502.c
index 8b24901..5baaf32 100644
--- a/emu/6502.c
+++ b/emu/6502.c
@@ -178,6 +178,8 @@ void cpu_6502_step( cpu_6502_t *cpu )
{
uint8_t opcode;
uint8_t operand8;
+ uint16_t operand16;
+ uint16_t tmp;
opcode = cpu_6502_read_byte( cpu, cpu->PC );
cpu->PC++;
@@ -230,6 +232,44 @@ void cpu_6502_step( cpu_6502_t *cpu )
cpu->A = cpu_6502_read_byte( cpu, operand8 );
update_negative_and_sign( cpu, cpu->A );
break;
+
+ case STX_ABS:
+ operand16 = cpu_6502_read_word( cpu, cpu->PC );
+ cpu->PC += 2;
+ cpu_6502_write_word( cpu, operand16, cpu->X );
+ break;
+
+ case DEY_IMPL:
+ cpu->Y--;
+ update_negative_and_sign( cpu, cpu->Y );
+ break;
+
+ case ROL_ACC:
+ tmp = ( cpu->A << 1 ) | is_carry( cpu );
+ if( tmp & 0xFF00 ) {
+ cpu->PS |= PS_C;
+ } else {
+ cpu->PS &= ~PS_C;
+ }
+ cpu->A = tmp & 0xFF;
+ update_negative_and_sign( cpu, cpu->A );
+ break;
+
+ case BNE_REL:
+ operand8 = cpu_6502_read_byte( cpu, cpu->PC );
+ cpu->PC++;
+ if( !is_zero( cpu ) ) {
+ cpu->PC += (int8_t)operand8;
+ }
+ break;
+
+ case BCC_REL:
+ operand8 = cpu_6502_read_byte( cpu, cpu->PC );
+ cpu->PC++;
+ if( !is_carry( cpu ) ) {
+ cpu->PC += (int8_t)operand8;
+ }
+ break;
case JMP_ABS:
cpu->PC = cpu_6502_read_word( cpu, cpu->PC );
diff --git a/emu/6502.h b/emu/6502.h
index b5ab14a..dac07a1 100644
--- a/emu/6502.h
+++ b/emu/6502.h
@@ -31,14 +31,19 @@ enum {
};
enum {
- LDX_IMM = 0xA2,
+ LDX_IMM = 0xA2,
LDX_ZERO = 0xA6,
- LDY_IMM = 0xA0,
+ LDY_IMM = 0xA0,
LDY_ZERO = 0xA4,
- LDA_IMM = 0xA9,
+ LDA_IMM = 0xA9,
LDA_ZERO = 0xA5,
- JMP_ABS = 0x4C,
- JSR_ABS = 0x20,
+ STX_ABS = 0x8E,
+ DEY_IMPL = 0x88,
+ ROL_ACC = 0x2A,
+ BNE_REL = 0xD0,
+ BCC_REL = 0x90,
+ JMP_ABS = 0x4C,
+ JSR_ABS = 0x20,
RTS_IMPL = 0x60,
TXS_IMPL = 0x9A
};
diff --git a/emu/7seg.c b/emu/7seg.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/emu/7seg.c
diff --git a/emu/7seg.h b/emu/7seg.h
new file mode 100644
index 0000000..c49a8a1
--- /dev/null
+++ b/emu/7seg.h
@@ -0,0 +1,12 @@
+#ifndef 7_SEG_H
+#define 7_SEG_H
+
+#ifdef WITH_GUI
+#include <SDL.h>
+#endif
+
+typedef struct 7seg_t
+{
+} 7seg_t;
+
+#endif
diff --git a/emu/CMakeLists.txt b/emu/CMakeLists.txt
new file mode 100644
index 0000000..e1fe6c9
--- /dev/null
+++ b/emu/CMakeLists.txt
@@ -0,0 +1,41 @@
+cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
+
+set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
+
+include(cmake/find_gengetopt.cmake)
+
+project(emu C)
+
+set( EMU_VERSION 0.0.1 )
+
+set(CMAKE_C_FLAGS "-g -O0 -std=c99 -Wall -DWITH_GUI")
+
+add_custom_target(distclean
+ COMMAND make clean
+ COMMAND git clean -d -f -x
+)
+
+configure_file( "${PROJECT_SOURCE_DIR}/options.ggo.in"
+ "${PROJECT_SOURCE_DIR}/options.ggo" @ONLY )
+configure_file( "${PROJECT_SOURCE_DIR}/version.h.in"
+ "${PROJECT_SOURCE_DIR}/version.h" @ONLY )
+
+set(SRC
+ 6502.c
+ memory.c
+ 7seg.c
+ emul.c
+ emu.c
+)
+
+ADD_GENGETOPT_FILES(SRC options.ggo)
+
+INCLUDE(FindPkgConfig)
+
+PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
+
+include_directories(${SDL2_INCLUDE_DIRS})
+
+add_executable(emu ${SRC})
+target_link_libraries(emu ${SDL2_LIBRARIES})
+
diff --git a/emu/cmake/find_gengetopt.cmake b/emu/cmake/find_gengetopt.cmake
new file mode 100644
index 0000000..3caea3e
--- /dev/null
+++ b/emu/cmake/find_gengetopt.cmake
@@ -0,0 +1,33 @@
+MACRO(FIND_GENGETOPT)
+ IF(NOT GENGETOPT_EXECUTABLE)
+ FIND_PROGRAM(GENGETOPT_EXECUTABLE gengetopt)
+ IF (NOT GENGETOPT_EXECUTABLE)
+ MESSAGE(FATAL_ERROR "gengetopt not found - aborting")
+ ENDIF (NOT GENGETOPT_EXECUTABLE)
+ ENDIF(NOT GENGETOPT_EXECUTABLE)
+ENDMACRO(FIND_GENGETOPT)
+
+MACRO(ADD_GENGETOPT_FILES _sources )
+ FIND_GENGETOPT()
+
+ FOREACH (_current_FILE ${ARGN})
+ GET_FILENAME_COMPONENT(_in ${_current_FILE} ABSOLUTE)
+ GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE)
+
+ SET(_out ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.c)
+ SET(_header ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h)
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${_out} ${_header}
+ COMMAND ${GENGETOPT_EXECUTABLE}
+ ARGS
+ -F ${_basename}
+ --unamed-opts
+ --input=${_in}
+ DEPENDS ${_in}
+ )
+
+ SET(${_sources} ${${_sources}} ${_out} )
+ SET(${_sources} ${${_sources}} ${_header} )
+ ENDFOREACH (_current_FILE)
+ENDMACRO(ADD_GENGETOPT_FILES)
diff --git a/emu/emu.c b/emu/emu.c
index 7d5c37c..7c8f041 100644
--- a/emu/emu.c
+++ b/emu/emu.c
@@ -4,11 +4,35 @@
#include <stdlib.h>
+#include "options.h"
+#include "version.h"
+
+static int parse_options_and_arguments( int argc, char *argv[], struct gengetopt_args_info *args_info ) {
+ cmdline_parser_init( args_info );
+
+ if( cmdline_parser2( argc, argv, args_info, 1, 0, 1 ) != 0 ) {
+ cmdline_parser_free( args_info );
+ return 1;
+ }
+
+ return 0;
+}
+
int main( int argc, char *argv[] )
{
+ struct gengetopt_args_info args_info;
emul_t emul;
cpu_6502_t cpu;
memory_t memory;
+
+ if( parse_options_and_arguments( argc, argv, &args_info ) != 0 ) {
+ exit( EXIT_FAILURE );
+ }
+
+ if( args_info.long_version_given ) {
+ printf( "emu version: %s, Copyright (c) 2020, LGPLv3, Andreas Baumann <mail at andreasbaumann dot cc>\n", EMU_VERSION );
+ exit( EXIT_SUCCESS );
+ }
memory_init( &memory );
memory_load( &memory, ROM_START, ROM_SIZE, "./rom.bin" );
diff --git a/emu/emul.c b/emu/emul.c
index dc7453b..70a1144 100644
--- a/emu/emul.c
+++ b/emu/emul.c
@@ -23,14 +23,12 @@ void emul_start( emul_t *emul )
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 );
@@ -110,8 +108,12 @@ void emul_run( emul_t *emul )
void emul_free( emul_t *emul )
{
- SDL_DestroyTexture( emul->background_texture );
- SDL_FreeSurface( emul->background_image );
- SDL_DestroyRenderer( emul->renderer );
- SDL_DestroyWindow( emul->window );
+#ifdef WITH_GUI
+ if( emul->gui ) {
+ SDL_DestroyTexture( emul->background_texture );
+ SDL_FreeSurface( emul->background_image );
+ SDL_DestroyRenderer( emul->renderer );
+ SDL_DestroyWindow( emul->window );
+ }
+#endif
}
diff --git a/emu/options.ggo.in b/emu/options.ggo.in
new file mode 100644
index 0000000..61fb1d4
--- /dev/null
+++ b/emu/options.ggo.in
@@ -0,0 +1,18 @@
+package "emu"
+version "@EMU_VERSION@"
+usage "emu [options]"
+description "6502 emulator"
+
+section "Main Options"
+ option "long-version" -
+ "Full version and credentials"
+ optional
+
+ option "gui" g
+ "Enable GUI"
+ optional
+
+ option "debug" d
+ "Enable debugging output"
+ optional
+
diff --git a/emu/version.h.in b/emu/version.h.in
new file mode 100644
index 0000000..1935a18
--- /dev/null
+++ b/emu/version.h.in
@@ -0,0 +1,6 @@
+#ifndef VERSION_H
+#define VERSION_H
+
+#define EMU_VERSION "@EMU_VERSION@"
+
+#endif