From 394c9fbb6cc243e46b32aa9e7221b0e6cadd4c13 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Wed, 25 Nov 2020 20:35:13 +0100 Subject: some work on emulator, also added gengetopt and cmake support for it --- emu/6502.c | 40 ++++++++++++++++++++++++++++++++++++++++ emu/6502.h | 15 ++++++++++----- emu/7seg.c | 0 emu/7seg.h | 12 ++++++++++++ emu/CMakeLists.txt | 41 +++++++++++++++++++++++++++++++++++++++++ emu/cmake/find_gengetopt.cmake | 33 +++++++++++++++++++++++++++++++++ emu/emu.c | 24 ++++++++++++++++++++++++ emu/emul.c | 14 ++++++++------ emu/options.ggo.in | 18 ++++++++++++++++++ emu/version.h.in | 6 ++++++ 10 files changed, 192 insertions(+), 11 deletions(-) create mode 100644 emu/7seg.c create mode 100644 emu/7seg.h create mode 100644 emu/CMakeLists.txt create mode 100644 emu/cmake/find_gengetopt.cmake create mode 100644 emu/options.ggo.in create mode 100644 emu/version.h.in (limited to 'emu') 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 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 +#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 +#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 \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 -- cgit v1.2.3-54-g00ecf