162 lines
4.1 KiB
C++
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];
|
|
}
|
|
}
|