Files
z80/zx_mem.cpp

162 lines
4.1 KiB
C++

#include "zx_mem.h"
#include "stdlib.h"
#include "z80.h"
#include "zx_screen.h"
#define ZX_128MEM_PAGE 0x07
#define ZX_128MEM_SCREEN 0x08
#define ZX_128MEM_ROM 0x10
#define ZX_128MEM_DISPAG 0x20
namespace mem
{
uint8_t mode = ZX_48K;
uint32_t ram_size = 48*1024;
uint32_t rom_size = 16*1024;
uint8_t *ram = nullptr;
uint8_t *rom = nullptr;
uint8_t *slot[8];
bool writable[8];
uint8_t config_128K;
void zx_128_port_out(int port, int val);
void init(uint8_t mode)
{
mem::mode = mode;
if (ram) free(ram);
if (rom) free(rom);
reset();
}
void reset()
{
FILE* f;
switch(mode)
{
case ZX_48K:
ram_size = 48*1024;
ram = (uint8_t*)malloc(ram_size);
for (int i=0; i<ram_size; ++i) ram[i] = 0;
//for (int i=0; i<65536; ++i) tags[i] = MEMTAG_NONE;
rom_size = 16*1024;
rom = (uint8_t*)malloc(rom_size);
f = fopen("48.rom", "rb");
fread(rom, rom_size, 1, f);
fclose(f);
slot[0] = &rom[0*8192]; slot[1] = &rom[1*8192];
slot[2] = &ram[0*8192]; slot[3] = &ram[1*8192];
slot[4] = &ram[2*8192]; slot[5] = &ram[3*8192];
slot[6] = &ram[4*8192]; slot[7] = &ram[5*8192];
writable[0] = writable[1] = false;
for (int i=2;i<8;++i) writable[i] = true;
break;
case ZX_128K:
ram_size = 128*1024;
ram = (uint8_t*)malloc(ram_size);
for (int i=0x0000; i<ram_size; ++i) ram[i] = 0;
rom_size = 32*1024;
rom = (uint8_t*)malloc(rom_size);
f = fopen("128k.rom", "rb");
fread(rom, rom_size, 1, f);
fclose(f);
slot[0] = &rom[0*8192]; slot[1] = &rom[1*8192];
slot[2] = &ram[10*8192]; slot[3] = &ram[11*8192];
slot[4] = &ram[4*8192]; slot[5] = &ram[5*8192];
slot[6] = &ram[0*8192]; slot[7] = &ram[1*8192];
writable[0] = writable[1] = false;
for (int i=2;i<8;++i) writable[i] = true;
z80::connect_port(0x7ffd, 0x8002, nullptr, mem::zx_128_port_out);
break;
}
}
uint8_t readMem(uint16_t address)
{
const uint8_t slot_num = address >> 13;
const uint16_t displacement = address & 0x1fff;
return slot[slot_num][displacement];
}
void writeMem(uint16_t address, uint8_t value)
{
const uint8_t slot_num = address >> 13;
if (!writable[slot_num]) return;
const uint16_t displacement = address & 0x1fff;
slot[slot_num][displacement] = value;
}
void loadMem(uint16_t address, uint16_t len, uint8_t *buffer)
{
}
uint8_t getTag(uint16_t address)
{
return 0;
}
void setTag(uint16_t address, uint8_t value)
{
}
void saveState(FILE* f)
{
fwrite(ram, 0xc000, 1, f);
}
void loadState(FILE* f)
{
fread(ram, 0xc000, 1, f);
}
uint32_t getSize()
{
return 0;
}
uint8_t *rawPtr(uint32_t address)
{
return &ram[address];
}
uint8_t *rawTagPtr(uint32_t address)
{
return nullptr;
}
void zx_128_port_out(int port, int val)
{
if (port != 0x7ffd) return;
if (config_128K & ZX_128MEM_DISPAG) return;
const bool shadow = config_128K & ZX_128MEM_SCREEN;
config_128K = val;
if (config_128K & ZX_128MEM_SCREEN) {
if (!shadow) zxscreen::setBaseAddresses(0x4000*7, 0x1800+0x4000*7);
} else {
if (shadow) zxscreen::setBaseAddresses(0x4000*5, 0x1800+0x4000*5);
}
if (config_128K & ZX_128MEM_ROM) {
slot[0] = &rom[2*8192]; slot[1] = &rom[3*8192];
} else {
slot[0] = &rom[0*8192]; slot[1] = &rom[1*8192];
}
const uint8_t slot3 = (config_128K&ZX_128MEM_PAGE)*2;
slot[6] = &ram[slot3*8192]; slot[7] = &ram[(slot3+1)*8192];
}
}