1 // license:BSD-3-Clause
2 // copyright-holders:Nigel Barnes
3 /**********************************************************************
4
5 Tangerine TANDOS (MT0078)
6
7 http://www.microtan.ukpc.net/pageProducts.html#DOS
8
9 **********************************************************************/
10
11
12 #include "emu.h"
13 #include "tandos.h"
14
15
16 //**************************************************************************
17 // DEVICE DEFINITIONS
18 //**************************************************************************
19
20 DEFINE_DEVICE_TYPE(TANBUS_TANDOS, tanbus_tandos_device, "tanbus_tandos", "Tangerine Tandos Board")
21
22 //-------------------------------------------------
23 // SLOT_INTERFACE( tandos_floppies )
24 //-------------------------------------------------
25
tandos_floppies(device_slot_interface & device)26 static void tandos_floppies(device_slot_interface &device)
27 {
28 device.option_add("525sssd", FLOPPY_525_SSSD);
29 device.option_add("525sd", FLOPPY_525_SD);
30 device.option_add("525qd", FLOPPY_525_QD);
31 }
32
33 //-------------------------------------------------
34 // ROM( tandos )
35 //-------------------------------------------------
36
37 ROM_START(tandos)
38 ROM_REGION(0x1000, "dos_rom", 0)
39 ROM_DEFAULT_BIOS("step30")
40 ROM_SYSTEM_BIOS(0, "step30", "30ms Stepping Rate")
41 ROMX_LOAD("tandos_sr30.f2", 0x0000, 0x1000, CRC(54f55771) SHA1(5a801039fa8c05cd9227e9138469959524516c9e), ROM_BIOS(0))
42 ROM_SYSTEM_BIOS(1, "step6", "6ms Stepping Rate")
43 ROMX_LOAD("tandos_sr6.f2", 0x0000, 0x1000, CRC(10ef90fa) SHA1(b1e42cbf7197e693073d2578561803ea4c8efa8c), ROM_BIOS(1))
44 ROM_END
45
46 //-------------------------------------------------
47 // device_add_mconfig - add device configuration
48 //-------------------------------------------------
49
device_add_mconfig(machine_config & config)50 void tanbus_tandos_device::device_add_mconfig(machine_config &config)
51 {
52 FD1793(config, m_fdc, 8_MHz_XTAL / 8);
53 m_fdc->intrq_wr_callback().set(FUNC(tanbus_tandos_device::fdc_irq_w));
54 m_fdc->drq_wr_callback().set(FUNC(tanbus_tandos_device::fdc_drq_w));
55 m_fdc->hld_wr_callback().set(FUNC(tanbus_tandos_device::fdc_hld_w));
56 m_fdc->set_force_ready(true);
57
58 FLOPPY_CONNECTOR(config, m_floppies[0], tandos_floppies, "525qd", floppy_image_device::default_floppy_formats).enable_sound(true);
59 FLOPPY_CONNECTOR(config, m_floppies[1], tandos_floppies, "525qd", floppy_image_device::default_floppy_formats).enable_sound(true);
60 FLOPPY_CONNECTOR(config, m_floppies[2], tandos_floppies, nullptr, floppy_image_device::default_floppy_formats).enable_sound(true);
61 FLOPPY_CONNECTOR(config, m_floppies[3], tandos_floppies, nullptr, floppy_image_device::default_floppy_formats).enable_sound(true);
62 }
63
device_rom_region() const64 const tiny_rom_entry *tanbus_tandos_device::device_rom_region() const
65 {
66 return ROM_NAME(tandos);
67 }
68
69 //**************************************************************************
70 // LIVE DEVICE
71 //**************************************************************************
72
73 //-------------------------------------------------
74 // tanbus_tandos_device - constructor
75 //-------------------------------------------------
76
tanbus_tandos_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)77 tanbus_tandos_device::tanbus_tandos_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
78 : device_t(mconfig, TANBUS_TANDOS, tag, owner, clock)
79 , device_tanbus_interface(mconfig, *this)
80 , m_dos_rom(*this, "dos_rom")
81 , m_fdc(*this, "fdc")
82 , m_floppies(*this, "fdc:%u", 0)
83 , m_floppy(nullptr)
84 , m_drive_control(0)
85 {
86 }
87
88
89 //-------------------------------------------------
90 // device_start - device-specific startup
91 //-------------------------------------------------
92
device_start()93 void tanbus_tandos_device::device_start()
94 {
95 m_ram = std::make_unique<uint8_t[]>(0x0400);
96
97 save_pointer(NAME(m_ram), 0x0400);
98 }
99
100 //-------------------------------------------------
101 // device_reset - device-specific reset
102 //-------------------------------------------------
103
device_reset()104 void tanbus_tandos_device::device_reset()
105 {
106 // reset floppy control register
107 control_w(0);
108 }
109
110 //-------------------------------------------------
111 // read - card read
112 //-------------------------------------------------
113
read(offs_t offset,int inhrom,int inhram,int be)114 uint8_t tanbus_tandos_device::read(offs_t offset, int inhrom, int inhram, int be)
115 {
116 uint8_t data = 0xff;
117
118 switch (offset & 0xfc00)
119 {
120 case 0xa800: case 0xac00: case 0xb000: case 0xb400:
121 data = m_dos_rom->base()[offset & 0x0fff];
122 break;
123
124 case 0xb800:
125 data = m_ram[offset & 0x03ff];
126 break;
127
128 default:
129 switch (offset)
130 {
131 case 0xbf90: case 0xbf91: case 0xbf92: case 0xbf93:
132 data = m_fdc->read(offset & 0x03);
133 break;
134 case 0xbf94: case 0xbf96:
135 data = status_r();
136 break;
137 case 0xbf95: case 0xbf97:
138 // GPIB PCB Switches
139 break;
140 case 0xbf98: case 0xbf99: case 0xbf9a: case 0xbf9b: case 0xbf9c: case 0xbf9d: case 0xbf9e: case 0xbf9f:
141 // GPIB (9914)
142 break;
143 }
144 break;
145 }
146
147 return data;
148 }
149
150 //-------------------------------------------------
151 // write - card write
152 //-------------------------------------------------
153
write(offs_t offset,uint8_t data,int inhrom,int inhram,int be)154 void tanbus_tandos_device::write(offs_t offset, uint8_t data, int inhrom, int inhram, int be)
155 {
156 switch (offset & 0xfc00)
157 {
158 case 0xb800:
159 m_ram[offset & 0x03ff] = data;
160 break;
161
162 default:
163 switch (offset)
164 {
165 case 0xbf90: case 0xbf91: case 0xbf92: case 0xbf93:
166 m_fdc->write(offset & 0x03, data);
167 break;
168 case 0xbf94: case 0xbf96:
169 control_w(data);
170 break;
171 case 0xbf98: case 0xbf99: case 0xbf9a: case 0xbf9b: case 0xbf9c: case 0xbf9d: case 0xbf9e: case 0xbf9f:
172 // GPIB (9914)
173 break;
174 }
175 break;
176 }
177 }
178
179 //-------------------------------------------------
180 // set_inhibit_lines
181 //-------------------------------------------------
182
set_inhibit_lines(offs_t offset,int & inhram,int & inhrom)183 void tanbus_tandos_device::set_inhibit_lines(offs_t offset, int &inhram, int &inhrom)
184 {
185 if (offset >= 0xa800 && offset < 0xbc00)
186 {
187 inhram = 1;
188 inhrom = 1;
189 }
190 };
191
192 //**************************************************************************
193 // IMPLEMENTATION
194 //**************************************************************************
195
control_w(uint8_t data)196 void tanbus_tandos_device::control_w(uint8_t data)
197 {
198 logerror("control_w %02x\n", data);
199 m_drive_control = data;
200
201 // bit 0: irq enable
202 m_irq_enable = BIT(data, 0);
203
204 // bit 1: data select (data stream controller)
205
206 // bit 2, 3: drive select
207 m_floppy = m_floppies[(data >> 2) & 0x03]->get_device();
208 m_fdc->set_floppy(m_floppy);
209
210 // bit 4: side select
211 if (m_floppy)
212 m_floppy->ss_w(BIT(data, 4));
213
214 // bit 5: density
215 m_fdc->dden_w(BIT(data, 5));
216
217 // bit 6: head load timing
218 m_fdc->hlt_w(BIT(data, 6));
219 if (m_floppy)
220 m_floppy->mon_w(!BIT(data, 6));
221
222 // bit 7: drq enable
223 m_drq_enable = BIT(data, 7);
224 }
225
status_r()226 uint8_t tanbus_tandos_device::status_r()
227 {
228 uint8_t data = 0x00;
229
230 data |= m_drive_control & 0x3c;
231 data |= m_fdc->intrq_r() << 0;
232 data |= m_fdc->hld_r() << 6;
233 data |= m_fdc->drq_r() << 7;
234
235 return data;
236 }
237
238
WRITE_LINE_MEMBER(tanbus_tandos_device::fdc_drq_w)239 WRITE_LINE_MEMBER(tanbus_tandos_device::fdc_drq_w)
240 {
241 m_tanbus->so_w((m_drq_enable && state) ? ASSERT_LINE : CLEAR_LINE);
242 }
243
WRITE_LINE_MEMBER(tanbus_tandos_device::fdc_irq_w)244 WRITE_LINE_MEMBER(tanbus_tandos_device::fdc_irq_w)
245 {
246 m_tanbus->irq_w((m_irq_enable && state) ? ASSERT_LINE : CLEAR_LINE);
247 }
248
WRITE_LINE_MEMBER(tanbus_tandos_device::fdc_hld_w)249 WRITE_LINE_MEMBER(tanbus_tandos_device::fdc_hld_w)
250 {
251 logerror("fdc_hld_w %d\n", state);
252 if (m_floppy)
253 m_floppy->mon_w(state);
254 }
255