// license:BSD-3-Clause // copyright-holders:Nathan Woods, Miodrag Milanovic /* flopdrv provides simple emulation of a disc drive */ /* the 8271, upd765 and wd179x use this */ #ifndef MAME_DEVICES_IMAGEDV_FLOPDRV_H #define MAME_DEVICES_IMAGEDV_FLOPDRV_H #pragma once #include "formats/flopimg.h" #include "softlist_dev.h" #define FLOPPY_TYPE_REGULAR 0 #define FLOPPY_TYPE_APPLE 1 #define FLOPPY_TYPE_SONY 2 #define FLOPPY_DRIVE_2_8_INCH 1 #define FLOPPY_DRIVE_3_INCH 2 #define FLOPPY_DRIVE_3_5_INCH 3 #define FLOPPY_DRIVE_5_25_INCH 4 #define FLOPPY_DRIVE_8_INCH 5 // Maximum supported density #define FLOPPY_DRIVE_SD 1 #define FLOPPY_DRIVE_DD 2 #define FLOPPY_DRIVE_QD 3 #define FLOPPY_DRIVE_HD 4 #define FLOPPY_DRIVE_ED 5 #define FLOPPY_STANDARD_3_SSDD { FLOPPY_DRIVE_3_INCH, 1, 42, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_3_DSDD { FLOPPY_DRIVE_3_INCH, 2, 42, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_3_5_SSDD { FLOPPY_DRIVE_3_5_INCH, 1, 83, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_3_5_DSDD { FLOPPY_DRIVE_3_5_INCH, 2, 83, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_3_5_DSHD { FLOPPY_DRIVE_3_5_INCH, 2, 83, FLOPPY_DRIVE_HD } #define FLOPPY_STANDARD_3_5_DSED { FLOPPY_DRIVE_3_5_INCH, 2, 83, FLOPPY_DRIVE_ED } #define FLOPPY_STANDARD_5_25_SSSD_35 { FLOPPY_DRIVE_5_25_INCH, 1, 37, FLOPPY_DRIVE_SD } #define FLOPPY_STANDARD_5_25_DSSD_35 { FLOPPY_DRIVE_5_25_INCH, 2, 37, FLOPPY_DRIVE_SD } #define FLOPPY_STANDARD_5_25_SSSD { FLOPPY_DRIVE_5_25_INCH, 1, 42, FLOPPY_DRIVE_SD } #define FLOPPY_STANDARD_5_25_DSSD { FLOPPY_DRIVE_5_25_INCH, 2, 42, FLOPPY_DRIVE_SD } #define FLOPPY_STANDARD_5_25_SSDD_40 { FLOPPY_DRIVE_5_25_INCH, 1, 42, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_5_25_SSDD_80 { FLOPPY_DRIVE_5_25_INCH, 1, 83, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_5_25_DSDD_40 { FLOPPY_DRIVE_5_25_INCH, 2, 42, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_5_25_SSDD { FLOPPY_DRIVE_5_25_INCH, 1, 83, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_5_25_DSDD { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_5_25_DSQD { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_QD } #define FLOPPY_STANDARD_5_25_DSHD { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_HD } #define FLOPPY_STANDARD_8_SSSD { FLOPPY_DRIVE_8_INCH, 1, 77, FLOPPY_DRIVE_SD } #define FLOPPY_STANDARD_8_DSSD { FLOPPY_DRIVE_8_INCH, 2, 77, FLOPPY_DRIVE_SD } #define FLOPPY_STANDARD_8_DSDD { FLOPPY_DRIVE_8_INCH, 2, 77, FLOPPY_DRIVE_DD } /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ // ======================> floppy_type_t struct floppy_type_t { uint8_t media_size; uint8_t head_number; uint8_t max_track_number; uint8_t max_density; }; // ======================> floppy_interface struct floppy_interface { floppy_type_t floppy_type; const struct FloppyFormat *formats; const char *interface; }; struct chrn_id { unsigned char C; unsigned char H; unsigned char R; unsigned char N; int data_id; // id for read/write data command unsigned long flags; }; /* set if drive is ready */ #define FLOPPY_DRIVE_READY 0x0010 /* set if index has just occurred */ #define FLOPPY_DRIVE_INDEX 0x0020 #define MCFG_LEGACY_FLOPPY_IDX_CB(_devcb) \ devcb = &downcast(*device).set_out_idx_func(DEVCB_##_devcb); class legacy_floppy_image_device : public device_t, public device_image_interface { public: // construction/destruction legacy_floppy_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); ~legacy_floppy_image_device(); void set_floppy_config(const floppy_interface *config) { m_config = config; } template devcb_base &set_out_idx_func(Object &&cb) { return m_out_idx_func.set_callback(std::forward(cb)); } virtual image_init_result call_load() override; virtual const software_list_loader &get_software_list_loader() const override { return image_software_list_loader::instance(); } virtual image_init_result call_create(int format_type, util::option_resolution *format_options) override; virtual void call_unload() override; virtual iodevice_t image_type() const override { return IO_FLOPPY; } virtual bool is_readable() const override { return 1; } virtual bool is_writeable() const override { return 1; } virtual bool is_creatable() const override; virtual bool must_be_loaded() const override { return 0; } virtual bool is_reset_on_load() const override { return 0; } virtual const char *image_interface() const override; virtual const char *file_extensions() const override { return m_extension_list; } virtual const util::option_guide &create_option_guide() const override { return floppy_option_guide; } floppy_image_legacy *flopimg_get_image(); void floppy_drive_set_geometry(floppy_type_t type); void floppy_drive_set_flag_state(int flag, int state); void floppy_drive_set_ready_state(int state, int flag); int floppy_drive_get_flag_state(int flag); void floppy_drive_seek(signed int signed_tracks); int floppy_drive_get_next_id(int side, chrn_id *id); void floppy_drive_read_track_data_info_buffer(int side, void *ptr, int *length ); void floppy_drive_write_track_data_info_buffer(int side, const void *ptr, int *length ); void floppy_drive_format_sector(int side, int sector_index,int c,int h, int r, int n, int filler); void floppy_drive_read_sector_data(int side, int index1, void *ptr, int length); void floppy_drive_write_sector_data(int side, int index1, const void *ptr,int length, int ddam); void floppy_install_load_proc(void (*proc)(device_image_interface &image, bool is_created)); void floppy_install_unload_proc(void (*proc)(device_image_interface &image)); void floppy_drive_set_index_pulse_callback(void (*callback)(device_t *controller,device_t *image, int state)); int floppy_drive_get_current_track(); uint64_t floppy_drive_get_current_track_size(int head); void floppy_drive_set_rpm(float rpm); void floppy_drive_set_controller(device_t *controller); int floppy_get_drive_type(); void floppy_set_type(int ftype); WRITE_LINE_MEMBER( floppy_ds0_w ); WRITE_LINE_MEMBER( floppy_ds1_w ); WRITE_LINE_MEMBER( floppy_ds2_w ); WRITE_LINE_MEMBER( floppy_ds3_w ); WRITE8_MEMBER( floppy_ds_w ); WRITE_LINE_MEMBER( floppy_mon_w ); WRITE_LINE_MEMBER( floppy_drtn_w ); WRITE_LINE_MEMBER( floppy_wtd_w ); WRITE_LINE_MEMBER( floppy_stp_w ); WRITE_LINE_MEMBER( floppy_wtg_w ); READ_LINE_MEMBER( floppy_wpt_r ); READ_LINE_MEMBER( floppy_tk00_r ); READ_LINE_MEMBER( floppy_dskchg_r ); READ_LINE_MEMBER( floppy_twosid_r ); READ_LINE_MEMBER( floppy_index_r ); READ_LINE_MEMBER( floppy_ready_r ); private: int flopimg_get_sectors_per_track(int side); void flopimg_get_id_callback(chrn_id *id, int id_index, int side); void log_readwrite(const char *name, int head, int track, int sector, const char *buf, int length); void floppy_drive_set_geometry_absolute(int tracks, int sides); TIMER_CALLBACK_MEMBER(floppy_drive_index_callback); void floppy_drive_init(); void floppy_drive_index_func(); image_init_result internal_floppy_device_load(bool is_create, int create_format, util::option_resolution *create_args); TIMER_CALLBACK_MEMBER( set_wpt ); protected: legacy_floppy_image_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device overrides virtual void device_config_complete() override; virtual void device_start() override; /* callbacks */ devcb_write_line m_out_idx_func; /* state of input lines */ int m_drtn; /* direction */ int m_stp; /* step */ int m_wtg; /* write gate */ int m_mon; /* motor on */ /* state of output lines */ int m_idx; /* index pulse */ int m_tk00; /* track 00 */ int m_wpt; /* write protect */ int m_rdy; /* ready */ int m_dskchg; /* disk changed */ /* drive select logic */ int m_drive_id; int m_active; const floppy_interface *m_config; /* flags */ int m_flags; /* maximum track allowed */ int m_max_track; /* num sides */ int m_num_sides; /* current track - this may or may not relate to the present cylinder number stored by the fdc */ int m_current_track; /* index pulse timer */ emu_timer *m_index_timer; /* index pulse callback */ void (*m_index_pulse_callback)(device_t *controller,device_t *image, int state); /* rotation per minute => gives index pulse frequency */ float m_rpm; int m_id_index; device_t *m_controller; floppy_image_legacy *m_floppy; int m_track; void (*m_load_proc)(device_image_interface &image, bool is_created); void (*m_unload_proc)(device_image_interface &image); int m_floppy_drive_type; char m_extension_list[256]; }; // device type definition DECLARE_DEVICE_TYPE(LEGACY_FLOPPY, legacy_floppy_image_device) legacy_floppy_image_device *floppy_get_device(running_machine &machine,int drive); legacy_floppy_image_device *floppy_get_device_by_type(running_machine &machine,int ftype,int drive); int floppy_get_drive_by_type(legacy_floppy_image_device *image,int ftype); int floppy_get_count(running_machine &machine); /*************************************************************************** DEVICE CONFIGURATION MACROS ***************************************************************************/ #define FLOPPY_0 "floppy0" #define FLOPPY_1 "floppy1" #define FLOPPY_2 "floppy2" #define FLOPPY_3 "floppy3" #define MCFG_LEGACY_FLOPPY_CONFIG(_config) \ downcast(*device).set_floppy_config(&(_config)); #define MCFG_LEGACY_FLOPPY_DRIVE_ADD(_tag, _config) \ MCFG_DEVICE_ADD(_tag, LEGACY_FLOPPY, 0) \ MCFG_LEGACY_FLOPPY_CONFIG(_config) #define MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(_config) \ MCFG_DEVICE_ADD(FLOPPY_0, LEGACY_FLOPPY, 0) \ MCFG_LEGACY_FLOPPY_CONFIG(_config) \ MCFG_DEVICE_ADD(FLOPPY_1, LEGACY_FLOPPY, 0) \ MCFG_LEGACY_FLOPPY_CONFIG(_config) \ MCFG_DEVICE_ADD(FLOPPY_2, LEGACY_FLOPPY, 0) \ MCFG_LEGACY_FLOPPY_CONFIG(_config) \ MCFG_DEVICE_ADD(FLOPPY_3, LEGACY_FLOPPY, 0) \ MCFG_LEGACY_FLOPPY_CONFIG(_config) #define MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(_config) \ MCFG_DEVICE_ADD(FLOPPY_0, LEGACY_FLOPPY, 0) \ MCFG_LEGACY_FLOPPY_CONFIG(_config) \ MCFG_DEVICE_ADD(FLOPPY_1, LEGACY_FLOPPY, 0) \ MCFG_LEGACY_FLOPPY_CONFIG(_config) #endif // MAME_DEVICES_IMAGEDV_FLOPDRV_H