summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/nes/hosenkan.cpp
blob: 4200655897e03c4134b1f113348bdb26efe46bb4 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
/***********************************************************************************************************


 NES/Famicom cartridge emulation for Hosenkan PCBs


 ***********************************************************************************************************/


#include "emu.h"
#include "hosenkan.h"

#include "video/ppu2c0x.h"      // this has to be included so that IRQ functions can access ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE
#include "screen.h"


#ifdef NES_PCB_DEBUG
#define VERBOSE 1
#else
#define VERBOSE 0
#endif

#define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)


//-------------------------------------------------
//  constructor
//-------------------------------------------------

DEFINE_DEVICE_TYPE(NES_HOSENKAN, nes_hosenkan_device, "nes_hosenkan", "NES Cart HOSENKAN PCB")


nes_hosenkan_device::nes_hosenkan_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: nes_nrom_device(mconfig, NES_HOSENKAN, tag, owner, clock)
	, m_irq_count(0)
	, m_irq_count_latch(0)
	, m_irq_clear(0)
	, m_irq_enable(0)
	, m_latch(0)
{
}




void nes_hosenkan_device::device_start()
{
	common_start();
	save_item(NAME(m_irq_enable));
	save_item(NAME(m_irq_count));
	save_item(NAME(m_irq_count_latch));
	save_item(NAME(m_irq_clear));
	save_item(NAME(m_latch));
}

void nes_hosenkan_device::pcb_reset()
{
	m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
	prg32((m_prg_chunks - 1) >> 1);
	chr8(0, m_chr_source);

	m_latch = 0;
	m_irq_enable = 0;
	m_irq_count = m_irq_count_latch = 0;
	m_irq_clear = 0;
}



/*-------------------------------------------------
 mapper specific handlers
 -------------------------------------------------*/

/*-------------------------------------------------

 Bootleg Board by Hosenkan

 Games: Pocahontas, Super Donkey Kong

 iNES: mapper 182

 In MESS: Supported.

 -------------------------------------------------*/

// same as MMC3!
void nes_hosenkan_device::hblank_irq( int scanline, int vblank, int blanked )
{
	if (scanline < ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE)
	{
		int prior_count = m_irq_count;
		if ((m_irq_count == 0) || m_irq_clear)
			m_irq_count = m_irq_count_latch;
		else
			m_irq_count--;

		if (m_irq_enable && !blanked && (m_irq_count == 0) && (prior_count || m_irq_clear))
		{
			LOG_MMC(("irq fired, scanline: %d\n", scanline));
			hold_irq_line();
		}
	}
	m_irq_clear = 0;
}

WRITE8_MEMBER(nes_hosenkan_device::write_h)
{
	LOG_MMC(("hosenkan write_h, offset: %04x, data: %02x\n", offset, data));

	switch (offset & 0x7003)
	{
		case 0x0001:
			set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
			break;
		case 0x2000:
			m_latch = data;
			break;
		case 0x4000:
			switch (m_latch)
			{
				case 0:
					chr2_0(data >> 1, CHRROM);
					break;
				case 1:
					chr1_5(data, CHRROM);
					break;
				case 2:
					chr2_2(data >> 1, CHRROM);
					break;
				case 3:
					chr1_7(data, CHRROM);
					break;
				case 4:
					prg8_89(data);
					break;
				case 5:
					prg8_ab(data);
					break;
				case 6:
					chr1_4(data, CHRROM);
					break;
				case 7:
					chr1_6(data, CHRROM);
					break;
			}
			break;
		case 0x6003:
			if (data)
			{
				m_irq_count = data;
				m_irq_enable = 1;
			}
			else
				m_irq_enable = 0;
			break;
	}
}