~ubuntu-branches/ubuntu/utopic/fceux/utopic-proposed

« back to all changes in this revision

Viewing changes to src/boards/178.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
1
/* FCE Ultra - NES/Famicom Emulator
2
2
 *
3
3
 * Copyright notice for this file:
4
 
 *  Copyright (C) 2007 CaH4e3
 
4
 *  Copyright (C) 2013 CaH4e3
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or modify
7
7
 * it under the terms of the GNU General Public License as published by
16
16
 * You should have received a copy of the GNU General Public License
17
17
 * along with this program; if not, write to the Free Software
18
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 *
 
20
 * DSOUNDV1/FL-TR8MA boards (32K WRAM, 8/16M), 178 mapper boards (8K WRAM, 4/8M)
 
21
 * Various Education Cartridges
 
22
 *
19
23
 */
20
24
 
21
25
#include "mapinc.h"
22
26
 
23
27
static uint8 reg[4];
 
28
 
24
29
static uint8 *WRAM = NULL;
25
30
static uint32 WRAMSIZE;
26
31
 
 
32
// SND Registers
 
33
static uint8 pcm_enable = 0;
 
34
static int16 pcm_latch = 0x3F6, pcm_clock = 0x3F6;
 
35
static writefunc pcmwrite;
 
36
 
27
37
static SFORMAT StateRegs[] =
28
38
{
29
39
        { reg, 4, "REGS" },
30
40
        { 0 }
31
41
};
32
42
 
 
43
static int16 step_size[49] = {
 
44
        16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
 
45
        41, 45, 50, 55, 60, 66, 73, 80, 88, 97,
 
46
        107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
 
47
        279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
 
48
        724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
 
49
};      //49 items
 
50
static int32 step_adj[16] = { -1, -1, -1, -1, 2, 5, 7, 9, -1, -1, -1, -1, 2, 5, 7, 9 };
 
51
 
 
52
//decode stuff
 
53
static int32 jedi_table[16 * 49];
 
54
static int32 acc = 0;   //ADPCM accumulator, initial condition must be 0
 
55
static int32 decstep = 0;       //ADPCM decoding step, initial condition must be 0
 
56
 
 
57
static void jedi_table_init() {
 
58
        int step, nib;
 
59
 
 
60
        for (step = 0; step < 49; step++) {
 
61
                for (nib = 0; nib < 16; nib++) {
 
62
                        int value = (2 * (nib & 0x07) + 1) * step_size[step] / 8;
 
63
                        jedi_table[step * 16 + nib] = ((nib & 0x08) != 0) ? -value : value;
 
64
                }
 
65
        }
 
66
}
 
67
 
 
68
static uint8 decode(uint8 code) {
 
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
 
33
79
static void Sync(void) {
34
 
        uint8 bank = (reg[2] & 3) << 3;
 
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
        }
35
98
        setmirror((reg[0] & 1) ^ 1);
36
 
        setprg8r(0x10, 0x6000, 0);
37
 
        setchr8(0);
38
 
        if (reg[0] & 2) {
39
 
                setprg16(0x8000, (reg[1] & 7) | bank);
40
 
                setprg16(0xC000, ((~0) & 7) | bank);
41
 
        } else {
42
 
                setprg16(0x8000, (reg[1] & 6) | bank);
43
 
                setprg16(0xC000, (reg[1] & 6) | bank | 1);
44
 
        }
45
99
}
46
100
 
47
101
static DECLFW(M178Write) {
48
102
        reg[A & 3] = V;
 
103
//      FCEU_printf("cmd %04x:%02x\n", A, V);
49
104
        Sync();
50
105
}
51
106
 
 
107
static DECLFW(M178WriteSnd) {
 
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(M178ReadSnd) {
 
120
        if (A == 0x5800)
 
121
                return (X.DB & 0xBF) | ((pcm_enable ^ 1) << 6);
 
122
        else
 
123
                return X.DB;
 
124
}
 
125
 
52
126
static void M178Power(void) {
53
 
        reg[0] = 1;
54
 
        reg[1] = 0;
55
 
        reg[2] = 0;
56
 
        reg[3] = 0;
 
127
        reg[0] = reg[1] = reg[2] = reg[3] = 0;
57
128
        Sync();
58
 
        SetReadHandler(0x6000, 0x7FFF, CartBR);
59
 
        SetWriteHandler(0x6000, 0x7FFF, CartBW);
60
 
        SetReadHandler(0x8000, 0xFFFF, CartBR);
61
 
        SetWriteHandler(0x4800, 0x4803, M178Write);
 
129
        pcmwrite = GetWriteHandler(0x4011);
 
130
        SetWriteHandler(0x4800, 0x4fff, M178Write);
 
131
        SetWriteHandler(0x5800, 0x5fff, M178WriteSnd);
 
132
        SetReadHandler(0x5800, 0x5fff, M178ReadSnd);
 
133
        SetReadHandler(0x6000, 0x7fff, CartBR);
 
134
        SetWriteHandler(0x6000, 0x7fff, CartBW);
 
135
        SetReadHandler(0x8000, 0xffff, CartBR);
 
136
}
 
137
 
 
138
static void M178SndClk(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
        }
62
146
}
63
147
 
64
148
static void M178Close(void) {
67
151
        WRAM = NULL;
68
152
}
69
153
 
70
 
 
71
154
static void StateRestore(int version) {
72
155
        Sync();
73
156
}
76
159
        info->Power = M178Power;
77
160
        info->Close = M178Close;
78
161
        GameStateRestore = StateRestore;
79
 
 
80
 
        WRAMSIZE = 8192;
 
162
        MapIRQHook = M178SndClk;
 
163
 
 
164
        jedi_table_init();
 
165
 
 
166
        WRAMSIZE = 32768;
81
167
        WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
82
168
        SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
83
169
        if (info->battery) {