/* * Precondition: reg_mutex must be held */ static void adm6996_apply_vlan_filters(struct adm6996_priv *priv) { u8 ports, tagged; u16 vid, reg; int i; for (i = 0; i < ADM_NUM_VLANS; i++) { vid = priv->vlan_id[i]; ports = priv->vlan_table[i]; tagged = priv->vlan_tagged[i]; if (ports == 0) { /* Disable VLAN entry */ w16(priv->phydev, ADM_VLAN_FILT_H(i), 0); w16(priv->phydev, ADM_VLAN_FILT_L(i), 0); continue; } reg = ADM_VLAN_FILT_MEMBER(ports); reg |= ADM_VLAN_FILT_TAGGED(tagged); w16(priv->phydev, ADM_VLAN_FILT_L(i), reg); reg = ADM_VLAN_FILT_VALID | ADM_VLAN_FILT_VID(vid); w16(priv->phydev, ADM_VLAN_FILT_H(i), reg); } }
void CPacket::wStrW(irr::core::stringc &str) { if((WritePointer + (str.size() * 2) + 2) > DataLen) resize(WritePointer + (str.size() * 2) + 2); for(irr::s32 i = 0; i < str.size(); i++) w16(str[i]); w16(0x0000); };
bool ADMMemioAvi::writeWavStruct(const WAVHeader &hdr) { w16( encoding); w16( channels); /* 1 = mono, 2 = stereo */ w32( frequency); /* One of 11025, 22050, or 44100 48000 Hz */ w32( byterate); /* Average bytes per second */ w16( blockalign); /* Bytes per sample block */ w16( bitspersample); /* One of 8, 1 */ return true; }
u32 Mic::DMA(u32 Command, u32* buffer_in, u32 buffer_in_len, u32* buffer_out, u32& buffer_out_len) { u8* buffer_out_b = (u8*)buffer_out; // Buffer overflow if (buffer_in_len > 8) return CommandUnknown; switch (Command) { case GetStatus: //functionality info w32(m_FuncType); w32(m_FuncDef[0]); w32(m_FuncDef[1]); w32(m_FuncDef[2]); w8(m_Region); w8(m_Direction); wString(m_strName, 30); wString(m_License, 60); w16(m_mAstandby); w16(m_mAmax); DEBUG_LOG("GetStatus\n"); return DeviceInfo; case GetStatusAll: w32(m_FuncType); w32(m_FuncDef[0]); w32(m_FuncDef[1]); w32(m_FuncDef[2]); w8(m_Region); w8(m_Direction); wString(m_strName, 30); wString(m_License, 60); w16(m_mAstandby); w16(m_mAmax); wString(m_strNameEx, 172); // TODO verify DEBUG_LOG("GetStatusAll\n"); return DeviceInfoEx; case GetCondition: return DataTransfer; default: printf("UNKNOWN MAPLE COMMAND %d (sent to %s)\n", Command, m_strName); return CommandUnknown; } }
bool ADMMemioAvi::writeBihStruct(const ADM_BITMAPINFOHEADER &hdr) { w32( biSize); w32( biWidth); w32( biHeight); w16( biPlanes); w16( biBitCount); w32( biCompression); w32( biSizeImage); w32( biXPelsPerMeter); w32( biYPelsPerMeter); w32( biClrUsed); w32( biClrImportant); return true; }
static int mvswitch_read_status(struct phy_device *pdev) { pdev->speed = SPEED_100; pdev->duplex = DUPLEX_FULL; pdev->link = 1; /* XXX ugly workaround: we can't force the switch * to gracefully handle hosts moving from one port to another, * so we have to regularly clear the ATU database */ /* wait for the ATU to become available */ mvswitch_wait_mask(pdev, MV_SWITCHREG(ATU_OP), MV_ATUOP_INPROGRESS, 0); /* flush the ATU */ w16(pdev, MV_SWITCHREG(ATU_OP), MV_ATUOP_INPROGRESS | MV_ATUOP_FLUSH_ALL ); /* wait for operation to complete */ mvswitch_wait_mask(pdev, MV_SWITCHREG(ATU_OP), MV_ATUOP_INPROGRESS, 0); return 0; }
void set_operational(void) { //if (g_is_PCI == TRUE) w16(HcHWCfg , 0x302d ); // set INT1 to Active LOW, Level Triggered //else w16(HcHWCfg , 0x342D ); w32(HcFmItv , 0x25002EDF); w32(HcControl , 0x00000680); }
/* * Disable VLANs * * Sets VLAN mapping for port-based VLAN with all ports connected to * eachother (this is also the power-on default). * * Precondition: reg_mutex must be held */ static void adm6996_disable_vlan(struct adm6996_priv *priv) { u16 reg; int i; for (i = 0; i < ADM_NUM_PORTS; i++) { reg = ADM_VLAN_FILT_MEMBER_MASK; w16(priv->phydev, ADM_VLAN_FILT_L(i), reg); reg = ADM_VLAN_FILT_VALID | ADM_VLAN_FILT_VID(1); w16(priv->phydev, ADM_VLAN_FILT_H(i), reg); } reg = r16(priv->phydev, ADM_OTBE_P2_PVID); reg |= ADM_OTBE_MASK; w16(priv->phydev, ADM_OTBE_P2_PVID, reg); reg = r16(priv->phydev, ADM_IFNTE); reg |= ADM_IFNTE_MASK; w16(priv->phydev, ADM_IFNTE, reg); reg = r16(priv->phydev, ADM_VID_CHECK); reg &= ~(ADM_VID_CHECK_MASK); w16(priv->phydev, ADM_VID_CHECK, reg); reg = r16(priv->phydev, ADM_SYSC0); reg &= ~(ADM_NTTE); reg |= ADM_RVID1; w16(priv->phydev, ADM_SYSC0, reg); reg = r16(priv->phydev, ADM_SYSC3); reg &= ~(ADM_TBV); w16(priv->phydev, ADM_SYSC3, reg); }
/** \fn writeWavHeader */ bool riffWritter::writeWavHeader(const char *tag,WAVHeader *hdr) { uint32_t fcc; fcc = fourCC::get((uint8_t *)tag); ADM_assert(fcc); write32(fcc); write32(sizeof(*hdr)); #define w16(x) write16(hdr->x) #define w32(x) write32(hdr->x) w16( encoding); w16( channels); /* 1 = mono, 2 = stereo */ w32( frequency); /* One of 11025, 22050, or 44100 48000 Hz */ w32( byterate); /* Average bytes per second */ w16( blockalign); /* Bytes per sample block */ w16( bitspersample); /* One of 8, 12, 16, or 4 for ADPCM */ return true; }
void RDA5807M::getRadioInfo(RADIO_INFO &ri) { if (_rc) return; uint8_t t = 10; do { _rc = I2c.read(RDA5807M_I2C_ADDR_RANDOM, RDA5807M_R0A_STATUS, (2+4)*2); if (_rc == 0) { ri.R0A = w16(); ri.R0B = w16(); for (uint8_t i = 0; i < 4; ++i) ri.blk[i] = w16(); return; } delay(5); } while (--t > 0); if (_rc) { Serial.print(F("ERR")); Serial.print(_rc); Serial.print(F(" ")); Serial.print(__LINE__); Serial.print("#"); delay(5000); } }
static int adm6996_config_init(struct phy_device *pdev) { int i; printk("%s: ADM6996 PHY driver attached.\n", pdev->attached_dev->name); pdev->supported = ADVERTISED_100baseT_Full; pdev->advertising = ADVERTISED_100baseT_Full; /* initialize port and vlan settings */ for (i = 0; i < ADM_PHY_PORTS; i++) { w16(pdev, adm_portcfg[i], ADM_PORTCFG_INIT | ADM_PORTCFG_PVID((i == ADM_WAN_PORT) ? 1 : 0)); } w16(pdev, adm_portcfg[5], ADM_PORTCFG_CPU); /* reset all ports */ for (i = 0; i < ADM_PHY_PORTS; i++) { w16(pdev, ADM_PHY_PORT(i), ADM_PHYCFG_INIT); } return 0; }
static int adm6996_set_data(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) { struct adm6996_priv *priv = to_adm(dev); if (val->value.i > 65535) return -EINVAL; w16(priv->phydev, priv->addr, val->value.i); return 0; };
/* * Reset the switch * * The ADM6996 can't do a software-initiated reset, so we just initialise the * registers we support in this driver. * * Precondition: reg_mutex must be held */ static void adm6996_perform_reset (struct adm6996_priv *priv) { int i; /* initialize port and vlan settings */ for (i = 0; i < ADM_NUM_PORTS - 1; i++) { w16(priv->phydev, adm_portcfg[i], ADM_PORTCFG_INIT | ADM_PORTCFG_PVID(0)); } w16(priv->phydev, adm_portcfg[5], ADM_PORTCFG_CPU); /* reset all PHY ports */ for (i = 0; i < ADM_PHY_PORTS; i++) { w16(priv->phydev, ADM_PHY_PORT(i), ADM_PHYCFG_INIT); } priv->enable_vlan = 0; priv->vlan_enabled = 0; for (i = 0; i < ADM_NUM_PORTS; i++) { priv->pvid[i] = 0; } for (i = 0; i < ADM_NUM_VLANS; i++) { priv->vlan_id[i] = i; priv->vlan_table[i] = 0; priv->vlan_tagged[i] = 0; } if (priv->model == ADM6996M) { /* Clear VLAN priority map so prio's are unused */ w16 (priv->phydev, ADM_VLAN_PRIOMAP, 0); adm6996_disable_vlan(priv); adm6996_apply_port_pvids(priv); } }
/* * Precondition: reg_mutex must be held */ static void adm6996_enable_vlan(struct adm6996_priv *priv) { u16 reg; reg = r16(priv->phydev, ADM_OTBE_P2_PVID); reg &= ~(ADM_OTBE_MASK); w16(priv->phydev, ADM_OTBE_P2_PVID, reg); reg = r16(priv->phydev, ADM_IFNTE); reg &= ~(ADM_IFNTE_MASK); w16(priv->phydev, ADM_IFNTE, reg); reg = r16(priv->phydev, ADM_VID_CHECK); reg |= ADM_VID_CHECK_MASK; w16(priv->phydev, ADM_VID_CHECK, reg); reg = r16(priv->phydev, ADM_SYSC0); reg |= ADM_NTTE; reg &= ~(ADM_RVID1); w16(priv->phydev, ADM_SYSC0, reg); reg = r16(priv->phydev, ADM_SYSC3); reg |= ADM_TBV; w16(priv->phydev, ADM_SYSC3, reg); };
bool ADMMemioAvi::writeStreamHeaderStruct(const AVIStreamHeader &hdr) { w32( fccType); w32( fccHandler); w32( dwFlags); /* Contains AVITF_* flags */ w16( wPriority); /* dwPriority - splited for audio */ w16( wLanguage); w32( dwInitialFrames); w32( dwScale); w32( dwRate); /* dwRate / dwScale == samples/second */ w32( dwStart); w32( dwLength); /* In units above... */ w32( dwSuggestedBufferSize); w32( dwQuality); w32( dwSampleSize); w16( rcFrame.left); w16( rcFrame.top); w16( rcFrame.right); w16( rcFrame.bottom); return true; }
/* * Precondition: reg_mutex must be held */ static void adm6996_apply_port_pvids(struct adm6996_priv *priv) { u16 reg; int i; for (i = 0; i < ADM_NUM_PORTS; i++) { reg = r16(priv->phydev, adm_portcfg[i]); reg &= ~(ADM_PORTCFG_PVID_MASK); reg |= ADM_PORTCFG_PVID(priv->pvid[i]); w16(priv->phydev, adm_portcfg[i], reg); } w16(priv->phydev, ADM_P0_PVID, ADM_P0_PVID_VAL(priv->pvid[0])); w16(priv->phydev, ADM_P1_PVID, ADM_P1_PVID_VAL(priv->pvid[1])); reg = r16(priv->phydev, ADM_OTBE_P2_PVID); reg &= ~(ADM_P2_PVID_MASK); reg |= ADM_P2_PVID_VAL(priv->pvid[2]); w16(priv->phydev, ADM_OTBE_P2_PVID, reg); reg = ADM_P3_PVID_VAL(priv->pvid[3]); reg |= ADM_P4_PVID_VAL(priv->pvid[4]); w16(priv->phydev, ADM_P3_P4_PVID, reg); w16(priv->phydev, ADM_P5_PVID, ADM_P5_PVID_VAL(priv->pvid[5])); }
static int mvswitch_config_init(struct phy_device *pdev) { struct mvswitch_priv *priv = to_mvsw(pdev); struct net_device *dev = pdev->attached_dev; u8 vlmap = 0; int i; if (!dev) return -EINVAL; printk("%s: Marvell 88E6060 PHY driver attached.\n", dev->name); pdev->supported = ADVERTISED_100baseT_Full; pdev->advertising = ADVERTISED_100baseT_Full; dev->phy_ptr = priv; pdev->irq = PHY_POLL; #ifdef HEADER_MODE dev->flags |= IFF_PROMISC; #endif /* initialize default vlans */ for (i = 0; i < MV_PORTS; i++) priv->vlans[(i == MV_WANPORT ? 2 : 1)] |= (1 << i); /* before entering reset, disable all ports */ for (i = 0; i < MV_PORTS; i++) w16(pdev, MV_PORTREG(CONTROL, i), 0x00); msleep(2); /* wait for the status change to settle in */ /* put the ATU in reset */ w16(pdev, MV_SWITCHREG(ATU_CTRL), MV_ATUCTL_RESET); i = mvswitch_wait_mask(pdev, MV_SWITCHREG(ATU_CTRL), MV_ATUCTL_RESET, 0); if (i < 0) { printk("%s: Timeout waiting for the switch to reset.\n", dev->name); return i; } /* set the ATU flags */ w16(pdev, MV_SWITCHREG(ATU_CTRL), MV_ATUCTL_NO_LEARN | MV_ATUCTL_ATU_1K | MV_ATUCTL_AGETIME(MV_ATUCTL_AGETIME_MIN) /* minimum without disabling ageing */ ); /* initialize the cpu port */ w16(pdev, MV_PORTREG(CONTROL, MV_CPUPORT), #ifdef HEADER_MODE MV_PORTCTRL_HEADER | #else MV_PORTCTRL_RXTR | MV_PORTCTRL_TXTR | #endif MV_PORTCTRL_ENABLED ); /* wait for the phy change to settle in */ msleep(2); for (i = 0; i < MV_PORTS; i++) { u8 pvid = 0; int j; vlmap = 0; /* look for the matching vlan */ for (j = 0; j < ARRAY_SIZE(priv->vlans); j++) { if (priv->vlans[j] & (1 << i)) { vlmap = priv->vlans[j]; pvid = j; } } /* leave port unconfigured if it's not part of a vlan */ if (!vlmap) continue; /* add the cpu port to the allowed destinations list */ vlmap |= (1 << MV_CPUPORT); /* take port out of its own vlan destination map */ vlmap &= ~(1 << i); /* apply vlan settings */ w16(pdev, MV_PORTREG(VLANMAP, i), MV_PORTVLAN_PORTS(vlmap) | MV_PORTVLAN_ID(i) ); /* re-enable port */ w16(pdev, MV_PORTREG(CONTROL, i), MV_PORTCTRL_ENABLED ); } w16(pdev, MV_PORTREG(VLANMAP, MV_CPUPORT), MV_PORTVLAN_ID(MV_CPUPORT) ); /* set the port association vector */ for (i = 0; i <= MV_PORTS; i++) { w16(pdev, MV_PORTREG(ASSOC, i), MV_PORTASSOC_PORTS(1 << i) ); } /* init switch control */ w16(pdev, MV_SWITCHREG(CTRL), MV_SWITCHCTL_MSIZE | MV_SWITCHCTL_DROP ); dev->eth_mangle_rx = mvswitch_mangle_rx; dev->eth_mangle_tx = mvswitch_mangle_tx; priv->orig_features = dev->features; #ifdef HEADER_MODE dev->priv_flags |= IFF_NO_IP_ALIGN; dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX; #else dev->features |= NETIF_F_HW_VLAN_RX; #endif return 0; }
u32 Maxi::DMA(u32 Command, u32* buffer_in, u32 buffer_in_len, u32* buffer_out, u32& buffer_out_len) { // Update the xpad the thread uses... EnterCriticalSection(&m_status.section); m_status.currentXPad = m_xpad; LeaveCriticalSection(&m_status.section); u8* buffer_out_b = (u8*)buffer_out; switch (Command) { case GetStatus: //functionality info w32(m_FuncType); w32(m_FuncDef[0]); w32(m_FuncDef[1]); w32(m_FuncDef[2]); w8(m_Region); w8(m_Direction); wString(m_strName, 30); wString(m_License, 60); w16(m_mAstandby); w16(m_mAmax); DEBUG_LOG("GetStatus\n"); return DeviceInfo; case GetStatusAll: w32(m_FuncType); w32(m_FuncDef[0]); w32(m_FuncDef[1]); w32(m_FuncDef[2]); w8(m_Region); w8(m_Direction); wString(m_strName, 30); wString(m_License, 60); w16(m_mAstandby); w16(m_mAmax); wString(m_strNameEx, 40); DEBUG_LOG("GetStatusAll\n"); return DeviceInfoEx; case GetCondition: // This command should return ALL vibration sources' settings. we only have one at the moment... w32(m_FuncType); w32(m_status.srcSettings.U32); DEBUG_LOG("GetCondition\n"); //w32(purupuru_cond.srcSettings[VN].U32); return DataTransfer; case GetMediaInfo: { if (!m_status.srcSettings.VN) // there are no vibration sources?!?! return TransmitAgain; w32(m_FuncType); w32(m_status.srcSettings.U32); u8 source = (*(++buffer_in) & 0x000000FF); DEBUG_LOG("GetMediaInfo for source 0x%02x\n", source); } return DataTransfer; case BlockRead: if (*(++buffer_in) == 0) // It's not looking for waveform data { // Read back the AutoStop settings w32(m_FuncType); w32(0); // VN(1), Phase(1), Block No.(2) w16(0x0200); // ASR for VN 1 w8(m_status.AST); } else { printf("BlockRead for waveform!\n"); printf("REPORT THIS\n"); return CommandUnknown; } return DataTransfer; case BlockWrite: { // GAH this can also be used to set auto stop time so we have to support it if (*(++buffer_in) == 0) // It's not trying to send waveform data { int numAST = (buffer_in_len-6)/4; // Doesn't include VN(1), Phase(1), Block Number(2), or ASR(2) // example ASR and AST (as the game sends): 0x000c0200 buffer_in++; u16 ASR = (u16)*(buffer_in) & 0x0000FFFF; // don't swap ASR because I am lazy if (numAST == 1 && ASR == 0x0200) // yeah, we'll handle it { EnterCriticalSection(&m_status.section); m_status.AST = (*(buffer_in) & 0x00FF0000) >> 16; LeaveCriticalSection(&m_status.section); DEBUG_LOG("BlockWrite set AutoStop: %f seconds\n", m_status.AST * .25); } else { printf("BlockWrite set numAST: %i ASR: 0x%04x\n", numAST, ASR); printf("REPORT THIS\n"); return TransmitAgain; } }
static int adm6996_config_init(struct phy_device *pdev) { struct adm6996_priv *priv; struct switch_dev *swdev; int ret; u16 test, old; pdev->supported = ADVERTISED_100baseT_Full; pdev->advertising = ADVERTISED_100baseT_Full; if (pdev->addr != 0) { pr_info ("%s: PHY overlaps ADM6996, providing fixed PHY 0x%x.\n" , pdev->attached_dev->name, pdev->addr); return 0; } priv = kzalloc(sizeof(struct adm6996_priv), GFP_KERNEL); if (priv == NULL) return -ENOMEM; mutex_init(&priv->reg_mutex); priv->phydev = pdev; priv->read = adm6996_read_mii_reg; priv->write = adm6996_write_mii_reg; pdev->priv = priv; /* Detect type of chip */ old = r16(pdev, ADM_VID_CHECK); test = old ^ (1 << 12); w16(pdev, ADM_VID_CHECK, test); test ^= r16(pdev, ADM_VID_CHECK); if (test & (1 << 12)) { /* * Bit 12 of this register is read-only. * This is the FC model. */ priv->model = ADM6996FC; } else { /* Bit 12 is read-write. This is the M model. */ priv->model = ADM6996M; w16(pdev, ADM_VID_CHECK, old); } swdev = &priv->dev; swdev->name = (adm6996_model_name[priv->model]); swdev->cpu_port = ADM_CPU_PORT; swdev->ports = ADM_NUM_PORTS; swdev->vlans = ADM_NUM_VLANS; swdev->ops = &adm6996_ops; pr_info ("%s: %s model PHY found.\n", pdev->attached_dev->name, swdev->name); mutex_lock(&priv->reg_mutex); adm6996_perform_reset (priv); mutex_unlock(&priv->reg_mutex); if (priv->model == ADM6996M) { if ((ret = register_switch(swdev, pdev->attached_dev)) < 0) { kfree(priv); return ret; } } return 0; }
////////////////////////////////////////////////////////////////////////////////////////// // NAOMI JAMMA DMA // --------------- u32 FASTCALL ControllerDMA_NAOMI(void* device_instance,u32 Command,u32* buffer_in,u32 buffer_in_len,u32* buffer_out,u32& buffer_out_len) { u8*buffer_out_b=(u8*)buffer_out; u8*buffer_in_b=(u8*)buffer_in; buffer_out_len=0; u16 kcode[4]={0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; if(joysticks[0].enabled) GetJoyStatus(0); else memset(joystate[0].control, 0, sizeof(joystate[0].control)); if(joysticks[1].enabled) GetJoyStatus(1); else memset(joystate[1].control, 0, sizeof(joystate[1].control)); switch (Command) { case 0x86: { u32 subcode=*(u8*)buffer_in; switch(subcode) { case 0x15: case 0x33: { buffer_out[0]=0xffffffff; buffer_out[1]=0xffffffff; if(joystate[0].control[CTLN_SERVICE2] || joystate[1].control[CTLN_SERVICE2]) buffer_out[0]&=~(1<<0x1b); if(joystate[0].control[CTLN_TEST2] || joystate[1].control[CTLN_TEST2]) buffer_out[0]&=~(1<<0x1a); if(State.Mode==0 && subcode!=0x33) //Get Caps { buffer_out_b[0x11+1]=0x8E; //Valid data check buffer_out_b[0x11+2]=0x01; buffer_out_b[0x11+3]=0x00; buffer_out_b[0x11+4]=0xFF; buffer_out_b[0x11+5]=0xE0; buffer_out_b[0x11+8]=0x01; switch(State.Cmd) { //Reset, in : 2 bytes, out : 0 case 0xF0: break; //Find nodes? //In addressing Slave address, in : 2 bytes, out : 1 case 0xF1: { buffer_out_len=4*4; } break; //Speed Change, in : 2 bytes, out : 0 case 0xF2: break; //Name //"In the I / O ID" "Reading each slave ID data" //"NAMCO LTD.; I / O PCB-1000; ver1.0; for domestic only, no analog input" //in : 1 byte, out : max 102 case 0x10: { static char ID1[102]="nullDC Team; I/O Plugin-1; ver0.2; for nullDC or other emus"; buffer_out_b[0x8+0x10]=(BYTE)strlen(ID1)+3; for(int i=0;ID1[i]!=0;++i) { buffer_out_b[0x8+0x13+i]=ID1[i]; } } break; //CMD Version //REV in command|Format command to read the (revision)|One|Two //in : 1 byte, out : 2 bytes case 0x11: { buffer_out_b[0x8+0x13]=0x13; } break; //JVS Version //In JV REV|JAMMA VIDEO standard reading (revision)|One|Two //in : 1 byte, out : 2 bytes case 0x12: { buffer_out_b[0x8+0x13]=0x30; } break; //COM Version //VER in the communication system|Read a communication system compliant version of |One|Two //in : 1 byte, out : 2 bytes case 0x13: { buffer_out_b[0x8+0x13]=0x10; } break; //Features //Check in feature |Each features a slave to read |One |6 to //in : 1 byte, out : 6 + (?) case 0x14: { unsigned char *FeatPtr=buffer_out_b+0x8+0x13; buffer_out_b[0x8+0x9+0x3]=0x0; buffer_out_b[0x8+0x9+0x9]=0x1; #define ADDFEAT(Feature,Count1,Count2,Count3) *FeatPtr++=Feature; *FeatPtr++=Count1; *FeatPtr++=Count2; *FeatPtr++=Count3; ADDFEAT(1,2,12,0); //Feat 1=Digital Inputs. 2 Players. 10 bits ADDFEAT(2,2,0,0); //Feat 2=Coin inputs. 2 Inputs ADDFEAT(3,2,0,0); //Feat 3=Analog. 2 Chans ADDFEAT(0,0,0,0); //End of list } break; default: printf("unknown CAP %X\n",State.Cmd); return 0; } buffer_out_len=4*4; } else if(State.Mode==1 || State.Mode==2 || subcode==0x33) //Get Data { unsigned char glbl=0x00; unsigned char p1_1=0x00; unsigned char p1_2=0x00; unsigned char p2_1=0x00; unsigned char p2_2=0x00; static unsigned char LastKey[256]; static unsigned short coin1=0x0000; static unsigned short coin2=0x0000; if(joystate[0].control[CTLN_TEST1] || joystate[1].control[CTLN_TEST1]) glbl|=0x80; if(joystate[0].control[CTLN_SERVICE1]) p1_1|=0x40; if(joystate[0].control[CTLN_START]) p1_1|=0x80; if(joystate[0].control[CTLN_D_UP] ) p1_1|=0x20; if(joystate[0].control[CTLN_D_DOWN] ) p1_1|=0x10; if(joystate[0].control[CTLN_D_LEFT] ) p1_1|=0x08; if(joystate[0].control[CTLN_D_RIGHT]) p1_1|=0x04; if(joystate[0].control[CTLN_BUTTON1]) p1_1|=0x02; if(joystate[0].control[CTLN_BUTTON2]) p1_1|=0x01; if(joystate[0].control[CTLN_BUTTON3]) p1_2|=0x80; if(joystate[0].control[CTLN_BUTTON4]) p1_2|=0x40; if(joystate[0].control[CTLN_BUTTON5]) p1_2|=0x20; if(joystate[0].control[CTLN_BUTTON6]) p1_2|=0x10; // Player 2 if(joystate[1].control[CTLN_SERVICE1]) p2_1|=0x40; if(joystate[1].control[CTLN_START]) p2_1|=0x80; if(joystate[1].control[CTLN_D_UP] ) p2_1|=0x20; if(joystate[1].control[CTLN_D_DOWN] ) p2_1|=0x10; if(joystate[1].control[CTLN_D_LEFT] ) p2_1|=0x08; if(joystate[1].control[CTLN_D_RIGHT]) p2_1|=0x04; if(joystate[1].control[CTLN_BUTTON1]) p2_1|=0x02; if(joystate[1].control[CTLN_BUTTON2]) p2_1|=0x01; if(joystate[1].control[CTLN_BUTTON3]) p2_2|=0x80; if(joystate[1].control[CTLN_BUTTON4]) p2_2|=0x40; if(joystate[1].control[CTLN_BUTTON5]) p2_2|=0x20; if(joystate[1].control[CTLN_BUTTON6]) p2_2|=0x10; static bool old_coin1 = false; static bool old_coin2 = false; if(!old_coin1 && joystate[0].control[CTLN_COIN]) // Coin key { coin1++; old_coin1 = true; } else if(old_coin1 && !joystate[0].control[CTLN_COIN]) // Coin key old_coin1 = false; if(!old_coin2 && joystate[1].control[CTLN_COIN]) // Coin key { coin2++; old_coin2 = true; } else if(old_coin2 && !joystate[1].control[CTLN_COIN]) // Coin key old_coin2 = false; buffer_out_b[0x11+0]=0x00; buffer_out_b[0x11+1]=0x8E; //Valid data check buffer_out_b[0x11+2]=0x01; buffer_out_b[0x11+3]=0x00; buffer_out_b[0x11+4]=0xFF; buffer_out_b[0x11+5]=0xE0; buffer_out_b[0x11+8]=0x01; //memset(OutData+8+0x11,0x00,0x100); buffer_out_b[8+0x12+0]=1; buffer_out_b[8+0x12+1]=glbl; buffer_out_b[8+0x12+2]=p1_1; buffer_out_b[8+0x12+3]=p1_2; buffer_out_b[8+0x12+4]=p2_1; buffer_out_b[8+0x12+5]=p2_2; buffer_out_b[8+0x12+6]=1; buffer_out_b[8+0x12+7]=coin1>>8; buffer_out_b[8+0x12+8]=coin1&0xff; buffer_out_b[8+0x12+9]=coin2>>8; buffer_out_b[8+0x12+10]=coin2&0xff; buffer_out_b[8+0x12+11]=1; buffer_out_b[8+0x12+12]=0x00; buffer_out_b[8+0x12+13]=0x00; buffer_out_b[8+0x12+14]=0x00; buffer_out_b[8+0x12+15]=0x00; buffer_out_b[8+0x12+16]=0x00; buffer_out_b[8+0x12+17]=0x00; buffer_out_b[8+0x12+18]=0x00; buffer_out_b[8+0x12+19]=0x00; buffer_out_b[8+0x12+20]=0x00; if(State.Mode==1) { buffer_out_b[0x11+0x7]=19; buffer_out_b[0x11+0x4]=19+5; } else { buffer_out_b[0x11+0x7]=17; buffer_out_b[0x11+0x4]=17-1; } //OutLen=8+0x11+16; buffer_out_len=8+0x12+20; } } return 8; case 0x17: //Select Subdevice { State.Mode=0; State.Cmd=buffer_in_b[8]; State.Node=buffer_in_b[9]; buffer_out_len=0; } return (7); case 0x27: //Transfer request { State.Mode=1; State.Cmd=buffer_in_b[8]; State.Node=buffer_in_b[9]; buffer_out_len=0; } return (7); case 0x21: //Transfer request with repeat { State.Mode=2; State.Cmd=buffer_in_b[8]; State.Node=buffer_in_b[9]; buffer_out_len=0; } return (7); case 0x0B: //EEPROM write { int address=buffer_in_b[1]; int size=buffer_in_b[2]; //printf("EEprom write %08X %08X\n",address,size); //printState(Command,buffer_in,buffer_in_len); memcpy(EEPROM+address,buffer_in_b+4,size); wchar eeprom_file[512]; host.ConfigLoadStr(L"emu",L"gamefile",eeprom_file,L""); wcscat_s(eeprom_file,L".eeprom"); FILE* f; _wfopen_s(&f,eeprom_file,L"wb"); if (f) { fwrite(EEPROM,1,0x80,f); fclose(f); wprintf(L"SAVED EEPROM to %s\n",eeprom_file); } } return (7); case 0x3: //EEPROM read { if (!EEPROM_loaded) { EEPROM_loaded=true; wchar eeprom_file[512]; host.ConfigLoadStr(L"emu",L"gamefile",eeprom_file,L""); wcscat_s(eeprom_file,L".eeprom"); FILE* f; _wfopen_s(&f,eeprom_file,L"rb"); if (f) { fread(EEPROM,1,0x80,f); fclose(f); wprintf(L"LOADED EEPROM from %s\n",eeprom_file); } } //printf("EEprom READ ?\n"); int address=buffer_in_b[1]; //printState(Command,buffer_in,buffer_in_len); memcpy(buffer_out,EEPROM+address,0x80); buffer_out_len=0x80; } return 8; //IF I return all FF, then board runs in low res case 0x31: { buffer_out[0]=0xffffffff; buffer_out[1]=0xffffffff; } return (8); default: printf("PuruPuru => Unknown 0x86: Sub 0x%X - State: 0x%X Mode: 0x%X Node: 0x%X\n",subcode,State.Cmd,State.Mode,State.Node); printState(Command,buffer_in,buffer_in_len); } return 8;//MAPLE_RESPONSE_DATATRF } break; case 0x82: { const char *ID="315-6149 COPYRIGHT SEGA E\x83\x00\x20\x05NTERPRISES CO,LTD. "; memset(buffer_out_b,0x20,256); memcpy(buffer_out_b,ID,0x38-4); buffer_out_len=256; return (0x83); } /*typedef struct { DWORD func;//4 DWORD function_data[3];//3*4 u8 area_code;//1 u8 connector_direction;//1 char product_name[30];//30*1 char product_license[60];//60*1 WORD standby_power;//2 WORD max_power;//2 } maple_devinfo_t;*/ case 1: { w32(1 << 24); // Caps w32( 0xfe060f00); //struct data w32( 0); w32( 0); w8(0xFF); //1 area code w8(0); //1 direction wStrings(Joy_strName, Joy_strBrand_2); //ptr_out += 60; w16(0xAE01); //2 w16(0xF401); //2 } return 5; case 9: { w32(1 << 24); //struct data w16(kcode[0] | 0xF901); //2 w8(0x0); //triggers w8(0x0); w8(0x80); // Analog XY w8(0x80); w8(0x80); // XY2 w8(0x80); //are these needed ? //1 //WriteMem8(ptr_out, 10); ptr_out += 1; //1 //WriteMem8(ptr_out, 10); ptr_out += 1; } return 8; default: printf("PuruPuru => unknown MAPLE Frame: "); printState(Command,buffer_in,buffer_in_len); return 7; }
u32 FASTCALL ControllerDMA(void* device_instance, u32 Command,u32* buffer_in, u32 buffer_in_len, u32* buffer_out, u32& buffer_out_len) { u8*buffer_out_b=(u8*)buffer_out; u32 port=((maple_device_instance*)device_instance)->port>>6; // Enabled check ain't necessary. Only the plugin's active ports are checked. :) // Update input information. GetJoyStatus(port); switch (Command) { case 1: { w32(1<<24); //Controller function w32(0xFE060F00); //values a real dc controller returns w32(0); w32(0); w8(0xFF); //1 area code ( 0xFF = all regions) w8(0); //1 connector direction , i think 0 means 'on top' wStrings(Joy_strName, Joy_strBrand); //30 and 60 chars respectively, pad with ' ' w16(0x01AE); // Standby current consumption w16(0x01F4); // Maximum current consumption return 5; // 5 = Device Info. } case 9: { w32(1 << 24); //its a reply about controller ;p // Set buttons u16 kcode = 0xFFFF; if( joystate[port].control[CTL_A_BUTTON] ) kcode ^= key_CONT_A; if( joystate[port].control[CTL_B_BUTTON] ) kcode ^= key_CONT_B; if( joystate[port].control[CTL_X_BUTTON] ) kcode ^= key_CONT_X; if( joystate[port].control[CTL_Y_BUTTON] ) kcode ^= key_CONT_Y; if( joystate[port].control[CTL_START] ) kcode ^= key_CONT_START; if( joystate[port].control[CTL_D_PAD_UP] ) kcode ^= key_CONT_DPAD_UP; if( joystate[port].control[CTL_D_PAD_DOWN] ) kcode ^= key_CONT_DPAD_DOWN; if( joystate[port].control[CTL_D_PAD_LEFT] ) kcode ^= key_CONT_DPAD_LEFT; if( joystate[port].control[CTL_D_PAD_RIGHT] ) kcode ^= key_CONT_DPAD_RIGHT; w16(kcode | 0xF901); //0xF901 -> buttons that are allways up on a dc // Set triggers w8(joystate[port].control[CTL_R_SHOULDER]); w8(joystate[port].control[CTL_L_SHOULDER]); // Set Analog sticks (Main) w16(GetAnalog1(port)); //x/y2 are missing on DC w8(0x80); w8(0x80); return 8; } default: printf("PuruPuru -> UNKNOWN MAPLE COMMAND %d\n", Command); return 7; } }