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

    audio\skydiver.c

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


/************************************************************************/
/* skydiver Sound System Analog emulation                               */
/* Jan 2004, Derrick Renaud                                             */
/************************************************************************/

static const discrete_555_desc skydiverWhistl555 =
{
	DISC_555_OUT_SQW | DISC_555_OUT_AC,
	5,      // B+ voltage of 555
	DEFAULT_555_VALUES
};

static const discrete_lfsr_desc skydiver_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 */
	DISC_LFSR_FLAG_OUT_INVERT,  /* Output is inverted, Active Low Reset */
	15                      /* Output bit */
};

/* Nodes - Sounds */
#define SKYDIVER_NOTE_SND       NODE_11
#define SKYDIVER_NOISE_SND      NODE_12
#define SKYDIVER_WHISTLE1_SND   NODE_13
#define SKYDIVER_WHISTLE2_SND   NODE_14

DISCRETE_SOUND_START(skydiver_discrete)
	/************************************************/
	/* skydiver  Effects Relative Gain Table        */
	/*                                              */
	/* Effect  V-ampIn  Gain ratio        Relative  */
	/* Note     3.8     3.8/260.5          1000.0   */
	/* Noise    3.8     3.8/680             383.1   */
	/* Whistle  5.0     5.0/1500            228.5   */
	/************************************************/

	/************************************************/
	/* Input register mapping for skydiver          */
	/************************************************/
	/*                    NODE                  GAIN        OFFSET  INIT */
	DISCRETE_INPUT_DATA  (SKYDIVER_RANGE_DATA)
	DISCRETE_INPUT_LOGIC (SKYDIVER_RANGE3_EN)
	DISCRETE_INPUT_DATA  (SKYDIVER_NOTE_DATA)
	DISCRETE_INPUTX_DATA (SKYDIVER_NOISE_DATA,  383.1/15.0, 0.0,    0.0)
	DISCRETE_INPUT_NOT   (SKYDIVER_NOISE_RST)
	DISCRETE_INPUT_LOGIC (SKYDIVER_WHISTLE1_EN)
	DISCRETE_INPUT_LOGIC (SKYDIVER_WHISTLE2_EN)
	DISCRETE_INPUT_LOGIC (SKYDIVER_OCT1_EN)
	DISCRETE_INPUT_LOGIC (SKYDIVER_OCT2_EN)
	DISCRETE_INPUT_LOGIC (SKYDIVER_SOUND_EN)
	/************************************************/

	/************************************************/
	/* The note generator has a selectable range    */
	/* and selectable frequency.                    */
	/* The base frequency is                        */
	/* 12.096MHz / 2 / range / note freq / 2        */
	/* The final /2 is just to give a 50% duty,     */
	/* so we can just start by 12.096MHz/4/range    */
	/* The octave is selected by 3 bits selecting   */
	/* 000 64H  = 12096MHz / 2 / 128                */
	/* 001 32H  = 12096MHz / 2 / 64                 */
	/* 010 16H  = 12096MHz / 2 / 32                 */
	/* 011  8H  = 12096MHz / 2 / 16                 */
	/* 100  4H  = 12096MHz / 2 / 8                  */
	/* 101  2H  = 12096MHz / 2 / 4                  */
	/* 110  1H  = 12096MHz / 2 / 2                  */
	/* 111 6MHz = 12096MHz / 2 / 1                  */
	/* We will convert the 3 range bits to a        */
	/* divide value in the driver before sending    */
	/* to the sound interface.                      */
	/*                                              */
	/* note data: 0xff = off,                       */
	/*            0xfe = /2,                        */
	/*            0x00 = /256                       */
	/* We will send the note data bit inverted to   */
	/* sound interface so it is easier to work with.*/
	/*                                              */
	/* The note generator is disabled by a low on   */
	/* RANGE3.                                      */
	/************************************************/
	// We will disable the divide if SKYDIVER_RANGE_DATA = 0
	DISCRETE_DIVIDE(NODE_20, SKYDIVER_RANGE_DATA, 12096000.0 /2.0 / 2.0, SKYDIVER_RANGE_DATA)
	DISCRETE_ADDER2(NODE_21, 1, SKYDIVER_NOTE_DATA, 1)
	// We will disable the divide if SKYDIVER_NOTE_DATA = 0
	DISCRETE_DIVIDE(NODE_22, SKYDIVER_NOTE_DATA, NODE_20, NODE_21)  // freq
	DISCRETE_SQUAREWAVE(SKYDIVER_NOTE_SND, SKYDIVER_RANGE3_EN, NODE_22, 1000.0, 50.0, 0, 0.0)

	/************************************************/
	/* Noise circuit is built around a noise        */
	/* generator built from 2 shift registers that  */
	/* are clocked by the 1V signal.                */
	/* 1V = HSYNC/2                                 */
	/*    = 15750/2                                 */
	/* Output is binary weighted with 4 bits of     */
	/* volume.                                      */
	/************************************************/
	DISCRETE_LFSR_NOISE(SKYDIVER_NOISE_SND, SKYDIVER_NOISE_RST, SKYDIVER_NOISE_RST, 15750.0/2.0, SKYDIVER_NOISE_DATA, 0, 0, &skydiver_lfsr)

	/************************************************/
	/* Whistle circuit is a 555 capacitor charge    */
	/* waveform.  The original game pot varies from */
	/* 0-250k, but we are going to limit it because */
	/* below 50k the frequency is too high.         */
	/* When triggered it starts at it's highest     */
	/* frequency, then decays at the rate set by    */
	/* a 68k resistor and 22uf capacitor.           */
	/************************************************/
	DISCRETE_ADJUSTMENT(NODE_30, 250000, 50000, DISC_LINADJ, "WHISTLE1")    /* R66 */
	DISCRETE_MULTADD(NODE_31, SKYDIVER_WHISTLE1_EN, 3.05-0.33, 0.33)
	DISCRETE_RCDISC2(NODE_32, SKYDIVER_WHISTLE1_EN, NODE_31, 1.0, NODE_31, 68000.0, 2.2e-5) /* CV */
	DISCRETE_SWITCH(NODE_33, 1, SKYDIVER_OCT1_EN, 1e-8, 1e-8 + 3.3e-9)  /* Cap C73 & C58 */
	DISCRETE_555_ASTABLE_CV(NODE_34, SKYDIVER_WHISTLE1_EN, 100000, NODE_30, NODE_33, NODE_32, &skydiverWhistl555)
	DISCRETE_MULTIPLY(SKYDIVER_WHISTLE1_SND, NODE_34, 228.5/3.3)

	DISCRETE_ADJUSTMENT(NODE_35, 250000, 50000, DISC_LINADJ, "WHISTLE2")    /* R65 */
	DISCRETE_MULTADD(NODE_36, SKYDIVER_WHISTLE2_EN, 3.05-0.33, 0.33)
	DISCRETE_RCDISC2(NODE_37, SKYDIVER_WHISTLE2_EN, NODE_36, 1.0, NODE_36, 68000.0, 2.2e-5) /* CV */
	DISCRETE_SWITCH(NODE_38, 1, SKYDIVER_OCT2_EN, 1e-8, 1e-8 + 3.3e-9)  /* Cap C72 & C59 */
	DISCRETE_555_ASTABLE_CV(NODE_39, SKYDIVER_WHISTLE2_EN, 100000, NODE_35, NODE_38, NODE_37, &skydiverWhistl555)
	DISCRETE_MULTIPLY(SKYDIVER_WHISTLE2_SND, NODE_39, 228.5/3.3)

	/************************************************/
	/* Final mix and output.                        */
	/************************************************/
	DISCRETE_ADDER4(NODE_90, SKYDIVER_SOUND_EN, SKYDIVER_NOTE_SND, SKYDIVER_NOISE_SND, SKYDIVER_WHISTLE1_SND, SKYDIVER_WHISTLE2_SND)

	DISCRETE_OUTPUT(NODE_90, 65534.0/(1000.0 + 383.1 + 228.5 + 228.5))
DISCRETE_SOUND_END