summaryrefslogtreecommitdiffstats
path: root/src/mame/drivers/pes.cpp
blob: 3728fe719c3a4e09374f08a1e12ca1b4ac003fe3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// license:BSD-3-Clause
// copyright-holders:Jonathan Gevaryahu
/******************************************************************************
*
*  Pacific Educational Systems 'PES' Speech box
*  Part number VPU-1 V1
*  By Kevin 'kevtris' Horton and Jonathan Gevaryahu AKA Lord Nightmare
*
*  Pacific Educational Systems, 915 Woodhall Drive, Victoria, Canada.
*
*  RE work done by Kevin Horton and Jonathan Gevaryahu
*
*  DONE:
*  compiles correctly
*  rom loads correctly
*  interface with tms5220 is done
*  rts and cts bits are stored in struct
*  serial is attached to terminal
*
*  TODO:
*  serial receive clear should happen after delay of one cpu cycle, not ASSERT and then CLEAR immediately after
*  figure out how to attach serial to external socket
*
***********************************************************************
This is almost as simple as hardware gets from the digital side:
Hardware consists of:
10.245Mhz xtal
80c31 cpu/mcu
27c64 rom (holds less than 256 bytes of code)
unpopulated 6164 sram, which isn't used
TSP5220C speech chip (aka tms5220c)
mc145406 RS232 driver/receiver (+-24v to 0-5v converter for serial i/o)
74hc573b1 octal tri-state D-latch (part of bus interface for ROM)
74hc74b1 dual d-flipflop with set/reset, positive edge trigger (?)
74hc02b1 quad 2-input NOR gate (wired up to decode address 0, and data 0 and 1 to produce /RS and /WS)
mc14520b dual 4-bit binary up counter (used as a chopper for the analog filter)
Big messy analog section to allow voice output to be filtered extensively by a 4th order filter

Address map:
80C31 ADDR:
  0000-1FFF: ROM
  2000-3FFF: open bus (would be ram)
  4000-ffff: open bus
80C31 IO:
  00 W: d0 and d1 are the /RS and /WS bits
  port 1.x: tms5220 bus
  port 2.x: unused
  port 3.0: RxD serial receive
  port 3.1: TxD serial send
  port 3.2: read, from /INT on tms5220c
  port 3.3: read, from /READY on tms5220c
  port 3.4: read, from the serial RTS line
  port 3.5: read/write, to the serial CTS line, inverted (effectively /CTS)
  port 3.6: write, /WR (general) and /WE (pin 27) for unpopulated 6164 SRAM
  port 3.7: write, /RD (general) and /OE (pin 22) for unpopulated 6164 SRAM


Current status:
- bios 0 : working. Hold down various letters for fragments of sound. g makes a beep. Status is reflected on the screen (eg space,@,`).
- bios 1 : working as above, however it does not get the tms5220 status and it does not write to the screen.

*/

#include "emu.h"
#include "cpu/mcs51/mcs51.h"
#include "sound/tms5220.h"
#include "machine/terminal.h"
#include "speaker.h"


class pes_state : public driver_device
{
public:
	pes_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag)
		, m_maincpu(*this, "maincpu")
		, m_terminal(*this, "terminal")
		, m_speech(*this, "tms5220")
	{ }

	void pes(machine_config &config);

private:

	u8 m_term_data;
	u8 m_port3;
	virtual void machine_reset() override;
	void port3_w(u8 data);
	u8 port3_r();
	void kbd_put(u8 data);
	void io_map(address_map &map);
	void prg_map(address_map &map);
	required_device<i80c31_device> m_maincpu;
	required_device<generic_terminal_device> m_terminal;
	required_device<tms5220_device> m_speech;
};



/* Devices */
void pes_state::kbd_put(u8 data)
{
	m_maincpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE);
	m_maincpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE);
	m_term_data = data;
}


/* Port Handlers */
void pes_state::port3_w(u8 data)
{
	m_port3 = data;
#if 0
	logerror("port3 write: control data written: %02X; ", data);
	logerror("RXD: %d; ", BIT(data,0));
	logerror("TXD: %d; ", BIT(data,1));
	logerror("/INT: %d; ", BIT(data,2));
	logerror("/RDY: %d; ", BIT(data,3));
	logerror("RTS: %d; ", BIT(data,4));
	logerror("CTS: %d; ", BIT(data,5));
	logerror("WR: %d; ", BIT(data,6));
	logerror("RD: %d;\n", BIT(data,7));
#endif
	// todo: poke serial handler here somehow?
}

u8 pes_state::port3_r()
{
	uint8_t data = m_port3 & 0xE3; // return last written state with rts, /rdy and /int masked out
	// check rts state; if virtual fifo is nonzero, rts is set, otherwise it is cleared
	//data |= 0x10; // set RTS bit
	data |= (m_speech->intq_r()<<2);
	data |= (m_speech->readyq_r()<<3);
	return data;
}


/* Reset */
void pes_state::machine_reset()
{
	m_port3 = 0; // reset the openbus state of port 3
	m_speech->reset(); // reset the 5220
}


/******************************************************************************
 Address Maps
******************************************************************************/

void pes_state::prg_map(address_map &map)
{
	map.unmap_value_high();
	map(0x0000, 0x1fff).rom(); /* 27C64 ROM */
	// map(0x2000, 0x3fff).ram(); /* 6164 8k SRAM, not populated */
}

void pes_state::io_map(address_map &map)
{
	map(0x0000, 0x0000).w(m_speech, FUNC(tms5220_device::combined_rsq_wsq_w)); // /WS(0) and /RS(1)
}

/******************************************************************************
 Input Ports
******************************************************************************/
static INPUT_PORTS_START( pes )
INPUT_PORTS_END

/******************************************************************************
 Machine Drivers
******************************************************************************/

void pes_state::pes(machine_config &config)
{
	/* basic machine hardware */
	I80C31(config, m_maincpu, XTAL(10'245'000));
	m_maincpu->set_addrmap(AS_PROGRAM, &pes_state::prg_map);
	m_maincpu->set_addrmap(AS_IO, &pes_state::io_map);
	m_maincpu->port_in_cb<1>().set(m_speech, FUNC(tms5220_device::status_r));
	m_maincpu->port_out_cb<1>().set(m_speech, FUNC(tms5220_device::data_w));
	m_maincpu->port_in_cb<3>().set(FUNC(pes_state::port3_r));
	m_maincpu->port_out_cb<3>().set(FUNC(pes_state::port3_w));
	m_maincpu->serial_tx_cb().set(m_terminal, FUNC(generic_terminal_device::write));
	m_maincpu->serial_rx_cb().set([this] () { return m_term_data; });

	/* sound hardware */
	SPEAKER(config, "mono").front_center();
	TMS5220C(config, m_speech, 720000); /* 720Khz clock, 9khz sample-rate, adjustable with 10-turn trimpot */
	m_speech->add_route(ALL_OUTPUTS, "mono", 1.0);

	GENERIC_TERMINAL(config, m_terminal, 0);
	m_terminal->set_keyboard_callback(FUNC(pes_state::kbd_put));
}

/******************************************************************************
 ROM Definitions
******************************************************************************/
ROM_START( pes )
	ROM_REGION( 0x10000, "maincpu", 0 )
	ROM_DEFAULT_BIOS("kevbios")
	ROM_SYSTEM_BIOS( 0, "orig", "PES box with original firmware v2.5")
	ROMX_LOAD( "vpu_2-5.bin",   0x0000, 0x2000, CRC(b27cfdf7) SHA1(c52acf9c080823de5ef26ac55abe168ad53a7d38), ROM_BIOS(0)) // original firmware, rather buggy, 4800bps serial, buggy RTS/CTS flow control, no buffer
	ROM_SYSTEM_BIOS( 1, "kevbios", "PES box with kevtris' rewritten firmware")
	ROMX_LOAD( "pes.bin",   0x0000, 0x2000, CRC(22c1c4ec) SHA1(042e139cd0cf6ffafcd88904f1636c6fa1b38f25), ROM_BIOS(1)) // rewritten firmware by kevtris, 4800bps serial, RTS/CTS plus XON/XOFF flow control, 64 byte buffer
ROM_END

/******************************************************************************
 Drivers
******************************************************************************/

//    YEAR  NAME  PARENT  COMPAT  MACHINE  INPUT  CLASS      INIT        COMPANY                        FULLNAME             FLAGS
COMP( 1987, pes,  0,      0,      pes,     pes,   pes_state, empty_init, "Pacific Educational Systems", "VPU-01 Speech box", 0 )