1 // license:BSD-3-Clause
2 // copyright-holders:Wilbert Pol
3 #ifndef MAME_MACHINE_PCE_CD_H
4 #define MAME_MACHINE_PCE_CD_H
5 
6 #pragma once
7 
8 /***************************************************************************
9  TYPE DEFINITIONS
10  ***************************************************************************/
11 
12 #include "imagedev/chd_cd.h"
13 #include "machine/nvram.h"
14 #include "sound/cdda.h"
15 #include "sound/msm5205.h"
16 
17 #define PCE_BRAM_SIZE               0x800
18 #define PCE_ADPCM_RAM_SIZE          0x10000
19 #define PCE_ACARD_RAM_SIZE          0x200000
20 #define PCE_CD_COMMAND_BUFFER_SIZE  0x100
21 
22 #define PCE_CD_IRQ_TRANSFER_READY       0x40
23 #define PCE_CD_IRQ_TRANSFER_DONE        0x20
24 #define PCE_CD_IRQ_BRAM                 0x10 /* ??? */
25 #define PCE_CD_IRQ_SAMPLE_FULL_PLAY     0x08
26 #define PCE_CD_IRQ_SAMPLE_HALF_PLAY     0x04
27 
28 #define PCE_CD_ADPCM_PLAY_FLAG      0x08
29 #define PCE_CD_ADPCM_STOP_FLAG      0x01
30 
31 #define PCE_CD_DATA_FRAMES_PER_SECOND   75
32 
33 enum {
34 	PCE_CD_CDDA_OFF = 0,
35 	PCE_CD_CDDA_PLAYING,
36 	PCE_CD_CDDA_PAUSED
37 };
38 
39 
40 
41 // ======================> pce_cd_device
42 
43 class pce_cd_device : public device_t,
44 					  public device_memory_interface
45 {
46 public:
47 	// construction/destruction
48 	pce_cd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
49 
50 	void update();
51 
52 	void late_setup();
53 
54 	void bram_w(offs_t offset, uint8_t data);
55 	void intf_w(offs_t offset, uint8_t data);
56 	void acard_w(offs_t offset, uint8_t data);
57 	uint8_t bram_r(offs_t offset);
58 	uint8_t intf_r(offs_t offset);
59 	uint8_t acard_r(offs_t offset);
60 
61 protected:
62 	// device-level overrides
63 	virtual void device_start() override;
64 	virtual void device_add_mconfig(machine_config &config) override;
65 	virtual void device_reset() override;
66 	virtual space_config_vector memory_space_config() const override;
67 
68 private:
69 	const address_space_config m_space_config;
70 
71 	uint8_t cdc_status_r();
72 	void cdc_status_w(uint8_t data);
73 	uint8_t cdc_reset_r();
74 	void cdc_reset_w(uint8_t data);
75 	uint8_t irq_mask_r();
76 	void irq_mask_w(uint8_t data);
77 	uint8_t irq_status_r();
78 	uint8_t cdc_data_r();
79 	void cdc_data_w(uint8_t data);
80 	uint8_t bram_status_r();
81 	void bram_unlock_w(uint8_t data);
82 	uint8_t cdda_data_r(offs_t offset);
83 	uint8_t cd_data_r();
84 	uint8_t adpcm_dma_control_r();
85 	void adpcm_dma_control_w(uint8_t data);
86 	uint8_t adpcm_status_r();
87 	uint8_t adpcm_data_r();
88 	void adpcm_data_w(uint8_t data);
89 	void adpcm_address_lo_w(uint8_t data);
90 	void adpcm_address_hi_w(uint8_t data);
91 	uint8_t adpcm_address_control_r();
92 	void adpcm_address_control_w(uint8_t data);
93 	void adpcm_playback_rate_w(uint8_t data);
94 	void fade_register_w(uint8_t data);
95 
96 	uint8_t m_reset_reg;
97 	uint8_t m_irq_mask;
98 	uint8_t m_irq_status;
99 	uint8_t m_cdc_status;
100 	uint8_t m_cdc_data;
101 	uint8_t m_bram_status;
102 	uint8_t m_adpcm_status;
103 	uint16_t m_adpcm_latch_address;
104 	uint8_t m_adpcm_control;
105 	uint8_t m_adpcm_dma_reg;
106 	uint8_t m_fade_reg;
107 
108 	void regs_map(address_map &map);
109 	void adpcm_stop(uint8_t irq_flag);
110 	void adpcm_play();
111 	void reply_status_byte(uint8_t status);
112 	void test_unit_ready();
113 	void read_6();
114 	void nec_set_audio_start_position();
115 	void nec_set_audio_stop_position();
116 	void nec_pause();
117 	void nec_get_subq();
118 	void nec_get_dir_info();
119 	void end_of_list();
120 	void handle_data_output();
121 	void handle_data_input();
122 	void handle_message_output();
123 	void handle_message_input();
124 	void set_irq_line(int num, int state);
125 	void set_adpcm_ram_byte(uint8_t val);
126 	uint8_t get_cd_data_byte();
127 	uint8_t get_adpcm_ram_byte();
128 
129 	TIMER_CALLBACK_MEMBER(data_timer_callback);
130 	TIMER_CALLBACK_MEMBER(cdda_fadeout_callback);
131 	TIMER_CALLBACK_MEMBER(cdda_fadein_callback);
132 	TIMER_CALLBACK_MEMBER(adpcm_fadeout_callback);
133 	TIMER_CALLBACK_MEMBER(adpcm_fadein_callback);
134 	TIMER_CALLBACK_MEMBER(clear_ack);
135 	TIMER_CALLBACK_MEMBER(adpcm_dma_timer_callback);
136 
137 	required_device<cpu_device> m_maincpu;
138 
139 	std::unique_ptr<uint8_t[]>   m_bram;
140 	std::unique_ptr<uint8_t[]>   m_adpcm_ram;
141 	int     m_bram_locked;
142 	int     m_adpcm_read_ptr;
143 	uint8_t   m_adpcm_read_buf;
144 	int     m_adpcm_write_ptr;
145 	uint8_t   m_adpcm_write_buf;
146 	int     m_adpcm_length;
147 	int     m_adpcm_clock_divider;
148 	uint32_t  m_msm_start_addr;
149 	uint32_t  m_msm_end_addr;
150 	uint32_t  m_msm_half_addr;
151 	uint8_t   m_msm_nibble;
152 	uint8_t   m_msm_idle;
153 	uint8_t   m_msm_repeat;
154 
155 	/* SCSI signals */
156 	int     m_scsi_BSY;   /* Busy. Bus in use */
157 	int     m_scsi_SEL;   /* Select. Initiator has won arbitration and has selected a target */
158 	int     m_scsi_CD;    /* Control/Data. Target is sending control (data) information */
159 	int     m_scsi_IO;    /* Input/Output. Target is sending (receiving) information */
160 	int     m_scsi_MSG;   /* Message. Target is sending or receiving a message */
161 	int     m_scsi_REQ;   /* Request. Target is requesting a data transfer */
162 	int     m_scsi_ACK;   /* Acknowledge. Initiator acknowledges that it is ready for a data transfer */
163 	int     m_scsi_ATN;   /* Attention. Initiator has a message ready for the target */
164 	int     m_scsi_RST;   /* Reset. Initiator forces all targets and any other initiators to do a warm reset */
165 	int     m_scsi_last_RST;  /* To catch setting of RST signal */
166 	int     m_cd_motor_on;
167 	int     m_selected;
168 	std::unique_ptr<uint8_t[]>  m_command_buffer;
169 	int     m_command_buffer_index;
170 	int     m_status_sent;
171 	int     m_message_after_status;
172 	int     m_message_sent;
173 	std::unique_ptr<uint8_t[]> m_data_buffer;
174 	int     m_data_buffer_size;
175 	int     m_data_buffer_index;
176 	int     m_data_transferred;
177 
178 	/* Arcade Card specific */
179 	std::unique_ptr<uint8_t[]>  m_acard_ram;
180 	uint8_t   m_acard_latch;
181 	uint8_t   m_acard_ctrl[4];
182 	uint32_t  m_acard_base_addr[4];
183 	uint16_t  m_acard_addr_offset[4];
184 	uint16_t  m_acard_addr_inc[4];
185 	uint32_t  m_acard_shift;
186 	uint8_t   m_acard_shift_reg;
187 
188 	uint32_t  m_current_frame;
189 	uint32_t  m_end_frame;
190 	uint32_t  m_last_frame;
191 	uint8_t   m_cdda_status;
192 	uint8_t   m_cdda_play_mode;
193 	std::unique_ptr<uint8_t[]>   m_subcode_buffer;
194 	uint8_t   m_end_mark;
195 
196 	required_device<msm5205_device> m_msm;
197 	required_device<cdda_device> m_cdda;
198 	required_device<nvram_device> m_nvram;
199 	required_device<cdrom_image_device> m_cdrom;
200 
201 	cdrom_file  *m_cd_file;
202 	const cdrom_toc*    m_toc;
203 	emu_timer   *m_data_timer;
204 	emu_timer   *m_adpcm_dma_timer;
205 
206 	emu_timer   *m_cdda_fadeout_timer;
207 	emu_timer   *m_cdda_fadein_timer;
208 	double  m_cdda_volume;
209 	emu_timer   *m_adpcm_fadeout_timer;
210 	emu_timer   *m_adpcm_fadein_timer;
211 	double  m_adpcm_volume;
212 
213 	DECLARE_WRITE_LINE_MEMBER(msm5205_int);
214 	void nvram_init(nvram_device &nvram, void *data, size_t size);
215 };
216 
217 
218 
219 // device type definition
220 DECLARE_DEVICE_TYPE(PCE_CD, pce_cd_device)
221 
222 #endif // MAME_MACHINE_PCE_CD_H
223