- [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:
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];
|
||||
}
|
||||
Reference in New Issue
Block a user