1 // license:BSD-3-Clause
2 // copyright-holders:Fabio Priuli
3 /***********************************************************************************************************
4
5
6 NES/Famicom cartridge emulation for Hosenkan PCBs
7
8
9 ***********************************************************************************************************/
10
11
12 #include "emu.h"
13 #include "hosenkan.h"
14
15 #include "video/ppu2c0x.h" // this has to be included so that IRQ functions can access ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE
16 #include "screen.h"
17
18
19 #ifdef NES_PCB_DEBUG
20 #define VERBOSE 1
21 #else
22 #define VERBOSE 0
23 #endif
24
25 #define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
26
27
28 //-------------------------------------------------
29 // constructor
30 //-------------------------------------------------
31
32 DEFINE_DEVICE_TYPE(NES_HOSENKAN, nes_hosenkan_device, "nes_hosenkan", "NES Cart HOSENKAN PCB")
33
34
nes_hosenkan_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)35 nes_hosenkan_device::nes_hosenkan_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
36 : nes_nrom_device(mconfig, NES_HOSENKAN, tag, owner, clock)
37 , m_irq_count(0)
38 , m_irq_count_latch(0)
39 , m_irq_clear(0)
40 , m_irq_enable(0)
41 , m_latch(0)
42 {
43 }
44
45
46
47
device_start()48 void nes_hosenkan_device::device_start()
49 {
50 common_start();
51 save_item(NAME(m_irq_enable));
52 save_item(NAME(m_irq_count));
53 save_item(NAME(m_irq_count_latch));
54 save_item(NAME(m_irq_clear));
55 save_item(NAME(m_latch));
56 }
57
pcb_reset()58 void nes_hosenkan_device::pcb_reset()
59 {
60 m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
61 prg32((m_prg_chunks - 1) >> 1);
62 chr8(0, m_chr_source);
63
64 m_latch = 0;
65 m_irq_enable = 0;
66 m_irq_count = m_irq_count_latch = 0;
67 m_irq_clear = 0;
68 }
69
70
71
72 /*-------------------------------------------------
73 mapper specific handlers
74 -------------------------------------------------*/
75
76 /*-------------------------------------------------
77
78 Bootleg Board by Hosenkan
79
80 Games: Pocahontas, Super Donkey Kong
81
82 iNES: mapper 182
83
84 In MESS: Supported.
85
86 -------------------------------------------------*/
87
88 // same as MMC3!
hblank_irq(int scanline,int vblank,int blanked)89 void nes_hosenkan_device::hblank_irq( int scanline, int vblank, int blanked )
90 {
91 if (scanline < ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE)
92 {
93 int prior_count = m_irq_count;
94 if ((m_irq_count == 0) || m_irq_clear)
95 m_irq_count = m_irq_count_latch;
96 else
97 m_irq_count--;
98
99 if (m_irq_enable && !blanked && (m_irq_count == 0) && (prior_count || m_irq_clear))
100 {
101 LOG_MMC(("irq fired, scanline: %d\n", scanline));
102 hold_irq_line();
103 }
104 }
105 m_irq_clear = 0;
106 }
107
write_h(offs_t offset,uint8_t data)108 void nes_hosenkan_device::write_h(offs_t offset, uint8_t data)
109 {
110 LOG_MMC(("hosenkan write_h, offset: %04x, data: %02x\n", offset, data));
111
112 switch (offset & 0x7003)
113 {
114 case 0x0001:
115 set_nt_mirroring(BIT(data, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
116 break;
117 case 0x2000:
118 m_latch = data;
119 break;
120 case 0x4000:
121 switch (m_latch)
122 {
123 case 0:
124 chr2_0(data >> 1, CHRROM);
125 break;
126 case 1:
127 chr1_5(data, CHRROM);
128 break;
129 case 2:
130 chr2_2(data >> 1, CHRROM);
131 break;
132 case 3:
133 chr1_7(data, CHRROM);
134 break;
135 case 4:
136 prg8_89(data);
137 break;
138 case 5:
139 prg8_ab(data);
140 break;
141 case 6:
142 chr1_4(data, CHRROM);
143 break;
144 case 7:
145 chr1_6(data, CHRROM);
146 break;
147 }
148 break;
149 case 0x6003:
150 if (data)
151 {
152 m_irq_count = data;
153 m_irq_enable = 1;
154 }
155 else
156 m_irq_enable = 0;
157 break;
158 }
159 }
160