summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/diablo_hd.h
blob: 93915e628e356ccdbf745f4c19044fdf11bf9b30 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                        

                                                           

                                                            

                                
 
            
 
                            



                             
                                                



                                        
                                                                                                          












































                                                                                                              


                                                                                                       
                                                                         

        
                                                                                                                  
 
                        

























                                                                                                            

                                                                                                         














                                                                                                    
                                                        

                                                         
                                                                      

                                                                 
                                                                    

                                                                
                                                                                      

                                                      
                                                                                     

                                                                
                                  
 
                                                      
                                                   

                                    
                                                                                             

                                                              
                                                                     

                                                                          
                                                                       

                                                                          
                                                                                       

                                                                           
                                                                     










                                                                       
                                       
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
/**********************************************************
 *   DIABLO31 and DIABLO44 hard drive support
 **********************************************************/

#ifndef MAME_MACHINE_DIABLO_HD_H
#define MAME_MACHINE_DIABLO_HD_H

#pragma once

#include "imagedev/diablo.h"

#define DIABLO_HD_0 "diablo0"
#define DIABLO_HD_1 "diablo1"

DECLARE_DEVICE_TYPE(DIABLO_HD, diablo_hd_device)

class diablo_hd_device : public device_t
{
public:
	diablo_hd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
	~diablo_hd_device();

	static const int DIABLO_UNIT_MAX = 2;           //!< max number of drive units
	static const int DIABLO_CYLINDERS = 203;        //!< number of cylinders per drive
	static const int DIABLO_CYLINDER_MASK = 0777;   //!< bit maks for cylinder number (9 bits)
	static const int DIABLO_SPT = 12;               //!< number of sectors per track
	static const int DIABLO_SECTOR_MASK = 017;      //!< bit maks for sector number (4 bits)
	static const int DIABLO_HEADS = 2;              //!< number of heads per drive
	static const int DIABLO_HEAD_MASK = 1;          //!< bit maks for head number (1 bit)
	static const int DIABLO_PAGES = 203*2*12;       //!< number of pages per drive
	//! convert a cylinder/head/sector to a logical block address (page)
	static inline int DIABLO_PAGE(int c, int h, int s) { return (c * DIABLO_HEADS + h) * DIABLO_SPT + s; }

	void set_sector_callback(void* cookie, void(*callback)(void*, int));

	int bits_per_sector() const;
	const char* description() const;
	int unit() const;
	attotime rotation_time() const;
	attotime sector_time() const;
	attotime bit_time() const;

	int get_seek_read_write_0() const;
	int get_ready_0() const;
	int get_sector_mark_0() const;
	int get_addx_acknowledge_0() const;
	int get_log_addx_interlock_0() const;
	int get_seek_incomplete_0() const;
	int get_cylinder() const;
	int get_head() const;
	int get_sector() const;
	int get_page() const;
	void select(int unit);
	void set_head(int head);
	void set_cylinder(int cylinder);
	void set_restore(int restore);
	void set_strobe(int strobe);
	void set_egate(int gate);
	void set_wrgate(int gate);
	void set_rdgate(int gate);
	void wr_data(int index, int wrdata);
	int rd_data(int index);
	int rd_clock(int index);

protected:
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
	virtual void device_add_mconfig(machine_config &config) override;

private:
	template <typename Format, typename... Params> void logprintf(int level, Format &&fmt, Params &&... args);

	int m_log_level;
	bool m_diablo31;                        //!< true, if this is a DIABLO31 drive
	int m_unit;                             //!< drive unit number (0 or 1)
	char m_description[32];                 //!< description of the drive(s)
	int m_packs;                            //!< number of packs in drive (1 or 2)
	attotime m_rotation_time;               //!< rotation time in atto seconds
	attotime m_sector_time;                 //!< sector time in atto seconds
	attotime m_sector_mark_0_time;          //!< sector mark going 0 before sector pulse time
	attotime m_sector_mark_1_time;          //!< sector mark going 1 after sector pulse time
	attotime m_bit_time;                    //!< bit time in atto seconds
	int m_s_r_w_0;                          //!< drive seek/read/write signal (active 0)
	int m_ready_0;                          //!< drive ready signal (active 0)
	int m_sector_mark_0;                    //!< sector mark (0 if new sector)
	int m_addx_acknowledge_0;               //!< address acknowledge, i.e. seek successful (active 0)
	int m_log_addx_interlock_0;             //!< log address interlock, i.e. seek in progress (active 0)
	int m_seek_incomplete_0;                //!< seek incomplete, i.e. seek in progress (active 0)
	int m_egate_0;                          //!< erase gate
	int m_wrgate_0;                         //!< write gate
	int m_rdgate_0;                         //!< read gate
	int m_cylinders;                        //!< total number of cylinders
	int m_pages;                            //!< total number of pages
	int m_seekto;                           //!< seek to cylinder number
	int m_restore;                          //!< restore to cylinder 0 flag
	int m_cylinder;                         //!< current cylinder number
	int m_head;                             //!< current head (track) number on cylinder
	int m_sector;                           //!< current sector number in track
	int m_page;                             //!< current page (derived from cylinder, head and sector)
	std::unique_ptr<uint8_t[]> m_cache[2 * DIABLO_PAGES];                        //!< pages raw bytes
	uint32_t** m_bits;                        //!< pages expanded to bits
	int m_rdfirst;                          //!< set to first bit of a sector that is read from
	int m_rdlast;                           //!< set to last bit of a sector that was read from
	int m_wrfirst;                          //!< set to non-zero if a sector is written to
	int m_wrlast;                           //!< set to last bit of a sector that was written to
	void *m_sector_callback_cookie;         //!< cookie to pass to callback
	void (*m_sector_callback)(void*,int);   //!< callback to call at the start of each sector
	emu_timer* m_timer;                     //!< sector timer
	diablo_image_device* m_image;           //!< diablo_image_device interfacing the CHD
	chd_file* m_handle;                     //!< underlying CHD handle
	hard_disk_file* m_disk;                 //!< underlying hard disk file

	//! translate C/H/S to a page and read the sector
	void read_sector();

	//! compute the checksum of a record
	int cksum(uint8_t *src, size_t size, int start);

	//! expand a series of clock bits and 0 data bits
	size_t expand_zeroes(uint32_t *bits, size_t dst, size_t size);

	//! expand a series of 0 words and write a final sync bit
	size_t expand_sync(uint32_t *bits, size_t dst, size_t size);

	//! expand a record of words into a array of bits at dst
	size_t expand_record(uint32_t *bits, size_t dst, uint8_t *field, size_t size);

	//! expand a record's checksum word to 32 bits
	size_t expand_cksum(uint32_t *bits, size_t dst, uint8_t *field, size_t size);

	//! expand a sector into an array of clock and data bits
	uint32_t* expand_sector();

	//! dump a number of words as ASCII characters
	void dump_ascii(uint8_t *src, size_t size);

	//! dump a record's contents
	size_t dump_record(uint8_t *src, size_t addr, size_t size, const char *name, int cr);

	//! find a sync bit in an array of clock and data bits
	size_t squeeze_sync(uint32_t *bits, size_t src, size_t size);

	//! find a 16 x 0 bits sequence in an array of clock and data bits
	size_t squeeze_unsync(uint32_t *bits, size_t src, size_t size);

	//! squeeze an array of clock and data bits into a sector's record
	size_t squeeze_record(uint32_t *bits, size_t src, uint8_t *field, size_t size);

	//! squeeze an array of 32 clock and data bits into a checksum word
	size_t squeeze_cksum(uint32_t *bits, size_t src, int *cksum);

	//! squeeze a array of clock and data bits into a sector's data
	void squeeze_sector();

	//! deassert the sector mark
	void sector_mark_1();

	//! assert the sector mark and read the next sector
	void sector_mark_0();
};

#endif  // !defined(_DIABLO_HD_DEVICE_)