1 // license:BSD-3-Clause
2 // copyright-holders:Robbbert
3 /***************************************************************************
4 
5 HP Z80-based unknown in a large metal cage
6 
7 2012-05-25 Skeleton driver [Robbbert]
8 
9 http://www.classiccmp.org/hp/unknown Z80 computer/
10 
11 Looks like roms are in 2 banks in range C000-FFFF.
12 BASIC is included, if we can find out how to access it.
13 
14 Commands:
15 Axxxx         Disassemble (. to quit)
16 DAxxxx,yyyy   Ascii Dump of memory
17 DBxxxx,yyyy   Binary Dump of memory
18 DHxxxx,yyyy   Hex Dump of memory
19 DOxxxx,yyyy   Octal dump of memory
20 G
21 H
22 L
23 MMxxxx        Modify Memory (. to quit)
24 Pxx           Binary Display of Port
25 Pxx,xx        Write to port
26 RC            ???
27 RF            ???
28 RM            ???
29 RT            ???
30 UC            Displays 11111111
31 US            ???
32 UZ            Displays FFFF
33 W             Punch papertape
34 X             choose Q,V,R,P (Q to quit; others ask for ram and prom ranges)
35 Y nothing
36 Z nothing
37 
38     ToDo:
39     - Almost everything; there are a lot of I/O ports used
40     - Hook up rom banking
41 
42 ****************************************************************************/
43 
44 #include "emu.h"
45 #include "cpu/z80/z80.h"
46 #include "machine/ay31015.h"
47 #include "machine/clock.h"
48 #include "bus/rs232/rs232.h"
49 
50 
51 class hpz80unk_state : public driver_device
52 {
53 public:
hpz80unk_state(const machine_config & mconfig,device_type type,const char * tag)54 	hpz80unk_state(const machine_config &mconfig, device_type type, const char *tag)
55 		: driver_device(mconfig, type, tag)
56 		, m_maincpu(*this, "maincpu")
57 		, m_p_rom(*this, "rom")
58 		, m_uart(*this, "uart%u", 1)
59 	{ }
60 
61 	void hpz80unk(machine_config &config);
62 
63 private:
64 	u8 port00_r();
65 	u8 port02_r();
66 	u8 port03_r();
67 	u8 port0d_r();
68 	u8 portfc_r();
69 
70 	void io_map(address_map &map);
71 	void mem_map(address_map &map);
72 
73 	u8 m_port02_data;
74 	void machine_reset() override;
75 	void machine_start() override;
76 	required_device<cpu_device> m_maincpu;
77 	required_shared_ptr<u8> m_p_rom;
78 	required_device_array<ay51013_device, 3> m_uart;
79 };
80 
port00_r()81 u8 hpz80unk_state::port00_r()
82 {
83 	return (m_uart[0]->dav_r() << 1) | (m_uart[0]->tbmt_r()) | 0xfc;
84 }
85 
port02_r()86 u8 hpz80unk_state::port02_r()
87 {
88 	m_port02_data ^= 1;
89 	return m_port02_data;
90 }
91 
port03_r()92 u8 hpz80unk_state::port03_r()
93 {
94 	return (m_uart[1]->dav_r() << 1) | (m_uart[1]->tbmt_r()) | 0xfc;
95 }
96 
port0d_r()97 u8 hpz80unk_state::port0d_r()
98 {
99 	return (m_uart[2]->dav_r() << 1) | (m_uart[2]->tbmt_r()) | 0xfc;
100 }
101 
portfc_r()102 u8 hpz80unk_state::portfc_r()
103 {
104 	return 0xfe; // or it halts
105 }
106 
mem_map(address_map & map)107 void hpz80unk_state::mem_map(address_map &map)
108 {
109 	map.unmap_value_high();
110 	map(0x0000, 0xbfff).ram();
111 	map(0xc000, 0xffff).rom().share("rom");
112 }
113 
io_map(address_map & map)114 void hpz80unk_state::io_map(address_map &map)
115 {
116 	map.unmap_value_high();
117 	map.global_mask(0xff);
118 	map(0x00, 0x00).r(FUNC(hpz80unk_state::port00_r)); // uart1 status
119 	map(0x01, 0x01).rw("uart1", FUNC(ay31015_device::receive), FUNC(ay31015_device::transmit)); // uart1 data
120 	map(0x02, 0x02).r(FUNC(hpz80unk_state::port02_r));
121 	map(0x03, 0x03).r(FUNC(hpz80unk_state::port03_r)); // uart2 status
122 	map(0x04, 0x04).rw("uart2", FUNC(ay31015_device::receive), FUNC(ay31015_device::transmit)); // uart2 data
123 	map(0x0d, 0x0d).r(FUNC(hpz80unk_state::port0d_r)); // uart3 status
124 	map(0x0e, 0x0e).w("uart3", FUNC(ay31015_device::transmit)); // uart3 data
125 	map(0x1d, 0x1e); // top of memory is written here, big-endian
126 	map(0x1f, 0x1f).portr("DSW"); // select which uarts to use
127 	map(0xfc, 0xfc).r(FUNC(hpz80unk_state::portfc_r));
128 }
129 
130 /* Input ports */
131 static INPUT_PORTS_START( hpz80unk )
132 	// this is a theoretical switch
133 	PORT_START("DSW")
134 	PORT_DIPNAME( 0x03, 0x00, "UART selection")
135 	PORT_DIPSETTING(    0x00, "In UART1, Out UART1")
136 	PORT_DIPSETTING(    0x01, "In UART1, Out UART2")
137 	PORT_DIPSETTING(    0x02, "In UART1, Out UART3")
138 	PORT_DIPSETTING(    0x03, "In UART2, Out UART1")
139 INPUT_PORTS_END
140 
141 
machine_start()142 void hpz80unk_state::machine_start()
143 {
144 	save_item(NAME(m_port02_data));
145 }
146 
machine_reset()147 void hpz80unk_state::machine_reset()
148 {
149 	u8* user1 = memregion("user1")->base();
150 	memcpy((u8*)m_p_rom, user1, 0x4000);
151 	m_maincpu->set_pc(0xc000);
152 
153 	// no idea if these are hard-coded, or programmable
154 	for (auto &uart : m_uart)
155 	{
156 		uart->write_xr(0);
157 		uart->write_xr(1);
158 		uart->write_swe(0);
159 		uart->write_np(1);
160 		uart->write_tsb(0);
161 		uart->write_nb1(1);
162 		uart->write_nb2(1);
163 		uart->write_eps(1);
164 		uart->write_cs(1);
165 		uart->write_cs(0);
166 	}
167 
168 	// this should be rom/ram banking
169 }
170 
171 
hpz80unk(machine_config & config)172 void hpz80unk_state::hpz80unk(machine_config &config)
173 {
174 	/* basic machine hardware */
175 	Z80(config, m_maincpu, XTAL(4'000'000));
176 	m_maincpu->set_addrmap(AS_PROGRAM, &hpz80unk_state::mem_map);
177 	m_maincpu->set_addrmap(AS_IO, &hpz80unk_state::io_map);
178 
179 	AY51013(config, m_uart[0]); // COM2502
180 	m_uart[0]->read_si_callback().set("rs232a", FUNC(rs232_port_device::rxd_r));
181 	m_uart[0]->write_so_callback().set("rs232a", FUNC(rs232_port_device::write_txd));
182 	m_uart[0]->set_auto_rdav(true);
183 	RS232_PORT(config, "rs232a", default_rs232_devices, "terminal");
184 
185 	AY51013(config, m_uart[1]); // COM2502
186 	m_uart[1]->read_si_callback().set("rs232b", FUNC(rs232_port_device::rxd_r));
187 	m_uart[1]->write_so_callback().set("rs232b", FUNC(rs232_port_device::write_txd));
188 	m_uart[1]->set_auto_rdav(true);
189 	RS232_PORT(config, "rs232b", default_rs232_devices, nullptr);
190 
191 	AY51013(config, m_uart[2]); // COM2502
192 	m_uart[2]->read_si_callback().set("rs232c", FUNC(rs232_port_device::rxd_r));
193 	m_uart[2]->write_so_callback().set("rs232c", FUNC(rs232_port_device::write_txd));
194 	m_uart[2]->set_auto_rdav(true);
195 	RS232_PORT(config, "rs232c", default_rs232_devices, nullptr);
196 
197 	clock_device &uart_clock(CLOCK(config, "uart_clock", 153600));
198 	uart_clock.signal_handler().set(m_uart[0], FUNC(ay51013_device::write_tcp));
199 	uart_clock.signal_handler().append(m_uart[0], FUNC(ay51013_device::write_rcp));
200 	uart_clock.signal_handler().append(m_uart[1], FUNC(ay51013_device::write_tcp));
201 	uart_clock.signal_handler().append(m_uart[1], FUNC(ay51013_device::write_rcp));
202 	uart_clock.signal_handler().append(m_uart[2], FUNC(ay51013_device::write_tcp));
203 	uart_clock.signal_handler().append(m_uart[2], FUNC(ay51013_device::write_rcp));
204 }
205 
206 /* ROM definition */
207 ROM_START( hpz80unk )
208 	ROM_REGION( 0x8000, "user1", 0 )
209 	// 1st bank
210 	ROM_LOAD( "u1",        0x0000, 0x0800, CRC(080cd04a) SHA1(42004af65d44e3507a4e0f343c5bf385b6377c40) )
211 	ROM_LOAD( "u3",        0x0800, 0x0800, CRC(694075e1) SHA1(3db62645ade6a7f454b2d505aecc1661284c8ce2) )
212 	ROM_LOAD( "u5",        0x1000, 0x0800, CRC(5573bd05) SHA1(68c8f02b3fe9d77ecb83df407ca78430e118004a) )
213 	ROM_LOAD( "u7",        0x1800, 0x0800, CRC(d18a304a) SHA1(69dd0486bb6e4c2a22ab9da863bfb962016a321b) )
214 	ROM_LOAD( "u9",        0x2000, 0x0800, CRC(f7a8665c) SHA1(e39d0ba4ce2dc773622d411a25f40a6a24b45449) )
215 	ROM_LOAD( "u11",       0x2800, 0x0800, CRC(6c1ac77a) SHA1(50ca04ff0a11bd1c7d96f4731cef50978266ecca) )
216 	ROM_LOAD( "u13",       0x3000, 0x0800, CRC(8b166911) SHA1(4301dcd6840d37ccfa5bff998a0d88bebe99dc31) )
217 	ROM_LOAD( "u15",       0x3800, 0x0800, CRC(c6300499) SHA1(1b62d2a85c8f0b6a817e4be73ee34e0d90515c00) )
218 	// 2nd bank
219 	ROM_LOAD( "u2",        0x4000, 0x0800, CRC(080cd04a) SHA1(42004af65d44e3507a4e0f343c5bf385b6377c40) )
220 	ROM_LOAD( "u4",        0x4800, 0x0800, CRC(66c3745c) SHA1(d79fe764312a222ac64d325bf5f4abc7ca401d0f) )
221 	ROM_LOAD( "u6",        0x5000, 0x0800, CRC(80761b4c) SHA1(5f6a12fbba533308b9fe7067c67a836be436a6f0) )
222 	ROM_LOAD( "u8",        0x5800, 0x0800, CRC(64a2be18) SHA1(b11c08fdc9dc126038559462493f458ecdc78532) )
223 	ROM_LOAD( "u10",       0x6000, 0x0800, CRC(40244d09) SHA1(106f8f978de36df9f3ebbe1e2c959b60e53273a2) )
224 	ROM_LOAD( "u12",       0x6800, 0x0800, CRC(6eb01765) SHA1(66f9036a9f86cf3a79493330bbc06fb6932ab771) )
225 	ROM_LOAD( "u14",       0x7000, 0x0800, CRC(3410e682) SHA1(30d94c0c0b6478dab202a603edaccca943008e35) )
226 	ROM_LOAD( "u16",       0x7800, 0x0800, CRC(c03fdcab) SHA1(1081d787085add489c6e2a1d450e1a5790d18885) )
227 ROM_END
228 
229 /* Driver */
230 
231 //    YEAR  NAME      PARENT  COMPAT  MACHINE   INPUT     CLASS           INIT        COMPANY            FULLNAME                       FLAGS
232 COMP( 1977, hpz80unk, 0,      0,      hpz80unk, hpz80unk, hpz80unk_state, empty_init, "Hewlett-Packard", "unknown Z80-based mainframe", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE )
233