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
|
// license:GPL-2.0+
// copyright-holders:Joseph Zbiciak,Tim Lindner
/**********************************************************************
SP0256 Narrator Speech Processor emulation
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
**********************************************************************
_____ _____
Vss 1 |* \_/ | 28 OSC 2
_RESET 2 | | 27 OSC 1
ROM DISABLE 3 | | 26 ROM CLOCK
C1 4 | | 25 _SBY RESET
C2 5 | | 24 DIGITAL OUT
C3 6 | | 23 Vdi
Vdd 7 | SP0256 | 22 TEST
SBY 8 | | 21 SER IN
_LRQ 9 | | 20 _ALD
A8 10 | | 19 SE
A7 11 | | 18 A1
SER OUT 12 | | 17 A2
A6 13 | | 16 A3
A5 14 |_____________| 15 A4
**********************************************************************/
/*
GI SP0256 Narrator Speech Processor
By Joe Zbiciak. Ported to MESS by tim lindner.
Copyright Joseph Zbiciak, all rights reserved.
Copyright tim lindner, all rights reserved.
- This source code is released as freeware for non-commercial purposes.
- You are free to use and redistribute this code in modified or
unmodified form, provided you list us in the credits.
- If you modify this source code, you must add a notice to each
modified source file that it has been changed. If you're a nice
person, you will clearly mark each change too. :)
- If you wish to use this for commercial purposes, please contact us at
intvnut@gmail.com (Joe Zbiciak), tlindner@macmess.org (tim lindner)
- This entire notice must remain in the source code.
*/
#pragma once
#ifndef __SP0256_H__
#define __SP0256_H__
#define MCFG_SP0256_DATA_REQUEST_CB(_devcb) \
devcb = &sp0256_device::set_data_request_callback(*device, DEVCB_##_devcb);
#define MCFG_SP0256_STANDBY_CB(_devcb) \
devcb = &sp0256_device::set_standby_callback(*device, DEVCB_##_devcb);
struct lpc12_t
{
int rpt, cnt; /* Repeat counter, Period down-counter. */
UINT32 per, rng; /* Period, Amplitude, Random Number Generator */
int amp;
INT16 f_coef[6]; /* F0 through F5. */
INT16 b_coef[6]; /* B0 through B5. */
INT16 z_data[6][2]; /* Time-delay data for the filter stages. */
UINT8 r[16]; /* The encoded register set. */
int interp;
};
class sp0256_device : public device_t,
public device_sound_interface
{
public:
sp0256_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~sp0256_device() { }
template<class _Object> static devcb_base &set_data_request_callback(device_t &device, _Object object) { return downcast<sp0256_device &>(device).m_drq_cb.set_callback(object); }
template<class _Object> static devcb_base &set_standby_callback(device_t &device, _Object object) { return downcast<sp0256_device &>(device).m_sby_cb.set_callback(object); }
DECLARE_WRITE8_MEMBER(ald_w);
DECLARE_READ_LINE_MEMBER(lrq_r);
DECLARE_READ_LINE_MEMBER(sby_r);
DECLARE_READ16_MEMBER(spb640_r);
DECLARE_WRITE16_MEMBER(spb640_w);
TIMER_CALLBACK_MEMBER(set_lrq_timer_proc);
void set_clock(int clock);
void bitrevbuff(UINT8 *buffer, unsigned int start, unsigned int length);
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
private:
UINT32 getb(int len);
void micro();
required_region_ptr<UINT8> m_rom; /* 64K ROM. */
sound_stream *m_stream; /* MAME core sound stream */
devcb_write_line m_drq_cb; /* Data request callback */
devcb_write_line m_sby_cb; /* Standby callback */
int m_sby_line; /* Standby line state */
int m_cur_len; /* Fullness of current sound buffer. */
int m_silent; /* Flag: SP0256 is silent. */
INT16 *m_scratch; /* Scratch buffer for audio. */
UINT32 m_sc_head; /* Head pointer into scratch circular buf */
UINT32 m_sc_tail; /* Tail pointer into scratch circular buf */
struct lpc12_t m_filt; /* 12-pole filter */
int m_lrq; /* Load ReQuest. == 0 if we can accept a load */
int m_ald; /* Address LoaD. < 0 if no command pending. */
int m_pc; /* Microcontroller's PC value. */
int m_stack; /* Microcontroller's PC stack. */
int m_fifo_sel; /* True when executing from FIFO. */
int m_halted; /* True when CPU is halted. */
UINT32 m_mode; /* Mode register. */
UINT32 m_page; /* Page set by SETPAGE */
UINT32 m_fifo_head; /* FIFO head pointer (where new data goes). */
UINT32 m_fifo_tail; /* FIFO tail pointer (where data comes from). */
UINT32 m_fifo_bitp; /* FIFO bit-pointer (for partial decles). */
UINT16 m_fifo[64]; /* The 64-decle FIFO. */
emu_timer *m_lrq_timer;
};
extern const device_type SP0256;
#endif /* __SP0256_H__ */
|