summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/imagedev/flopdrv.h
blob: 1546eec85462c6ba2e6fdbb0b9101b9f0986d4e6 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                                    


                                                       



                                      
 
                            
                         

                             

                             
 




                                 









                                                                                       
                                                                                       

                                                                                       
                                                                                       




                                                                                       
                                                                                       











                                                                                       


                                        

                    



                                 

  
                                           
 
                       
 




                                           
              




                        
                                                                 
                            
  

                           
                                                      
                                    
                                                      
 
                                           
                                                                                                  
 
                                                    



                                                                                                     
                                                                                                                    

                                      

                                                                                                                                          
 
                                                       
                                                                                                                                        
                                                                                                                 



                                                                            

                                                                
                                                   

                                                                    

                                                                                         
                                                                                                              
 











                                                                                                          
                                                                                                    

                                                                                                                      
                                             
                                                               





























                                                                                                           
                                                                                                                               

                                         
          

                                                                                                                                      
                           

                                                       
 
                       
                                        




































                                                                                           





                                      
                                                                            


                                                             
                                              
  
 
                         
                                                              
 



                                                                                                    



                                                                          








                                                                            
                                            
                                                                                      
 

                                                         
                                          
 

                                                         
                                            
                                                         
                                            
                                                         
                                            
                                                         
                                          
 

                                                         
                                            
                                                         
                                          
 
                                        
// 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<legacy_floppy_image_device &>(*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<class Object> devcb_base &set_out_idx_func(Object &&cb) { return m_out_idx_func.set_callback(std::forward<Object>(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<legacy_floppy_image_device &>(*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