- [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 "z80mem.h"
|
||||
#include "zx_48mem.h"
|
||||
#include "zx_128mem.h"
|
||||
|
||||
uint8_t memory[65536];
|
||||
uint32_t time = 0;
|
||||
@@ -73,10 +74,10 @@ namespace actions
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const uint32_t clock = 3500000;
|
||||
const uint32_t clock = 3500000; // 3546900;
|
||||
const uint32_t update_freq = clock / 10;
|
||||
|
||||
new zx_48mem();
|
||||
new zx_48mem(); // zx_128mem();
|
||||
|
||||
z80dis::loadSymbols();
|
||||
z80::reset();
|
||||
@@ -84,6 +85,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
z80debug::init();
|
||||
//zxscreen::init(SCREEN_MODE_128K);
|
||||
zxscreen::init(SCREEN_MODE_48K);
|
||||
|
||||
ui::menu::init();
|
||||
@@ -116,6 +118,7 @@ int main(int argc, char *argv[])
|
||||
zx_tape::load("fernandomartin.tap");
|
||||
|
||||
if (argc==3) { z80debug::loadngo(argv[1], argv[2]); }
|
||||
//z80debug::stop();
|
||||
|
||||
bool should_exit = false;
|
||||
SDL_Event e;
|
||||
|
||||
16
z80.cpp
16
z80.cpp
@@ -15,8 +15,8 @@ namespace z80
|
||||
bool options[Z80_NUM_OPTIONS] = { true, false };
|
||||
int calls_stacked = 0;
|
||||
|
||||
int (*in_ports[256])(int);
|
||||
void (*out_ports[256])(int, int);
|
||||
int (*in_ports[65536])(int);
|
||||
void (*out_ports[65536])(int, int);
|
||||
|
||||
//#define _rM16(a) (uint16_t*)&memory[a]
|
||||
//#define rM16(a) *_rM16(a)
|
||||
@@ -1118,17 +1118,17 @@ namespace z80
|
||||
|
||||
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)
|
||||
{
|
||||
in_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)
|
||||
|
||||
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;
|
||||
}
|
||||
t_screen++;
|
||||
if (t_screen>=69888) {
|
||||
if (t_screen>=t_states_total) {
|
||||
pixels_draw=0;
|
||||
t_flash++;
|
||||
if (t_flash==16) { t_flash=0; flash = !flash; }
|
||||
@@ -269,7 +269,7 @@ namespace zxscreen
|
||||
t_screen = 0;
|
||||
uint8_t * tmp_ptr = ptr_pixel;
|
||||
ptr_pixel = zx_pixels;
|
||||
refresh(69888, true);
|
||||
refresh(t_states_total, true);
|
||||
ptr_pixel = tmp_ptr;
|
||||
t_screen = tmp;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user