diff --git a/src/xenia/apu/xma_decoder.cc b/src/xenia/apu/xma_decoder.cc index b15bd7fe2..cd04ebd91 100644 --- a/src/xenia/apu/xma_decoder.cc +++ b/src/xenia/apu/xma_decoder.cc @@ -123,7 +123,7 @@ X_STATUS XmaDecoder::Setup(kernel::KernelState* kernel_state) { sizeof(XMA_CONTEXT_DATA) * kContextCount, 256, kSystemHeapPhysical); context_data_last_ptr_ = context_data_first_ptr_ + (sizeof(XMA_CONTEXT_DATA) * kContextCount - 1); - register_file_[XE_XMA_REG_CONTEXT_ARRAY_ADDRESS].u32 = + register_file_[XmaRegister::ContextArrayAddress] = memory()->GetPhysicalAddress(context_data_first_ptr_); // Setup XMA contexts. @@ -134,7 +134,7 @@ X_STATUS XmaDecoder::Setup(kernel::KernelState* kernel_state) { assert_always(); } } - register_file_[XE_XMA_REG_NEXT_CONTEXT_INDEX].u32 = 1; + register_file_[XmaRegister::NextContextIndex] = 1; context_bitmap_.Resize(kContextCount); worker_running_ = true; @@ -254,27 +254,29 @@ bool XmaDecoder::BlockOnContext(uint32_t guest_ptr, bool poll) { } uint32_t XmaDecoder::ReadRegister(uint32_t addr) { - uint32_t r = (addr & 0xFFFF) / 4; + auto r = (addr & 0xFFFF) / 4; assert_true(r < XmaRegisterFile::kRegisterCount); switch (r) { - case XE_XMA_REG_CURRENT_CONTEXT_INDEX: { + case XmaRegister::ContextArrayAddress: + break; + case XmaRegister::CurrentContextIndex: { // 0606h (1818h) is rotating context processing # set to hardware ID of // context being processed. // If bit 200h is set, the locking code will possibly collide on hardware // IDs and error out, so we should never set it (I think?). uint32_t& current_context_index = - register_file_[XE_XMA_REG_CURRENT_CONTEXT_INDEX].u32; + register_file_[XmaRegister::CurrentContextIndex]; uint32_t& next_context_index = - register_file_[XE_XMA_REG_NEXT_CONTEXT_INDEX].u32; + register_file_[XmaRegister::NextContextIndex]; // To prevent games from seeing a stuck XMA context, return a rotating // number. current_context_index = next_context_index; next_context_index = (next_context_index + 1) % kContextCount; break; } - default: { + default: const auto register_info = register_file_.GetRegisterInfo(r); if (register_info) { XELOGW("XMA: Read from unhandled register ({:04X}, {})", r, @@ -283,10 +285,9 @@ uint32_t XmaDecoder::ReadRegister(uint32_t addr) { XELOGW("XMA: Read from unknown register ({:04X})", r); } break; - } } - return xe::byte_swap(register_file_.values[r].u32); + return xe::byte_swap(register_file_[r]); } void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) { @@ -296,16 +297,16 @@ void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) { value = xe::byte_swap(value); assert_true(r < XmaRegisterFile::kRegisterCount); - register_file_.values[r].u32 = value; + register_file_[r] = value; - if (r >= XE_XMA_REG_CONTEXT_KICK_0 && r <= XE_XMA_REG_CONTEXT_KICK_9) { + if (r >= XmaRegister::Context0Kick && r <= XmaRegister::Context9Kick) { // Context kick command. // This will kick off the given hardware contexts. // Basically, this kicks the SPU and says "hey, decode that audio!" // XMAEnableContext // The context ID is a bit in the range of the entire context array. - uint32_t base_context_id = (r - XE_XMA_REG_CONTEXT_KICK_0) * 32; + uint32_t base_context_id = (r - XmaRegister::Context0Kick) * 32; for (int i = 0; value && i < 32; ++i, value >>= 1) { if (value & 1) { uint32_t context_id = base_context_id + i; @@ -315,11 +316,11 @@ void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) { } // Signal the decoder thread to start processing. work_event_->Set(); - } else if (r >= XE_XMA_REG_CONTEXT_LOCK_0 && r <= XE_XMA_REG_CONTEXT_LOCK_9) { + } else if (r >= XmaRegister::Context0Lock && r <= XmaRegister::Context9Lock) { // Context lock command. // This requests a lock by flagging the context. // XMADisableContext - uint32_t base_context_id = (r - XE_XMA_REG_CONTEXT_LOCK_0) * 32; + uint32_t base_context_id = (r - XmaRegister::Context0Lock) * 32; for (int i = 0; value && i < 32; ++i, value >>= 1) { if (value & 1) { uint32_t context_id = base_context_id + i; @@ -328,12 +329,12 @@ void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) { } } // Signal the decoder thread to start processing. - work_event_->Set(); - } else if (r >= XE_XMA_REG_CONTEXT_CLEAR_0 && - r <= XE_XMA_REG_CONTEXT_CLEAR_9) { + // work_event_->Set(); + } else if (r >= XmaRegister::Context0Clear && + r <= XmaRegister::Context9Clear) { // Context clear command. // This will reset the given hardware contexts. - uint32_t base_context_id = (r - XE_XMA_REG_CONTEXT_CLEAR_0) * 32; + uint32_t base_context_id = (r - XmaRegister::Context0Clear) * 32; for (int i = 0; value && i < 32; ++i, value >>= 1) { if (value & 1) { uint32_t context_id = base_context_id + i; diff --git a/src/xenia/apu/xma_decoder.h b/src/xenia/apu/xma_decoder.h index 228a7290d..73da02c2e 100644 --- a/src/xenia/apu/xma_decoder.h +++ b/src/xenia/apu/xma_decoder.h @@ -2,7 +2,7 @@ ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * + * Copyright 2021 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ @@ -37,7 +37,7 @@ class XmaDecoder { void Shutdown(); uint32_t context_array_ptr() const { - return register_file_.values[XE_XMA_REG_CONTEXT_ARRAY_ADDRESS].u32; + return register_file_[XmaRegister::ContextArrayAddress]; } uint32_t AllocateContext(); diff --git a/src/xenia/apu/xma_register_file.cc b/src/xenia/apu/xma_register_file.cc index d3383b9cb..ee45b2811 100644 --- a/src/xenia/apu/xma_register_file.cc +++ b/src/xenia/apu/xma_register_file.cc @@ -2,7 +2,7 @@ ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** - * Copyright 2014 Ben Vanik. All rights reserved. * + * Copyright 2021 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ @@ -20,10 +20,9 @@ XmaRegisterFile::XmaRegisterFile() { std::memset(values, 0, sizeof(values)); } const XmaRegisterInfo* XmaRegisterFile::GetRegisterInfo(uint32_t index) { switch (index) { -#define XE_XMA_REGISTER(index, type, name) \ +#define XE_XMA_REGISTER(index, name) \ case index: { \ static const XmaRegisterInfo reg_info = { \ - XmaRegisterInfo::Type::type, \ #name, \ }; \ return ®_info; \ diff --git a/src/xenia/apu/xma_register_file.h b/src/xenia/apu/xma_register_file.h index 09154b9ad..e2e924c57 100644 --- a/src/xenia/apu/xma_register_file.h +++ b/src/xenia/apu/xma_register_file.h @@ -2,7 +2,7 @@ ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** - * Copyright 2014 Ben Vanik. All rights reserved. * + * Copyright 2021 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ @@ -16,18 +16,13 @@ namespace xe { namespace apu { -enum XmaRegister { -#define XE_XMA_REGISTER(index, type, name) XE_XMA_REG_##name = index, +struct XmaRegister { +#define XE_XMA_REGISTER(index, name) static const uint32_t name = index; #include "xenia/apu/xma_register_table.inc" #undef XE_XMA_REGISTER }; struct XmaRegisterInfo { - enum class Type { - kDword, - kFloat, - }; - Type type; const char* name; }; @@ -38,14 +33,10 @@ class XmaRegisterFile { static const XmaRegisterInfo* GetRegisterInfo(uint32_t index); static const size_t kRegisterCount = (0xFFFF + 1) / 4; - union RegisterValue { - uint32_t u32; - float f32; - }; - RegisterValue values[kRegisterCount]; + uint32_t values[kRegisterCount]; - RegisterValue& operator[](int reg) { return values[reg]; } - RegisterValue& operator[](XmaRegister reg) { return values[reg]; } + uint32_t operator[](uint32_t reg) const { return values[reg]; } + uint32_t& operator[](uint32_t reg) { return values[reg]; } }; } // namespace apu diff --git a/src/xenia/apu/xma_register_table.inc b/src/xenia/apu/xma_register_table.inc index 49b32e26f..1703c2e9f 100644 --- a/src/xenia/apu/xma_register_table.inc +++ b/src/xenia/apu/xma_register_table.inc @@ -2,7 +2,7 @@ ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * + * Copyright 2021 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ @@ -10,42 +10,72 @@ // This is a partial file designed to be included by other files when // constructing various tables. -//#define XE_XMA_REGISTER(index, type, name) +#ifndef XE_XMA_REGISTER +#define XE_XMA_REGISTER(index, name) +#define __XE_XMA_REGISTER_UNSET +#endif -XE_XMA_REGISTER(0x0600, kDword, CONTEXT_ARRAY_ADDRESS) +#ifndef XE_XMA_REGISTER_CONTEXT_GROUP +#define XE_XMA_REGISTER_CONTEXT_GROUP(index, suffix) \ + XE_XMA_REGISTER(index + 0, Context0##suffix) \ + XE_XMA_REGISTER(index + 1, Context1##suffix) \ + XE_XMA_REGISTER(index + 2, Context2##suffix) \ + XE_XMA_REGISTER(index + 3, Context3##suffix) \ + XE_XMA_REGISTER(index + 4, Context4##suffix) \ + XE_XMA_REGISTER(index + 5, Context5##suffix) \ + XE_XMA_REGISTER(index + 6, Context6##suffix) \ + XE_XMA_REGISTER(index + 7, Context7##suffix) \ + XE_XMA_REGISTER(index + 8, Context8##suffix) \ + XE_XMA_REGISTER(index + 9, Context9##suffix) +#endif -XE_XMA_REGISTER(0x0606, kDword, CURRENT_CONTEXT_INDEX) -XE_XMA_REGISTER(0x0607, kDword, NEXT_CONTEXT_INDEX) +// 0x0000..0x001F : ??? +// 0x0020..0x03FF : all 0xFFs? +// 0x0400..0x043F : ??? +// 0x0440..0x047F : all 0xFFs? +// 0x0480..0x048B : ??? +// 0x048C..0x04C0 : all 0xFFs? +// 0x04C1..0x04CB : ??? +// 0x04CC..0x04FF : all 0xFFs? +// 0x0500..0x051F : ??? +// 0x0520..0x057F : all 0xFFs? +// 0x0580..0x058F : ??? +// 0x0590..0x05FF : all 0xFFs? -XE_XMA_REGISTER(0x0650, kDword, CONTEXT_KICK_0) -XE_XMA_REGISTER(0x0651, kDword, CONTEXT_KICK_1) -XE_XMA_REGISTER(0x0652, kDword, CONTEXT_KICK_2) -XE_XMA_REGISTER(0x0653, kDword, CONTEXT_KICK_3) -XE_XMA_REGISTER(0x0654, kDword, CONTEXT_KICK_4) -XE_XMA_REGISTER(0x0655, kDword, CONTEXT_KICK_5) -XE_XMA_REGISTER(0x0656, kDword, CONTEXT_KICK_6) -XE_XMA_REGISTER(0x0657, kDword, CONTEXT_KICK_7) -XE_XMA_REGISTER(0x0658, kDword, CONTEXT_KICK_8) -XE_XMA_REGISTER(0x0659, kDword, CONTEXT_KICK_9) +// XMA stuff is probably only 0x0600..0x06FF +//---------------------------------------------------------------------------// -XE_XMA_REGISTER(0x0690, kDword, CONTEXT_LOCK_0) -XE_XMA_REGISTER(0x0691, kDword, CONTEXT_LOCK_1) -XE_XMA_REGISTER(0x0692, kDword, CONTEXT_LOCK_2) -XE_XMA_REGISTER(0x0693, kDword, CONTEXT_LOCK_3) -XE_XMA_REGISTER(0x0694, kDword, CONTEXT_LOCK_4) -XE_XMA_REGISTER(0x0695, kDword, CONTEXT_LOCK_5) -XE_XMA_REGISTER(0x0696, kDword, CONTEXT_LOCK_6) -XE_XMA_REGISTER(0x0697, kDword, CONTEXT_LOCK_7) -XE_XMA_REGISTER(0x0698, kDword, CONTEXT_LOCK_8) -XE_XMA_REGISTER(0x0699, kDword, CONTEXT_LOCK_9) +XE_XMA_REGISTER(0x0600, ContextArrayAddress) +// 0x0601..0x0605 : ??? +XE_XMA_REGISTER(0x0606, CurrentContextIndex) +XE_XMA_REGISTER(0x0607, NextContextIndex) +// 0x0608 : ??? +// 0x0609..0x060F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0610, Unknown610) +// 0x061A..0x061F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0620, Unknown620) +// 0x062A..0x0641 : zero? +// 0x0642..0x0644 : ??? +// 0x0645..0x064F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0650, Kick) +// 0x065A..0x065F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0660, Unknown660) +// 0x066A..0x0681 : zero? +// 0x0682..0x0684 : ??? +// 0x0685..0x068F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x0690, Lock) +// 0x069A..0x069F : zero? +XE_XMA_REGISTER_CONTEXT_GROUP(0x06A0, Clear) -XE_XMA_REGISTER(0x06A0, kDword, CONTEXT_CLEAR_0) -XE_XMA_REGISTER(0x06A1, kDword, CONTEXT_CLEAR_1) -XE_XMA_REGISTER(0x06A2, kDword, CONTEXT_CLEAR_2) -XE_XMA_REGISTER(0x06A3, kDword, CONTEXT_CLEAR_3) -XE_XMA_REGISTER(0x06A4, kDword, CONTEXT_CLEAR_4) -XE_XMA_REGISTER(0x06A5, kDword, CONTEXT_CLEAR_5) -XE_XMA_REGISTER(0x06A6, kDword, CONTEXT_CLEAR_6) -XE_XMA_REGISTER(0x06A7, kDword, CONTEXT_CLEAR_7) -XE_XMA_REGISTER(0x06A8, kDword, CONTEXT_CLEAR_8) -XE_XMA_REGISTER(0x06A9, kDword, CONTEXT_CLEAR_9) +//---------------------------------------------------------------------------// + +// 0x0700..0x07FF : all 0xFFs? +// 0x0800..0x17FF : ??? +// 0x1800..0x2FFF : all 0xFFs? +// 0x3000..0x30FF : ??? +// 0x3100..0x3FFF : all 0xFFs? + +#ifdef __XE_XMA_REGISTER_UNSET +#undef __XE_XMA_REGISTER_UNSET +#undef XE_XMA_REGISTER +#endif