summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/stvcd.h
blob: 6931edec867f5babbc78d68875639f75b5a88a0c (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
// license:LGPL-2.1+
// copyright-holders:Angelo Salese, R. Belmont

#ifndef MAME_MACHINE_STVCD_H
#define MAME_MACHINE_STVCD_H

#pragma once

#include "cdrom.h"
#include "imagedev/chd_cd.h"
#include "machine/timer.h"
#include "sound/cdda.h"

class stvcd_device : public device_t
{
	static constexpr unsigned MAX_FILTERS = 24;
	static constexpr unsigned MAX_BLOCKS = 200;
	static constexpr uint32_t MAX_DIR_SIZE = 256*1024;

public:
	stvcd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	DECLARE_READ32_MEMBER(stvcd_r);
	DECLARE_WRITE32_MEMBER(stvcd_w);

	DECLARE_READ16_MEMBER(channel_volume_r);

	void set_tray_open();
	void set_tray_close();

protected:
	virtual void device_add_mconfig(machine_config &config) override;
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_stop() override;

private:
	TIMER_DEVICE_CALLBACK_MEMBER( stv_sector_cb );
	TIMER_DEVICE_CALLBACK_MEMBER( stv_sh1_sim );

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

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

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

	struct partitionT
	{
		int32_t size;
		blockT *blocks[MAX_BLOCKS];
		uint8_t bnum[MAX_BLOCKS];
		uint8_t numblks;
	};

	// 16-bit transfer types
	enum transT
	{
		XFERTYPE_INVALID,
		XFERTYPE_TOC,
		XFERTYPE_FILEINFO_1,
		XFERTYPE_FILEINFO_254,
		XFERTYPE_SUBQ,
		XFERTYPE_SUBRW
	};

	// 32-bit transfer types
	enum trans32T
	{
		XFERTYPE32_INVALID,
		XFERTYPE32_GETSECTOR,
		XFERTYPE32_GETDELETESECTOR,
		XFERTYPE32_PUTSECTOR,
		XFERTYPE32_MOVESECTOR
	};

	int get_track_index(uint32_t fad);
	int sega_cdrom_get_adr_control(cdrom_file *file, int track);
	void cr_standard_return(uint16_t cur_status);
	void mpeg_standard_return(uint16_t cur_status);
	void cd_free_block(blockT *blktofree);
	void cd_defragblocks(partitionT *part);
	void cd_getsectoroffsetnum(uint32_t bufnum, uint32_t *sectoffs, uint32_t *sectnum);

	uint16_t cd_readWord(uint32_t addr);
	void cd_writeWord(uint32_t addr, uint16_t data);
	uint32_t cd_readLong(uint32_t addr);
	void cd_writeLong(uint32_t addr, uint32_t data);

	void cd_readTOC();
	void cd_readblock(uint32_t fad, uint8_t *dat);
	void cd_playdata();

	void cd_exec_command( void );
	// iso9660 utilities
	void make_dir_current(uint32_t fad);
	void read_new_dir(uint32_t fileno);

	blockT *cd_alloc_block(uint8_t *blknum);
	partitionT *cd_filterdata(filterT *flt, int trktype, uint8_t *p_ok);
	partitionT *cd_read_filtered_sector(int32_t fad, uint8_t *p_ok);

	cdrom_file *cdrom;// = (cdrom_file *)nullptr;

	// local variables
	partitionT partitions[MAX_FILTERS];
	partitionT *transpart;

	blockT blocks[MAX_BLOCKS];
	blockT curblock;

	uint8_t tocbuf[102*4];
	uint8_t subqbuf[5*2];
	uint8_t subrwbuf[12*2];
	uint8_t finfbuf[256];

	int32_t sectlenin, sectlenout;

	uint8_t lastbuf, playtype;

	transT xfertype;
	trans32T xfertype32;
	uint32_t xfercount, calcsize;
	uint32_t xferoffs, xfersect, xfersectpos, xfersectnum, xferdnum;

	filterT filters[MAX_FILTERS];
	filterT *cddevice;
	int cddevicenum;

	uint16_t cr1, cr2, cr3, cr4;
	uint16_t prev_cr1, prev_cr2, prev_cr3, prev_cr4;
	uint8_t status_type;
	uint16_t hirqmask, hirqreg;
	uint16_t cd_stat;
	uint32_t cd_curfad;// = 0;
	uint32_t cd_fad_seek;
	uint32_t fadstoplay;// = 0;
	uint32_t in_buffer;// = 0;    // amount of data in the buffer
	int oddframe;// = 0;
	int buffull, sectorstore, freeblocks;
	int cur_track;
	uint8_t cmd_pending;
	uint8_t cd_speed;
	uint8_t cdda_maxrepeat;
	uint8_t cdda_repeat_count;
	uint8_t tray_is_closed;
	int get_timing_command( void );

	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

	required_device<cdrom_image_device> m_cdrom_image;
	required_device<timer_device> m_sector_timer;
	required_device<timer_device> m_sh1_timer;
	required_device<cdda_device> m_cdda;
};

// device type definition
DECLARE_DEVICE_TYPE(STVCD, stvcd_device)

#endif // MAME_MACHINE_STVCD_H