xbox.cpp: more usb, usb device from chihiro baseboard now sends some data (nw)

This commit is contained in:
yz70s 2016-03-27 23:15:38 +02:00
parent 337f659072
commit 72c19c76a3
3 changed files with 89 additions and 21 deletions

View File

@ -240,8 +240,8 @@ Notes:
24LC64 - Microchip 24LC64 64K I2C Serial EEPROM (SOIC8)
24LC024 - Microchip 24LC024 2K I2C Serial EEPROM (SOIC8)
M68AF127B - ST Microelectronics 1Mbit (128K x8), 5V Asynchronous SRAM (SOP32)
AN2131QC - Cypress AN2131 EZ-USB-Family 8051-based High-Speed USB IC's (QFP80)
AN2131SC / (QFP44)
AN2131QC - Cypress AN2131 EZ-USB-Family 8051-based High-Speed USB IC's (QFP80) firmware in IC11
AN2131SC / (QFP44) firmware in IC32
ADM3222 - Analog Devices ADM3222 High-Speed, +3.3V, 2-Channel RS232/V.28 Interface Device (SOIC20)
SN65240 - Texas Instruments SN65240 USB Port Transient Suppressor (SOIC8)
BA7623 - Rohm BA7623 75-Ohm driver IC with 3 internal circuits (SOIC8)
@ -572,7 +572,7 @@ static const struct {
UINT32 address;
UINT8 write_byte;
} modify[16];
} hacks[2] = { { "chihiro", { { 0x6a79f, 0x01 }, { 0x6a7a0, 0x00 }, { 0x6b575, 0x00 }, { 0x6b576, 0x00 }, { 0x6b5af, 0x75 }, { 0x6b78a, 0x75 }, { 0x6b7ca, 0x00 }, { 0x6b7b8, 0x00 }, { 0x8f5b2, 0x75 }, { 0x79a9e, 0x74 }, { 0x79b80, 0x74 }, { 0x79b97, 0x74 }, { 0, 0 } } },
} hacks[2] = { { "chihiro", { { 0x6a79f/*3f79f*/, 0x01 }, { 0x6a7a0/*3f7a0*/, 0x00 }, { 0x6b575/*40575*/, 0x00 }, { 0x6b576/*40576*/, 0x00 }, { 0x6b5af/*405af*/, 0x75 }, { 0x6b78a/*4078a*/, 0x75 }, { 0x6b7ca/*407ca*/, 0x00 }, { 0x6b7b8/*407b8*/, 0x00 }, { 0x8f5b2, 0x75 }, { 0x79a9e/*2ea9e*/, 0x74 }, { 0x79b80/*2eb80*/, 0x74 }, { 0x79b97/*2eb97*/, 0x74 }, { 0, 0 } } },
{ "outr2", { { 0x12e4cf, 0x01 }, { 0x12e4d0, 0x00 }, { 0x4793e, 0x01 }, { 0x4793f, 0x00 }, { 0x47aa3, 0x01 }, { 0x47aa4, 0x00 }, { 0x14f2b6, 0x84 }, { 0x14f2d1, 0x75 }, { 0x8732f, 0x7d }, { 0x87384, 0x7d }, { 0x87388, 0xeb }, { 0, 0 } } } };
void chihiro_state::hack_usb()

View File

@ -261,7 +261,7 @@ 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) ;
int execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size);
protected:
virtual int handle_nonstandard_request(int endpoint, USBSetupPacket *setup) { return -1; };
virtual int handle_get_status_request(int endpoint, USBSetupPacket *setup) { return 0; };
@ -269,6 +269,8 @@ protected:
virtual int handle_set_feature_request(int endpoint, USBSetupPacket *setup) { return 0; };
virtual int handle_set_descriptor_request(int endpoint, USBSetupPacket *setup) { return 0; };
virtual int handle_synch_frame_request(int endpoint, USBSetupPacket *setup) { return 0; };
virtual void handle_status_stage(int endpoint) { return; };
virtual int handle_bulk_pid(int endpoint, int pid, UINT8 *buffer, int size) { return 0; };
void add_device_descriptor(const USBStandardDeviceDescriptor &descriptor);
void add_configuration_descriptor(const USBStandardConfigurationDescriptor &descriptor);
@ -297,6 +299,7 @@ protected:
int configurationvalue;
UINT8 *descriptors;
int descriptors_pos;
bool wantstatuscallback;
USBStandardDeviceDescriptor device_descriptor;
std::forward_list<usb_device_configuration *> configurations;
std::forward_list<usb_device_string *> device_strings;
@ -323,6 +326,8 @@ class ohci_hlean2131qc_device: public ohci_function_device
public:
ohci_hlean2131qc_device(running_machine &machine);
int handle_nonstandard_request(int endpoint, USBSetupPacket *setup) override;
int handle_bulk_pid(int endpoint, int pid, UINT8 *buffer, int size) override;
void set_region_base(UINT8 *data);
private:
static const USBStandardDeviceDescriptor devdesc;
static const USBStandardConfigurationDescriptor condesc;
@ -340,6 +345,8 @@ private:
static const UINT8 strdesc0[];
static const UINT8 strdesc1[];
static const UINT8 strdesc2[];
int maximum_send;
UINT8 *region;
};
class ohci_hlean2131sc_device : public ohci_function_device

View File

@ -984,6 +984,7 @@ ohci_function_device::ohci_function_device(running_machine &machine)
endpoints[e].position = nullptr;
}
endpoints[0].type = ControlEndpoint;
wantstatuscallback = false;
settingaddress = false;
configurationvalue = 0;
selected_configuration = nullptr;
@ -1253,13 +1254,22 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
if (pid == SetupPid) {
USBSetupPacket *p=(USBSetupPacket *)buffer;
// control transfers are done in 3 stages: first the setup stage, then an optional data stage, then a status stage
// so there are 3 cases:
// 1- control transfer with a data stage where the host sends data to the device
// in this case the sequence of pids transferred is control pid, data out pid, data in pid
// 2- control transfer with a data stage where the host receives data from the device
// in this case the sequence of pids transferred is control pid, data in pid, data out pid
// 3- control transfer without a data stage
// in this case the sequence of pids transferred is control pid, data in pid
// 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
// direction == 1 -> IN data stage and OUT status stage
// direction == 0 -> OUT data stage and IN status stage
// data stage not present -> IN status stage
endpoints[endpoint].controldirection = (p->bmRequestType & 128) >> 7;
endpoints[endpoint].controltype = (p->bmRequestType & 0x60) >> 5;
endpoints[endpoint].controlrecipient = p->bmRequestType & 0x1f;
wantstatuscallback = false;
if (endpoint == 0) {
endpoints[endpoint].position = nullptr;
// number of byte to transfer in data stage (0 no data stage)
@ -1341,23 +1351,26 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
return handle_nonstandard_request(endpoint, p);
}
else if (pid == InPid) {
if (endpoint == 0) {
if (endpoints[endpoint].type == ControlEndpoint) { //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) && (endpoints[endpoint].remain == 0)) {
if (settingaddress == true)
if ((endpoints[endpoint].remain == 0) && (size == 0)) {
if ((endpoint == 0) && (settingaddress == true))
{
// set of address is active at end of status stage
address = newaddress;
settingaddress = false;
state = AddressState;
}
if (wantstatuscallback == true)
handle_status_stage(endpoint);
wantstatuscallback = false;
return 0;
}
// case ==1, give data
// case ==0, nothing
// if device->host
// if device->host, since InPid then this is data stage
if (endpoints[endpoint].controldirection == DeviceToHost) {
// data stage
if (size > endpoints[endpoint].remain)
@ -1367,15 +1380,22 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
endpoints[endpoint].position = endpoints[endpoint].position + size;
endpoints[endpoint].remain = endpoints[endpoint].remain - size;
}
else {
if (wantstatuscallback == true)
handle_status_stage(endpoint);
wantstatuscallback = false;
}
}
else if (endpoints[endpoint].type == BulkEndpoint)
return handle_bulk_pid(endpoint, pid, buffer, size);
else
return -1;
}
else if (pid == OutPid) {
if (endpoint == 0) {
if (endpoints[endpoint].type == ControlEndpoint) { //if (endpoint == 0) {
// case ==1, nothing
// case ==0, give data
// if host->device
// if host->device, since OutPid then this is data stage
if (endpoints[endpoint].controldirection == HostToDevice) {
// data stage
if (size > endpoints[endpoint].remain)
@ -1385,7 +1405,14 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
endpoints[endpoint].position = endpoints[endpoint].position + size;
endpoints[endpoint].remain = endpoints[endpoint].remain - size;
}
else {
if (wantstatuscallback == true)
handle_status_stage(endpoint);
wantstatuscallback = false;
}
}
else if (endpoints[endpoint].type == BulkEndpoint)
return handle_bulk_pid(endpoint, pid, buffer, size);
else
return -1;
}
@ -1454,25 +1481,43 @@ ohci_hlean2131qc_device::ohci_hlean2131qc_device(running_machine &machine) :
add_device_descriptor(devdesc);
add_configuration_descriptor(condesc);
add_interface_descriptor(intdesc);
add_endpoint_descriptor(enddesc81);
add_endpoint_descriptor(enddesc82);
add_endpoint_descriptor(enddesc83);
add_endpoint_descriptor(enddesc84);
add_endpoint_descriptor(enddesc85);
// it is important to add the endpoints in the same order they are found in the device firmware
add_endpoint_descriptor(enddesc01);
add_endpoint_descriptor(enddesc02);
add_endpoint_descriptor(enddesc03);
add_endpoint_descriptor(enddesc04);
add_endpoint_descriptor(enddesc05);
add_endpoint_descriptor(enddesc81);
add_endpoint_descriptor(enddesc82);
add_endpoint_descriptor(enddesc83);
add_endpoint_descriptor(enddesc84);
add_endpoint_descriptor(enddesc85);
add_string_descriptor(strdesc0);
add_string_descriptor(strdesc1);
add_string_descriptor(strdesc2);
maximum_send = 0;
region = nullptr;
}
void ohci_hlean2131qc_device::set_region_base(UINT8 *data)
{
region = data;
}
int ohci_hlean2131qc_device::handle_nonstandard_request(int endpoint, USBSetupPacket *setup)
{
if (endpoint != 0)
return -1;
printf("Control request: %x %x %x %x %x %x %x\n\r", endpoint, endpoints[endpoint].controldirection, setup->bmRequestType, setup->bRequest, setup->wValue, setup->wIndex, setup->wLength);
//if ((setup->bRequest == 0x18) && (setup->wValue == 0x8000))
if (setup->bRequest == 0x17)
{
maximum_send = setup->wIndex;
if (maximum_send > 0x40)
maximum_send = 0x40;
endpoints[2].remain = maximum_send;
endpoints[2].position = region + 0x2000 + setup->wValue;
}
for (int n = 0; n < setup->wLength; n++)
endpoints[endpoint].buffer[n] = 0xa0 ^ n;
endpoints[endpoint].buffer[0] = 0;
@ -1481,6 +1526,20 @@ int ohci_hlean2131qc_device::handle_nonstandard_request(int endpoint, USBSetupPa
return 0;
}
int ohci_hlean2131qc_device::handle_bulk_pid(int endpoint, int pid, UINT8 *buffer, int size)
{
printf("Bulk request: %x %d %x\n\r", endpoint, pid, size);
if ((endpoint == 2) && (pid == InPid))
{
if (size > endpoints[2].remain)
size = endpoints[2].remain;
memcpy(buffer, endpoints[2].position, size);
endpoints[2].position = endpoints[3].position + size;
endpoints[2].remain = endpoints[3].remain - size;
}
return size;
}
//pc20
const USBStandardDeviceDescriptor ohci_hlean2131sc_device::devdesc = { 0x12,0x01,0x0100,0x60,0x01,0x00,0x40,0x0CA3,0x0003,0x0110,0x01,0x02,0x00,0x01 };
const USBStandardConfigurationDescriptor ohci_hlean2131sc_device::condesc = { 0x09,0x02,0x003C,0x01,0x01,0x00,0x80,0x96 };
@ -1501,12 +1560,13 @@ ohci_hlean2131sc_device::ohci_hlean2131sc_device(running_machine &machine) :
add_device_descriptor(devdesc);
add_configuration_descriptor(condesc);
add_interface_descriptor(intdesc);
add_endpoint_descriptor(enddesc81);
add_endpoint_descriptor(enddesc82);
add_endpoint_descriptor(enddesc83);
// it is important to add the endpoints in the same order they are found in the device firmware
add_endpoint_descriptor(enddesc01);
add_endpoint_descriptor(enddesc02);
add_endpoint_descriptor(enddesc03);
add_endpoint_descriptor(enddesc81);
add_endpoint_descriptor(enddesc82);
add_endpoint_descriptor(enddesc83);
add_string_descriptor(strdesc0);
add_string_descriptor(strdesc1);
add_string_descriptor(strdesc2);
@ -2221,6 +2281,7 @@ void xbox_base_state::machine_start()
ohcist.timer->enable(false);
//usb_device = new ohci_game_controller_device(machine());
usb_device = new ohci_hlean2131qc_device(machine());
usb_device->set_region_base(memregion(":others")->base()); // temporary, should be in chihiro
//usb_device = new ohci_hlean2131sc_device(machine());
usb_ohci_plug(1, usb_device); // test connect
#endif