mirror of
https://github.com/holub/mame
synced 2025-07-02 16:49:22 +03:00
Preliminary hook up of sh3 dma from Haze + flash access code from Luca. (nw)
This commit is contained in:
parent
f8aba531d3
commit
6d00689c35
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -451,6 +451,8 @@ src/emu/cpu/sh4/sh4.h svneol=native#text/plain
|
||||
src/emu/cpu/sh4/sh4comn.c svneol=native#text/plain
|
||||
src/emu/cpu/sh4/sh4comn.h svneol=native#text/plain
|
||||
src/emu/cpu/sh4/sh4dasm.c svneol=native#text/plain
|
||||
src/emu/cpu/sh4/sh4dmac.c svneol=native#text/plain
|
||||
src/emu/cpu/sh4/sh4dmac.h svneol=native#text/plain
|
||||
src/emu/cpu/sh4/sh4regs.h svneol=native#text/plain
|
||||
src/emu/cpu/sh4/sh4tmu.c svneol=native#text/plain
|
||||
src/emu/cpu/sh4/sh4tmu.h svneol=native#text/plain
|
||||
|
@ -532,7 +532,7 @@ $(CPUOBJ)/sh2/sh2fe.o: $(CPUSRC)/sh2/sh2fe.c \
|
||||
|
||||
ifneq ($(filter SH4,$(CPUS)),)
|
||||
OBJDIRS += $(CPUOBJ)/sh4
|
||||
CPUOBJS += $(CPUOBJ)/sh4/sh4.o $(CPUOBJ)/sh4/sh4comn.o $(CPUOBJ)/sh4/sh3comn.o $(CPUOBJ)/sh4/sh4tmu.o
|
||||
CPUOBJS += $(CPUOBJ)/sh4/sh4.o $(CPUOBJ)/sh4/sh4comn.o $(CPUOBJ)/sh4/sh3comn.o $(CPUOBJ)/sh4/sh4tmu.o $(CPUOBJ)/sh4/sh4dmac.o
|
||||
DASMOBJS += $(CPUOBJ)/sh4/sh4dasm.o
|
||||
endif
|
||||
|
||||
@ -560,6 +560,16 @@ $(CPUOBJ)/sh4/sh4tmu.o: $(CPUSRC)/sh4/sh4tmu.c \
|
||||
$(CPUSRC)/sh4/sh4comn.h \
|
||||
$(CPUSRC)/sh4/sh3comn.h
|
||||
|
||||
$(CPUOBJ)/sh4/sh4dmac.o: $(CPUSRC)/sh4/sh4dmac.c \
|
||||
$(CPUSRC)/sh4/sh4dmac.h \
|
||||
$(CPUSRC)/sh4/sh3comn.c \
|
||||
$(CPUSRC)/sh4/sh3comn.h \
|
||||
$(CPUSRC)/sh4/sh4.c \
|
||||
$(CPUSRC)/sh4/sh4.h \
|
||||
$(CPUSRC)/sh4/sh4regs.h \
|
||||
$(CPUSRC)/sh4/sh4comn.h \
|
||||
$(CPUSRC)/sh4/sh3comn.h
|
||||
|
||||
#-------------------------------------------------
|
||||
# Hudsonsoft 6280
|
||||
#-------------------------------------------------
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "sh4comn.h"
|
||||
#include "sh3comn.h"
|
||||
#include "sh4tmu.h"
|
||||
#include "sh4dmac.h"
|
||||
|
||||
/* High internal area (ffffxxxx) */
|
||||
|
||||
WRITE32_HANDLER( sh3_internal_high_w )
|
||||
@ -145,6 +147,26 @@ READ32_HANDLER( sh3_internal_r )
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
|
||||
case SH3_SAR0_ADDR: return sh4_handle_sar0_addr_r(sh4,mem_mask);
|
||||
case SH3_SAR1_ADDR: return sh4_handle_sar1_addr_r(sh4,mem_mask);
|
||||
case SH3_SAR2_ADDR: return sh4_handle_sar2_addr_r(sh4,mem_mask);
|
||||
case SH3_SAR3_ADDR: return sh4_handle_sar3_addr_r(sh4,mem_mask);
|
||||
case SH3_DAR0_ADDR: return sh4_handle_dar0_addr_r(sh4,mem_mask);
|
||||
case SH3_DAR1_ADDR: return sh4_handle_dar1_addr_r(sh4,mem_mask);
|
||||
case SH3_DAR2_ADDR: return sh4_handle_dar2_addr_r(sh4,mem_mask);
|
||||
case SH3_DAR3_ADDR: return sh4_handle_dar3_addr_r(sh4,mem_mask);
|
||||
case SH3_DMATCR0_ADDR: return sh4_handle_dmatcr0_addr_r(sh4,mem_mask);
|
||||
case SH3_DMATCR1_ADDR: return sh4_handle_dmatcr1_addr_r(sh4,mem_mask);
|
||||
case SH3_DMATCR2_ADDR: return sh4_handle_dmatcr2_addr_r(sh4,mem_mask);
|
||||
case SH3_DMATCR3_ADDR: return sh4_handle_dmatcr3_addr_r(sh4,mem_mask);
|
||||
case SH3_CHCR0_ADDR: return sh4_handle_chcr0_addr_r(sh4,mem_mask);
|
||||
case SH3_CHCR1_ADDR: return sh4_handle_chcr1_addr_r(sh4,mem_mask);
|
||||
case SH3_CHCR2_ADDR: return sh4_handle_chcr2_addr_r(sh4,mem_mask);
|
||||
case SH3_CHCR3_ADDR: return sh4_handle_chcr3_addr_r(sh4,mem_mask);
|
||||
case SH3_DMAOR_ADDR: return sh4_handle_dmaor_addr_r(sh4,mem_mask)<<16;
|
||||
|
||||
|
||||
case INTEVT2:
|
||||
{
|
||||
// logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (INTEVT2)\n",sh4->device->tag(), sh4->pc & AM,(offset *4)+0x4000000,mem_mask);
|
||||
@ -248,6 +270,25 @@ WRITE32_HANDLER( sh3_internal_w )
|
||||
switch (offset)
|
||||
{
|
||||
|
||||
case SH3_SAR0_ADDR: sh4_handle_sar0_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_SAR1_ADDR: sh4_handle_sar1_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_SAR2_ADDR: sh4_handle_sar2_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_SAR3_ADDR: sh4_handle_sar3_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_DAR0_ADDR: sh4_handle_dar0_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_DAR1_ADDR: sh4_handle_dar1_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_DAR2_ADDR: sh4_handle_dar2_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_DAR3_ADDR: sh4_handle_dar3_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_DMATCR0_ADDR: sh4_handle_dmatcr0_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_DMATCR1_ADDR: sh4_handle_dmatcr1_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_DMATCR2_ADDR: sh4_handle_dmatcr2_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_DMATCR3_ADDR: sh4_handle_dmatcr3_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_CHCR0_ADDR: sh4_handle_chcr0_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_CHCR1_ADDR: sh4_handle_chcr1_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_CHCR2_ADDR: sh4_handle_chcr2_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_CHCR3_ADDR: sh4_handle_chcr3_addr_w(sh4,data,mem_mask); break;
|
||||
case SH3_DMAOR_ADDR: sh4_handle_dmaor_addr_w(sh4,data>>16,mem_mask>>16); break;
|
||||
|
||||
|
||||
case IRR0_IRR1:
|
||||
{
|
||||
{
|
||||
|
@ -11,6 +11,26 @@
|
||||
#define INTEVT2 ((0x4000000 - SH3_LOWER_REGBASE)/4)
|
||||
#define IRR0_IRR1 ((0x4000004 - SH3_LOWER_REGBASE)/4)
|
||||
#define PINTER_IPRC ((0x4000014 - SH3_LOWER_REGBASE)/4)
|
||||
|
||||
#define SH3_SAR0_ADDR ((0x4000020 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_DAR0_ADDR ((0x4000024 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_DMATCR0_ADDR ((0x4000028 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_CHCR0_ADDR ((0x400002c - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_SAR1_ADDR ((0x4000030 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_DAR1_ADDR ((0x4000034 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_DMATCR1_ADDR ((0x4000038 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_CHCR1_ADDR ((0x400003c - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_SAR2_ADDR ((0x4000040 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_DAR2_ADDR ((0x4000044 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_DMATCR2_ADDR ((0x4000048 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_CHCR2_ADDR ((0x400004c - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_SAR3_ADDR ((0x4000050 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_DAR3_ADDR ((0x4000054 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_DMATCR3_ADDR ((0x4000058 - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_CHCR3_ADDR ((0x400005c - SH3_LOWER_REGBASE)/4)
|
||||
#define SH3_DMAOR_ADDR ((0x4000060 - SH3_LOWER_REGBASE)/4)
|
||||
|
||||
|
||||
#define PCCR_PDCR ((0x4000104 - SH3_LOWER_REGBASE)/4)
|
||||
#define PECR_PFCR ((0x4000108 - SH3_LOWER_REGBASE)/4)
|
||||
#define PGCR_PHCR ((0x400010c - SH3_LOWER_REGBASE)/4)
|
||||
|
@ -3313,7 +3313,14 @@ static CPU_RESET( sh3 )
|
||||
CPU_RESET_CALL(common_sh4_reset);
|
||||
|
||||
sh4->cpu_type = CPU_TYPE_SH3;
|
||||
|
||||
|
||||
sh4->SH4_TCOR0 = 0xffffffff;
|
||||
sh4->SH4_TCNT0 = 0xffffffff;
|
||||
sh4->SH4_TCOR1 = 0xffffffff;
|
||||
sh4->SH4_TCNT1 = 0xffffffff;
|
||||
sh4->SH4_TCOR2 = 0xffffffff;
|
||||
sh4->SH4_TCNT2 = 0xffffffff;
|
||||
|
||||
}
|
||||
|
||||
static CPU_RESET( sh4 )
|
||||
|
@ -13,11 +13,11 @@
|
||||
#include "sh4comn.h"
|
||||
#include "sh3comn.h"
|
||||
#include "sh4tmu.h"
|
||||
|
||||
#include "sh4dmac.h"
|
||||
|
||||
static const int rtcnt_div[8] = { 0, 4, 16, 64, 256, 1024, 2048, 4096 };
|
||||
static const int daysmonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
static const int dmasize[8] = { 8, 1, 2, 4, 32, 0, 0, 0 };
|
||||
|
||||
|
||||
|
||||
static const UINT32 exception_priority_default[] = {
|
||||
@ -627,280 +627,11 @@ static TIMER_CALLBACK( sh4_rtc_timer_callback )
|
||||
}
|
||||
|
||||
|
||||
static TIMER_CALLBACK( sh4_dmac_callback )
|
||||
{
|
||||
sh4_state *sh4 = (sh4_state *)ptr;
|
||||
int channel = param;
|
||||
|
||||
if (sh4->cpu_type != CPU_TYPE_SH4)
|
||||
fatalerror("sh4_dmac_callback uses sh4->m[] with SH3\n");
|
||||
|
||||
LOG(("SH4 '%s': DMA %d complete\n", sh4->device->tag(), channel));
|
||||
sh4->dma_timer_active[channel] = 0;
|
||||
switch (channel)
|
||||
{
|
||||
case 0:
|
||||
sh4->m[DMATCR0] = 0;
|
||||
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] |= 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] |= 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] |= CHCR_TE;
|
||||
if (sh4->m[CHCR3] & CHCR_IE)
|
||||
sh4_exception_request(sh4, SH4_INTC_DMTE3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int sh4_dma_transfer(sh4_state *sh4, int channel, int timermode, UINT32 chcr, UINT32 *sar, UINT32 *dar, UINT32 *dmatcr)
|
||||
{
|
||||
int incs, incd, size;
|
||||
UINT32 src, dst, count;
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
src = *sar;
|
||||
dst = *dar;
|
||||
count = *dmatcr;
|
||||
if (!count)
|
||||
count = 0x1000000;
|
||||
|
||||
LOG(("SH4: DMA %d start %x, %x, %x, %04x, %d, %d, %d\n", channel, src, dst, count, chcr, incs, incd, size));
|
||||
|
||||
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) // timer activated immediately
|
||||
{
|
||||
sh4->dma_timer_active[channel] = 1;
|
||||
sh4->dma_timer[channel]->adjust(attotime::zero, channel);
|
||||
}
|
||||
|
||||
src &= AM;
|
||||
dst &= AM;
|
||||
|
||||
switch(size)
|
||||
{
|
||||
case 1: // 8 bit
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src --;
|
||||
if(incd == 2)
|
||||
dst --;
|
||||
sh4->program->write_byte(dst, sh4->program->read_byte(src));
|
||||
if(incs == 1)
|
||||
src ++;
|
||||
if(incd == 1)
|
||||
dst ++;
|
||||
}
|
||||
break;
|
||||
case 2: // 16 bit
|
||||
src &= ~1;
|
||||
dst &= ~1;
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src -= 2;
|
||||
if(incd == 2)
|
||||
dst -= 2;
|
||||
sh4->program->write_word(dst, sh4->program->read_word(src));
|
||||
if(incs == 1)
|
||||
src += 2;
|
||||
if(incd == 1)
|
||||
dst += 2;
|
||||
}
|
||||
break;
|
||||
case 8: // 64 bit
|
||||
src &= ~7;
|
||||
dst &= ~7;
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src -= 8;
|
||||
if(incd == 2)
|
||||
dst -= 8;
|
||||
sh4->program->write_qword(dst, sh4->program->read_qword(src));
|
||||
if(incs == 1)
|
||||
src += 8;
|
||||
if(incd == 1)
|
||||
dst += 8;
|
||||
|
||||
}
|
||||
break;
|
||||
case 4: // 32 bit
|
||||
src &= ~3;
|
||||
dst &= ~3;
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src -= 4;
|
||||
if(incd == 2)
|
||||
dst -= 4;
|
||||
sh4->program->write_dword(dst, sh4->program->read_dword(src));
|
||||
if(incs == 1)
|
||||
src += 4;
|
||||
if(incd == 1)
|
||||
dst += 4;
|
||||
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
src &= ~31;
|
||||
dst &= ~31;
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src -= 32;
|
||||
if(incd == 2)
|
||||
dst -= 32;
|
||||
sh4->program->write_qword(dst, sh4->program->read_qword(src));
|
||||
sh4->program->write_qword(dst+8, sh4->program->read_qword(src+8));
|
||||
sh4->program->write_qword(dst+16, sh4->program->read_qword(src+16));
|
||||
sh4->program->write_qword(dst+24, sh4->program->read_qword(src+24));
|
||||
if(incs == 1)
|
||||
src += 32;
|
||||
if(incd == 1)
|
||||
dst += 32;
|
||||
}
|
||||
break;
|
||||
}
|
||||
*sar = (*sar & !AM) | src;
|
||||
*dar = (*dar & !AM) | dst;
|
||||
*dmatcr = count;
|
||||
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;
|
||||
|
||||
if (sh4->cpu_type != CPU_TYPE_SH4)
|
||||
fatalerror("sh4_dmac_check uses sh4->m[] with SH3\n");
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case 0:
|
||||
sar = sh4->m[SAR0];
|
||||
dar = sh4->m[DAR0];
|
||||
chcr = sh4->m[CHCR0];
|
||||
dmatcr = sh4->m[DMATCR0];
|
||||
break;
|
||||
case 1:
|
||||
sar = sh4->m[SAR1];
|
||||
dar = sh4->m[DAR1];
|
||||
chcr = sh4->m[CHCR1];
|
||||
dmatcr = sh4->m[DMATCR1];
|
||||
break;
|
||||
case 2:
|
||||
sar = sh4->m[SAR2];
|
||||
dar = sh4->m[DAR2];
|
||||
chcr = sh4->m[CHCR2];
|
||||
dmatcr = sh4->m[DMATCR2];
|
||||
break;
|
||||
case 3:
|
||||
sar = sh4->m[SAR3];
|
||||
dar = sh4->m[DAR3];
|
||||
chcr = sh4->m[CHCR3];
|
||||
dmatcr = sh4->m[DMATCR3];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (chcr & sh4->m[DMAOR] & DMAOR_DME)
|
||||
{
|
||||
if ((((chcr & CHCR_RS) >> 8) < 2) || (((chcr & CHCR_RS) >> 8) > 6))
|
||||
return;
|
||||
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
|
||||
{
|
||||
if (sh4->dma_timer_active[channel])
|
||||
{
|
||||
logerror("SH4: DMA %d cancelled in-flight but all data transferred", channel);
|
||||
sh4->dma_timer[channel]->adjust(attotime::never, channel);
|
||||
sh4->dma_timer_active[channel] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sh4_dmac_nmi(sh4_state *sh4) // manage dma when nmi gets asserted
|
||||
{
|
||||
int s;
|
||||
int s;
|
||||
|
||||
if (sh4->cpu_type != CPU_TYPE_SH4)
|
||||
fatalerror("sh4_dmac_nmi uses sh4->m[] with SH3\n");
|
||||
|
||||
sh4->m[DMAOR] |= DMAOR_NMIF;
|
||||
sh4->SH4_DMAOR |= DMAOR_NMIF;
|
||||
for (s = 0;s < 4;s++)
|
||||
{
|
||||
if (sh4->dma_timer_active[s])
|
||||
@ -935,6 +666,7 @@ void sh4_handler_ipra_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
sh4_exception_recompute(sh4);
|
||||
}
|
||||
|
||||
|
||||
WRITE32_HANDLER( sh4_internal_w )
|
||||
{
|
||||
sh4_state *sh4 = get_safe_token(&space->device());
|
||||
@ -1089,50 +821,35 @@ WRITE32_HANDLER( sh4_internal_w )
|
||||
sh4->exception_priority[SH4_INTC_GPOI] = INTPRI((sh4->m[IPRC] & 0xf000) >> 12, SH4_INTC_GPOI);
|
||||
sh4_exception_recompute(sh4);
|
||||
break;
|
||||
|
||||
// DMA
|
||||
case SAR0:
|
||||
case SAR1:
|
||||
case SAR2:
|
||||
case SAR3:
|
||||
case DAR0:
|
||||
case DAR1:
|
||||
case DAR2:
|
||||
case DAR3:
|
||||
case DMATCR0:
|
||||
case DMATCR1:
|
||||
case DMATCR2:
|
||||
case DMATCR3:
|
||||
break;
|
||||
case CHCR0:
|
||||
sh4_dmac_check(sh4, 0);
|
||||
break;
|
||||
case CHCR1:
|
||||
sh4_dmac_check(sh4, 1);
|
||||
break;
|
||||
case CHCR2:
|
||||
sh4_dmac_check(sh4, 2);
|
||||
break;
|
||||
case CHCR3:
|
||||
sh4_dmac_check(sh4, 3);
|
||||
break;
|
||||
case DMAOR:
|
||||
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);
|
||||
sh4_dmac_check(sh4, 3);
|
||||
break;
|
||||
|
||||
// Store Queues
|
||||
/*********************************************************************************************************************
|
||||
DMAC (DMA Controller)
|
||||
*********************************************************************************************************************/
|
||||
case SH4_SAR0_ADDR: sh4_handle_sar0_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_SAR1_ADDR: sh4_handle_sar1_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_SAR2_ADDR: sh4_handle_sar2_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_SAR3_ADDR: sh4_handle_sar3_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_DAR0_ADDR: sh4_handle_dar0_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_DAR1_ADDR: sh4_handle_dar1_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_DAR2_ADDR: sh4_handle_dar2_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_DAR3_ADDR: sh4_handle_dar3_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_DMATCR0_ADDR: sh4_handle_dmatcr0_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_DMATCR1_ADDR: sh4_handle_dmatcr1_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_DMATCR2_ADDR: sh4_handle_dmatcr2_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_DMATCR3_ADDR: sh4_handle_dmatcr3_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_CHCR0_ADDR: sh4_handle_chcr0_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_CHCR1_ADDR: sh4_handle_chcr1_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_CHCR2_ADDR: sh4_handle_chcr2_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_CHCR3_ADDR: sh4_handle_chcr3_addr_w(sh4,data,mem_mask); break;
|
||||
case SH4_DMAOR_ADDR: sh4_handle_dmaor_addr_w(sh4,data,mem_mask); break;
|
||||
/*********************************************************************************************************************
|
||||
Store Queues
|
||||
*********************************************************************************************************************/
|
||||
case QACR0:
|
||||
case QACR1:
|
||||
break;
|
||||
|
||||
// I/O ports
|
||||
/*********************************************************************************************************************
|
||||
I/O
|
||||
*********************************************************************************************************************/
|
||||
case PCTRA:
|
||||
sh4->ioport16_pullup = 0;
|
||||
sh4->ioport16_direction = 0;
|
||||
@ -1234,6 +951,26 @@ READ32_HANDLER( sh4_internal_r )
|
||||
case SH4_TCOR2_ADDR: return sh4_handle_tcor2_addr_r(sh4, mem_mask);
|
||||
case SH4_TOCR_ADDR: return sh4_handle_tocr_addr_r(sh4, mem_mask); // not supported
|
||||
case SH4_TCPR2_ADDR: return sh4_handle_tcpr2_addr_r(sh4, mem_mask); // not supported
|
||||
/*********************************************************************************************************************
|
||||
DMAC (DMA Controller)
|
||||
*********************************************************************************************************************/
|
||||
case SH4_SAR0_ADDR: return sh4_handle_sar0_addr_r(sh4,mem_mask);
|
||||
case SH4_SAR1_ADDR: return sh4_handle_sar1_addr_r(sh4,mem_mask);
|
||||
case SH4_SAR2_ADDR: return sh4_handle_sar2_addr_r(sh4,mem_mask);
|
||||
case SH4_SAR3_ADDR: return sh4_handle_sar3_addr_r(sh4,mem_mask);
|
||||
case SH4_DAR0_ADDR: return sh4_handle_dar0_addr_r(sh4,mem_mask);
|
||||
case SH4_DAR1_ADDR: return sh4_handle_dar1_addr_r(sh4,mem_mask);
|
||||
case SH4_DAR2_ADDR: return sh4_handle_dar2_addr_r(sh4,mem_mask);
|
||||
case SH4_DAR3_ADDR: return sh4_handle_dar3_addr_r(sh4,mem_mask);
|
||||
case SH4_DMATCR0_ADDR: return sh4_handle_dmatcr0_addr_r(sh4,mem_mask);
|
||||
case SH4_DMATCR1_ADDR: return sh4_handle_dmatcr1_addr_r(sh4,mem_mask);
|
||||
case SH4_DMATCR2_ADDR: return sh4_handle_dmatcr2_addr_r(sh4,mem_mask);
|
||||
case SH4_DMATCR3_ADDR: return sh4_handle_dmatcr3_addr_r(sh4,mem_mask);
|
||||
case SH4_CHCR0_ADDR: return sh4_handle_chcr0_addr_r(sh4,mem_mask);
|
||||
case SH4_CHCR1_ADDR: return sh4_handle_chcr1_addr_r(sh4,mem_mask);
|
||||
case SH4_CHCR2_ADDR: return sh4_handle_chcr2_addr_r(sh4,mem_mask);
|
||||
case SH4_CHCR3_ADDR: return sh4_handle_chcr3_addr_r(sh4,mem_mask);
|
||||
case SH4_DMAOR_ADDR: return sh4_handle_dmaor_addr_r(sh4,mem_mask);
|
||||
/*********************************************************************************************************************
|
||||
I/O Ports
|
||||
*********************************************************************************************************************/
|
||||
@ -1491,270 +1228,6 @@ 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);
|
||||
UINT32 chcr;
|
||||
UINT32 *p32bits;
|
||||
UINT64 *p32bytes;
|
||||
UINT32 pos,len,siz;
|
||||
|
||||
if (sh4->cpu_type != CPU_TYPE_SH4)
|
||||
fatalerror("sh4_dma_ddt uses sh4->m[] with SH3\n");
|
||||
|
||||
if (sh4->dma_timer_active[s->channel])
|
||||
return;
|
||||
if (s->mode >= 0) {
|
||||
switch (s->channel)
|
||||
{
|
||||
case 0:
|
||||
if (s->mode & 1)
|
||||
s->source = sh4->m[SAR0];
|
||||
if (s->mode & 2)
|
||||
sh4->m[SAR0] = s->source;
|
||||
if (s->mode & 4)
|
||||
s->destination = sh4->m[DAR0];
|
||||
if (s->mode & 8)
|
||||
sh4->m[DAR0] = s->destination;
|
||||
break;
|
||||
case 1:
|
||||
if (s->mode & 1)
|
||||
s->source = sh4->m[SAR1];
|
||||
if (s->mode & 2)
|
||||
sh4->m[SAR1] = s->source;
|
||||
if (s->mode & 4)
|
||||
s->destination = sh4->m[DAR1];
|
||||
if (s->mode & 8)
|
||||
sh4->m[DAR1] = s->destination;
|
||||
break;
|
||||
case 2:
|
||||
if (s->mode & 1)
|
||||
s->source = sh4->m[SAR2];
|
||||
if (s->mode & 2)
|
||||
sh4->m[SAR2] = s->source;
|
||||
if (s->mode & 4)
|
||||
s->destination = sh4->m[DAR2];
|
||||
if (s->mode & 8)
|
||||
sh4->m[DAR2] = s->destination;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
if (s->mode & 1)
|
||||
s->source = sh4->m[SAR3];
|
||||
if (s->mode & 2)
|
||||
sh4->m[SAR3] = s->source;
|
||||
if (s->mode & 4)
|
||||
s->destination = sh4->m[DAR3];
|
||||
if (s->mode & 8)
|
||||
sh4->m[DAR3] = s->destination;
|
||||
break;
|
||||
}
|
||||
switch (s->channel)
|
||||
{
|
||||
case 0:
|
||||
chcr = sh4->m[CHCR0];
|
||||
len = sh4->m[DMATCR0];
|
||||
break;
|
||||
case 1:
|
||||
chcr = sh4->m[CHCR1];
|
||||
len = sh4->m[DMATCR1];
|
||||
break;
|
||||
case 2:
|
||||
chcr = sh4->m[CHCR2];
|
||||
len = sh4->m[DMATCR2];
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
chcr = sh4->m[CHCR3];
|
||||
len = sh4->m[DMATCR3];
|
||||
break;
|
||||
}
|
||||
if ((s->direction) == 0) {
|
||||
chcr = (chcr & 0xffff3fff) | ((s->mode & 0x30) << 10);
|
||||
} else {
|
||||
chcr = (chcr & 0xffffcfff) | ((s->mode & 0x30) << 8);
|
||||
}
|
||||
siz = dmasize[(chcr >> 4) & 7];
|
||||
if (siz && (s->size))
|
||||
if ((len * siz) != (s->length * s->size))
|
||||
return;
|
||||
sh4_dma_transfer(sh4, s->channel, 0, chcr, &s->source, &s->destination, &len);
|
||||
} else {
|
||||
if (s->size == 4) {
|
||||
if ((s->direction) == 0) {
|
||||
len = s->length;
|
||||
p32bits = (UINT32 *)(s->buffer);
|
||||
for (pos = 0;pos < len;pos++) {
|
||||
*p32bits = sh4->program->read_dword(s->source);
|
||||
p32bits++;
|
||||
s->source = s->source + 4;
|
||||
}
|
||||
} else {
|
||||
len = s->length;
|
||||
p32bits = (UINT32 *)(s->buffer);
|
||||
for (pos = 0;pos < len;pos++) {
|
||||
sh4->program->write_dword(s->destination, *p32bits);
|
||||
p32bits++;
|
||||
s->destination = s->destination + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (s->size == 32) {
|
||||
if ((s->direction) == 0) {
|
||||
len = s->length * 4;
|
||||
p32bytes = (UINT64 *)(s->buffer);
|
||||
for (pos = 0;pos < len;pos++) {
|
||||
*p32bytes = sh4->program->read_qword(s->source);
|
||||
p32bytes++;
|
||||
s->destination = s->destination + 8;
|
||||
}
|
||||
} else {
|
||||
len = s->length * 4;
|
||||
p32bytes = (UINT64 *)(s->buffer);
|
||||
for (pos = 0;pos < len;pos++) {
|
||||
sh4->program->write_qword(s->destination, *p32bytes);
|
||||
p32bytes++;
|
||||
s->destination = s->destination + 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 sh4_getsqremap(sh4_state *sh4, UINT32 address)
|
||||
{
|
||||
if (!sh4->sh4_mmu_enabled)
|
||||
|
@ -101,6 +101,29 @@ typedef struct
|
||||
|
||||
UINT32 SH4_IPRC;
|
||||
|
||||
// DMAC regs
|
||||
UINT32 SH4_SAR0;
|
||||
UINT32 SH4_SAR1;
|
||||
UINT32 SH4_SAR2;
|
||||
UINT32 SH4_SAR3;
|
||||
|
||||
UINT32 SH4_DAR0;
|
||||
UINT32 SH4_DAR1;
|
||||
UINT32 SH4_DAR2;
|
||||
UINT32 SH4_DAR3;
|
||||
|
||||
UINT32 SH4_CHCR0;
|
||||
UINT32 SH4_CHCR1;
|
||||
UINT32 SH4_CHCR2;
|
||||
UINT32 SH4_CHCR3;
|
||||
|
||||
UINT32 SH4_DMATCR0;
|
||||
UINT32 SH4_DMATCR1;
|
||||
UINT32 SH4_DMATCR2;
|
||||
UINT32 SH4_DMATCR3;
|
||||
|
||||
UINT32 SH4_DMAOR;
|
||||
|
||||
|
||||
// sh3 internal
|
||||
UINT32 m_sh3internal_upper[0x3000/4];
|
||||
|
686
src/emu/cpu/sh4/sh4dmac.c
Normal file
686
src/emu/cpu/sh4/sh4dmac.c
Normal file
@ -0,0 +1,686 @@
|
||||
/* SHA3/4 DMA Controller */
|
||||
|
||||
#include "emu.h"
|
||||
#include "debugger.h"
|
||||
#include "sh4.h"
|
||||
#include "sh4comn.h"
|
||||
#include "sh3comn.h"
|
||||
#include "sh4dmac.h"
|
||||
|
||||
static const int dmasize[8] = { 8, 1, 2, 4, 32, 0, 0, 0 };
|
||||
|
||||
static const int sh3_dmasize[4] = { 1, 2, 4, 16 };
|
||||
|
||||
TIMER_CALLBACK( sh4_dmac_callback )
|
||||
{
|
||||
sh4_state *sh4 = (sh4_state *)ptr;
|
||||
int channel = param;
|
||||
|
||||
LOG(("SH4 '%s': DMA %d complete\n", sh4->device->tag(), channel));
|
||||
sh4->dma_timer_active[channel] = 0;
|
||||
switch (channel)
|
||||
{
|
||||
case 0:
|
||||
sh4->SH4_DMATCR0 = 0;
|
||||
sh4->SH4_CHCR0 |= CHCR_TE;
|
||||
if (sh4->SH4_CHCR0 & CHCR_IE)
|
||||
sh4_exception_request(sh4, SH4_INTC_DMTE0);
|
||||
break;
|
||||
case 1:
|
||||
sh4->SH4_DMATCR1 = 0;
|
||||
sh4->SH4_CHCR1 |= CHCR_TE;
|
||||
if (sh4->SH4_CHCR1 & CHCR_IE)
|
||||
sh4_exception_request(sh4, SH4_INTC_DMTE1);
|
||||
break;
|
||||
case 2:
|
||||
sh4->SH4_DMATCR2 = 0;
|
||||
sh4->SH4_CHCR2 |= CHCR_TE;
|
||||
if (sh4->SH4_CHCR2 & CHCR_IE)
|
||||
sh4_exception_request(sh4, SH4_INTC_DMTE2);
|
||||
break;
|
||||
case 3:
|
||||
sh4->SH4_DMATCR3 = 0;
|
||||
sh4->SH4_CHCR3 |= CHCR_TE;
|
||||
if (sh4->SH4_CHCR3 & CHCR_IE)
|
||||
sh4_exception_request(sh4, SH4_INTC_DMTE3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int sh4_dma_transfer(sh4_state *sh4, int channel, int timermode, UINT32 chcr, UINT32 *sar, UINT32 *dar, UINT32 *dmatcr)
|
||||
{
|
||||
int incs, incd, size;
|
||||
UINT32 src, dst, count;
|
||||
|
||||
incd = (chcr & CHCR_DM) >> 14;
|
||||
incs = (chcr & CHCR_SM) >> 12;
|
||||
|
||||
if (sh4->cpu_type == CPU_TYPE_SH4)
|
||||
{
|
||||
size = dmasize[(chcr & CHCR_TS) >> 4];
|
||||
}
|
||||
else
|
||||
{
|
||||
size = sh3_dmasize[(chcr >> 3) & 3];
|
||||
}
|
||||
|
||||
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 %x, %x, %x, %04x, %d, %d, %d\n", channel, src, dst, count, chcr, incs, incd, size));
|
||||
|
||||
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) // timer activated immediately
|
||||
{
|
||||
sh4->dma_timer_active[channel] = 1;
|
||||
sh4->dma_timer[channel]->adjust(attotime::zero, channel);
|
||||
}
|
||||
|
||||
src &= AM;
|
||||
dst &= AM;
|
||||
|
||||
switch(size)
|
||||
{
|
||||
case 1: // 8 bit
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src --;
|
||||
if(incd == 2)
|
||||
dst --;
|
||||
sh4->program->write_byte(dst, sh4->program->read_byte(src));
|
||||
if(incs == 1)
|
||||
src ++;
|
||||
if(incd == 1)
|
||||
dst ++;
|
||||
}
|
||||
break;
|
||||
case 2: // 16 bit
|
||||
src &= ~1;
|
||||
dst &= ~1;
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src -= 2;
|
||||
if(incd == 2)
|
||||
dst -= 2;
|
||||
sh4->program->write_word(dst, sh4->program->read_word(src));
|
||||
if(incs == 1)
|
||||
src += 2;
|
||||
if(incd == 1)
|
||||
dst += 2;
|
||||
}
|
||||
break;
|
||||
case 8: // 64 bit
|
||||
src &= ~7;
|
||||
dst &= ~7;
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src -= 8;
|
||||
if(incd == 2)
|
||||
dst -= 8;
|
||||
sh4->program->write_qword(dst, sh4->program->read_qword(src));
|
||||
if(incs == 1)
|
||||
src += 8;
|
||||
if(incd == 1)
|
||||
dst += 8;
|
||||
|
||||
}
|
||||
break;
|
||||
case 4: // 32 bit
|
||||
src &= ~3;
|
||||
dst &= ~3;
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src -= 4;
|
||||
if(incd == 2)
|
||||
dst -= 4;
|
||||
sh4->program->write_dword(dst, sh4->program->read_dword(src));
|
||||
if(incs == 1)
|
||||
src += 4;
|
||||
if(incd == 1)
|
||||
dst += 4;
|
||||
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
src &= ~31;
|
||||
dst &= ~31;
|
||||
for(;count > 0; count --)
|
||||
{
|
||||
if(incs == 2)
|
||||
src -= 32;
|
||||
if(incd == 2)
|
||||
dst -= 32;
|
||||
sh4->program->write_qword(dst, sh4->program->read_qword(src));
|
||||
sh4->program->write_qword(dst+8, sh4->program->read_qword(src+8));
|
||||
sh4->program->write_qword(dst+16, sh4->program->read_qword(src+16));
|
||||
sh4->program->write_qword(dst+24, sh4->program->read_qword(src+24));
|
||||
if(incs == 1)
|
||||
src += 32;
|
||||
if(incd == 1)
|
||||
dst += 32;
|
||||
}
|
||||
break;
|
||||
}
|
||||
*sar = (*sar & !AM) | src;
|
||||
*dar = (*dar & !AM) | dst;
|
||||
*dmatcr = count;
|
||||
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;
|
||||
|
||||
|
||||
if (sh4->cpu_type == CPU_TYPE_SH4)
|
||||
{
|
||||
size = dmasize[(chcr & CHCR_TS) >> 4];
|
||||
}
|
||||
else
|
||||
{
|
||||
size = sh3_dmasize[(chcr >> 3) & 3];
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case 0:
|
||||
sar = sh4->SH4_SAR0;
|
||||
dar = sh4->SH4_DAR0;
|
||||
chcr = sh4->SH4_CHCR0;
|
||||
dmatcr = sh4->SH4_DMATCR0;
|
||||
break;
|
||||
case 1:
|
||||
sar = sh4->SH4_SAR1;
|
||||
dar = sh4->SH4_DAR1;
|
||||
chcr = sh4->SH4_CHCR1;
|
||||
dmatcr = sh4->SH4_DMATCR1;
|
||||
break;
|
||||
case 2:
|
||||
sar = sh4->SH4_SAR2;
|
||||
dar = sh4->SH4_DAR2;
|
||||
chcr = sh4->SH4_CHCR2;
|
||||
dmatcr = sh4->SH4_DMATCR2;
|
||||
break;
|
||||
case 3:
|
||||
sar = sh4->SH4_SAR3;
|
||||
dar = sh4->SH4_DAR3;
|
||||
chcr = sh4->SH4_CHCR3;
|
||||
dmatcr = sh4->SH4_DMATCR3;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (chcr & sh4->SH4_DMAOR & DMAOR_DME)
|
||||
{
|
||||
if ((((chcr & CHCR_RS) >> 8) < 2) || (((chcr & CHCR_RS) >> 8) > 6))
|
||||
return;
|
||||
if (!sh4->dma_timer_active[channel] && !(chcr & CHCR_TE) && !(sh4->SH4_DMAOR & (DMAOR_AE | DMAOR_NMIF)))
|
||||
{
|
||||
if (((chcr & CHCR_RS) >> 8) > 3)
|
||||
sh4_dma_transfer(sh4, channel, 1, chcr, &sar, &dar, &dmatcr);
|
||||
else if ((sh4->SH4_DMAOR & DMAOR_DDT) == 0)
|
||||
sh4_dma_transfer_device(sh4, channel, chcr, &sar, &dar, &dmatcr); // tell device we are ready to transfer
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sh4->dma_timer_active[channel])
|
||||
{
|
||||
logerror("SH4: DMA %d cancelled in-flight but all data transferred", channel);
|
||||
sh4->dma_timer[channel]->adjust(attotime::never, channel);
|
||||
sh4->dma_timer_active[channel] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
UINT32 chcr;
|
||||
UINT32 *p32bits;
|
||||
UINT64 *p32bytes;
|
||||
UINT32 pos,len,siz;
|
||||
|
||||
if (sh4->cpu_type != CPU_TYPE_SH4)
|
||||
fatalerror("sh4_dma_ddt uses sh4->m[] with SH3\n");
|
||||
|
||||
if (sh4->dma_timer_active[s->channel])
|
||||
return;
|
||||
if (s->mode >= 0) {
|
||||
switch (s->channel)
|
||||
{
|
||||
case 0:
|
||||
if (s->mode & 1)
|
||||
s->source = sh4->SH4_SAR0;
|
||||
if (s->mode & 2)
|
||||
sh4->SH4_SAR0 = s->source;
|
||||
if (s->mode & 4)
|
||||
s->destination = sh4->SH4_DAR0;
|
||||
if (s->mode & 8)
|
||||
sh4->SH4_DAR0 = s->destination;
|
||||
break;
|
||||
case 1:
|
||||
if (s->mode & 1)
|
||||
s->source = sh4->SH4_SAR1;
|
||||
if (s->mode & 2)
|
||||
sh4->SH4_SAR1 = s->source;
|
||||
if (s->mode & 4)
|
||||
s->destination = sh4->SH4_DAR1;
|
||||
if (s->mode & 8)
|
||||
sh4->SH4_DAR1 = s->destination;
|
||||
break;
|
||||
case 2:
|
||||
if (s->mode & 1)
|
||||
s->source = sh4->SH4_SAR2;
|
||||
if (s->mode & 2)
|
||||
sh4->SH4_SAR2 = s->source;
|
||||
if (s->mode & 4)
|
||||
s->destination = sh4->SH4_DAR2;
|
||||
if (s->mode & 8)
|
||||
sh4->SH4_DAR2 = s->destination;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
if (s->mode & 1)
|
||||
s->source = sh4->SH4_SAR3;
|
||||
if (s->mode & 2)
|
||||
sh4->SH4_SAR3 = s->source;
|
||||
if (s->mode & 4)
|
||||
s->destination = sh4->SH4_DAR3;
|
||||
if (s->mode & 8)
|
||||
sh4->SH4_DAR3 = s->destination;
|
||||
break;
|
||||
}
|
||||
switch (s->channel)
|
||||
{
|
||||
case 0:
|
||||
chcr = sh4->SH4_CHCR0;
|
||||
len = sh4->SH4_DMATCR0;
|
||||
break;
|
||||
case 1:
|
||||
chcr = sh4->SH4_CHCR1;
|
||||
len = sh4->SH4_DMATCR1;
|
||||
break;
|
||||
case 2:
|
||||
chcr = sh4->SH4_CHCR2;
|
||||
len = sh4->SH4_DMATCR2;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
chcr = sh4->SH4_CHCR3;
|
||||
len = sh4->SH4_DMATCR3;
|
||||
break;
|
||||
}
|
||||
if ((s->direction) == 0) {
|
||||
chcr = (chcr & 0xffff3fff) | ((s->mode & 0x30) << 10);
|
||||
} else {
|
||||
chcr = (chcr & 0xffffcfff) | ((s->mode & 0x30) << 8);
|
||||
}
|
||||
|
||||
|
||||
if (sh4->cpu_type == CPU_TYPE_SH4)
|
||||
{
|
||||
//siz = dmasize[(chcr & CHCR_TS) >> 4];
|
||||
siz = dmasize[(chcr >> 4) & 7];
|
||||
}
|
||||
else
|
||||
{
|
||||
siz = sh3_dmasize[(chcr >> 3) & 3];
|
||||
}
|
||||
|
||||
|
||||
if (siz && (s->size))
|
||||
if ((len * siz) != (s->length * s->size))
|
||||
return;
|
||||
sh4_dma_transfer(sh4, s->channel, 0, chcr, &s->source, &s->destination, &len);
|
||||
} else {
|
||||
if (s->size == 4) {
|
||||
if ((s->direction) == 0) {
|
||||
len = s->length;
|
||||
p32bits = (UINT32 *)(s->buffer);
|
||||
for (pos = 0;pos < len;pos++) {
|
||||
*p32bits = sh4->program->read_dword(s->source);
|
||||
p32bits++;
|
||||
s->source = s->source + 4;
|
||||
}
|
||||
} else {
|
||||
len = s->length;
|
||||
p32bits = (UINT32 *)(s->buffer);
|
||||
for (pos = 0;pos < len;pos++) {
|
||||
sh4->program->write_dword(s->destination, *p32bits);
|
||||
p32bits++;
|
||||
s->destination = s->destination + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (s->size == 32) {
|
||||
if ((s->direction) == 0) {
|
||||
len = s->length * 4;
|
||||
p32bytes = (UINT64 *)(s->buffer);
|
||||
for (pos = 0;pos < len;pos++) {
|
||||
*p32bytes = sh4->program->read_qword(s->source);
|
||||
p32bytes++;
|
||||
s->destination = s->destination + 8;
|
||||
}
|
||||
} else {
|
||||
len = s->length * 4;
|
||||
p32bytes = (UINT64 *)(s->buffer);
|
||||
for (pos = 0;pos < len;pos++) {
|
||||
sh4->program->write_qword(s->destination, *p32bytes);
|
||||
p32bytes++;
|
||||
s->destination = s->destination + 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sh4_handle_sar0_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_SAR0);
|
||||
}
|
||||
|
||||
void sh4_handle_sar1_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_SAR1);
|
||||
}
|
||||
|
||||
void sh4_handle_sar2_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_SAR2);
|
||||
}
|
||||
|
||||
void sh4_handle_sar3_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_SAR3);
|
||||
}
|
||||
|
||||
void sh4_handle_dar0_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_DAR0);
|
||||
}
|
||||
|
||||
void sh4_handle_dar1_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_DAR1);
|
||||
}
|
||||
|
||||
void sh4_handle_dar2_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_DAR2);
|
||||
}
|
||||
|
||||
void sh4_handle_dar3_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_DAR3);
|
||||
}
|
||||
|
||||
void sh4_handle_dmatcr0_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_DMATCR0);
|
||||
}
|
||||
|
||||
void sh4_handle_dmatcr1_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_DMATCR1);
|
||||
}
|
||||
|
||||
void sh4_handle_dmatcr2_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_DMATCR2);
|
||||
}
|
||||
|
||||
void sh4_handle_dmatcr3_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_DMATCR3);
|
||||
}
|
||||
|
||||
void sh4_handle_chcr0_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_CHCR0);
|
||||
sh4_dmac_check(sh4, 0);
|
||||
}
|
||||
|
||||
void sh4_handle_chcr1_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_CHCR1);
|
||||
sh4_dmac_check(sh4, 1);
|
||||
}
|
||||
|
||||
void sh4_handle_chcr2_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_CHCR2);
|
||||
sh4_dmac_check(sh4, 2);
|
||||
}
|
||||
|
||||
void sh4_handle_chcr3_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&sh4->SH4_CHCR3);
|
||||
sh4_dmac_check(sh4, 3);
|
||||
}
|
||||
|
||||
void sh4_handle_dmaor_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
UINT32 old = sh4->SH4_DMAOR;
|
||||
COMBINE_DATA(&sh4->SH4_DMAOR);
|
||||
|
||||
if ((sh4->SH4_DMAOR & DMAOR_AE) && (~old & DMAOR_AE))
|
||||
sh4->SH4_DMAOR &= ~DMAOR_AE;
|
||||
if ((sh4->SH4_DMAOR & DMAOR_NMIF) && (~old & DMAOR_NMIF))
|
||||
sh4->SH4_DMAOR &= ~DMAOR_NMIF;
|
||||
sh4_dmac_check(sh4, 0);
|
||||
sh4_dmac_check(sh4, 1);
|
||||
sh4_dmac_check(sh4, 2);
|
||||
sh4_dmac_check(sh4, 3);
|
||||
}
|
||||
|
||||
UINT32 sh4_handle_sar0_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_SAR0; }
|
||||
UINT32 sh4_handle_sar1_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_SAR1; }
|
||||
UINT32 sh4_handle_sar2_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_SAR2; }
|
||||
UINT32 sh4_handle_sar3_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_SAR3; }
|
||||
UINT32 sh4_handle_dar0_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_DAR0; }
|
||||
UINT32 sh4_handle_dar1_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_DAR1; }
|
||||
UINT32 sh4_handle_dar2_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_DAR2; }
|
||||
UINT32 sh4_handle_dar3_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_DAR3; }
|
||||
UINT32 sh4_handle_dmatcr0_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_DMATCR0; }
|
||||
UINT32 sh4_handle_dmatcr1_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_DMATCR1; }
|
||||
UINT32 sh4_handle_dmatcr2_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_DMATCR2; }
|
||||
UINT32 sh4_handle_dmatcr3_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_DMATCR3; }
|
||||
UINT32 sh4_handle_chcr0_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_CHCR0; }
|
||||
UINT32 sh4_handle_chcr1_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_CHCR1; }
|
||||
UINT32 sh4_handle_chcr2_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_CHCR2; }
|
||||
UINT32 sh4_handle_chcr3_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_CHCR3; }
|
||||
UINT32 sh4_handle_dmaor_addr_r(sh4_state *sh4, UINT32 mem_mask) { return sh4->SH4_DMAOR; }
|
63
src/emu/cpu/sh4/sh4dmac.h
Normal file
63
src/emu/cpu/sh4/sh4dmac.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* SHA3/4 DMA Controller */
|
||||
|
||||
/* 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
|
||||
|
||||
TIMER_CALLBACK( sh4_dmac_callback );
|
||||
|
||||
void sh4_handle_sar0_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_sar1_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_sar2_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_sar3_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_dar0_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_dar1_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_dar2_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_dar3_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_dmatcr0_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_dmatcr1_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_dmatcr2_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_dmatcr3_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_chcr0_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_chcr1_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_chcr2_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_chcr3_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
void sh4_handle_dmaor_addr_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_sar0_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_sar1_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_sar2_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_sar3_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_dar0_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_dar1_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_dar2_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_dar3_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_dmatcr0_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_dmatcr1_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_dmatcr2_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_dmatcr3_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_chcr0_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_chcr1_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_chcr2_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_chcr3_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
||||
UINT32 sh4_handle_dmaor_addr_r(sh4_state *sh4, UINT32 mem_mask);
|
@ -49,23 +49,23 @@
|
||||
#define GPIOIC 0x3012 /* FF800048 */
|
||||
#define SDMR2 0x3200 /* FF900000 */
|
||||
#define SDMR3 0x3280 /* FF940000 */
|
||||
#define SAR0 0x3400 /* FFA00000 */
|
||||
#define DAR0 0x3401 /* FFA00004 */
|
||||
#define DMATCR0 0x3402 /* FFA00008 */
|
||||
#define CHCR0 0x3403 /* FFA0000C */
|
||||
#define SAR1 0x3404 /* FFA00010 */
|
||||
#define DAR1 0x3405 /* FFA00014 */
|
||||
#define DMATCR1 0x3406 /* FFA00018 */
|
||||
#define CHCR1 0x3407 /* FFA0001C */
|
||||
#define SAR2 0x3408 /* FFA00020 */
|
||||
#define DAR2 0x3409 /* FFA00024 */
|
||||
#define DMATCR2 0x340A /* FFA00028 */
|
||||
#define CHCR2 0x340B /* FFA0002C */
|
||||
#define SAR3 0x340C /* FFA00030 */
|
||||
#define DAR3 0x340D /* FFA00034 */
|
||||
#define DMATCR3 0x340E /* FFA00038 */
|
||||
#define CHCR3 0x340F /* FFA0003C */
|
||||
#define DMAOR 0x3410 /* FFA00040 */
|
||||
#define SH4_SAR0_ADDR 0x3400 /* FFA00000 */
|
||||
#define SH4_DAR0_ADDR 0x3401 /* FFA00004 */
|
||||
#define SH4_DMATCR0_ADDR 0x3402 /* FFA00008 */
|
||||
#define SH4_CHCR0_ADDR 0x3403 /* FFA0000C */
|
||||
#define SH4_SAR1_ADDR 0x3404 /* FFA00010 */
|
||||
#define SH4_DAR1_ADDR 0x3405 /* FFA00014 */
|
||||
#define SH4_DMATCR1_ADDR 0x3406 /* FFA00018 */
|
||||
#define SH4_CHCR1_ADDR 0x3407 /* FFA0001C */
|
||||
#define SH4_SAR2_ADDR 0x3408 /* FFA00020 */
|
||||
#define SH4_DAR2_ADDR 0x3409 /* FFA00024 */
|
||||
#define SH4_DMATCR2_ADDR 0x340A /* FFA00028 */
|
||||
#define SH4_CHCR2_ADDR 0x340B /* FFA0002C */
|
||||
#define SH4_SAR3_ADDR 0x340C /* FFA00030 */
|
||||
#define SH4_DAR3_ADDR 0x340D /* FFA00034 */
|
||||
#define SH4_DMATCR3_ADDR 0x340E /* FFA00038 */
|
||||
#define SH4_CHCR3_ADDR 0x340F /* FFA0003C */
|
||||
#define SH4_DMAOR_ADDR 0x3410 /* FFA00040 */
|
||||
#define SAR4 0x3414 /* FFA00050 */
|
||||
#define DAR4 0x3415 /* FFA00054 */
|
||||
#define DMATCR4 0x3416 /* FFA00058 */
|
||||
@ -158,30 +158,7 @@
|
||||
#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
|
||||
|
@ -6,12 +6,12 @@
|
||||
#include "cpu/sh4/sh4.h"
|
||||
|
||||
|
||||
|
||||
class cavesh3_state : public driver_device
|
||||
{
|
||||
public:
|
||||
cavesh3_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag) { }
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -26,37 +26,22 @@ SCREEN_UPDATE(cavesh3)
|
||||
|
||||
|
||||
|
||||
static READ64_HANDLER( serial_rtc_eeprom_r )
|
||||
|
||||
static READ32_HANDLER( cavesh3_blitter_r )
|
||||
{
|
||||
if (mem_mask & U64(0xff00ffffffffffff))
|
||||
{
|
||||
logerror("unknown serial_rtc_eeprom_r access %08x%08x\n",(UINT32)(mem_mask>>32),(UINT32)(mem_mask&0xffffffff));
|
||||
}
|
||||
// UINT64 ret = space->machine().rand();
|
||||
static UINT32 i = 0;
|
||||
i^=0xffffffff;
|
||||
|
||||
return (UINT64)(space->machine().rand()&0xff)<<(32+16);
|
||||
}
|
||||
|
||||
static WRITE64_HANDLER( serial_rtc_eeprom_w )
|
||||
{
|
||||
if (mem_mask & U64(0xff000000ffffffff))
|
||||
{
|
||||
logerror("unknown serial_rtc_eeprom_w access %08x%08x\n",(UINT32)(mem_mask>>32),(UINT32)(mem_mask&0xffffffff));
|
||||
}
|
||||
}
|
||||
|
||||
static READ64_HANDLER( cavesh3_blitter_r )
|
||||
{
|
||||
UINT64 ret = space->machine().rand();
|
||||
|
||||
logerror("cavesh3_blitter_r access at %08x (%08x) - mem_mask %08x%08x\n",offset, offset*8, (UINT32)(mem_mask>>32),(UINT32)(mem_mask&0xffffffff));
|
||||
logerror("%08x cavesh3_blitter_r access at %08x (%08x) - mem_mask %08x\n",cpu_get_pc(&space->device()), offset, offset*4, mem_mask);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
|
||||
case 0x2:
|
||||
return ret ^ (ret<<32);
|
||||
|
||||
case 0x4:
|
||||
return i;
|
||||
|
||||
case 0x9:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
@ -71,9 +56,9 @@ static READ64_HANDLER( cavesh3_blitter_r )
|
||||
|
||||
}
|
||||
|
||||
static WRITE64_HANDLER( cavesh3_blitter_w )
|
||||
static WRITE32_HANDLER( cavesh3_blitter_w )
|
||||
{
|
||||
logerror("cavesh3_blitter_w access at %08x (%08x) - %08x%08x %08x%08x\n",offset, offset*8, (UINT32)(data>>32),(UINT32)(data&0xffffffff),(UINT32)(mem_mask>>32),(UINT32)(mem_mask&0xffffffff));
|
||||
logerror("%08x cavesh3_blitter_w access at %08x (%08x) - %08x %08x\n",cpu_get_pc(&space->device()),offset, offset*8, data,mem_mask);
|
||||
}
|
||||
|
||||
static READ64_HANDLER( ymz2770c_z_r )
|
||||
@ -88,32 +73,307 @@ static WRITE64_HANDLER( ymz2770c_z_w )
|
||||
|
||||
}
|
||||
|
||||
static READ64_HANDLER( cavesh3_nand_r )
|
||||
|
||||
|
||||
// FLASH
|
||||
|
||||
#define FLASH_PAGE_SIZE (2048+64)
|
||||
|
||||
UINT8 flash_page_data[FLASH_PAGE_SIZE];
|
||||
|
||||
typedef enum { STATE_IDLE = 0, STATE_READ, STATE_READ_ID, STATE_READ_STATUS } flash_state_t;
|
||||
static const char *flash_state_name[] = { "IDLE", "READ", "READ_ID", "READ_STATUS" };
|
||||
|
||||
static flash_state_t flash_state;
|
||||
|
||||
static UINT8 flash_enab;
|
||||
|
||||
static UINT8 flash_cmd_seq;
|
||||
static UINT32 flash_cmd_prev;
|
||||
|
||||
static UINT8 flash_addr_seq;
|
||||
static UINT8 flash_read_seq;
|
||||
|
||||
static UINT16 flash_row, flash_col;
|
||||
static UINT16 flash_page_addr;
|
||||
static UINT16 flash_page_index;
|
||||
|
||||
static void flash_hard_reset(running_machine &machine)
|
||||
{
|
||||
if (mem_mask & U64(0x00ffffffffffffff))
|
||||
// logerror("%08x FLASH: RESET\n", cpuexec_describe_context(machine));
|
||||
|
||||
flash_state = STATE_READ;
|
||||
|
||||
flash_cmd_prev = -1;
|
||||
flash_cmd_seq = 0;
|
||||
|
||||
flash_addr_seq = 0;
|
||||
flash_read_seq = 0;
|
||||
|
||||
flash_row = 0;
|
||||
flash_col = 0;
|
||||
|
||||
memset(flash_page_data, 0, FLASH_PAGE_SIZE);
|
||||
flash_page_addr = 0;
|
||||
flash_page_index = 0;
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( flash_enab_w )
|
||||
{
|
||||
logerror("%08x FLASH: enab = %02X\n", cpu_get_pc(&space->device()), data);
|
||||
//flash_enab = data;
|
||||
flash_enab = 1; // todo, why does it get turned off again instantly?
|
||||
}
|
||||
|
||||
static void flash_change_state(running_machine &machine, flash_state_t state)
|
||||
{
|
||||
flash_state = state;
|
||||
|
||||
flash_cmd_prev = -1;
|
||||
flash_cmd_seq = 0;
|
||||
|
||||
flash_read_seq = 0;
|
||||
flash_addr_seq = 0;
|
||||
|
||||
logerror("flash_change_state - FLASH: state = %s\n", flash_state_name[state]);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( flash_cmd_w )
|
||||
{
|
||||
if (!flash_enab)
|
||||
return;
|
||||
|
||||
logerror("%08x FLASH: cmd = %02X (prev = %02X)\n", cpu_get_pc(&space->device()), data, flash_cmd_prev);
|
||||
|
||||
if (flash_cmd_prev == -1)
|
||||
{
|
||||
logerror("unknown cavesh3_nand_r access %08x%08x\n",(UINT32)(mem_mask>>32),(UINT32)(mem_mask&0xffffffff));
|
||||
flash_cmd_prev = data;
|
||||
|
||||
switch (data)
|
||||
{
|
||||
case 0x00: // READ
|
||||
flash_addr_seq = 0;
|
||||
break;
|
||||
|
||||
case 0x70: // READ STATUS
|
||||
flash_change_state( space->machine(), STATE_READ_STATUS );
|
||||
break;
|
||||
|
||||
case 0x90: // READ ID
|
||||
flash_change_state( space->machine(), STATE_READ_ID );
|
||||
break;
|
||||
|
||||
case 0xff: // RESET
|
||||
flash_change_state( space->machine(), STATE_IDLE );
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
logerror("%08x FLASH: unknown cmd1 = %02X\n", cpu_get_pc(&space->device()), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("cavesh3_nand_r access %08x%08x\n",(UINT32)(mem_mask>>32),(UINT32)(mem_mask&0xffffffff));
|
||||
}
|
||||
switch (flash_cmd_prev)
|
||||
{
|
||||
case 0x00: // READ
|
||||
if (data == 0x30)
|
||||
{
|
||||
UINT8 *region = space->machine().region( "game" )->base();
|
||||
|
||||
return 0;// (UINT64)(space->machine().rand()&0xff)<<(32+16+8);
|
||||
memcpy(flash_page_data, region + flash_row * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE);
|
||||
flash_page_addr = flash_col;
|
||||
flash_page_index = flash_row;
|
||||
|
||||
flash_change_state( space->machine(), STATE_READ );
|
||||
|
||||
logerror("%08x FLASH: caching page = %04X\n", cpu_get_pc(&space->device()), flash_row);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
logerror("%08x FLASH: unknown cmd2 = %02X (cmd1 = %02X)\n", cpu_get_pc(&space->device()), data, flash_cmd_prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static WRITE64_HANDLER( cavesh3_nand_w )
|
||||
static WRITE8_HANDLER( flash_addr_w )
|
||||
{
|
||||
if (mem_mask & U64(0xff0000ffffffffff))
|
||||
if (!flash_enab)
|
||||
return;
|
||||
|
||||
logerror("%08x FLASH: addr = %02X (seq = %02X)\n", cpu_get_pc(&space->device()), data, flash_addr_seq);
|
||||
|
||||
switch( flash_addr_seq++ )
|
||||
{
|
||||
logerror("unknown cavesh3_nand_w access %08x%08x %08x%08x\n",(UINT32)(data>>32),(UINT32)(data&0xffffffff),(UINT32)(mem_mask>>32),(UINT32)(mem_mask&0xffffffff));
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("cavesh3_nand_w access %08x%08x %08x%08x\n",(UINT32)(data>>32),(UINT32)(data&0xffffffff),(UINT32)(mem_mask>>32),(UINT32)(mem_mask&0xffffffff));
|
||||
case 0:
|
||||
flash_col = (flash_col & 0xff00) | data;
|
||||
break;
|
||||
case 1:
|
||||
flash_col = (flash_col & 0x00ff) | (data << 8);
|
||||
break;
|
||||
case 2:
|
||||
flash_row = (flash_row & 0xff00) | data;
|
||||
break;
|
||||
case 3:
|
||||
flash_row = (flash_row & 0x00ff) | (data << 8);
|
||||
flash_addr_seq = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static READ8_HANDLER( flash_io_r )
|
||||
{
|
||||
UINT8 data = 0x00;
|
||||
UINT32 old;
|
||||
|
||||
if (!flash_enab)
|
||||
return 0xff;
|
||||
|
||||
switch (flash_state)
|
||||
{
|
||||
case STATE_READ_ID:
|
||||
old = flash_read_seq;
|
||||
|
||||
switch( flash_read_seq++ )
|
||||
{
|
||||
case 0:
|
||||
data = 0xEC; // Manufacturer
|
||||
break;
|
||||
case 1:
|
||||
data = 0xF1; // Device
|
||||
break;
|
||||
case 2:
|
||||
data = 0x00; // XX
|
||||
break;
|
||||
case 3:
|
||||
data = 0x15; // Flags
|
||||
flash_read_seq = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
logerror("%08x FLASH: read %02X from id(%02X)\n", cpu_get_pc(&space->device()), data, old);
|
||||
break;
|
||||
|
||||
case STATE_READ:
|
||||
if (flash_page_addr > FLASH_PAGE_SIZE-1)
|
||||
flash_page_addr = FLASH_PAGE_SIZE-1;
|
||||
|
||||
old = flash_page_addr;
|
||||
|
||||
data = flash_page_data[flash_page_addr++];
|
||||
|
||||
// logerror("%08x FLASH: read data %02X from addr %03X (page %04X)\n", cpu_get_pc(&space->device()), data, old, flash_page_index);
|
||||
break;
|
||||
|
||||
case STATE_READ_STATUS:
|
||||
// bit 7 = writeable, bit 6 = ready, bit 5 = ready/true ready, bit 1 = fail(N-1), bit 0 = fail
|
||||
data = 0xe0;
|
||||
logerror("%08x FLASH: read status %02X\n", cpu_get_pc(&space->device()), data);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
logerror("%08x FLASH: unknown read in state %s\n", cpu_get_pc(&space->device()), flash_state_name[flash_state]);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
/*
|
||||
static READ8_HANDLER( flash_ready_r )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// FLASH interface
|
||||
|
||||
static READ32_HANDLER( ibara_flash_ready_r )
|
||||
{
|
||||
// 400012a contains test bit (shown in service mode)
|
||||
return ((flash_ready_r(space, offset) ? 0x20 : 0x00) << 24) |
|
||||
input_port_read(space->machine(), "PORT_EF");
|
||||
}
|
||||
*/
|
||||
static READ8_HANDLER( ibara_flash_io_r )
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
default:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
|
||||
// logerror("ibara_flash_io_r offset %04x\n", offset);
|
||||
return 0xff;
|
||||
|
||||
case 0x00:
|
||||
return flash_io_r(space,offset);
|
||||
}
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( ibara_flash_io_w )
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
default:
|
||||
case 0x00:
|
||||
case 0x03:
|
||||
logerror("unknown ibara_flash_io_w offset %04x data %02x\n", offset, data); // 03 enable/disable fgpa access?
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
flash_cmd_w(space, offset, data);
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
flash_addr_w(space, offset, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static READ8_HANDLER( serial_rtc_eeprom_r )
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
default:
|
||||
logerror("unknown serial_rtc_eeprom_r access offset %02x\n", offset);
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( serial_rtc_eeprom_w )
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x01:
|
||||
// data & 0x00010000 = DATA
|
||||
// data & 0x00020000 = CLK
|
||||
// data & 0x00040000 = CE
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
flash_enab_w(space,offset,data);
|
||||
return;
|
||||
|
||||
default:
|
||||
logerror("unknown serial_rtc_eeprom_w access offset %02x data %02x\n",offset, data);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ADDRESS_MAP_START( cavesh3_map, AS_PROGRAM, 64 )
|
||||
AM_RANGE(0x00000000, 0x001fffff) AM_ROM AM_REGION("maincpu", 0)
|
||||
@ -124,10 +384,10 @@ static ADDRESS_MAP_START( cavesh3_map, AS_PROGRAM, 64 )
|
||||
AM_RANGE(0x0c000000, 0x0c7fffff) AM_RAM // work RAM
|
||||
AM_RANGE(0x0c800000, 0x0cffffff) AM_RAM // mirror of above on type B boards, extra ram on type D
|
||||
|
||||
AM_RANGE(0x10000000, 0x10000007) AM_READWRITE(cavesh3_nand_r, cavesh3_nand_w)
|
||||
AM_RANGE(0x10000000, 0x10000007) AM_READWRITE8(ibara_flash_io_r, ibara_flash_io_w, U64(0xffffffffffffffff))
|
||||
AM_RANGE(0x10400000, 0x10400007) AM_READWRITE(ymz2770c_z_r, ymz2770c_z_w)
|
||||
AM_RANGE(0x10C00000, 0x10C00007) AM_READWRITE(serial_rtc_eeprom_r, serial_rtc_eeprom_w)
|
||||
AM_RANGE(0x18000000, 0x18000057) AM_READWRITE(cavesh3_blitter_r, cavesh3_blitter_w)
|
||||
AM_RANGE(0x10C00000, 0x10C00007) AM_READWRITE8(serial_rtc_eeprom_r, serial_rtc_eeprom_w, U64(0xffffffffffffffff))
|
||||
AM_RANGE(0x18000000, 0x18000057) AM_READWRITE32(cavesh3_blitter_r, cavesh3_blitter_w, U64(0xffffffffffffffff))
|
||||
|
||||
AM_RANGE(0xf0000000, 0xf0ffffff) AM_RAM // mem mapped cache (sh3 internal?)
|
||||
/* 0xffffe000, 0xffffffff SH3 Internal Regs 2 */
|
||||
@ -143,26 +403,12 @@ static INPUT_PORTS_START( cavesh3 )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
#define CAVE_CPU_CLOCK 133333333
|
||||
#define CAVE_CPU_CLOCK 12800000 * 8
|
||||
|
||||
static const struct sh4_config sh4cpu_config = { 1, 0, 1, 0, 0, 0, 1, 1, 0, CAVE_CPU_CLOCK };
|
||||
|
||||
|
||||
|
||||
static IRQ_CALLBACK(cavesh3_int_callback)
|
||||
{
|
||||
if (irqline == 4)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("irqline %02x\n",irqline);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static INTERRUPT_GEN(cavesh3_interrupt)
|
||||
{
|
||||
@ -171,9 +417,11 @@ static INTERRUPT_GEN(cavesh3_interrupt)
|
||||
|
||||
static MACHINE_RESET( cavesh3 )
|
||||
{
|
||||
device_set_irq_callback(machine.device("maincpu"), cavesh3_int_callback);
|
||||
flash_enab = 0;
|
||||
flash_hard_reset(machine);
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_CONFIG_START( cavesh3, cavesh3_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", SH3BE, CAVE_CPU_CLOCK)
|
||||
@ -375,6 +623,7 @@ ROM_END
|
||||
|
||||
|
||||
|
||||
|
||||
GAME( 2004, mushisam, 0, cavesh3, cavesh3, 0, ROT0, "Cave", "Mushihime Sama (2004/10/12 MASTER VER.)", GAME_NOT_WORKING | GAME_NO_SOUND )
|
||||
GAME( 2004, mushisama, mushisam, cavesh3, cavesh3, 0, ROT0, "Cave", "Mushihime Sama (2004/10/12 MASTER VER)", GAME_NOT_WORKING | GAME_NO_SOUND )
|
||||
GAME( 2005, espgal2, 0, cavesh3, cavesh3, 0, ROT0, "Cave", "EspGaluda II (2005/11/14 MASTER VER)", GAME_NOT_WORKING | GAME_NO_SOUND )
|
||||
|
Loading…
Reference in New Issue
Block a user