1 // license:LGPL-2.1+
2 // copyright-holders:Michael Zapf
3 /****************************************************************************
4 
5     Myarc Hard and Floppy Disk Controller
6     See hfdc.c for documentation
7 
8     January 2012: rewritten as class
9     June 2014: rewritten for modern floppy implementation
10 
11     Michael Zapf
12     July 2015
13 
14 ****************************************************************************/
15 
16 #ifndef MAME_BUS_TI99_PEB_HFDC_H
17 #define MAME_BUS_TI99_PEB_HFDC_H
18 
19 #pragma once
20 
21 #include "peribox.h"
22 
23 #include "imagedev/floppy.h"
24 #include "imagedev/mfmhd.h"
25 
26 #include "machine/mm58274c.h"
27 #include "machine/hdc92x4.h"
28 #include "machine/ram.h"
29 
30 namespace bus { namespace ti99 { namespace peb {
31 
32 /*
33     Implementation for modern floppy system.
34 */
35 class myarc_hfdc_device : public device_t, public device_ti99_peribox_card_interface
36 {
37 public:
38 	myarc_hfdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
39 
40 	void readz(offs_t offset, uint8_t *value) override;
41 	void write(offs_t offset, uint8_t data) override;
42 	void setaddress_dbin(offs_t offset, int state) override;
43 	void crureadz(offs_t offset, uint8_t *value) override;
44 	void cruwrite(offs_t offset, uint8_t data) override;
45 
46 protected:
47 	void device_config_complete() override;
48 
49 private:
50 	void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
51 	void device_start() override;
52 	void device_reset() override;
53 
54 	const tiny_rom_entry *device_rom_region() const override;
55 	virtual void device_add_mconfig(machine_config &config) override;
56 	ioport_constructor device_input_ports() const override;
57 
58 	DECLARE_WRITE_LINE_MEMBER( dmarq_w );
59 	DECLARE_WRITE_LINE_MEMBER( intrq_w );
60 	DECLARE_WRITE_LINE_MEMBER( dip_w );
61 	void auxbus_out(offs_t offset, uint8_t data);
62 	uint8_t read_buffer();
63 	void write_buffer(uint8_t data);
64 
65 	DECLARE_FLOPPY_FORMATS( floppy_formats );
66 
67 	// Debug accessors
68 	void debug_read(offs_t offset, uint8_t* value);
69 	void debug_write(offs_t offset, uint8_t data);
70 
71 	// Callbacks for the index hole and seek complete
72 	void floppy_index_callback(floppy_image_device *floppy, int state);
73 	void harddisk_index_callback(mfm_harddisk_device *harddisk, int state);
74 	void harddisk_ready_callback(mfm_harddisk_device *harddisk, int state);
75 	void harddisk_skcom_callback(mfm_harddisk_device *harddisk, int state);
76 
77 	// Operate the floppy motors
78 	void set_floppy_motors_running(bool run);
79 
80 	// Connect floppy drives
81 	void connect_floppy_unit(int index);
82 
83 	// Connect harddisk drives
84 	void connect_harddisk_unit(int index);
85 
86 	// Disconnect drives
87 	void disconnect_floppy_drives();
88 	void disconnect_hard_drives();
89 
90 	// Pushes the drive status to the HDC
91 	void signal_drive_status();
92 
93 	// Motor monoflop (4.23 sec)
94 	emu_timer*      m_motor_on_timer;
95 
96 	// HDC9234 controller on the board
97 	required_device<hdc9234_device> m_hdc9234;
98 
99 	// Clock chip on the board
100 	required_device<mm58274c_device> m_clock;
101 
102 	// Link to the attached floppy drives
103 	floppy_image_device*    m_floppy_unit[4];
104 
105 	// Link to the attached hard disks
106 	mfm_harddisk_device*    m_harddisk_unit[3];
107 
108 	// Currently selected floppy drive
109 	floppy_image_device*    m_current_floppy;
110 
111 	// Currently selected hard drive
112 	mfm_harddisk_device*    m_current_harddisk;
113 
114 	// True: Access to DIP switch settings, false: access to line states
115 	bool    m_see_switches;
116 
117 	// IRQ state
118 	int    m_irq;
119 
120 	// DMA in Progress state
121 	int    m_dip;
122 
123 	// When true, motor monoflop is high
124 	bool    m_motor_running;
125 
126 	// Address in card area
127 	bool m_inDsrArea;
128 
129 	// HDC selected
130 	bool m_HDCsel;
131 
132 	// RTC selected
133 	bool m_RTCsel;
134 
135 	// Tape selected
136 	bool m_tapesel;
137 
138 	// RAM selected
139 	bool m_RAMsel;
140 
141 	// RAM selected
142 	bool m_ROMsel;
143 
144 	// Recent address
145 	int m_address;
146 
147 	// Wait for HD. This was an addition in later cards.
148 	bool m_wait_for_hd1;
149 
150 	// Device Service Routine ROM (firmware)
151 	uint8_t*  m_dsrrom;
152 
153 	// ROM banks.
154 	int     m_rom_page;
155 
156 	// HFDC on-board SRAM (8K or 32K)
157 	required_device<ram_device> m_buffer_ram;
158 
159 	// RAM page registers
160 	int     m_ram_page[4];
161 
162 	// Drive status latch (STB0)
163 	uint8_t   m_status_latch;
164 
165 	// DMA address latch (in Gate Array) (STB1)
166 	uint32_t  m_dma_address;
167 
168 	// Output 1 latch (STB2)
169 	uint8_t   m_output1_latch;
170 
171 	// Output 2 latch (STB3)
172 	uint8_t   m_output2_latch;
173 
174 	// Needed for triggering the motor monoflop
175 	uint8_t m_lastval;
176 
177 	// Signal motor_on. When true, makes all drives turning.
178 	int m_MOTOR_ON;
179 
180 	// Calculates the index from the bit
181 	int bit_to_index(int value);
182 
183 	// Utility function to set or unset bits in a byte
184 	void set_bits(uint8_t& byte, int mask, bool set);
185 
186 	// Joined ready line towards the controller
187 	int  m_readyflags;
188 };
189 
190 } } } // end namespace bus::ti99::peb
191 
192 DECLARE_DEVICE_TYPE_NS(TI99_HFDC, bus::ti99::peb, myarc_hfdc_device)
193 
194 #endif // MAME_BUS_TI99_PEB_HFDC_H
195