From 737b50e211ec89a3c7dbb65e7f4641095757e7ab Mon Sep 17 00:00:00 2001 From: Tony Di Nucci Date: Tue, 23 Apr 2019 21:19:00 +0100 Subject: [PATCH] Start of graphics support --- CMakeLists.txt | 7 ++++- sample/draw.asm | 9 ++++++ src/machine/machine.cpp | 16 ++++++++-- src/machine/machine.h | 2 +- src/machine/terminal.cpp | 66 ++++++++++++++++++++++++++-------------- src/machine/terminal.h | 19 +++++++----- src/main.cpp | 16 +++++----- test/test-utils.cpp | 2 +- 8 files changed, 94 insertions(+), 43 deletions(-) create mode 100644 sample/draw.asm diff --git a/CMakeLists.txt b/CMakeLists.txt index 10a1462..3745d12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,11 +23,16 @@ add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src ${CMAKE_CURRENT_BINARY_DIR}/googletest-build EXCLUDE_FROM_ALL) +find_package(SDL2 REQUIRED) +include_directories(${SDL2_INCLUDE_DIRS}) + file(GLOB_RECURSE test_src "test/**.h" "test/**.cpp" "src/**.h" "src/**.cpp") list(FILTER test_src EXCLUDE REGEX ".*/6502-emulator/src/main.cpp$") add_executable(6502_emulator_test ${test_src}) target_link_libraries(6502_emulator_test gtest_main) +target_link_libraries(6502_emulator_test ${SDL2_LIBRARIES}) add_test(NAME run_tests COMMAND 6502_emulator_test) file(GLOB_RECURSE emulator_src "src/**.h" "src/**.cpp") -add_executable(6502_emulator ${emulator_src}) \ No newline at end of file +add_executable(6502_emulator ${emulator_src}) +target_link_libraries(6502_emulator ${SDL2_LIBRARIES}) \ No newline at end of file diff --git a/sample/draw.asm b/sample/draw.asm new file mode 100644 index 0000000..87b428f --- /dev/null +++ b/sample/draw.asm @@ -0,0 +1,9 @@ + lda #$0 + + loop + sta $e000, x + inx + adc #$1 + cpx #$ff + bne loop + diff --git a/src/machine/machine.cpp b/src/machine/machine.cpp index 4dbcd24..a635dc2 100644 --- a/src/machine/machine.cpp +++ b/src/machine/machine.cpp @@ -1,4 +1,5 @@ #include "machine.h" +#include "terminal.h" #include "../opcode/opcode-handler-directory.h" #include @@ -6,18 +7,26 @@ namespace emu_6502 { class MachineImpl { private: + bool terminal_initialised = false; uint16_t code_loaded_at; uint16_t code_size; unique_ptr cpu; unique_ptr memory; unique_ptr stack; + unique_ptr terminal; unique_ptr opcode_handler_dir; public: - MachineImpl() { + MachineImpl(bool init_terminal) { cpu = make_unique(); memory = make_unique(); stack = make_unique(*memory, cpu->get_sp()); + + if (init_terminal) { + terminal = make_unique(*memory); + terminal_initialised = true; + } + opcode_handler_dir = make_unique(); } @@ -67,11 +76,14 @@ namespace emu_6502 { while (!is_eop()) { auto byte = read_program_byte(); opcode_handler_dir->execute(byte, machine); + + if (terminal_initialised) + terminal->refresh(); } } }; - Machine::Machine() : pimpl(make_unique()) { + Machine::Machine(bool init_terminal) : pimpl(make_unique(init_terminal)) { } Machine::~Machine() = default; diff --git a/src/machine/machine.h b/src/machine/machine.h index b63980c..26b358e 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -17,7 +17,7 @@ namespace emu_6502 { private: unique_ptr pimpl; public: - Machine(); + Machine(bool init_terminal = true); ~Machine(); Machine(const Machine&) = delete; Machine& operator=(const Machine&) = delete; diff --git a/src/machine/terminal.cpp b/src/machine/terminal.cpp index dcf6392..1f2264f 100644 --- a/src/machine/terminal.cpp +++ b/src/machine/terminal.cpp @@ -5,33 +5,55 @@ namespace emu_6502 { Terminal::Terminal(Memory& memory) : memory(memory) { -// for (auto i = 0; i < 100; i++) -// memory->set_at(Terminal::LOW_ADDR + i, 0x20 + i); -// -// if ((mainwin = initscr()) == NULL) { -// fprintf(stderr, "Error initialising ncurses.\n"); -// exit(EXIT_FAILURE); -// } -// -// start_color(); + int width = WIDTH * PIXEL_WEIGHT; + int height = HEIGHT * PIXEL_WEIGHT; + + SDL_Init(SDL_INIT_VIDEO); + SDL_CreateWindowAndRenderer(width, height, 0, &window, &renderer); + SDL_RenderClear(renderer); + + for (auto i = LOW_ADDR; i <= HIGH_ADDR; i++) { + memory.set_at(i, 0); + } } Terminal::~Terminal() { -// delwin(mainwin); -// endwin(); - - cout << "shutting down" << endl; + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); } void Terminal::refresh() { -// for (auto n = 0; n <= 100; n++) { -// auto line = (n / TERM_COLS); -// auto col = n % TERM_COLS; -// -// mvaddch(line, col, memory->get_at(Terminal::LOW_ADDR + n)); -// n++; -// } -// -// wrefresh(mainwin); + int x, y = 0; + for (auto i = LOW_ADDR; i <= HIGH_ADDR; i++) { + x = (i - LOW_ADDR) % WIDTH; + y = (i - LOW_ADDR) / HEIGHT; + + auto colour = memory.get_at(i); + if (colour) { + draw_pixel(x, y, colour); + } + } + + SDL_RenderPresent(renderer); + SDL_Delay(5); + } + + void Terminal::draw_pixel(int x, int y, uint8_t colour) { + uint8_t red, green, blue = 0; + red = colour >> 5; + green = (colour >> 2) & 0x07; + blue = colour & 0x03; + + cout << "RED: " << (int)red << " GREEN: " << (int)green << " BLUE: " << (int)blue << endl; + + SDL_SetRenderDrawColor(renderer, red * 36, green * 36, blue * 85, 0); + for (int i = 0; i < PIXEL_WEIGHT; i++) { + SDL_RenderDrawPoint(renderer, (x * PIXEL_WEIGHT) + i, (y * PIXEL_WEIGHT)); + + for (int j = 0; j < PIXEL_WEIGHT; j++) { + SDL_RenderDrawPoint(renderer, (x * PIXEL_WEIGHT) + i, (y * PIXEL_WEIGHT) + j); + } + } } } \ No newline at end of file diff --git a/src/machine/terminal.h b/src/machine/terminal.h index a44a3de..d3f6e2a 100644 --- a/src/machine/terminal.h +++ b/src/machine/terminal.h @@ -1,8 +1,8 @@ #ifndef INC_6502_EMULATOR_TERMINAL_H #define INC_6502_EMULATOR_TERMINAL_H -#include #include +#include #include "memory.h" using namespace std; @@ -10,15 +10,20 @@ using namespace std; namespace emu_6502 { class Terminal { private: - const uint16_t LOW_ADDR = 0xFB00; - const uint16_t HIGH_ADDR = 0xFF00; - const uint8_t TERM_LINES = 25; - const uint8_t TERM_COLS = 40; - - //WINDOW * mainwin; + const uint16_t LOW_ADDR = 0xE000; + const uint16_t HIGH_ADDR = 0xF000; + const uint8_t WIDTH = 64; + const uint8_t HEIGHT = 64; + const uint8_t PIXEL_WEIGHT = 8; Memory& memory; + SDL_Event event; + SDL_Renderer* renderer; + SDL_Window* window; + + void draw_pixel(int x, int y, uint8_t colour); + public: Terminal(Memory& memory); Terminal(const Terminal&) = delete; diff --git a/src/main.cpp b/src/main.cpp index a84138e..07355ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "machine/machine.h" #include "machine/terminal.h" #include "machine/memory.h" @@ -11,20 +12,17 @@ using namespace std; using namespace emu_6502; int main() { + ifstream in("/home/tony/CLionProjects/6502-emulator/sample/a.o65", ios::binary); + if (in.fail()) + throw runtime_error("Failed to read program file"); - vector code{0xa9, 53, 0xA5, 16}; + vector code( + (istreambuf_iterator(in)), + (istreambuf_iterator())); auto machine = make_unique(); machine->load(code, 0x600); - machine->execute(); -// auto memory = make_shared(); -// auto term = make_unique(memory); -// -// term->refresh(); - - - return 0; } \ No newline at end of file diff --git a/test/test-utils.cpp b/test/test-utils.cpp index c5ca35f..0ed04d3 100644 --- a/test/test-utils.cpp +++ b/test/test-utils.cpp @@ -1,7 +1,7 @@ #include "test-utils.h" unique_ptr create_machine(vector code) { - auto machine = make_unique(); + auto machine = make_unique(false); machine->load(code, CODE_LOAD_ADDR); return machine;