~ubuntu-branches/ubuntu/vivid/fceux/vivid

« back to all changes in this revision

Viewing changes to src/boards/dsoundv1.cpp

  • Committer: Package Import Robot
  • Author(s): Joe Nahmias
  • Date: 2014-03-02 19:22:04 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20140302192204-9f0aehi5stfnhn7d
Tags: 2.2.2+dfsg0-1
* Imported Upstream version 2.2.2
  + remove patches merged upstream; refresh remaining
  + remove windows compiled help files and non-free Visual C files
* Use C++11 standard static assertion functionality
* fix upstream installation of support files
* New patch 0004-ignore-missing-windows-help-CHM-file.patch
* update d/copyright for new, renamed, deleted files
* d/control: bump std-ver to 3.9.5, no changes needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* FCE Ultra - NES/Famicom Emulator
2
 
 *
3
 
 * Copyright notice for this file:
4
 
 *  Copyright (C) 2013 CaH4e3
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 */
20
 
 
21
 
#include "mapinc.h"
22
 
 
23
 
static uint8 reg[4];
24
 
 
25
 
static uint8 *WRAM = NULL;
26
 
static uint32 WRAMSIZE;
27
 
 
28
 
// SND Registers
29
 
static uint8 pcm_enable = 0;
30
 
static int16 pcm_latch = 0x3F6, pcm_clock = 0x3F6;
31
 
static writefunc pcmwrite;
32
 
 
33
 
static SFORMAT StateRegs[] =
34
 
{
35
 
        { reg, 4, "REGS" },
36
 
        { 0 }
37
 
};
38
 
 
39
 
static int16 step_size[49] = {
40
 
                           16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
41
 
                           41, 45, 50, 55, 60, 66, 73, 80, 88, 97,
42
 
                           107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
43
 
                           279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
44
 
                           724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
45
 
                           }; //49 items
46
 
static int32 step_adj[16] = { -1, -1, -1, -1, 2, 5, 7, 9, -1, -1, -1, -1, 2, 5, 7, 9 };
47
 
 
48
 
//decode stuff
49
 
static int32 jedi_table[16 * 49];
50
 
static int32 acc = 0; //ADPCM accumulator, initial condition must be 0
51
 
static int32 decstep = 0; //ADPCM decoding step, initial condition must be 0
52
 
 
53
 
static void jedi_table_init()
54
 
{
55
 
        int step, nib;
56
 
 
57
 
        for (step = 0; step < 49; step++)
58
 
        {
59
 
                for (nib = 0; nib < 16; nib++)
60
 
                {
61
 
                        int value = (2 * (nib & 0x07) + 1) * step_size[step] / 8;
62
 
                        jedi_table[step * 16 + nib] = ((nib & 0x08) != 0) ? -value : value;
63
 
                }
64
 
        }
65
 
}
66
 
 
67
 
static uint8 decode(uint8 code)
68
 
{
69
 
        acc += jedi_table[decstep + code];
70
 
        if ((acc & ~0x7ff) != 0) // acc is > 2047
71
 
                acc |= ~0xfff;
72
 
        else acc &= 0xfff;
73
 
        decstep += step_adj[code & 7] * 16;
74
 
        if (decstep < 0) decstep = 0;
75
 
        if (decstep > 48 * 16) decstep = 48 * 16;
76
 
        return (acc >> 8) & 0xff;
77
 
}
78
 
 
79
 
static void Sync(void) {
80
 
        uint32 sbank = reg[1] & 0x7;
81
 
        uint32 bbank = reg[2];
82
 
        setchr8(0);
83
 
        setprg8r(0x10, 0x6000, reg[3] & 3);
84
 
        if(reg[0] & 2) {        // UNROM mode
85
 
                setprg16(0x8000, (bbank << 3) | sbank);
86
 
                if(reg[0] & 4)
87
 
                        setprg16(0xC000, (bbank << 3) | 6 | (reg[1] & 1));
88
 
                else
89
 
                        setprg16(0xC000, (bbank << 3) | 7);
90
 
        } else {                // NROM mode
91
 
                uint32 bank = (bbank << 3) | sbank;
92
 
                if(reg[0] & 4) {
93
 
                        setprg16(0x8000, bank);
94
 
                        setprg16(0xC000, bank);
95
 
                } else
96
 
                        setprg32(0x8000, bank >> 1);
97
 
        }
98
 
        setmirror((reg[0] & 1) ^ 1);
99
 
}
100
 
 
101
 
static DECLFW(UNLDSOUNDV1Write) {
102
 
        reg[A & 3] = V;
103
 
//      FCEU_printf("cmd %04x:%02x\n", A, V);
104
 
        Sync();
105
 
}
106
 
 
107
 
static DECLFW(UNLDSOUNDV1WriteSnd) {
108
 
        if(A == 0x5800) {
109
 
                if(V & 0xF0) {
110
 
                pcm_enable = 1;
111
 
//                      pcmwrite(0x4011, (V & 0xF) << 3);
112
 
                        pcmwrite(0x4011, decode(V & 0xf));
113
 
                } else
114
 
                pcm_enable = 0;
115
 
        } else
116
 
                FCEU_printf("misc %04x:%02x\n", A, V);
117
 
}
118
 
 
119
 
static DECLFR(UNLDSOUNDV1ReadSnd) {
120
 
        if(A == 0x5800)
121
 
                return (X.DB & 0xBF) | ((pcm_enable ^ 1) <<6);
122
 
        else
123
 
                return X.DB;
124
 
}
125
 
 
126
 
static void UNLDSOUNDV1Power(void) {
127
 
        reg[0] = reg[1] = reg[2]  = reg[3] = 0;
128
 
        Sync();
129
 
        pcmwrite = GetWriteHandler(0x4011);
130
 
        SetWriteHandler(0x4800, 0x4fff, UNLDSOUNDV1Write);
131
 
        SetWriteHandler(0x5800, 0x5fff, UNLDSOUNDV1WriteSnd);
132
 
        SetReadHandler(0x5800, 0x5fff, UNLDSOUNDV1ReadSnd);
133
 
        SetReadHandler(0x6000, 0x7fff, CartBR);
134
 
        SetWriteHandler(0x6000, 0x7fff, CartBW);
135
 
        SetReadHandler(0x8000, 0xffff, CartBR);
136
 
}
137
 
 
138
 
static void UNLDSOUNDV1SndClk(int a) {
139
 
        if (pcm_enable) {
140
 
                pcm_latch -= a;
141
 
                if (pcm_latch <= 0) {
142
 
                        pcm_latch += pcm_clock;
143
 
                        pcm_enable = 0;
144
 
                }
145
 
        }
146
 
}
147
 
 
148
 
static void UNLDSOUNDV1Close(void) {
149
 
        if (WRAM)
150
 
                FCEU_gfree(WRAM);
151
 
        WRAM = NULL;
152
 
}
153
 
 
154
 
static void StateRestore(int version) {
155
 
        Sync();
156
 
}
157
 
 
158
 
void UNLDSOUNDV1_Init(CartInfo *info) {
159
 
        info->Power = UNLDSOUNDV1Power;
160
 
        info->Close = UNLDSOUNDV1Close;
161
 
        GameStateRestore = StateRestore;
162
 
        MapIRQHook = UNLDSOUNDV1SndClk;
163
 
 
164
 
        jedi_table_init();
165
 
 
166
 
        WRAMSIZE = 32768;
167
 
        WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
168
 
        SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
169
 
        AddExState(WRAM, WRAMSIZE, 0, "WRAM");
170
 
        if (info->battery) {
171
 
                info->SaveGame[0] = WRAM;
172
 
                info->SaveGameLen[0] = WRAMSIZE;
173
 
        }
174
 
        AddExState(&StateRegs, ~0, 0, 0);
175
 
}