From e0b7fe59f7ad6d48ecea5de15ced7a4524af107a Mon Sep 17 00:00:00 2001 From: Tony Di Nucci Date: Thu, 25 Apr 2019 19:43:04 +0100 Subject: [PATCH] Improved graphics performance (callback on memory write) --- sample/test.s | 49 +++++++++++++++++++ src/machine/machine.cpp | 4 +- src/machine/memory.cpp | 10 ++++ src/machine/memory.h | 4 ++ src/machine/terminal.cpp | 35 +++++++++---- src/machine/terminal.h | 3 +- src/main.cpp | 6 ++- .../handler/jump-opcode-handler-container.cpp | 2 +- 8 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 sample/test.s diff --git a/sample/test.s b/sample/test.s new file mode 100644 index 0000000..33df0d1 --- /dev/null +++ b/sample/test.s @@ -0,0 +1,49 @@ +; head position +ldx #$00 +stx $00 ; head position low +ldx #$e0 +stx $01 ; head position high + +; colours +ldx #$f0 +stx $04 ; paint colour +ldx #$00 +stx $05 ; rubber colour + +jsr one +jsr two +jsr three +jsr four + +clv +bvc end + +one + lda #$50 + ldx #$00 + sta ($00, x) + inc $00 + rts + +two + lda #$F0 + ldx #$00 + sta ($00, x) + inc $00 + rts + +three + lda #$FF + ldx #$00 + sta ($00, x) + inc $00 + rts + +four + lda #$af + ldx #$00 + sta ($00, x) + inc $00 + rts + +end diff --git a/src/machine/machine.cpp b/src/machine/machine.cpp index a635dc2..bbe2e96 100644 --- a/src/machine/machine.cpp +++ b/src/machine/machine.cpp @@ -77,8 +77,8 @@ namespace emu_6502 { auto byte = read_program_byte(); opcode_handler_dir->execute(byte, machine); - if (terminal_initialised) - terminal->refresh(); +// if (terminal_initialised) +// terminal->refresh(); } } }; diff --git a/src/machine/memory.cpp b/src/machine/memory.cpp index 1bd1776..1047acd 100644 --- a/src/machine/memory.cpp +++ b/src/machine/memory.cpp @@ -7,6 +7,7 @@ namespace emu_6502 { Memory::Memory() { memory = vector(0xFFFF); + on_write_callbacks = {}; } uint8_t Memory::get_at(uint16_t address) { @@ -15,6 +16,11 @@ namespace emu_6502 { void Memory::set_at(uint16_t address, uint8_t value) { memory.at(address) = value; + + for (auto& cb : on_write_callbacks) { + pair address_value{address, value}; + cb(address_value); + } } uint8_t Memory::get_from_page(uint8_t page, uint8_t offset) { @@ -24,4 +30,8 @@ namespace emu_6502 { void Memory::set_on_page(uint8_t page, uint8_t offset, uint8_t value) { set_at(get_page_offset(page) + offset, value); } + + void Memory::register_callback(function)> callback) { + on_write_callbacks.push_back(callback); + } } \ No newline at end of file diff --git a/src/machine/memory.h b/src/machine/memory.h index 81bd9e7..0ca9e32 100644 --- a/src/machine/memory.h +++ b/src/machine/memory.h @@ -3,6 +3,7 @@ #include #include +#include using namespace std; @@ -10,6 +11,7 @@ namespace emu_6502 { class Memory { private: vector memory; + vector)>> on_write_callbacks; uint16_t get_page_offset(uint8_t page); @@ -23,6 +25,8 @@ namespace emu_6502 { uint8_t get_from_page(uint8_t page, uint8_t offset); void set_on_page(uint8_t page, uint8_t offset, uint8_t value); + + void register_callback(function)> callback); }; } diff --git a/src/machine/terminal.cpp b/src/machine/terminal.cpp index f129666..616ccc9 100644 --- a/src/machine/terminal.cpp +++ b/src/machine/terminal.cpp @@ -15,6 +15,8 @@ namespace emu_6502 { for (auto i = LOW_ADDR; i <= HIGH_ADDR; i++) { memory.set_at(i, 0); } + + memory.register_callback([this](pair addr_val) { on_memory_written(addr_val); }); } Terminal::~Terminal() { @@ -23,17 +25,32 @@ namespace emu_6502 { SDL_Quit(); } - void Terminal::refresh() { - int x, y = 0; - for (auto i = LOW_ADDR; i <= HIGH_ADDR; i++) { - x = (i - LOW_ADDR) % WIDTH; - y = (i - LOW_ADDR) / HEIGHT; +// void Terminal::refresh() { +// int x, y = 0; +// for (auto i = LOW_ADDR; i <= HIGH_ADDR; i++) { +// x = (i - LOW_ADDR) % WIDTH; +// y = (i - LOW_ADDR) / HEIGHT; +// +// draw_pixel(x, y, memory.get_at(i)); +// } +// +// SDL_RenderPresent(renderer); +// SDL_Delay(150); +// } - draw_pixel(x, y, memory.get_at(i)); + void Terminal::on_memory_written(pair address_value) { + uint16_t address = address_value.first; + + if (address >= LOW_ADDR && address <= HIGH_ADDR) { + uint8_t colour = address_value.second; + int x = (address - LOW_ADDR) % WIDTH; + int y = (address - LOW_ADDR) / HEIGHT; + + draw_pixel(x, y, colour); + + SDL_RenderPresent(renderer); + SDL_Delay(5); } - - SDL_RenderPresent(renderer); - //SDL_Delay(20); } void Terminal::draw_pixel(int x, int y, uint8_t colour) { diff --git a/src/machine/terminal.h b/src/machine/terminal.h index cd901c2..4b6e638 100644 --- a/src/machine/terminal.h +++ b/src/machine/terminal.h @@ -23,6 +23,7 @@ namespace emu_6502 { SDL_Renderer* renderer; SDL_Window* window; + void on_memory_written(pair address_value); void draw_pixel(int x, int y, uint8_t colour); public: @@ -31,7 +32,7 @@ namespace emu_6502 { Terminal& operator=(const Terminal&) = delete; ~Terminal(); - void refresh(); + //void refresh(); }; } diff --git a/src/main.cpp b/src/main.cpp index a928e6e..64dccdb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,7 +12,9 @@ using namespace std; using namespace emu_6502; int main() { - ifstream in("/home/tony/CLionProjects/6502-emulator/sample/a.o65", ios::binary); + string binary = "/home/tony/CLionProjects/6502-emulator/sample/a.o65"; + //string binary = "/home/tony/Downloads/6502_functional_test.bin"; + ifstream in(binary, ios::binary); if (in.fail()) throw runtime_error("Failed to read program file"); @@ -21,7 +23,7 @@ int main() { (istreambuf_iterator())); auto machine = make_unique(); - machine->load(code, 0x1000); + machine->load(code, 0x600); machine->execute(); return 0; diff --git a/src/opcode/handler/jump-opcode-handler-container.cpp b/src/opcode/handler/jump-opcode-handler-container.cpp index 7598044..5a21c03 100644 --- a/src/opcode/handler/jump-opcode-handler-container.cpp +++ b/src/opcode/handler/jump-opcode-handler-container.cpp @@ -38,7 +38,7 @@ namespace emu_6502 { auto low_byte = machine.get_stack().pop(); auto high_byte = machine.get_stack().pop(); - uint16_t return_address = (high_byte << 8) + low_byte + 1; + uint16_t return_address = (high_byte << 8) + low_byte;// + 1; machine.get_cpu().get_pc().set_value(return_address); } } \ No newline at end of file