From 422639411d015ac91ea80d9dbff5d635b73406c3 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Mon, 13 Feb 2023 01:43:50 +0100 Subject: [PATCH] Initial Burgundy sound codec emulation. --- devices/sound/burgundy.cpp | 104 +++++++++++++++++++++++++++++++++++ devices/sound/burgundy.h | 64 +++++++++++++++++++++ machines/machineyosemite.cpp | 2 +- 3 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 devices/sound/burgundy.cpp create mode 100644 devices/sound/burgundy.h diff --git a/devices/sound/burgundy.cpp b/devices/sound/burgundy.cpp new file mode 100644 index 0000000..51aabad --- /dev/null +++ b/devices/sound/burgundy.cpp @@ -0,0 +1,104 @@ +/* +DingusPPC - The Experimental PowerPC Macintosh emulator +Copyright (C) 2018-23 divingkatae and maximum + (theweirdo) spatium + +(Contact divingkatae#1017 or powermax#2286 on Discord for more info) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +/** Burgundy sound codec emulation. */ + +#include +#include +#include +#include +#include +#include +#include + +BurgundyCodec::BurgundyCodec(std::string name) : AwacsBase(name) +{ + supports_types(HWCompType::SND_CODEC); + + static int burgundy_sample_rates[1] = { 44100 }; + + // Burgundy seems to supports only one sample rate + this->sr_table = burgundy_sample_rates; + this->max_sr_id = 1; + + this->set_sample_rate(0); // set default sample rate +} + +uint32_t BurgundyCodec::snd_ctrl_read(uint32_t offset, int size) { + uint32_t result = 0; + + switch (offset) { + case AWAC_CODEC_CTRL_REG: + result = this->last_ctrl_data; + break; + case AWAC_CODEC_STATUS_REG: + result = (this->first_valid << 23) | BURGUNDY_READY | + (this->byte_counter << 14) | (this->read_pos << 12) | + (this->data_byte << 4); + break; + default: + LOG_F(ERROR, "%s: read from unsupported register 0x%X", this->name.c_str(), + offset); + } + + return BYTESWAP_32(result); +} + +void BurgundyCodec::snd_ctrl_write(uint32_t offset, uint32_t value, int size) { + uint8_t reg_addr, cur_byte, last_byte; + + value = BYTESWAP_32(value); + + switch (offset) { + case AWAC_CODEC_CTRL_REG: + this->last_ctrl_data = value; + reg_addr = (value >> 12) & 0xFF; + cur_byte = (value >> 8) & 3; + last_byte = (value >> 10) & 3; + if (value & BURGUNDY_REG_WR) { + uint32_t mask = 0xFFU << (cur_byte * 8); + this->reg_array[reg_addr] = (this->reg_array[reg_addr] & ~mask) | + ((value & 0xFFU) << (cur_byte * 8)); + } else { + this->reg_addr = reg_addr; + this->read_pos = cur_byte; + this->data_byte = (this->reg_array[reg_addr] >> (cur_byte * 8)) & 0xFFU; + this->first_valid = 1; + + TimerManager::get_instance()->add_oneshot_timer( + USECS_TO_NSECS(10), // not sure if this is the correct delay + [this]() { + this->first_valid = 0; + this->byte_counter = (this->byte_counter + 1) & 3; + }); + } + break; + default: + LOG_F(ERROR, "%s: write to unsupported register 0x%X", this->name.c_str(), + offset); + } +} + +static const DeviceDescription Burgundy_Descriptor = { + BurgundyCodec::create, {}, {} +}; + +REGISTER_DEVICE(BurgundySnd, Burgundy_Descriptor); diff --git a/devices/sound/burgundy.h b/devices/sound/burgundy.h new file mode 100644 index 0000000..0be9346 --- /dev/null +++ b/devices/sound/burgundy.h @@ -0,0 +1,64 @@ +/* +DingusPPC - The Experimental PowerPC Macintosh emulator +Copyright (C) 2018-23 divingkatae and maximum + (theweirdo) spatium + +(Contact divingkatae#1017 or powermax#2286 on Discord for more info) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +/** Burgundy sound codec definitions. */ + +#ifndef BURGUNDY_H +#define BURGUNDY_H + +#include +#include + +#include +#include + +enum { + BURGUNDY_REG_WR = 1 << 21, + BURGUNDY_READY = 1 << 22, +}; + +/** Number of internal registers implemented in Burgundy. */ +#define BURGUNDY_NUM_REGS 123 + +class BurgundyCodec : public MacioSndCtrl { +public: + BurgundyCodec(std::string name); + ~BurgundyCodec() = default; + + uint32_t snd_ctrl_read(uint32_t offset, int size); + void snd_ctrl_write(uint32_t offset, uint32_t value, int size); + + static std::unique_ptr create() { + return std::unique_ptr(new BurgundyCodec("Burgundy")); + } + +private: + uint32_t last_ctrl_data = 0; + uint8_t byte_counter = 0; + uint8_t reg_addr = 0; + uint8_t first_valid = 0; + uint8_t read_pos = 0; + uint8_t data_byte = 0; + + uint32_t reg_array[BURGUNDY_NUM_REGS] = {}; +}; + +#endif // BURGUNDY_H diff --git a/machines/machineyosemite.cpp b/machines/machineyosemite.cpp index 5017fa8..406b0d2 100644 --- a/machines/machineyosemite.cpp +++ b/machines/machineyosemite.cpp @@ -97,7 +97,7 @@ static const PropMap yosemite_settings = { }; static vector pmg3nw_devices = { - "Grackle", "Dec21154", "Heathrow" + "Grackle", "Dec21154", "BurgundySnd", "Heathrow" }; static const MachineDescription pmg3nw_descriptor = {