summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/naomigd.h
blob: 8ee20e62c99e2afb29d3d0657d641354336fe7e5 (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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
#ifndef MAME_MACHINE_NAOMIGD_H
#define MAME_MACHINE_NAOMIGD_H

#pragma once

#include "machine/naomibd.h"
#include "cpu/pic16c62x/pic16c62x.h"
#include "machine/i2cmem.h"
#include "machine/eepromser.h"
#include "machine/315-6154.h"
#include "machine/idectrl.h"
#include "machine/gdrom.h"

// For ide gdrom controller

class idegdrom_device : public pci_device {
public:
	idegdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const char *image_tag, const char *space_tag, int space_id);
	idegdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	auto irq_callback() { return irq_cb.bind(); }

	virtual void device_add_mconfig(machine_config &config) override;

	void map_command(address_map &map);
	void map_control(address_map &map);
	void map_dma(address_map &map);

	uint32_t ide_cs0_r(offs_t offset, uint32_t mem_mask = ~0);
	uint32_t ide_cs1_r(offs_t offset, uint32_t mem_mask = ~0);
	void ide_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	void ide_cs1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
	DECLARE_WRITE_LINE_MEMBER(ide_irq);

protected:
	virtual void device_start() override;
	virtual void device_reset() override;

	virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
		uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;

private:
	required_device<bus_master_ide_controller_device> m_ide;
	devcb_write_line irq_cb;
	const char *space_owner_tag;
	int space_owner_id;
};

DECLARE_DEVICE_TYPE(IDE_GDROM, idegdrom_device)

class naomi_gdrom_board : public naomi_board
{
public:
	template <typename T, typename U>
	naomi_gdrom_board(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&eeprom_tag, const char *_image_tag, U &&picregion_tag)
		: naomi_gdrom_board(mconfig, tag, owner, clock)
	{
		eeprom.set_tag(std::forward<T>(eeprom_tag));
		set_image_tag(_image_tag);
		picdata.set_tag(std::forward<U>(picregion_tag));
	}

	template <typename T>
	naomi_gdrom_board(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const char *_image_tag, T &&picregion_tag)
		: naomi_gdrom_board(mconfig, tag, owner, clock)
	{
		picdata.set_tag(std::forward<T>(picregion_tag));
		set_image_tag(_image_tag);
	}

	naomi_gdrom_board(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	virtual void device_add_mconfig(machine_config &config) override;
	virtual void submap(address_map &map) override;
	void sh4_map(address_map &map);
	void sh4_io_map(address_map &map);
	void pic_map(address_map &map);
	void pci_map(address_map &map);
	void pci_config_map(address_map &map);

	void set_image_tag(const char *_image_tag)
	{
		image_tag = _image_tag;
	}

	uint8_t *memory(uint32_t &size) { size = dimm_data_size; return dimm_data.get(); }

	virtual const tiny_rom_entry *device_rom_region() const override;

	void dimm_command_w(uint16_t data);     // 5f703c
	uint16_t dimm_command_r();
	void dimm_offsetl_w(uint16_t data);     // 5f7040
	uint16_t dimm_offsetl_r();
	void dimm_parameterl_w(uint16_t data);  // 5f7044
	uint16_t dimm_parameterl_r();
	void dimm_parameterh_w(uint16_t data);  // 5f7048
	uint16_t dimm_parameterh_r();
	void dimm_status_w(uint16_t data);      // 5f704c
	uint16_t dimm_status_r();

	void sh4_unknown_w(uint32_t data);      // 14000000
	uint32_t sh4_unknown_r();
	void sh4_command_w(uint32_t data);      // 14000014
	uint32_t sh4_command_r();
	void sh4_offsetl_w(uint32_t data);      // 14000018
	uint32_t sh4_offsetl_r();
	void sh4_parameterl_w(uint32_t data);   // 1400001c
	uint32_t sh4_parameterl_r();
	void sh4_parameterh_w(uint32_t data);   // 14000020
	uint32_t sh4_parameterh_r();
	void sh4_status_w(uint32_t data);       // 14000024
	uint32_t sh4_status_r();
	void sh4_control_w(uint32_t data);      // 14000028
	uint32_t sh4_control_r();
	void sh4_sdramconfig_w(uint32_t data);  // 1400002c
	uint32_t sh4_sdramconfig_r();
	void sh4_des_keyl_w(uint32_t data);     // 14000030
	uint32_t sh4_des_keyl_r();
	void sh4_des_keyh_w(uint32_t data);     // 14000034
	uint32_t sh4_des_keyh_r();
	uint64_t shared_6154_sdram_r(offs_t offset);
	void shared_6154_sdram_w(offs_t offset, uint64_t data, uint64_t mem_mask);
	uint32_t shared_sh4_sdram_r(offs_t offset);
	void shared_sh4_sdram_w(offs_t offset, uint32_t data, uint32_t mem_mask);
	uint64_t i2cmem_dimm_r();
	void i2cmem_dimm_w(uint64_t data);
	uint8_t pic_dimm_r(offs_t offset);
	void pic_dimm_w(offs_t offset, uint8_t data);

protected:
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual ioport_constructor device_input_ports() const override;

	virtual void board_setup_address(uint32_t address, bool is_dma) override;
	virtual void board_get_buffer(uint8_t *&base, uint32_t &limit) override;
	virtual void board_advance(uint32_t size) override;

private:
	enum { FILENAME_LENGTH=24 };
	int work_mode; // set it different from 0 to enable the cpus and full dimm board emulation

	required_device<sh4_device> m_maincpu;
	required_device<pic16c622_device> m_securitycpu;
	required_device<i2cmem_device> m_i2c0;
	required_device<i2cmem_device> m_i2c1;
	required_device<eeprom_serial_93cxx_device> m_eeprom;
	required_device<sega_315_6154_device> m_315_6154;
	required_device<idegdrom_device> m_idegdrom;
	required_ioport m_debug_dipswitches;
	optional_region_ptr<uint8_t> picdata;

	const char *image_tag;
	address_space *space_sh4;
	address_space *space_6154;

	uint32_t dimm_cur_address;
	uint8_t picbus;
	uint8_t picbus_pullup;
	uint8_t picbus_io[2]; // 0 for sh4, 1 for pic
	bool picbus_used;
	uint32_t dimm_command;
	uint32_t dimm_offsetl;
	uint32_t dimm_parameterl;
	uint32_t dimm_parameterh;
	uint32_t dimm_status;
	uint32_t dimm_control;
	uint32_t dimm_sdramconfig;
	uint32_t sh4_unknown;
	uint64_t dimm_des_key;

	// Note: voluntarily not saved into the state
	std::unique_ptr<uint8_t[]> dimm_des_data;
	std::unique_ptr<uint8_t[]> dimm_data;
	uint32_t dimm_data_size;

	static const uint32_t DES_LEFTSWAP[];
	static const uint32_t DES_RIGHTSWAP[];
	static const uint32_t DES_SBOX1[];
	static const uint32_t DES_SBOX2[];
	static const uint32_t DES_SBOX3[];
	static const uint32_t DES_SBOX4[];
	static const uint32_t DES_SBOX5[];
	static const uint32_t DES_SBOX6[];
	static const uint32_t DES_SBOX7[];
	static const uint32_t DES_SBOX8[];
	static const uint32_t DES_MASK_TABLE[];
	static const uint8_t DES_ROTATE_TABLE[16];

	void find_file(const char *name, const uint8_t *dir_sector, uint32_t &file_start, uint32_t &file_size);

	inline void permutate(uint32_t &a, uint32_t &b, uint32_t m, int shift);
	void des_generate_subkeys(const uint64_t key, uint32_t *subkeys);
	uint64_t des_encrypt_decrypt(bool decrypt, uint64_t src, const uint32_t *des_subkeys);
	uint64_t rev64(uint64_t src);
	uint64_t read_to_qword(const uint8_t *region);
	void write_from_qword(uint8_t *region, uint64_t qword);
};

DECLARE_DEVICE_TYPE(NAOMI_GDROM_BOARD, naomi_gdrom_board)


#endif // MAME_MACHINE_NAOMIGD_H