-/*\r
- Skelton for retropc emulator\r
-\r
- Origin : M88\r
- Author : Takeda.Toshiya\r
- Date : 2006.09.17-\r
-\r
- [ uPD765A ]\r
-*/\r
-\r
-#ifndef _UPD765A_H_\r
-#define _UPD765A_H_\r
-\r
-#include "vm.h"\r
-#include "../emu.h"\r
-#include "device.h"\r
-\r
-#define SIG_UPD765A_RESET 0\r
-#define SIG_UPD765A_TC 1\r
-#define SIG_UPD765A_MOTOR 2\r
-#define SIG_UPD765A_MOTOR_NEG 3\r
-#define SIG_UPD765A_DRVSEL 4\r
-#define SIG_UPD765A_IRQ_MASK 5\r
-#define SIG_UPD765A_DRQ_MASK 6\r
-#define SIG_UPD765A_FREADY 7\r
-\r
-class DISK;\r
-\r
-class UPD765A : public DEVICE\r
-{\r
-private:\r
- // output signals\r
- outputs_t outputs_irq;\r
- outputs_t outputs_drq;\r
- outputs_t outputs_hdu;\r
- outputs_t outputs_index;\r
- \r
- // fdc\r
- struct {\r
- uint8 track;\r
- uint8 result;\r
- bool access;\r
- // timing\r
- int cur_position;\r
- int next_trans_position;\r
- uint32 prev_clock;\r
- } fdc[4];\r
- DISK* disk[4];\r
- \r
- uint8 hdu, hdue, id[4], eot, gpl, dtl;\r
- \r
- int phase, prevphase;\r
- uint8 status, seekstat, command;\r
- uint32 result;\r
- int step_rate_time;\r
- bool no_dma_mode, motor_on;\r
-#ifdef UPD765A_DMA_MODE\r
- bool dma_data_lost;\r
-#endif\r
- bool irq_masked, drq_masked;\r
- \r
- uint8* bufptr;\r
- uint8 buffer[0x8000];\r
- int count;\r
- int event_phase;\r
- int phase_id, drq_id, lost_id, result7_id, seek_id[4];\r
- bool force_ready;\r
- bool reset_signal;\r
- bool prev_index;\r
- \r
- // timing\r
- uint32 prev_drq_clock;\r
- \r
- int get_cur_position(int drv);\r
- double get_usec_to_exec_phase();\r
- \r
- // update status\r
- void set_irq(bool val);\r
- void set_drq(bool val);\r
- void set_hdu(uint8 val);\r
- \r
- // phase shift\r
- void shift_to_idle();\r
- void shift_to_cmd(int length);\r
- void shift_to_exec();\r
- void shift_to_read(int length);\r
- void shift_to_write(int length);\r
- void shift_to_scan(int length);\r
- void shift_to_result(int length);\r
- void shift_to_result7();\r
- void shift_to_result7_event();\r
- \r
- // command\r
- void process_cmd(int cmd);\r
- void cmd_sence_devstat();\r
- void cmd_sence_intstat();\r
- uint8 get_devstat(int drv);\r
- void cmd_seek();\r
- void cmd_recalib();\r
- void seek(int drv, int trk);\r
- void seek_event(int drv);\r
- void cmd_read_data();\r
- void cmd_write_data();\r
- void cmd_scan();\r
- void cmd_read_diagnostic();\r
- void read_data(bool deleted, bool scan);\r
- void write_data(bool deleted);\r
- void read_diagnostic();\r
- uint32 read_sector();\r
- uint32 write_sector(bool deleted);\r
- uint32 find_id();\r
- uint32 check_cond(bool write);\r
- void get_sector_params();\r
- bool id_incr();\r
- void cmd_read_id();\r
- void cmd_write_id();\r
- uint32 read_id();\r
- uint32 write_id();\r
- void cmd_specify();\r
- void cmd_invalid();\r
- \r
-public:\r
- UPD765A(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)\r
- {\r
- init_output_signals(&outputs_irq);\r
- init_output_signals(&outputs_drq);\r
- init_output_signals(&outputs_hdu);\r
- init_output_signals(&outputs_index);\r
- raise_irq_when_media_changed = false;\r
- }\r
- ~UPD765A() {}\r
- \r
- // common functions\r
- void initialize();\r
- void release();\r
- void reset();\r
- void write_io8(uint32 addr, uint32 data);\r
- uint32 read_io8(uint32 addr);\r
- void write_dma_io8(uint32 addr, uint32 data);\r
- uint32 read_dma_io8(uint32 addr);\r
- void write_signal(int id, uint32 data, uint32 mask);\r
- uint32 read_signal(int ch);\r
- void event_callback(int event_id, int err);\r
- void save_state(FILEIO* state_fio);\r
- bool load_state(FILEIO* state_fio);\r
- \r
- // unique function\r
- void set_context_irq(DEVICE* device, int id, uint32 mask)\r
- {\r
- register_output_signal(&outputs_irq, device, id, mask);\r
- }\r
- void set_context_drq(DEVICE* device, int id, uint32 mask)\r
- {\r
- register_output_signal(&outputs_drq, device, id, mask);\r
- }\r
- void set_context_hdu(DEVICE* device, int id, uint32 mask)\r
- {\r
- register_output_signal(&outputs_hdu, device, id, mask);\r
- }\r
- void set_context_index(DEVICE* device, int id, uint32 mask)\r
- {\r
- register_output_signal(&outputs_index, device, id, mask);\r
- }\r
- DISK* get_disk_handler(int drv)\r
- {\r
- return disk[drv];\r
- }\r
- void open_disk(int drv, _TCHAR path[], int offset);\r
- void close_disk(int drv);\r
- bool disk_inserted(int drv);\r
- bool disk_inserted(); // current hdu\r
- bool disk_ejected(int drv);\r
- bool disk_ejected(); // current hdu\r
- uint8 media_type(int drv);\r
- void set_drive_type(int drv, uint8 type);\r
- uint8 get_drive_type(int drv);\r
- void set_drive_rpm(int drv, int rpm);\r
- void set_drive_mfm(int drv, bool mfm);\r
- bool raise_irq_when_media_changed;\r
-};\r
-\r
-#endif\r
-\r
+/*
+ Skelton for retropc emulator
+
+ Origin : M88
+ Author : Takeda.Toshiya
+ Date : 2006.09.17-
+
+ [ uPD765A ]
+*/
+
+#ifndef _UPD765A_H_
+#define _UPD765A_H_
+
+#include "vm.h"
+#include "../emu.h"
+#include "device.h"
+
+#define SIG_UPD765A_RESET 0
+#define SIG_UPD765A_TC 1
+#define SIG_UPD765A_MOTOR 2
+#define SIG_UPD765A_MOTOR_NEG 3
+#define SIG_UPD765A_DRVSEL 4
+#define SIG_UPD765A_IRQ_MASK 5
+#define SIG_UPD765A_DRQ_MASK 6
+#define SIG_UPD765A_FREADY 7
+
+//#if defined(USE_SOUND_FILES)
+#define UPD765A_SND_TBL_MAX 256
+#ifndef SIG_SOUNDER_MUTE
+#define SIG_SOUNDER_MUTE (65536 + 0)
+#endif
+#ifndef SIG_SOUNDER_RELOAD
+#define SIG_SOUNDER_RELOAD (65536 + 32)
+#endif
+#ifndef SIG_SOUNDER_ADD
+#define SIG_SOUNDER_ADD (65536 + 64)
+#endif
+
+#define UPD765A_SND_TYPE_SEEK 0
+#define UPD765A_SND_TYPE_HEAD 1
+//#endif
+
+class DISK;
+
+class UPD765A : public DEVICE
+{
+private:
+ // output signals
+ outputs_t outputs_irq;
+ outputs_t outputs_drq;
+ outputs_t outputs_hdu;
+ outputs_t outputs_index;
+
+ // fdc
+ struct {
+ uint8_t track;
+ uint8_t result;
+ bool access;
+ // timing
+ int cur_position;
+ int next_trans_position;
+ uint32_t prev_clock;
+ } fdc[4];
+ DISK* disk[4];
+//#if defined(USE_SOUND_FILES)
+ int seek_snd_trk[4];
+ int seek_snd_id[4];
+//#endif
+ uint8_t hdu, hdue, id[4], eot, gpl, dtl;
+
+ int phase, prevphase;
+ uint8_t status, seekstat, command;
+ uint32_t result;
+ int step_rate_time;
+ bool no_dma_mode, motor_on;
+//#ifdef UPD765A_DMA_MODE
+ bool dma_data_lost;
+//#endif
+ bool irq_masked, drq_masked;
+
+ uint8_t* bufptr;
+ uint8_t buffer[0x8000];
+ int count;
+ int event_phase;
+ int phase_id, drq_id, lost_id, result7_id, seek_id[4];
+
+ bool force_ready;
+ bool reset_signal;
+ bool prev_index;
+
+ // timing
+ uint32_t prev_drq_clock;
+
+ int get_cur_position(int drv);
+ double get_usec_to_exec_phase();
+
+ // update status
+ void set_irq(bool val);
+ void set_drq(bool val);
+ void set_hdu(uint8_t val);
+
+ // phase shift
+ void shift_to_idle();
+ void shift_to_cmd(int length);
+ void shift_to_exec();
+ void shift_to_read(int length);
+ void shift_to_write(int length);
+ void shift_to_scan(int length);
+ void shift_to_result(int length);
+ void shift_to_result7();
+ void shift_to_result7_event();
+
+ // command
+ void process_cmd(int cmd);
+ void cmd_sence_devstat();
+ void cmd_sence_intstat();
+ uint8_t get_devstat(int drv);
+ void cmd_seek();
+ void cmd_recalib();
+ void seek(int drv, int trk);
+ void seek_event(int drv);
+ void cmd_read_data();
+ void cmd_write_data();
+ void cmd_scan();
+ void cmd_read_diagnostic();
+ void read_data(bool deleted, bool scan);
+ void write_data(bool deleted);
+ void read_diagnostic();
+ uint32_t read_sector();
+ uint32_t write_sector(bool deleted);
+ uint32_t find_id();
+ uint32_t check_cond(bool write);
+ void get_sector_params();
+ bool id_incr();
+ void cmd_read_id();
+ void cmd_write_id();
+ uint32_t read_id();
+ uint32_t write_id();
+ void cmd_specify();
+ void cmd_invalid();
+
+//#if defined(USE_SOUND_FILES)
+ _TCHAR snd_seek_name[512];
+ _TCHAR snd_head_name[512];
+ int snd_seek_mix_tbl[UPD765A_SND_TBL_MAX];
+ int snd_head_mix_tbl[UPD765A_SND_TBL_MAX];
+ int16_t *snd_seek_data; // Read only
+ int16_t *snd_head_data; // Read only
+ int snd_seek_samples_size;
+ int snd_head_samples_size;
+ bool snd_mute;
+ int snd_level_l, snd_level_r;
+ virtual void mix_main(int32_t *dst, int count, int16_t *src, int *table, int samples);
+ void add_sound(int type);
+//#endif
+public:
+ UPD765A(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
+ {
+ initialize_output_signals(&outputs_irq);
+ initialize_output_signals(&outputs_drq);
+ initialize_output_signals(&outputs_hdu);
+ initialize_output_signals(&outputs_index);
+ force_ready = false;
+ raise_irq_when_media_changed = false;
+ set_device_name(_T("uPD765A FDC"));
+//#if defined(USE_SOUND_FILES)
+ for(int i = 0; i < UPD765A_SND_TBL_MAX; i++) {
+ snd_seek_mix_tbl[i] = -1;
+ snd_head_mix_tbl[i] = -1;
+ }
+ snd_seek_data = snd_head_data = NULL;
+ snd_seek_samples_size = snd_head_samples_size = 0;
+ snd_mute = false;
+ snd_level_l = snd_level_r = decibel_to_volume(0);
+ memset(snd_seek_name, 0x00, sizeof(snd_seek_name));
+ memset(snd_head_name, 0x00, sizeof(snd_head_name));
+//#endif
+ }
+ ~UPD765A() {}
+
+ // common functions
+ void initialize();
+ void release();
+ void reset();
+ void write_io8(uint32_t addr, uint32_t data);
+ uint32_t read_io8(uint32_t addr);
+ void write_dma_io8(uint32_t addr, uint32_t data);
+ uint32_t read_dma_io8(uint32_t addr);
+ void write_signal(int id, uint32_t data, uint32_t mask);
+ uint32_t read_signal(int ch);
+ void event_callback(int event_id, int err);
+ void save_state(FILEIO* state_fio);
+ bool load_state(FILEIO* state_fio);
+ // unique function
+ void set_context_irq(DEVICE* device, int id, uint32_t mask)
+ {
+ register_output_signal(&outputs_irq, device, id, mask);
+ }
+ void set_context_drq(DEVICE* device, int id, uint32_t mask)
+ {
+ register_output_signal(&outputs_drq, device, id, mask);
+ }
+ void set_context_hdu(DEVICE* device, int id, uint32_t mask)
+ {
+ register_output_signal(&outputs_hdu, device, id, mask);
+ }
+ void set_context_index(DEVICE* device, int id, uint32_t mask)
+ {
+ register_output_signal(&outputs_index, device, id, mask);
+ }
+ DISK* get_disk_handler(int drv)
+ {
+ return disk[drv];
+ }
+//#if defined(USE_SOUND_FILES)
+ // Around SOUND. 20161004 K.O
+ bool load_sound_data(int type, const _TCHAR *pathname);
+ void release_sound_data(int type);
+ bool reload_sound_data(int type);
+
+ void mix(int32_t *buffer, int cnt);
+ void set_volume(int ch, int decibel_l, int decibel_r);
+//#endif
+ void open_disk(int drv, const _TCHAR* file_path, int bank);
+ void close_disk(int drv);
+ bool is_disk_inserted(int drv);
+ bool is_disk_inserted(); // current hdu
+ bool disk_ejected(int drv);
+ bool disk_ejected(); // current hdu
+ void is_disk_protected(int drv, bool value);
+ bool is_disk_protected(int drv);
+ uint8_t media_type(int drv);
+ void set_drive_type(int drv, uint8_t type);
+ uint8_t get_drive_type(int drv);
+ void set_drive_rpm(int drv, int rpm);
+ void set_drive_mfm(int drv, bool mfm);
+ bool raise_irq_when_media_changed;
+};
+
+#endif
+