summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/psxcd.h
blob: b8146a3bc42b0742fcea96d3fcea1795e3f9b6af (plain) (tree)
1
2
3
4
5
6
7
8
9
                       
                                                  



                            

                            
                      
 
 
                                              

       







                                                                                                               
                                                                                                      
 
                                
                                                           
                                                       
                                            
 

                                                
                                                        

          



                                                                                                       
                                                                         
 
        

                                                       
                                         

                                              

                             
                                          

                                     
                     

                             
          


















                               








                             



                               
 
                                         
                                     

                                               

                                                                                                                         


                          

                           
                           

                                                                        
 



                                                                                                       
 

                                                                                                              
 

                                                                              
                


                                            
                                           

                
                                    
                        
                                               

                      
 

















                                        
                              
                                                                                           
 

                               
                                              

                                            
                                       

                                              

  
                         
                                        
 
                              
// license:BSD-3-Clause
// copyright-holders:smf,R. Belmont,pSXAuthor,Carl
#ifndef MAME_MACHINE_PSXCD_H
#define MAME_MACHINE_PSXCD_H

#pragma once

#include "imagedev/chd_cd.h"
#include "sound/spu.h"


class psxcd_device : public cdrom_image_device
{
public:
	template <typename T, typename U>
	psxcd_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&spu_tag)
		: psxcd_device(mconfig, tag, owner, (uint32_t)0)
	{
		m_maincpu.set_tag(std::forward<T>(cpu_tag));
		m_spu.set_tag(std::forward<U>(spu_tag));
	}

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

	// configuration helpers
	auto irq_handler() { return m_irq_handler.bind(); }
	virtual image_init_result call_load() override;
	virtual void call_unload() override;

	void write(offs_t offset, uint8_t data);
	uint8_t read(offs_t offset);
	void start_dma(uint8_t *mainram, uint32_t size);

protected:
	virtual void device_start() override;
	virtual void device_stop() override;
	virtual void device_reset() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
	virtual const tiny_rom_entry *device_rom_region() const override;

private:
	static constexpr unsigned MAX_PSXCD_TIMERS = 4;

	void write_command(uint8_t byte);

	typedef void (psxcd_device::*cdcmd)();
	struct command_result
	{
		uint8_t data[32], sz, res;
		command_result *next;
	};
	union CDPOS {
		uint8_t b[4];
		uint32_t w;
	};

	void cdcmd_sync();
	void cdcmd_nop();
	void cdcmd_setloc();
	void cdcmd_play();
	void cdcmd_forward();
	void cdcmd_backward();
	void cdcmd_readn();
	void cdcmd_standby();
	void cdcmd_stop();
	void cdcmd_pause();
	void cdcmd_init();
	void cdcmd_mute();
	void cdcmd_demute();
	void cdcmd_setfilter();
	void cdcmd_setmode();
	void cdcmd_getparam();
	void cdcmd_getlocl();
	void cdcmd_getlocp();
	void cdcmd_gettn();
	void cdcmd_gettd();
	void cdcmd_seekl();
	void cdcmd_seekp();
	void cdcmd_test();
	void cdcmd_id();
	void cdcmd_reads();
	void cdcmd_reset();
	void cdcmd_readtoc();
	void cdcmd_unknown12();
	void cdcmd_illegal17();
	void cdcmd_illegal18();
	void cdcmd_illegal1d();

	static const cdcmd cmd_table[31];
	void illegalcmd(uint8_t cmd);

	void cmd_complete(command_result *res);
	void send_result(uint8_t res, uint8_t *data=nullptr, int sz=0, int delay=default_irq_delay, uint8_t errcode = 0);
	command_result *prepare_result(uint8_t res, uint8_t *data=nullptr, int sz=0, uint8_t errcode = 0);

	void start_read();
	void start_play();
	void stop_read();
	void read_sector();
	void play_sector();
	uint32_t sub_loc(CDPOS src1, CDPOS src2);
	int add_system_event(int type, uint64_t t, command_result *ptr);

	uint8_t bcd_to_decimal(const uint8_t bcd) { return ((bcd>>4)*10)+(bcd&0xf); }
	uint8_t decimal_to_bcd(const uint8_t dec) { return ((dec/10)<<4)|(dec%10); }
	uint32_t msf_to_lba_ps(uint32_t msf) { msf = msf_to_lba(msf); return (msf>150)?(msf-150):msf; }
	uint32_t lba_to_msf_ps(uint32_t lba) { return lba_to_msf_alt(lba+150); }

	static const unsigned int sector_buffer_size=16, default_irq_delay=16000;   //480;  //8000; //2000<<2;
	static const unsigned int raw_sector_size=2352;

	uint8_t cmdbuf[64], mode, secbuf[sector_buffer_size][raw_sector_size];
	uint8_t filter_file, filter_channel, lastsechdr[8], status;
	int rdp;
	uint8_t m_cursec, sectail;
	uint16_t m_transcurr;
	uint8_t m_transbuf[raw_sector_size];
	command_result *res_queue, *m_int1;

	struct {
		uint8_t sr, ir, imr;
		struct {
			uint8_t ll, lr, rl, rr;
		} vol;
	} m_regs;

	CDPOS loc, curpos;

#ifdef LSB_FIRST
	enum {
		M = 2,
		S = 1,
		F = 0
	};
#else
	enum {
		M = 1,
		S = 2,
		F = 3
	};
#endif

	bool open, m_mute, m_dmaload;
	device_timer_id next_read_event;
	int64_t next_sector_t;
	unsigned int autopause_sector, start_read_delay, read_sector_cycles, preread_delay;

	uint32_t m_param_count;
	uint32_t m_sysclock;
	emu_timer *m_timers[MAX_PSXCD_TIMERS];
	bool m_timerinuse[MAX_PSXCD_TIMERS];

	devcb_write_line m_irq_handler;
	required_device<cpu_device> m_maincpu;
	required_device<spu_device> m_spu;
};

// device type definition
DECLARE_DEVICE_TYPE(PSXCD, psxcd_device)

#endif // MAME_MACHINE_PSXCD_H