diff --git a/src/burn/drv/pre90s/d_spectrum.cpp b/src/burn/drv/pre90s/d_spectrum.cpp index ddbf899d1..8ff05e675 100644 --- a/src/burn/drv/pre90s/d_spectrum.cpp +++ b/src/burn/drv/pre90s/d_spectrum.cpp @@ -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("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 }, };