/*
ATV Track
(c)2002 Gaelco
ATV Track
Gaelco 2002
PCB Layout
GAELCO
REF. 020419
|--------------------------------------------------------------|
| |
| SW3 EPC1PC8 |
| K4S643232 |
| LC245A 7LB176 |-|
| FLASH.IC14 FLASH.IC19 7LB176 | |
| |-----| 7LB176 | |DB9
| | SH4 | 7LB176 |-|
| | | FLASH.IC15 FLASH.IC20 |
| |-----| |
| |----------| |
|-| K4S643232 |ALTERA | |
| | L4955 |FLEX | |
| | |-----| K4S643232 |EPF10K50 | |
| |CN1 | SH4 | |EQC240-3 | |
| | | | |----------| |
| | |-----| |
|-| |
| |
| 33MHz K4S643232 |----------| |
| K4S643232 | GFX | |
| LED | | |-|
| LED | | | |
| K4S643232 | | | |DB9
| K4S643232 |----------| |-|
| TL074C TL074C 385-1 |
| TDA1387 TDA1387 14.31818MHz |
| |
|--------------------------------------------------------------|
Notes:
SH4 - Hitachi HD6417750S SH4 CPU (BGA)
K4S643232 - Samsung K4S643232E-TC70 64M x 32-bit SDRAM (TSSOP86)
GFX - Unknown BGA graphics chip (heatsinked)
FLASH.IC* - Samsung K9F2808U0B 128MBit (16M + 512k Spare x 8-bit) FlashROM (TSOP48)
EPF10K50 - Altera Flex EPF10K50EQC240-3 FPGA (QFP240)
EPC1PC8 - Altera EPC1PC8 FPGA Configuration Device (DIP8)
TL074C - Texas Instruments TL074C Low Noise Quad JFet Operational Amplifier (SOIC14)
TDA1387 - Philips TDA1387 Stereo Continuous Calibration DAC (SOIC8)
L4955 - ST Microelectronics L4955 low-power, quad channel, 8-bit buffered voltage output DAC and amplifier
7LB176 - Texas Instruments 7LB176 Differential Bus Tranceiver (SOIC8)
385-1 - National LM385 Adjustable Micropower Voltage Reference Diode (SOIC8)
CN1 - Multi-pin connector for filter board (input, video, power & controls connectors etc)
DB9 - Probably used for cabinet linking
SW3 - Push button switch
*/
#include "emu.h"
#include "cpu/sh4/sh4.h"
#include "debugger.h"
const memory_region *nandregion;
int nandcommand[4], nandoffset[4], nandaddressstep, nandaddress[4];
UINT32 area1_data[4];
//#define SPECIALMODE 1 // Alternate code path
class atvtrack_state : public driver_device
{
public:
atvtrack_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
};
static void logbinary(UINT32 data,int high=31,int low=0)
{
UINT32 s;
int z;
s=1 << high;
for (z = high;z >= low;z--) {
if (data & s)
logerror("1");
else
logerror("0");
s=s >> 1;
}
}
static inline UINT32 decode64_32(offs_t offset64, UINT64 data, UINT64 mem_mask, offs_t &offset32)
{
if (ACCESSING_BITS_0_31) {
offset32 = offset64 << 1;
return (UINT32)data;
}
if (ACCESSING_BITS_32_63) {
offset32 = (offset64 << 1)+1;
return (UINT32)(data >> 32);
}
logerror("Wrong word size in external access\n");
//debugger_break(NULL);
return 0;
}
static READ64_HANDLER( area1_r )
{
UINT32 addr;
addr = 0;
decode64_32(offset, 0, mem_mask, addr);
if (addr == (0x00020000-0x00020000)/4)
return -1;
else if (addr == (0x00020004-0x00020000)/4)
return -1;
return -1;
}
static WRITE64_HANDLER( area1_w )
{
UINT32 addr, dat; //, old;
addr = 0;
dat = decode64_32(offset, data, mem_mask, addr);
// old = area1_data[addr];
area1_data[addr] = dat;
if (addr == (0x00020000-0x00020000)/4) {
if (data & 4) {
device_execute_interface *exec = dynamic_cast<device_execute_interface *>(space->machine().device("subcpu"));
exec->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
}
}
logerror("Write %08x at %08x ",dat, 0x20000+addr*4+0);
logbinary(dat);
logerror("\n");
}
static READ64_HANDLER( area2_r )
{
UINT32 addr, dat;
int c;
addr = 0;
dat = decode64_32(offset, 0, mem_mask, addr);
if (addr == 0) {
dat = 0;
for (c = 3;c >= 0;c--) {
if (nandcommand[c] <= 0x50) {
addr = nandaddress[c]+nandoffset[c];
dat = (dat << 8) | nandregion->u8(addr+c);
nandoffset[c] += 4;
} else
dat = (dat << 8) | 0xc0;
}
return dat;
} else
;
return 0;
}
static WRITE64_HANDLER( area2_w )
{
// UINT32 addr, dat;
// addr = 0;
// dat = decode64_32(offset, data, mem_mask, addr);
// if (addr == 0)
// ;
// else
// ;
}
static READ64_HANDLER( area3_r )
{
// UINT32 addr, dat;
// addr = 0;
// dat = decode64_32(offset, 0, mem_mask, addr);
// if (addr == 0)
// ;
// else
// ;
return 0;
}
static WRITE64_HANDLER( area3_w )
{
UINT32 addr; //, dat;
int c;
addr = 0;
// dat = decode64_32(offset, data, mem_mask, addr);
if (addr == 0) {
for (c = 0;c < 4;c++) {
nandcommand[c] = data & 0xff;
if (nandcommand[c] == 0x00) {
nandoffset[c] = 0;
} else if (nandcommand[c] == 0x01) {
nandoffset[c] = 256*4;
} else if (nandcommand[c] == 0x50) {
nandoffset[c] = 512*4;
} else if (nandcommand[c] == 0x90) {
} else if (nandcommand[c] == 0xff) {
} else if (nandcommand[c] == 0x80) {
} else if (nandcommand[c] == 0x60) {
} else if (nandcommand[c] == 0x70) {
} else if (nandcommand[c] == 0x10) {
} else if (nandcommand[c] == 0xd0) {
} else {
nandcommand[c] = 0xff;
}
data=data >> 8;
}
nandaddressstep = 0;
} else
;
}
static READ64_HANDLER( area4_r )
{
// UINT32 addr, dat;
// addr = 0;
// dat = decode64_32(offset, 0, mem_mask, addr);
// if (addr == 0)
// ;
// else
// ;
return 0;
}
static WRITE64_HANDLER( area4_w )
{
UINT32 addr; //, dat;
int c;
addr = 0;
// dat = decode64_32(offset, data, mem_mask, addr);
if (addr == 0) {
for (c = 0;c < 4;c++) {
if (nandaddressstep == 0) {
nandaddress[c] = (data & 0xff)*4;
} else if (nandaddressstep == 1) {
nandaddress[c] = nandaddress[c]+(data & 0xff)*0x840;
} else if (nandaddressstep == 2) {
nandaddress[c] = nandaddress[c]+(data & 0xff)*0x84000;
}
data = data >> 8;
}
nandaddressstep++;
} else
;
}
static READ64_HANDLER( ioport_r )
{
if (offset == SH4_IOPORT_16/8) {
// much simplified way
if (strcmp(space->device().tag(), "maincpu") == 0)
#ifndef SPECIALMODE
return -1; // normal
#else
return 0; // testing
#endif
else
return 0; // unknown
}
return 0;
}
static WRITE64_HANDLER( ioport_w )
{
#ifdef SPECIALMODE
UINT64 d;
static int cnt=0;
sh4_device_dma dm;
#endif
if (offset == SH4_IOPORT_16/8) {
logerror("SH4 16bit i/o port write ");
logbinary((UINT32)data,15,0);
logerror("\n");
}
#ifdef SPECIALMODE
if (offset == SH4_IOPORT_DMA/8) {
dm.buffer = &d;
dm.channel = data & 0xffff;
dm.length = 1;
dm.size = 4;
if (cnt == 0)
d=0x12340153;
else
d=0x11223344;
if (cnt == 0)
sh4_dma_data(space->cpu,&dm);
else
sh4_dma_data(space->cpu,&dm);
cnt++;
}
#endif
}
VIDEO_START(atvtrack)
{
}
SCREEN_UPDATE(atvtrack)
{
return 0;
}
static MACHINE_START(atvtrack)
{
UINT8 *src, *dst;
address_space *as;
nandaddressstep = 0;
nandregion = machine.region("maincpu");
as = machine.device("maincpu")->memory().space(AS_PROGRAM);
dst = (UINT8 *)(as->get_write_ptr(0x0c7f0000));
src = nandregion->base()+0x10;
// copy 0x10000 bytes from region "maincpu" offset 0x10 to 0x0c7f0000
memcpy(dst, src, 0x10000);
}
static MACHINE_RESET(atvtrack)
{
address_space *as;
// Probably just after reset the cpu executes some bootsrtap routine from a memory inside the fpga.
// The routine initializes the cpu, copies the boot program from the flash memories into the cpu sdram
// and finally executes it.
// Here there is the setup of the cpu, the boot program is copied in machine_start
as = machine.device("maincpu")->memory().space(AS_PROGRAM);
// set cpu PC register to 0x0c7f0000
cpu_set_reg(machine.device("maincpu"), STATE_GENPC, 0x0c7f0000);
// set BCR2 to 1
sh4_internal_w(as, 0x3001, 1, 0xffffffff);
device_execute_interface *exec = dynamic_cast<device_execute_interface *>(machine.device("subcpu"));
exec->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
}
static ADDRESS_MAP_START( atvtrack_main_map, AS_PROGRAM, 64 )
AM_RANGE(0x00000000, 0x000003ff) AM_RAM AM_SHARE("sharedmem")
AM_RANGE(0x00020000, 0x00020007) AM_READWRITE(area1_r, area1_w)
AM_RANGE(0x14000000, 0x14000007) AM_READWRITE(area2_r, area2_w) // data
AM_RANGE(0x14100000, 0x14100007) AM_READWRITE(area3_r, area3_w) // command
AM_RANGE(0x14200000, 0x14200007) AM_READWRITE(area4_r, area4_w) // address
AM_RANGE(0x0c000000, 0x0cffffff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( atvtrack_main_port, AS_IO, 64 )
AM_RANGE(0x00, 0x1f) AM_READWRITE(ioport_r, ioport_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( atvtrack_sub_map, AS_PROGRAM, 64 )
AM_RANGE(0x00000000, 0x000003ff) AM_RAM AM_SHARE("sharedmem")
AM_RANGE(0x0c000000, 0x0cffffff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( atvtrack_sub_port, AS_IO, 64 )
/*AM_RANGE(0x00, 0x1f) AM_READWRITE(ioport_r, ioport_w) */
ADDRESS_MAP_END
static INPUT_PORTS_START( atvtrack )
INPUT_PORTS_END
// ?
#define ATV_CPU_CLOCK 200000000
// ?
static const struct sh4_config sh4cpu_config = { 1, 0, 1, 0, 0, 0, 1, 1, 0, ATV_CPU_CLOCK };
static MACHINE_CONFIG_START( atvtrack, atvtrack_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", SH4LE, ATV_CPU_CLOCK)
MCFG_CPU_CONFIG(sh4cpu_config)
MCFG_CPU_PROGRAM_MAP(atvtrack_main_map)
MCFG_CPU_IO_MAP(atvtrack_main_port)
MCFG_CPU_ADD("subcpu", SH4LE, ATV_CPU_CLOCK)
MCFG_CPU_CONFIG(sh4cpu_config)
MCFG_CPU_PROGRAM_MAP(atvtrack_sub_map)
MCFG_CPU_IO_MAP(atvtrack_sub_port)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
MCFG_SCREEN_SIZE(640, 480)
MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
MCFG_SCREEN_UPDATE(atvtrack)
MCFG_PALETTE_LENGTH(0x1000)
MCFG_MACHINE_RESET(atvtrack)
MCFG_MACHINE_START(atvtrack)
MCFG_VIDEO_START(atvtrack)
MACHINE_CONFIG_END
ROM_START( atvtrack )
ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASEFF) // NAND roms, contain additional data hence the sizes
ROM_LOAD32_BYTE("15.bin", 0x0000000, 0x1080000, CRC(84eaede7) SHA1(6e6230165c3bb35e49c660dfd0d07c132ed89e6a) )
ROM_LOAD32_BYTE("20.bin", 0x0000001, 0x1080000, CRC(649dc331) SHA1(0cac2d0c15dd564c7fdebdf4365422958f453d63) )
ROM_LOAD32_BYTE("14.bin", 0x0000002, 0x1080000, CRC(67983453) SHA1(05389a0ffc1a1bae9bac16a53a97d78b6eccc626) )
ROM_LOAD32_BYTE("19.bin", 0x0000003, 0x1080000, CRC(9fc5c579) SHA1(8829329ef229564952aea2108ef1750dc226cbac) )
ROM_REGION( 0x20000, "eeprom", ROMREGION_ERASEFF)
ROM_LOAD("epc1pc8.ic23", 0x0000000, 0x1ff01, CRC(752444c7) SHA1(c77e8fcfcbe15b53eda25553763bdac45f0ef7df) ) // contains configuration data for the fpga, maybe used for some form of protection
ROM_END
ROM_START( atvtracka )
ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASEFF) // NAND roms, contain additional data hence the sizes
ROM_LOAD32_BYTE("k9f2808u0b.ic15", 0x0000000, 0x1080000, CRC(10730001) SHA1(48c685a6ff7135abd074dc7fb7d10834c44da58f) )
ROM_LOAD32_BYTE("k9f2808u0b.ic20", 0x0000001, 0x1080000, CRC(b0c34433) SHA1(852c79bb3d7082cd2c056140071ae7d71679ec1d) )
ROM_LOAD32_BYTE("k9f2808u0b.ic14", 0x0000002, 0x1080000, CRC(02a12085) SHA1(acb112c9c7b29d92610465fb92268ce787ca06f4) )
ROM_LOAD32_BYTE("k9f2808u0b.ic19", 0x0000003, 0x1080000, CRC(856c1e6a) SHA1(a6b2839120d61811c36cc6b4095de9cefceb394b) )
ROM_END
GAME( 2002, atvtrack, 0, atvtrack, atvtrack, 0, ROT0, "Gaelco", "ATV Track (set 1)", GAME_NOT_WORKING | GAME_NO_SOUND )
GAME( 2002, atvtracka, atvtrack, atvtrack, atvtrack, 0, ROT0, "Gaelco", "ATV Track (set 2)", GAME_NOT_WORKING | GAME_NO_SOUND )