summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author yz70s <yz70s@users.noreply.github.com>2016-04-08 08:31:47 +0200
committer yz70s <yz70s@users.noreply.github.com>2016-04-08 11:46:01 +0200
commit8022a8285ea87d03652ff8f09d57830a40c2647c (patch)
treeb0cfa86f7518068b3e80ea81d0e354055d7a72f1
parent595d930f25b245578dfed88dd08d29297f81cb38 (diff)
xbox.cpp: more usb, possible to have more than 1 usb device plugged at the same time (nw)
-rw-r--r--src/mame/drivers/chihiro.cpp35
-rw-r--r--src/mame/includes/xbox.h61
-rw-r--r--src/mame/machine/xbox.cpp168
3 files changed, 199 insertions, 65 deletions
diff --git a/src/mame/drivers/chihiro.cpp b/src/mame/drivers/chihiro.cpp
index f7961417637..dfa70a7dcee 100644
--- a/src/mame/drivers/chihiro.cpp
+++ b/src/mame/drivers/chihiro.cpp
@@ -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
diff --git a/src/mame/includes/xbox.h b/src/mame/includes/xbox.h
index 8af8e83635d..5d11a86043d 100644
--- a/src/mame/includes/xbox.h
+++ b/src/mame/includes/xbox.h
@@ -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;
diff --git a/src/mame/machine/xbox.cpp b/src/mame/machine/xbox.cpp
index 132a46e75bf..96d2a688326 100644
--- a/src/mame/machine/xbox.cpp
+++ b/src/mame/machine/xbox.cpp
@@ -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;