From 804169dd621a3ad3eec1a32ce30350de667fee80 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Thu, 30 Oct 2014 00:23:30 +0100 Subject: apply a facelift --- source/dma.c | 1833 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 918 insertions(+), 915 deletions(-) (limited to 'source/dma.c') diff --git a/source/dma.c b/source/dma.c index e7de5b4..31814b2 100644 --- a/source/dma.c +++ b/source/dma.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -111,19 +111,19 @@ uint8 buffer[0x10000]; #endif extern int HDMA_ModeByteCounts [8]; -extern uint8 *HDMAMemPointers [8]; -extern uint8 *HDMABasePointers [8]; +extern uint8* HDMAMemPointers [8]; +extern uint8* HDMABasePointers [8]; // #define SETA010_HDMA_FROM_CART #ifdef SETA010_HDMA_FROM_CART -uint32 HDMARawPointers[8]; // Cart address space pointer +uint32 HDMARawPointers[8]; // Cart address space pointer #endif #if defined(__linux__) || defined(__WIN32__) -static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2) +static int S9xCompareSDD1IndexEntries(const void* p1, const void* p2) { - return (*(uint32 *) p1 - *(uint32 *) p2); + return (*(uint32*) p1 - * (uint32*) p2); } #endif @@ -132,979 +132,982 @@ static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2) /* This function preforms the general dma transfer */ /**********************************************************************************************/ -void S9xDoDMA (uint8 Channel) +void S9xDoDMA(uint8 Channel) { - uint8 Work; - - if (Channel > 7 || CPU.InDMA) - return; - - CPU.InDMA = TRUE; - bool8 in_sa1_dma = FALSE; - uint8 *in_sdd1_dma = NULL; - uint8 *spc7110_dma=NULL; - bool s7_wrap=false; - SDMA *d = &DMA[Channel]; - - - int count = d->TransferBytes; - - if (count == 0) - count = 0x10000; - - int inc = d->AAddressFixed ? 0 : (!d->AAddressDecrement ? 1 : -1); - - if((d->ABank==0x7E||d->ABank==0x7F)&&d->BAddress==0x80) - { - d->AAddress+= d->TransferBytes; - //does an invalid DMA actually take time? - // I'd say yes, since 'invalid' is probably just the WRAM chip - // not being able to read and write itself at the same time - CPU.Cycles+=(d->TransferBytes+1)*SLOW_ONE_CYCLE; - goto update_address; - } - switch (d->BAddress) - { - case 0x18: - case 0x19: - if (IPPU.RenderThisFrame) - FLUSH_REDRAW (); - break; - } - if (Settings.SDD1) - { - if (d->AAddressFixed && Memory.FillRAM [0x4801] > 0) - { - // Hacky support for pre-decompressed S-DD1 data - inc = !d->AAddressDecrement ? 1 : -1; - uint32 address = (((d->ABank << 16) | d->AAddress) & 0xfffff) << 4; - - address |= Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)]; + uint8 Work; + + if (Channel > 7 || CPU.InDMA) + return; + + CPU.InDMA = TRUE; + bool8 in_sa1_dma = FALSE; + uint8* in_sdd1_dma = NULL; + uint8* spc7110_dma = NULL; + bool s7_wrap = false; + SDMA* d = &DMA[Channel]; + + + int count = d->TransferBytes; + + if (count == 0) + count = 0x10000; + + int inc = d->AAddressFixed ? 0 : (!d->AAddressDecrement ? 1 : -1); + + if ((d->ABank == 0x7E || d->ABank == 0x7F) && d->BAddress == 0x80) + { + d->AAddress += d->TransferBytes; + //does an invalid DMA actually take time? + // I'd say yes, since 'invalid' is probably just the WRAM chip + // not being able to read and write itself at the same time + CPU.Cycles += (d->TransferBytes + 1) * SLOW_ONE_CYCLE; + goto update_address; + } + switch (d->BAddress) + { + case 0x18: + case 0x19: + if (IPPU.RenderThisFrame) + FLUSH_REDRAW(); + break; + } + if (Settings.SDD1) + { + if (d->AAddressFixed && Memory.FillRAM [0x4801] > 0) + { + // Hacky support for pre-decompressed S-DD1 data + inc = !d->AAddressDecrement ? 1 : -1; + uint32 address = (((d->ABank << 16) | d->AAddress) & 0xfffff) << 4; + + address |= Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)]; #ifdef SDD1_DECOMP - if(Settings.SDD1Pack) - { - uint8* in_ptr=GetBasePointer(((d->ABank << 16) | d->AAddress)); - in_ptr+=d->AAddress; + if (Settings.SDD1Pack) + { + uint8* in_ptr = GetBasePointer(((d->ABank << 16) | d->AAddress)); + in_ptr += d->AAddress; - SDD1_decompress(buffer,in_ptr,d->TransferBytes); - in_sdd1_dma=buffer; + SDD1_decompress(buffer, in_ptr, d->TransferBytes); + in_sdd1_dma = buffer; #ifdef SDD1_VERIFY - void *ptr = bsearch (&address, Memory.SDD1Index, - Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); - if(memcmp(buffer, ptr, d->TransferBytes)) - { - uint8 *p = Memory.SDD1LoggedData; - bool8 found = FALSE; - uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0; - - for (uint32 i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8) - { - if (*p == d->ABank || - *(p + 1) == (d->AAddress >> 8) && - *(p + 2) == (d->AAddress & 0xff) && - *(p + 3) == (count >> 8) && - *(p + 4) == (count & 0xff) && - *(p + 7) == SDD1Bank) - { - found = TRUE; - } - } - if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES) - { - int j=0; - while(ptr[j]==buffer[j]) - j++; - - *p = d->ABank; - *(p + 1) = d->AAddress >> 8; - *(p + 2) = d->AAddress & 0xff; - *(p + 3) = j&0xFF; - *(p + 4) = (j>>8)&0xFF; - *(p + 7) = SDD1Bank; - Memory.SDD1LoggedDataCount += 1; - } - } + void* ptr = bsearch(&address, Memory.SDD1Index, + Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); + if (memcmp(buffer, ptr, d->TransferBytes)) + { + uint8* p = Memory.SDD1LoggedData; + bool8 found = FALSE; + uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0; + + for (uint32 i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8) + { + if (*p == d->ABank || + *(p + 1) == (d->AAddress >> 8) && + *(p + 2) == (d->AAddress & 0xff) && + *(p + 3) == (count >> 8) && + *(p + 4) == (count & 0xff) && + *(p + 7) == SDD1Bank) + found = TRUE; + } + if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES) + { + int j = 0; + while (ptr[j] == buffer[j]) + j++; + + *p = d->ABank; + *(p + 1) = d->AAddress >> 8; + *(p + 2) = d->AAddress & 0xff; + *(p + 3) = j & 0xFF; + *(p + 4) = (j >> 8) & 0xFF; + *(p + 7) = SDD1Bank; + Memory.SDD1LoggedDataCount += 1; + } + } #endif - } + } - else - { + else + { #endif #if defined(__linux__) || defined (__WIN32__) - void *ptr = bsearch (&address, Memory.SDD1Index, - Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); - if (ptr) - in_sdd1_dma = *(uint32 *) ((uint8 *) ptr + 4) + Memory.SDD1Data; + void* ptr = bsearch(&address, Memory.SDD1Index, + Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); + if (ptr) + in_sdd1_dma = *(uint32*)((uint8*) ptr + 4) + Memory.SDD1Data; #else - uint8 *ptr = Memory.SDD1Index; - - uint32 e; - for (e = 0; e < Memory.SDD1Entries; e++, ptr += 12) - { - if (address == *(uint32 *) ptr) - { - in_sdd1_dma = *(uint32 *) (ptr + 4) + Memory.SDD1Data; - break; - } - } + uint8* ptr = Memory.SDD1Index; + + uint32 e; + for (e = 0; e < Memory.SDD1Entries; e++, ptr += 12) + { + if (address == *(uint32*) ptr) + { + in_sdd1_dma = *(uint32*)(ptr + 4) + Memory.SDD1Data; + break; + } + } #endif - - if (!in_sdd1_dma) - { - // No matching decompressed data found. Must be some new - // graphics not encountered before. Log it if it hasn't been - // already. - uint8 *p = Memory.SDD1LoggedData; - bool8 found = FALSE; - uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0; - - uint32 i; - for (i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8) - { - if (*p == d->ABank || - *(p + 1) == (d->AAddress >> 8) && - *(p + 2) == (d->AAddress & 0xff) && - *(p + 3) == (count >> 8) && - *(p + 4) == (count & 0xff) && - *(p + 7) == SDD1Bank) - { - found = TRUE; - break; - } - } - if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES) - { - *p = d->ABank; - *(p + 1) = d->AAddress >> 8; - *(p + 2) = d->AAddress & 0xff; - *(p + 3) = count >> 8; - *(p + 4) = count & 0xff; - *(p + 7) = SDD1Bank; - Memory.SDD1LoggedDataCount += 1; - } - } - } + + if (!in_sdd1_dma) + { + // No matching decompressed data found. Must be some new + // graphics not encountered before. Log it if it hasn't been + // already. + uint8* p = Memory.SDD1LoggedData; + bool8 found = FALSE; + uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0; + + uint32 i; + for (i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8) + { + if (*p == d->ABank || + *(p + 1) == (d->AAddress >> 8) && + *(p + 2) == (d->AAddress & 0xff) && + *(p + 3) == (count >> 8) && + *(p + 4) == (count & 0xff) && + *(p + 7) == SDD1Bank) + { + found = TRUE; + break; + } + } + if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES) + { + *p = d->ABank; + *(p + 1) = d->AAddress >> 8; + *(p + 2) = d->AAddress & 0xff; + *(p + 3) = count >> 8; + *(p + 4) = count & 0xff; + *(p + 7) = SDD1Bank; + Memory.SDD1LoggedDataCount += 1; + } + } + } #ifdef SDD1_DECOMP - } + } #endif - Memory.FillRAM [0x4801] = 0; - } - if(Settings.SPC7110&&(d->AAddress==0x4800||d->ABank==0x50)) - { - uint32 i,j; - i=(s7r.reg4805|(s7r.reg4806<<8)); - i*=s7r.AlignBy; - i+=s7r.bank50Internal; - i%=DECOMP_BUFFER_SIZE; - j=0; - if((i+d->TransferBytes)TransferBytes); - j=DECOMP_BUFFER_SIZE-i; - memcpy(spc7110_dma, &s7r.bank50[i], j); - memcpy(&spc7110_dma[j],s7r.bank50,d->TransferBytes-j); - s7_wrap=true; - } - int icount=s7r.reg4809|(s7r.reg480A<<8); - icount-=d->TransferBytes; - s7r.reg4809=0x00ff&icount; - s7r.reg480A=(0xff00&icount)>>8; - - s7r.bank50Internal+=d->TransferBytes; - s7r.bank50Internal%=DECOMP_BUFFER_SIZE; - inc=1; - d->AAddress-=count; - } - if (d->BAddress == 0x18 && SA1.in_char_dma && (d->ABank & 0xf0) == 0x40) - { - // Perform packed bitmap to PPU character format conversion on the - // data before transmitting it to V-RAM via-DMA. - int num_chars = 1 << ((Memory.FillRAM [0x2231] >> 2) & 7); - int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 : - (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2; - - int bytes_per_char = 8 * depth; - int bytes_per_line = depth * num_chars; - int char_line_bytes = bytes_per_char * num_chars; - uint32 addr = (d->AAddress / char_line_bytes) * char_line_bytes; - uint8 *base = GetBasePointer ((d->ABank << 16) + addr) + addr; - uint8 *buffer = &Memory.ROM [MAX_ROM_SIZE - 0x10000]; - uint8 *p = buffer; - uint32 inc = char_line_bytes - (d->AAddress % char_line_bytes); - uint32 char_count = inc / bytes_per_char; - - in_sa1_dma = TRUE; - - //printf ("%08x,", base); fflush (stdout); - //printf ("depth = %d, count = %d, bytes_per_char = %d, bytes_per_line = %d, num_chars = %d, char_line_bytes = %d\n", - //depth, count, bytes_per_char, bytes_per_line, num_chars, char_line_bytes); - int i; - - switch (depth) - { - case 2: - for (i = 0; i < count; i += inc, base += char_line_bytes, - inc = char_line_bytes, char_count = num_chars) - { + Memory.FillRAM [0x4801] = 0; + } + if (Settings.SPC7110 && (d->AAddress == 0x4800 || d->ABank == 0x50)) + { + uint32 i, j; + i = (s7r.reg4805 | (s7r.reg4806 << 8)); + i *= s7r.AlignBy; + i += s7r.bank50Internal; + i %= DECOMP_BUFFER_SIZE; + j = 0; + if ((i + d->TransferBytes) < DECOMP_BUFFER_SIZE) + spc7110_dma = &s7r.bank50[i]; + else + { + spc7110_dma = (uint8*)malloc(d->TransferBytes); + j = DECOMP_BUFFER_SIZE - i; + memcpy(spc7110_dma, &s7r.bank50[i], j); + memcpy(&spc7110_dma[j], s7r.bank50, d->TransferBytes - j); + s7_wrap = true; + } + int icount = s7r.reg4809 | (s7r.reg480A << 8); + icount -= d->TransferBytes; + s7r.reg4809 = 0x00ff & icount; + s7r.reg480A = (0xff00 & icount) >> 8; + + s7r.bank50Internal += d->TransferBytes; + s7r.bank50Internal %= DECOMP_BUFFER_SIZE; + inc = 1; + d->AAddress -= count; + } + if (d->BAddress == 0x18 && SA1.in_char_dma && (d->ABank & 0xf0) == 0x40) + { + // Perform packed bitmap to PPU character format conversion on the + // data before transmitting it to V-RAM via-DMA. + int num_chars = 1 << ((Memory.FillRAM [0x2231] >> 2) & 7); + int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 : + (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2; + + int bytes_per_char = 8 * depth; + int bytes_per_line = depth * num_chars; + int char_line_bytes = bytes_per_char * num_chars; + uint32 addr = (d->AAddress / char_line_bytes) * char_line_bytes; + uint8* base = GetBasePointer((d->ABank << 16) + addr) + addr; + uint8* buffer = &Memory.ROM [MAX_ROM_SIZE - 0x10000]; + uint8* p = buffer; + uint32 inc = char_line_bytes - (d->AAddress % char_line_bytes); + uint32 char_count = inc / bytes_per_char; + + in_sa1_dma = TRUE; + + //printf ("%08x,", base); fflush (stdout); + //printf ("depth = %d, count = %d, bytes_per_char = %d, bytes_per_line = %d, num_chars = %d, char_line_bytes = %d\n", + //depth, count, bytes_per_char, bytes_per_line, num_chars, char_line_bytes); + int i; + + switch (depth) + { + case 2: + for (i = 0; i < count; i += inc, base += char_line_bytes, + inc = char_line_bytes, char_count = num_chars) + { uint32 j; - uint8 *line = base + (num_chars - char_count) * 2; + uint8* line = base + (num_chars - char_count) * 2; for (j = 0; j < char_count && p - buffer < count; - j++, line += 2) - { - int b,l; - uint8 *q = line; + j++, line += 2) + { + int b, l; + uint8* q = line; for (l = 0; l < 8; l++, q += bytes_per_line) - { + { for (b = 0; b < 2; b++) - { - uint8 r = *(q + b); - *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); - *(p + 0) = (*(p + 0) << 1) | ((r >> 2) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 3) & 1); - *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); - *(p + 0) = (*(p + 0) << 1) | ((r >> 6) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 7) & 1); - } - p += 2; - } - } - } - break; - case 4: - for (i = 0; i < count; i += inc, base += char_line_bytes, - inc = char_line_bytes, char_count = num_chars) - { + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 2) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 3) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 6) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 7) & 1); + } + p += 2; + } + } + } + break; + case 4: + for (i = 0; i < count; i += inc, base += char_line_bytes, + inc = char_line_bytes, char_count = num_chars) + { uint32 j; - uint8 *line = base + (num_chars - char_count) * 4; + uint8* line = base + (num_chars - char_count) * 4; for (j = 0; j < char_count && p - buffer < count; - j++, line += 4) - { - uint8 *q = line; - int b,l; + j++, line += 4) + { + uint8* q = line; + int b, l; for (l = 0; l < 8; l++, q += bytes_per_line) - { + { for (b = 0; b < 4; b++) - { - uint8 r = *(q + b); - *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); - *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); - *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); - *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); - *(p + 16) = (*(p + 16) << 1) | ((r >> 6) & 1); - *(p + 17) = (*(p + 17) << 1) | ((r >> 7) & 1); - } - p += 2; - } - p += 32 - 16; - } - } - break; - case 8: - for (i = 0; i < count; i += inc, base += char_line_bytes, - inc = char_line_bytes, char_count = num_chars) - { - uint8 *line = base + (num_chars - char_count) * 8; + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 6) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 7) & 1); + } + p += 2; + } + p += 32 - 16; + } + } + break; + case 8: + for (i = 0; i < count; i += inc, base += char_line_bytes, + inc = char_line_bytes, char_count = num_chars) + { + uint8* line = base + (num_chars - char_count) * 8; uint32 j; for (j = 0; j < char_count && p - buffer < count; - j++, line += 8) - { - uint8 *q = line; - int b,l; + j++, line += 8) + { + uint8* q = line; + int b, l; for (l = 0; l < 8; l++, q += bytes_per_line) - { + { for (b = 0; b < 8; b++) - { - uint8 r = *(q + b); - *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); - *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); - *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); - *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1); - *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1); - *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1); - *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1); - } - p += 2; - } - p += 64 - 16; - } - } - break; - } - } - - if (!d->TransferDirection) - { - /* XXX: DMA is potentially broken here for cases where we DMA across - * XXX: memmap boundries. A possible solution would be to re-call - * XXX: GetBasePointer whenever we cross a boundry, and when - * XXX: GetBasePointer returns (0) to take the 'slow path' and use - * XXX: S9xGetByte instead of *base. GetBasePointer() would want to - * XXX: return (0) for MAP_PPU and whatever else is a register range - * XXX: rather than a RAM/ROM block, and we'd want to detect MAP_PPU - * XXX: (or specifically, Address Bus B addresses $2100-$21FF in - * XXX: banks $00-$3F) specially and treat it as MAP_NONE (since - * XXX: PPU->PPU transfers don't work). - */ - - //reflects extra cycle used by DMA - CPU.Cycles += SLOW_ONE_CYCLE * (count+1); - - uint8 *base = GetBasePointer ((d->ABank << 16) + d->AAddress); - uint16 p = d->AAddress; - - if (!base) - base = Memory.ROM; - - if (in_sa1_dma) - { + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); + *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1); + *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1); + *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1); + *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1); + } + p += 2; + } + p += 64 - 16; + } + } + break; + } + } + + if (!d->TransferDirection) + { + /* XXX: DMA is potentially broken here for cases where we DMA across + * XXX: memmap boundries. A possible solution would be to re-call + * XXX: GetBasePointer whenever we cross a boundry, and when + * XXX: GetBasePointer returns (0) to take the 'slow path' and use + * XXX: S9xGetByte instead of *base. GetBasePointer() would want to + * XXX: return (0) for MAP_PPU and whatever else is a register range + * XXX: rather than a RAM/ROM block, and we'd want to detect MAP_PPU + * XXX: (or specifically, Address Bus B addresses $2100-$21FF in + * XXX: banks $00-$3F) specially and treat it as MAP_NONE (since + * XXX: PPU->PPU transfers don't work). + */ + + //reflects extra cycle used by DMA + CPU.Cycles += SLOW_ONE_CYCLE * (count + 1); + + uint8* base = GetBasePointer((d->ABank << 16) + d->AAddress); + uint16 p = d->AAddress; + + if (!base) + base = Memory.ROM; + + if (in_sa1_dma) + { base = &Memory.ROM [MAX_ROM_SIZE - 0x10000]; - p = 0; - } - - if (in_sdd1_dma) - { - base = in_sdd1_dma; - p = 0; - } - if(spc7110_dma) - { - base=spc7110_dma; - p = 0; - } - if (inc > 0) - d->AAddress += count; - else - if (inc < 0) - d->AAddress -= count; - - if (d->TransferMode == 0 || d->TransferMode == 2 || d->TransferMode == 6) - { - switch (d->BAddress) - { - case 0x04: - do - { - Work = *(base + p); - REGISTER_2104(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - break; - case 0x18: + p = 0; + } + + if (in_sdd1_dma) + { + base = in_sdd1_dma; + p = 0; + } + if (spc7110_dma) + { + base = spc7110_dma; + p = 0; + } + if (inc > 0) + d->AAddress += count; + else if (inc < 0) + d->AAddress -= count; + + if (d->TransferMode == 0 || d->TransferMode == 2 || d->TransferMode == 6) + { + switch (d->BAddress) + { + case 0x04: + do + { + Work = *(base + p); + REGISTER_2104(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + break; + case 0x18: #ifndef CORRECT_VRAM_READS - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - if (!PPU.VMA.FullGraphicCount) - { - do - { - Work = *(base + p); - REGISTER_2118_linear(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - } - else - { - do - { - Work = *(base + p); - REGISTER_2118_tile(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - } - break; - case 0x19: + if (!PPU.VMA.FullGraphicCount) + { + do + { + Work = *(base + p); + REGISTER_2118_linear(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + } + else + { + do + { + Work = *(base + p); + REGISTER_2118_tile(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + } + break; + case 0x19: #ifndef CORRECT_VRAM_READS - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - if (!PPU.VMA.FullGraphicCount) - { - do - { - Work = *(base + p); - REGISTER_2119_linear(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - } - else - { - do - { - Work = *(base + p); - REGISTER_2119_tile(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - } - break; - case 0x22: - do - { - Work = *(base + p); - REGISTER_2122(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - break; - case 0x80: - do - { - Work = *(base + p); - REGISTER_2180(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - break; - default: - do - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - break; - } - } - else - if (d->TransferMode == 1 || d->TransferMode == 5) - { - if (d->BAddress == 0x18) - { - // Write to V-RAM + if (!PPU.VMA.FullGraphicCount) + { + do + { + Work = *(base + p); + REGISTER_2119_linear(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + } + else + { + do + { + Work = *(base + p); + REGISTER_2119_tile(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + } + break; + case 0x22: + do + { + Work = *(base + p); + REGISTER_2122(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + break; + case 0x80: + do + { + Work = *(base + p); + REGISTER_2180(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + break; + default: + do + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + break; + } + } + else if (d->TransferMode == 1 || d->TransferMode == 5) + { + if (d->BAddress == 0x18) + { + // Write to V-RAM #ifndef CORRECT_VRAM_READS - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - if (!PPU.VMA.FullGraphicCount) - { - while (count > 1) - { - Work = *(base + p); - REGISTER_2118_linear(Work); - p += inc; - - Work = *(base + p); - REGISTER_2119_linear(Work); - p += inc; - CHECK_SOUND(); - count -= 2; - } - if (count == 1) - { - Work = *(base + p); - REGISTER_2118_linear(Work); - p += inc; - } - } - else - { - while (count > 1) - { - Work = *(base + p); - REGISTER_2118_tile(Work); - p += inc; - - Work = *(base + p); - REGISTER_2119_tile(Work); - p += inc; - CHECK_SOUND(); - count -= 2; - } - if (count == 1) - { - Work = *(base + p); - REGISTER_2118_tile(Work); - p += inc; - } - } - } - else - { - // DMA mode 1 general case - while (count > 1) - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - - Work = *(base + p); - S9xSetPPU (Work, 0x2101 + d->BAddress); - p += inc; - CHECK_SOUND(); - count -= 2; - } - if (count == 1) - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - } - } - } - else - if (d->TransferMode == 3 || d->TransferMode == 7) - { - do - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - if (count <= 1) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - if (count <= 2) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2101 + d->BAddress); - p += inc; - if (count <= 3) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2101 + d->BAddress); - p += inc; - CHECK_SOUND(); - count -= 4; - } while (count > 0); - } - else - if (d->TransferMode == 4) - { - do - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - if (count <= 1) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2101 + d->BAddress); - p += inc; - if (count <= 2) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2102 + d->BAddress); - p += inc; - if (count <= 3) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2103 + d->BAddress); - p += inc; - CHECK_SOUND(); - count -= 4; - } while (count > 0); - } - } - else - { - /* XXX: DMA is potentially broken here for cases where the dest is - * XXX: in the Address Bus B range. Note that this bad dest may not - * XXX: cover the whole range of the DMA though, if we transfer - * XXX: 65536 bytes only 256 of them may be Address Bus B. - */ - do - { - switch (d->TransferMode) - { - case 0: - case 2: - case 6: - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - --count; - break; - - case 1: - case 5: - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2101 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - count--; - break; - - case 3: - case 7: - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2101 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2101 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - count--; - break; - - case 4: - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2101 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2102 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2103 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - count--; - break; - - default: - count = 0; - break; - } - CHECK_SOUND(); - } while (count); - } - + if (!PPU.VMA.FullGraphicCount) + { + while (count > 1) + { + Work = *(base + p); + REGISTER_2118_linear(Work); + p += inc; + + Work = *(base + p); + REGISTER_2119_linear(Work); + p += inc; + CHECK_SOUND(); + count -= 2; + } + if (count == 1) + { + Work = *(base + p); + REGISTER_2118_linear(Work); + p += inc; + } + } + else + { + while (count > 1) + { + Work = *(base + p); + REGISTER_2118_tile(Work); + p += inc; + + Work = *(base + p); + REGISTER_2119_tile(Work); + p += inc; + CHECK_SOUND(); + count -= 2; + } + if (count == 1) + { + Work = *(base + p); + REGISTER_2118_tile(Work); + p += inc; + } + } + } + else + { + // DMA mode 1 general case + while (count > 1) + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + + Work = *(base + p); + S9xSetPPU(Work, 0x2101 + d->BAddress); + p += inc; + CHECK_SOUND(); + count -= 2; + } + if (count == 1) + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + } + } + } + else if (d->TransferMode == 3 || d->TransferMode == 7) + { + do + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + if (count <= 1) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + if (count <= 2) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2101 + d->BAddress); + p += inc; + if (count <= 3) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2101 + d->BAddress); + p += inc; + CHECK_SOUND(); + count -= 4; + } + while (count > 0); + } + else if (d->TransferMode == 4) + { + do + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + if (count <= 1) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2101 + d->BAddress); + p += inc; + if (count <= 2) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2102 + d->BAddress); + p += inc; + if (count <= 3) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2103 + d->BAddress); + p += inc; + CHECK_SOUND(); + count -= 4; + } + while (count > 0); + } + } + else + { + /* XXX: DMA is potentially broken here for cases where the dest is + * XXX: in the Address Bus B range. Note that this bad dest may not + * XXX: cover the whole range of the DMA though, if we transfer + * XXX: 65536 bytes only 256 of them may be Address Bus B. + */ + do + { + switch (d->TransferMode) + { + case 0: + case 2: + case 6: + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + --count; + break; + + case 1: + case 5: + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2101 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + count--; + break; + + case 3: + case 7: + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2101 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2101 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + count--; + break; + + case 4: + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2101 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2102 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2103 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + count--; + break; + + default: + count = 0; + break; + } + CHECK_SOUND(); + } + while (count); + } + #ifdef SPC700_C - IAPU.APUExecuting = Settings.APUEnabled; - APU_EXECUTE (); + IAPU.APUExecuting = Settings.APUEnabled; + APU_EXECUTE(); #endif - if (Settings.SuperFX) - while (CPU.Cycles > CPU.NextEvent) - S9xDoHBlankProcessing_SFX (); - else /* if (!Settings.SuperFX) */ - while (CPU.Cycles > CPU.NextEvent) - S9xDoHBlankProcessing_NoSFX (); - - if(Settings.SPC7110&&spc7110_dma) - { - if(spc7110_dma&&s7_wrap) + if (Settings.SuperFX) + while (CPU.Cycles > CPU.NextEvent) + S9xDoHBlankProcessing_SFX(); + else /* if (!Settings.SuperFX) */ + while (CPU.Cycles > CPU.NextEvent) + S9xDoHBlankProcessing_NoSFX(); + + if (Settings.SPC7110 && spc7110_dma) + { + if (spc7110_dma && s7_wrap) free(spc7110_dma); - } + } update_address: - // Super Punch-Out requires that the A-BUS address be updated after the - // DMA transfer. - Memory.FillRAM[0x4302 + (Channel << 4)] = (uint8) d->AAddress; - Memory.FillRAM[0x4303 + (Channel << 4)] = d->AAddress >> 8; - - // Secret of the Mana requires that the DMA bytes transfer count be set to - // zero when DMA has completed. - Memory.FillRAM [0x4305 + (Channel << 4)] = 0; - Memory.FillRAM [0x4306 + (Channel << 4)] = 0; - - DMA[Channel].IndirectAddress = 0; - d->TransferBytes = 0; - - CPU.InDMA = FALSE; + // Super Punch-Out requires that the A-BUS address be updated after the + // DMA transfer. + Memory.FillRAM[0x4302 + (Channel << 4)] = (uint8) d->AAddress; + Memory.FillRAM[0x4303 + (Channel << 4)] = d->AAddress >> 8; + + // Secret of the Mana requires that the DMA bytes transfer count be set to + // zero when DMA has completed. + Memory.FillRAM [0x4305 + (Channel << 4)] = 0; + Memory.FillRAM [0x4306 + (Channel << 4)] = 0; + + DMA[Channel].IndirectAddress = 0; + d->TransferBytes = 0; + + CPU.InDMA = FALSE; } -void S9xStartHDMA () +void S9xStartHDMA() { - if (Settings.DisableHDMA) - IPPU.HDMA = 0; - else - missing.hdma_this_frame = IPPU.HDMA = Memory.FillRAM [0x420c]; - - //per anomie timing post - if(IPPU.HDMA!=0) - CPU.Cycles+=ONE_CYCLE*3; - - IPPU.HDMAStarted = TRUE; - - uint8 i; - for (i = 0; i < 8; i++) - { - if (IPPU.HDMA & (1 << i)) - { - CPU.Cycles+=SLOW_ONE_CYCLE ; - DMA [i].LineCount = 0; - DMA [i].FirstLine = TRUE; - DMA [i].Address = DMA [i].AAddress; - if(DMA[i].HDMAIndirectAddressing) - CPU.Cycles+=(SLOW_ONE_CYCLE <<2); - } - HDMAMemPointers [i] = NULL; + if (Settings.DisableHDMA) + IPPU.HDMA = 0; + else + missing.hdma_this_frame = IPPU.HDMA = Memory.FillRAM [0x420c]; + + //per anomie timing post + if (IPPU.HDMA != 0) + CPU.Cycles += ONE_CYCLE * 3; + + IPPU.HDMAStarted = TRUE; + + uint8 i; + for (i = 0; i < 8; i++) + { + if (IPPU.HDMA & (1 << i)) + { + CPU.Cycles += SLOW_ONE_CYCLE ; + DMA [i].LineCount = 0; + DMA [i].FirstLine = TRUE; + DMA [i].Address = DMA [i].AAddress; + if (DMA[i].HDMAIndirectAddressing) + CPU.Cycles += (SLOW_ONE_CYCLE << 2); + } + HDMAMemPointers [i] = NULL; #ifdef SETA010_HDMA_FROM_CART - HDMARawPointers [i] = 0; + HDMARawPointers [i] = 0; #endif - } + } } -uint8 S9xDoHDMA (uint8 byte) +uint8 S9xDoHDMA(uint8 byte) { - SDMA *p = &DMA [0]; - - int d = 0; + SDMA* p = &DMA [0]; + + int d = 0; - CPU.InDMA = TRUE; - CPU.Cycles+=ONE_CYCLE*3; + CPU.InDMA = TRUE; + CPU.Cycles += ONE_CYCLE * 3; uint8 mask; for (mask = 1; mask; mask <<= 1, p++, d++) - { - if (byte & mask) - { - if (!p->LineCount) - { - //remember, InDMA is set. - //Get/Set incur no charges! - CPU.Cycles+=SLOW_ONE_CYCLE; - uint8 line = S9xGetByte ((p->ABank << 16) + p->Address); - if (line == 0x80) - { - p->Repeat = TRUE; - p->LineCount = 128; - } - else - { - p->Repeat = !(line & 0x80); - p->LineCount = line & 0x7f; - } - - // Disable H-DMA'ing into V-RAM (register 2118) for Hook - /* XXX: instead of p->BAddress == 0x18, make S9xSetPPU fail - * XXX: writes to $2118/9 when appropriate - */ + { + if (byte & mask) + { + if (!p->LineCount) + { + //remember, InDMA is set. + //Get/Set incur no charges! + CPU.Cycles += SLOW_ONE_CYCLE; + uint8 line = S9xGetByte((p->ABank << 16) + p->Address); + if (line == 0x80) + { + p->Repeat = TRUE; + p->LineCount = 128; + } + else + { + p->Repeat = !(line & 0x80); + p->LineCount = line & 0x7f; + } + + // Disable H-DMA'ing into V-RAM (register 2118) for Hook + /* XXX: instead of p->BAddress == 0x18, make S9xSetPPU fail + * XXX: writes to $2118/9 when appropriate + */ #ifdef SETA010_HDMA_FROM_CART - if (!p->LineCount) + if (!p->LineCount) #else - if (!p->LineCount || p->BAddress == 0x18) + if (!p->LineCount || p->BAddress == 0x18) #endif - { - byte &= ~mask; - p->IndirectAddress += HDMAMemPointers [d] - HDMABasePointers [d]; - Memory.FillRAM [0x4305 + (d << 4)] = (uint8) p->IndirectAddress; - Memory.FillRAM [0x4306 + (d << 4)] = p->IndirectAddress >> 8; - continue; - } - - p->Address++; - p->FirstLine = 1; - if (p->HDMAIndirectAddressing) - { - p->IndirectBank = Memory.FillRAM [0x4307 + (d << 4)]; - //again, no cycle charges while InDMA is set! - CPU.Cycles+=SLOW_ONE_CYCLE<<2; - p->IndirectAddress = S9xGetWord ((p->ABank << 16) + p->Address); - p->Address += 2; - } - else - { - p->IndirectBank = p->ABank; - p->IndirectAddress = p->Address; - } - HDMABasePointers [d] = HDMAMemPointers [d] = - S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress); + { + byte &= ~mask; + p->IndirectAddress += HDMAMemPointers [d] - HDMABasePointers [d]; + Memory.FillRAM [0x4305 + (d << 4)] = (uint8) p->IndirectAddress; + Memory.FillRAM [0x4306 + (d << 4)] = p->IndirectAddress >> 8; + continue; + } + + p->Address++; + p->FirstLine = 1; + if (p->HDMAIndirectAddressing) + { + p->IndirectBank = Memory.FillRAM [0x4307 + (d << 4)]; + //again, no cycle charges while InDMA is set! + CPU.Cycles += SLOW_ONE_CYCLE << 2; + p->IndirectAddress = S9xGetWord((p->ABank << 16) + p->Address); + p->Address += 2; + } + else + { + p->IndirectBank = p->ABank; + p->IndirectAddress = p->Address; + } + HDMABasePointers [d] = HDMAMemPointers [d] = + S9xGetMemPointer((p->IndirectBank << 16) + p->IndirectAddress); #ifdef SETA010_HDMA_FROM_CART - HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress; + HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress; #endif - } - else - { - CPU.Cycles += SLOW_ONE_CYCLE; - } - - if (!HDMAMemPointers [d]) - { - if (!p->HDMAIndirectAddressing) - { - p->IndirectBank = p->ABank; - p->IndirectAddress = p->Address; - } + } + else + CPU.Cycles += SLOW_ONE_CYCLE; + + if (!HDMAMemPointers [d]) + { + if (!p->HDMAIndirectAddressing) + { + p->IndirectBank = p->ABank; + p->IndirectAddress = p->Address; + } #ifdef SETA010_HDMA_FROM_CART - HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress; + HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress; #endif - if (!(HDMABasePointers [d] = HDMAMemPointers [d] = - S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress))) - { - /* XXX: Instead of this, goto a slow path that first - * XXX: verifies src!=Address Bus B, then uses - * XXX: S9xGetByte(). Or make S9xGetByte return OpenBus - * XXX: (probably?) for Address Bus B while inDMA. - */ - byte &= ~mask; - continue; - } - // Uncommenting the following line breaks Punchout - it starts - // H-DMA during the frame. - //p->FirstLine = TRUE; - } - if (p->Repeat && !p->FirstLine) - { - p->LineCount--; - continue; - } - - if (p->BAddress == 0x04){ - if(SNESGameFixes.Uniracers){ - PPU.OAMAddr = 0x10c; - PPU.OAMFlip=0; - } - } - - switch (p->TransferMode) - { - case 0: - CPU.Cycles += SLOW_ONE_CYCLE; + if (!(HDMABasePointers [d] = HDMAMemPointers [d] = + S9xGetMemPointer((p->IndirectBank << 16) + p->IndirectAddress))) + { + /* XXX: Instead of this, goto a slow path that first + * XXX: verifies src!=Address Bus B, then uses + * XXX: S9xGetByte(). Or make S9xGetByte return OpenBus + * XXX: (probably?) for Address Bus B while inDMA. + */ + byte &= ~mask; + continue; + } + // Uncommenting the following line breaks Punchout - it starts + // H-DMA during the frame. + //p->FirstLine = TRUE; + } + if (p->Repeat && !p->FirstLine) + { + p->LineCount--; + continue; + } + + if (p->BAddress == 0x04) + { + if (SNESGameFixes.Uniracers) + { + PPU.OAMAddr = 0x10c; + PPU.OAMFlip = 0; + } + } + + switch (p->TransferMode) + { + case 0: + CPU.Cycles += SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]++), 0x2100 + p->BAddress); - HDMAMemPointers [d]++; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]++), 0x2100 + p->BAddress); + HDMAMemPointers [d]++; #else - S9xSetPPU (*HDMAMemPointers [d]++, 0x2100 + p->BAddress); + S9xSetPPU(*HDMAMemPointers [d]++, 0x2100 + p->BAddress); #endif - break; - case 5: - CPU.Cycles += 2*SLOW_ONE_CYCLE; + break; + case 5: + CPU.Cycles += 2 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress); - HDMARawPointers [d] += 2; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2101 + p->BAddress); + HDMARawPointers [d] += 2; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); #endif - HDMAMemPointers [d] += 2; - /* fall through */ - case 1: - CPU.Cycles += 2*SLOW_ONE_CYCLE; + HDMAMemPointers [d] += 2; + /* fall through */ + case 1: + CPU.Cycles += 2 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress); - HDMARawPointers [d] += 2; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2101 + p->BAddress); + HDMARawPointers [d] += 2; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); #endif - HDMAMemPointers [d] += 2; - break; - case 2: - case 6: - CPU.Cycles += 2*SLOW_ONE_CYCLE; + HDMAMemPointers [d] += 2; + break; + case 2: + case 6: + CPU.Cycles += 2 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2100 + p->BAddress); - HDMARawPointers [d] += 2; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2100 + p->BAddress); + HDMARawPointers [d] += 2; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); #endif - HDMAMemPointers [d] += 2; - break; - case 3: - case 7: - CPU.Cycles += 4*SLOW_ONE_CYCLE; + HDMAMemPointers [d] += 2; + break; + case 3: + case 7: + CPU.Cycles += 4 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 2), 0x2101 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 3), 0x2101 + p->BAddress); - HDMARawPointers [d] += 4; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 2), 0x2101 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 3), 0x2101 + p->BAddress); + HDMARawPointers [d] += 4; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2101 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 2), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 3), 0x2101 + p->BAddress); #endif - HDMAMemPointers [d] += 4; - break; - case 4: - CPU.Cycles += 4*SLOW_ONE_CYCLE; + HDMAMemPointers [d] += 4; + break; + case 4: + CPU.Cycles += 4 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 2), 0x2102 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 3), 0x2103 + p->BAddress); - HDMARawPointers [d] += 4; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2101 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 2), 0x2102 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 3), 0x2103 + p->BAddress); + HDMARawPointers [d] += 4; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2102 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2103 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 2), 0x2102 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 3), 0x2103 + p->BAddress); #endif - HDMAMemPointers [d] += 4; - break; - } - if (!p->HDMAIndirectAddressing) - p->Address += HDMA_ModeByteCounts [p->TransferMode]; - p->IndirectAddress += HDMA_ModeByteCounts [p->TransferMode]; - /* XXX: Check for p->IndirectAddress crossing a mapping boundry, - * XXX: and invalidate HDMAMemPointers[d] - */ - p->FirstLine = FALSE; - p->LineCount--; - } - } - CPU.InDMA=FALSE; - return (byte); + HDMAMemPointers [d] += 4; + break; + } + if (!p->HDMAIndirectAddressing) + p->Address += HDMA_ModeByteCounts [p->TransferMode]; + p->IndirectAddress += HDMA_ModeByteCounts [p->TransferMode]; + /* XXX: Check for p->IndirectAddress crossing a mapping boundry, + * XXX: and invalidate HDMAMemPointers[d] + */ + p->FirstLine = FALSE; + p->LineCount--; + } + } + CPU.InDMA = FALSE; + return (byte); } -void S9xResetDMA () +void S9xResetDMA() { - int c,d; - for (d = 0; d < 8; d++) - { - DMA [d].TransferDirection = FALSE; - DMA [d].HDMAIndirectAddressing = FALSE; - DMA [d].AAddressFixed = TRUE; - DMA [d].AAddressDecrement = FALSE; - DMA [d].TransferMode = 0xff; - DMA [d].ABank = 0xff; - DMA [d].AAddress = 0xffff; - DMA [d].Address = 0xffff; - DMA [d].BAddress = 0xff; - DMA [d].TransferBytes = 0xffff; - } - for (c = 0x4300; c < 0x4380; c += 0x10) - { - for (d = c; d < c + 12; d++) - Memory.FillRAM [d] = 0xff; - - Memory.FillRAM [c + 0xf] = 0xff; - } + int c, d; + for (d = 0; d < 8; d++) + { + DMA [d].TransferDirection = FALSE; + DMA [d].HDMAIndirectAddressing = FALSE; + DMA [d].AAddressFixed = TRUE; + DMA [d].AAddressDecrement = FALSE; + DMA [d].TransferMode = 0xff; + DMA [d].ABank = 0xff; + DMA [d].AAddress = 0xffff; + DMA [d].Address = 0xffff; + DMA [d].BAddress = 0xff; + DMA [d].TransferBytes = 0xffff; + } + for (c = 0x4300; c < 0x4380; c += 0x10) + { + for (d = c; d < c + 12; d++) + Memory.FillRAM [d] = 0xff; + + Memory.FillRAM [c + 0xf] = 0xff; + } } -- cgit v1.2.3