1 // license:BSD-3-Clause
2 // copyright-holders:
3 /***************************************************************************
4 
5 2013-09-10 Skeleton driver for Televideo TS816
6 
7 TODO:
8 - Connect up the devices to each other
9 - Connect up RS232 terminal instead of parallel one
10 - Connect centronics printer to PIO
11 - 4 diagnostic LEDs
12 - Hard Drive
13 - Tape Drive
14 - Get a good dump of the rom. If the undocumented DSW is enabled, it
15   calls up code in the missing half of the rom. Also it isn't possible
16   at the moment to get any useful response to commands.
17 
18 ****************************************************************************/
19 
20 #include "emu.h"
21 #include "cpu/z80/z80.h"
22 #include "machine/terminal.h"
23 #include "machine/z80daisy.h"
24 #include "machine/z80ctc.h"
25 #include "machine/z80pio.h"
26 #include "machine/z80sio.h"
27 #include "machine/z80dma.h"
28 
29 class ts816_state : public driver_device
30 {
31 public:
ts816_state(const machine_config & mconfig,device_type type,const char * tag)32 	ts816_state(const machine_config &mconfig, device_type type, const char *tag)
33 		: driver_device(mconfig, type, tag)
34 		, m_maincpu(*this, "maincpu")
35 		, m_terminal(*this, "terminal")
36 	{ }
37 
38 	void ts816(machine_config &config);
39 
40 	void init_ts816();
41 
42 private:
43 	void kbd_put(u8 data);
44 	uint8_t keyin_r();
45 	uint8_t status_r();
46 	void port68_w(uint8_t data);
47 	void port78_w(uint8_t data);
48 	void porte0_w(uint8_t data);
49 	void portf0_w(uint8_t data);
50 
51 	void ts816_io(address_map &map);
52 	void ts816_mem(address_map &map);
53 
54 	uint8_t m_term_data;
55 	uint8_t m_status;
56 	bool m_2ndbank;
57 	bool m_endram;
58 	void set_banks();
59 	virtual void machine_reset() override;
60 	required_device<z80_device> m_maincpu;
61 	required_device<generic_terminal_device> m_terminal;
62 };
63 
ts816_mem(address_map & map)64 void ts816_state::ts816_mem(address_map &map)
65 {
66 	map.unmap_value_high();
67 	map(0x0000, 0x3fff).bankr("bankr0").bankw("bankw0");
68 	map(0x4000, 0xdfff).bankrw("bank1");
69 	map(0xe000, 0xffff).bankrw("bank2");
70 }
71 
ts816_io(address_map & map)72 void ts816_state::ts816_io(address_map &map)
73 {
74 	map.global_mask(0xff);
75 	map(0x00, 0x00); // Tape status byte 1
76 	map(0x01, 0x01); // Tape status byte 2 and diagnostics mode
77 	map(0x02, 0x02); // Hard Disk status
78 	map(0x03, 0x03); // Hard Disk output latch
79 	map(0x04, 0x04); // Tape output latch byte 2
80 	map(0x05, 0x05); // Tape output latch byte 1
81 	map(0x07, 0x07); // Indicator load (LED)
82 	map(0x10, 0x13).rw("sio1", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w)); // SIO 1 for user 1 & 2
83 	map(0x18, 0x1b).rw("sio5", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w)); // SIO 5 for user 9 & 10
84 	map(0x20, 0x23).rw("sio2", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w)); // SIO 2 for user 3 & 4
85 	map(0x28, 0x2b).rw("sio6", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w)); // SIO 6 for user 11 & 12
86 	map(0x30, 0x33).rw("sio3", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w)); // SIO 3 for user 5 & 6
87 	map(0x38, 0x3b).rw("sio7", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w)); // SIO 7 for user 13 & 14
88 	map(0x40, 0x43).rw("sio4", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w)); // SIO 4 for user 7 & 8
89 	map(0x48, 0x4b).rw("sio8", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w)); // SIO 8 for user 15 & 16
90 	//map(0x50, 0x53) // SIO 0 for RS232 1 and part of tape interface
91 	map(0x50, 0x50).r(FUNC(ts816_state::keyin_r)).w(m_terminal, FUNC(generic_terminal_device::write));
92 	map(0x52, 0x52).r(FUNC(ts816_state::status_r));
93 	map(0x58, 0x5b).rw("sio9", FUNC(z80sio_device::cd_ba_r), FUNC(z80sio_device::cd_ba_w)); // SIO 9 for RS232 2 & 3
94 	map(0x60, 0x60).portr("DSW");
95 	map(0x68, 0x68).w(FUNC(ts816_state::port68_w)); // set 2nd bank latch
96 	map(0x70, 0x78).w(FUNC(ts816_state::port78_w)); // reset 2nd bank latch (manual can't decide between 70 and 78, so we take both)
97 	map(0x80, 0x83).rw("ctc1", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write)); // CTC 1 (ch 0 baud A)
98 	map(0x90, 0x93).rw("dma", FUNC(z80dma_device::read), FUNC(z80dma_device::write)); // DMA
99 	map(0xA0, 0xA0); // WDC status / command
100 	map(0xA1, 0xA1); // WDC data
101 	map(0xB0, 0xB0).noprw(); // undocumented, written to at @0707 and @0710
102 	map(0xC0, 0xC3).rw("ctc2", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write)); // CTC 2 (ch 0 baud B, ch 1 baud C)
103 	map(0xD0, 0xD3).rw("pio", FUNC(z80pio_device::read), FUNC(z80pio_device::write));
104 	map(0xE0, 0xE0).w(FUNC(ts816_state::porte0_w)); // set ENDRAM memory banking
105 	map(0xF0, 0xF0).w(FUNC(ts816_state::portf0_w)); // reset ENDRAM memory banking
106 }
107 
108 
109 /* Input ports */
110 static INPUT_PORTS_START( ts816 )
111 	PORT_START("DSW") //
112 	PORT_DIPNAME( 0x07, 0x01, "System Terminal") // read at @0368
113 	PORT_DIPSETTING(    0x00, "19200 baud")
114 	PORT_DIPSETTING(    0x01, "9600 baud")
115 	PORT_DIPSETTING(    0x02, "4800 baud")
116 	PORT_DIPSETTING(    0x03, "2400 baud")
117 	PORT_DIPSETTING(    0x04, "1200 baud")
118 	PORT_DIPSETTING(    0x05, "600 baud")
119 	PORT_DIPSETTING(    0x06, "300 baud")
120 	PORT_DIPSETTING(    0x07, "150 baud")
121 	PORT_DIPNAME( 0x80, 0x00, "Operation Switch") // this switch checked @006F (undocumented)
DEF_STR(On)122 	PORT_DIPSETTING(    0x80, DEF_STR(On))
123 	PORT_DIPSETTING(    0x00, DEF_STR(Off))
124 INPUT_PORTS_END
125 
126 
127 uint8_t ts816_state::keyin_r()
128 {
129 	uint8_t ret = m_term_data;
130 	m_term_data = 0;
131 	return ret;
132 }
133 
status_r()134 uint8_t ts816_state::status_r()
135 {
136 	if (m_status)
137 	{
138 		m_status--;
139 		return 5;
140 	}
141 	else
142 		return 4;
143 }
144 
port68_w(uint8_t data)145 void ts816_state::port68_w(uint8_t data)
146 {
147 	m_2ndbank = 1;
148 	set_banks();
149 }
150 
port78_w(uint8_t data)151 void ts816_state::port78_w(uint8_t data)
152 {
153 	m_2ndbank = 0;
154 	set_banks();
155 }
156 
porte0_w(uint8_t data)157 void ts816_state::porte0_w(uint8_t data)
158 {
159 	m_endram = 1;
160 	set_banks();
161 }
162 
portf0_w(uint8_t data)163 void ts816_state::portf0_w(uint8_t data)
164 {
165 	m_endram = 0;
166 	set_banks();
167 }
168 
set_banks()169 void ts816_state::set_banks()
170 {
171 	if (!m_2ndbank)
172 	{
173 		if (!m_endram)
174 		{
175 			// bootup setting
176 			membank("bankr0")->set_entry(2); // point at rom
177 			membank("bankw0")->set_entry(0);
178 			membank("bank1")->set_entry(0);
179 			membank("bank2")->set_entry(0);
180 		}
181 		else
182 		{
183 			// 64k ram (lower half)
184 			membank("bankr0")->set_entry(0);
185 			membank("bankw0")->set_entry(0);
186 			membank("bank1")->set_entry(0);
187 			membank("bank2")->set_entry(0);
188 		}
189 	}
190 	else
191 	{
192 		if (!m_endram)
193 		{
194 			// not documented, so assuming roms with ram (upper half)
195 			membank("bankr0")->set_entry(2);
196 			membank("bankw0")->set_entry(1);
197 			membank("bank1")->set_entry(1);
198 			membank("bank2")->set_entry(1);
199 		}
200 		else
201 		{
202 			// split of upper and lower ram (not documented if ram has a new address, assuming not)
203 			membank("bankr0")->set_entry(1);
204 			membank("bankw0")->set_entry(1);
205 			membank("bank1")->set_entry(1);
206 			membank("bank2")->set_entry(0);
207 		}
208 	}
209 }
210 
kbd_put(u8 data)211 void ts816_state::kbd_put(u8 data)
212 {
213 	m_term_data = data;
214 	m_status = 3;
215 }
216 
machine_reset()217 void ts816_state::machine_reset()
218 {
219 	m_2ndbank = 0;
220 	m_endram = 0;
221 	m_term_data = 0;
222 	m_status = 1;
223 	set_banks();
224 	m_maincpu->reset();
225 }
226 
227 // correct order yet to be determined
228 static const z80_daisy_config daisy_chain[] =
229 {
230 	{ "dma" },
231 	{ "pio" },
232 	{ "ctc1" },
233 	{ "ctc2" },
234 //  { "sio0" },
235 	{ "sio1" },
236 	{ "sio2" },
237 	{ "sio3" },
238 	{ "sio4" },
239 	{ "sio5" },
240 	{ "sio6" },
241 	{ "sio7" },
242 	{ "sio8" },
243 	{ "sio9" },
244 	{ nullptr }
245 };
246 
init_ts816()247 void ts816_state::init_ts816()
248 {
249 	uint8_t *roms = memregion("roms")->base();
250 	uint8_t *rams = memregion("rams")->base();
251 
252 	// 0000-3FFF
253 	membank("bankr0")->configure_entry(2, &roms[0x00000]); // roms
254 	membank("bankr0")->configure_entry(0, &rams[0x00000]);
255 	membank("bankr0")->configure_entry(1, &rams[0x10000]);
256 	membank("bankw0")->configure_entry(0, &rams[0x00000]);
257 	membank("bankw0")->configure_entry(1, &rams[0x10000]);
258 	// 4000-DFFF
259 	membank("bank1")->configure_entry(0, &rams[0x04000]);
260 	membank("bank1")->configure_entry(1, &rams[0x14000]);
261 	// E000-FFFF
262 	membank("bank2")->configure_entry(0, &rams[0x0e000]);
263 	membank("bank2")->configure_entry(1, &rams[0x1e000]);
264 }
265 
ts816(machine_config & config)266 void ts816_state::ts816(machine_config &config)
267 {
268 	/* basic machine hardware */
269 	Z80(config, m_maincpu, XTAL(16'000'000) / 4);
270 	m_maincpu->set_addrmap(AS_PROGRAM, &ts816_state::ts816_mem);
271 	m_maincpu->set_addrmap(AS_IO, &ts816_state::ts816_io);
272 	m_maincpu->set_daisy_config(daisy_chain);
273 
274 	/* video hardware */
275 	GENERIC_TERMINAL(config, m_terminal, 0);
276 	m_terminal->set_keyboard_callback(FUNC(ts816_state::kbd_put));
277 
278 	//z80sio_device& sio0(Z80SIO(config, "sio0", XTAL(16'000'000) / 4));
279 	//sio0.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
280 	z80sio_device& sio1(Z80SIO(config, "sio1", XTAL(16'000'000) / 4));
281 	sio1.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
282 	z80sio_device& sio2(Z80SIO(config, "sio2", XTAL(16'000'000) / 4));
283 	sio2.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
284 	z80sio_device& sio3(Z80SIO(config, "sio3", XTAL(16'000'000) / 4));
285 	sio3.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
286 	z80sio_device& sio4(Z80SIO(config, "sio4", XTAL(16'000'000) / 4));
287 	sio4.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
288 	z80sio_device& sio5(Z80SIO(config, "sio5", XTAL(16'000'000) / 4));
289 	sio5.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
290 	z80sio_device& sio6(Z80SIO(config, "sio6", XTAL(16'000'000) / 4));
291 	sio6.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
292 	z80sio_device& sio7(Z80SIO(config, "sio7", XTAL(16'000'000) / 4));
293 	sio7.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
294 	z80sio_device& sio8(Z80SIO(config, "sio8", XTAL(16'000'000) / 4));
295 	sio8.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
296 	z80sio_device& sio9(Z80SIO(config, "sio9", XTAL(16'000'000) / 4));
297 	sio9.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
298 
299 	z80pio_device& pio(Z80PIO(config, "pio", XTAL(16'000'000) / 4));
300 	pio.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
301 	//pio.in_pa_callback().set(FUNC(ts816_state::porta_r));
302 	//pio.in_pb_callback().set(FUNC(ts816_state::portb_r));
303 	//pio.out_pb_callback().set(FUNC(ts816_state::portb_w));
304 
305 	z80ctc_device& ctc1(Z80CTC(config, "ctc1", XTAL(16'000'000) / 4));
306 	ctc1.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
307 
308 	z80ctc_device& ctc2(Z80CTC(config, "ctc2", XTAL(16'000'000) / 4));
309 	ctc2.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
310 
311 	z80dma_device& dma(Z80DMA(config, "dma", XTAL(16'000'000) / 4));
312 	//dma.out_busreq_callback().set(FUNC(ts816_state::busreq_w));
313 	dma.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
314 }
315 
316 /* ROM definition */
317 ROM_START( ts816 )
318 	ROM_REGION(0x4000, "roms", 0)
319 	ROM_LOAD( "81640v11.rom", 0x0000, 0x1000, BAD_DUMP CRC(295a15e7) SHA1(6f49078ab3cd49aecd2afafcbed3af0e3bcfd48c) ) // both halves identical
320 
321 	ROM_REGION(0x20000, "rams", ROMREGION_ERASEFF)
322 ROM_END
323 
324 /* Driver */
325 
326 //    YEAR  NAME   PARENT  COMPAT  MACHINE  INPUT  STATE        INIT        COMPANY      FULLNAME  FLAGS
327 COMP( 1980, ts816, 0,      0,      ts816,   ts816, ts816_state, init_ts816, "Televideo", "TS816",  MACHINE_IS_SKELETON )
328