1 // license:BSD-3-Clause
2 // copyright-holders:68bit
3 /**********************************************************************
4
5 PIA IDE Hard Disk Interface
6
7 Note this interface does appear to have used an 8 bit IDE data path, and
8 does appear to have discarded every second byte of storage - this does not
9 appear to be mis-implementation here. FLEX uses 256 byte sectors so half
10 of the IDE 512 byte sector give the required fit.
11
12 Some emulators appear to have stripped out that second unused byte when
13 writing their disk images. So their disk images will need to be filled
14 when importing these images for use with this device. Also some emulators
15 appear tolerant of trailing unused data and their images might need to be
16 truncated to the length defined by the disk geomentry.
17
18 The FLEX drivers for the PIA IDE appear to translate FLEX virtual track
19 and sector ID's into a target geometry. The disk geometry will likely need
20 to be defined and that can be done by using the MAME CHD disk format. The
21 range of FLEX tracks and sectors is limited to 0 to 255 so it needs to use
22 that full virtual range get the largest usable partitions. The drivers
23 support multiple partitions that appears as multiple disks to FLEX to make
24 use of more storage.
25
26 A similar (compatible) interface appears to have been used by the 'PT69'
27 SBC and drivers and disks targeting the PT69 have also run with this
28 device. The 'PT69' appears to place the PIA at 0xe010 to 0xe013 and it's
29 supporting ROM based at 0xf000, in contrast to the MAME swtpc09i machine
30 which places the PIA IDE in IO6 at 0xe060 (so that the DC5 FDC can remain
31 at IO1) and places the supporting ROM at $e800. The MAME swtpc09i machine
32 has booted some PT69 disk images with some minor software changes.
33
34 **********************************************************************/
35
36 #include "emu.h"
37 #include "piaide.h"
38
39 #include "machine/6821pia.h"
40 #include "machine/idectrl.h"
41
42 //**************************************************************************
43 // TYPE DEFINITIONS
44 //**************************************************************************
45
46 // ======================> ss50_piaide_device
47
48 class ss50_piaide_device : public device_t, public ss50_card_interface
49 {
50 public:
51 // construction/destruction
ss50_piaide_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)52 ss50_piaide_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
53 : device_t(mconfig, SS50_PIAIDE, tag, owner, clock)
54 , ss50_card_interface(mconfig, *this)
55 , m_pia(*this, "pia")
56 , m_ide(*this, "ide")
57 {
58 }
59
60 protected:
61 // device-specific overrides
62 virtual void device_add_mconfig(machine_config &config) override;
63 virtual void device_start() override;
64
65 // interface-specific overrides
66 virtual uint8_t register_read(offs_t offset) override;
67 virtual void register_write(offs_t offset, uint8_t data) override;
68
69 private:
70 optional_device<pia6821_device> m_pia;
71 optional_device<ide_controller_device> m_ide;
72
73 uint8_t m_pia_porta;
74 uint8_t m_pia_portb;
75
76 uint8_t pia_a_r();
77 uint8_t pia_b_r();
78 void pia_a_w(uint8_t data);
79 void pia_b_w(uint8_t data);
80
81 };
82
device_start()83 void ss50_piaide_device::device_start()
84 {
85 save_item(NAME(m_pia_porta));
86 save_item(NAME(m_pia_portb));
87 }
88
89 //-------------------------------------------------
90 // device_add_mconfig - add device-specific
91 // machine configuration
92 //-------------------------------------------------
93
device_add_mconfig(machine_config & config)94 void ss50_piaide_device::device_add_mconfig(machine_config &config)
95 {
96 PIA6821(config, m_pia, 0);
97 m_pia->readpa_handler().set(FUNC(ss50_piaide_device::pia_a_r));
98 m_pia->readpb_handler().set(FUNC(ss50_piaide_device::pia_b_r));
99 m_pia->writepa_handler().set(FUNC(ss50_piaide_device::pia_a_w));
100 m_pia->writepb_handler().set(FUNC(ss50_piaide_device::pia_b_w));
101
102 IDE_CONTROLLER(config, m_ide).options(ata_devices, "hdd", nullptr, false);
103 }
104
105 //-------------------------------------------------
106 // register_read - read from a port register
107 //-------------------------------------------------
108
register_read(offs_t offset)109 uint8_t ss50_piaide_device::register_read(offs_t offset)
110 {
111 return m_pia->read(offset & 3);
112 }
113
114 //-------------------------------------------------
115 // register_write - write to a port register
116 //-------------------------------------------------
117
register_write(offs_t offset,uint8_t data)118 void ss50_piaide_device::register_write(offs_t offset, uint8_t data)
119 {
120 m_pia->write(offset & 3, data);
121 }
122
123 /******* MC6821 PIA on IDE Board *******/
124 /* Read/Write handlers for pia ide */
125
pia_a_r()126 uint8_t ss50_piaide_device::pia_a_r()
127 {
128 return m_pia_porta;
129 }
130
pia_b_r()131 uint8_t ss50_piaide_device::pia_b_r()
132 {
133 return m_pia_portb;
134 }
135
pia_a_w(uint8_t data)136 void ss50_piaide_device::pia_a_w(uint8_t data)
137 {
138 m_pia_porta = data;
139 }
140
pia_b_w(uint8_t data)141 void ss50_piaide_device::pia_b_w(uint8_t data)
142 {
143 uint16_t tempidedata;
144
145 m_pia_portb = data;
146
147 // Pass through a 16 bit accessor to the IDE bus.
148 uint8_t low = (data & 0x04) >> 2;
149 uint8_t high = (data & 0x18) >> 3;
150 uint16_t ide_mem_mask = low ? 0xff00 : 0x00ff;
151
152 if ((data & 0x40)&&(!(data&0x20))) //cs0=0 cs1=1 bit 5&6
153 {
154 if (!(data & 0x02)) //rd line bit 1
155 {
156 tempidedata = m_ide->read_cs0(high, ide_mem_mask);
157 logerror("ide_bus_r: offset $%02X data %04X\n", (data&0x1c)>>2, tempidedata);
158 m_pia_porta = low ? tempidedata >> 8 : tempidedata & 0x00ff;
159 }
160 else if (!(data & 0x01)) //wr line bit 0
161 {
162 uint16_t ide_data = low ? m_pia_porta << 8: m_pia_porta;
163 m_ide->write_cs0(high, ide_data, ide_mem_mask);
164 logerror("ide_bus_w: offset $%02X data %04X\n", (data&0x1c)>>2, m_pia_porta);
165 }
166 }
167 else if ((data & 0x20)&&(!(data&0x40))) //cs0=1 cs1=0 bit 5&6
168 {
169 if (!(data & 0x02)) //rd line bit 1
170 {
171 tempidedata = m_ide->read_cs1(high, ide_mem_mask);
172 logerror("ide_bus_r: offset $%02X data %04X\n", (data&0x1c)>>2, tempidedata);
173 m_pia_porta = low ? tempidedata >> 8 : tempidedata & 0x00ff;
174 }
175 else if (!(data & 0x01)) //wr line bit 0
176 {
177 uint16_t ide_data = low ? m_pia_porta << 8: m_pia_porta;
178 m_ide->write_cs1(high, ide_data, ide_mem_mask);
179 logerror("ide_bus_w: offset $%02X data %04X\n", (data&0x1c)>>2, m_pia_porta);
180 }
181 }
182 }
183
184 // device type definition
185 DEFINE_DEVICE_TYPE_PRIVATE(SS50_PIAIDE, ss50_card_interface, ss50_piaide_device, "ss50_piaide", "PIA IDE Hard Disk Interface")
186