OSDN Git Service

[VM][FMTOWNS][CDROM] CDROM checks DMAC's mask as running DMAC CH.3.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / cdrom.h
index c2409d9..d50711b 100644 (file)
@@ -11,7 +11,6 @@
 #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;
@@ -89,8 +92,8 @@ namespace FMTOWNS {
 #pragma pack()
 #pragma pack(1)
        /*!
-        * 
-        * 
+        *
+        *
         */
        typedef struct {
                cd_data_head_t header;
@@ -113,7 +116,7 @@ namespace FMTOWNS {
 #pragma pack()
 #pragma pack(1)
        /*!
-        * @note 
+        * @note
         * @note 20201116 K.O
         */
        typedef union cdimage_buffer_s {
@@ -160,7 +163,7 @@ enum {
        CCD_PREGAP_MODE = 0x201,
        CCD_PREGAP_SUBC
 };
-       
+
 enum {
        CDROM_READ_MODE1 = 1,
        CDROM_READ_MODE2 = 2,
@@ -181,7 +184,9 @@ enum {
        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].
@@ -200,11 +205,13 @@ enum {
        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,
 };
 
@@ -222,9 +229,9 @@ enum {
        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 {
@@ -252,12 +259,19 @@ 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;
@@ -266,28 +280,28 @@ protected:
        // 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;
@@ -301,9 +315,9 @@ protected:
                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;
@@ -313,7 +327,7 @@ protected:
        int cdda_repeat_count;
        bool cdda_interrupt;
        int cdda_buffer_ptr;
-       
+
        int mix_loop_num;
        int current_track;
        int read_sector;
@@ -322,25 +336,28 @@ protected:
 
        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;
@@ -350,10 +367,10 @@ protected:
        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;
@@ -361,29 +378,32 @@ protected:
 
        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();
@@ -392,48 +412,55 @@ protected:
 
        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);
@@ -444,8 +471,6 @@ protected:
         * @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);
 
@@ -456,11 +481,12 @@ protected:
 
        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();
@@ -473,17 +499,33 @@ protected:
 
        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;
@@ -497,35 +539,45 @@ public:
                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();
@@ -533,22 +585,20 @@ public:
        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
@@ -626,15 +676,21 @@ public:
        {
                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;
@@ -646,5 +702,5 @@ public:
        }
 };
 
-       
+
 }