summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/orbit.cpp
blob: 2deacd5afb3ff194cae58f26c5471846106bc06b (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
// license:BSD-3-Clause
// copyright-holders:Derrick Renaud
/*************************************************************************

    audio\orbit.c

*************************************************************************/
#include "emu.h"
#include "includes/orbit.h"
#include "sound/discrete.h"

/*************************************
 *
 *  Write handlers
 *
 *************************************/

WRITE8_MEMBER(orbit_state::orbit_note_w)
{
	m_discrete->write(space, ORBIT_NOTE_FREQ, (~data) & 0xff);
}

WRITE8_MEMBER(orbit_state::orbit_note_amp_w)
{
	m_discrete->write(space, ORBIT_ANOTE1_AMP, data & 0x0f);
	m_discrete->write(space, ORBIT_ANOTE2_AMP, data >> 4);
}

WRITE8_MEMBER(orbit_state::orbit_noise_amp_w)
{
	m_discrete->write(space, ORBIT_NOISE1_AMP, data & 0x0f);
	m_discrete->write(space, ORBIT_NOISE2_AMP, data >> 4);
}

WRITE8_MEMBER(orbit_state::orbit_noise_rst_w)
{
	m_discrete->write(space, ORBIT_NOISE_EN, 0);
}


/************************************************************************/
/* orbit Sound System Analog emulation                                  */
/************************************************************************/

static const discrete_lfsr_desc orbit_lfsr =
{
	DISC_CLK_IS_FREQ,
	16,         /* Bit Length */
	0,          /* Reset Value */
	0,          /* Use Bit 0 as XOR input 0 */
	14,         /* Use Bit 14 as XOR input 1 */
	DISC_LFSR_XNOR,     /* Feedback stage1 is XNOR */
	DISC_LFSR_OR,       /* Feedback stage2 is just stage 1 output OR with external feed */
	DISC_LFSR_REPLACE,  /* Feedback stage3 replaces the shifted register contents */
	0x000001,       /* Everything is shifted into the first bit only */
	0,          /* Output is already inverted by XNOR */
	15          /* Output bit */
};

/* Nodes - Sounds */
#define ORBIT_NOISE         NODE_10
#define ORBIT_NOISE1_SND    NODE_11
#define ORBIT_NOISE2_SND    NODE_12
#define ORBIT_ANOTE1_SND    NODE_13
#define ORBIT_ANOTE2_SND    NODE_14
#define ORBIT_WARNING_SND   NODE_15

DISCRETE_SOUND_START(orbit)
	/************************************************/
	/* orbit  Effects Relataive Gain Table          */
	/*                                              */
	/* Effect  V-ampIn  Gain ratio        Relative  */
	/* Note     3.8     10/(20.1+.47+.55)   962.1   */
	/* Warning  3.8     10/(20.1+6.8)       755.4   */
	/* Noise    3.8     10/(20.1+.22)      1000.0   */
	/************************************************/

	/************************************************/
	/* Input register mapping for orbit             */
	/************************************************/
	/*                   NODE              GAIN      OFFSET  INIT */
	DISCRETE_INPUT_DATA (ORBIT_NOTE_FREQ)
	DISCRETE_INPUTX_DATA(ORBIT_ANOTE1_AMP, 962.1/15,  0,     0.0)
	DISCRETE_INPUTX_DATA(ORBIT_ANOTE2_AMP, 962.1/15,  0,     0.0)
	DISCRETE_INPUTX_DATA(ORBIT_NOISE1_AMP, 1000.0/15*10, 0,     0.0)
	DISCRETE_INPUTX_DATA(ORBIT_NOISE2_AMP, 1000.0/15*10, 0,     0.0)
	DISCRETE_INPUT_LOGIC(ORBIT_WARNING_EN)
	DISCRETE_INPUT_PULSE(ORBIT_NOISE_EN, 1)

	/************************************************/
	/* Warning is just a triggered 2V signal        */
	/************************************************/
	DISCRETE_SQUAREWFIX(ORBIT_WARNING_SND, ORBIT_WARNING_EN, 15750.0/4, 755.4, 50.0, 0, 0.0)

	/************************************************/
	/* Noise effect is variable amplitude, filtered */
	/* random noise.                                */
	/* LFSR clk = 32V= 15750.0Hz/2/32               */
	/************************************************/
	DISCRETE_LFSR_NOISE(ORBIT_NOISE, ORBIT_NOISE_EN, ORBIT_NOISE_EN, 15750.0/2/32, 1, 0, 0, &orbit_lfsr)
	DISCRETE_MULTIPLY(NODE_20, ORBIT_NOISE, ORBIT_NOISE1_AMP)
	DISCRETE_MULTIPLY(NODE_21, ORBIT_NOISE, ORBIT_NOISE2_AMP)
	DISCRETE_FILTER2(ORBIT_NOISE1_SND, 1, NODE_20, 160.0, (1.0 / 10.0), DISC_FILTER_BANDPASS)
	DISCRETE_FILTER2(ORBIT_NOISE2_SND, 1, NODE_21, 160.0, (1.0 / 10.0), DISC_FILTER_BANDPASS)

	/************************************************/
	/* Note sound is created by a divider circuit.  */
	/* The master clock is the 64H signal, which is */
	/* 12.096MHz/256.  This is then sent to a       */
	/* preloadable 8 bit counter, which loads the   */
	/* value from NOTELD when overflowing from 0xFF */
	/* to 0x00.  Therefore it divides by 2 (NOTELD  */
	/* = FE) to 256 (NOTELD = 00).                  */
	/* There is also a final /2 stage.              */
	/* Note that there is no music disable line.    */
	/* When there is no music, the game sets the    */
	/* oscillator to 0Hz.  (NOTELD = FF)            */
	/************************************************/
	DISCRETE_ADDER2(NODE_30, 1, ORBIT_NOTE_FREQ, 1) /* To get values of 1 - 256 */
	DISCRETE_DIVIDE(NODE_31, 1, 12096000.0/256/2, NODE_30)
	DISCRETE_SQUAREWAVE(ORBIT_ANOTE1_SND, ORBIT_NOTE_FREQ, NODE_31, ORBIT_ANOTE1_AMP, 50.0, 0, 0.0) /* NOTE=FF Disables audio */
	DISCRETE_SQUAREWAVE(ORBIT_ANOTE2_SND, ORBIT_NOTE_FREQ, NODE_31, ORBIT_ANOTE2_AMP, 50.0, 0, 0.0) /* NOTE=FF Disables audio */

	/************************************************/
	/* Final mix and output.                        */
	/************************************************/
	DISCRETE_ADDER3(NODE_90, 1, ORBIT_WARNING_SND, ORBIT_NOISE1_SND, ORBIT_ANOTE1_SND)
	DISCRETE_ADDER3(NODE_91, 1, ORBIT_WARNING_SND, ORBIT_NOISE2_SND, ORBIT_ANOTE2_SND)

	DISCRETE_OUTPUT(NODE_90, 65534.0/(962.1+755.4+1000.0))
	DISCRETE_OUTPUT(NODE_91, 65534.0/(962.1+755.4+1000.0))
DISCRETE_SOUND_END