summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/segacdblock.h
blob: 5b0c260ad7e1d444088f197a8b16b8b2cbfff088 (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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
// license:LGPL-2.1+
// copyright-holders:Angelo Salese, R. Belmont
/***************************************************************************

Sega Saturn CD-Block HLE device implementation

***************************************************************************/
#include "cdrom.h"

#pragma once

#ifndef __SEGACDBLOCKDEV_H__
#define __SEGACDBLOCKDEV_H__

#define MAX_BLOCKS  (200)
#define MAX_FILTERS (24)
#define MAX_DIR_SIZE    (256*1024)

//**************************************************************************
//  INTERFACE CONFIGURATION MACROS
//**************************************************************************

#define MCFG_SEGACDBLOCK_ADD(_tag,_freq) \
	MCFG_DEVICE_ADD(_tag, SEGACDBLOCK, _freq)

//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// ======================> segacdblock_device

class segacdblock_device : public device_t,
						   public device_memory_interface
{
public:
	// construction/destruction
	segacdblock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);

	// I/O operations
	DECLARE_WRITE32_MEMBER( write );
	DECLARE_READ32_MEMBER( read );

	DECLARE_READ16_MEMBER( cr0_r );
	DECLARE_READ16_MEMBER( cr1_r );
	DECLARE_READ16_MEMBER( cr2_r );
	DECLARE_READ16_MEMBER( cr3_r );

	DECLARE_WRITE16_MEMBER( cr0_w );
	DECLARE_WRITE16_MEMBER( cr1_w );
	DECLARE_WRITE16_MEMBER( cr2_w );
	DECLARE_WRITE16_MEMBER( cr3_w );

	DECLARE_READ16_MEMBER( hirq_r );
	DECLARE_WRITE16_MEMBER( hirq_w );

	DECLARE_READ16_MEMBER( hirq_mask_r );
	DECLARE_WRITE16_MEMBER( hirq_mask_w );

	DECLARE_READ16_MEMBER( datatrns_r );
	DECLARE_READ32_MEMBER( datatrns32_r );
	
protected:
	// device-level overrides
	virtual void device_validity_check(validity_checker &valid) const;
	virtual void device_start();
	virtual void device_reset();
	virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
	virtual machine_config_constructor device_mconfig_additions() const;

	address_space_config        m_space_config;
	address_space *m_space;

private:
	static const device_timer_id PERI_TIMER = 0;
	static const device_timer_id CMD_TIMER = 1;
	static const device_timer_id CD_TIMER = 2;

	UINT16 m_cr[4];
	UINT16 m_dr[4];
	UINT16 m_hirq_mask;
	UINT16 m_hirq;
	UINT32 m_FAD;
	UINT32 m_FADEnd;
	UINT16 m_cd_state;
	UINT8 m_cmd_issued;
	bool m_sh1_inited;
	bool m_isDiscInTray;
	//bool m_TOCPhase;
	bool m_TransferActive;
	UINT32 m_DiscLeadOut;

	cdrom_file *cdrom;

	struct direntryT
	{
		UINT8 record_size;
		UINT8 xa_record_size;
		UINT32 firstfad;        // first sector of file
		UINT32 length;      // length of file
		UINT8 year;
		UINT8 month;
		UINT8 day;
		UINT8 hour;
		UINT8 minute;
		UINT8 second;
		UINT8 gmt_offset;
		UINT8 flags;        // iso9660 flags
		UINT8 file_unit_size;
		UINT8 interleave_gap_size;
		UINT16 volume_sequencer_number;
		UINT8 name[128];
	};

	
	enum transT
	{
		CDDMA_STOPPED,
		CDDMA_INPROGRESS
		/*XFERTYPE_TOC,
		XFERTYPE_FILEINFO_1,
		XFERTYPE_FILEINFO_254,
		XFERTYPE_SUBQ,
		XFERTYPE_SUBRW*/
	};
	
	enum sourceT
	{
		SOURCE_NONE,
		SOURCE_TOC,
		SOURCE_DATA,
		SOURCE_AUDIO
	};

	struct blockT
	{
		INT32 size; // size of block
		INT32 FAD;  // FAD on disc
		UINT8 data[CD_MAX_SECTOR_DATA];
		UINT8 chan; // channel
		UINT8 fnum; // file number
		UINT8 subm; // subchannel mode
		UINT8 cinf; // coding information
	};

	struct partitionT
	{
		INT32 size;
		blockT *blocks[MAX_BLOCKS];
		UINT8 bnum[MAX_BLOCKS];
		UINT8 numblks;
	};
	
	transT xfertype;
	sourceT sourcetype;
	UINT32 m_dma_src,m_dma_size;

	struct filterT
	{
		UINT8 mode;
		UINT8 chan;
		UINT8 smmask;
		UINT8 cimask;
		UINT8 fid;
		UINT8 smval;
		UINT8 cival;
		UINT8 condtrue;
		UINT8 condfalse;
		UINT32 fad;
		UINT32 range;
	};
	


	filterT CDFilters[MAX_FILTERS];
	filterT *CDDeviceConnection;
	partitionT partitions[MAX_FILTERS];
	partitionT *transpart;
	blockT blocks[MAX_BLOCKS];
	blockT curblock;
	partitionT *cd_read_filtered_sector(INT32 fad, UINT8 *p_ok);
	partitionT *cd_filterdata(filterT *flt, int trktype, UINT8 *p_ok);

	void dma_setup();

	UINT8 tocbuf[102*4]; /**< @todo Subchannel Q of lead-in */
	UINT8 finfbuf[256];
	UINT8 *m_DMABuffer;
	UINT8 m_LastBuffer;
	void TOCRetrieve();

	void cd_standard_return(bool isPeri);
	blockT *cd_alloc_block(UINT8 *blknum);
	void cd_free_block(blockT *blktofree);
	int freeblocks;

	// 0x00
	void cd_cmd_status();
	void cd_cmd_get_hw_info();
	void cd_cmd_get_toc();
	void cd_cmd_get_session_info(UINT8 param);
	void cd_cmd_init(UINT8 init_flags);
	void cd_cmd_end_transfer();

	// 0x10
	void cd_cmd_play_disc();
	
	// 0x30
	void cd_cmd_set_device_connection(UINT8 param);
	// 0x40
	void cd_cmd_set_filter_range(UINT8 filter_number);
	void cd_cmd_set_filter_mode(UINT8 mode, UINT8 filter_number);
	void cd_cmd_set_filter_subheader_conditions();
	void cd_cmd_set_filter_connection(UINT8 filter_number);
	void cd_cmd_reset_selector(UINT8 reset_flags, UINT8 buffer_number);
	
	// 0x50
	void cd_cmd_get_buffer_size();
	void cd_cmd_get_sector_number(UINT8 buffer_number);
	void cd_cmd_calculate_actual_size();
	void cd_cmd_get_sector_info(UINT8 sector_offset, UINT8 buffer_number);
	void cd_cmd_get_actual_size();
	
	// 0x60
	void cd_cmd_set_sector_length(UINT8 length_in, UINT8 length_out);
	void cd_cmd_get_sector(bool AutoDelete);
	void cd_cmd_delete_sector();
//	void cd_cmd_get_then_delete_sector();
	void cd_cmd_get_copy_error();

	// 0x70
	void cd_cmd_change_dir(UINT32 dir_entry);
	void cd_cmd_read_directory(UINT8 filter_number);
	void cd_cmd_get_file_system_scope();
	void cd_cmd_get_file_info(UINT32 fileid);
	void cd_cmd_read_file();
	void cd_cmd_abort();

	// 0xe0
	void cd_cmd_auth_device(UINT16 AuthType);
	void cd_cmd_device_auth_status(UINT16 AuthType);
	void SH2SendsCommand();
	void SH1CommandExecute();

	void set_flag(UINT16 which);
	void clear_flag(UINT16 which);
	//emu_timer *m_sh1_timer;
	emu_timer *m_peri_timer;
	emu_timer *m_cmd_timer;
	emu_timer *m_cd_timer;
	UINT16 read_cd_state();
	void write_cd_state(UINT16 which);
	void write_fad();
	int m_SectorLengthIn;
	int m_SectorLengthOut;
	void read_new_dir(UINT32 fileno);
	void make_dir_current(UINT32 fad);
	void cd_readblock(UINT32 fad, UINT8 *dat);
	direntryT curroot;       // root entry of current filesystem
	std::vector<direntryT> curdir;       // current directory
	int numfiles;            // # of entries in current directory
	int firstfile;           // first non-directory file
	void cd_getsectoroffsetnum(UINT32 bufnum, UINT32 *sectoffs, UINT32 *sectnum);
	UINT32 xferoffs, xfersect, xfersectpos, xfersectnum, xferdnum;
	bool DeleteSectorMode;
	void cd_defragblocks(partitionT *part);
	bool m_playtype;
	sega_cdrom_get_adr_control(cdrom_file *file, int track);
	int m_CurrentTrack;
	int m_CalculateActualSize;
	bool m_TempPause;
	//bool m_BufferFull;
};


// device type definition
extern const device_type SEGACDBLOCK;



//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************



#endif