Spectrum WIP (add 128K) - AY8910 is producing scratchy sampled audio, other AY sound is ok - is it our AY8910 core?

This commit is contained in:
Barry Harris 2018-06-07 19:56:45 +00:00
parent 2a79ed3e56
commit 0e10a77534

View File

@ -6,6 +6,7 @@
#include "z80_intf.h"
#include "bitswap.h"
#include "dac.h"
#include "ay8910.h"
#define SPEC_NO_SNAPSHOT 0
#define SPEC_SNAPSHOT_SNA 1
@ -29,19 +30,24 @@ static struct BurnRomInfo emptyRomDesc[] = {
{ "", 0, 0, 0 },
};
static UINT8 DrvInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static UINT8 DrvInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static UINT8 DrvInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static UINT8 DrvInputPort3[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static UINT8 DrvInputPort4[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static UINT8 DrvInputPort5[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static UINT8 DrvInputPort6[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static UINT8 DrvInputPort7[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static UINT8 DrvInputPort0[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard - Caps - V
static UINT8 DrvInputPort1[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard - A - G
static UINT8 DrvInputPort2[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard - Q - T
static UINT8 DrvInputPort3[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard - 1 - 5
static UINT8 DrvInputPort4[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard - 6 - 0
static UINT8 DrvInputPort5[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard - Y - P
static UINT8 DrvInputPort6[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard - H - Enter
static UINT8 DrvInputPort7[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard - B - Space
static UINT8 DrvInputPort8[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // kempston
static UINT8 DrvInputPort9[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // interface 2 - joystick 1
static UINT8 DrvInputPort10[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // interface 2 - joystick 2
static UINT8 DrvInputPort11[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard (128K) Extra Keys
static UINT8 DrvInputPort12[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard (128K) Extra Keys
static UINT8 DrvInputPort13[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard (128K) Extra Keys
static UINT8 DrvInputPort14[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard (128K) Extra Keys
static UINT8 DrvInputPort15[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // keyboard (128K) Extra Keys
static UINT8 DrvDip[2] = {0, 0};
static UINT8 DrvInput[11] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static UINT8 DrvInput[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static UINT8 DrvReset = 0;
static UINT8 *Mem = NULL;
@ -49,6 +55,7 @@ static UINT8 *MemEnd = NULL;
static UINT8 *RamStart = NULL;
static UINT8 *RamEnd = NULL;
static UINT8 *DrvZ80Rom = NULL;
static UINT8 *DrvVideoRam = NULL;
static UINT8 *DrvSnapshotData = NULL;
static UINT8 *DrvZ80Ram = NULL;
static UINT32 *DrvPalette = NULL;
@ -71,7 +78,12 @@ static UINT32 nPreviousBorderX = 0;
static UINT32 nPreviousBorderY = 0;
static UINT8 nPortFEData = 0;
static INT32 DrvIsSpec128 = 0;
static INT32 nPort7FFDData = -1;
static void spectrum_UpdateScreenBitmap(bool);
static void spectrum_UpdateBorderBitmap();
static void spectrum_128_update_memory();
static struct BurnInputInfo DrvInputList[] =
{
@ -134,6 +146,27 @@ static struct BurnInputInfo DrvInputList[] =
{"9" , BIT_DIGITAL , DrvInputPort4 + 1, "keyb_9" },
{"0" , BIT_DIGITAL , DrvInputPort4 + 0, "keyb_0" },
{"EDIT" , BIT_DIGITAL , DrvInputPort11 + 0, "keyb_insert" },
{"CAPS LOCK" , BIT_DIGITAL , DrvInputPort11 + 1, "keyb_caps_lock" },
{"TRUE VID" , BIT_DIGITAL , DrvInputPort11 + 2, "keyb_home" },
{"INV VID" , BIT_DIGITAL , DrvInputPort11 + 3, "keyb_end" },
{"Cursor Left" , BIT_DIGITAL , DrvInputPort11 + 4, "keyb_left" },
{"DEL" , BIT_DIGITAL , DrvInputPort12 + 0, "keyb_backspace" },
{"GRAPH" , BIT_DIGITAL , DrvInputPort12 + 1, "keyb_left_alt" },
{"Cursor Right" , BIT_DIGITAL , DrvInputPort12 + 2, "keyb_right" },
{"Cursor Up" , BIT_DIGITAL , DrvInputPort12 + 3, "keyb_up" },
{"Cursor Down" , BIT_DIGITAL , DrvInputPort12 + 4, "keyb_down" },
{"BREAK" , BIT_DIGITAL , DrvInputPort13 + 0, "keyb_pause" },
{"EXT MODE" , BIT_DIGITAL , DrvInputPort13 + 1, "keyb_left_ctrl" },
{"\"" , BIT_DIGITAL , DrvInputPort14 + 0, "keyb_apost" },
{";" , BIT_DIGITAL , DrvInputPort14 + 1, "keyb_colon" },
{"." , BIT_DIGITAL , DrvInputPort15 + 0, "keyb_stop" },
{"," , BIT_DIGITAL , DrvInputPort15 + 1, "keyb_comma" },
{"Reset" , BIT_DIGITAL , &DrvReset , "reset" },
{"Dip 1" , BIT_DIPSWITCH, DrvDip + 0 , "dip" },
};
@ -142,7 +175,7 @@ STDINPUTINFO(Drv)
static inline void DrvMakeInputs()
{
DrvInput[0] = DrvInput[1] = DrvInput[2] = DrvInput[3] = DrvInput[4] = DrvInput[5] = DrvInput[6] = DrvInput[7] = DrvInput[9] = DrvInput[10] = 0x1f;
DrvInput[0] = DrvInput[1] = DrvInput[2] = DrvInput[3] = DrvInput[4] = DrvInput[5] = DrvInput[6] = DrvInput[7] = DrvInput[9] = DrvInput[10] = DrvInput[11] = DrvInput[12] = DrvInput[13] = DrvInput[14] = DrvInput[15] = 0x1f;
DrvInput[8] = 0x00;
@ -158,17 +191,22 @@ static inline void DrvMakeInputs()
DrvInput[8] |= (DrvInputPort8[i] & 1) << i;
DrvInput[9] -= (DrvInputPort9[i] & 1) << i;
DrvInput[10] -= (DrvInputPort10[i] & 1) << i;
DrvInput[11] -= (DrvInputPort11[i] & 1) << i;
DrvInput[12] -= (DrvInputPort12[i] & 1) << i;
DrvInput[13] -= (DrvInputPort13[i] & 1) << i;
DrvInput[14] -= (DrvInputPort14[i] & 1) << i;
DrvInput[15] -= (DrvInputPort15[i] & 1) << i;
}
}
static struct BurnDIPInfo DrvDIPList[]=
{
// Default Values
{46, 0xff, 0xff, 0x00, NULL },
{72, 0xff, 0xff, 0x00, NULL },
{0 , 0xfe, 0 , 2 , "Hardware Version" },
{46, 0x01, 0x80, 0x00, "Issue 2" },
{46, 0x01, 0x80, 0x80, "Issue 3" },
{72, 0x01, 0x80, 0x00, "Issue 2" },
{72, 0x01, 0x80, 0x80, "Issue 3" },
};
STDDIPINFO(Drv)
@ -200,7 +238,9 @@ INT32 SpectrumGetZipName(char** pszName, UINT32 i)
// remove leader
INT32 offset = 0;
if (pszGameName[0] == 's' && pszGameName[1] == '4' && pszGameName[2] == '8' && pszGameName[3] == '_') offset = 4;
if (pszGameName[0] == 's' && pszGameName[1] == '1' && pszGameName[2] == '2' && pszGameName[3] == '8' && pszGameName[4] == '_') offset = 5;
if (!strcmp(pszGameName, "spectrum")) offset = 0;
if (!strcmp(pszGameName, "spec128")) offset = 0;
memset(szFilename, 0, MAX_PATH);
for (UINT32 j = 0; j < strlen(pszGameName); j++) {
@ -219,15 +259,23 @@ static struct BurnRomInfo SpectrumRomDesc[] = {
STD_ROM_PICK(Spectrum)
STD_ROM_FN(Spectrum)
static struct BurnRomInfo Spec128RomDesc[] = {
{ "zx128_0.rom", 0x04000, 0xe76799d2, BRF_BIOS },
{ "zx128_1.rom", 0x04000, 0xb96a36be, BRF_BIOS },
};
STD_ROM_PICK(Spec128)
STD_ROM_FN(Spec128)
static INT32 MemIndex()
{
UINT8 *Next; Next = Mem;
DrvZ80Rom = Next; Next += 0x04000;
DrvSnapshotData = Next; Next += 0x10000;
DrvZ80Rom = Next; Next += 0x08000;
DrvSnapshotData = Next; Next += 0x20000;
RamStart = Next;
DrvZ80Ram = Next; Next += 0x0c000;
DrvZ80Ram = Next; Next += 0x20000;
RamEnd = Next;
DrvPalette = (UINT32*)Next; Next += 0x00010 * sizeof(UINT32);
@ -377,14 +425,22 @@ static INT32 spectrum_identify_z80(UINT32 SnapshotSize)
return SPEC_Z80_SNAPSHOT_INVALID;
}
static void DrvWriteByte(UINT16 addr, UINT8 data)
static void DrvWriteByte(UINT32 addr, UINT8 data)
{
if (addr >= 0x4000) {
DrvZ80Ram[addr - 0x4000] = data;
}
}
static void z80_decompress_block(UINT8 *source, UINT16 dest, UINT16 size)
static void update_paging()
{
// this will be different for +2/+3
ZetOpen(0);
spectrum_128_update_memory();
ZetClose();
}
static void z80_decompress_block(UINT8 *source, UINT32 dest, UINT16 size)
{
UINT8 ch;
INT32 i;
@ -560,7 +616,6 @@ static void DrvLoadZ80Snapshot()
bprintf(PRINT_NORMAL, _T("Not compressed\n"));
//for (i = 0; i < 49152; i++) space.write_byte(i + 16384, DrvSnapshotData[30 + i]);
} else {
bprintf(PRINT_NORMAL, _T("Compressed\n"));
z80_decompress_block(DrvSnapshotData + 30, 16384, 49152);
}
} else {
@ -573,18 +628,14 @@ static void DrvLoadZ80Snapshot()
hi = DrvSnapshotData[33] & 0x0ff;
ZetSetPC(0, (hi << 8) | lo);
/* if ((z80_type == SPEC_Z80_SNAPSHOT_128K) || ((z80_type == SPEC_Z80_SNAPSHOT_TS2068) && !strcmp(machine().system().name,"ts2068")))
{
ay8910_device *ay8912 = subdevice<ay8910_device>("ay8912");
// Only set up sound registers for 128K machine or TS2068!
for (i = 0; i < 16; i++)
{
ay8912->address_w(generic_space(), 0, i);
ay8912->data_w(generic_space(), 0, snapdata[39 + i]);
// if ((z80_type == SPEC_Z80_SNAPSHOT_128K) || ((z80_type == SPEC_Z80_SNAPSHOT_TS2068) && !strcmp(machine().system().name,"ts2068")))
if (z80_type == SPEC_Z80_SNAPSHOT_128K) {
for (INT32 i = 0; i < 16; i++) {
AY8910Write(0, 1, i);
AY8910Write(0, 0, DrvSnapshotData[39 + i]);
}
ay8912->address_w(generic_space(), 0, snapdata[38]);
}*/
AY8910Write(0, 1, DrvSnapshotData[38]);
}
pSource = DrvSnapshotData + header_size;
@ -600,7 +651,7 @@ static void DrvLoadZ80Snapshot()
length = (pSource[0] & 0x0ff) | ((pSource[1] & 0x0ff) << 8);
page = pSource[2];
if (z80_type == SPEC_Z80_SNAPSHOT_48K || z80_type == SPEC_Z80_SNAPSHOT_TS2068) {
switch (page) {
case 4: Dest = 0x08000; break;
@ -609,12 +660,8 @@ static void DrvLoadZ80Snapshot()
default: Dest = 0; break;
}
} else {
// 3 = bank 0, 4 = bank 1 ... 10 = bank 7
if ((page >= 3) && (page <= 10)) {
// Page the appropriate bank into 0xc000 - 0xfff
//m_port_7ffd_data = page - 3;
//update_paging();
Dest = 0x0c000;
Dest = ((page - 3) * 0x4000) + 0x4000;
} else {
// Other values correspond to ROM pages
Dest = 0x0;
@ -623,13 +670,10 @@ static void DrvLoadZ80Snapshot()
if (Dest != 0) {
if (length == 0x0ffff) {
// block is uncompressed
bprintf(PRINT_NORMAL, _T("Not compressed\n"));
//for (i = 0; i < 16384; i++) space.write_byte(i + Dest, pSource[i]);
} else {
bprintf(PRINT_NORMAL, _T("Compressed\n"));
z80_decompress_block(&pSource[3], Dest, 16384);
}
}
@ -639,13 +683,12 @@ static void DrvLoadZ80Snapshot()
}
while ((pSource - DrvSnapshotData) < SnapshotSize);
/*if ((m_port_7ffd_data != -1) && (z80_type != SPEC_Z80_SNAPSHOT_48K))
{
if ((nPort7FFDData != -1) && (z80_type != SPEC_Z80_SNAPSHOT_48K)) {
// Set up paging
m_port_7ffd_data = (snapdata[35] & 0x0ff);
nPort7FFDData = (DrvSnapshotData[35] & 0x0ff);
update_paging();
}
if ((z80_type == SPEC_Z80_SNAPSHOT_48K) && !strcmp(machine().system().name,"ts2068"))
/*if ((z80_type == SPEC_Z80_SNAPSHOT_48K) && !strcmp(machine().system().name,"ts2068"))
{
m_port_f4_data = 0x03;
m_port_ff_data = 0x00;
@ -668,12 +711,21 @@ static INT32 DrvDoReset()
DACReset();
if (DrvIsSpec128) AY8910Reset(0);
nPreviousScreenX = 0;
nPreviousScreenY = 0;
nPreviousBorderX = 0;
nPreviousBorderY = 0;
nPort7FFDData = 0;
nPortFEData = 0;
if (DrvIsSpec128) {
ZetOpen(0);
spectrum_128_update_memory();
ZetClose();
}
if (nActiveSnapshotType == SPEC_SNAPSHOT_SNA) DrvLoadSNASnapshot();
if (nActiveSnapshotType == SPEC_SNAPSHOT_Z80) DrvLoadZ80Snapshot();
@ -728,19 +780,19 @@ static UINT8 __fastcall DrvZ80PortRead(UINT16 a)
}
bprintf(PRINT_NORMAL, _T("Read Port %x\n"), a);
return (nScanline < 193) ? DrvZ80Ram[(nScanline & 0xf8) << 2] : 0xff;
return (nScanline < 193) ? DrvVideoRam[(nScanline & 0xf8) << 2] : 0xff;
}
UINT8 lines = a >> 8;
UINT8 data = 0xff;
int cs_extra1 = 0x1f;//m_io_plus0.read_safe(0x1f) & 0x1f;
int cs_extra2 = 0x1f;//m_io_plus1.read_safe(0x1f) & 0x1f;
int cs_extra3 = 0x1f;//m_io_plus2.read_safe(0x1f) & 0x1f;
int ss_extra1 = 0x1f;//m_io_plus3.read_safe(0x1f) & 0x1f;
int ss_extra2 = 0x1f;//m_io_plus4.read_safe(0x1f) & 0x1f;
int joy1 = 0x1f;//m_io_joy1.read_safe(0x1f) & 0x1f;
int joy2 = 0x1f;//m_io_joy2.read_safe(0x1f) & 0x1f;
INT32 cs_extra1 = 0x1f;//m_io_plus0.read_safe(0x1f) & 0x1f;
INT32 cs_extra2 = 0x1f;//m_io_plus1.read_safe(0x1f) & 0x1f;
INT32 cs_extra3 = 0x1f;//m_io_plus2.read_safe(0x1f) & 0x1f;
INT32 ss_extra1 = 0x1f;//m_io_plus3.read_safe(0x1f) & 0x1f;
INT32 ss_extra2 = 0x1f;//m_io_plus4.read_safe(0x1f) & 0x1f;
INT32 joy1 = 0x1f;//m_io_joy1.read_safe(0x1f) & 0x1f;
INT32 joy2 = 0x1f;//m_io_joy2.read_safe(0x1f) & 0x1f;
// keys: Caps - V
if ((lines & 1) == 0) {
@ -825,6 +877,177 @@ static void __fastcall DrvZ80PortWrite(UINT16 a, UINT8 d)
}
}
static void spectrum_128_update_memory()
{
INT32 ram_page = nPort7FFDData & 0x07;
ZetMapArea(0xc000, 0xffff, 0, DrvZ80Ram + (ram_page << 14));
ZetMapArea(0xc000, 0xffff, 1, DrvZ80Ram + (ram_page << 14));
ZetMapArea(0xc000, 0xffff, 2, DrvZ80Ram + (ram_page << 14));
if (BIT(nPort7FFDData, 3)) {
DrvVideoRam = DrvZ80Ram + (7 << 14);
} else {
DrvVideoRam = DrvZ80Ram + (5 << 14);
}
}
static UINT8 __fastcall DrvSpec128Z80Read(UINT16 a)
{
if (a < 0x4000) {
INT32 ROMSelection = BIT(nPort7FFDData, 4);
return DrvZ80Rom[(ROMSelection << 14) + a];
}
switch (a) {
default: {
bprintf(PRINT_NORMAL, _T("Z80 Read => %04X\n"), a);
}
}
return 0;
}
static void __fastcall DrvSpec128Z80Write(UINT16 a, UINT8 d)
{
if (a <= 0x4000) return;
switch (a) {
default: {
bprintf(PRINT_NORMAL, _T("Z80 Write => %04X, %02X\n"), a, d);
}
}
}
static UINT8 __fastcall DrvSpec128Z80PortRead(UINT16 a)
{
if ((a & 0xff) != 0xfe) {
if ((a & 0xff) == 0x1f) {
// kempston
return DrvInput[8] & 0x1f;
}
if (a == 0xfffd) {
return AY8910Read(0);
}
bprintf(PRINT_NORMAL, _T("Read Port %x\n"), a);
return (nScanline < 193) ? DrvVideoRam[0x1800 | ((nScanline & 0xf8) << 2)] : 0xff;
}
UINT8 lines = a >> 8;
UINT8 data = 0xff;
INT32 cs_extra1 = DrvInput[11] & 0x1f;
INT32 cs_extra2 = DrvInput[12] & 0x1f;
INT32 cs_extra3 = DrvInput[13] & 0x1f;
INT32 ss_extra1 = DrvInput[14] & 0x1f;
INT32 ss_extra2 = DrvInput[15] & 0x1f;
INT32 joy1 = 0x1f;//m_io_joy1.read_safe(0x1f) & 0x1f;
INT32 joy2 = 0x1f;//m_io_joy2.read_safe(0x1f) & 0x1f;
// keys: Caps - V
if ((lines & 1) == 0) {
data &= DrvInput[0];
// CAPS for extra keys
if (cs_extra1 != 0x1f || cs_extra2 != 0x1f || cs_extra3 != 0x1f) data &= ~0x01;
}
// keys: A - G
if ((lines & 2) == 0) data &= DrvInput[1];
// keys: Q - T
if ((lines & 4) == 0) data &= DrvInput[2];
// keys 1 - 5
if ((lines & 8) == 0) data &= DrvInput[3] & cs_extra1 & joy2;
// keys: 6 - 0
if ((lines & 16) == 0) data &= DrvInput[4] & cs_extra2 & joy1;
// keys: Y - P
if ((lines & 32) == 0) data &= DrvInput[5] & ss_extra1;
// keys: H - Enter
if ((lines & 64) == 0) data &= DrvInput[6];
// keys: B - Space
if ((lines & 128) == 0) {
data &= DrvInput[7] & cs_extra3 & ss_extra2;
// SYMBOL SHIFT for extra keys
if (ss_extra1 != 0x1f || ss_extra2 != 0x1f) data &= ~0x02;
}
data |= (0xe0); // Set bits 5-7 - as reset above
// cassette input from wav
/*if (m_cassette->input() > 0.0038) {
data &= ~0x40;
}*/
// expansion port
data &= DrvIntf2PortFERead(a);
// Issue 2 Spectrums default to having bits 5, 6 & 7 set. Issue 3 Spectrums default to having bits 5 & 7 set and bit 6 reset.
if (DrvDip[0] & 0x80) data ^= (0x40);
return data;
}
static void __fastcall DrvSpec128Z80PortWrite(UINT16 a, UINT8 d)
{
if (a == 0x7ffd) {
if (nPort7FFDData & 0x20) return;
if ((nPort7FFDData ^ d) & 0x08) spectrum_UpdateScreenBitmap(false);
nPort7FFDData = d;
spectrum_128_update_memory();
return;
}
if ((a & 0xff) == 0xfe) {
UINT8 Changed = nPortFEData ^ d;
if ((Changed & 0x07) != 0) {
spectrum_UpdateBorderBitmap();
}
if ((Changed & (1 << 4)) !=0 ) {
DACSignedWrite(0, BIT(d, 4) * 0x10);
}
if ((Changed & (1 << 3)) != 0) {
// write cassette data
//m_cassette->output((data & (1<<3)) ? -1.0 : +1.0);
bprintf(PRINT_IMPORTANT, _T("Write Cassette Data %x\n"), d);
}
nPortFEData = d;
return;
}
switch (a) {
case 0xbefd:
case 0xbffd: {
AY8910Write(0, 1, d);
break;
}
case 0xfffd: {
AY8910Write(0, 0, d);
break;
}
default: {
bprintf(PRINT_NORMAL, _T("Z80 Port Write => %02X, %04X\n"), a, d);
}
}
}
static INT32 SpectrumInit(INT32 nSnapshotType)
{
nActiveSnapshotType = nSnapshotType;
@ -859,7 +1082,7 @@ static INT32 SpectrumInit(INT32 nSnapshotType)
ZetClose();
DACInit(0, 0, 0, DrvSyncDAC);
DACSetRoute(0, 1.00, BURN_SND_ROUTE_BOTH);
DACSetRoute(0, 0.50, BURN_SND_ROUTE_BOTH);
BurnSetRefreshRate(50.0);
@ -871,6 +1094,69 @@ static INT32 SpectrumInit(INT32 nSnapshotType)
DrvNumScanlines = 312;
DrvNumCylesPerScanline = 224;
DrvVBlankScanline = 310;
nPort7FFDData = -1;
DrvVideoRam = DrvZ80Ram;
DrvDoReset();
return 0;
}
static INT32 Spectrum128Init(INT32 nSnapshotType)
{
nActiveSnapshotType = nSnapshotType;
INT32 nRet = 0, nLen;
Mem = NULL;
MemIndex();
nLen = MemEnd - (UINT8 *)0;
if ((Mem = (UINT8 *)BurnMalloc(nLen)) == NULL) return 1;
memset(Mem, 0, nLen);
MemIndex();
if (nSnapshotType == SPEC_NO_SNAPSHOT) {
nRet = BurnLoadRom(DrvZ80Rom + 0x00000, 0, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(DrvZ80Rom + 0x04000, 1, 1); if (nRet != 0) return 1;
} else {
nRet = BurnLoadRom(DrvSnapshotData + 0x00000, 0, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(DrvZ80Rom + 0x00000, 0x80, 1); if (nRet != 0) return 1;
nRet = BurnLoadRom(DrvZ80Rom + 0x04000, 0x81, 1); if (nRet != 0) return 1;
}
ZetInit(0);
ZetOpen(0);
ZetSetReadHandler(DrvSpec128Z80Read);
ZetSetWriteHandler(DrvSpec128Z80Write);
ZetSetInHandler(DrvSpec128Z80PortRead);
ZetSetOutHandler(DrvSpec128Z80PortWrite);
ZetMapArea(0x4000, 0x7fff, 0, DrvZ80Ram + (5 << 14) );
ZetMapArea(0x4000, 0x7fff, 1, DrvZ80Ram + (5 << 14) );
ZetMapArea(0x4000, 0x7fff, 2, DrvZ80Ram + (5 << 14) );
ZetMapArea(0x8000, 0xbfff, 0, DrvZ80Ram + (2 << 14) );
ZetMapArea(0x8000, 0xbfff, 1, DrvZ80Ram + (2 << 14) );
ZetMapArea(0x8000, 0xbfff, 2, DrvZ80Ram + (2 << 14) );
ZetClose();
DACInit(0, 0, 0, DrvSyncDAC);
DACSetRoute(0, 0.50, BURN_SND_ROUTE_BOTH);
AY8910Init(0, 17734475 / 10, 1);
AY8910SetAllRoutes(0, 0.25, BURN_SND_ROUTE_BOTH);
BurnSetRefreshRate(50.0);
GenericTilesInit();
DrvFrameInvertCount = 16;
DrvFrameNumber = 0;
DrvFlashInvert = 0;
DrvNumScanlines = 312;
DrvNumCylesPerScanline = 224;
DrvVBlankScanline = 310;
DrvIsSpec128 = 1;
nPort7FFDData = 0;
DrvVideoRam = DrvZ80Ram;
DrvDoReset();
@ -892,15 +1178,30 @@ static INT32 Z80SnapshotInit()
return SpectrumInit(SPEC_SNAPSHOT_Z80);
}
static INT32 DrvSpec128Init()
{
return Spectrum128Init(SPEC_NO_SNAPSHOT);
}
static INT32 Z80128KSnapshotInit()
{
return Spectrum128Init(SPEC_SNAPSHOT_Z80);
}
static INT32 DrvExit()
{
ZetExit();
DACExit();
if (DrvIsSpec128) AY8910Exit(0);
GenericTilesExit();
BurnFree(Mem);
DrvVideoRam = NULL;
nActiveSnapshotType = SPEC_NO_SNAPSHOT;
nCyclesDone = 0;
nScanline = 0;
@ -910,6 +1211,8 @@ static INT32 DrvExit()
DrvNumScanlines = 312;
DrvNumCylesPerScanline = 224;
DrvVBlankScanline = 310;
DrvIsSpec128 = 0;
nPort7FFDData = 1;
return 0;
}
@ -956,8 +1259,8 @@ static void spectrum_UpdateScreenBitmap(bool eof)
if (xSrc < SPEC_SCREEN_XSIZE && ySrc < SPEC_SCREEN_YSIZE) {
if ((xSrc & 7) == 0) {
UINT16 *bm = pTransDraw + (nPreviousScreenY * nScreenWidth) + nPreviousScreenX;
UINT8 attr = *(DrvZ80Ram + ((ySrc & 0xF8) << 2) + (xSrc >> 3) + 0x1800);
UINT8 scr = *(DrvZ80Ram + ((ySrc & 7) << 8) + ((ySrc & 0x38) << 2) + ((ySrc & 0xC0) << 5) + (xSrc >> 3));
UINT8 attr = *(DrvVideoRam + ((ySrc & 0xF8) << 2) + (xSrc >> 3) + 0x1800);
UINT8 scr = *(DrvVideoRam + ((ySrc & 7) << 8) + ((ySrc & 0x38) << 2) + ((ySrc & 0xC0) << 5) + (xSrc >> 3));
UINT16 ink = (attr & 0x07) + ((attr >> 3) & 0x08);
UINT16 pap = (attr >> 3) & 0x0f;
@ -1062,6 +1365,10 @@ static INT32 DrvFrame()
if (pBurnSoundOut) {
DACUpdate(pBurnSoundOut, nBurnSoundLen);
if (DrvIsSpec128) {
AY8910Render(pBurnSoundOut, nBurnSoundLen);
}
}
ZetClose();
@ -1112,6 +1419,26 @@ struct BurnDriver BurnDrvSpectrum = {
&DrvRecalc, 0x10, 352, 296, 4, 3
};
struct BurnDriver BurnDrvSpec128BIOS = {
"spec128", NULL, NULL, NULL, "1984",
"ZX Spectrum 128\0", "BIOS Only", "Sinclair Research Limited", "ZX Spectrum",
NULL, NULL, NULL, NULL,
BDF_BOARDROM, 0, HARDWARE_MISC_PRE90S, GBF_BIOS, 0,
SpectrumGetZipName, Spec128RomInfo, Spec128RomName, NULL, NULL, DrvInputInfo, DrvDIPInfo,
DrvSpec128Init, DrvExit, DrvFrame, DrvDraw, DrvScan,
&DrvRecalc, 0x10, 352, 296, 4, 3
};
struct BurnDriver BurnDrvSpec128 = {
"spec128", NULL, NULL, NULL, "1984",
"ZX Spectrum 128\0", NULL, "Sinclair Research Limited", "ZX Spectrum",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING, 1, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
SpectrumGetZipName, Spec128RomInfo, Spec128RomName, NULL, NULL, DrvInputInfo, DrvDIPInfo,
DrvSpec128Init, DrvExit, DrvFrame, DrvDraw, DrvScan,
&DrvRecalc, 0x10, 352, 296, 4, 3
};
// games
static struct BurnRomInfo S48180RomDesc[] = {
{ "180.z80", 0x08d96, 0x8cba8fcd, BRF_ESS | BRF_PRG },
@ -1190,7 +1517,7 @@ STD_ROM_FN(S48Chasehq)
struct BurnDriver BurnDrvS48Chasehq = {
"s48_chasehq", NULL, "spectrum", NULL, "1989",
"Chase HQ\0", NULL, "Ocean Software", "ZX Spectrum",
"Chase HQ (48K)\0", NULL, "Ocean Software", "ZX Spectrum",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING, 1, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
SpectrumGetZipName, S48ChasehqRomInfo, S48ChasehqRomName, NULL, NULL, DrvInputInfo, DrvDIPInfo,
@ -1198,6 +1525,23 @@ struct BurnDriver BurnDrvS48Chasehq = {
&DrvRecalc, 0x10, 352, 296, 4, 3
};
static struct BurnRomInfo S128ChasehqRomDesc[] = {
{ "chasehq_128.z80", 0x1c04f, 0xbb5ae933, BRF_ESS | BRF_PRG },
};
STDROMPICKEXT(S128Chasehq, S128Chasehq, Spec128)
STD_ROM_FN(S128Chasehq)
struct BurnDriver BurnDrvS128Chasehq = {
"s128_chasehq", "s48_chasehq", "spec128", NULL, "1989",
"Chase HQ (128K)\0", NULL, "Ocean Software", "ZX Spectrum",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE, 1, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
SpectrumGetZipName, S128ChasehqRomInfo, S128ChasehqRomName, NULL, NULL, DrvInputInfo, DrvDIPInfo,
Z80128KSnapshotInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
&DrvRecalc, 0x10, 352, 296, 4, 3
};
static struct BurnRomInfo S48ChuckieRomDesc[] = {
{ "chuckie.z80", 0x04c8b, 0xf274304f, BRF_ESS | BRF_PRG },
};
@ -1385,13 +1729,6 @@ struct BurnDriver BurnDrvS48Feud = {
&DrvRecalc, 0x10, 352, 296, 4, 3
};
static struct BurnRomInfo S48FootDirRomDesc[] = {
{ "footdir.z80", 0x09abb, 0x6fdbf2bd, BRF_ESS | BRF_PRG },
};
@ -1681,6 +2018,23 @@ struct BurnDriver BurnDrvS48Renegade = {
&DrvRecalc, 0x10, 352, 296, 4, 3
};
static struct BurnRomInfo S128RobocopRomDesc[] = {
{ "robocop.z80", 0x1bc85, 0xe5ae03c8, BRF_ESS | BRF_PRG },
};
STDROMPICKEXT(S128Robocop, S128Robocop, Spec128)
STD_ROM_FN(S128Robocop)
struct BurnDriver BurnDrvS128Robocop = {
"s128_robocop", NULL, "spec128", NULL, "1988",
"Robocop (128K)\0", NULL, "Ocean Software", "ZX Spectrum",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING, 1, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
SpectrumGetZipName, S128RobocopRomInfo, S128RobocopRomName, NULL, NULL, DrvInputInfo, DrvDIPInfo,
Z80128KSnapshotInit, DrvExit, DrvFrame, DrvDraw, DrvScan,
&DrvRecalc, 0x10, 352, 296, 4, 3
};
static struct BurnRomInfo S48ThebossRomDesc[] = {
{ "theboss.z80", 0x093f2, 0xafbdbe2a, BRF_ESS | BRF_PRG },
};