mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
xbox.cpp: more usb (nw)
This commit is contained in:
parent
b61b025eab
commit
d9a00119f4
@ -1,6 +1,8 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Samuele Zannoli
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
struct OHCIEndpointDescriptor {
|
||||
int mps; // MaximumPacketSize
|
||||
int f; // Format
|
||||
@ -211,29 +213,79 @@ enum USBDeviceState
|
||||
ConfiguredState
|
||||
};
|
||||
|
||||
enum USBControlDirection
|
||||
{
|
||||
HostToDevice=0,
|
||||
DeviceToHost=1
|
||||
};
|
||||
|
||||
enum USBEndpointType
|
||||
{
|
||||
ControlEndpoint=0,
|
||||
IsochronousEndpoint,
|
||||
BulkEndpoint,
|
||||
InterruptEndpoint
|
||||
};
|
||||
|
||||
struct usb_device_interface_alternate
|
||||
{
|
||||
USBStandardInterfaceDescriptor interface_descriptor;
|
||||
std::forward_list<USBStandardEndpointDescriptor> endpoint_descriptors;
|
||||
};
|
||||
|
||||
struct usb_device_interface
|
||||
{
|
||||
std::forward_list<usb_device_interface_alternate> alternate_settings;
|
||||
int selected_alternate;
|
||||
};
|
||||
|
||||
struct usb_device_configuration
|
||||
{
|
||||
USBStandardConfigurationDescriptor configuration_descriptor;
|
||||
std::forward_list<usb_device_interface> interfaces;
|
||||
};
|
||||
|
||||
class ohci_function_device {
|
||||
public:
|
||||
ohci_function_device(running_machine &machine);
|
||||
void execute_reset();
|
||||
int execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size);
|
||||
protected:
|
||||
int handle_nonstandard_request(int endpoint, USBSetupPacket *setup);
|
||||
virtual int handle_get_status_request(int endpoint, USBSetupPacket *setup) = 0;
|
||||
virtual int handle_clear_feature_request(int endpoint, USBSetupPacket *setup) = 0;
|
||||
virtual int handle_set_feature_request(int endpoint, USBSetupPacket *setup) = 0;
|
||||
virtual int handle_set_descriptor_request(int endpoint, USBSetupPacket *setup) = 0;
|
||||
virtual int handle_synch_frame_request(int endpoint, USBSetupPacket *setup) = 0;
|
||||
private:
|
||||
void add_device_descriptor(USBStandardDeviceDescriptor &descriptor);
|
||||
void add_configuration_descriptor(USBStandardConfigurationDescriptor &descriptor);
|
||||
void add_interface_descriptor(USBStandardInterfaceDescriptor &descriptor);
|
||||
void add_endpoint_descriptor(USBStandardEndpointDescriptor &descriptor);
|
||||
int handle_nonstandard_request(USBSetupPacket *setup);
|
||||
void select_configuration(int index);
|
||||
void select_alternate(int interfacei, int index);
|
||||
int find_alternate(int interfacei);
|
||||
struct {
|
||||
int type;
|
||||
int controldirection;
|
||||
int controltype;
|
||||
int controlrecipient;
|
||||
int remain;
|
||||
UINT8 *position;
|
||||
UINT8 buffer[4];
|
||||
} endpoints[256];
|
||||
int state;
|
||||
int address;
|
||||
int newaddress;
|
||||
int controldirection;
|
||||
int controltype;
|
||||
int controlrecipient;
|
||||
int configurationvalue;
|
||||
bool settingaddress;
|
||||
int remain;
|
||||
UINT8 *position;
|
||||
int newaddress;
|
||||
int address;
|
||||
int configurationvalue;
|
||||
UINT8 *descriptors;
|
||||
int descriptors_pos;
|
||||
USBStandardDeviceDescriptor device_descriptor;
|
||||
std::forward_list<usb_device_configuration> configurations;
|
||||
usb_device_configuration *latest_configuration;
|
||||
usb_device_interface_alternate *latest_alternate;
|
||||
usb_device_configuration *selected_configuration;
|
||||
};
|
||||
|
||||
class xbox_base_state : public driver_device
|
||||
|
@ -846,13 +846,19 @@ ohci_function_device::ohci_function_device(running_machine &machine)
|
||||
descriptors_pos = 0;
|
||||
address = 0;
|
||||
newaddress = 0;
|
||||
controldirection = 0;
|
||||
controltype = 0;
|
||||
controlrecipient = 0;
|
||||
configurationvalue = 0;
|
||||
remain = 0;
|
||||
position = nullptr;
|
||||
for (int e = 0; e < 256;e++) {
|
||||
endpoints[e].type = -1;
|
||||
endpoints[e].controldirection = 0;
|
||||
endpoints[e].controltype = 0;
|
||||
endpoints[e].controlrecipient = 0;
|
||||
endpoints[e].remain = 0;
|
||||
endpoints[e].position = nullptr;
|
||||
}
|
||||
endpoints[0].type = ControlEndpoint;
|
||||
settingaddress = false;
|
||||
configurationvalue = 0;
|
||||
latest_configuration = nullptr;
|
||||
latest_alternate = nullptr;
|
||||
add_device_descriptor(devdesc);
|
||||
add_configuration_descriptor(condesc);
|
||||
add_interface_descriptor(intdesc);
|
||||
@ -862,26 +868,175 @@ ohci_function_device::ohci_function_device(running_machine &machine)
|
||||
|
||||
void ohci_function_device::add_device_descriptor(USBStandardDeviceDescriptor &descriptor)
|
||||
{
|
||||
memcpy(descriptors + descriptors_pos, &descriptor, sizeof(descriptor));
|
||||
UINT8 *p = descriptors + descriptors_pos;
|
||||
|
||||
p[0] = descriptor.bLength;
|
||||
p[1] = descriptor.bDescriptorType;
|
||||
p[2] = descriptor.bcdUSB & 255;
|
||||
p[3] = descriptor.bcdUSB >> 8;
|
||||
p[4] = descriptor.bDeviceClass;
|
||||
p[5] = descriptor.bDeviceSubClass;
|
||||
p[6] = descriptor.bDeviceProtocol;
|
||||
p[7] = descriptor.bMaxPacketSize0;
|
||||
p[8] = descriptor.idVendor & 255;
|
||||
p[9] = descriptor.idVendor >> 8;
|
||||
p[10] = descriptor.idProduct & 255;
|
||||
p[11] = descriptor.idProduct >> 8;
|
||||
p[12] = descriptor.bcdDevice & 255;
|
||||
p[13] = descriptor.bcdDevice >> 8;
|
||||
p[14] = descriptor.iManufacturer;
|
||||
p[15] = descriptor.iProduct;
|
||||
p[16] = descriptor.iSerialNumber;
|
||||
p[17] = descriptor.bNumConfigurations;
|
||||
descriptors_pos += descriptor.bLength;
|
||||
memcpy(&device_descriptor, &descriptor, sizeof(USBStandardDeviceDescriptor));
|
||||
}
|
||||
|
||||
void ohci_function_device::add_configuration_descriptor(USBStandardConfigurationDescriptor &descriptor)
|
||||
{
|
||||
memcpy(descriptors + descriptors_pos, &descriptor, sizeof(descriptor));
|
||||
usb_device_configuration *c = new usb_device_configuration;
|
||||
UINT8 *p = descriptors + descriptors_pos;
|
||||
|
||||
p[0] = descriptor.bLength;
|
||||
p[1] = descriptor.bDescriptorType;
|
||||
p[2] = descriptor.wTotalLength & 255;
|
||||
p[3] = descriptor.wTotalLength >> 8;
|
||||
p[4] = descriptor.bNumInterfaces;
|
||||
p[5] = descriptor.bConfigurationValue;
|
||||
p[6] = descriptor.iConfiguration;
|
||||
p[7] = descriptor.bmAttributes;
|
||||
p[8] = descriptor.MaxPower;
|
||||
descriptors_pos += descriptor.bLength;
|
||||
memcpy(&c->configuration_descriptor, &descriptor, sizeof(USBStandardConfigurationDescriptor));
|
||||
configurations.push_front(*c);
|
||||
latest_configuration = c;
|
||||
latest_alternate = nullptr;
|
||||
}
|
||||
|
||||
void ohci_function_device::add_interface_descriptor(USBStandardInterfaceDescriptor &descriptor)
|
||||
{
|
||||
memcpy(descriptors + descriptors_pos, &descriptor, sizeof(descriptor));
|
||||
usb_device_interface *ii;
|
||||
usb_device_interface_alternate *aa;
|
||||
UINT8 *p = descriptors + descriptors_pos;
|
||||
|
||||
if (latest_configuration == nullptr)
|
||||
return;
|
||||
p[0] = descriptor.bLength;
|
||||
p[1] = descriptor.bDescriptorType;
|
||||
p[2] = descriptor.bInterfaceNumber;
|
||||
p[3] = descriptor.bAlternateSetting;
|
||||
p[4] = descriptor.bNumEndpoints;
|
||||
p[5] = descriptor.bInterfaceClass;
|
||||
p[6] = descriptor.bInterfaceSubClass;
|
||||
p[7] = descriptor.bInterfaceProtocol;
|
||||
p[8] = descriptor.iInterface;
|
||||
descriptors_pos += descriptor.bLength;
|
||||
for (auto i = latest_configuration->interfaces.begin(); i != latest_configuration->interfaces.end(); ++i)
|
||||
{
|
||||
if (i->alternate_settings.front().interface_descriptor.bInterfaceNumber == descriptor.bInterfaceNumber)
|
||||
{
|
||||
aa = new usb_device_interface_alternate;
|
||||
memcpy(&aa->interface_descriptor, &descriptor, sizeof(USBStandardInterfaceDescriptor));
|
||||
i->alternate_settings.push_front(*aa);
|
||||
latest_alternate = aa;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ii = new usb_device_interface;
|
||||
aa = new usb_device_interface_alternate;
|
||||
memcpy(&aa->interface_descriptor, &descriptor, sizeof(USBStandardInterfaceDescriptor));
|
||||
ii->selected_alternate = -1;
|
||||
ii->alternate_settings.push_front(*aa);
|
||||
latest_alternate = aa;
|
||||
latest_configuration->interfaces.push_front(*ii);
|
||||
}
|
||||
|
||||
void ohci_function_device::add_endpoint_descriptor(USBStandardEndpointDescriptor &descriptor)
|
||||
{
|
||||
memcpy(descriptors + descriptors_pos, &descriptor, sizeof(descriptor));
|
||||
UINT8 *p = descriptors + descriptors_pos;
|
||||
|
||||
if (latest_alternate == nullptr)
|
||||
return;
|
||||
p[0] = descriptor.bLength;
|
||||
p[1] = descriptor.bDescriptorType;
|
||||
p[2] = descriptor.bEndpointAddress;
|
||||
p[3] = descriptor.bmAttributes;
|
||||
p[4] = descriptor.wMaxPacketSize & 255;
|
||||
p[5] = descriptor.wMaxPacketSize >> 8;
|
||||
p[6] = descriptor.bInterval;
|
||||
descriptors_pos += descriptor.bLength;
|
||||
latest_alternate->endpoint_descriptors.push_front(descriptor);
|
||||
}
|
||||
|
||||
void ohci_function_device::select_configuration(int index)
|
||||
{
|
||||
configurationvalue = index;
|
||||
for (auto c = configurations.begin(); c != configurations.end(); ++c)
|
||||
{
|
||||
if (c->configuration_descriptor.bConfigurationValue == index)
|
||||
{
|
||||
selected_configuration = &(*c);
|
||||
for (auto i = c->interfaces.begin(); i != c->interfaces.end(); ++i)
|
||||
{
|
||||
i->selected_alternate = 0;
|
||||
for (auto a = i->alternate_settings.begin(); a != i->alternate_settings.end(); ++a)
|
||||
{
|
||||
if (a->interface_descriptor.bAlternateSetting == 0)
|
||||
{
|
||||
for (auto e = a->endpoint_descriptors.begin(); e != a->endpoint_descriptors.end(); ++e)
|
||||
{
|
||||
endpoints[e->bEndpointAddress].type = e->bmAttributes & 3;
|
||||
endpoints[e->bEndpointAddress].remain = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ohci_function_device::select_alternate(int interfacei, int index)
|
||||
{
|
||||
for (auto i = selected_configuration->interfaces.begin(); i != selected_configuration->interfaces.end(); ++i)
|
||||
{
|
||||
for (auto a = i->alternate_settings.begin(); a != i->alternate_settings.end(); ++a)
|
||||
{
|
||||
if ((a->interface_descriptor.bInterfaceNumber == interfacei) && (a->interface_descriptor.bAlternateSetting == i->selected_alternate))
|
||||
{
|
||||
for (auto e = a->endpoint_descriptors.begin(); e != a->endpoint_descriptors.end(); ++e)
|
||||
{
|
||||
endpoints[e->bEndpointAddress].type = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto a = i->alternate_settings.begin(); a != i->alternate_settings.end(); ++a)
|
||||
{
|
||||
if ((a->interface_descriptor.bInterfaceNumber == interfacei) && (a->interface_descriptor.bAlternateSetting == index))
|
||||
{
|
||||
i->selected_alternate = index;
|
||||
for (auto e = a->endpoint_descriptors.begin(); e != a->endpoint_descriptors.end(); ++e)
|
||||
{
|
||||
endpoints[e->bEndpointAddress].type = e->bmAttributes & 3;
|
||||
endpoints[e->bEndpointAddress].remain = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ohci_function_device::find_alternate(int interfacei)
|
||||
{
|
||||
for (auto i = selected_configuration->interfaces.begin(); i != selected_configuration->interfaces.end(); ++i)
|
||||
{
|
||||
for (auto a = i->alternate_settings.begin(); a != i->alternate_settings.end(); ++a)
|
||||
{
|
||||
if (a->interface_descriptor.bInterfaceNumber == interfacei)
|
||||
{
|
||||
return i->selected_alternate;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ohci_function_device::execute_reset()
|
||||
@ -894,25 +1049,30 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
|
||||
{
|
||||
int descriptortype;// descriptorindex;
|
||||
|
||||
if (endpoint == 0) {
|
||||
if (pid == SetupPid) {
|
||||
USBSetupPacket *p=(USBSetupPacket *)buffer;
|
||||
// define direction 0:host->device 1:device->host
|
||||
controldirection = (p->bmRequestType & 128) >> 7;
|
||||
// case ==1, IN data stage and OUT status stage
|
||||
// case ==0, OUT data stage and IN status stage
|
||||
// data stage is optional, IN status stage
|
||||
controltype = (p->bmRequestType & 0x60) >> 5;
|
||||
controlrecipient = p->bmRequestType & 0x1f;
|
||||
position = nullptr;
|
||||
if (pid == SetupPid) {
|
||||
USBSetupPacket *p=(USBSetupPacket *)buffer;
|
||||
// define direction 0:host->device 1:device->host
|
||||
// case == 1, IN data stage and OUT status stage
|
||||
// case == 0, OUT data stage and IN status stage
|
||||
// data stage is optional, IN status stage
|
||||
endpoints[endpoint].controldirection = (p->bmRequestType & 128) >> 7;
|
||||
endpoints[endpoint].controltype = (p->bmRequestType & 0x60) >> 5;
|
||||
endpoints[endpoint].controlrecipient = p->bmRequestType & 0x1f;
|
||||
if (endpoint == 0) {
|
||||
endpoints[endpoint].position = nullptr;
|
||||
// number of byte to transfer in data stage (0 no data stage)
|
||||
remain = p->wLength;
|
||||
endpoints[endpoint].remain = p->wLength;
|
||||
// if standard device request
|
||||
if ((controltype == StandardType) && (controlrecipient == DeviceRecipient)) {
|
||||
if ((endpoints[endpoint].controltype == StandardType) && (endpoints[endpoint].controlrecipient == DeviceRecipient)) {
|
||||
switch (p->bRequest) {
|
||||
case GET_STATUS:
|
||||
return handle_get_status_request(endpoint, p);
|
||||
break;
|
||||
case CLEAR_FEATURE:
|
||||
return handle_clear_feature_request(endpoint, p);
|
||||
break;
|
||||
case SET_FEATURE:
|
||||
return handle_set_feature_request(endpoint, p);
|
||||
break;
|
||||
case SET_ADDRESS:
|
||||
newaddress = p->wValue;
|
||||
@ -922,52 +1082,74 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
|
||||
descriptortype = p->wValue >> 8;
|
||||
//descriptorindex = p->wValue & 255;
|
||||
if (descriptortype == DEVICE) { // device descriptor
|
||||
position = descriptors;
|
||||
remain = descriptors[0];
|
||||
endpoints[endpoint].position = descriptors;
|
||||
endpoints[endpoint].remain = descriptors[0];
|
||||
}
|
||||
else if (descriptortype == CONFIGURATION) { // configuration descriptor
|
||||
position = descriptors + 18;
|
||||
remain = descriptors[18+2];
|
||||
endpoints[endpoint].position = descriptors + 18;
|
||||
endpoints[endpoint].remain = descriptors[18 + 2];
|
||||
}
|
||||
else if (descriptortype == INTERFACE) { // interface descriptor
|
||||
position = descriptors + 18 + 9;
|
||||
remain = descriptors[18 + 9];
|
||||
endpoints[endpoint].position = descriptors + 18 + 9;
|
||||
endpoints[endpoint].remain = descriptors[18 + 9];
|
||||
}
|
||||
else if (descriptortype == ENDPOINT) { // endpoint descriptor
|
||||
position = descriptors + 18 + 9 + 9;
|
||||
remain = descriptors[18 + 9 + 9];
|
||||
endpoints[endpoint].position = descriptors + 18 + 9 + 9;
|
||||
endpoints[endpoint].remain = descriptors[18 + 9 + 9];
|
||||
}
|
||||
else
|
||||
remain = 0;
|
||||
if (remain > p->wLength)
|
||||
remain = p->wLength;
|
||||
endpoints[endpoint].remain = 0;
|
||||
if (endpoints[endpoint].remain > p->wLength)
|
||||
endpoints[endpoint].remain = p->wLength;
|
||||
break;
|
||||
case SET_CONFIGURATION:
|
||||
if (p->wValue == 0)
|
||||
state = AddressState;
|
||||
else {
|
||||
configurationvalue = p->wValue;
|
||||
select_configuration(p->wValue);
|
||||
state = ConfiguredState;
|
||||
}
|
||||
break;
|
||||
case SET_DESCRIPTOR:
|
||||
case GET_CONFIGURATION:
|
||||
case GET_INTERFACE:
|
||||
case SET_INTERFACE:
|
||||
select_alternate(p->wIndex, p->wValue);
|
||||
break;
|
||||
case SET_DESCRIPTOR:
|
||||
return handle_set_descriptor_request(endpoint, p);
|
||||
break;
|
||||
case GET_CONFIGURATION:
|
||||
endpoints[endpoint].buffer[0] = (UINT8)configurationvalue;
|
||||
endpoints[endpoint].position = endpoints[endpoint].buffer;
|
||||
endpoints[endpoint].remain = 1;
|
||||
if (p->wLength == 0)
|
||||
endpoints[endpoint].remain = 0;
|
||||
break;
|
||||
case GET_INTERFACE:
|
||||
endpoints[endpoint].buffer[0] = (UINT8)find_alternate(p->wIndex);
|
||||
endpoints[endpoint].position = endpoints[endpoint].buffer;
|
||||
endpoints[endpoint].remain = 1;
|
||||
if (p->wLength == 0)
|
||||
endpoints[endpoint].remain = 0;
|
||||
break;
|
||||
case SYNCH_FRAME:
|
||||
return handle_synch_frame_request(endpoint, p);
|
||||
default:
|
||||
return handle_nonstandard_request(endpoint, p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return handle_nonstandard_request(p);
|
||||
return handle_nonstandard_request(endpoint, p);
|
||||
size = 0;
|
||||
}
|
||||
else if (pid == InPid) {
|
||||
else
|
||||
return handle_nonstandard_request(endpoint, p);
|
||||
}
|
||||
else if (pid == InPid) {
|
||||
if (endpoint == 0) {
|
||||
// if no data has been transferred (except for the setup stage)
|
||||
// and the lenght of this IN transaction is 0
|
||||
// assume this is the status stage
|
||||
if ((size == 0) && (remain == 0)) {
|
||||
if ((size == 0) && (endpoints[endpoint].remain == 0)) {
|
||||
if (settingaddress == true)
|
||||
{
|
||||
// set of address is active at end of status stage
|
||||
@ -980,53 +1162,58 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
|
||||
// case ==1, give data
|
||||
// case ==0, nothing
|
||||
// if device->host
|
||||
if (controldirection == 1) {
|
||||
if (endpoints[endpoint].controldirection == DeviceToHost) {
|
||||
// data stage
|
||||
if (size > remain)
|
||||
size = remain;
|
||||
if (position != nullptr)
|
||||
memcpy(buffer, position, size);
|
||||
position = position + size;
|
||||
remain = remain - size;
|
||||
if (size > endpoints[endpoint].remain)
|
||||
size = endpoints[endpoint].remain;
|
||||
if (endpoints[endpoint].position != nullptr)
|
||||
memcpy(buffer, endpoints[endpoint].position, size);
|
||||
endpoints[endpoint].position = endpoints[endpoint].position + size;
|
||||
endpoints[endpoint].remain = endpoints[endpoint].remain - size;
|
||||
}
|
||||
}
|
||||
else if (pid == OutPid) {
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else if (pid == OutPid) {
|
||||
if (endpoint == 0) {
|
||||
// case ==1, nothing
|
||||
// case ==0, give data
|
||||
// if host->device
|
||||
if (controldirection == 0) {
|
||||
if (endpoints[endpoint].controldirection == HostToDevice) {
|
||||
// data stage
|
||||
if (size > remain)
|
||||
size = remain;
|
||||
if (position != nullptr)
|
||||
memcpy(position, buffer, size);
|
||||
position = position + size;
|
||||
remain = remain - size;
|
||||
if (size > endpoints[endpoint].remain)
|
||||
size = endpoints[endpoint].remain;
|
||||
if (endpoints[endpoint].position != nullptr)
|
||||
memcpy(endpoints[endpoint].position, buffer, size);
|
||||
endpoints[endpoint].position = endpoints[endpoint].position + size;
|
||||
endpoints[endpoint].remain = endpoints[endpoint].remain - size;
|
||||
}
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
return size;
|
||||
}
|
||||
|
||||
int ohci_function_device::handle_nonstandard_request(USBSetupPacket *setup)
|
||||
int ohci_function_device::handle_nonstandard_request(int endpoint, USBSetupPacket *setup)
|
||||
{
|
||||
// >=8 ==42 !=0 !=0 1,3 2<20 <=20
|
||||
static UINT8 mytestdata[16] = { 0x10,0x42 ,0x32,0x43,1 ,0x65,0x18,0x20,0x98,0xa9,0xba,0xcb,0xdc,0xed,0xfe };
|
||||
|
||||
if ((controltype == VendorType) && (controlrecipient == InterfaceRecipient))
|
||||
if ((endpoints[endpoint].controltype == VendorType) && (endpoints[endpoint].controlrecipient == InterfaceRecipient))
|
||||
{
|
||||
if (setup->bRequest == GET_DESCRIPTOR)
|
||||
{
|
||||
if (setup->wValue == 0x4200)
|
||||
{
|
||||
position = mytestdata;
|
||||
remain = 16;
|
||||
endpoints[endpoint].position = mytestdata;
|
||||
endpoints[endpoint].remain = 16;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void xbox_base_state::usb_ohci_interrupts()
|
||||
@ -1232,8 +1419,8 @@ WRITE32_MEMBER(xbox_base_state::audio_apu_w)
|
||||
return;
|
||||
}
|
||||
if (offset == 0x2037c / 4) { // value related to sample rate
|
||||
INT16 v = (INT16)(data >> 16); // upper 16 bits as a signed 16 bit value
|
||||
float vv = ((float)v) / 4096.0f; // divide by 4096
|
||||
INT16 v0 = (INT16)(data >> 16); // upper 16 bits as a signed 16 bit value
|
||||
float vv = ((float)v0) / 4096.0f; // divide by 4096
|
||||
float vvv = powf(2, vv); // two to the vv
|
||||
int f = vvv*48000.0f; // sample rate
|
||||
apust.voices_frequency[apust.voice_number] = f;
|
||||
|
Loading…
Reference in New Issue
Block a user