mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
xbox.cpp: more usb, possible to have more than 1 usb device plugged at the same time (nw)
This commit is contained in:
parent
595d930f25
commit
8022a8285e
@ -385,7 +385,7 @@ Thanks to Alex, Mr Mudkips, and Philip Burke for this info.
|
||||
class ohci_hlean2131qc_device : public ohci_function_device
|
||||
{
|
||||
public:
|
||||
ohci_hlean2131qc_device(running_machine &machine);
|
||||
ohci_hlean2131qc_device(running_machine &machine, xbox_base_state *usb_bus_manager);
|
||||
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);
|
||||
@ -413,7 +413,7 @@ private:
|
||||
class ohci_hlean2131sc_device : public ohci_function_device
|
||||
{
|
||||
public:
|
||||
ohci_hlean2131sc_device(running_machine &machine);
|
||||
ohci_hlean2131sc_device(running_machine &machine, xbox_base_state *usb_bus_manager);
|
||||
int handle_nonstandard_request(int endpoint, USBSetupPacket *setup) override;
|
||||
private:
|
||||
static const USBStandardDeviceDescriptor devdesc;
|
||||
@ -665,8 +665,8 @@ const UINT8 ohci_hlean2131qc_device::strdesc0[] = { 0x04,0x03,0x00,0x00 };
|
||||
const UINT8 ohci_hlean2131qc_device::strdesc1[] = { 0x0A,0x03,0x53,0x00,0x45,0x00,0x47,0x00,0x41,0x00 };
|
||||
const UINT8 ohci_hlean2131qc_device::strdesc2[] = { 0x0E,0x03,0x42,0x00,0x41,0x00,0x53,0x00,0x45,0x00,0x42,0x03,0xFF,0x0B };
|
||||
|
||||
ohci_hlean2131qc_device::ohci_hlean2131qc_device(running_machine &machine) :
|
||||
ohci_function_device(machine)
|
||||
ohci_hlean2131qc_device::ohci_hlean2131qc_device(running_machine &machine, xbox_base_state *usb_bus_manager) :
|
||||
ohci_function_device(machine, usb_bus_manager)
|
||||
{
|
||||
add_device_descriptor(devdesc);
|
||||
add_configuration_descriptor(condesc);
|
||||
@ -712,17 +712,22 @@ int ohci_hlean2131qc_device::handle_nonstandard_request(int endpoint, USBSetupPa
|
||||
}
|
||||
if ((setup->bRequest == 0x16) && (setup->wValue == 0x1f00))
|
||||
{
|
||||
// should be for an2131sc
|
||||
endpoints[1].remain = setup->wIndex;
|
||||
endpoints[1].position = region + 0x1f00;
|
||||
}
|
||||
if (setup->bRequest == 0x19) // 19 used to receive jvs packet, 20 to send
|
||||
if (setup->bRequest == 0x19) // 19 used to receive packet, 20 to send ?
|
||||
{
|
||||
endpoints[endpoint].buffer[5] = 0;
|
||||
endpoints[endpoint].buffer[4] = 20;
|
||||
// amount to transfer
|
||||
endpoints[endpoint].buffer[5] = 20 >> 8;
|
||||
endpoints[endpoint].buffer[4] = (20 & 0xff);
|
||||
endpoints[4].remain = 20;
|
||||
endpoints[4].position = endpoints[4].buffer;
|
||||
memset(endpoints[4].buffer, 0, 20);
|
||||
}
|
||||
if (setup->bRequest == 0x20)
|
||||
{
|
||||
printf("\tJvs packet of %d bytes\n\r", setup->wIndex);
|
||||
printf(" Jvs packet of %d bytes\n\r", setup->wIndex-3);
|
||||
}
|
||||
|
||||
endpoints[endpoint].buffer[0] = 0;
|
||||
@ -734,7 +739,7 @@ int ohci_hlean2131qc_device::handle_nonstandard_request(int endpoint, USBSetupPa
|
||||
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 == 1) || (endpoint == 2)) && (pid == InPid))
|
||||
if (((endpoint == 1) || (endpoint == 2) || (endpoint == 4)) && (pid == InPid))
|
||||
{
|
||||
if (size > endpoints[endpoint].remain)
|
||||
size = endpoints[endpoint].remain;
|
||||
@ -742,6 +747,12 @@ int ohci_hlean2131qc_device::handle_bulk_pid(int endpoint, int pid, UINT8 *buffe
|
||||
endpoints[endpoint].position = endpoints[endpoint].position + size;
|
||||
endpoints[endpoint].remain = endpoints[endpoint].remain - size;
|
||||
}
|
||||
if ((endpoint == 4) && (pid == OutPid))
|
||||
{
|
||||
for (int n = 0; n < size; n++)
|
||||
printf(" %02x",buffer[n]);
|
||||
printf("\n\r");
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@ -759,8 +770,8 @@ const UINT8 ohci_hlean2131sc_device::strdesc0[] = { 0x04,0x03,0x00,0x00 };
|
||||
const UINT8 ohci_hlean2131sc_device::strdesc1[] = { 0x0A,0x03,0x53,0x00,0x45,0x00,0x47,0x00,0x41,0x00 };
|
||||
const UINT8 ohci_hlean2131sc_device::strdesc2[] = { 0x0E,0x03,0x42,0x00,0x41,0x00,0x53,0x00,0x45,0x00,0x42,0x00,0x44,0x00 };
|
||||
|
||||
ohci_hlean2131sc_device::ohci_hlean2131sc_device(running_machine &machine) :
|
||||
ohci_function_device(machine)
|
||||
ohci_hlean2131sc_device::ohci_hlean2131sc_device(running_machine &machine, xbox_base_state *usb_bus_manager) :
|
||||
ohci_function_device(machine, usb_bus_manager)
|
||||
{
|
||||
add_device_descriptor(devdesc);
|
||||
add_configuration_descriptor(condesc);
|
||||
@ -1058,7 +1069,7 @@ void chihiro_state::machine_start()
|
||||
break;
|
||||
}
|
||||
usbhack_counter = 0;
|
||||
usb_device = new ohci_hlean2131qc_device(machine());
|
||||
usb_device = new ohci_hlean2131qc_device(machine(), this);
|
||||
usb_device->set_region_base(memregion(":others")->base()); // temporary
|
||||
//usb_device = new ohci_hlean2131sc_device(machine());
|
||||
usb_ohci_plug(1, usb_device); // connect
|
||||
|
@ -70,6 +70,45 @@ enum OHCIRegisters {
|
||||
HcRhPortStatus1
|
||||
};
|
||||
|
||||
enum HcControlBits
|
||||
{
|
||||
CBSR = 1 << 0, // ControlBulkServiceRatio
|
||||
PLE = 1 << 2, // PeriodicListEnable
|
||||
IE = 1 << 3, // IsochronousEnable
|
||||
CLE = 1 << 4, // ControlListEnable
|
||||
BLE = 1 << 5, // BulkListEnable
|
||||
HCFS = 1 << 6, // HostControllerFunctionalState
|
||||
IR = 1 << 8, // InterruptRouting
|
||||
RWC = 1 << 9, // RemoteWakeupConnected
|
||||
RWE = 1 << 10 // RemoteWakeupEnable
|
||||
};
|
||||
|
||||
enum HcRhStatusBits
|
||||
{
|
||||
LPS = 1 << 0, // LocalPowerStatus
|
||||
OCI = 1 << 1, // OverCurrentIndicator
|
||||
DRWE = 1 << 15, // DeviceRemoteWakeupEnable
|
||||
LPSC = 1 << 16, // LocalPowerStatusChange
|
||||
OCIC = 1 << 17, // OverCurrentIndicatorChange
|
||||
CRWE = 1 << 31, // ClearRemoteWakeupEnable
|
||||
};
|
||||
|
||||
enum HcRhPortStatusBits
|
||||
{
|
||||
CCS = 1 << 0, // CurrentConnectStatus
|
||||
PES = 1 << 1, // PortEnableStatus
|
||||
PSS = 1 << 2, // PortSuspendStatus
|
||||
POCI = 1 << 3, // PortOverCurrentIndicator
|
||||
PRS = 1 << 4, // PortResetStatus
|
||||
PPS = 1 << 8, // PortPowerStatus
|
||||
LSDA = 1 << 9, // LowSpeedDeviceAttached
|
||||
CSC = 1 << 16, // ConnectStatusChange
|
||||
PESC = 1 << 17, // PortEnableStatusChange
|
||||
PSSC = 1 << 18, // PortSuspendStatusChange
|
||||
POCIC = 1 << 19, // PortOverCurrentIndicatorChange
|
||||
PRSC = 1 << 20 // PortResetStatusChange
|
||||
};
|
||||
|
||||
enum OHCIHostControllerFunctionalState {
|
||||
UsbReset=0,
|
||||
UsbResume,
|
||||
@ -257,11 +296,15 @@ struct usb_device_configuration
|
||||
std::forward_list<usb_device_interface *> interfaces;
|
||||
};
|
||||
|
||||
class xbox_base_state; // forward declaration
|
||||
|
||||
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);
|
||||
ohci_function_device(running_machine &machine, xbox_base_state *usb_bus_manager);
|
||||
virtual void execute_reset();
|
||||
virtual void execute_connect() {};
|
||||
virtual void execute_disconnect() {};
|
||||
int execute_transfer(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; };
|
||||
@ -283,6 +326,7 @@ protected:
|
||||
UINT8 *position_device_descriptor(int &size);
|
||||
UINT8 *position_configuration_descriptor(int index, int &size);
|
||||
UINT8 *position_string_descriptor(int index, int &size);
|
||||
xbox_base_state *busmanager;
|
||||
struct {
|
||||
int type;
|
||||
int controldirection;
|
||||
@ -311,7 +355,7 @@ protected:
|
||||
class ohci_game_controller_device : public ohci_function_device
|
||||
{
|
||||
public:
|
||||
ohci_game_controller_device(running_machine &machine);
|
||||
ohci_game_controller_device(running_machine &machine, xbox_base_state *usb_bus_manager);
|
||||
int handle_nonstandard_request(int endpoint, USBSetupPacket *setup) override;
|
||||
private:
|
||||
static const USBStandardDeviceDescriptor devdesc;
|
||||
@ -360,8 +404,7 @@ public:
|
||||
void usb_ohci_writeback_transfer_descriptor(UINT32 address);
|
||||
void usb_ohci_read_isochronous_transfer_descriptor(UINT32 address);
|
||||
void usb_ohci_writeback_isochronous_transfer_descriptor(UINT32 address);
|
||||
void dword_write_le(UINT8 *addr, UINT32 d);
|
||||
void word_write_le(UINT8 *addr, UINT16 d);
|
||||
void usb_ohci_device_address_changed(int old_address, int new_address);
|
||||
void debug_generate_irq(int irq, bool active);
|
||||
virtual void hack_eeprom() {};
|
||||
virtual void hack_usb() {};
|
||||
@ -422,8 +465,14 @@ public:
|
||||
UINT32 hc_regs[255];
|
||||
struct {
|
||||
ohci_function_device *function;
|
||||
int address;
|
||||
int delay;
|
||||
} ports[4 + 1];
|
||||
struct
|
||||
{
|
||||
ohci_function_device *function;
|
||||
int port;
|
||||
} address[256];
|
||||
emu_timer *timer;
|
||||
int state;
|
||||
UINT32 framenumber;
|
||||
|
@ -492,7 +492,7 @@ static void geforce_pci_w(device_t *busdevice, device_t *device, int function, i
|
||||
}
|
||||
|
||||
/*
|
||||
* ohci usb controller (placeholder for now)
|
||||
* ohci usb controller
|
||||
*/
|
||||
|
||||
#ifdef LOG_OHCI
|
||||
@ -552,30 +552,36 @@ WRITE32_MEMBER(xbox_base_state::usbctrl_w)
|
||||
logerror("usb controller 0 register %s write %08X\n", usbregnames[offset], data);
|
||||
#endif
|
||||
if (offset == HcRhStatus) {
|
||||
if (data & 0x80000000)
|
||||
ohcist.hc_regs[HcRhStatus] &= ~0x8000;
|
||||
if (data & 0x00020000)
|
||||
ohcist.hc_regs[HcRhStatus] &= ~0x0002;
|
||||
if (data & 0x00010000)
|
||||
ohcist.hc_regs[HcRhStatus] &= ~0x0001;
|
||||
if (data & CRWE)
|
||||
ohcist.hc_regs[HcRhStatus] &= ~DRWE;
|
||||
if (data & OCIC)
|
||||
ohcist.hc_regs[HcRhStatus] &= ~OCI;
|
||||
if (data & LPSC)
|
||||
ohcist.hc_regs[HcRhStatus] &= ~LPS;
|
||||
return;
|
||||
}
|
||||
if (offset == HcControl) {
|
||||
int hcfs;
|
||||
|
||||
hcfs = (data >> 6) & 3;
|
||||
hcfs = (data >> 6) & 3; // HostControllerFunctionalState
|
||||
if (hcfs == UsbOperational) {
|
||||
ohcist.timer->enable();
|
||||
ohcist.timer->adjust(attotime::from_msec(1), 0, attotime::from_msec(1));
|
||||
ohcist.writebackdonehadcounter = 7;
|
||||
// need to load the FrameRemaining field of HcFmRemaining with the value of the FrameInterval field in HcFmInterval
|
||||
}
|
||||
else
|
||||
ohcist.timer->enable(false);
|
||||
ohcist.state = hcfs;
|
||||
ohcist.interruptbulkratio = (data & 3) + 1;
|
||||
if ((hcfs != UsbReset) && (ohcist.state == UsbReset))
|
||||
{
|
||||
ohcist.hc_regs[HcInterruptStatus] |= RootHubStatusChange;
|
||||
usb_ohci_interrupts();
|
||||
}
|
||||
ohcist.state = hcfs;
|
||||
}
|
||||
if (offset == HcCommandStatus) {
|
||||
if (data & 1)
|
||||
if (data & 1) // HostControllerReset
|
||||
ohcist.hc_regs[HcControl] |= 3 << 6;
|
||||
ohcist.hc_regs[HcCommandStatus] |= data;
|
||||
return;
|
||||
@ -597,24 +603,69 @@ WRITE32_MEMBER(xbox_base_state::usbctrl_w)
|
||||
}
|
||||
if (offset >= HcRhPortStatus1) {
|
||||
int port = offset - HcRhPortStatus1 + 1; // port 0 not used
|
||||
// bit 0 ClearPortEnable: 1 clears PortEnableStatus
|
||||
// bit 1 SetPortEnable: 1 sets PortEnableStatus
|
||||
// bit 2 SetPortSuspend: 1 sets PortSuspendStatus
|
||||
// bit 3 ClearSuspendStatus: 1 clears PortSuspendStatus
|
||||
// bit 4 SetPortReset: 1 sets PortResetStatus
|
||||
if (data & 0x10) {
|
||||
ohcist.hc_regs[offset] |= 0x10;
|
||||
// bit 0 R:CurrentConnectStatus W:ClearPortEnable: 1 clears PortEnableStatus
|
||||
if (data & CCS) {
|
||||
ohcist.hc_regs[offset] &= ~PES;
|
||||
ohcist.address[ohcist.ports[port].address].port = -1;
|
||||
}
|
||||
// bit 1 R:PortEnableStatus W:SetPortEnable: 1 sets PortEnableStatus
|
||||
if (data & PES) {
|
||||
ohcist.hc_regs[offset] |= PES;
|
||||
// the port is enabled, so the device connected to it can communicate on the bus
|
||||
ohcist.address[ohcist.ports[port].address].function = ohcist.ports[port].function;
|
||||
ohcist.address[ohcist.ports[port].address].port = port;
|
||||
}
|
||||
// bit 2 R:PortSuspendStatus W:SetPortSuspend: 1 sets PortSuspendStatus
|
||||
if (data & PSS) {
|
||||
ohcist.hc_regs[offset] |= PSS;
|
||||
}
|
||||
// bit 3 R:PortOverCurrentIndicator W:ClearSuspendStatus: 1 clears PortSuspendStatus
|
||||
if (data & POCI) {
|
||||
ohcist.hc_regs[offset] &= ~PSS;
|
||||
}
|
||||
// bit 4 R: PortResetStatus W:SetPortReset: 1 sets PortResetStatus
|
||||
if (data & PRS) {
|
||||
ohcist.hc_regs[offset] |= PRS;
|
||||
if (ohcist.ports[port].address >= 0)
|
||||
ohcist.address[ohcist.ports[port].address].port = -1;
|
||||
ohcist.ports[port].address = 0;
|
||||
if (ohcist.hc_regs[offset] & PES)
|
||||
{
|
||||
ohcist.address[0].function = ohcist.ports[port].function;
|
||||
ohcist.address[0].port = port;
|
||||
}
|
||||
ohcist.ports[port].function->execute_reset();
|
||||
// after 10ms set PortResetStatusChange and clear PortResetStatus and set PortEnableStatus
|
||||
ohcist.ports[port].delay = 10;
|
||||
}
|
||||
// bit 8 SetPortPower: 1 sets PortPowerStatus
|
||||
// bit 9 ClearPortPower: 1 clears PortPowerStatus
|
||||
// bit 16 1 clears ConnectStatusChange
|
||||
// bit 17 1 clears PortEnableStatusChange
|
||||
// bit 18 1 clears PortSuspendStatusChange
|
||||
// bit 19 1 clears PortOverCurrentIndicatorChange
|
||||
// bit 20 1 clears PortResetStatusChange
|
||||
// bit 8 R:PortPowerStatus W:SetPortPower: 1 sets PortPowerStatus
|
||||
if (data & PPS) {
|
||||
ohcist.hc_regs[offset] |= PPS;
|
||||
}
|
||||
// bit 9 R:LowSpeedDeviceAttached W:ClearPortPower: 1 clears PortPowerStatus
|
||||
if (data & LSDA) {
|
||||
ohcist.hc_regs[offset] &= ~PPS;
|
||||
}
|
||||
// bit 16 R:ConnectStatusChange W: 1 clears ConnectStatusChange
|
||||
if (data & CSC) {
|
||||
ohcist.hc_regs[offset] &= ~CSC;
|
||||
}
|
||||
// bit 17 R:PortEnableStatusChange W: 1 clears PortEnableStatusChange
|
||||
if (data & PESC) {
|
||||
ohcist.hc_regs[offset] &= ~PESC;
|
||||
}
|
||||
// bit 18 R:PortSuspendStatusChange W: 1 clears PortSuspendStatusChange
|
||||
if (data & PSSC) {
|
||||
ohcist.hc_regs[offset] &= ~PSSC;
|
||||
}
|
||||
// bit 19 R:PortOverCurrentIndicatorChange W: 1 clears PortOverCurrentIndicatorChange
|
||||
if (data & POCIC) {
|
||||
ohcist.hc_regs[offset] &= ~POCIC;
|
||||
}
|
||||
// bit 20 R:PortResetStatusChange W: 1 clears PortResetStatusChange
|
||||
if (data & PRSC) {
|
||||
ohcist.hc_regs[offset] &= ~PRSC;
|
||||
}
|
||||
if (ohcist.hc_regs[offset] != old)
|
||||
ohcist.hc_regs[HcInterruptStatus] |= RootHubStatusChange;
|
||||
usb_ohci_interrupts();
|
||||
@ -644,7 +695,9 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
if (ohcist.ports[p].delay > 0) {
|
||||
ohcist.ports[p].delay--;
|
||||
if (ohcist.ports[p].delay == 0) {
|
||||
ohcist.hc_regs[HcRhPortStatus1 + p - 1] = (ohcist.hc_regs[HcRhPortStatus1 + p - 1] & ~(1 << 4)) | (1 << 20) | (1 << 1); // bit 1 PortEnableStatus
|
||||
ohcist.hc_regs[HcRhPortStatus1 + p - 1] = (ohcist.hc_regs[HcRhPortStatus1 + p - 1] & ~PRS) | PRSC | PES;
|
||||
ohcist.address[ohcist.ports[p].address].function = ohcist.ports[p].function;
|
||||
ohcist.address[ohcist.ports[p].address].port = p;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
@ -654,9 +707,9 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
{
|
||||
// select list, do transfer
|
||||
if (list == 0) {
|
||||
if (ohcist.hc_regs[HcControl] & (1 << 2)) {
|
||||
if (ohcist.hc_regs[HcControl] & PLE) {
|
||||
// periodic list
|
||||
if (ohcist.hc_regs[HcControl] & (1 << 3)) {
|
||||
if (ohcist.hc_regs[HcControl] & IE) {
|
||||
// isochronous list
|
||||
}
|
||||
}
|
||||
@ -665,7 +718,7 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
if (list == 1) {
|
||||
// control list
|
||||
// check if control list active
|
||||
if (ohcist.hc_regs[HcControl] & (1 << 4)) {
|
||||
if (ohcist.hc_regs[HcControl] & CLE) {
|
||||
cont = true;
|
||||
while (cont == true) {
|
||||
// if current endpoint descriptor is not 0 use it, otherwise ...
|
||||
@ -736,8 +789,8 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
}
|
||||
}
|
||||
// should check for time available
|
||||
// execute transaction
|
||||
done=ohcist.ports[1].function->execute_transfer(ohcist.endpoint_descriptor.fa, ohcist.endpoint_descriptor.en, pid, ohcist.buffer, mps);
|
||||
// execute transaction ohcist.endpoint_descriptor.fa
|
||||
done = ohcist.address[ohcist.endpoint_descriptor.fa].function->execute_transfer(ohcist.endpoint_descriptor.en, pid, ohcist.buffer, mps);
|
||||
// if receiving ...
|
||||
if (pid == InPid) {
|
||||
// ... store done bytes
|
||||
@ -751,7 +804,7 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
// status writeback (CompletionCode field, DataToggleControl field, CurrentBufferPointer field, ErrorCount field)
|
||||
ohcist.transfer_descriptor.cc = NoError;
|
||||
ohcist.transfer_descriptor.t = (ohcist.transfer_descriptor.t ^ 1) | 2;
|
||||
// if all data is transferred (or there was no data to transfer) cbp must be 0 ?
|
||||
// if all data is transferred (or there was no data to transfer) cbp must be 0, otherwise it must be updated
|
||||
if ((done == remain) || (pid == SetupPid))
|
||||
b = 0;
|
||||
ohcist.transfer_descriptor.cbp = b;
|
||||
@ -793,7 +846,7 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
// one bulk every n control transfers
|
||||
ohcist.interruptbulkratio--;
|
||||
if (ohcist.interruptbulkratio <= 0) {
|
||||
ohcist.interruptbulkratio = (ohcist.hc_regs[HcControl] & 3) + 1;
|
||||
ohcist.interruptbulkratio = (ohcist.hc_regs[HcControl] & 3) + 1; // ControlBulkServiceRatio
|
||||
cont = false;
|
||||
}
|
||||
}
|
||||
@ -803,7 +856,7 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
if (list == 2) {
|
||||
// bulk list
|
||||
// check if bulk list active
|
||||
if (ohcist.hc_regs[HcControl] & (1 << 5)) {
|
||||
if (ohcist.hc_regs[HcControl] & BLE) {
|
||||
// if current endpoint descriptor is not 0 use it, otherwise ...
|
||||
if (ohcist.hc_regs[HcBulkCurrentED] == 0) {
|
||||
// ... check the filled bit ...
|
||||
@ -868,8 +921,8 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
}
|
||||
}
|
||||
// should check for time available
|
||||
// execute transaction
|
||||
done = ohcist.ports[1].function->execute_transfer(ohcist.endpoint_descriptor.fa, ohcist.endpoint_descriptor.en, pid, ohcist.buffer, mps);
|
||||
// execute transaction ohcist.endpoint_descriptor.fa
|
||||
done = ohcist.address[ohcist.endpoint_descriptor.fa].function->execute_transfer(ohcist.endpoint_descriptor.en, pid, ohcist.buffer, mps);
|
||||
// if receiving ...
|
||||
if (pid == InPid) {
|
||||
// ... store done bytes
|
||||
@ -883,7 +936,7 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
// status writeback (CompletionCode field, DataToggleControl field, CurrentBufferPointer field, ErrorCount field)
|
||||
ohcist.transfer_descriptor.cc = NoError;
|
||||
ohcist.transfer_descriptor.t = (ohcist.transfer_descriptor.t ^ 1) | 2;
|
||||
// if all data is transferred (or there was no data to transfer) cbp must be 0 ?
|
||||
// if all data is transferred (or there was no data to transfer) cbp must be 0, otherwise it must be updated
|
||||
if (done == remain)
|
||||
b = 0;
|
||||
ohcist.transfer_descriptor.cbp = b;
|
||||
@ -925,9 +978,9 @@ TIMER_CALLBACK_MEMBER(xbox_base_state::usb_ohci_timer)
|
||||
}
|
||||
}
|
||||
// go to the next list
|
||||
if ((ohcist.hc_regs[HcCommandStatus] & (1 << 1)) && (ohcist.hc_regs[HcControl] & (1 << 4)))
|
||||
if ((ohcist.hc_regs[HcCommandStatus] & (1 << 1)) && (ohcist.hc_regs[HcControl] & CLE))
|
||||
list = 1; // go to control list if enabled and filled
|
||||
else if ((ohcist.hc_regs[HcCommandStatus] & (1 << 2)) && (ohcist.hc_regs[HcControl] & (1 << 5)))
|
||||
else if ((ohcist.hc_regs[HcCommandStatus] & (1 << 2)) && (ohcist.hc_regs[HcControl] & BLE))
|
||||
list = 2; // otherwise stai in bulk list if enabled and filled
|
||||
else
|
||||
list = 0; // if no control or bulk lists, go to periodic list
|
||||
@ -960,12 +1013,19 @@ void xbox_base_state::usb_ohci_plug(int port, ohci_function_device *function)
|
||||
{
|
||||
if ((port > 0) && (port <= 4)) {
|
||||
ohcist.ports[port].function = function;
|
||||
ohcist.hc_regs[HcRhPortStatus1+port-1] = 1;
|
||||
ohcist.ports[port].address = -1;
|
||||
ohcist.hc_regs[HcRhPortStatus1+port-1] = CCS | CSC;
|
||||
if (ohcist.state != UsbReset)
|
||||
{
|
||||
ohcist.hc_regs[HcInterruptStatus] |= RootHubStatusChange;
|
||||
usb_ohci_interrupts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ohci_function_device::ohci_function_device(running_machine &machine)
|
||||
ohci_function_device::ohci_function_device(running_machine &machine, xbox_base_state *usb_bus_manager)
|
||||
{
|
||||
busmanager = usb_bus_manager;
|
||||
state = DefaultState;
|
||||
descriptors = auto_alloc_array(machine, UINT8, 1024);
|
||||
descriptors_pos = 0;
|
||||
@ -1244,7 +1304,7 @@ void ohci_function_device::execute_reset()
|
||||
newaddress = 0;
|
||||
}
|
||||
|
||||
int ohci_function_device::execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size)
|
||||
int ohci_function_device::execute_transfer(int endpoint, int pid, UINT8 *buffer, int size)
|
||||
{
|
||||
int descriptortype, descriptorindex;
|
||||
|
||||
@ -1355,6 +1415,7 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
|
||||
if ((endpoint == 0) && (settingaddress == true))
|
||||
{
|
||||
// set of address is active at end of status stage
|
||||
busmanager->usb_ohci_device_address_changed(address, newaddress);
|
||||
address = newaddress;
|
||||
settingaddress = false;
|
||||
state = AddressState;
|
||||
@ -1421,8 +1482,8 @@ const USBStandardInterfaceDescriptor ohci_game_controller_device::intdesc = { 9,
|
||||
const USBStandardEndpointDescriptor ohci_game_controller_device::enddesc82 = { 7,5,0x82,3,0x20,4 };
|
||||
const USBStandardEndpointDescriptor ohci_game_controller_device::enddesc02 = { 7,5,0x02,3,0x20,4 };
|
||||
|
||||
ohci_game_controller_device::ohci_game_controller_device(running_machine &machine) :
|
||||
ohci_function_device(machine)
|
||||
ohci_game_controller_device::ohci_game_controller_device(running_machine &machine, xbox_base_state *usb_bus_manager) :
|
||||
ohci_function_device(machine, usb_bus_manager)
|
||||
{
|
||||
add_device_descriptor(devdesc);
|
||||
add_configuration_descriptor(condesc);
|
||||
@ -1434,7 +1495,7 @@ ohci_game_controller_device::ohci_game_controller_device(running_machine &machin
|
||||
int ohci_game_controller_device::handle_nonstandard_request(int endpoint, USBSetupPacket *setup)
|
||||
{
|
||||
// >=8 ==42 !=0 !=0 1,3 2<20 <=20
|
||||
const UINT8 mytestdata[16] = { 0x10,0x42 ,0x32,0x43,1 ,0x65,0x18,0x20,0x98,0xa9,0xba,0xcb,0xdc,0xed,0xfe };
|
||||
static const UINT8 mytestdata[16] = { 0x10,0x42 ,0x32,0x43,1 ,0x65,0x18,0x20,0x98,0xa9,0xba,0xcb,0xdc,0xed,0xfe };
|
||||
|
||||
if (endpoint != 0)
|
||||
return -1;
|
||||
@ -1572,6 +1633,13 @@ void xbox_base_state::usb_ohci_writeback_isochronous_transfer_descriptor(UINT32
|
||||
ohcist.space->write_dword(address + 28, w);
|
||||
}
|
||||
|
||||
void xbox_base_state::usb_ohci_device_address_changed(int old_address, int new_address)
|
||||
{
|
||||
ohcist.address[new_address].function = ohcist.address[old_address].function;
|
||||
ohcist.address[new_address].port = ohcist.address[old_address].port;
|
||||
ohcist.address[old_address].port = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Audio
|
||||
*/
|
||||
@ -2105,7 +2173,7 @@ ADDRESS_MAP_END
|
||||
|
||||
void xbox_base_state::machine_start()
|
||||
{
|
||||
//ohci_game_controller_device *usb_device;
|
||||
ohci_game_controller_device *usb_device;
|
||||
|
||||
nvidia_nv2a = std::make_unique<nv2a_renderer>(machine());
|
||||
memset(pic16lc_buffer, 0, sizeof(pic16lc_buffer));
|
||||
@ -2140,13 +2208,19 @@ void xbox_base_state::machine_start()
|
||||
ohcist.hc_regs[HcFmInterval] = 0x2edf;
|
||||
ohcist.hc_regs[HcLSThreshold] = 0x628;
|
||||
ohcist.hc_regs[HcRhDescriptorA] = 4;
|
||||
ohcist.hc_regs[HcControl] = UsbReset << 6;
|
||||
ohcist.state = UsbReset;
|
||||
ohcist.interruptbulkratio = 1;
|
||||
ohcist.writebackdonehadcounter = 7;
|
||||
for (int n = 0; n <= 4; n++)
|
||||
ohcist.ports[n].address = -1;
|
||||
for (int n = 0; n < 256; n++)
|
||||
ohcist.address[n].port = -1;
|
||||
ohcist.space = &m_maincpu->space();
|
||||
ohcist.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(xbox_base_state::usb_ohci_timer), this), (void *)"USB OHCI Timer");
|
||||
ohcist.timer->enable(false);
|
||||
//usb_device = new ohci_game_controller_device(machine());
|
||||
//usb_ohci_plug(3, usb_device); // connect top root hub port 3, chihiro needs to use 1 and 2
|
||||
usb_device = new ohci_game_controller_device(machine(), this);
|
||||
usb_ohci_plug(3, usb_device); // connect to root hub port 3, chihiro needs to use 1 and 2
|
||||
// super-io
|
||||
memset(&superiost, 0, sizeof(superiost));
|
||||
superiost.configuration_mode = false;
|
||||
|
Loading…
Reference in New Issue
Block a user