summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mame/drivers/chihiro.cpp3
-rw-r--r--src/mame/includes/xbox.h20
-rw-r--r--src/mame/machine/xbox.cpp189
3 files changed, 187 insertions, 25 deletions
diff --git a/src/mame/drivers/chihiro.cpp b/src/mame/drivers/chihiro.cpp
index 624c58b7b95..7e7a6e96a23 100644
--- a/src/mame/drivers/chihiro.cpp
+++ b/src/mame/drivers/chihiro.cpp
@@ -364,14 +364,11 @@ Thanks to Alex, Mr Mudkips, and Philip Burke for this info.
#include "emu.h"
#include "cpu/i386/i386.h"
-#include "machine/lpci.h"
#include "machine/pic8259.h"
-#include "machine/pit8253.h"
#include "machine/idectrl.h"
#include "machine/idehd.h"
#include "machine/naomigd.h"
#include "video/poly.h"
-#include "bitmap.h"
#include "debug/debugcon.h"
#include "debug/debugcmd.h"
#include "debug/debugcpu.h"
diff --git a/src/mame/includes/xbox.h b/src/mame/includes/xbox.h
index eec1d3655de..ea4db5c7db4 100644
--- a/src/mame/includes/xbox.h
+++ b/src/mame/includes/xbox.h
@@ -39,6 +39,8 @@ struct OHCIIsochronousTransferDescriptor {
UINT32 nexttd; // NextTD
UINT32 be; // BufferEnd
UINT32 offset[8]; // Offset/PacketStatusWord
+ UINT32 word0;
+ UINT32 word1;
};
enum OHCIRegisters {
@@ -193,7 +195,11 @@ public:
int execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size);
private:
int address;
- int controldir;
+ int newaddress;
+ int controldirection;
+ int controltype;
+ int controlrecipient;
+ bool settingaddress;
int remain;
UINT8 *position;
};
@@ -214,6 +220,10 @@ public:
DECLARE_WRITE32_MEMBER(usbctrl_w);
DECLARE_READ32_MEMBER(smbus_r);
DECLARE_WRITE32_MEMBER(smbus_w);
+ DECLARE_READ8_MEMBER(superio_read);
+ DECLARE_WRITE8_MEMBER(superio_write);
+ DECLARE_READ8_MEMBER(superiors232_read);
+ DECLARE_WRITE8_MEMBER(superiors232_write);
DECLARE_READ32_MEMBER(audio_apu_r);
DECLARE_WRITE32_MEMBER(audio_apu_w);
DECLARE_READ32_MEMBER(audio_ac93_r);
@@ -232,6 +242,7 @@ public:
void usb_ohci_read_transfer_descriptor(UINT32 address);
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 debug_generate_irq(int irq, bool active);
@@ -309,6 +320,13 @@ public:
OHCITransferDescriptor transfer_descriptor;
OHCIIsochronousTransferDescriptor isochronous_transfer_descriptor;
} ohcist;
+ struct superio_state
+ {
+ bool configuration_mode;
+ int index;
+ int selected;
+ UINT8 registers[16][256]; // 256 registers for up to 16 devices, registers 0-0x2f common to all
+ } superiost;
UINT8 pic16lc_buffer[0xff];
std::unique_ptr<nv2a_renderer> nvidia_nv2a;
bool debug_irq_active;
diff --git a/src/mame/machine/xbox.cpp b/src/mame/machine/xbox.cpp
index 73cbb24a406..7740b1545b0 100644
--- a/src/mame/machine/xbox.cpp
+++ b/src/mame/machine/xbox.cpp
@@ -7,7 +7,6 @@
#include "machine/pic8259.h"
#include "machine/pit8253.h"
#include "machine/idectrl.h"
-#include "machine/idehd.h"
#include "video/poly.h"
#include "bitmap.h"
#include "debug/debugcon.h"
@@ -17,6 +16,7 @@
#include "includes/xbox.h"
#define LOG_PCI
+//#define LOG_AUDIO
//#define LOG_OHCI
//#define USB_ENABLED
@@ -827,14 +827,17 @@ static USBStandardDeviceDscriptor devdesc = {18,1,0x201,0xff,0x34,0x56,64,0x100,
ohci_function_device::ohci_function_device()
{
address = 0;
- controldir = 0;
+ newaddress = 0;
+ controldirection = 0;
remain = 0;
position = nullptr;
+ settingaddress = false;
}
void ohci_function_device::execute_reset()
{
address = 0;
+ newaddress = 0;
}
int ohci_function_device::execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size)
@@ -842,35 +845,69 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
if (endpoint == 0) {
if (pid == SetupPid) {
struct USBSetupPacket *p=(struct USBSetupPacket *)buffer;
- // define direction
- controldir = p->bmRequestType & 128;
- // case !=0, in data stage and out status stage
- // case ==0, out data stage and in status stage
+ // 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;
remain = p->wLength;
- if ((p->bmRequestType & 0x60) == 0) {
+ // if standard
+ if (controltype == 0) {
switch (p->bRequest) {
+ case GET_STATUS:
+ case CLEAR_FEATURE:
+ case SET_FEATURE:
+ break;
+ case SET_ADDRESS:
+ newaddress = p->wValue;
+ settingaddress = true;
+ break;
case GET_DESCRIPTOR:
- if ((p->wValue >> 8) == 1) { // device descriptor
+ if ((p->wValue >> 8) == DEVICE) { // device descriptor
//p->wValue & 255;
position = (UINT8 *)&devdesc;
remain = sizeof(devdesc);
}
+ else if ((p->wValue >> 8) == CONFIGURATION) { // configuration descriptor
+ remain = 0;
+ }
+ if (remain > p->wLength)
+ remain = p->wLength;
break;
- case SET_ADDRESS:
- //p->wValue;
- break;
+ case SET_DESCRIPTOR:
+ case GET_CONFIGURATION:
+ case SET_CONFIGURATION:
+ case GET_INTERFACE:
+ case SET_INTERFACE:
+ case SYNCH_FRAME:
default:
break;
}
}
}
else if (pid == InPid) {
- // case !=0, give data
+ // 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) {
+ if (settingaddress == true)
+ {
+ // set of address is active at end of status stage
+ address = newaddress;
+ settingaddress = false;
+ }
+ return 0;
+ }
+ // case ==1, give data
// case ==0, nothing
- if (size > remain)
- size = remain;
- if (controldir != 0) {
+ // if device->host
+ if (controldirection == 1) {
+ // data stage
+ if (size > remain)
+ size = remain;
if (position != nullptr)
memcpy(buffer, position, size);
position = position + size;
@@ -878,11 +915,13 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
}
}
else if (pid == OutPid) {
- // case !=0, nothing
+ // case ==1, nothing
// case ==0, give data
- if (size > remain)
- size = remain;
- if (controldir == 0) {
+ // if host->device
+ if (controldirection == 0) {
+ // data stage
+ if (size > remain)
+ size = remain;
if (position != nullptr)
memcpy(position, buffer, size);
position = position + size;
@@ -966,11 +1005,14 @@ void xbox_base_state::usb_ohci_read_isochronous_transfer_descriptor(UINT32 addre
UINT32 w;
w = ohcist.space->read_dword(address);
+ ohcist.isochronous_transfer_descriptor.word0 = w;
ohcist.isochronous_transfer_descriptor.cc = (w >> 28) & 15;
ohcist.isochronous_transfer_descriptor.fc = (w >> 24) & 7;
ohcist.isochronous_transfer_descriptor.di = (w >> 21) & 7;
ohcist.isochronous_transfer_descriptor.sf = w & 0xffff;
- ohcist.isochronous_transfer_descriptor.bp0 = ohcist.space->read_dword(address + 4) & 0xfffff000;
+ w = ohcist.space->read_dword(address + 4);
+ ohcist.isochronous_transfer_descriptor.word1 = w;
+ ohcist.isochronous_transfer_descriptor.bp0 = w & 0xfffff000;
ohcist.isochronous_transfer_descriptor.nexttd = ohcist.space->read_dword(address + 8);
ohcist.isochronous_transfer_descriptor.be = ohcist.space->read_dword(address + 12);
w = ohcist.space->read_dword(address + 16);
@@ -987,13 +1029,37 @@ void xbox_base_state::usb_ohci_read_isochronous_transfer_descriptor(UINT32 addre
ohcist.isochronous_transfer_descriptor.offset[7] = (w >> 16) & 0xffff;
}
+void xbox_base_state::usb_ohci_writeback_isochronous_transfer_descriptor(UINT32 address)
+{
+ UINT32 w;
+
+ w = ohcist.isochronous_transfer_descriptor.word0 & 0x1f0000;
+ w = w | (ohcist.isochronous_transfer_descriptor.cc << 28) | (ohcist.isochronous_transfer_descriptor.fc << 24) | (ohcist.isochronous_transfer_descriptor.di << 21) | ohcist.isochronous_transfer_descriptor.sf;
+ ohcist.space->write_dword(address, w);
+ w = ohcist.isochronous_transfer_descriptor.word1 & 0xfff;
+ w = w | ohcist.isochronous_transfer_descriptor.bp0;
+ ohcist.space->write_dword(address + 4, w);
+ ohcist.space->write_dword(address + 8, ohcist.isochronous_transfer_descriptor.nexttd);
+ ohcist.space->write_dword(address + 12, ohcist.isochronous_transfer_descriptor.be);
+ w = (ohcist.isochronous_transfer_descriptor.offset[1] << 16) | ohcist.isochronous_transfer_descriptor.offset[0];
+ ohcist.space->write_dword(address + 16, w);
+ w = (ohcist.isochronous_transfer_descriptor.offset[3] << 16) | ohcist.isochronous_transfer_descriptor.offset[2];
+ ohcist.space->write_dword(address + 20, w);
+ w = (ohcist.isochronous_transfer_descriptor.offset[5] << 16) | ohcist.isochronous_transfer_descriptor.offset[4];
+ ohcist.space->write_dword(address + 24, w);
+ w = (ohcist.isochronous_transfer_descriptor.offset[7] << 16) | ohcist.isochronous_transfer_descriptor.offset[6];
+ ohcist.space->write_dword(address + 28, w);
+}
+
/*
* Audio
*/
READ32_MEMBER(xbox_base_state::audio_apu_r)
{
+#ifdef LOG_AUDIO
logerror("Audio_APU: read from %08X mask %08X\n", 0xfe800000 + offset * 4, mem_mask);
+#endif
if (offset == 0x20010 / 4) // some kind of internal counter or state value
return 0x20 + 4 + 8 + 0x48 + 0x80;
return apust.memory[offset];
@@ -1004,7 +1070,9 @@ WRITE32_MEMBER(xbox_base_state::audio_apu_w)
//UINT32 old;
UINT32 v;
+#ifdef LOG_AUDIO
logerror("Audio_APU: write at %08X mask %08X value %08X\n", 0xfe800000 + offset * 4, mem_mask, data);
+#endif
//old = apust.memory[offset];
apust.memory[offset] = data;
if (offset == 0x02040 / 4) // address of memory area with scatter-gather info (gpdsp scratch dma)
@@ -1110,7 +1178,9 @@ READ32_MEMBER(xbox_base_state::audio_ac93_r)
{
UINT32 ret = 0;
+#ifdef LOG_AUDIO
logerror("Audio_AC3: read from %08X mask %08X\n", 0xfec00000 + offset * 4, mem_mask);
+#endif
if (offset < 0x80 / 4)
{
ret = ac97st.mixer_regs[offset];
@@ -1137,7 +1207,9 @@ READ32_MEMBER(xbox_base_state::audio_ac93_r)
WRITE32_MEMBER(xbox_base_state::audio_ac93_w)
{
+#ifdef LOG_AUDIO
logerror("Audio_AC3: write at %08X mask %08X value %08X\n", 0xfec00000 + offset * 4, mem_mask, data);
+#endif
if (offset < 0x80 / 4)
{
COMBINE_DATA(ac97st.mixer_regs + offset);
@@ -1421,6 +1493,76 @@ WRITE32_MEMBER(xbox_base_state::smbus_w)
smbusst.command = data;
}
+/*
+ * SuperIO
+ */
+READ8_MEMBER(xbox_base_state::superio_read)
+{
+ if (superiost.configuration_mode == false)
+ return 0;
+ if (offset == 0) // index port 0x2e
+ return superiost.index;
+ if (offset == 1)
+ {
+ // data port 0x2f
+ if (superiost.index < 0x30)
+ return superiost.registers[0][superiost.index];
+ return superiost.registers[superiost.selected][superiost.index];
+ }
+ return 0;
+}
+
+WRITE8_MEMBER(xbox_base_state::superio_write)
+{
+ if (superiost.configuration_mode == false)
+ {
+ // config port 0x2e
+ if ((offset == 0) && (data == 0x55))
+ superiost.configuration_mode = true;
+ return;
+ }
+ if ((offset == 0) && (data == 0xaa))
+ {
+ // config port 0x2e
+ superiost.configuration_mode = false;
+ return;
+ }
+ if (offset == 0)
+ {
+ // index port 0x2e
+ superiost.index = data;
+ }
+ if (offset == 1)
+ {
+ // data port 0x2f
+ if (superiost.index < 0x30)
+ {
+ superiost.registers[0][superiost.index] = data;
+ superiost.selected = superiost.registers[0][7];
+ } else
+ {
+ superiost.registers[superiost.selected][superiost.index] = data;
+ //if ((superiost.selected == 4) && (superiost.index == 0x30) && (data != 0))
+ // ; // add handlers 0x3f8- +7
+ }
+ }
+}
+
+READ8_MEMBER(xbox_base_state::superiors232_read)
+{
+ if (offset == 5)
+ return 0x20;
+ return 0;
+}
+
+WRITE8_MEMBER(xbox_base_state::superiors232_write)
+{
+ if (offset == 0)
+ {
+ printf("%c", data);
+ }
+}
+
ADDRESS_MAP_START(xbox_base_map, AS_PROGRAM, 32, xbox_base_state)
AM_RANGE(0x00000000, 0x07ffffff) AM_RAM AM_SHARE("nv2a_share") // 128 megabytes
AM_RANGE(0xf0000000, 0xf7ffffff) AM_RAM AM_SHARE("nv2a_share") // 3d accelerator wants this
@@ -1433,9 +1575,11 @@ ADDRESS_MAP_END
ADDRESS_MAP_START(xbox_base_map_io, AS_IO, 32, xbox_base_state)
AM_RANGE(0x0020, 0x0023) AM_DEVREADWRITE8("pic8259_1", pic8259_device, read, write, 0xffffffff)
+ AM_RANGE(0x002c, 0x002f) AM_READWRITE8(superio_read, superio_write, 0xffff0000)
AM_RANGE(0x0040, 0x0043) AM_DEVREADWRITE8("pit8254", pit8254_device, read, write, 0xffffffff)
AM_RANGE(0x00a0, 0x00a3) AM_DEVREADWRITE8("pic8259_2", pic8259_device, read, write, 0xffffffff)
AM_RANGE(0x01f0, 0x01f7) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, read_cs0, write_cs0)
+ AM_RANGE(0x03f8, 0x03ff) AM_READWRITE8(superiors232_read, superiors232_write, 0xffffffff)
AM_RANGE(0x0cf8, 0x0cff) AM_DEVREADWRITE("pcibus", pci_bus_legacy_device, read, write)
AM_RANGE(0x8000, 0x80ff) AM_READWRITE(dummy_r, dummy_w)
AM_RANGE(0xc000, 0xc0ff) AM_READWRITE(smbus_r, smbus_w)
@@ -1472,11 +1616,11 @@ void xbox_base_state::machine_start()
pic16lc_buffer[0x1d] = 0x0d;
pic16lc_buffer[0x1e] = 0x0e;
pic16lc_buffer[0x1f] = 0x0f;
-#ifdef USB_ENABLED
ohcist.hc_regs[HcRevision] = 0x10;
ohcist.hc_regs[HcFmInterval] = 0x2edf;
ohcist.hc_regs[HcLSThreshold] = 0x628;
ohcist.hc_regs[HcRhDescriptorA] = 4;
+#ifdef USB_ENABLED
ohcist.interruptbulkratio = 1;
ohcist.writebackdonehadcounter = 7;
ohcist.space = &m_maincpu->space();
@@ -1484,6 +1628,9 @@ void xbox_base_state::machine_start()
ohcist.timer->enable(false);
usb_ohci_plug(1, new ohci_function_device()); // test connect
#endif
+ memset(&superiost, 0, sizeof(superiost));
+ superiost.configuration_mode = false;
+ superiost.registers[0][0x26] = 0x2e; // Configuration port address byte 0
// savestates
save_item(NAME(debug_irq_active));
save_item(NAME(debug_irq_number));