Skip to content

Commit 39ba2ac

Browse files
committed
NES: Mapper 165 from VirtuaNES (not working correctly yet) (#194)
1 parent bc85754 commit 39ba2ac

File tree

2 files changed

+215
-0
lines changed

2 files changed

+215
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/*
2+
** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com)
3+
**
4+
**
5+
** This program is free software; you can redistribute it and/or
6+
** modify it under the terms of version 2 of the GNU Library General
7+
** Public License as published by the Free Software Foundation.
8+
**
9+
** This program is distributed in the hope that it will be useful,
10+
** but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
** Library General Public License for more details. To obtain a
13+
** copy of the GNU Library General Public License, write to the Free
14+
** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15+
**
16+
** Any permitted reproduction of these routines, in whole or in part,
17+
** must bear this legend.
18+
**
19+
**
20+
** map165.c: Fire Emblem mapper
21+
** Code adapted from VirtuaNES (GPLv2)
22+
**
23+
*/
24+
25+
#include "nes/nes.h"
26+
27+
static uint8_t reg[8];
28+
static uint8_t prg0, prg1;
29+
static uint8_t chr0, chr1, chr2, chr3;
30+
static uint8_t we_sram;
31+
static uint8_t latch;
32+
33+
static void SetPROM_8K_Bank(int page, int bank)
34+
{
35+
// CPU_MEM_BANK[page] = PROM+0x2000*bank;
36+
// CPU_MEM_TYPE[page] = BANKTYPE_ROM;
37+
// CPU_MEM_PAGE[page] = bank;
38+
mmc_bankprg(8, 0x2000 * page, bank, PRG_ROM);
39+
}
40+
41+
static void SetBank_CPU(void)
42+
{
43+
SetPROM_8K_Bank(4, prg0);
44+
SetPROM_8K_Bank(5, prg1);
45+
SetPROM_8K_Bank(6, -2); // PROM_8K_SIZE - 2
46+
SetPROM_8K_Bank(7, -1); // PROM_8K_SIZE - 1
47+
}
48+
49+
static void SetBank_PPUSUB(int bank, int page)
50+
{
51+
if (page == 0)
52+
{
53+
// SetCRAM_4K_Bank(bank, page >> 2);
54+
mmc_bankchr(4, 0x0400 * bank, page >> 2, CHR_RAM);
55+
}
56+
else
57+
{
58+
// SetVROM_4K_Bank(bank, page >> 2);
59+
mmc_bankchr(4, 0x0400 * bank, page >> 2, CHR_ROM);
60+
}
61+
}
62+
63+
static void SetBank_PPU(void)
64+
{
65+
if (latch == 0xFD)
66+
{
67+
SetBank_PPUSUB(0, chr0);
68+
SetBank_PPUSUB(4, chr2);
69+
}
70+
else
71+
{
72+
SetBank_PPUSUB(0, chr1);
73+
SetBank_PPUSUB(4, chr3);
74+
}
75+
}
76+
77+
static void PPU_ChrLatch(uint32 addr, uint8 data)
78+
{
79+
uint32_t mask = addr & 0x1FF0;
80+
81+
if (mask == 0x1FD0)
82+
{
83+
latch = 0xFD;
84+
SetBank_PPU();
85+
}
86+
else if (mask == 0x1FE0)
87+
{
88+
latch = 0xFE;
89+
SetBank_PPU();
90+
}
91+
}
92+
93+
static void map_write(uint32 addr, uint8 data)
94+
{
95+
switch (addr & 0xE001)
96+
{
97+
case 0x8000:
98+
reg[0] = data;
99+
SetBank_CPU();
100+
SetBank_PPU();
101+
break;
102+
case 0x8001:
103+
reg[1] = data;
104+
105+
switch (reg[0] & 0x07)
106+
{
107+
case 0x00:
108+
chr0 = data & 0xFC;
109+
if (latch == 0xFD)
110+
SetBank_PPU();
111+
break;
112+
case 0x01:
113+
chr1 = data & 0xFC;
114+
if (latch == 0xFE)
115+
SetBank_PPU();
116+
break;
117+
118+
case 0x02:
119+
chr2 = data & 0xFC;
120+
if (latch == 0xFD)
121+
SetBank_PPU();
122+
break;
123+
case 0x04:
124+
chr3 = data & 0xFC;
125+
if (latch == 0xFE)
126+
SetBank_PPU();
127+
break;
128+
129+
case 0x06:
130+
prg0 = data;
131+
SetBank_CPU();
132+
break;
133+
case 0x07:
134+
prg1 = data;
135+
SetBank_CPU();
136+
break;
137+
}
138+
break;
139+
case 0xA000:
140+
reg[2] = data;
141+
if (data & 0x01)
142+
ppu_setmirroring(PPU_MIRROR_HORI);
143+
else
144+
ppu_setmirroring(PPU_MIRROR_VERT);
145+
break;
146+
case 0xA001:
147+
reg[3] = data;
148+
break;
149+
default:
150+
break;
151+
}
152+
}
153+
154+
static void map_getstate(uint8 *state)
155+
{
156+
for (int i = 0; i < 8; i++)
157+
state[i] = reg[i];
158+
state[8] = prg0;
159+
state[9] = prg1;
160+
state[10] = chr0;
161+
state[11] = chr1;
162+
state[12] = chr2;
163+
state[13] = chr3;
164+
state[14] = latch;
165+
}
166+
167+
static void map_setstate(uint8 *state)
168+
{
169+
for (int i = 0; i < 8; i++)
170+
reg[i] = state[i];
171+
prg0 = state[8];
172+
prg1 = state[9];
173+
chr0 = state[10];
174+
chr1 = state[11];
175+
chr2 = state[12];
176+
chr3 = state[13];
177+
latch = state[14];
178+
}
179+
180+
static void map_init(rom_t *cart)
181+
{
182+
for (int i = 0; i < 8; i++)
183+
reg[i] = 0x00;
184+
prg0 = 0;
185+
prg1 = 1;
186+
SetBank_CPU();
187+
188+
chr0 = 0;
189+
chr1 = 0;
190+
chr2 = 4;
191+
chr3 = 4;
192+
latch = 0xFD;
193+
SetBank_PPU();
194+
195+
we_sram = 0; // Disable
196+
197+
ppu_setlatchfunc(PPU_ChrLatch);
198+
}
199+
200+
mapintf_t map165_intf =
201+
{
202+
.number = 165,
203+
.name = "Mapper 165",
204+
.init = map_init,
205+
.vblank = NULL,
206+
.hblank = NULL,
207+
.get_state = map_getstate,
208+
.set_state = map_setstate,
209+
.mem_read = {},
210+
.mem_write = {
211+
{0x8000, 0xFFFF, map_write},
212+
},
213+
};

retro-core/components/nofrendo/mappers/mappers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ extern mapintf_t map119_intf;
5252
extern mapintf_t map160_intf;
5353
extern mapintf_t map162_intf;
5454
extern mapintf_t map163_intf;
55+
extern mapintf_t map165_intf;
5556
extern mapintf_t map176_intf;
5657
extern mapintf_t map185_intf;
5758
extern mapintf_t map191_intf;
@@ -116,6 +117,7 @@ static const mapintf_t *mappers[] =
116117
&map160_intf,
117118
&map162_intf,
118119
&map163_intf,
120+
&map165_intf,
119121
&map176_intf,
120122
&map185_intf,
121123
&map191_intf,

0 commit comments

Comments
 (0)