#include "../../common.h"
#include "../device.h"
-
// 0 - 9 : SCSI_CDROM::
// 100 - : SCSI_DEV::
#define SIG_TOWNS_CDROM_PLAYING 0
#define SIG_TOWNS_CDROM_RESET 0x23
#define SIG_TOWNS_CDROM_DMAINT 0x24
#define SIG_TOWNS_CDROM_DMAACK 0x25
+#define SIG_TOWNS_CDROM_DMAMASK 0x26
+
#define SIG_TOWNS_CDROM_MUTE_L 0x29
#define SIG_TOWNS_CDROM_MUTE_R 0x2a
#define SIG_TOWNS_CDROM_MUTE_ALL 0x2b
+
class SCSI_HOST;
class FIFO;
+class RINGBUFFER;
class FILEIO;
class DEBUGGER;
namespace FMTOWNS {
#pragma pack(1)
- typedef union {
+ typedef union SUBC_u {
struct {
uint8_t P:1;
uint8_t Q:1;
#pragma pack()
#pragma pack(1)
/*!
- *
- *
+ *
+ *
*/
typedef struct {
cd_data_head_t header;
#pragma pack()
#pragma pack(1)
/*!
- * @note
+ * @note
* @note 20201116 K.O
*/
typedef union cdimage_buffer_s {
CCD_PREGAP_MODE = 0x201,
CCD_PREGAP_SUBC
};
-
+
enum {
CDROM_READ_MODE1 = 1,
CDROM_READ_MODE2 = 2,
CDROM_COMMAND_SET_CDDASET = 0x81,
CDROM_COMMAND_STOP_CDDA = 0x84,
CDROM_COMMAND_PAUSE_CDDA = 0x85,
+ CDROM_COMMAND_86 = 0x86,
CDROM_COMMAND_RESUME_CDDA = 0x87,
+ CDROM_COMMAND_9F = 0x9f,
};
// STATUS[0].
TOWNS_CD_STATUS_RESUME_DONE = 0x13,
TOWNS_CD_STATUS_TOC_ADDR = 0x16,
TOWNS_CD_STATUS_TOC_DATA = 0x17,
- TOWNS_CD_STATUS_SUBQ_READ = 0x18,
- TOWNS_CD_STATUS_SUBQ_READ2 = 0x18,
- TOWNS_CD_STATUS_SUBQ_READ3 = 0x18,
+ TOWNS_CD_STATUS_SUBQ_READ1 = 0x18,
+ TOWNS_CD_STATUS_SUBQ_READ2 = 0x19,
+ TOWNS_CD_STATUS_SUBQ_READ3 = 0x19,
+ TOWNS_CD_STATUS_SUBQ_READ4 = 0x20,
TOWNS_CD_STATUS_CMD_ABEND = 0x21,
- TOWNS_CD_STATUS_DATA_READY = 0x22,
+ TOWNS_CD_STATUS_DATA_PIO = 0x21,
+ TOWNS_CD_STATUS_DATA_DMA = 0x22,
TOWNS_CD_STATUS_UNKNOWN = 0xff,
};
TOWNS_CD_ACCEPT_04H_FOR_CMD_A0H = 0x04,
TOWNS_CD_ACCEPT_08H_FOR_CMD_A0H = 0x08,
TOWNS_CD_ACCEPT_MEDIA_CHANGED = 0x09,
- TOWNS_CD_ACCEPT_WAIT = 0x0d,
+ TOWNS_CD_ACCEPT_WAIT = 0x0d,
};
-
+
// status[1] @ status[0] == 21h
// From Tsugaru Thanks to Yamakawa-San.
enum {
TOWNS_CD_PAUSE_CDDA,
TOWNS_CD_UNPAUSE_CDDA,
};
-
+
/*class TOWNS_CDROM : public SCSI_CDROM */
class TOWNS_CDROM: public DEVICE {
protected:
outputs_t outputs_drq;
- outputs_t outputs_mcuint;
+ outputs_t outputs_eot;
+ outputs_t outputs_pic;
+
+ // Note: READ interrupt status at PIC as of Tsugaru.
+
+ int pic_signal;
+ uint32_t pic_mask;
+
FILEIO* fio_img;
// FIFO* subq_buffer;
FIFO* databuffer;
// For Debugging, will remove 20200822 K.O
DEVICE* d_cpu;
DEVICE* d_dmac;
-
+
uint32_t max_fifo_length;
uint32_t fifo_length;
-
+
uint16_t cpu_id;
uint16_t machine_id;
-
- uint8_t data_reg;
+
+ pair16_t data_reg;
bool dma_transfer;
bool pio_transfer;
- bool dma_transfer_phase;
- bool pio_transfer_phase;
bool cdrom_halted;
bool status_seek;
-
+
+ uint8_t subq_bytes[12];
+ uint8_t subq_snapshot[12];
SUBC_t subq_buffer[98]; // OK?
+
int subq_bitptr;
int subq_bitwidth;
bool subq_overrun;
- bool is_playing;
-
+
int stat_track;
bool is_cue;
int physical_size;
int logical_size;
} toc_table[108];
- _TCHAR track_data_path[100][_MAX_PATH];
+ _TCHAR track_data_path[101][_MAX_PATH];
_TCHAR img_file_path_bak[_MAX_PATH];
- bool with_filename[100];
+ bool with_filename[101];
uint32_t cdda_start_frame;
uint32_t cdda_end_frame;
int cdda_repeat_count;
bool cdda_interrupt;
int cdda_buffer_ptr;
-
+
int mix_loop_num;
int current_track;
int read_sector;
int next_seek_lba;
int read_mode;
-
- uint8_t prev_command;
- uint8_t latest_command;
- uint8_t reserved_command;
+
bool req_status;
+
bool stat_reply_intr;
+ bool dma_transfer_phase;
+ bool pio_transfer_phase;
bool mcu_ready;
+ bool has_status;
+ bool dmac_running;
+
+
+ bool command_execute_phase;
bool mcu_intr;
bool dma_intr;
bool mcu_intr_mask;
bool dma_intr_mask;
-
- bool mcuint_val;
-
+
+ int event_execute;
int event_drq;
int event_seek;
int event_next_sector;
- int event_seek_completed;
int event_cdda;
int event_cdda_delay_play;
int event_cdda_delay_stop;
int event_delay_command;
int event_time_out;
int event_eot;
-
+
int cdda_sample_l;
int cdda_sample_r;
-
+
int _decibel_l;
int _decibel_r;
int volume_l;
bool mute_left;
bool mute_right;
-
+
uint8_t w_regs[16];
static const uint16_t crc_table[256];
- int param_ptr;
- bool command_entered;
- bool param_filled;
- uint8_t param_pre_queue[8];
- uint8_t param_queue[8];
+ uint8_t reserved_command;
+ RINGBUFFER* param_queue;
+ uint8_t prev_command;
+ uint8_t prev_params[8];
+
+ uint8_t latest_command;
+ uint8_t exec_params[8];
bool command_received;
-
+
double seek_time;
int track_num;
uint32_t max_logical_block;
int bytes_per_sec;
bool access;
bool media_changed;
+ bool media_ejected;
bool cdda_stopped;
uint32_t read_lba;
bool cdrom_prefetch;
-
+
int extra_status;
void play_cdda_from_cmd();
void unpause_cdda_from_cmd();
bool is_device_ready();
void reset_device();
+
virtual void read_a_cdda_sample();
void send_mcu_ready();
virtual void set_extra_status();
- void set_status(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3);
- void set_status_read_done(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3);
- void set_status_cddareply(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3);
- void set_status_immediate(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3);
- virtual void set_status_extra(uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3);
- void set_status_extra_toc_addr(uint8_t s1, uint8_t s2, uint8_t s3);
- void set_status_extra_toc_data(uint8_t s1, uint8_t s2, uint8_t s3);
+ void __FASTCALL clear_status_queue(const bool is_clear_extra);
+ void __FASTCALL push_status_queue(uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3);
+
virtual int __FASTCALL check_cdda_track_boundary(uint32_t frame_no);
virtual bool seek_relative_frame_in_image(uint32_t frame_no);
virtual int prefetch_audio_sectors(int sectors);
virtual int __FASTCALL dequeue_audio_data(pair16_t& left, pair16_t& right);
-
+
virtual void read_cdrom();
- virtual int read_sectors_image(int sectors, uint32_t& transferred_bytes);
+ virtual int read_sectors_image(int sectors, uint32_t& transferred_bytes);
- bool check_notready_and_changed(bool force_int);
-
virtual void execute_command(uint8_t command);
-
- bool __FASTCALL status_not_ready(bool forceint);
- bool __FASTCALL status_media_changed(bool forceint);
- bool __FASTCALL status_media_changed_or_not_ready(bool forceint);
-
- void __FASTCALL status_hardware_error(bool forceint);
- void __FASTCALL status_parameter_error(bool forceint);
- void __FASTCALL status_read_done(bool forceint);
- void __FASTCALL status_data_ready(bool forceint);
-
- void __FASTCALL status_accept(int extra, uint8_t s2, uint8_t s3);
- void __FASTCALL status_not_accept(int extra, uint8_t s1, uint8_t s2, uint8_t s3);
-
+
+ bool __FASTCALL status_not_ready(const bool force_interrupt);
+ bool __FASTCALL status_media_changed(const bool force_interrupt);
+ bool __FASTCALL status_media_changed_or_not_ready(const bool force_interrupt);
+
+ void __FASTCALL status_hardware_error(const bool force_interrupt);
+ void __FASTCALL status_parameter_error(const bool force_interrupt);
+ void __FASTCALL status_time_out(const bool force_interrupt);
+
+ void __FASTCALL status_read_done(const bool force_interrupt);
+ void __FASTCALL status_data_ready(const bool force_interrupt);
+
+ void __FASTCALL status_accept(int extra, uint8_t s2, uint8_t s3, bool immediate_interrupt, const bool force_interrupt);
+ void set_status(const bool push_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3, const bool force_interrupt);
+ void set_status_read_done(bool push_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3);
+ void set_status_cddareply(const bool force_interrupt, int extra, uint8_t s2, uint8_t s3);
+ void __FASTCALL set_status_immediate(const bool push_status, const bool force_interrupt, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3);
+
+ virtual void set_extra_status_values(uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3, const bool is_immediate, const bool force_interrupt);
+ void __FASTCALL set_status_extra_toc_addr(uint8_t s1, uint8_t s2, uint8_t s3);
+ void __FASTCALL set_status_extra_toc_data(uint8_t s1, uint8_t s2, uint8_t s3);
+
+ virtual void __FASTCALL status_accept2(const bool force_interrupt, int extra, uint8_t s2, uint8_t s3);
+ virtual void __FASTCALL status_accept3(int extra, uint8_t s2, uint8_t s3);
+
+ void __FASTCALL status_not_accept(int extra, uint8_t s1, uint8_t s2, uint8_t s3, bool immediate_interrupt, const bool force_interrupt);
+
void __FASTCALL status_illegal_lba(int extra, uint8_t s1, uint8_t s2, uint8_t s3);
- void set_delay_ready();
- void set_delay_ready_nostatus();
- void set_delay_ready_eot();
- void set_delay_ready_cddareply();
-
+ void set_delay_ready(const bool force_interrupt);
+ void set_delay_ready_eot(const bool force_interrupt);
+
uint32_t cdrom_get_adr(int trk);
void __FASTCALL set_dma_intr(bool val);
* @param dma interrupt value to set.
* @param use_mask true when masking mcu and dma.
*/
- void __FASTCALL set_intrs_force(bool mcu, bool dma, bool use_mask = false);
-
void __FASTCALL make_bitslice_subc_q(uint8_t *data, int bitwidth);
uint16_t __FASTCALL calc_subc_crc16(uint8_t *databuf, int bytes, uint16_t initval);
virtual bool open_iso_file(const _TCHAR* file_path);
virtual bool open_ccd_file(const _TCHAR* file_path, _TCHAR* img_file_path);
-
+
virtual uint8_t read_subq();
virtual uint8_t get_subq_status();
- virtual void set_subq(void);
-
+ virtual void set_subq(uint32_t lba);
+ virtual bool start_to_play_cdda();
+
virtual int get_track_noop(uint32_t lba);
virtual void get_track_by_track_num(int track);
virtual uint32_t get_image_cur_position();
virtual void open_from_cmd(const _TCHAR* file_path);
virtual void close_from_cmd();
- virtual void do_dma_eot(bool by_signal);
+ virtual void dma_transfer_epilogue();
+ virtual void pio_transfer_epilogue();
- void __FASTCALL write_mcuint_signals(uint32_t val)
+ void start_time_out();
+ void stop_time_out();
+ virtual void start_drq(const double usec);
+ virtual void stop_drq();
+ void do_drq();
+
+ inline void __FASTCALL write_mcuint_signals(const bool val)
{
- mcuint_val = (val != 0) ? true : false;
- write_signals(&outputs_mcuint, val);
+ write_signals(&outputs_pic, (val) ? 0xffffffff : 0x00000000);
}
void cdrom_debug_log(const char *fmt, ...);
virtual const _TCHAR* __FASTCALL get_cdda_status_name(int _status);
virtual const _TCHAR* __FASTCALL get_command_name_from_command(uint8_t cmd);
+ inline void fetch_datareg_8()
+ {
+ data_reg.b.h = data_reg.b.l;
+ data_reg.b.l = (uint8_t)(databuffer->read() & 0xff);
+ }
+ inline void fetch_datareg_16()
+ {
+ data_reg.b.l = (uint8_t)(databuffer->read() & 0xff);
+ data_reg.b.h = (uint8_t)(databuffer->read() & 0xff);
+ }
bool __CDROM_DEBUG_LOG;
bool _USE_CDROM_PREFETCH;
bool force_logging;
access = false;
databuffer = NULL;
status_queue = NULL;
+ param_queue = NULL;
_decibel_l = 0;
_decibel_r = 0;
-
+
memset(subq_buffer, 0x00, sizeof(subq_buffer));
-
+
initialize_output_signals(&outputs_drq);
- initialize_output_signals(&outputs_mcuint);
+ initialize_output_signals(&outputs_eot);
+ initialize_output_signals(&outputs_pic);
+
set_device_name(_T("FM-Towns CD-ROM drive"));
d_dmac = NULL;
// For Debugging, will remove 20200822 K.O
d_cpu = NULL;
}
~TOWNS_CDROM() { }
- virtual void initialize();
- virtual void release();
-
- virtual void reset();
- virtual uint32_t __FASTCALL read_io8(uint32_t addr);
- virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data);
- virtual uint32_t __FASTCALL read_dma_io8(uint32_t addr);
- virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data);
-
- virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask);
- virtual uint32_t __FASTCALL read_signal(int id);
-
- virtual void __FASTCALL event_callback(int event_id, int err);
- virtual void __FASTCALL mix(int32_t* buffer, int cnt);
-
- virtual bool process_state(FILEIO* state_fio, bool loading);
+ virtual void initialize() override;
+ virtual void release() override;
+
+ virtual void reset() override;
+ virtual uint32_t __FASTCALL read_io8(uint32_t addr) override;
+ virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data) override;
+ virtual uint32_t __FASTCALL read_io16(uint32_t addr) override;
+ /*
+ virtual void __FASTCALL write_io16(uint32_t addr, uint32_t data) override;
+ */
+ virtual uint32_t __FASTCALL read_dma_io8w(uint32_t addr, int *wait) override;
+ virtual void __FASTCALL write_dma_io8w(uint32_t addr, uint32_t data, int *wait) override;
+
+ virtual uint32_t __FASTCALL read_dma_io16w(uint32_t addr, int *wait) override;
+ virtual void __FASTCALL write_dma_io16w(uint32_t addr, uint32_t data, int *wait) override;
+
+ virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask) override;
+ virtual uint32_t __FASTCALL read_signal(int id) override;
+
+ virtual void __FASTCALL event_callback(int event_id, int err) override;
+ virtual void __FASTCALL mix(int32_t* buffer, int cnt) override;
+
+ virtual bool process_state(FILEIO* state_fio, bool loading) override;
virtual bool mounted();
virtual bool accessed();
virtual void close();
// for debug
- virtual void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data);
- virtual uint32_t __FASTCALL read_debug_data8(uint32_t addr);
- virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
- virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data);
- bool is_debugger_available()
+ virtual void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data) override;
+ virtual uint32_t __FASTCALL read_debug_data8(uint32_t addr) override;
+ virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) override;
+ virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data) override;
+ bool is_debugger_available() override
{
return true;
}
- uint64_t get_debug_data_addr_space()
+ uint64_t get_debug_data_addr_space() override
{
return 0x1fff; // Will change
}
-
-
- virtual void set_volume(int ch, int decibel_l, int decibel_r);
- virtual void get_volume(int ch, int& decibel_l, int& decibel_r);
+ virtual void set_volume(int ch, int decibel_l, int decibel_r) override;
+ virtual void get_volume(int ch, int& decibel_l, int& decibel_r) override;
virtual bool read_buffer(int sectors);
// unique functions
{
cpu_id = val & 0x07;
}
-
+
void set_context_mpuint_line(DEVICE* dev, int id, uint32_t mask)
{
- register_output_signal(&outputs_mcuint, dev, id, mask);
+ if(dev != NULL) {
+ register_output_signal(&outputs_pic, dev, id, mask);
+ }
}
void set_context_drq_line(DEVICE* dev, int id, uint32_t mask)
{
register_output_signal(&outputs_drq, dev, id, mask);
}
+ void set_context_eot_line(DEVICE* dev, int id, uint32_t mask)
+ {
+ register_output_signal(&outputs_eot, dev, id, mask);
+ }
void set_context_dmac(DEVICE* d)
{
d_dmac = d;
}
};
-
+
}