blob: ee3c8e544da40464b9349488f222a686e1f14484 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
/***************************************************************************
dma.c - description
-------------------
begin : Wed May 15 2002
copyright : (C) 2002 by Pete Bernert
email : BlackDove@addcom.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. See also the license.txt file for *
* additional informations. *
* *
***************************************************************************/
#include "stdafx.h"
#define _IN_DMA
#include "externals.h"
#include "registers.h"
////////////////////////////////////////////////////////////////////////
// READ DMA (one value)
////////////////////////////////////////////////////////////////////////
unsigned short CALLBACK SPUreadDMA(void)
{
unsigned short s=spuMem[spuAddr>>1];
spuAddr+=2;
if(spuAddr>0x7ffff) spuAddr=0;
iSpuAsyncWait=0;
return s;
}
////////////////////////////////////////////////////////////////////////
// READ DMA (many values)
////////////////////////////////////////////////////////////////////////
void CALLBACK SPUreadDMAMem(unsigned short * pusPSXMem,int iSize)
{
int i;
unsigned char crc=0;
spuStat |= STAT_DATA_BUSY;
for(i=0;i<iSize;i++)
{
Check_IRQ( spuAddr, 0 );
crc|=*pusPSXMem++=spuMem[spuAddr>>1]; // spu addr got by writeregister
spuAddr+=2; // inc spu addr
spuMem[spuAddr>>1];
// guess based on Vib Ribbon (below)
if(spuAddr>0x7ffff) break;
}
iSpuAsyncWait=0;
/*
/* Toshiden Subaru "story screen" hack.
/*
/* After character selection screen, the game checks values inside returned
/* SPU buffer and all values cannot be 0x0.
/* Due to XA timings(?) we return buffer that has only NULLs.
/* Setting little lag to MixXA() causes buffer to have some non-NULL values,
/* but causes garbage sound so this hack is preferable.
/*
/* Note: When messing with xa.c like fixing Suikoden II's demo video sound issue
/* this should be handled as well.
*/
if (crc == 0) *--pusPSXMem=0xFF;
spuStat &= ~STAT_DATA_BUSY;
spuStat &= ~STAT_DMA_NON;
spuStat &= ~STAT_DMA_W;
spuStat |= STAT_DMA_R;
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// to investigate: do sound data updates by writedma affect spu
// irqs? Will an irq be triggered, if new data is written to
// the memory irq address?
////////////////////////////////////////////////////////////////////////
// WRITE DMA (one value)
////////////////////////////////////////////////////////////////////////
void CALLBACK SPUwriteDMA(unsigned short val)
{
spuMem[spuAddr>>1] = val; // spu addr got by writeregister
spuAddr+=2; // inc spu addr
if(spuAddr>0x7ffff) spuAddr=0; // wrap
iSpuAsyncWait=0;
}
////////////////////////////////////////////////////////////////////////
// WRITE DMA (many values)
////////////////////////////////////////////////////////////////////////
void CALLBACK SPUwriteDMAMem(unsigned short * pusPSXMem,int iSize)
{
int i;
spuStat |= STAT_DATA_BUSY;
for(i=0;i<iSize;i++)
{
Check_IRQ( spuAddr, 0 );
spuMem[spuAddr>>1] = *pusPSXMem++; // spu addr got by writeregister
spuAddr+=2; // inc spu addr
// Vib Ribbon - stop transfer (reverb playback)
if(spuAddr>0x7ffff) break;
}
iSpuAsyncWait=0;
spuStat &= ~STAT_DATA_BUSY;
spuStat &= ~STAT_DMA_NON;
spuStat &= ~STAT_DMA_R;
spuStat |= STAT_DMA_W;
}
////////////////////////////////////////////////////////////////////////
|