From fecff8f38706ab7c5ad080b00df683cd5990d06f Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Mon, 11 Jul 2011 15:06:19 +0000 Subject: [PATCH] Preliminary work for ATV Track, in order to get the second SH-4 into business [Samuele Zannoli] Added support for dma transfers between the processor and external devices in SH-4 CPU core [Samuele Zannoli] Modified naomibd device so that it allocates the memory for the gdrom data on startup based on a parameter that specifies the size in megabytes. [Samuele Zannoli] Added two new commands to the unidasm utility [Samuele Zannoli] -skip allows to skip the first bytes from the file -count specifiest that only bytes from the file must be disassembled --- src/emu/cpu/sh4/sh4.h | 14 +- src/emu/cpu/sh4/sh4comn.c | 235 ++++++++++++++++++++++++---- src/emu/cpu/sh4/sh4comn.h | 7 + src/emu/cpu/sh4/sh4regs.h | 44 ++++++ src/mame/drivers/atvtrack.c | 301 ++++++++++++++++++++++++++++++++++-- src/mame/drivers/chihiro.c | 2 +- src/mame/drivers/naomi.c | 2 +- src/mame/drivers/triforce.c | 2 +- src/mame/includes/naomibd.h | 14 +- src/mame/machine/naomibd.c | 19 ++- src/tools/unidasm.c | 35 ++++- 11 files changed, 620 insertions(+), 55 deletions(-) diff --git a/src/emu/cpu/sh4/sh4.h b/src/emu/cpu/sh4/sh4.h index 54879eee05a..d5b211bc511 100644 --- a/src/emu/cpu/sh4/sh4.h +++ b/src/emu/cpu/sh4/sh4.h @@ -57,9 +57,10 @@ enum { SH4_IOPORT_16=8*0, SH4_IOPORT_4=8*1, + SH4_IOPORT_DMA=8*2, // future use - SH4_IOPORT_SCI=8*2, - SH4_IOPORT_SCIF=8*3 + SH4_IOPORT_SCI=8*3, + SH4_IOPORT_SCIF=8*4 }; struct sh4_config @@ -76,6 +77,14 @@ struct sh4_config int clock; }; +struct sh4_device_dma +{ + UINT32 length; + UINT32 size; + void *buffer; + int channel; +}; + struct sh4_ddt_dma { UINT32 source; @@ -99,6 +108,7 @@ READ32_HANDLER( sh4_internal_r ); void sh4_set_frt_input(device_t *device, int state); void sh4_set_irln_input(device_t *device, int value); void sh4_set_ftcsr_callback(device_t *device, sh4_ftcsr_callback callback); +int sh4_dma_data(device_t *device, struct sh4_device_dma *s); void sh4_dma_ddt(device_t *device, struct sh4_ddt_dma *s); /*************************************************************************** diff --git a/src/emu/cpu/sh4/sh4comn.c b/src/emu/cpu/sh4/sh4comn.c index 6097ece9251..0ddf9e4297b 100644 --- a/src/emu/cpu/sh4/sh4comn.c +++ b/src/emu/cpu/sh4/sh4comn.c @@ -404,26 +404,26 @@ static TIMER_CALLBACK( sh4_dmac_callback ) { case 0: sh4->m[DMATCR0] = 0; - sh4->m[CHCR0] |= 2; - if (sh4->m[CHCR0] & 4) + sh4->m[CHCR0] |= CHCR_TE; + if (sh4->m[CHCR0] & CHCR_IE) sh4_exception_request(sh4, SH4_INTC_DMTE0); break; case 1: sh4->m[DMATCR1] = 0; - sh4->m[CHCR1] |= 2; - if (sh4->m[CHCR1] & 4) + sh4->m[CHCR1] |= CHCR_TE; + if (sh4->m[CHCR1] & CHCR_IE) sh4_exception_request(sh4, SH4_INTC_DMTE1); break; case 2: sh4->m[DMATCR2] = 0; - sh4->m[CHCR2] |= 2; - if (sh4->m[CHCR2] & 4) + sh4->m[CHCR2] |= CHCR_TE; + if (sh4->m[CHCR2] & CHCR_IE) sh4_exception_request(sh4, SH4_INTC_DMTE2); break; case 3: sh4->m[DMATCR3] = 0; - sh4->m[CHCR3] |= 2; - if (sh4->m[CHCR3] & 4) + sh4->m[CHCR3] |= CHCR_TE; + if (sh4->m[CHCR3] & CHCR_IE) sh4_exception_request(sh4, SH4_INTC_DMTE3); break; } @@ -434,9 +434,9 @@ static int sh4_dma_transfer(sh4_state *sh4, int channel, int timermode, UINT32 c int incs, incd, size; UINT32 src, dst, count; - incd = (chcr >> 14) & 3; - incs = (chcr >> 12) & 3; - size = dmasize[(chcr >> 4) & 7]; + incd = (chcr & CHCR_DM) >> 14; + incs = (chcr & CHCR_SM) >> 12; + size = dmasize[(chcr & CHCR_TS) >> 4]; if(incd == 3 || incs == 3) { logerror("SH4: DMA: bad increment values (%d, %d, %d, %04x)\n", incd, incs, size, chcr); @@ -450,12 +450,12 @@ static int sh4_dma_transfer(sh4_state *sh4, int channel, int timermode, UINT32 c LOG(("SH4: DMA %d start %x, %x, %x, %04x, %d, %d, %d\n", channel, src, dst, count, chcr, incs, incd, size)); - if (timermode == 1) + if (timermode == 1) // timer actvated after a time based on the number of words to transfer { sh4->dma_timer_active[channel] = 1; sh4->dma_timer[channel]->adjust(sh4->device->cycles_to_attotime(2*count+1), channel); } - else if (timermode == 2) + else if (timermode == 2) // timer activated immediately { sh4->dma_timer_active[channel] = 1; sh4->dma_timer[channel]->adjust(attotime::zero, channel); @@ -556,9 +556,50 @@ static int sh4_dma_transfer(sh4_state *sh4, int channel, int timermode, UINT32 c return 1; } +static int sh4_dma_transfer_device(sh4_state *sh4, int channel, UINT32 chcr, UINT32 *sar, UINT32 *dar, UINT32 *dmatcr) +{ + int incs, incd, size, mod; + UINT32 src, dst, count; + + incd = (chcr & CHCR_DM) >> 14; + incs = (chcr & CHCR_SM) >> 12; + size = dmasize[(chcr & CHCR_TS) >> 4]; + mod = ((chcr & CHCR_RS) >> 8); + if (incd == 3 || incs == 3) + { + logerror("SH4: DMA: bad increment values (%d, %d, %d, %04x)\n", incd, incs, size, chcr); + return 0; + } + src = *sar; + dst = *dar; + count = *dmatcr; + if (!count) + count = 0x1000000; + + LOG(("SH4: DMA %d start device<->memory %x, %x, %x, %04x, %d, %d, %d\n", channel, src, dst, count, chcr, incs, incd, size)); + + sh4->dma_timer_active[channel] = 1; + + src &= AM; + dst &= AM; + + // remember parameters + sh4->dma_source[channel]=src; + sh4->dma_destination[channel]=dst; + sh4->dma_count[channel]=count; + sh4->dma_wordsize[channel]=size; + sh4->dma_source_increment[channel]=incs; + sh4->dma_destination_increment[channel]=incd; + sh4->dma_mode[channel]=mod; + + // inform device its ready to transfer + sh4->io->write_dword(SH4_IOPORT_DMA, channel | (mod << 16)); + return 1; +} + static void sh4_dmac_check(sh4_state *sh4, int channel) { -UINT32 dmatcr,chcr,sar,dar; +UINT32 dmatcr, chcr, sar, dar; switch (channel) { @@ -589,12 +630,17 @@ UINT32 dmatcr,chcr,sar,dar; default: return; } - if (chcr & sh4->m[DMAOR] & 1) + if (chcr & sh4->m[DMAOR] & DMAOR_DME) { - if ((((chcr >> 8) & 15) < 4) || (((chcr >> 8) & 15) > 6)) + if ((((chcr & CHCR_RS) >> 8) < 2) || (((chcr & CHCR_RS) >> 8) > 6)) return; - if (!sh4->dma_timer_active[channel] && !(chcr & 2) && !(sh4->m[DMAOR] & 6)) - sh4_dma_transfer(sh4, channel, 1, chcr, &sar, &dar, &dmatcr); + if (!sh4->dma_timer_active[channel] && !(chcr & CHCR_TE) && !(sh4->m[DMAOR] & (DMAOR_AE | DMAOR_NMIF))) + { + if (((chcr & CHCR_RS) >> 8) > 3) + sh4_dma_transfer(sh4, channel, 1, chcr, &sar, &dar, &dmatcr); + else if ((sh4->m[DMAOR] & DMAOR_DDT) == 0) + sh4_dma_transfer_device(sh4, channel, chcr, &sar, &dar, &dmatcr); // tell device we are ready to transfer + } } else { @@ -607,11 +653,11 @@ UINT32 dmatcr,chcr,sar,dar; } } -static void sh4_dmac_nmi(sh4_state *sh4) // manage dma when nmi +static void sh4_dmac_nmi(sh4_state *sh4) // manage dma when nmi gets asserted { int s; - sh4->m[DMAOR] |= 2; // nmif = 1 + sh4->m[DMAOR] |= DMAOR_NMIF; for (s = 0;s < 4;s++) { if (sh4->dma_timer_active[s]) @@ -638,7 +684,7 @@ WRITE32_HANDLER( sh4_internal_w ) switch( offset ) { case MMUCR: // MMU Control - if (data & 1) + if (data & MMUCR_AT) { printf("SH4 MMU Enabled\n"); printf("If you're seeing this, but running something other than a Naomi GD-ROM game then chances are it won't work\n"); @@ -880,10 +926,10 @@ WRITE32_HANDLER( sh4_internal_w ) sh4_dmac_check(sh4, 3); break; case DMAOR: - if ((sh4->m[DMAOR] & 4) && (~old & 4)) - sh4->m[DMAOR] &= ~4; - if ((sh4->m[DMAOR] & 2) && (~old & 2)) - sh4->m[DMAOR] &= ~2; + if ((sh4->m[DMAOR] & DMAOR_AE) && (~old & DMAOR_AE)) + sh4->m[DMAOR] &= ~DMAOR_AE; + if ((sh4->m[DMAOR] & DMAOR_NMIF) && (~old & DMAOR_NMIF)) + sh4->m[DMAOR] &= ~DMAOR_NMIF; sh4_dmac_check(sh4, 0); sh4_dmac_check(sh4, 1); sh4_dmac_check(sh4, 2); @@ -953,7 +999,10 @@ READ32_HANDLER( sh4_internal_r ) switch( offset ) { case VERSION: - return 0x040205c1; // this is what a real SH7750 in a Dreamcast returns - the later Naomi BIOSes check and care! + return PVR_SH7091; // 0x040205c1, this is what a real SH7091 in a Dreamcast returns - the later Naomi BIOSes check and care! + break; + case PRR: + return 0; break; case IPRD: return 0x00000000; // SH7750 ignores writes here and always returns zero @@ -1197,6 +1246,140 @@ void sh4_common_init(device_t *device) sh4->m = auto_alloc_array(device->machine(), UINT32, 16384); } +// called by drivers to transfer data in a cpu<->device dma. 'device' must be a SH4 cpu +int sh4_dma_data(device_t *device, struct sh4_device_dma *s) +{ + UINT32 pos, len, siz; + int channel = s->channel; + void *data = s->buffer; + + sh4_state *sh4 = get_safe_token(device); + + if (!sh4->dma_timer_active[channel]) + return 0; + + if (sh4->dma_mode[channel] == 2) + { + // device receives data + len = sh4->dma_count[channel]; + if (s->length < len) + len = s->length; + siz = sh4->dma_wordsize[channel]; + for (pos = 0;pos < len;pos++) { + switch (siz) + { + case 8: + if (sh4->dma_source_increment[channel] == 2) + sh4->dma_source[channel] -= 8; + *(UINT64 *)data = sh4->program->read_qword(sh4->dma_source[channel] & ~7); + if (sh4->dma_source_increment[channel] == 1) + sh4->dma_source[channel] += 8; + break; + case 1: + if (sh4->dma_source_increment[channel] == 2) + sh4->dma_source[channel]--; + *(UINT8 *)data = sh4->program->read_byte(sh4->dma_source[channel]); + if (sh4->dma_source_increment[channel] == 1) + sh4->dma_source[channel]++; + break; + case 2: + if (sh4->dma_source_increment[channel] == 2) + sh4->dma_source[channel] -= 2; + *(UINT16 *)data = sh4->program->read_word(sh4->dma_source[channel] & ~1); + if (sh4->dma_source_increment[channel] == 1) + sh4->dma_source[channel] += 2; + break; + case 4: + if (sh4->dma_source_increment[channel] == 2) + sh4->dma_source[channel] -= 4; + *(UINT32 *)data = sh4->program->read_dword(sh4->dma_source[channel] & ~3); + if (sh4->dma_source_increment[channel] == 1) + sh4->dma_source[channel] += 4; + break; + case 32: + if (sh4->dma_source_increment[channel] == 2) + sh4->dma_source[channel] -= 32; + *(UINT64 *)data = sh4->program->read_qword(sh4->dma_source[channel] & ~31); + *((UINT64 *)data+1) = sh4->program->read_qword((sh4->dma_source[channel] & ~31)+8); + *((UINT64 *)data+2) = sh4->program->read_qword((sh4->dma_source[channel] & ~31)+16); + *((UINT64 *)data+3) = sh4->program->read_qword((sh4->dma_source[channel] & ~31)+24); + if (sh4->dma_source_increment[channel] == 1) + sh4->dma_source[channel] += 32; + break; + } + sh4->dma_count[channel]--; + } + if (sh4->dma_count[channel] == 0) // all data transferred ? + { + sh4->dma_timer[channel]->adjust(attotime::zero, channel); + return 2; + } + return 1; + } + else if (sh4->dma_mode[channel] == 3) + { + // device sends data + len = sh4->dma_count[channel]; + if (s->length < len) + len = s->length; + siz = sh4->dma_wordsize[channel]; + for (pos = 0;pos < len;pos++) { + switch (siz) + { + case 8: + if (sh4->dma_destination_increment[channel] == 2) + sh4->dma_destination[channel]-=8; + sh4->program->write_qword(sh4->dma_destination[channel] & ~7, *(UINT64 *)data); + if (sh4->dma_destination_increment[channel] == 1) + sh4->dma_destination[channel]+=8; + break; + case 1: + if (sh4->dma_destination_increment[channel] == 2) + sh4->dma_destination[channel]--; + sh4->program->write_byte(sh4->dma_destination[channel], *(UINT8 *)data); + if (sh4->dma_destination_increment[channel] == 1) + sh4->dma_destination[channel]++; + break; + case 2: + if (sh4->dma_destination_increment[channel] == 2) + sh4->dma_destination[channel]-=2; + sh4->program->write_word(sh4->dma_destination[channel] & ~1, *(UINT16 *)data); + if (sh4->dma_destination_increment[channel] == 1) + sh4->dma_destination[channel]+=2; + break; + case 4: + if (sh4->dma_destination_increment[channel] == 2) + sh4->dma_destination[channel]-=4; + sh4->program->write_dword(sh4->dma_destination[channel] & ~3, *(UINT32 *)data); + if (sh4->dma_destination_increment[channel] == 1) + sh4->dma_destination[channel]+=4; + break; + case 32: + if (sh4->dma_destination_increment[channel] == 2) + sh4->dma_destination[channel]-=32; + sh4->program->write_qword(sh4->dma_destination[channel] & ~31, *(UINT64 *)data); + sh4->program->write_qword((sh4->dma_destination[channel] & ~31)+8, *((UINT64 *)data+1)); + sh4->program->write_qword((sh4->dma_destination[channel] & ~31)+16, *((UINT64 *)data+2)); + sh4->program->write_qword((sh4->dma_destination[channel] & ~31)+24, *((UINT64 *)data+3)); + if (sh4->dma_destination_increment[channel] == 1) + sh4->dma_destination[channel]+=32; + break; + } + sh4->dma_count[channel]--; + } + + if (sh4->dma_count[channel] == 0) // all data transferred ? + { + sh4->dma_timer[channel]->adjust(attotime::zero, channel); + return 2; + } + return 1; + } + else + return 0; +} + +// called by drivers to transfer data in a DDT dma. 'device' must be a SH4 cpu void sh4_dma_ddt(device_t *device, struct sh4_ddt_dma *s) { sh4_state *sh4 = get_safe_token(device); diff --git a/src/emu/cpu/sh4/sh4comn.h b/src/emu/cpu/sh4/sh4comn.h index ef589829c4c..ab08e9ffd1b 100644 --- a/src/emu/cpu/sh4/sh4comn.h +++ b/src/emu/cpu/sh4/sh4comn.h @@ -94,6 +94,13 @@ typedef struct emu_timer *timer[3]; UINT32 refresh_timer_base; int dma_timer_active[4]; + UINT32 dma_source[4]; + UINT32 dma_destination[4]; + UINT32 dma_count[4]; + int dma_wordsize[4]; + int dma_source_increment[4]; + int dma_destination_increment[4]; + int dma_mode[4]; int sh4_icount; int is_slave; diff --git a/src/emu/cpu/sh4/sh4regs.h b/src/emu/cpu/sh4/sh4regs.h index b8c2233e3f9..e6c1aaa80c6 100644 --- a/src/emu/cpu/sh4/sh4regs.h +++ b/src/emu/cpu/sh4/sh4regs.h @@ -19,6 +19,7 @@ #define PTEA 0x200D /* FF000034 */ #define QACR0 0x200E /* FF000038 */ #define QACR1 0x200F /* FF00003C */ +#define PRR 0x2011 /* FF000044 */ #define BARA 0x2400 /* FF200000 */ #define BAMRA 0x2401 /* FF200004 */ #define BBRA 0x2402 /* FF200008 */ @@ -157,4 +158,47 @@ #define SDINT 0x3E05 /* FFF00014 */ #define SIZEREGS 15878 +/* bit definitions */ +#define CHCR_SSA 0xe0000000 +#define CHCR_STC 0x10000000 +#define CHCR_DSA 0x0e000000 +#define CHCR_DTC 0x01000000 +#define CHCR_DS 0x00080000 +#define CHCR_RL 0x00040000 +#define CHCR_AM 0x00020000 +#define CHCR_AL 0x00010000 +#define CHCR_DM 0x0000c000 +#define CHCR_SM 0x00003000 +#define CHCR_RS 0x00000f00 +#define CHCR_TM 0x00000080 +#define CHCR_TS 0x00000070 +#define CHCR_IE 0x00000004 +#define CHCR_TE 0x00000002 +#define CHCR_DE 0x00000001 + +#define DMAOR_DDT 0x8000 +#define DMAOR_PR 0x0300 +#define DMAOR_COD 0x0010 +#define DMAOR_AE 0x0004 +#define DMAOR_NMIF 0x0002 +#define DMAOR_DME 0x0001 + +#define MMUCR_LRUI 0xfc000000 +#define MMUCR_URB 0x00fc0000 +#define MMUCR_URC 0x0000fc00 +#define MMUCR_SQMD 0x00000200 +#define MMUCR_SV 0x00000100 +#define MMUCR_TI 0x00000004 +#define MMUCR_AT 0x00000001 + +/* constants */ +#define PVR_SH7091 0x040205c1 +#define PVR_SH7750 0x04020500 // from TN-SH7-361B/E +#define PVR_SH7750S 0x04020600 +#define PVR_SH7750R 0x04050000 +#define PRR_SH7750R 0x00000100 +#define PVR_SH7751 0x04110000 +#define PVR_SH7751R 0x04050000 +#define PRR_SH7751R 0x00000110 + #endif /* __SH4REGS_H__ */ diff --git a/src/mame/drivers/atvtrack.c b/src/mame/drivers/atvtrack.c index 70decf11f3e..e8729ff0680 100644 --- a/src/mame/drivers/atvtrack.c +++ b/src/mame/drivers/atvtrack.c @@ -50,15 +50,21 @@ Notes: 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 power & controls connectors etc) - DB9 - Video output connector (for twin monitors) + 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 { @@ -68,6 +74,232 @@ public: }; +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(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) { @@ -78,11 +310,57 @@ SCREEN_UPDATE(atvtrack) return 0; } -static ADDRESS_MAP_START( atvtrack_map, AS_PROGRAM, 64 ) - AM_RANGE(0x00000000, 0x001fffff) AM_ROM AM_REGION("maincpu", 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(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_port, AS_IO, 64 ) +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 @@ -98,14 +376,13 @@ static MACHINE_CONFIG_START( atvtrack, atvtrack_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", SH4, ATV_CPU_CLOCK) MCFG_CPU_CONFIG(sh4cpu_config) - MCFG_CPU_PROGRAM_MAP(atvtrack_map) - MCFG_CPU_IO_MAP(atvtrack_port) + MCFG_CPU_PROGRAM_MAP(atvtrack_main_map) + MCFG_CPU_IO_MAP(atvtrack_main_port) MCFG_CPU_ADD("subcpu", SH4, ATV_CPU_CLOCK) MCFG_CPU_CONFIG(sh4cpu_config) - MCFG_CPU_PROGRAM_MAP(atvtrack_map) - MCFG_CPU_IO_MAP(atvtrack_port) - MCFG_DEVICE_DISABLE() + MCFG_CPU_PROGRAM_MAP(atvtrack_sub_map) + MCFG_CPU_IO_MAP(atvtrack_sub_port) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -118,6 +395,8 @@ static MACHINE_CONFIG_START( atvtrack, atvtrack_state ) MCFG_PALETTE_LENGTH(0x1000) + MCFG_MACHINE_RESET(atvtrack) + MCFG_MACHINE_START(atvtrack) MCFG_VIDEO_START(atvtrack) MACHINE_CONFIG_END @@ -129,7 +408,7 @@ ROM_START( atvtrack ) 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 a large amount of data, maybe used for some form of protection + 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 ) diff --git a/src/mame/drivers/chihiro.c b/src/mame/drivers/chihiro.c index 0722120bf3a..3c17a9cc015 100644 --- a/src/mame/drivers/chihiro.c +++ b/src/mame/drivers/chihiro.c @@ -661,7 +661,7 @@ static MACHINE_CONFIG_START( chihiro_base, driver_device ) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( chihirogd, chihiro_base ) - MCFG_NAOMI_DIMM_BOARD_ADD("rom_board", "gdrom", "user1", "picreturn") + MCFG_NAOMI_DIMM_BOARD_ADD("rom_board", "gdrom", NULL, 512, "picreturn") MACHINE_CONFIG_END #define ROM_LOAD16_WORD_SWAP_BIOS(bios,name,offset,length,hash) \ diff --git a/src/mame/drivers/naomi.c b/src/mame/drivers/naomi.c index 4bb404af9d8..b59a3595e80 100644 --- a/src/mame/drivers/naomi.c +++ b/src/mame/drivers/naomi.c @@ -2545,7 +2545,7 @@ static MACHINE_CONFIG_DERIVED( naomigd, naomi_base ) MCFG_SEGA_837_13551_DEVICE_ADD("837_13551", "mie", "TILT", "P1", "P2", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "OUTPUT") MCFG_EEPROM_93C46_8BIT_ADD("mie_eeprom") - MCFG_NAOMI_DIMM_BOARD_ADD("rom_board", "gdrom", "user1", "picreturn") + MCFG_NAOMI_DIMM_BOARD_ADD("rom_board", "gdrom", NULL, 512, "picreturn") MCFG_X76F100_ADD("naomibd_eeprom") MACHINE_CONFIG_END diff --git a/src/mame/drivers/triforce.c b/src/mame/drivers/triforce.c index 22b57eb525c..db59d487b3e 100644 --- a/src/mame/drivers/triforce.c +++ b/src/mame/drivers/triforce.c @@ -443,7 +443,7 @@ static MACHINE_CONFIG_START( triforce_base, driver_device ) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( triforcegd, triforce_base ) - MCFG_NAOMI_DIMM_BOARD_ADD("rom_board", "gdrom", "user1", "picreturn") + MCFG_NAOMI_DIMM_BOARD_ADD("rom_board", "gdrom", NULL, 256, "picreturn") MACHINE_CONFIG_END #define ROM_LOAD16_WORD_SWAP_BIOS(bios,name,offset,length,hash) \ diff --git a/src/mame/includes/naomibd.h b/src/mame/includes/naomibd.h index dcfc20389c5..3ad71fc2d00 100644 --- a/src/mame/includes/naomibd.h +++ b/src/mame/includes/naomibd.h @@ -26,16 +26,17 @@ enum TYPE DEFINITIONS ***************************************************************************/ -typedef void (*naomibd_interrupt_func)(device_t *device, int state); +typedef void (*naomibd_signal_func)(device_t *device, int signal, int state); typedef struct _naomibd_config naomibd_config; struct _naomibd_config { int type; + int size; const char * regiontag; const char * gdromregiontag; const char * picregiontag; - naomibd_interrupt_func interrupt; + naomibd_signal_func signal; }; @@ -56,10 +57,11 @@ struct _naomibd_config MCFG_NAOMIBD_ADD(_tag, AW_ROM_BOARD) \ MCFG_NAOMIBD_REGION(_region) -#define MCFG_NAOMI_DIMM_BOARD_ADD(_tag, _gdrom, _region, _pic) \ +#define MCFG_NAOMI_DIMM_BOARD_ADD(_tag, _gdrom, _callback, _sizemb, _pic) \ MCFG_NAOMIBD_ADD(_tag, DIMM_BOARD) \ - MCFG_NAOMIBD_REGION(_region) \ + MCFG_DEVICE_CONFIG_DATAPTR(naomibd_config, signal, _callback) \ MCFG_NAOMIBD_GDROM_REGION(_gdrom) \ + MCFG_NAOMIBD_SIZE(_sizemb) \ MCFG_NAOMIBD_PIC_REGION(_pic) #define MCFG_NAOMIBD_REGION(_region) \ @@ -71,6 +73,9 @@ struct _naomibd_config #define MCFG_NAOMIBD_PIC_REGION(_region) \ MCFG_DEVICE_CONFIG_DATAPTR(naomibd_config, picregiontag, _region) +#define MCFG_NAOMIBD_SIZE(_sizemb) \ + MCFG_DEVICE_CONFIG_DATA32(naomibd_config, size, _sizemb) + #define MCFG_NAOMIBD_MODIFY(_tag) \ MCFG_DEVICE_MODIFY(_tag) @@ -84,7 +89,6 @@ struct _naomibd_config FUNCTION PROTOTYPES ***************************************************************************/ -int naomibd_interrupt_callback(device_t *device, naomibd_interrupt_func callback); int naomibd_get_type(device_t *device); void *naomibd_get_memory(device_t *device, UINT32 length); offs_t naomibd_get_dmaoffset(device_t *device); diff --git a/src/mame/machine/naomibd.c b/src/mame/machine/naomibd.c index f87ee50455d..6cdf1ad5f14 100644 --- a/src/mame/machine/naomibd.c +++ b/src/mame/machine/naomibd.c @@ -238,7 +238,9 @@ struct _naomibd_state UINT8 * memory; chd_file * gdromchd; + cdrom_file * gdrom; UINT8 * picdata; + UINT32 size; /* size of installed dimm memory */ UINT32 rom_offset, rom_offset_flags, dma_count; UINT32 dma_offset, dma_offset_flags; UINT32 prot_offset, prot_key; @@ -351,11 +353,14 @@ INLINE naomibd_state *get_safe_token(device_t *device) * *************************************/ -int naomibd_interrupt_callback(device_t *device, naomibd_interrupt_func callback) +// send interrupt to host system +void output_interrupt(naomibd_state *st, int state) { - naomibd_config *config = (naomibd_config *)downcast(device)->inline_config(); - config->interrupt = callback; - return 0; + naomibd_config *config = (naomibd_config *)downcast(st->device)->inline_config(); + + /* send out an interrupt */ + if (config->signal != NULL) + (*config->signal)(st->device, 0, state); // 0: this signal is an interrupt } int naomibd_get_type(device_t *device) @@ -1438,6 +1443,8 @@ static void load_rom_gdrom(running_machine& machine, naomibd_state *v) } if (start != 0) { + // check for size + assert(size <= v->size); // read encrypted data into memory ptr = v->memory; sectors = (size+2047)/2048; @@ -2093,7 +2100,9 @@ static DEVICE_START( naomibd ) break; case DIMM_BOARD: - v->memory = (UINT8 *)auto_alloc_array_clear(device->machine(), UINT8, 0x40000000/4); // 0x40000000 is needed for some Chihiro sets, Naomi should be less, we should pass as device param + assert((config->size >= 256) && !(config->size & 255)); // size multiple of 256 megabytes ? + v->size = config->size << 20; + v->memory = (UINT8 *)auto_alloc_array_clear(device->machine(), UINT8, v->size); // 0x40000000 is needed for some Chihiro sets, Naomi should be less v->gdromchd = get_disk_handle(device->machine(), config->gdromregiontag); v->picdata = (UINT8 *)device->machine().region(config->picregiontag)->base(); if (v->memory != NULL && v->gdromchd != NULL && v->picdata != NULL) diff --git a/src/tools/unidasm.c b/src/tools/unidasm.c index d48591d5ebc..b56a668c5ff 100644 --- a/src/tools/unidasm.c +++ b/src/tools/unidasm.c @@ -83,6 +83,8 @@ struct _options UINT8 flipped; int mode; const dasm_table_entry *dasm; + UINT32 skip; + UINT32 count; }; @@ -356,6 +358,8 @@ static int parse_options(int argc, char *argv[], options *opts) int pending_base = FALSE; int pending_arch = FALSE; int pending_mode = FALSE; + int pending_skip = FALSE; + int pending_count = FALSE; int curarch; int numrows; int arg; @@ -370,7 +374,7 @@ static int parse_options(int argc, char *argv[], options *opts) // is it a switch? if (curarg[0] == '-') { - if (pending_base || pending_arch || pending_mode) + if (pending_base || pending_arch || pending_mode || pending_skip || pending_count) goto usage; if (tolower((UINT8)curarg[1]) == 'a') @@ -383,6 +387,10 @@ static int parse_options(int argc, char *argv[], options *opts) opts->lower = TRUE; else if (tolower((UINT8)curarg[1]) == 'm') pending_mode = TRUE; + else if (tolower((UINT8)curarg[1]) == 's') + pending_skip = TRUE; + else if (tolower((UINT8)curarg[1]) == 'c') + pending_count = TRUE; else if (tolower((UINT8)curarg[1]) == 'n') opts->norawbytes = TRUE; else if (tolower((UINT8)curarg[1]) == 'u') @@ -426,6 +434,22 @@ static int parse_options(int argc, char *argv[], options *opts) pending_arch = FALSE; } + // skip bytes + else if (pending_skip) + { + if (sscanf(curarg, "%d", &opts->skip) != 1) + goto usage; + pending_skip = FALSE; + } + + // size + else if (pending_count) + { + if (sscanf(curarg, "%d", &opts->count) != 1) + goto usage; + pending_count = FALSE; + } + // filename else if (opts->filename == NULL) opts->filename = curarg; @@ -436,7 +460,7 @@ static int parse_options(int argc, char *argv[], options *opts) } // if we have a dangling option, error - if (pending_base || pending_arch || pending_mode) + if (pending_base || pending_arch || pending_mode || pending_skip || pending_count) goto usage; // if no file or no architecture, fail @@ -447,6 +471,7 @@ static int parse_options(int argc, char *argv[], options *opts) usage: printf("Usage: %s -arch [-basepc ] \n", argv[0]); printf(" [-mode ] [-norawbytes] [-flipped] [-upper] [-lower]\n"); + printf(" [-skip ] [-count ]\n"); printf("\n"); printf("Supported architectures:"); numrows = (ARRAY_LENGTH(dasm_table) + 6) / 7; @@ -504,10 +529,14 @@ int main(int argc, char *argv[]) // run it try { + if (length > opts.skip) + length = length - opts.skip; + if ((length > opts.count) && (opts.count != 0)) + length = opts.count; curpc = opts.basepc; for (curbyte = 0; curbyte < length; curbyte += numbytes) { - UINT8 *oprom = (UINT8 *)data + curbyte; + UINT8 *oprom = (UINT8 *)data + opts.skip + curbyte; char buffer[1024]; UINT32 pcdelta; int numchunks;