Example #1
0
// Translates an Errno code into an exception.
// Throws an exception based on the given error code (usually taken from ANSI C's errno)
BaseException* Exception::FromErrno( const wxString& streamname, int errcode )
{
	pxAssumeDev( errcode != 0, "Invalid NULL error code?  (errno)" );

	switch( errcode )
	{
		case EINVAL:
			pxFailDev( L"Invalid argument" );
			return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Invalid argument? (likely caused by an unforgivable programmer error!)" );

		case EACCES:	// Access denied!
			return new Exception::AccessDenied( streamname );

		case EMFILE:	// Too many open files!
			return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"Too many open files");	// File handle allocation failure

		case EEXIST:
			return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"File already exists");

		case ENOENT:	// File not found!
			return new Exception::FileNotFound( streamname );

		case EPIPE:
			return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Broken pipe");

		case EBADF:
			return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Bad file number");

		default:
			return &(new Exception::BadStream( streamname ))->SetDiagMsg(pxsFmt( L"General file/stream error [errno: %d]", errcode ));
	}
}
Example #2
0
xAddressVoid& xAddressVoid::Add( const xAddressReg& src )
{
	if( src == Index )
	{
		Factor++;
	}
	else if( src == Base )
	{
		// Compound the existing register reference into the Index/Scale pair.
		Base = xEmptyReg;

		if( src == Index )
			Factor++;
		else
		{
			pxAssertDev( Index.IsEmpty(), "x86Emitter: Only one scaled index register is allowed in an address modifier." );
			Index = src;
			Factor = 2;
		}
	}
	else if( Base.IsEmpty() )
		Base = src;
	else if( Index.IsEmpty() )
		Index = src;
	else
		pxAssumeDev( false, L"x86Emitter: address modifiers cannot have more than two index registers." );	// oops, only 2 regs allowed per ModRm!

	return *this;
}
Example #3
0
// This method allows the programmer to specify the block size of the array as a function
// of its reserved size.  This function *must* be called *after* the reserve has been made,
// and *before* the array contents have been accessed.
//
// Calls to this function prior to initializing the reserve or after the reserve has been
// accessed (resulting in committed blocks) will be ignored -- and will generate an assertion
// in debug builds.
SpatialArrayReserve& SpatialArrayReserve::SetBlockCount( uint blocks )
{
	pxAssumeDev( !m_pages_commited, "Invalid object state: SetBlockCount must be called prior to reserved memory accesses." );

	// Calculate such that the last block extends past the end of the array, if necessary.

	m_numblocks = blocks;
	m_blocksize = (m_pages_reserved + m_numblocks-1) / m_numblocks;

	return *this;
}
Example #4
0
xAddressVoid &xAddressVoid::Add(const xAddressVoid &src)
{
    Add(src.Base);
    Add(src.Displacement);

    // If the factor is 1, we can just treat index like a base register also.
    if (src.Factor == 1) {
        Add(src.Index);
    } else if (Index.IsEmpty()) {
        Index = src.Index;
        Factor = src.Factor;
    } else if (Index == src.Index) {
        Factor += src.Factor;
    } else
        pxAssumeDev(false, L"x86Emitter: address modifiers cannot have more than two index registers."); // oops, only 2 regs allowed per ModRm!

    return *this;
}
Example #5
0
// Generates a 'reduced' ModSib form, which has valid Base, Index, and Scale values.
// Necessary because by default ModSib compounds registers into Index when possible.
//
// If the ModSib is in illegal form ([Base + Index*5] for example) then an assertion
// followed by an InvalidParameter Exception will be tossed around in haphazard
// fashion.
//
// Optimization Note: Currently VC does a piss poor job of inlining this, even though
// constant propagation *should* resove it to little or no code (VC's constprop fails
// on C++ class initializers).  There is a work around [using array initializers instead]
// but it's too much trouble for code that isn't performance critical anyway.
// And, with luck, maybe VC10 will optimize it better and make it a non-issue. :D
//
void xIndirectVoid::Reduce()
{
	if( Index.IsStackPointer() )
	{
		// esp cannot be encoded as the index, so move it to the Base, if possible.
		// note: intentionally leave index assigned to esp also (generates correct
		// encoding later, since ESP cannot be encoded 'alone')

		pxAssert( Scale == 0 );		// esp can't have an index modifier!
		pxAssert( Base.IsEmpty() );	// base must be empty or else!

		Base = Index;
		return;
	}

	// If no index reg, then load the base register into the index slot.
	if( Index.IsEmpty() )
	{
		Index = Base;
		Scale = 0;
		if( !Base.IsStackPointer() )	// prevent ESP from being encoded 'alone'
			Base = xEmptyReg;
		return;
	}

	// The Scale has a series of valid forms, all shown here:

	switch( Scale )
	{
		case 0: break;
		case 1: Scale = 0; break;
		case 2: Scale = 1; break;

		case 3:				// becomes [reg*2+reg]
			pxAssertDev( Base.IsEmpty(), "Cannot scale an Index register by 3 when Base is not empty!" );
			Base = Index;
			Scale = 1;
		break;

		case 4: Scale = 2; break;

		case 5:				// becomes [reg*4+reg]
			pxAssertDev( Base.IsEmpty(), "Cannot scale an Index register by 5 when Base is not empty!" );
			Base = Index;
			Scale = 2;
		break;

		case 6:				// invalid!
			pxAssumeDev( false, "x86 asm cannot scale a register by 6." );
		break;

		case 7:				// so invalid!
			pxAssumeDev( false, "x86 asm cannot scale a register by 7." );
		break;

		case 8: Scale = 3; break;
		case 9:				// becomes [reg*8+reg]
			pxAssertDev( Base.IsEmpty(), "Cannot scale an Index register by 9 when Base is not empty!" );
			Base = Index;
			Scale = 3;
		break;
		
		jNO_DEFAULT
	}
}
Example #6
0
void SIO_CommandWrite(u8 value,int way) {
	PAD_LOG("sio write8 %x", value);

	// PAD COMMANDS
	switch (sio.padst) {
		case 1: SIO_INT();
			if ((value&0x40) == 0x40) {
				sio.padst = 2; sio.parp = 1;
				switch (sio.CtrlReg&0x2002) {
					case 0x0002:
						sio.packetsize ++;	// Total packet size sent
						sio.buf[sio.parp] = PADpoll(value);
						break;
					case 0x2002:
						sio.packetsize ++;	// Total packet size sent
						sio.buf[sio.parp] = PADpoll(value);
						break;
				}
				if (!(sio.buf[sio.parp] & 0x0f)) {
					sio.bufcount = 2 + 32;
				} else {
					sio.bufcount = 2 + (sio.buf[sio.parp] & 0x0f) * 2;
				}
			}
			else sio.padst = 0;
			return;
		case 2:
			sio.parp++;
			switch (sio.CtrlReg&0x2002) {
				case 0x0002: sio.packetsize ++; sio.buf[sio.parp] = PADpoll(value); break;
				case 0x2002: sio.packetsize ++; sio.buf[sio.parp] = PADpoll(value); break;
			}
			if (sio.parp == sio.bufcount) { sio.padst = 0; return; }
			SIO_INT();
			return;
		case 3:
			// No pad connected.
			sio.parp++;
			if (sio.parp == sio.bufcount) { sio.padst = 0; return; }
			SIO_INT();
			return;
	}

	// MEMORY CARD COMMANDS
	switch (sio.mcdst) {
		case 1:
		{
			sio.packetsize++;
			SIO_INT();
			if (sio.rdwr) { sio.parp++; return; }
			sio.parp = 1;

			const char* log_cmdname = "";

			switch (value) {
			case 0x11: // RESET
				log_cmdname = "Reset1";

				sio.bufcount =  8;
				memset8<0xff>(sio.buf);
				sio.buf[3] = sio.terminator;
				sio.buf[2] = '+';
				sio.mcdst = 99;
				sio2.packet.recvVal3 = 0x8c;
				break;

			// FIXME : Why are there two identical cases for resetting the
			// memorycard(s)?  there doesn't appear to be anything dealing with
			// card slots here.  --air
			case 0x12: // RESET
				log_cmdname = "Reset2";
				sio.bufcount =  8;
				memset8<0xff>(sio.buf);
				sio.buf[3] = sio.terminator;
				sio.buf[2] = '+';
				sio.mcdst = 99;
				sio2.packet.recvVal3 = 0x8c;
				break;

			case 0x81: // COMMIT
				log_cmdname = "Commit";
				sio.bufcount =  8;
				memset8<0xff>(sio.buf);
				sio.mcdst = 99;
				sio.buf[3] = sio.terminator;
				sio.buf[2] = '+';
				sio2.packet.recvVal3 = 0x8c;
				if(value == 0x81) {
					if(sio.mc_command==0x42)
						sio2.packet.recvVal1 = 0x1600; // Writing
					else if(sio.mc_command==0x43) sio2.packet.recvVal1 = 0x1700; // Reading
				}
				break;
			case 0x21:
			case 0x22:
			case 0x23: // SECTOR SET
				log_cmdname = "SetSector";
                sio.bufcount =  8; sio.mcdst = 99; sio.sector=0; sio.k=0;
				memset8<0xff>(sio.buf);
				sio2.packet.recvVal3 = 0x8c;
				sio.buf[8]=sio.terminator;
				sio.buf[7]='+';
				break;

			case 0x24: break;
			case 0x25: break;

			case 0x26:
			{
				log_cmdname = "GetInfo";

				const uint port = sio.GetMemcardIndex();
				const uint slot = sio.activeMemcardSlot[port];

				mc_command_0x26_tag cmd = mc_sizeinfo_8mb;
				PS2E_McdSizeInfo info;
				
				info.SectorSize			= cmd.sectorSize;
				info.EraseBlockSizeInSectors			= cmd.eraseBlocks;
				info.McdSizeInSectors	= cmd.mcdSizeInSectors;
				
				SysPlugins.McdGetSizeInfo( port, slot, info );
				pxAssumeDev( cmd.mcdSizeInSectors >= mc_sizeinfo_8mb.mcdSizeInSectors,
					"Mcd plugin returned an invalid memorycard size: Cards smaller than 8MB are not supported." );
				
				cmd.sectorSize			= info.SectorSize;
				cmd.eraseBlocks			= info.EraseBlockSizeInSectors;
				cmd.mcdSizeInSectors	= info.McdSizeInSectors;
				
				// Recalculate the xor summation
				// This uses a trick of removing the known xor values for a default 8mb memorycard (for which the XOR
				// was calculated), and replacing it with our new values.
				
				apply_xor( cmd.mc_xor, mc_sizeinfo_8mb.sectorSize );
				apply_xor( cmd.mc_xor, mc_sizeinfo_8mb.eraseBlocks );
				apply_xor( cmd.mc_xor, mc_sizeinfo_8mb.mcdSizeInSectors );

				apply_xor( cmd.mc_xor, cmd.sectorSize );
				apply_xor( cmd.mc_xor, cmd.eraseBlocks );
				apply_xor( cmd.mc_xor, cmd.mcdSizeInSectors );
				
				sio.bufcount = 12; sio.mcdst = 99; sio2.packet.recvVal3 = 0x83;
				memset8<0xff>(sio.buf);
				memcpy_fast(&sio.buf[2], &cmd, sizeof(cmd));
				sio.buf[12]=sio.terminator;
			}
			break;

			case 0x27:
			case 0x28:
			case 0xBF:
				log_cmdname = "NotSure";	// FIXME !!
				sio.bufcount =  4; sio.mcdst = 99; sio2.packet.recvVal3 = 0x8b;
				memset8<0xff>(sio.buf);
				sio.buf[4]=sio.terminator;
				sio.buf[3]='+';
				break;

			// FIXME ?
			// sio.lastsector and sio.mode are unused.

			case 0x42: // WRITE
				log_cmdname = "Write";
				//sio.mode = 0;
			goto __doReadWrite;

			case 0x43: // READ
				log_cmdname = "Read";
				//sio.lastsector = sio.sector; // Reading
			goto __doReadWrite;

			case 0x82:
				log_cmdname = "Read(?)"; // FIXME !!
				//if(sio.lastsector==sio.sector) sio.mode = 2;

			__doReadWrite:
				sio.bufcount =133; sio.mcdst = 99;
				memset8<0xff>(sio.buf);
				sio.buf[133]=sio.terminator;
				sio.buf[132]='+';
			break;
			

			case 0xf0:
			case 0xf1:
			case 0xf2:
				log_cmdname = "NoClue"; // FIXME !!
				sio.mcdst = 99;
				break;

			case 0xf3:
			case 0xf7:
				log_cmdname = "NoClueHereEither"; // FIXME !!
				sio.bufcount = 4; sio.mcdst = 99;
				memset8<0xff>(sio.buf);
				sio.buf[4]=sio.terminator;
				sio.buf[3]='+';
				break;

			case 0x52:
				log_cmdname = "FixMe"; // FIXME !!
				sio.rdwr = 1; memset8<0xff>(sio.buf);
				sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+';
				break;
			case 0x57:
				log_cmdname = "FixMe"; // FIXME !!
				sio.rdwr = 2; memset8<0xff>(sio.buf);
				sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+';
				break;
			default:
				log_cmdname = "Unknown";
				sio.mcdst = 0;
				memset8<0xff>(sio.buf);
				sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+';
			}
			MEMCARDS_LOG("MC(%d) command 0x%02X [%s]", sio.GetMemcardIndex()+1, value, log_cmdname);
			sio.mc_command = value;
		}
		return;		// END CASE 1.

		// FURTHER PROCESSING OF THE MEMORY CARD COMMANDS
		case 99:
		{
			sio.packetsize++;
			sio.parp++;
			switch(sio.mc_command)
			{
			// SET_ERASE_PAGE; the next erase commands will *clear* data starting with the page set here
			case 0x21:
			// SET_WRITE_PAGE; the next write commands will commit data starting with the page set here
			case 0x22:
			// SET_READ_PAGE; the next read commands will return data starting with the page set here
			case 0x23:
                if (sio.parp==2)sio.sector|=(value & 0xFF)<< 0;
				if (sio.parp==3)sio.sector|=(value & 0xFF)<< 8;
				if (sio.parp==4)sio.sector|=(value & 0xFF)<<16;
				if (sio.parp==5)sio.sector|=(value & 0xFF)<<24;
				if (sio.parp==6)
				{
					if (sio_xor((u8 *)&sio.sector, 4) == value)
						MEMCARDS_LOG("MC(%d) SET PAGE sio.sector, sector=0x%04X", sio.GetMemcardIndex()+1, sio.sector);
					else
						MEMCARDS_LOG("MC(%d) SET PAGE XOR value ERROR 0x%02X != ^0x%02X",
							sio.GetMemcardIndex()+1, value, sio_xor((u8 *)&sio.sector, 4));
				}
				break;

			// SET_TERMINATOR; reads the new terminator code
			case 0x27:
				if(sio.parp==2)	{
					sio.terminator = value;
					sio.buf[4] = value;
					MEMCARDS_LOG("MC(%d) SET TERMINATOR command, value=0x%02X", sio.GetMemcardIndex()+1, value);

				}
				break;

			// GET_TERMINATOR; puts in position 3 the current terminator code and in 4 the default one
			//                                                                  depending on the param
			case 0x28:
				if(sio.parp == 2) {
					sio.buf[2] = '+';
					sio.buf[3] = sio.terminator;

					//if(value == 0) sio.buf[4] = 0xFF;
					sio.buf[4] = 0x55;
					MEMCARDS_LOG("MC(%d) GET TERMINATOR command, value=0x%02X", sio.GetMemcardIndex()+1, value);
				}
				break;
			// WRITE DATA
			case 0x42:
				if (sio.parp==2) {
					sio.bufcount=5+value;
					memset8<0xff>(sio.buf);
					sio.buf[sio.bufcount-1]='+';
					sio.buf[sio.bufcount]=sio.terminator;
					MEMCARDS_LOG("MC(%d) WRITE command, size=0x%02X", sio.GetMemcardIndex()+1, value);
				}
				else
				if ((sio.parp>2) && (sio.parp<sio.bufcount-2)) {
					sio.buf[sio.parp]=value;
					//MEMCARDS_LOG("MC(%d) WRITING 0x%02X", sio.GetMemcardIndex()+1, value);
				} else
				if (sio.parp==sio.bufcount-2) {
					if (sio_xor(&sio.buf[3], sio.bufcount-5)==value) {
                        _SaveMcd(&sio.buf[3], (512+16)*sio.sector+sio.k, sio.bufcount-5);
						sio.buf[sio.bufcount-1]=value;
						sio.k+=sio.bufcount-5;
					} else {
						MEMCARDS_LOG("MC(%d) write XOR value error 0x%02X != ^0x%02X",
							sio.GetMemcardIndex()+1, value, sio_xor(&sio.buf[3], sio.bufcount-5));
					}
				}
				break;
			// READ DATA
			case 0x43:
				if (sio.parp==2)
				{
					//int i;
					sio.bufcount=value+5;
					sio.buf[3]='+';
					MEMCARDS_LOG("MC(%d) READ command, size=0x%02X", sio.GetMemcardIndex()+1, value);
					_ReadMcd(&sio.buf[4], (512+16)*sio.sector+sio.k, value);

					/*if(sio.mode==2)
					{
						int j;
						for(j=0; j < value; j++)
							sio.buf[4+j] = ~sio.buf[4+j];
					}*/

					sio.k+=value;
					sio.buf[sio.bufcount-1]=sio_xor(&sio.buf[4], value);
					sio.buf[sio.bufcount]=sio.terminator;
				}
				break;
			// INTERNAL ERASE
			case 0x82:
				if(sio.parp==2)
				{
					sio.buf[2]='+';
					sio.buf[3]=sio.terminator;
					//if (sio.k != 0 || (sio.sector & 0xf) != 0)
					//	Console.Warning("saving : odd position for erase.");

					_EraseMCDBlock((512+16)*(sio.sector&~0xf));

				/*	memset(sio.buf, -1, 256);
					_SaveMcd(sio.buf, (512+16)*sio.sector, 256);
					_SaveMcd(sio.buf, (512+16)*sio.sector+256, 256);
					_SaveMcd(sio.buf, (512+16)*sio.sector+512, 16);
					sio.buf[2]='+';
					sio.buf[3]=sio.terminator;*/
					//sio.buf[sio.bufcount] = sio.terminator;
					MEMCARDS_LOG("MC(%d) INTERNAL ERASE command 0x%02X", sio.GetMemcardIndex()+1, value);
				}
				break;
			// CARD AUTHENTICATION CHECKS
			case 0xF0:
				if (sio.parp==2)
				{
					MEMCARDS_LOG("MC(%d) CARD AUTH :0x%02X", sio.GetMemcardIndex()+1, value);
					switch(value){
					case  1:
					case  2:
					case  4:
					case 15:
					case 17:
					case 19:
						sio.bufcount=13;
						memset8<0xff>(sio.buf);
						sio.buf[12] = 0; // Xor value of data from index 4 to 11
						sio.buf[3]='+';
						sio.buf[13] = sio.terminator;
						break;
					case  6:
					case  7:
					case 11:
						sio.bufcount=13;
						memset8<0xff>(sio.buf);
						sio.buf[12]='+';
						sio.buf[13] = sio.terminator;
						break;
					default:
						sio.bufcount=4;
						memset8<0xff>(sio.buf);
						sio.buf[3]='+';
						sio.buf[4] = sio.terminator;
					}
				}
				break;
			}
			if (sio.bufcount<=sio.parp)	sio.mcdst = 0;
		}
		return;		// END CASE 99.
	}

	switch (sio.mtapst)
	{
		case 0x1:
			sio.packetsize++;
			sio.parp = 1;
			SIO_INT();
			switch(value) {
			case 0x12:
				// Query number of pads supported.
				sio.buf[3] = 4;
				sio.mtapst = 2;
				sio.bufcount = 5;
				break;
			case 0x13:
				// Query number of memcards supported.
				sio.buf[3] = 4;
				sio.mtapst = 2;
				sio.bufcount = 5;
				break;
			case 0x21:
				// Set pad slot.
				sio.mtapst = value;
				sio.bufcount = 6; // No idea why this is 6, saved from old code.
				break;
			case 0x22:
				// Set memcard slot.
				sio.mtapst = value;
				sio.bufcount = 6; // No idea why this is 6, saved from old code.
				break;
			}
			// Commented out values are from original code.  They break multitap in bios.
			sio.buf[sio.bufcount-1]=0;//'+';
			sio.buf[sio.bufcount]=0;//'Z';
			return;
		case 0x2:
			sio.packetsize++;
			sio.parp++;
            if (sio.bufcount<=sio.parp)	sio.mcdst = 0;
			SIO_INT();
			return;
		case 0x21:
			// Set pad slot.
			sio.packetsize++;
			sio.parp++;
			sio.mtapst = 2;
			if (sio.CtrlReg & 2)
			{
				int port = sio.GetMultitapPort();
				if (IsMtapPresent(port))
					sio.activePadSlot[port] = value;
			}
			SIO_INT();
			return;
		case 0x22:
			// Set memcard slot.
			sio.packetsize++;
			sio.parp++;
			sio.mtapst = 2;
			if (sio.CtrlReg & 2)
			{
				int port = sio.GetMultitapPort();
				if (IsMtapPresent(port))
					sio.activeMemcardSlot[port] = value;
			}
			SIO_INT();
			return;
	}

	if(sio.count == 1 || way == 0) InitializeSIO(value);
}