summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/psxcd.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/psxcd.h')
-rw-r--r--src/mame/machine/psxcd.h161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/mame/machine/psxcd.h b/src/mame/machine/psxcd.h
new file mode 100644
index 00000000000..3239ea8ef2c
--- /dev/null
+++ b/src/mame/machine/psxcd.h
@@ -0,0 +1,161 @@
+// license:BSD-3-Clause
+// copyright-holders:smf,R. Belmont,pSXAuthor,Carl
+#ifndef _included_psxcdrom_
+#define _included_psxcdrom_
+
+#include "imagedev/chd_cd.h"
+#include "sound/spu.h"
+
+#define MAX_PSXCD_TIMERS (4)
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_PSXCD_ADD(_tag, _devname) \
+ MCFG_DEVICE_ADD(_tag, PSXCD, 0)
+
+#define MCFG_PSXCD_IRQ_HANDLER(_devcb) \
+ devcb = &psxcd_device::set_irq_handler(*device, DEVCB_##_devcb);
+
+class psxcd_device : public cdrom_image_device
+{
+public:
+ psxcd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // static configuration helpers
+ template<class _Object> static devcb_base &set_irq_handler(device_t &device, _Object object) { return downcast<psxcd_device &>(device).m_irq_handler.set_callback(object); }
+ static void static_set_devname(device_t &device, const char *devname);
+ virtual bool call_load();
+ virtual void call_unload();
+
+ DECLARE_WRITE8_MEMBER( write );
+ DECLARE_READ8_MEMBER( read );
+ void start_dma(UINT8 *mainram, UINT32 size);
+
+protected:
+ virtual void device_start();
+ virtual void device_stop();
+ virtual void device_reset();
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+
+private:
+ void write_command(UINT8 byte);
+
+ typedef void (psxcd_device::*cdcmd)();
+ struct command_result
+ {
+ UINT8 data[32], sz, res;
+ command_result *next;
+ };
+ union CDPOS {
+ UINT8 b[4];
+ UINT32 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 cmd);
+
+ void cmd_complete(command_result *res);
+ void send_result(UINT8 res, UINT8 *data=NULL, int sz=0, int delay=default_irq_delay, UINT8 errcode = 0);
+ command_result *prepare_result(UINT8 res, UINT8 *data=NULL, int sz=0, UINT8 errcode = 0);
+
+ void start_read();
+ void start_play();
+ void stop_read();
+ void read_sector();
+ void play_sector();
+ UINT32 sub_loc(CDPOS src1, CDPOS src2);
+ int add_system_event(int type, UINT64 t, command_result *ptr);
+
+ UINT8 bcd_to_decimal(const UINT8 bcd) { return ((bcd>>4)*10)+(bcd&0xf); }
+ UINT8 decimal_to_bcd(const UINT8 dec) { return ((dec/10)<<4)|(dec%10); }
+ UINT32 msf_to_lba_ps(UINT32 msf) { msf = msf_to_lba(msf); return (msf>150)?(msf-150):msf; }
+ UINT32 lba_to_msf_ps(UINT32 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 cmdbuf[64], mode, secbuf[sector_buffer_size][raw_sector_size];
+ UINT8 filter_file, filter_channel, lastsechdr[8], status;
+ int rdp;
+ UINT8 m_cursec, sectail;
+ UINT16 m_transcurr;
+ UINT8 m_transbuf[raw_sector_size];
+ command_result *res_queue, *m_int1;
+
+ struct {
+ UINT8 sr, ir, imr;
+ struct {
+ UINT8 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 next_sector_t;
+ unsigned int autopause_sector, start_read_delay, read_sector_cycles, preread_delay;
+
+ UINT32 m_param_count;
+ UINT32 m_sysclock;
+ emu_timer *m_timers[MAX_PSXCD_TIMERS];
+ bool m_timerinuse[MAX_PSXCD_TIMERS];
+
+
+ devcb_write_line m_irq_handler;
+ cpu_device *m_maincpu;
+ spu_device *m_spu;
+};
+
+// device type definition
+extern const device_type PSXCD;
+
+#endif