- [NEW] Implementat el mòdul de memòria per al ZX Spectrum 128K

- Primera prova falla, mirar la conexió al port 0x7ffd, que pareix que no ana.
This commit is contained in:
2024-12-20 13:18:55 +01:00
parent 184389a89e
commit ab476a19b1
5 changed files with 211 additions and 12 deletions

View File

@@ -14,6 +14,7 @@
#include "ui_window.h" #include "ui_window.h"
#include "z80mem.h" #include "z80mem.h"
#include "zx_48mem.h" #include "zx_48mem.h"
#include "zx_128mem.h"
uint8_t memory[65536]; uint8_t memory[65536];
uint32_t time = 0; uint32_t time = 0;
@@ -73,10 +74,10 @@ namespace actions
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
const uint32_t clock = 3500000; const uint32_t clock = 3500000; // 3546900;
const uint32_t update_freq = clock / 10; const uint32_t update_freq = clock / 10;
new zx_48mem(); new zx_48mem(); // zx_128mem();
z80dis::loadSymbols(); z80dis::loadSymbols();
z80::reset(); z80::reset();
@@ -84,6 +85,7 @@ int main(int argc, char *argv[])
SDL_Init(SDL_INIT_EVERYTHING); SDL_Init(SDL_INIT_EVERYTHING);
z80debug::init(); z80debug::init();
//zxscreen::init(SCREEN_MODE_128K);
zxscreen::init(SCREEN_MODE_48K); zxscreen::init(SCREEN_MODE_48K);
ui::menu::init(); ui::menu::init();
@@ -116,6 +118,7 @@ int main(int argc, char *argv[])
zx_tape::load("fernandomartin.tap"); zx_tape::load("fernandomartin.tap");
if (argc==3) { z80debug::loadngo(argv[1], argv[2]); } if (argc==3) { z80debug::loadngo(argv[1], argv[2]); }
//z80debug::stop();
bool should_exit = false; bool should_exit = false;
SDL_Event e; SDL_Event e;

16
z80.cpp
View File

@@ -15,8 +15,8 @@ namespace z80
bool options[Z80_NUM_OPTIONS] = { true, false }; bool options[Z80_NUM_OPTIONS] = { true, false };
int calls_stacked = 0; int calls_stacked = 0;
int (*in_ports[256])(int); int (*in_ports[65536])(int);
void (*out_ports[256])(int, int); void (*out_ports[65536])(int, int);
//#define _rM16(a) (uint16_t*)&memory[a] //#define _rM16(a) (uint16_t*)&memory[a]
//#define rM16(a) *_rM16(a) //#define rM16(a) *_rM16(a)
@@ -1118,17 +1118,17 @@ namespace z80
void reset() void reset()
{ {
z80mem::get()->reset();
rPC = iff1 = iff2 = im = 0;
rAF = rAF2 = rBC = rBC2 = rDE = rDE2 = rHL = rHL2 = rIX = rIY = rSP = 0xffff;
t = 0;
for (int i=0; i<256; ++i) for (int i=0; i<256; ++i)
{ {
in_ports[i] = nullptr; in_ports[i] = nullptr;
out_ports[i] = nullptr; out_ports[i] = nullptr;
} }
z80mem::get()->reset();
rPC = iff1 = iff2 = im = 0;
rAF = rAF2 = rBC = rBC2 = rDE = rDE2 = rHL = rHL2 = rIX = rIY = rSP = 0xffff;
t = 0;
} }
void setClock(uint32_t freq) void setClock(uint32_t freq)

158
zx_128mem.cpp Normal file
View File

@@ -0,0 +1,158 @@
#include "zx_128mem.h"
#include "z80mem.h"
#include "z80.h"
#include "zx_screen.h"
#include <string.h>
#include <stdio.h>
#define ZX_128MEM_PAGE 0x07
#define ZX_128MEM_SCREEN 0x04
#define ZX_128MEM_ROM 0x10
#define ZX_128MEM_DISPAG 0x20
void zx_128_port_out(int port, int val)
{
((zx_128mem*)z80mem::get())->port_out(port, val);
}
zx_128mem::zx_128mem()
{
z80mem::singleton = this;
}
void zx_128mem::port_out(int port, int val)
{
const bool shadow = config & ZX_128MEM_SCREEN;
if (config & ZX_128MEM_DISPAG) return;
config = val;
if (config & ZX_128MEM_SCREEN) {
if (!shadow) zxscreen::setBaseAddresses(0x4000*7, 0x1800+0x4000*7);
} else {
if (shadow) zxscreen::setBaseAddresses(0x4000*5, 0x1800+0x4000*5);
}
}
uint8_t zx_128mem::readMem(uint16_t address)
{
const uint8_t bank = address >> 14;
const uint16_t disp = address & 0x3fff;
switch (bank)
{
case 0:
return rom[disp | ((config & ZX_128MEM_ROM)<<4)];
break;
case 1:
return memory[disp | 0x14000];
break;
case 2:
return memory[address];
break;
case 3:
return memory[disp | (0x4000 * (config&ZX_128MEM_PAGE))];
break;
}
}
void zx_128mem::writeMem(uint16_t address, uint8_t value)
{
const uint8_t bank = address >> 14;
const uint16_t disp = address & 0x3fff;
switch (bank)
{
case 0:
break;
case 1:
memory[disp | 0x14000] = value;
break;
case 2:
memory[address] = value;
break;
case 3:
memory[disp | (0x4000 * (config&ZX_128MEM_PAGE))] = value;
break;
}
}
void zx_128mem::loadMem(uint16_t address, uint16_t len, uint8_t *buffer)
{
memcpy(&memory[address], buffer, len);
}
uint8_t zx_128mem::getTag(uint16_t address)
{
const uint8_t bank = address >> 14;
const uint16_t disp = address & 0x3fff;
switch (bank)
{
case 0:
return romtags[disp | ((config & ZX_128MEM_ROM)<<4)];
break;
case 1:
return tags[disp | 0x14000];
break;
case 2:
return tags[address];
break;
case 3:
return tags[disp | (0x4000 * (config&ZX_128MEM_PAGE))];
break;
}
return tags[address];
}
void zx_128mem::setTag(uint16_t address, uint8_t value)
{
const uint8_t bank = address >> 14;
const uint16_t disp = address & 0x3fff;
switch (bank)
{
case 0:
romtags[disp | ((config & ZX_128MEM_ROM)<<4)] = value;
break;
case 1:
tags[disp | 0x14000] = value;
break;
case 2:
tags[address] = value;
break;
case 3:
tags[disp | (0x4000 * (config&ZX_128MEM_PAGE))] = value;
break;
}
}
void zx_128mem::reset()
{
FILE* f = fopen("128k.rom", "rb");
fread(rom, 1024, 32, f);
fclose(f);
for (int i=0x0000; i<=0x1FFFF; ++i) memory[i] = 0;
for (int i=0; i<131072; ++i) tags[i] = MEMTAG_NONE;
z80::connect_port(0x7ffd, nullptr, zx_128_port_out);
}
void zx_128mem::saveState(FILE *f)
{
fwrite(&memory[0x0000], 131072, 1, f);
}
void zx_128mem::loadState(FILE *f)
{
fread(&memory[0x0000], 131072, 1, f);
}
uint32_t zx_128mem::getSize()
{
return 131072;
}
uint8_t *zx_128mem::rawPtr(uint32_t address)
{
return &memory[address];
}

38
zx_128mem.h Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include "z80mem.h"
void zx_128_port_out(int port, int val);
class zx_128mem : public z80mem
{
public:
zx_128mem();
void port_out(int port, int val);
uint8_t readMem(uint16_t address);
void writeMem(uint16_t address, uint8_t value);
void loadMem(uint16_t address, uint16_t len, uint8_t *buffer);
uint8_t getTag(uint16_t address);
void setTag(uint16_t address, uint8_t value);
void reset();
void saveState(FILE* f);
void loadState(FILE* f);
uint32_t getSize();
uint8_t *rawPtr(uint32_t address);
protected:
uint8_t config;
uint8_t memory[131072];
uint8_t tags[131072];
uint8_t rom[32768];
uint8_t romtags[32768];
};

View File

@@ -251,7 +251,7 @@ namespace zxscreen
pixels_draw+=2; pixels_draw+=2;
} }
t_screen++; t_screen++;
if (t_screen>=69888) { if (t_screen>=t_states_total) {
pixels_draw=0; pixels_draw=0;
t_flash++; t_flash++;
if (t_flash==16) { t_flash=0; flash = !flash; } if (t_flash==16) { t_flash=0; flash = !flash; }
@@ -269,7 +269,7 @@ namespace zxscreen
t_screen = 0; t_screen = 0;
uint8_t * tmp_ptr = ptr_pixel; uint8_t * tmp_ptr = ptr_pixel;
ptr_pixel = zx_pixels; ptr_pixel = zx_pixels;
refresh(69888, true); refresh(t_states_total, true);
ptr_pixel = tmp_ptr; ptr_pixel = tmp_ptr;
t_screen = tmp; t_screen = tmp;
} }