From 184389a89e5c124d83b3d7828e1da404a5716e15 Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Fri, 20 Dec 2024 12:15:26 +0100 Subject: [PATCH] - [NEW] zx_screen preparat per al ZX Spectrum 128k - [NEW] Afegida rom del ZX Spectrum 128K --- 128k.rom | Bin 0 -> 32768 bytes main.cpp | 2 +- z80mem.h | 2 ++ zx_48mem.cpp | 4 ++++ zx_48mem.h | 4 +++- zx_screen.cpp | 48 ++++++++++++++++++++++++++++++++++++------------ zx_screen.h | 7 +++++-- zx_ula.cpp | 2 +- 8 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 128k.rom diff --git a/128k.rom b/128k.rom new file mode 100644 index 0000000000000000000000000000000000000000..1ddee8c967ca8ec1fa9f73a826f5d1b013758ae9 GIT binary patch literal 32768 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 literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp index 236d50f..b897ea4 100644 --- a/main.cpp +++ b/main.cpp @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) SDL_Init(SDL_INIT_EVERYTHING); z80debug::init(); - zxscreen::init(0x4000, 0x5800); + zxscreen::init(SCREEN_MODE_48K); ui::menu::init(); ui::menu::setexitcallback(actions::exitMenu); diff --git a/z80mem.h b/z80mem.h index b1a50c6..b41a19e 100644 --- a/z80mem.h +++ b/z80mem.h @@ -34,6 +34,8 @@ class z80mem virtual void loadState(FILE* f) = 0; virtual uint32_t getSize() = 0; + + virtual uint8_t *rawPtr(uint32_t address) = 0; protected: diff --git a/zx_48mem.cpp b/zx_48mem.cpp index 24afe3d..fa1e612 100644 --- a/zx_48mem.cpp +++ b/zx_48mem.cpp @@ -59,3 +59,7 @@ uint32_t zx_48mem::getSize() return 65536; } +uint8_t *zx_48mem::rawPtr(uint32_t address) +{ + return &memory[address]; +} \ No newline at end of file diff --git a/zx_48mem.h b/zx_48mem.h index b1fa26f..5309b20 100644 --- a/zx_48mem.h +++ b/zx_48mem.h @@ -20,7 +20,9 @@ class zx_48mem : public z80mem void loadState(FILE* f); uint32_t getSize(); - + + uint8_t *rawPtr(uint32_t address); + protected: uint8_t memory[65536]; diff --git a/zx_screen.cpp b/zx_screen.cpp index ba96ca9..1d8ec28 100644 --- a/zx_screen.cpp +++ b/zx_screen.cpp @@ -19,6 +19,12 @@ namespace zxscreen SDL_Texture *tex = nullptr; SDL_Texture *uitex = nullptr; + int mode = SCREEN_MODE_48K; + + uint32_t t_states_total = 69888; + uint32_t t_states_per_scanline = 224; + uint32_t vsync_lines = 16; + uint8_t zoom = 1; bool fullscreen = false; bool full_refresh = true; @@ -36,8 +42,8 @@ namespace zxscreen uint16_t pixel_base_addr = 0x4000; uint16_t color_base_addr = 0x5800; - uint16_t pixel_addr[69888]; - uint16_t color_addr[69888]; + uint16_t *pixel_addr = nullptr; //[69888]; + uint16_t *color_addr = nullptr; //[69888]; uint8_t zx_pixels[352*296]; uint8_t *ptr_pixel = zx_pixels; @@ -48,16 +54,21 @@ namespace zxscreen { uint32_t count = 0; + if (pixel_addr) free(pixel_addr); + if (color_addr) free(color_addr); + pixel_addr = (uint16_t*)malloc(t_states_total*sizeof(uint16_t)); + color_addr = (uint16_t*)malloc(t_states_total*sizeof(uint16_t)); + uint16_t *ptr_pixel = pixel_addr; uint16_t *ptr_color = color_addr; // vsync - for (int i=0; i<224*16;++i) { *(ptr_pixel++) = 0; *(ptr_color++) = SCREEN_SYNC; } + for (int i=0; irawPtr(pixel_base_addr); + const uint8_t* color_mem = z80mem::get()->rawPtr(color_base_addr); const uint8_t border_color = zx_ula::get_border_color(); for (int i=0;ireadMem(color_base_addr + color_addr[t_screen]); + uint8_t color = *(color_mem + color_addr[t_screen]); // z80mem::get()->readMem(color_base_addr + color_addr[t_screen]); uint8_t c1 = color&0x7, c2 = (color>>3)&0x7; if ((color&0x80) && flash) { c1=c2; c2=color&0x7; } if ((color&0x40)) { c1 |= 0x8; c2 |= 0x8; } uint16_t address = /*(0x4000) |*/ (pixel_addr[t_screen]&0x1FFF); uint8_t mask = 1 << (pixel_addr[t_screen]>>13); - uint8_t block = z80mem::get()->readMem(pixel_base_addr + address); + uint8_t block = *(pixel_mem + address); // z80mem::get()->readMem(pixel_base_addr + address); *(ptr_pixel++)=(block&mask) ? c1 : c2; mask>>=1; *(ptr_pixel++)=(block&mask) ? c1 : c2; diff --git a/zx_screen.h b/zx_screen.h index 6b4790e..57e6f4a 100644 --- a/zx_screen.h +++ b/zx_screen.h @@ -1,10 +1,13 @@ #pragma once #include +#define SCREEN_MODE_48K 0 +#define SCREEN_MODE_128K 1 + namespace zxscreen { - void init(const uint16_t pixeladdr, const uint16_t coloraddr); - void setBaseAddresses(const uint16_t pixeladdr, const uint16_t coloraddr); + void init(int mode); + void setBaseAddresses(const uint32_t pixeladdr, const uint32_t coloraddr); void reinit(); void focus(); void refresh(const uint32_t dt, const bool full=false); diff --git a/zx_ula.cpp b/zx_ula.cpp index 6b98bec..b41c3cd 100644 --- a/zx_ula.cpp +++ b/zx_ula.cpp @@ -1,5 +1,5 @@ #include "zx_ula.h" -#include +#include "z80.h" #include #define AUDIO_BUFFER_SIZE 2048