- [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:
7
main.cpp
7
main.cpp
@@ -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
16
z80.cpp
@@ -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
158
zx_128mem.cpp
Normal 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
38
zx_128mem.h
Normal 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];
|
||||||
|
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user