1 // license:BSD-3-Clause
2 // copyright-holders:Fabio Priuli
3 /***********************************************************************************************************
4 
5 
6  NES/Famicom cartridge emulation for 2A03 Puritans Album
7 
8 
9  Here we emulate the PCB designed by infiniteneslives and
10  rainwarrior for this homebew multicart [mapper 31]
11  The main difference of this PCB compared to others is that it
12  uses 4k PRG banks!
13 
14  ***********************************************************************************************************/
15 
16 
17 #include "emu.h"
18 #include "2a03pur.h"
19 
20 
21 #ifdef NES_PCB_DEBUG
22 #define VERBOSE 1
23 #else
24 #define VERBOSE 0
25 #endif
26 
27 #define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
28 
29 
30 //-------------------------------------------------
31 //  constructor
32 //-------------------------------------------------
33 
34 DEFINE_DEVICE_TYPE(NES_2A03PURITANS, nes_2a03pur_device, "nes_2a03pur", "NES Cart 2A03 Puritans Album PCB")
35 
36 
nes_2a03pur_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)37 nes_2a03pur_device::nes_2a03pur_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
38 	: nes_nrom_device(mconfig, NES_2A03PURITANS, tag, owner, clock)
39 {
40 }
41 
42 
43 
device_start()44 void nes_2a03pur_device::device_start()
45 {
46 	common_start();
47 	save_item(NAME(m_reg));
48 	memset(m_reg, 0x00, sizeof(m_reg));
49 	m_reg[7] = 0xff & ((m_prg_chunks << 2) - 1);
50 }
51 
pcb_reset()52 void nes_2a03pur_device::pcb_reset()
53 {
54 	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
55 	chr8(0, m_chr_source);
56 	// register content is not touched by reset
57 }
58 
59 
60 /*-------------------------------------------------
61  mapper specific handlers
62  -------------------------------------------------*/
63 
64 /*-------------------------------------------------
65 
66  Board 2A03 Puritans Album
67 
68  In MESS: supported.
69 
70  This mapper supports up to 1MB of PRG-ROM, in 4k
71  banks located at $8000, $9000, $A000, $B000, $C000,
72  $D000, $E000, and $F000. Each bank is selected by n
73  8-bit register at $5FF8, $5FF9, $5FFA, $5FFB, $5FFC,
74  $5FFD, $5FFE, and $5FFF, respectively, just like NSF
75  banking. These registers are mirrored across the
76  entire $5000-$5FFF region (the register is selected
77  by the low 3 bits), but it is recommended to use the
78  original addresses. The mirroring is merely a
79  convenience for the hardware implementation.
80 
81  The 8kb CHR region may be RAM or ROM. This project
82  uses CHR-RAM, and the board used by infiniteneslives
83  for this project may only support CHR-RAM.
84 
85  At power-on, the mapper automatically sets all bits
86  in the $5FFF bank register, placing the highest bank
87  in $F000. This occurs on power-on but not on reset,
88  so any bank that is mapped to $F000 after power-on
89  should contain a valid reset vector.
90 
91  This has been assigned to iNES mapper 31.
92  -------------------------------------------------*/
93 
write_l(offs_t offset,uint8_t data)94 void nes_2a03pur_device::write_l(offs_t offset, uint8_t data)
95 {
96 	LOG_MMC(("2a03 puritans write_l, offset: %04x, data: %02x\n", offset, data));
97 	offset += 0x100;
98 	if (offset >= 0x1000)
99 		m_reg[offset & 7] = data & ((m_prg_chunks << 2) - 1);
100 }
101 
read_h(offs_t offset)102 uint8_t nes_2a03pur_device::read_h(offs_t offset)
103 {
104 	LOG_MMC(("2a03 puritans read_h, offset: %04x\n", offset));
105 
106 	return m_prg[(m_reg[(offset >> 12) & 7] * 0x1000) + (offset & 0x0fff)];
107 }
108