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
|
// license:BSD-3-Clause
// copyright-holders:Joseph Zbiciak,Tim Lindner
/**********************************************************************
SP0256 Narrator Speech Processor emulation
**********************************************************************
_____ _____
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.
*/
#ifndef MAME_SOUND_SP0256_H
#define MAME_SOUND_SP0256_H
#pragma once
class sp0256_device : public device_t,
public device_sound_interface
{
public:
sp0256_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
auto data_request_callback() { return m_drq_cb.bind(); }
auto standby_callback() { return m_sby_cb.bind(); }
void ald_w(uint8_t data);
DECLARE_READ_LINE_MEMBER(lrq_r);
DECLARE_READ_LINE_MEMBER(sby_r);
uint16_t spb640_r(offs_t offset);
void spb640_w(offs_t offset, uint16_t data);
TIMER_CALLBACK_MEMBER(set_lrq_timer_proc);
void set_clock(int clock);
void bitrevbuff(uint8_t *buffer, unsigned int start, unsigned int length);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
private:
struct lpc12_t
{
int update(int num_samp, int16_t *out, uint32_t *optr);
void regdec();
int rpt, cnt; // Repeat counter, Period down-counter.
uint32_t per, rng; // Period, Amplitude, Random Number Generator
int amp;
int16_t f_coef[6]; // F0 through F5.
int16_t b_coef[6]; // B0 through B5.
int16_t z_data[6][2]; // Time-delay data for the filter stages.
uint8_t r[16]; // The encoded register set.
int interp;
private:
static int16_t limit(int16_t s);
};
uint32_t getb(int len);
void micro();
void SET_SBY(int line_state)
{
if (m_sby_line != line_state)
{
m_sby_line = line_state;
m_sby_cb(m_sby_line);
}
}
required_region_ptr<uint8_t> 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.
std::unique_ptr<int16_t[]> m_scratch; // Scratch buffer for audio.
uint32_t m_sc_head; // Head pointer into scratch circular buf
uint32_t m_sc_tail; // Tail pointer into scratch circular buf
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_t m_mode; // Mode register.
uint32_t m_page; // Page set by SETPAGE
uint32_t m_fifo_head; // FIFO head pointer (where new data goes).
uint32_t m_fifo_tail; // FIFO tail pointer (where data comes from).
uint32_t m_fifo_bitp; // FIFO bit-pointer (for partial decles).
uint16_t m_fifo[64]; // The 64-decle FIFO.
emu_timer *m_lrq_timer;
};
DECLARE_DEVICE_TYPE(SP0256, sp0256_device)
#endif // MAME_SOUND_SP0256_H
|