1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 #ifndef MAME_MACHINE_NES_VT_SOC_H
4 #define MAME_MACHINE_NES_VT_SOC_H
5 
6 #pragma once
7 
8 #include "cpu/m6502/n2a03.h"
9 #include "sound/nes_apu_vt.h"
10 #include "machine/m6502_vtscr.h"
11 #include "machine/m6502_swap_op_d5_d6.h"
12 #include "video/ppu2c0x_vt.h"
13 #include "screen.h"
14 #include "speaker.h"
15 
16 class nes_vt02_vt03_soc_device : public device_t, public device_memory_interface
17 {
18 public:
19 	nes_vt02_vt03_soc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
20 
21 	void program_map(address_map &map);
22 
23 	void vt03_8000_mapper_w(offs_t offset, uint8_t data);
24 
25 	// 8-bit ports
write_0_callback()26 	auto write_0_callback() { return m_write_0_callback.bind(); }
read_0_callback()27 	auto read_0_callback() { return m_read_0_callback.bind(); }
read_1_callback()28 	auto read_1_callback() { return m_read_1_callback.bind(); }
29 
30 	// 4-bit ports
extra_read_0_callback()31 	auto extra_read_0_callback() { return m_extra_read_0_callback.bind(); }
extra_read_1_callback()32 	auto extra_read_1_callback() { return m_extra_read_1_callback.bind(); }
extra_read_2_callback()33 	auto extra_read_2_callback() { return m_extra_read_2_callback.bind(); }
extra_read_3_callback()34 	auto extra_read_3_callback() { return m_extra_read_3_callback.bind(); }
35 
extra_write_0_callback()36 	auto extra_write_0_callback() { return m_extra_write_0_callback.bind(); }
extra_write_1_callback()37 	auto extra_write_1_callback() { return m_extra_write_1_callback.bind(); }
extra_write_2_callback()38 	auto extra_write_2_callback() { return m_extra_write_2_callback.bind(); }
extra_write_3_callback()39 	auto extra_write_3_callback() { return m_extra_write_3_callback.bind(); }
40 
set_201x_descramble(uint8_t reg0,uint8_t reg1,uint8_t reg2,uint8_t reg3,uint8_t reg4,uint8_t reg5)41 	void set_201x_descramble(uint8_t reg0, uint8_t reg1, uint8_t reg2, uint8_t reg3, uint8_t reg4, uint8_t reg5)
42 	{
43 		m_2012_2017_descramble[0] = reg0; // TOOD: name regs
44 		m_2012_2017_descramble[1] = reg1;
45 		m_2012_2017_descramble[2] = reg2;
46 		m_2012_2017_descramble[3] = reg3;
47 		m_2012_2017_descramble[4] = reg4;
48 		m_2012_2017_descramble[5] = reg5;
49 	};
50 
51 	void set_8000_scramble(uint8_t reg0, uint8_t reg1, uint8_t reg2, uint8_t reg3, uint8_t reg4, uint8_t reg5, uint8_t reg6, uint8_t reg7);
52 	void set_410x_scramble(uint8_t reg0, uint8_t reg1);
force_bad_dma()53 	void force_bad_dma() { m_force_baddma = true; }
force_raster_timing_hack()54 	void force_raster_timing_hack() { m_use_raster_timing_hack = true; }
55 
set_default_palette_mode(vtxx_pal_mode pmode)56 	void set_default_palette_mode(vtxx_pal_mode pmode) { m_default_palette_mode = pmode; }
57 
58 protected:
59 	nes_vt02_vt03_soc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
60 
61 	virtual void device_start() override;
62 	virtual void device_reset() override;
63 
64 	virtual space_config_vector memory_space_config() const override;
65 	virtual void device_add_mconfig(machine_config &config) override;
66 
67 	required_device<cpu_device> m_maincpu;
68 	required_device<screen_device> m_screen;
69 	required_device<ppu_vt03_device> m_ppu;
70 	required_device<nes_apu_vt_device> m_apu;
71 
72 	void nes_vt_map(address_map& map);
73 
74 	uint32_t get_banks(uint8_t bnk);
75 	void update_banks();
76 	uint16_t decode_nt_addr(uint16_t addr);
77 	void vt03_410x_w(offs_t offset, uint8_t data);
78 	uint8_t vt03_410x_r(offs_t offset);
79 	void scrambled_410x_w(uint16_t offset, uint8_t data);
80 	uint8_t spr_r(offs_t offset);
81 	uint8_t chr_r(offs_t offset);
82 	void chr_w(offs_t offset, uint8_t data);
83 	void scanline_irq(int scanline, int vblank, int blanked);
84 	void hblank_irq(int scanline, int vblank, int blanked);
85 	void video_irq(bool hblank, int scanline, int vblank, int blanked);
86 	uint8_t nt_r(offs_t offset);
87 	void nt_w(offs_t offset, uint8_t data);
88 	int calculate_real_video_address(int addr, int extended, int readtype);
89 	void scrambled_8000_w(uint16_t offset, uint8_t data);
90 	uint8_t psg1_4014_r();
91 	uint8_t psg1_4015_r();
92 	void psg1_4015_w(uint8_t data);
93 	void psg1_4017_w(uint8_t data);
94 	void vt_dma_w(uint8_t data);
95 	void do_dma(uint8_t data, bool has_ntsc_bug);
96 	void vt03_4034_w(uint8_t data);
97 
98 	uint8_t in0_r();
99 	uint8_t in1_r();
100 	void in0_w(offs_t offset, uint8_t data);
101 
102 	void extra_io_control_w(uint8_t data);
103 	uint8_t extrain_01_r();
104 	uint8_t extrain_23_r();
105 	void extraout_01_w(uint8_t data);
106 	void extraout_23_w(uint8_t data);
107 	uint8_t rs232flags_region_r();
108 
109 	uint32_t screen_update(screen_device& screen, bitmap_rgb32& bitmap, const rectangle& cliprect);
110 
111 	uint8_t m_410x[0xc];
112 
113 	uint8_t m_vdma_ctrl;
114 	int m_timer_irq_enabled;
115 	int m_timer_running;
116 	int m_timer_val;
117 
118 	uint8_t m_8000_scramble[8];
119 	uint8_t m_410x_scramble[2];
120 
121 	uint8_t m_8000_addr_latch;
122 
123 	uint8_t m_4242;
124 	uint8_t m_411c;
125 	uint8_t m_411d;
126 
127 	uint8_t m_initial_e000_bank;
128 	/* expansion nametable - todo, see if we can refactor NES code to be reusable without having to add full NES bus etc. */
129 	std::unique_ptr<uint8_t[]> m_ntram;
130 	std::unique_ptr<uint8_t[]> m_chrram;
131 
132 	DECLARE_WRITE_LINE_MEMBER(apu_irq);
133 	uint8_t apu_read_mem(offs_t offset);
134 
135 	uint8_t external_space_read(offs_t offset);
136 	void external_space_write(offs_t offset, uint8_t data);
137 
138 	void do_pal_timings_and_ppu_replacement(machine_config& config);
139 
140 private:
141 
142 	address_space_config        m_space_config;
143 
144 	int m_bankaddr[4];
145 
146 	devcb_write8 m_write_0_callback;
147 	devcb_read8 m_read_0_callback;
148 	devcb_read8 m_read_1_callback;
149 
150 	devcb_write8 m_extra_write_0_callback;
151 	devcb_write8 m_extra_write_1_callback;
152 	devcb_write8 m_extra_write_2_callback;
153 	devcb_write8 m_extra_write_3_callback;
154 
155 	devcb_read8 m_extra_read_0_callback;
156 	devcb_read8 m_extra_read_1_callback;
157 	devcb_read8 m_extra_read_2_callback;
158 	devcb_read8 m_extra_read_3_callback;
159 
160 	uint8_t m_2012_2017_descramble[0x6]; // passed to PPU in reset
161 	vtxx_pal_mode m_default_palette_mode;
162 	bool m_force_baddma;
163 	bool m_use_raster_timing_hack;
164 };
165 
166 class nes_vt02_vt03_soc_pal_device : public nes_vt02_vt03_soc_device
167 {
168 public:
169 	nes_vt02_vt03_soc_pal_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock);
170 
171 protected:
172 	virtual void device_add_mconfig(machine_config& config) override;
173 };
174 
175 class nes_vt02_vt03_soc_scramble_device : public nes_vt02_vt03_soc_device
176 {
177 public:
178 	nes_vt02_vt03_soc_scramble_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock);
179 
180 protected:
181 	virtual void device_add_mconfig(machine_config& config) override;
182 };
183 
184 DECLARE_DEVICE_TYPE(NES_VT02_VT03_SOC, nes_vt02_vt03_soc_device)
185 DECLARE_DEVICE_TYPE(NES_VT02_VT03_SOC_PAL, nes_vt02_vt03_soc_pal_device)
186 DECLARE_DEVICE_TYPE(NES_VT02_VT03_SOC_SCRAMBLE, nes_vt02_vt03_soc_scramble_device)
187 
188 #endif // MAME_MACHINE_NES_VT_SOC_H
189