1 /*
2  *  SPDX-License-Identifier: GPL-2.0-or-later
3  *
4  *  Copyright (C) 2020-2021  The DOSBox Staging Team
5  *  Copyright (C) 2002-2021  The DOSBox Team
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License along
18  *  with this program; if not, write to the Free Software Foundation, Inc.,
19  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 #include "dosbox.h"
23 
24 #include <array>
25 #include <iomanip>
26 #include <memory>
27 #include <string>
28 #include <unistd.h>
29 #include <vector>
30 
31 #include "control.h"
32 #include "dma.h"
33 #include "hardware.h"
34 #include "mixer.h"
35 #include "pic.h"
36 #include "setup.h"
37 #include "shell.h"
38 #include "soft_limiter.h"
39 #include "string_utils.h"
40 
41 #define LOG_GUS 0 // set to 1 for detailed logging
42 
43 // Global Constants
44 // ----------------
45 
46 // AdLib emulation state constant
47 constexpr uint8_t ADLIB_CMD_DEFAULT = 85u;
48 
49 // Buffer and memory constants
50 constexpr int BUFFER_FRAMES = 48;
51 constexpr uint32_t RAM_SIZE = 1024 * 1024;        // 1 MiB
52 
53 // DMA transfer size and rate constants
54 constexpr uint32_t BYTES_PER_DMA_XFER = 8 * 1024;         // 8 KiB per transfer
55 constexpr uint32_t ISA_BUS_THROUGHPUT = 32 * 1024 * 1024; // 32 MiB/s
56 constexpr uint16_t DMA_TRANSFERS_PER_S = ISA_BUS_THROUGHPUT / BYTES_PER_DMA_XFER;
57 constexpr double MS_PER_DMA_XFER = 1000.0 / DMA_TRANSFERS_PER_S;
58 
59 // Voice-channel and state related constants
60 constexpr uint8_t MAX_VOICES = 32u;
61 constexpr uint8_t MIN_VOICES = 14u;
62 constexpr uint8_t VOICE_DEFAULT_STATE = 3u;
63 
64 // DMA and IRQ extents and quantities
65 constexpr uint8_t MIN_DMA_ADDRESS = 0u;
66 constexpr uint8_t MAX_DMA_ADDRESS = 7u;
67 constexpr uint8_t MIN_IRQ_ADDRESS = 0u;
68 constexpr uint8_t MAX_IRQ_ADDRESS = 15u;
69 constexpr uint8_t DMA_IRQ_ADDRESSES = 8u; // number of IRQ and DMA channels
70 constexpr uint16_t DMA_TC_STATUS_BITMASK = 0b100000000; // Status in 9th bit
71 
72 // Pan position constants
73 constexpr uint8_t PAN_DEFAULT_POSITION = 7u;
74 constexpr uint8_t PAN_POSITIONS = 16u;  // 0: -45-deg, 7: centre, 15: +45-deg
75 
76 // Timer delay constants
77 constexpr double TIMER_1_DEFAULT_DELAY = 0.080;
78 constexpr double TIMER_2_DEFAULT_DELAY = 0.320;
79 
80 // Volume scaling and dampening constants
81 constexpr auto DELTA_DB = 0.002709201;     // 0.0235 dB increments
82 constexpr int16_t VOLUME_INC_SCALAR = 512; // Volume index increment scalar
83 constexpr uint16_t VOLUME_LEVELS = 4096u;
84 
85 // Interwave addressing constant
86 constexpr int16_t WAVE_WIDTH = 1 << 9; // Wave interpolation width (9 bits)
87 
88 // IO address quantities
89 constexpr uint8_t READ_HANDLERS = 8u;
90 constexpr uint8_t WRITE_HANDLERS = 9u;
91 
92 // A group of parameters defining the Gus's voice IRQ control that's also shared
93 // (as a reference) into each instantiated voice.
94 struct VoiceIrq {
95 	uint32_t vol_state = 0u;
96 	uint32_t wave_state = 0u;
97 	uint8_t status = 0u;
98 };
99 
100 // A group of parameters used in the Voice class to track the Wave and Volume
101 // controls.
102 struct VoiceCtrl {
103 	uint32_t &irq_state;
104 	int32_t start = 0;
105 	int32_t end = 0;
106 	int32_t pos = 0;
107 	int32_t inc = 0;
108 	uint16_t rate = 0;
109 	uint8_t state = VOICE_DEFAULT_STATE;
110 };
111 
112 // Collection types involving constant quantities
113 using address_array_t = std::array<uint8_t, DMA_IRQ_ADDRESSES>;
114 using autoexec_array_t = std::array<AutoexecObject, 2>;
115 using pan_scalars_array_t = std::array<AudioFrame, PAN_POSITIONS>;
116 using ram_array_t = std::array<uint8_t, RAM_SIZE>;
117 using read_io_array_t = std::array<IO_ReadHandleObject, READ_HANDLERS>;
118 using vol_scalars_array_t = std::array<float, VOLUME_LEVELS>;
119 using write_io_array_t = std::array<IO_WriteHandleObject, WRITE_HANDLERS>;
120 
121 // A Voice is used by the Gus class and instantiates 32 of these.
122 // Each voice represents a single "mono" render_buffer of audio having its own
123 // characteristics defined by the running program, such as:
124 //   - being 8bit or 16bit
125 //   - having a "position" along a left-right axis (panned)
126 //   - having its volume reduced by some amount (native-level down to 0)
127 //   - having start, stop, loop, and loop-backward controls
128 //   - informing the GUS DSP as to when an IRQ is needed to keep it playing
129 //
130 class Voice {
131 public:
132 	Voice(uint8_t num, VoiceIrq &irq) noexcept;
133 	void GenerateSamples(std::vector<float> &render_buffer,
134 	                     const ram_array_t &ram,
135 	                     const vol_scalars_array_t &vol_scalars,
136 	                     const pan_scalars_array_t &pan_scalars,
137 	                     uint16_t requested_frames);
138 
139 	uint8_t ReadVolState() const noexcept;
140 	uint8_t ReadWaveState() const noexcept;
141 	void ResetCtrls() noexcept;
142 	void WritePanPot(uint8_t pos) noexcept;
143 	void WriteVolRate(uint16_t rate) noexcept;
144 	void WriteWaveRate(uint16_t rate) noexcept;
145 	bool UpdateVolState(uint8_t state) noexcept;
146 	bool UpdateWaveState(uint8_t state) noexcept;
147 
148 	VoiceCtrl vol_ctrl;
149 	VoiceCtrl wave_ctrl;
150 
151 	uint32_t generated_8bit_ms = 0u;
152 	uint32_t generated_16bit_ms = 0u;
153 
154 private:
155 	Voice() = delete;
156 	Voice(const Voice &) = delete;            // prevent copying
157 	Voice &operator=(const Voice &) = delete; // prevent assignment
158 	bool CheckWaveRolloverCondition() noexcept;
159 	bool Is8Bit() const noexcept;
160 	float GetVolScalar(const vol_scalars_array_t &vol_scalars);
161 	float GetSample(const ram_array_t &ram) noexcept;
162 	int32_t PopWavePos() noexcept;
163 	float PopVolScalar(const vol_scalars_array_t &vol_scalars);
164 	float Read8BitSample(const ram_array_t &ram, int32_t addr) const noexcept;
165 	float Read16BitSample(const ram_array_t &ram, int32_t addr) const noexcept;
166 	uint8_t ReadCtrlState(const VoiceCtrl &ctrl) const noexcept;
167 	void IncrementCtrlPos(VoiceCtrl &ctrl, bool skip_loop) noexcept;
168 	bool UpdateCtrlState(VoiceCtrl &ctrl, uint8_t state) noexcept;
169 
170 	// Control states
171 	enum CTRL : uint8_t {
172 		RESET = 0x01,
173 		STOPPED = 0x02,
174 		DISABLED = RESET | STOPPED,
175 		BIT16 = 0x04,
176 		LOOP = 0x08,
177 		BIDIRECTIONAL = 0x10,
178 		RAISEIRQ = 0x20,
179 		DECREASING = 0x40,
180 	};
181 
182 	uint32_t irq_mask = 0u;
183 	uint8_t &shared_irq_status;
184 	uint8_t pan_position = PAN_DEFAULT_POSITION;
185 };
186 
187 static void GUS_TimerEvent(uint32_t t);
188 static void GUS_DMA_Event(uint32_t val);
189 
190 using voice_array_t = std::array<std::unique_ptr<Voice>, MAX_VOICES>;
191 
192 // The Gravis UltraSound GF1 DSP (classic)
193 // This class:
194 //   - Registers, receives, and responds to port address inputs, which are used
195 //     by the emulated software to configure and control the GUS card.
196 //   - Reads or provides audio samples via direct memory access (DMA)
197 //   - Provides shared resources to all of the Voices, such as the volume
198 //     reducing table, constant-power panning table, and IRQ states.
199 //   - Accumulates the audio from each active voice into a floating point
200 //     vector (the render_buffer), without resampling.
201 //   - Populates an autoexec line (ULTRASND=...) with its port, irq, and dma
202 //     addresses.
203 //
204 class Gus {
205 public:
206 	Gus(uint16_t port, uint8_t dma, uint8_t irq, const std::string &dir);
207 	virtual ~Gus();
208 	bool CheckTimer(size_t t);
209 	void PrintStats();
210 
211 	struct Timer {
212 		double delay = 0.0;
213 		uint8_t value = 0xff;
214 		bool has_expired = true;
215 		bool is_counting_down = false;
216 		bool is_masked = false;
217 		bool should_raise_irq = false;
218 	};
219 	Timer timer_one = {TIMER_1_DEFAULT_DELAY};
220 	Timer timer_two = {TIMER_2_DEFAULT_DELAY};
221 	bool PerformDmaTransfer();
222 
223 private:
224 	Gus() = delete;
225 	Gus(const Gus &) = delete;            // prevent copying
226 	Gus &operator=(const Gus &) = delete; // prevent assignment
227 
228 	void ActivateVoices(uint8_t requested_voices);
229 	void AudioCallback(uint16_t requested_frames);
230 	void BeginPlayback();
231 	void CheckIrq();
232 	void CheckVoiceIrq();
233 	uint32_t Dma8Addr() noexcept;
234 	uint32_t Dma16Addr() noexcept;
235 	void DmaCallback(DmaChannel *chan, DMAEvent event);
236 	void StartDmaTransfers();
237 	bool IsDmaPcm16Bit() noexcept;
238 	bool IsDmaXfer16Bit() noexcept;
239 	uint16_t ReadFromRegister();
240 	void PopulateAutoExec(uint16_t port, const std::string &dir);
241 	void PopulatePanScalars() noexcept;
242 	void PopulateVolScalars() noexcept;
243 	void PrepareForPlayback() noexcept;
244 	uint16_t ReadFromPort(io_port_t port, io_width_t width);
245 
246 	void RegisterIoHandlers();
247 	void Reset(uint8_t state);
248 	void SetLevelCallback(const AudioFrame &levels);
249 	void StopPlayback();
250 	void UpdateDmaAddress(uint8_t new_address);
251 	void UpdateWaveMsw(int32_t &addr) const noexcept;
252 	void UpdateWaveLsw(int32_t &addr) const noexcept;
253 	void WriteToPort(io_port_t port, io_val_t value, io_width_t width);
254 
255 	void WriteToRegister();
256 
257 	// Collections
258 	vol_scalars_array_t vol_scalars = {{}};
259 	std::vector<float> render_buffer = {};
260 	std::vector<int16_t> play_buffer = {};
261 	pan_scalars_array_t pan_scalars = {{}};
262 	ram_array_t ram = {{0u}};
263 	read_io_array_t read_handlers = {};   // std::functions
264 	write_io_array_t write_handlers = {}; // std::functions
265 	const address_array_t dma_addresses = {
266 	        {MIN_DMA_ADDRESS, 1, 3, 5, 6, MAX_IRQ_ADDRESS, 0, 0}};
267 	const address_array_t irq_addresses = {
268 	        {MIN_IRQ_ADDRESS, 2, 5, 3, 7, 11, 12, MAX_IRQ_ADDRESS}};
269 	voice_array_t voices = {{nullptr}};
270 	autoexec_array_t autoexec_lines = {};
271 
272 	// Struct and pointer members
273 	VoiceIrq voice_irq = {};
274 	SoftLimiter soft_limiter;
275 	Voice *target_voice = nullptr;
276 	DmaChannel *dma_channel = nullptr;
277 	mixer_channel_t audio_channel = nullptr;
278 	uint8_t &adlib_command_reg = adlib_commandreg;
279 
280 	// Port address
281 	io_port_t port_base = 0u;
282 
283 	// Voice states
284 	uint32_t active_voice_mask = 0u;
285 	uint16_t voice_index = 0u;
286 	uint8_t active_voices = 0u;
287 	uint8_t prev_logged_voices = 0u;
288 
289 	// Register and playback rate
290 	uint32_t dram_addr = 0u;
291 	uint32_t playback_rate = 0u;
292 	uint16_t register_data = 0u;
293 	uint8_t selected_register = 0u;
294 
295 	// Control states
296 	uint8_t mix_ctrl = 0x0b; // latches enabled, LINEs disabled
297 	uint8_t sample_ctrl = 0u;
298 	uint8_t timer_ctrl = 0u;
299 
300 	// DMA states
301 	uint16_t dma_addr = 0u;
302 	// dma_ctrl would normally be a uint8_t as real hardware uses 8 bits,
303 	// but we store the DMA terminal count status in the 9th bit
304 	uint16_t dma_ctrl = 0u;
305 	uint8_t dma1 = 0u; // playback DMA
306 	uint8_t dma2 = 0u; // recording DMA
307 
308 	// IRQ states
309 	uint8_t irq1 = 0u; // playback IRQ
310 	uint8_t irq2 = 0u; // MIDI IRQ
311 	uint8_t irq_status = 0u;
312 
313 	bool dac_enabled = false;
314 	bool irq_enabled = false;
315 	bool is_running = false;
316 	bool should_change_irq_dma = false;
317 };
318 
319 using namespace std::placeholders;
320 
321 // External Tie-in for OPL FM-audio
322 uint8_t adlib_commandreg = ADLIB_CMD_DEFAULT;
323 
324 static std::unique_ptr<Gus> gus = nullptr;
325 
Voice(uint8_t num,VoiceIrq & irq)326 Voice::Voice(uint8_t num, VoiceIrq &irq) noexcept
327         : vol_ctrl{irq.vol_state},
328           wave_ctrl{irq.wave_state},
329           irq_mask(1 << num),
330           shared_irq_status(irq.status)
331 {}
332 
333 /*
334 Gravis SDK, Section 3.11. Rollover feature:
335 	Each voice has a 'rollover' feature that allows an application to be notified
336 	when a voice's playback position passes over a particular place in DRAM.  This
337 	is very useful for getting seamless digital audio playback.  Basically, the GF1
338 	will generate an IRQ when a voice's current position is  equal to the end
339 	position.  However, instead of stopping or looping back to the start position,
340 	the voice will continue playing in the same direction.  This means that there
341 	will be no pause (or gap) in the playback.
342 
343 	Note that this feature is enabled/disabled through the voice's VOLUME control
344 	register (since there are no more bits available in the voice control
345 	registers).   A voice's loop enable bit takes precedence over the rollover. This
346 	means that if a voice's loop enable is on, it will loop when it hits the end
347 	position, regardless of the state of the rollover enable.
348 ---
349 Joh Campbell, maintainer of DOSox-X:
350 	Despite the confusing description above, that means that looping takes
351 	precedence over rollover. If not looping, then rollover means to fire the IRQ
352 	but keep moving. If looping, then fire IRQ and carry out loop behavior. Gravis
353 	Ultrasound Windows 3.1 drivers expect this behavior, else Windows WAVE output
354 	will not work correctly.
355 */
CheckWaveRolloverCondition()356 bool Voice::CheckWaveRolloverCondition() noexcept
357 {
358 	return (vol_ctrl.state & CTRL::BIT16) && !(wave_ctrl.state & CTRL::LOOP);
359 }
360 
IncrementCtrlPos(VoiceCtrl & ctrl,bool dont_loop_or_restart)361 void Voice::IncrementCtrlPos(VoiceCtrl &ctrl, bool dont_loop_or_restart) noexcept
362 {
363 	if (ctrl.state & CTRL::DISABLED)
364 		return;
365 	int32_t remaining = 0;
366 	if (ctrl.state & CTRL::DECREASING) {
367 		ctrl.pos -= ctrl.inc;
368 		remaining = ctrl.start - ctrl.pos;
369 	} else {
370 		ctrl.pos += ctrl.inc;
371 		remaining = ctrl.pos - ctrl.end;
372 	}
373 	// Not yet reaching a boundary
374 	if (remaining < 0)
375 		return;
376 
377 	// Generate an IRQ if requested
378 	if (ctrl.state & CTRL::RAISEIRQ) {
379 		ctrl.irq_state |= irq_mask;
380 	}
381 
382 	// Allow the current position to move beyond its limit
383 	if (dont_loop_or_restart)
384 		return;
385 
386 	// Should we loop?
387 	if (ctrl.state & CTRL::LOOP) {
388 		/* Bi-directional looping */
389 		if (ctrl.state & CTRL::BIDIRECTIONAL)
390 			ctrl.state ^= CTRL::DECREASING;
391 		ctrl.pos = (ctrl.state & CTRL::DECREASING)
392 		                   ? ctrl.end - remaining
393 		                   : ctrl.start + remaining;
394 	}
395 	// Otherwise, restart the position back to its start or end
396 	else {
397 		ctrl.state |= 1; // Stop the voice
398 		ctrl.pos = (ctrl.state & CTRL::DECREASING) ? ctrl.start : ctrl.end;
399 	}
400 	return;
401 }
402 
Is8Bit() const403 bool Voice::Is8Bit() const noexcept
404 {
405 	return !(wave_ctrl.state & CTRL::BIT16);
406 }
407 
GetSample(const ram_array_t & ram)408 float Voice::GetSample(const ram_array_t &ram) noexcept
409 {
410 	const int32_t pos = PopWavePos();
411 	const auto addr = pos / WAVE_WIDTH;
412 	const auto fraction = pos & (WAVE_WIDTH - 1);
413 	const bool should_interpolate = wave_ctrl.inc < WAVE_WIDTH && fraction;
414 	float sample = Is8Bit() ? Read8BitSample(ram, addr)
415 	                        : Read16BitSample(ram, addr);
416 	if (should_interpolate) {
417 		const auto next_addr = addr + 1;
418 		const float next_sample = Is8Bit() ? Read8BitSample(ram, next_addr)
419 		                                   : Read16BitSample(ram, next_addr);
420 		constexpr float WAVE_WIDTH_INV = 1.0 / WAVE_WIDTH;
421 		sample += (next_sample - sample) *
422 		          static_cast<float>(fraction) * WAVE_WIDTH_INV;
423 	}
424 	assert(sample >= static_cast<float>(MIN_AUDIO) &&
425 	       sample <= static_cast<float>(MAX_AUDIO));
426 	return sample;
427 }
428 
GenerateSamples(std::vector<float> & render_buffer,const ram_array_t & ram,const vol_scalars_array_t & vol_scalars,const pan_scalars_array_t & pan_scalars,const uint16_t requested_frames)429 void Voice::GenerateSamples(std::vector<float> &render_buffer,
430                             const ram_array_t &ram,
431                             const vol_scalars_array_t &vol_scalars,
432                             const pan_scalars_array_t &pan_scalars,
433                             const uint16_t requested_frames)
434 {
435 	if (vol_ctrl.state & wave_ctrl.state & CTRL::DISABLED)
436 		return;
437 
438 	// Setup our iterators and pan percents
439 	auto val = render_buffer.begin();
440 	const auto last_val = val + requested_frames * 2; // L * R channels
441 	assert(last_val <= render_buffer.end());
442 	const auto pan_scalar = pan_scalars.at(pan_position);
443 
444 	// Add the samples to the render_buffer, angled in L-R space
445 	while (val < last_val) {
446 		float sample = GetSample(ram);
447 		sample *= PopVolScalar(vol_scalars);
448 		*val++ += sample * pan_scalar.left;
449 		*val++ += sample * pan_scalar.right;
450 	}
451 	// Keep track of how many ms this voice has generated
452 	Is8Bit() ? generated_8bit_ms++ : generated_16bit_ms++;
453 }
454 
455 // Returns the current wave position and increments the position
456 // to the next wave position.
PopWavePos()457 int32_t Voice::PopWavePos() noexcept
458 {
459 	const int32_t current_pos = wave_ctrl.pos;
460 	IncrementCtrlPos(wave_ctrl, CheckWaveRolloverCondition());
461 	return current_pos;
462 }
463 
464 // Returns the current vol scalar and increments the volume control's position.
PopVolScalar(const vol_scalars_array_t & vol_scalars)465 float Voice::PopVolScalar(const vol_scalars_array_t &vol_scalars)
466 {
467 	// transform the current position into an index into the volume array
468 	const auto i = ceil_sdivide(vol_ctrl.pos, VOLUME_INC_SCALAR);
469 	IncrementCtrlPos(vol_ctrl, false); // don't check wave rollover
470 	return vol_scalars.at(static_cast<size_t>(i));
471 }
472 
473 // Read an 8-bit sample scaled into the 16-bit range, returned as a float
Read8BitSample(const ram_array_t & ram,const int32_t addr) const474 float Voice::Read8BitSample(const ram_array_t &ram, const int32_t addr) const noexcept
475 {
476 	const auto i = static_cast<size_t>(addr) & 0xfffffu;
477 	constexpr auto bits_in_16 = std::numeric_limits<int16_t>::digits;
478 	constexpr auto bits_in_8 = std::numeric_limits<int8_t>::digits;
479 	constexpr float to_16bit_range = 1 << (bits_in_16 - bits_in_8);
480 	return static_cast<int8_t>(ram.at(i)) * to_16bit_range;
481 }
482 
483 // Read a 16-bit sample returned as a float
Read16BitSample(const ram_array_t & ram,const int32_t addr) const484 float Voice::Read16BitSample(const ram_array_t &ram, const int32_t addr) const noexcept
485 {
486 	// Calculate offset of the 16-bit sample
487 	const auto lower = addr & 0b1100'0000'0000'0000'0000;
488 	const auto upper = addr & 0b0001'1111'1111'1111'1111;
489 	const auto i = static_cast<size_t>(lower | (upper << 1));
490 	return static_cast<int16_t>(host_readw(&ram.at(i)));
491 }
492 
ReadCtrlState(const VoiceCtrl & ctrl) const493 uint8_t Voice::ReadCtrlState(const VoiceCtrl &ctrl) const noexcept
494 {
495 	uint8_t state = ctrl.state;
496 	if (ctrl.irq_state & irq_mask)
497 		state |= 0x80;
498 	return state;
499 }
500 
ReadVolState() const501 uint8_t Voice::ReadVolState() const noexcept
502 {
503 	return ReadCtrlState(vol_ctrl);
504 }
505 
ReadWaveState() const506 uint8_t Voice::ReadWaveState() const noexcept
507 {
508 	return ReadCtrlState(wave_ctrl);
509 }
510 
ResetCtrls()511 void Voice::ResetCtrls() noexcept
512 {
513 	vol_ctrl.pos = 0u;
514 	UpdateVolState(0x1);
515 	UpdateWaveState(0x1);
516 	WritePanPot(PAN_DEFAULT_POSITION);
517 }
518 
UpdateCtrlState(VoiceCtrl & ctrl,uint8_t state)519 bool Voice::UpdateCtrlState(VoiceCtrl &ctrl, uint8_t state) noexcept
520 {
521 	const uint32_t orig_irq_state = ctrl.irq_state;
522 	// Manually set the irq
523 	if ((state & 0xa0) == 0xa0)
524 		ctrl.irq_state |= irq_mask;
525 	else
526 		ctrl.irq_state &= ~irq_mask;
527 
528 	// Always update the state
529 	ctrl.state = state & 0x7f;
530 
531 	// Indicate if the IRQ state changed
532 	return orig_irq_state != ctrl.irq_state;
533 }
534 
UpdateVolState(uint8_t state)535 bool Voice::UpdateVolState(uint8_t state) noexcept
536 {
537 	return UpdateCtrlState(vol_ctrl, state);
538 }
539 
UpdateWaveState(uint8_t state)540 bool Voice::UpdateWaveState(uint8_t state) noexcept
541 {
542 	return UpdateCtrlState(wave_ctrl, state);
543 }
544 
WritePanPot(uint8_t pos)545 void Voice::WritePanPot(uint8_t pos) noexcept
546 {
547 	constexpr uint8_t max_pos = PAN_POSITIONS - 1;
548 	pan_position = std::min(pos, max_pos);
549 }
550 
551 // Four volume-index-rate "banks" are available that define the number of
552 // volume indexes that will be incremented (or decremented, depending on the
553 // volume_ctrl value) each step, for a given voice.  The banks are:
554 //
555 // - 0 to 63, which defines single index increments,
556 // - 64 to 127 defines fractional index increments by 1/8th,
557 // - 128 to 191 defines fractional index increments by 1/64ths, and
558 // - 192 to 255 defines fractional index increments by 1/512ths.
559 //
560 // To ensure the smallest increment (1/512) effects an index change, we
561 // normalize all the volume index variables (including this) by multiplying by
562 // VOLUME_INC_SCALAR (or 512). Note that "index" qualifies all these variables
563 // because they are merely indexes into the vol_scalars[] array. The actual
564 // volume scalar value (a floating point fraction between 0.0 and 1.0) is never
565 // actually operated on, and is simply looked up from the final index position
566 // at the time of sample population.
WriteVolRate(uint16_t val)567 void Voice::WriteVolRate(uint16_t val) noexcept
568 {
569 	vol_ctrl.rate = val;
570 	constexpr uint8_t bank_lengths = 63u;
571 	const int pos_in_bank = val & bank_lengths;
572 	const int decimator = 1 << (3 * (val >> 6));
573 	vol_ctrl.inc = ceil_sdivide(pos_in_bank * VOLUME_INC_SCALAR, decimator);
574 
575 	// Sanity check the bounds of the incrementer
576 	assert(vol_ctrl.inc >= 0 && vol_ctrl.inc <= bank_lengths * VOLUME_INC_SCALAR);
577 }
578 
WriteWaveRate(uint16_t val)579 void Voice::WriteWaveRate(uint16_t val) noexcept
580 {
581 	wave_ctrl.rate = val;
582 	wave_ctrl.inc = ceil_udivide(val, 2u);
583 }
584 
Gus(uint16_t port,uint8_t dma,uint8_t irq,const std::string & ultradir)585 Gus::Gus(uint16_t port, uint8_t dma, uint8_t irq, const std::string &ultradir)
586         : render_buffer(BUFFER_FRAMES * 2), // 2 samples/frame, L & R channels
587           play_buffer(BUFFER_FRAMES * 2),   // 2 samples/frame, L & R channels
588           soft_limiter("GUS"),
589           port_base(port - 0x200u),
590           dma2(dma),
591           irq1(irq),
592           irq2(irq)
593 {
594 	// Create the internal voice channels
595 	for (uint8_t i = 0; i < MAX_VOICES; ++i) {
596 		voices.at(i) = std::make_unique<Voice>(i, voice_irq);
597 	}
598 
599 	RegisterIoHandlers();
600 
601 	// Register the Audio and DMA channels
602 	const auto mixer_callback = std::bind(&Gus::AudioCallback, this,
603 	                                      std::placeholders::_1);
604 	audio_channel = MIXER_AddChannel(mixer_callback, 1, "GUS");
605 
606 	// Let the mixer command adjust the GUS's internal amplitude level's
607 	const auto set_level_callback = std::bind(&Gus::SetLevelCallback, this, _1);
608 	audio_channel->RegisterLevelCallBack(set_level_callback);
609 
610 	UpdateDmaAddress(dma);
611 
612 	// Populate the volume, pan, and auto-exec arrays
613 	PopulateVolScalars();
614 	PopulatePanScalars();
615 	PopulateAutoExec(port, ultradir);
616 }
617 
ActivateVoices(uint8_t requested_voices)618 void Gus::ActivateVoices(uint8_t requested_voices)
619 {
620 	requested_voices = clamp(requested_voices, MIN_VOICES, MAX_VOICES);
621 	if (requested_voices != active_voices) {
622 		active_voices = requested_voices;
623 		assert(active_voices <= voices.size());
624 		active_voice_mask = 0xffffffffu >> (MAX_VOICES - active_voices);
625 		playback_rate = static_cast<uint32_t>(
626 		        round(1000000.0 / (1.619695497 * active_voices)));
627 		audio_channel->SetFreq(playback_rate);
628 	}
629 }
630 
SetLevelCallback(const AudioFrame & levels)631 void Gus::SetLevelCallback(const AudioFrame &levels)
632 {
633 	soft_limiter.UpdateLevels(levels, 1);
634 }
635 
AudioCallback(const uint16_t requested_frames)636 void Gus::AudioCallback(const uint16_t requested_frames)
637 {
638 	uint16_t generated_frames = 0;
639 	while (generated_frames < requested_frames) {
640 		const uint16_t frames = static_cast<uint16_t>(
641 		        std::min(BUFFER_FRAMES, requested_frames - generated_frames));
642 
643 		// Zero our buffer. The audio sequence for each active voice
644 		// will be accumulated one at a time by the buffer's elements.
645 		assert(frames <= render_buffer.size());
646 		const auto num_samples = frames * 2;
647 		std::fill_n(render_buffer.begin(), num_samples, 0.0f);
648 
649 		if (dac_enabled) {
650 			auto voice = voices.begin();
651 			const auto last_voice = voice + active_voices;
652 			while (voice < last_voice && *voice) {
653 				voice->get()->GenerateSamples(render_buffer,
654 				                              ram, vol_scalars,
655 				                              pan_scalars, frames);
656 				++voice;
657 			}
658 		}
659 		soft_limiter.Process(render_buffer, frames, play_buffer);
660 		audio_channel->AddSamples_s16(frames, play_buffer.data());
661 		CheckVoiceIrq();
662 		generated_frames += frames;
663 	}
664 }
665 
BeginPlayback()666 void Gus::BeginPlayback()
667 {
668 	dac_enabled = ((register_data & 0x200) != 0);
669 	irq_enabled = ((register_data & 0x400) != 0);
670 	audio_channel->Enable(true);
671 	if (prev_logged_voices != active_voices) {
672 		LOG_MSG("GUS: Activated %u voices at %u Hz", active_voices,
673 		        playback_rate);
674 		prev_logged_voices = active_voices;
675 	}
676 	is_running = true;
677 }
678 
CheckIrq()679 void Gus::CheckIrq()
680 {
681 	const bool should_interrupt = irq_status & (irq_enabled ? 0xff : 0x9f);
682 	const bool lines_enabled = mix_ctrl & 0x08;
683 	if (should_interrupt && lines_enabled)
684 		PIC_ActivateIRQ(irq1);
685 }
686 
CheckTimer(const size_t t)687 bool Gus::CheckTimer(const size_t t)
688 {
689 	auto &timer = t == 0 ? timer_one : timer_two;
690 	if (!timer.is_masked)
691 		timer.has_expired = true;
692 	if (timer.should_raise_irq) {
693 		irq_status |= 0x4 << t;
694 		CheckIrq();
695 	}
696 	return timer.is_counting_down;
697 }
698 
CheckVoiceIrq()699 void Gus::CheckVoiceIrq()
700 {
701 	irq_status &= 0x9f;
702 	const Bitu totalmask = (voice_irq.vol_state | voice_irq.wave_state) &
703 	                       active_voice_mask;
704 	if (!totalmask)
705 		return;
706 	if (voice_irq.vol_state)
707 		irq_status |= 0x40;
708 	if (voice_irq.wave_state)
709 		irq_status |= 0x20;
710 	CheckIrq();
711 	while (!(totalmask & 1ULL << voice_irq.status)) {
712 		voice_irq.status++;
713 		if (voice_irq.status >= active_voices)
714 			voice_irq.status = 0;
715 	}
716 }
717 
Dma8Addr()718 uint32_t Gus::Dma8Addr() noexcept
719 {
720 	return static_cast<uint32_t>(dma_addr << 4);
721 }
722 
Dma16Addr()723 uint32_t Gus::Dma16Addr() noexcept
724 {
725 	const auto lower = dma_addr & 0b0001'1111'1111'1111;
726 	const auto upper = dma_addr & 0b1100'0000'0000'0000;
727 	const auto combined = (lower << 1) | upper;
728 	return static_cast<uint32_t>(combined << 4);
729 }
730 
PerformDmaTransfer()731 bool Gus::PerformDmaTransfer()
732 {
733 	if (dma_channel->masked || !(dma_ctrl & 0x01))
734 		return false;
735 
736 #if LOG_GUS
737 	LOG_MSG("GUS DMA event: max %u bytes. DMA: tc=%u mask=0 cnt=%u",
738 	        BYTES_PER_DMA_XFER, dma_channel->tcount ? 1 : 0,
739 	        dma_channel->currcnt + 1);
740 #endif
741 
742 	const auto offset = IsDmaXfer16Bit() ? Dma16Addr() : Dma8Addr();
743 	const uint16_t desired = dma_channel->currcnt + 1;
744 
745 	// All of the operations below involve reading, writing, or skipping
746 	// starting at the offset for N-desired samples
747 	assert(static_cast<size_t>(offset) + desired <= ram.size());
748 
749 	// Copy samples via DMA from GUS memory
750 	if (dma_ctrl & 0x2) {
751 		dma_channel->Write(desired, &ram.at(offset));
752 	}
753 	// Skip DMA content
754 	else if (!(dma_ctrl & 0x80)) {
755 		dma_channel->Read(desired, &ram.at(offset));
756 	}
757 	// Copy samples via DMA into GUS memory
758 	else {
759 		//
760 		const auto samples = dma_channel->Read(desired, &ram.at(offset));
761 		auto ram_pos = ram.begin() + offset;
762 		const auto positions = samples *
763 		                       (static_cast<size_t>(dma_channel->DMA16) + 1u);
764 		const auto ram_pos_end = ram_pos + positions;
765 		// adjust our start and skip size if handling 16-bit
766 		ram_pos += IsDmaPcm16Bit() ? 1u : 0u;
767 		const auto skip = IsDmaPcm16Bit() ? 2u : 1u;
768 		assert(ram_pos >= ram.begin() && ram_pos <= ram_pos_end && ram_pos_end <= ram.end());
769 		while (ram_pos < ram_pos_end) {
770 			*ram_pos ^= 0x80;
771 			ram_pos += skip;
772 		}
773 	}
774 	// Raise the TC irq if needed
775 	if ((dma_ctrl & 0x20) != 0) {
776 		// We've hit the terminal count, so enable that bit
777 		dma_ctrl |= DMA_TC_STATUS_BITMASK;
778 		irq_status |= 0x80;
779 		CheckIrq();
780 		return false;
781 	}
782 	return true;
783 }
784 
IsDmaPcm16Bit()785 bool Gus::IsDmaPcm16Bit() noexcept
786 {
787 	return dma_ctrl & 0x40;
788 }
789 
IsDmaXfer16Bit()790 bool Gus::IsDmaXfer16Bit() noexcept
791 {
792 	// What bit-size should DMA memory be transferred as?
793 	// Mode PCM/DMA  Address Use-16  Note
794 	// 0x00   8/ 8   Any     No      Most DOS programs
795 	// 0x04   8/16   >= 4    Yes     16-bit if using High DMA
796 	// 0x04   8/16   < 4     No      8-bit if using Low DMA
797 	// 0x40  16/ 8   Any     No      Windows 3.1, Quake
798 	// 0x44  16/16   >= 4    Yes     Windows 3.1, Quake
799 	return (dma_ctrl & 0x4) && (dma1 >= 4);
800 }
801 
GUS_DMA_Event(uint32_t)802 static void GUS_DMA_Event(uint32_t)
803 {
804 	if (gus->PerformDmaTransfer())
805 		PIC_AddEvent(GUS_DMA_Event, MS_PER_DMA_XFER);
806 }
807 
StartDmaTransfers()808 void Gus::StartDmaTransfers()
809 {
810 	PIC_AddEvent(GUS_DMA_Event, MS_PER_DMA_XFER);
811 }
812 
DmaCallback(DmaChannel *,DMAEvent event)813 void Gus::DmaCallback(DmaChannel *, DMAEvent event)
814 {
815 	if (event == DMA_UNMASKED)
816 		StartDmaTransfers();
817 }
818 
PopulateAutoExec(uint16_t port,const std::string & ultradir)819 void Gus::PopulateAutoExec(uint16_t port, const std::string &ultradir)
820 {
821 	// Ensure our port and addresses will fit in our format widths
822 	// The config selection controls their actual values, so this is a
823 	// maximum-limit.
824 	assert(port < 0xfff);
825 	assert(dma1 < 10 && dma2 < 10);
826 	assert(irq1 < 10 && irq2 < 10);
827 
828 	// ULTRASND variable
829 	char set_ultrasnd[] = "@SET ULTRASND=HHH,D,D,I,I";
830 	safe_sprintf(set_ultrasnd,
831 	         "@SET ULTRASND=%x,%u,%u,%u,%u", port, dma1, dma2, irq1, irq2);
832 	LOG_MSG("GUS: %s", set_ultrasnd);
833 	autoexec_lines.at(0).Install(set_ultrasnd);
834 
835 	// ULTRADIR variable
836 	std::string dirline = "@SET ULTRADIR=" + ultradir;
837 	autoexec_lines.at(1).Install(dirline);
838 }
839 
840 // Generate logarithmic to linear volume conversion tables
PopulateVolScalars()841 void Gus::PopulateVolScalars() noexcept
842 {
843 	constexpr auto VOLUME_LEVEL_DIVISOR = 1.0 + DELTA_DB;
844 	double scalar = 1.0;
845 	auto volume = vol_scalars.end();
846 	// The last element starts at 1.0 and we divide downward to
847 	// the first element that holds zero, which is directly assigned
848 	// after the loop.
849 	while (volume != vol_scalars.begin()) {
850 		*(--volume) = static_cast<float>(scalar);
851 		scalar /= VOLUME_LEVEL_DIVISOR;
852 	}
853 	vol_scalars.front() = 0.0;
854 }
855 
856 /*
857 Constant-Power Panning
858 -------------------------
859 The GUS SDK describes having 16 panning positions (0 through 15)
860 with 0 representing the full-left rotation, 7 being the mid-point,
861 and 15 being the full-right rotation.  The SDK also describes
862 that output power is held constant through this range.
863 
864 	#!/usr/bin/env python3
865 	import math
866 	print(f'Left-scalar  Pot Norm.   Right-scalar | Power')
867 	print(f'-----------  --- -----   ------------ | -----')
868 	for pot in range(16):
869 		norm = (pot - 7.) / (7.0 if pot < 7 else 8.0)
870 		direction = math.pi * (norm + 1.0 ) / 4.0
871 		lscale = math.cos(direction)
872 		rscale = math.sin(direction)
873 		power = lscale * lscale + rscale * rscale
874 		print(f'{lscale:.5f} <~~~ {pot:2} ({norm:6.3f})'\
875 		      f' ~~~> {rscale:.5f} | {power:.3f}')
876 
877 	Left-scalar  Pot Norm.   Right-scalar | Power
878 	-----------  --- -----   ------------ | -----
879 	1.00000 <~~~  0 (-1.000) ~~~> 0.00000 | 1.000
880 	0.99371 <~~~  1 (-0.857) ~~~> 0.11196 | 1.000
881 	0.97493 <~~~  2 (-0.714) ~~~> 0.22252 | 1.000
882 	0.94388 <~~~  3 (-0.571) ~~~> 0.33028 | 1.000
883 	0.90097 <~~~  4 (-0.429) ~~~> 0.43388 | 1.000
884 	0.84672 <~~~  5 (-0.286) ~~~> 0.53203 | 1.000
885 	0.78183 <~~~  6 (-0.143) ~~~> 0.62349 | 1.000
886 	0.70711 <~~~  7 ( 0.000) ~~~> 0.70711 | 1.000
887 	0.63439 <~~~  8 ( 0.125) ~~~> 0.77301 | 1.000
888 	0.55557 <~~~  9 ( 0.250) ~~~> 0.83147 | 1.000
889 	0.47140 <~~~ 10 ( 0.375) ~~~> 0.88192 | 1.000
890 	0.38268 <~~~ 11 ( 0.500) ~~~> 0.92388 | 1.000
891 	0.29028 <~~~ 12 ( 0.625) ~~~> 0.95694 | 1.000
892 	0.19509 <~~~ 13 ( 0.750) ~~~> 0.98079 | 1.000
893 	0.09802 <~~~ 14 ( 0.875) ~~~> 0.99518 | 1.000
894 	0.00000 <~~~ 15 ( 1.000) ~~~> 1.00000 | 1.000
895 */
PopulatePanScalars()896 void Gus::PopulatePanScalars() noexcept
897 {
898 	int i = 0;
899 	auto pan_scalar = pan_scalars.begin();
900 	while (pan_scalar != pan_scalars.end()) {
901 		// Normalize absolute range [0, 15] to [-1.0, 1.0]
902 		const auto norm = (i - 7.0) / (i < 7 ? 7 : 8);
903 		// Convert to an angle between 0 and 90-degree, in radians
904 		const auto angle = (norm + 1) * M_PI / 4;
905 		pan_scalar->left = static_cast<float>(cos(angle));
906 		pan_scalar->right = static_cast<float>(sin(angle));
907 		++pan_scalar;
908 		++i;
909 		// DEBUG_LOG_MSG("GUS: pan_scalar[%u] = %f | %f", i,
910 		//               pan_scalar->left,
911 		//               pan_scalar->right);
912 	}
913 }
914 
PrepareForPlayback()915 void Gus::PrepareForPlayback() noexcept
916 {
917 	// Initialize the voice states
918 	for (auto &voice : voices)
919 		voice->ResetCtrls();
920 
921 	// Initialize the OPL emulator state
922 	adlib_command_reg = ADLIB_CMD_DEFAULT;
923 
924 	voice_irq = VoiceIrq{};
925 	timer_one = Timer{TIMER_1_DEFAULT_DELAY};
926 	timer_two = Timer{TIMER_2_DEFAULT_DELAY};
927 
928 	if (!is_running) {
929 		register_data = 0x100; // DAC/IRQ disabled
930 		is_running = true;
931 	}
932 }
933 
PrintStats()934 void Gus::PrintStats()
935 {
936 	// Aggregate stats from all voices
937 	uint32_t combined_8bit_ms = 0u;
938 	uint32_t combined_16bit_ms = 0u;
939 	uint32_t used_8bit_voices = 0u;
940 	uint32_t used_16bit_voices = 0u;
941 	for (const auto &voice : voices) {
942 		if (voice->generated_8bit_ms) {
943 			combined_8bit_ms += voice->generated_8bit_ms;
944 			used_8bit_voices++;
945 		}
946 		if (voice->generated_16bit_ms) {
947 			combined_16bit_ms += voice->generated_16bit_ms;
948 			used_16bit_voices++;
949 		}
950 	}
951 	const uint32_t combined_ms = combined_8bit_ms + combined_16bit_ms;
952 
953 	// Is there enough information to be meaningful?
954 	const auto peak = soft_limiter.GetPeaks();
955 	if (combined_ms < 10000u || (peak.left + peak.right) < 10 ||
956 	    !(used_8bit_voices + used_16bit_voices))
957 		return;
958 
959 	// Print info about the type of audio and voices used
960 	if (used_16bit_voices == 0u)
961 		LOG_MSG("GUS: Audio comprised of 8-bit samples from %u voices",
962 		        used_8bit_voices);
963 	else if (used_8bit_voices == 0u)
964 		LOG_MSG("GUS: Audio comprised of 16-bit samples from %u voices",
965 		        used_16bit_voices);
966 	else {
967 		const auto ratio_8bit = ceil_udivide(100u * combined_8bit_ms,
968 		                                     combined_ms);
969 		const auto ratio_16bit = ceil_udivide(100u * combined_16bit_ms,
970 		                                      combined_ms);
971 		LOG_MSG("GUS: Audio was made up of %u%% 8-bit %u-voice and "
972 		        "%u%% 16-bit %u-voice samples",
973 		        ratio_8bit, used_8bit_voices, ratio_16bit,
974 		        used_16bit_voices);
975 	}
976 	soft_limiter.PrintStats();
977 }
978 
ReadFromPort(const io_port_t port,io_width_t width)979 uint16_t Gus::ReadFromPort(const io_port_t port, io_width_t width)
980 {
981 	//	LOG_MSG("GUS: Read from port %x", port);
982 	switch (port - port_base) {
983 	case 0x206: return irq_status;
984 	case 0x208:
985 		uint8_t time;
986 		time = 0u;
987 		if (timer_one.has_expired)
988 			time |= (1 << 6);
989 		if (timer_two.has_expired)
990 			time |= 1 << 5;
991 		if (time & 0x60)
992 			time |= 1 << 7;
993 		if (irq_status & 0x04)
994 			time |= 1 << 2;
995 		if (irq_status & 0x08)
996 			time |= 1 << 1;
997 		return time;
998 	case 0x20a: return adlib_command_reg;
999 	case 0x302: return static_cast<uint8_t>(voice_index);
1000 	case 0x303: return selected_register;
1001 	case 0x304:
1002 		if (width == io_width_t::word)
1003 			return ReadFromRegister() & 0xffff;
1004 		else
1005 			return ReadFromRegister() & 0xff;
1006 	case 0x305: return ReadFromRegister() >> 8;
1007 	case 0x307:
1008 		return dram_addr < ram.size() ? ram.at(dram_addr) : 0;
1009 	default:
1010 #if LOG_GUS
1011 		LOG_MSG("GUS: Read at port %#x", port);
1012 #endif
1013 		break;
1014 	}
1015 	return 0xff;
1016 }
1017 
ReadFromRegister()1018 uint16_t Gus::ReadFromRegister()
1019 {
1020 	// LOG_MSG("GUS: Read register %x", selected_register);
1021 	uint8_t reg = 0;
1022 
1023 	// Registers that read from the general DSP
1024 	switch (selected_register) {
1025 	case 0x41: // DMA control register - read acknowledges DMA IRQ
1026 		reg = dma_ctrl & 0xbf;
1027 		// get the status and store it in bit 6 of the register
1028 		reg |= (dma_ctrl & DMA_TC_STATUS_BITMASK) >> 2;
1029 		dma_ctrl &= ~DMA_TC_STATUS_BITMASK; // clear the status bit
1030 		irq_status &= 0x7f;
1031 		CheckIrq();
1032 		return static_cast<uint16_t>(reg << 8);
1033 	case 0x42: // DMA address register
1034 		return dma_addr;
1035 	case 0x45: // Timer control register matches Adlib's behavior
1036 		return static_cast<uint16_t>(timer_ctrl << 8);
1037 	case 0x49: // DMA sample register
1038 		reg = dma_ctrl & 0xbf;
1039 		// get the status and store it in bit 6 of the register
1040 		reg |= (dma_ctrl & DMA_TC_STATUS_BITMASK) >> 2;
1041 		return static_cast<uint16_t>(reg << 8);
1042 	case 0x4c: // Reset register
1043 		reg = is_running ? 1 : 0;
1044 		if (dac_enabled)
1045 			reg |= 2;
1046 		if (irq_enabled)
1047 			reg |= 4;
1048 		return static_cast<uint16_t>(reg << 8);
1049 	case 0x8f: // General voice IRQ status register
1050 		reg = voice_irq.status | 0x20;
1051 		uint32_t mask;
1052 		mask = 1 << voice_irq.status;
1053 		if (!(voice_irq.vol_state & mask))
1054 			reg |= 0x40;
1055 		if (!(voice_irq.wave_state & mask))
1056 			reg |= 0x80;
1057 		voice_irq.vol_state &= ~mask;
1058 		voice_irq.wave_state &= ~mask;
1059 		CheckVoiceIrq();
1060 		return static_cast<uint16_t>(reg << 8);
1061 	default:
1062 		break;
1063 		// If the above weren't triggered, then fall-through
1064 		// to the voice-specific register switch below.
1065 	}
1066 
1067 	if (!target_voice)
1068 		return (selected_register == 0x80 || selected_register == 0x8d)
1069 		               ? 0x0300
1070 		               : 0u;
1071 
1072 	// Registers that read from from the current voice
1073 	switch (selected_register) {
1074 	case 0x80: // Voice wave control read register
1075 		return static_cast<uint16_t>(target_voice->ReadWaveState() << 8);
1076 	case 0x82: // Voice MSB start address register
1077 		return static_cast<uint16_t>(target_voice->wave_ctrl.start >> 16);
1078 	case 0x83: // Voice LSW start address register
1079 		return static_cast<uint16_t>(target_voice->wave_ctrl.start);
1080 	case 0x89: // Voice volume register
1081 	{
1082 		const int i = ceil_sdivide(target_voice->vol_ctrl.pos,
1083 		                           VOLUME_INC_SCALAR);
1084 		assert(i >= 0 && i < static_cast<int>(vol_scalars.size()));
1085 		return static_cast<uint16_t>(i << 4);
1086 	}
1087 	case 0x8a: // Voice MSB current address register
1088 		return static_cast<uint16_t>(target_voice->wave_ctrl.pos >> 16);
1089 	case 0x8b: // Voice LSW current address register
1090 		return static_cast<uint16_t>(target_voice->wave_ctrl.pos);
1091 	case 0x8d: // Voice volume control register
1092 		return static_cast<uint16_t>(target_voice->ReadVolState() << 8);
1093 	default:
1094 #if LOG_GUS
1095 		LOG_MSG("GUS: Register %#x not implemented for reading",
1096 		        selected_register);
1097 #endif
1098 		break;
1099 	}
1100 	return register_data;
1101 }
1102 
RegisterIoHandlers()1103 void Gus::RegisterIoHandlers()
1104 {
1105 	// Register the IO read addresses
1106 	assert(read_handlers.size() > 7);
1107 	const auto read_from = std::bind(&Gus::ReadFromPort, this, _1, _2);
1108 	read_handlers.at(0).Install(0x302 + port_base, read_from, io_width_t::byte);
1109 	read_handlers.at(1).Install(0x303 + port_base, read_from, io_width_t::byte);
1110 	read_handlers.at(2).Install(0x304 + port_base, read_from, io_width_t::word);
1111 	read_handlers.at(3).Install(0x305 + port_base, read_from, io_width_t::byte);
1112 	read_handlers.at(4).Install(0x206 + port_base, read_from, io_width_t::byte);
1113 	read_handlers.at(5).Install(0x208 + port_base, read_from, io_width_t::byte);
1114 	read_handlers.at(6).Install(0x307 + port_base, read_from, io_width_t::byte);
1115 	// Board Only
1116 	read_handlers.at(7).Install(0x20a + port_base, read_from, io_width_t::byte);
1117 
1118 	// Register the IO write addresses
1119 	// We'll leave the MIDI interface to the MPU-401
1120 	// Ditto for the Joystick
1121 	// GF1 Synthesizer
1122 	assert(write_handlers.size() > 8);
1123 	const auto write_to = std::bind(&Gus::WriteToPort, this, _1, _2, _3);
1124 	write_handlers.at(0).Install(0x302 + port_base, write_to, io_width_t::byte);
1125 	write_handlers.at(1).Install(0x303 + port_base, write_to, io_width_t::byte);
1126 	write_handlers.at(2).Install(0x304 + port_base, write_to, io_width_t::word);
1127 	write_handlers.at(3).Install(0x305 + port_base, write_to, io_width_t::byte);
1128 	write_handlers.at(4).Install(0x208 + port_base, write_to, io_width_t::byte);
1129 	write_handlers.at(5).Install(0x209 + port_base, write_to, io_width_t::byte);
1130 	write_handlers.at(6).Install(0x307 + port_base, write_to, io_width_t::byte);
1131 	// Board Only
1132 	write_handlers.at(7).Install(0x200 + port_base, write_to, io_width_t::byte);
1133 	write_handlers.at(8).Install(0x20b + port_base, write_to, io_width_t::byte);
1134 }
1135 
StopPlayback()1136 void Gus::StopPlayback()
1137 {
1138 	// Halt playback before altering the DSP state
1139 	audio_channel->Enable(false);
1140 
1141 	soft_limiter.Reset();
1142 
1143 	dac_enabled = false;
1144 	irq_enabled = false;
1145 	irq_status = 0;
1146 
1147 	dma_ctrl = 0u;
1148 	mix_ctrl = 0xb; // latches enabled, LINEs disabled
1149 	timer_ctrl = 0u;
1150 	sample_ctrl = 0u;
1151 
1152 	target_voice = nullptr;
1153 	voice_index = 0u;
1154 	active_voices = 0u;
1155 
1156 	dma_addr = 0u;
1157 	dram_addr = 0u;
1158 	register_data = 0u;
1159 	selected_register = 0u;
1160 	should_change_irq_dma = false;
1161 	PIC_RemoveEvents(GUS_TimerEvent);
1162 	is_running = false;
1163 }
1164 
GUS_TimerEvent(uint32_t t)1165 static void GUS_TimerEvent(uint32_t t)
1166 {
1167 	if (gus->CheckTimer(t)) {
1168 		const auto &timer = t == 0 ? gus->timer_one : gus->timer_two;
1169 		PIC_AddEvent(GUS_TimerEvent, timer.delay, t);
1170 	}
1171 }
1172 
UpdateDmaAddress(const uint8_t new_address)1173 void Gus::UpdateDmaAddress(const uint8_t new_address)
1174 {
1175 	// Has it changed?
1176 	if (new_address == dma1)
1177 		return;
1178 
1179 	// Unregister the current callback
1180 	if (dma_channel)
1181 		dma_channel->Register_Callback(nullptr);
1182 
1183 	// Update the address, channel, and callback
1184 	dma1 = new_address;
1185 	dma_channel = GetDMAChannel(dma1);
1186 	assert(dma_channel);
1187 	dma_channel->Register_Callback(std::bind(&Gus::DmaCallback, this, _1, _2));
1188 #if LOG_GUS
1189 	LOG_MSG("GUS: Assigned DMA1 address to %u", dma1);
1190 #endif
1191 }
1192 
WriteToPort(io_port_t port,io_val_t value,io_width_t width)1193 void Gus::WriteToPort(io_port_t port, io_val_t value, io_width_t width)
1194 {
1195 	const auto val = check_cast<uint16_t>(value);
1196 
1197 	//	LOG_MSG("GUS: Write to port %x val %x", port, val);
1198 	switch (port - port_base) {
1199 	case 0x200:
1200 		mix_ctrl = static_cast<uint8_t>(val);
1201 		should_change_irq_dma = true;
1202 		return;
1203 	case 0x208: adlib_command_reg = static_cast<uint8_t>(val); break;
1204 	case 0x209:
1205 		// TODO adlib_command_reg should be 4 for this to work
1206 		// else it should just latch the value
1207 		if (val & 0x80) {
1208 			timer_one.has_expired = false;
1209 			timer_two.has_expired = false;
1210 			return;
1211 		}
1212 		timer_one.is_masked = (val & 0x40) > 0;
1213 		timer_two.is_masked = (val & 0x20) > 0;
1214 		if (val & 0x1) {
1215 			if (!timer_one.is_counting_down) {
1216 				PIC_AddEvent(GUS_TimerEvent, timer_one.delay, 0);
1217 				timer_one.is_counting_down = true;
1218 			}
1219 		} else
1220 			timer_one.is_counting_down = false;
1221 		if (val & 0x2) {
1222 			if (!timer_two.is_counting_down) {
1223 				PIC_AddEvent(GUS_TimerEvent, timer_two.delay, 1);
1224 				timer_two.is_counting_down = true;
1225 			}
1226 		} else
1227 			timer_two.is_counting_down = false;
1228 		break;
1229 		// TODO Check if 0x20a register is also available on the gus
1230 		// like on the interwave
1231 	case 0x20b:
1232 		if (!should_change_irq_dma)
1233 			break;
1234 		should_change_irq_dma = false;
1235 		if (mix_ctrl & 0x40) {
1236 			// IRQ configuration, only use low bits for irq 1
1237 			const auto i = val & 7u;
1238 			const auto &address = irq_addresses.at(i);
1239 			if (address)
1240 				irq1 = address;
1241 #if LOG_GUS
1242 			LOG_MSG("GUS: Assigned IRQ1 to %d", irq1);
1243 #endif
1244 		} else {
1245 			// DMA configuration, only use low bits for dma 1
1246 			const uint8_t i = val & 0x7;
1247 			const auto address = dma_addresses.at(i);
1248 			if (address)
1249 				UpdateDmaAddress(address);
1250 		}
1251 		break;
1252 	case 0x302:
1253 		voice_index = val & 31;
1254 		target_voice = voices.at(voice_index).get();
1255 		break;
1256 	case 0x303:
1257 		selected_register = static_cast<uint8_t>(val);
1258 		register_data = 0;
1259 		break;
1260 	case 0x304:
1261 		if (width == io_width_t::word) {
1262 			register_data = val;
1263 			WriteToRegister();
1264 		} else
1265 			register_data = val;
1266 		break;
1267 	case 0x305:
1268 		register_data = static_cast<uint16_t>((0x00ff & register_data) |
1269 		                                      val << 8);
1270 		WriteToRegister();
1271 		break;
1272 	case 0x307:
1273 		if (dram_addr < ram.size())
1274 			ram.at(dram_addr) = static_cast<uint8_t>(val);
1275 		break;
1276 	default:
1277 #if LOG_GUS
1278 		LOG_MSG("GUS: Write to port %#x with value %x", port, val);
1279 #endif
1280 		break;
1281 	}
1282 }
1283 
UpdateWaveLsw(int32_t & addr) const1284 void Gus::UpdateWaveLsw(int32_t &addr) const noexcept
1285 {
1286 	constexpr auto WAVE_LSW_MASK = ~((1 << 16) - 1); // Lower wave mask
1287 	const auto lower = addr & WAVE_LSW_MASK;
1288 	addr = lower | register_data;
1289 }
1290 
UpdateWaveMsw(int32_t & addr) const1291 void Gus::UpdateWaveMsw(int32_t &addr) const noexcept
1292 {
1293 	constexpr auto WAVE_MSW_MASK = (1 << 16) - 1; // Upper wave mask
1294 	const auto upper = register_data & 0x1fff;
1295 	const auto lower = addr & WAVE_MSW_MASK;
1296 	addr = lower | (upper << 16);
1297 }
1298 
WriteToRegister()1299 void Gus::WriteToRegister()
1300 {
1301 	// Registers that write to the general DSP
1302 	switch (selected_register) {
1303 	case 0xe: // Set number of active voices
1304 		selected_register = register_data >> 8; // Jazz Jackrabbit needs this
1305 		{
1306 			const uint8_t num_voices = 1 + ((register_data >> 8) & 31);
1307 			ActivateVoices(num_voices);
1308 		}
1309 		return;
1310 	case 0x10: // Undocumented register used in Fast Tracker 2
1311 		return;
1312 	case 0x41: // DMA control register
1313 		// Clear all bits except the status and then replace dma_ctrl's
1314 		// lower bits with reg's top 8 bits
1315 		dma_ctrl &= DMA_TC_STATUS_BITMASK;
1316 		dma_ctrl |= register_data >> 8;
1317 		if (dma_ctrl & 1)
1318 			StartDmaTransfers();
1319 		return;
1320 	case 0x42: // Gravis DRAM DMA address register
1321 		dma_addr = register_data;
1322 		return;
1323 	case 0x43: // LSW Peek/poke DRAM position
1324 		dram_addr = (0xf0000 & dram_addr) |
1325 		            (static_cast<uint32_t>(register_data));
1326 		return;
1327 	case 0x44: // MSB Peek/poke DRAM position
1328 		dram_addr = (0x0ffff & dram_addr) |
1329 		            (static_cast<uint32_t>(register_data) & 0x0f00) << 8;
1330 		return;
1331 	case 0x45: // Timer control register.  Identical in operation to Adlib's
1332 		timer_ctrl = static_cast<uint8_t>(register_data >> 8);
1333 		timer_one.should_raise_irq = (timer_ctrl & 0x04) > 0;
1334 		if (!timer_one.should_raise_irq)
1335 			irq_status &= ~0x04;
1336 		timer_two.should_raise_irq = (timer_ctrl & 0x08) > 0;
1337 		if (!timer_two.should_raise_irq)
1338 			irq_status &= ~0x08;
1339 		return;
1340 	case 0x46: // Timer 1 control
1341 		timer_one.value = static_cast<uint8_t>(register_data >> 8);
1342 		timer_one.delay = (0x100 - timer_one.value) * TIMER_1_DEFAULT_DELAY;
1343 		return;
1344 	case 0x47: // Timer 2 control
1345 		timer_two.value = static_cast<uint8_t>(register_data >> 8);
1346 		timer_two.delay = (0x100 - timer_two.value) * TIMER_2_DEFAULT_DELAY;
1347 		return;
1348 	case 0x49: // DMA sampling control register
1349 		sample_ctrl = static_cast<uint8_t>(register_data >> 8);
1350 		if (sample_ctrl & 1)
1351 			StartDmaTransfers();
1352 		return;
1353 	case 0x4c: // Runtime control
1354 		{
1355 			const auto state = (register_data >> 8) & 7;
1356 			if (state == 0)
1357 				StopPlayback();
1358 			else if (state == 1)
1359 				PrepareForPlayback();
1360 			else if (active_voices)
1361 				BeginPlayback();
1362 		}
1363 		return;
1364 	default:
1365 		break;
1366 		// If the above weren't triggered, then fall-through
1367 		// to the target_voice-specific switch below.
1368 	}
1369 
1370 	// All the registers below operated on the target voice
1371 	if (!target_voice)
1372 		return;
1373 
1374 	uint8_t data = 0;
1375 	// Registers that write to the current voice
1376 	switch (selected_register) {
1377 	case 0x0: // Voice wave control register
1378 		if (target_voice->UpdateWaveState(register_data >> 8))
1379 			CheckVoiceIrq();
1380 		break;
1381 	case 0x1: // Voice rate control register
1382 		target_voice->WriteWaveRate(register_data);
1383 		break;
1384 	case 0x2: // Voice MSW start address register
1385 		UpdateWaveMsw(target_voice->wave_ctrl.start);
1386 		break;
1387 	case 0x3: // Voice LSW start address register
1388 		UpdateWaveLsw(target_voice->wave_ctrl.start);
1389 		break;
1390 	case 0x4: // Voice MSW end address register
1391 		UpdateWaveMsw(target_voice->wave_ctrl.end);
1392 		break;
1393 	case 0x5: // Voice LSW end address register
1394 		UpdateWaveLsw(target_voice->wave_ctrl.end);
1395 		break;
1396 	case 0x6: // Voice volume rate register
1397 		target_voice->WriteVolRate(register_data >> 8);
1398 		break;
1399 	case 0x7: // Voice volume start register  EEEEMMMM
1400 		data = register_data >> 8;
1401 		// Don't need to bounds-check the value because it's implied:
1402 		// 'data' is a uint8, so is 255 at most. 255 << 4 = 4080, which
1403 		// falls within-bounds of the 4096-long vol_scalars array.
1404 		target_voice->vol_ctrl.start = (data << 4) * VOLUME_INC_SCALAR;
1405 		break;
1406 	case 0x8: // Voice volume end register  EEEEMMMM
1407 		data = register_data >> 8;
1408 		// Same as above regarding bound-checking.
1409 		target_voice->vol_ctrl.end = (data << 4) * VOLUME_INC_SCALAR;
1410 		break;
1411 	case 0x9: // Voice current volume register
1412 		// Don't need to bounds-check the value because it's implied:
1413 		// reg data is a uint16, and 65535 >> 4 takes it down to 4095,
1414 		// which is the last element in the 4096-long vol_scalars array.
1415 		target_voice->vol_ctrl.pos = (register_data >> 4) * VOLUME_INC_SCALAR;
1416 		break;
1417 	case 0xa: // Voice MSW current address register
1418 		UpdateWaveMsw(target_voice->wave_ctrl.pos);
1419 		break;
1420 	case 0xb: // Voice LSW current address register
1421 		UpdateWaveLsw(target_voice->wave_ctrl.pos);
1422 		break;
1423 	case 0xc: // Voice pan pot register
1424 		target_voice->WritePanPot(register_data >> 8);
1425 		break;
1426 	case 0xd: // Voice volume control register
1427 		if (target_voice->UpdateVolState(register_data >> 8))
1428 			CheckVoiceIrq();
1429 		break;
1430 	default:
1431 #if LOG_GUS
1432 		LOG_MSG("GUS: Register %#x not implemented for writing",
1433 		        selected_register);
1434 #endif
1435 		break;
1436 	}
1437 	return;
1438 }
1439 
~Gus()1440 Gus::~Gus()
1441 {
1442 	DEBUG_LOG_MSG("GUS: Shutting down");
1443 	StopPlayback();
1444 
1445 	// remove the mixer channel
1446 	audio_channel.reset();
1447 
1448 	// remove the IO handlers
1449 	for (auto &rh : read_handlers)
1450 		rh.Uninstall();
1451 	for (auto &wh : write_handlers)
1452 		wh.Uninstall();
1453 }
1454 
gus_destroy(Section * sec)1455 static void gus_destroy([[maybe_unused]] Section *sec)
1456 {
1457 	// GUS destroy is run when the user wants to deactivate the GUS:
1458 	// C:\> config -set gus=false
1459 	// TODO: therefore, this function should also remove the
1460 	//       ULTRASND and ULTRADIR environment variables.
1461 
1462 	if (gus) {
1463 		gus->PrintStats();
1464 		gus.reset();
1465 	}
1466 }
1467 
gus_init(Section * sec)1468 static void gus_init(Section *sec)
1469 {
1470 	assert(sec);
1471 	const Section_prop *conf = dynamic_cast<Section_prop *>(sec);
1472 	if (!conf || !conf->Get_bool("gus"))
1473 		return;
1474 
1475 	// Read the GUS config settings
1476 	const auto port = static_cast<uint16_t>(conf->Get_hex("gusbase"));
1477 	const auto dma = clamp(static_cast<uint8_t>(conf->Get_int("gusdma")), MIN_DMA_ADDRESS, MAX_DMA_ADDRESS);
1478 	const auto irq = clamp(static_cast<uint8_t>(conf->Get_int("gusirq")), MIN_IRQ_ADDRESS, MAX_IRQ_ADDRESS);
1479 	const std::string ultradir = conf->Get_string("ultradir");
1480 
1481 	// Instantiate the GUS with the settings
1482 	gus = std::make_unique<Gus>(port, dma, irq, ultradir);
1483 	sec->AddDestroyFunction(&gus_destroy, true);
1484 }
1485 
init_gus_dosbox_settings(Section_prop & secprop)1486 void init_gus_dosbox_settings(Section_prop &secprop)
1487 {
1488 	constexpr auto when_idle = Property::Changeable::WhenIdle;
1489 
1490 	auto *bool_prop = secprop.Add_bool("gus", when_idle, false);
1491 	assert(bool_prop);
1492 	bool_prop->Set_help("Enable Gravis UltraSound emulation.");
1493 
1494 	auto *hex_prop = secprop.Add_hex("gusbase", when_idle, 0x240);
1495 	assert(hex_prop);
1496 	const char *const bases[] = {"240", "220", "260", "280",  "2a0",
1497 	                             "2c0", "2e0", "300", nullptr};
1498 	hex_prop->Set_values(bases);
1499 	hex_prop->Set_help("The IO base address of the Gravis UltraSound.");
1500 
1501 	auto *int_prop = secprop.Add_int("gusirq", when_idle, 5);
1502 	assert(int_prop);
1503 	const char *const irqs[] = {"5",  "3",  "7",  "9",
1504 	                            "10", "11", "12", nullptr};
1505 	int_prop->Set_values(irqs);
1506 	int_prop->Set_help("The IRQ number of the Gravis UltraSound.");
1507 
1508 	int_prop = secprop.Add_int("gusdma", when_idle, 3);
1509 	assert(int_prop);
1510 	const char *const dmas[] = {"3", "0", "1", "5", "6", "7", nullptr};
1511 	int_prop->Set_values(dmas);
1512 	int_prop->Set_help("The DMA channel of the Gravis UltraSound.");
1513 
1514 	auto *str_prop = secprop.Add_string("ultradir", when_idle, "C:\\ULTRASND");
1515 	assert(str_prop);
1516 	str_prop->Set_help("Path to UltraSound directory. In this directory\n"
1517 	                   "there should be a MIDI directory that contains\n"
1518 	                   "the patch files for GUS playback. Patch sets used\n"
1519 	                   "with Timidity should work fine.");
1520 }
1521 
GUS_AddConfigSection(Config * conf)1522 void GUS_AddConfigSection(Config *conf)
1523 {
1524 	assert(conf);
1525 	Section_prop *sec = conf->AddSection_prop("gus", &gus_init, true);
1526 	assert(sec);
1527 	init_gus_dosbox_settings(*sec);
1528 }
1529