Ejemplo n.º 1
0
/**
 *  Set watchpoint for data comparison with another 2 comparator used for data address matching
 *  Note : Will automatically set processor to CORE_DEBUG_MODE
 *
 *  Input : matchingCompNumber1 is the first comparator going to be used for data address matching
 *          Possible value :
 *              COMPARATOR_0               DWT Comparator Number 0
 *              COMPARATOR_2               DWT Comparator Number 2
 *              COMPARATOR_3               DWT Comparator Number 3
 *
 *          address1 is the first address to be used for data address matching
 *          addressMask1 is the mask going to be applied to the first address 
 *          Possible value :
 *              WATCHPOINT_MASK_NOTHING  		  Compare all 32 bits of address set in DWT_COMPn 
 *							WATCHPOINTMASK_BIT0 			    Ignore Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINTMASK_BIT1_BIT0		  Ignore Bit1 and Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINTMASK_BIT2_BIT0		  Ignore Bit2 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINTMASK_BIT3_BIT0		  Ignore Bit3 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT4_BIT0     Ignore Bit4 to Bit 0 of address set in DWT_COMPn during comparison
 *                        ""                                              ""
 *							WATCHPOINT_MASK_BIT12_BIT0		Ignore Bit12 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT13_BIT0		Ignore Bit13 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT14_BIT0	  Ignore Bit14 to Bit 0 of address set in DWT_COMPn during comparison
 *
 *          matchingCompNumber2 is the second comparator going to be used for data address matching
 *          Possible value :
 *              COMPARATOR_0               DWT Comparator Number 0
 *              COMPARATOR_2               DWT Comparator Number 2
 *              COMPARATOR_3               DWT Comparator Number 3
 *
 *          address2 is the second address to be used for data address matching
 *          addressMask2 is the mask going to be applied to the second address 
 *          Possible value :
 *              WATCHPOINT_MASK_NOTHING  		  Compare all 32 bits of address set in DWT_COMPn 
 *							WATCHPOINT_MASK_BIT0  			  Ignore Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT1_BIT0,		Ignore Bit1 and Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT2_BIT0,		Ignore Bit2 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT3_BIT0,		Ignore Bit3 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT4_BIT0     Ignore Bit4 to Bit 0 of address set in DWT_COMPn during comparison
 *                        ""                                              ""
 *							WATCHPOINT_MASK_BIT12_BIT0		Ignore Bit12 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT13_BIT0		Ignore Bit13 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT14_BIT0	  Ignore Bit14 to Bit 0 of address set in DWT_COMPn during comparison
 *
 *          matchedData is the data going to be matched/compared
 *          dataSize is the data size going to be compared
 *          Possible value :
 *              WATCHPOINT_BYTE         
 *              WATCHPOINT_HALFWORD
 *              WATCHPOINT_WORD
 *
 *          accessMode is the access mode for the watchpoint
 *          Possible value :
 *              WATCHPOINT_READ         Watchpoint on read access
 *              WATCHPOINT_WRITE        Watchpoint on write access
 *              WATCHPOINT_READWRITE    Watchpoint on read/write access
 *
 *  Output :  return 0 if watchpoint is set 
 *            return -1 if invalid comparator is selected 
 */
int setDataWatchpoint_MatchingTwoComparator(int matchingCompNumber1,uint32_t address1,Watchpoint_AddressMask addressMask1,
                                            int matchingCompNumber2,uint32_t address2,Watchpoint_AddressMask addressMask2,
                                            uint32_t matchedData,Watchpoint_DataSize dataSize,Watchpoint_AccessMode accessMode)
{
  int result = 0 ;
  int valid1 = 0 , valid2 = 0 ;
  uint32_t configData = 0 ;
  
  valid1 = checkForValidDWTComparator(matchingCompNumber1);
  valid2 = checkForValidDWTComparator(matchingCompNumber2);

  if(matchingCompNumber1 == 1 || matchingCompNumber2 == 1 || valid1 == -1 || valid2 == -1)
    return -1 ;

  configData = (matchingCompNumber2 << 16) + (matchingCompNumber1 << 12) + (dataSize << 10) + (DATA_COMPARISON << 8) + accessMode ;

  setAddressWatchpoint(matchingCompNumber1,address1,addressMask1,DISABLE_DWTCOMPARATOR);
  setAddressWatchpoint(matchingCompNumber2,address2,addressMask2,DISABLE_DWTCOMPARATOR);
  
  memoryWriteWord((uint32_t)(&DWT_COMP[1].FUNCTION),DISABLE_DWTCOMPARATOR); //disable selected comparator first
  
  memoryWriteWord((uint32_t)(&DWT_COMP[1].COMP),matchedData);
  memoryWriteWord((uint32_t)(&DWT_COMP[1].MASK),WATCHPOINT_MASK_NOTHING);
  memoryWriteWord((uint32_t)(&DWT_COMP[1].FUNCTION),configData);
  
  return result ;
}
Ejemplo n.º 2
0
static void cpuFrame4Words(UWO frame_code, UWO vector_offset, ULO pc)
{
  // save vector_offset word
  cpuSetAReg(7, cpuGetAReg(7) - 2);
  memoryWriteWord(frame_code | vector_offset, cpuGetAReg(7));

  // save PC
  cpuSetAReg(7, cpuGetAReg(7) - 4);
  memoryWriteLong(pc, cpuGetAReg(7));

  // save SR
  cpuSetAReg(7, cpuGetAReg(7) - 2);
  memoryWriteWord((UWO)cpuGetSR(), cpuGetAReg(7));
}
Ejemplo n.º 3
0
/*
 * interruptSet()
 *
 * ustawia funkcjê obs³ugi przerwania.
 */
void interruptSet(byte number, word offset)
{
    word segCS = 0;

#asm
    push ax
    mov ax,cs
    mov -6[bp],ax
    pop ax
#endasm

    memoryWriteWord(0x0000, number * 4, offset);
    memoryWriteWord(0x0000, number * 4 + 2, segCS);
}
Ejemplo n.º 4
0
	uint16_t SysEnvirons(uint16_t trap)
	{
		//  FUNCTION SysEnvirons (versionRequested: Integer;
		//                        VAR theWorld: SysEnvRec): OSErr;

		/*
		 * on entry:
		 * D0 Version requested
		 * A0 SysEnvRec pointer
		 *
		 * on exit:
		 * D0 Result code
		 *
		 */

		enum {
			/* SysEnvRec */
			_environsVersion = 0,
			_machineType = 2,
			_systemVersion = 4,
			_processor = 6,
			_hasFPU = 8,
			_hasColorQD = 9,
			_keyBoardType = 10,
			_atDrvrVersNum = 12,
			_sysVRefNum = 14,
		};

		uint16_t versionRequested = cpuGetDReg(0);
		uint32_t theWorld = cpuGetAReg(0);

		Log("%04x SysEnvirons(%04x, %08x)\n", trap, versionRequested, theWorld);

		memoryWriteWord(2, theWorld + _environsVersion);

		// negative version.
		if (versionRequested >= 0x8000)
			return MacOS::envBadVers;

		if (versionRequested > 2)
			return MacOS::envVersTooBig;

		memoryWriteWord(0, theWorld + _machineType); // 0 = unknown model newer than the IIci (v1) or IIfx (v2)
		memoryWriteWord(1 + cpuGetModelMajor(), theWorld + _processor);
		memoryWriteWord(0x0700, theWorld + _systemVersion); // system 7
		memoryWriteWord(0, theWorld + _hasFPU);
		memoryWriteWord(0, theWorld + _hasColorQD);
		memoryWriteWord(5, theWorld + _keyBoardType); // standard adb I guess
		memoryWriteWord(0, theWorld + _atDrvrVersNum); // no appletalk
		memoryWriteWord(-1, theWorld + _sysVRefNum); // System folder #

		return 0;
	}
Ejemplo n.º 5
0
void mmuWriteWord(Word vAddr, Word data, Bool userMode) {
  if ((vAddr & 3) != 0) {
    /* throw illegal address exception */
    mmuBadAccs = MMU_ACCS_WRITE | MMU_ACCS_WORD;
    mmuBadAddr = vAddr;
    throwException(EXC_ILL_ADDRESS);
  }
  memoryWriteWord(v2p(vAddr, userMode, true, MMU_ACCS_WORD), data);
}
Ejemplo n.º 6
0
static void cpuFrameGroup1(UWO vector_offset, ULO pcPtr)
{
  // save PC
  cpuSetAReg(7, cpuGetAReg(7) - 4);
  memoryWriteLong(pcPtr, cpuGetAReg(7));

  // save SR
  cpuSetAReg(7, cpuGetAReg(7) - 2);
  memoryWriteWord((UWO)cpuGetSR(), cpuGetAReg(7));
}
Ejemplo n.º 7
0
/**
 *  Set watchpoint for address comparison
 *  Note : Will automatically set processor to CORE_DEBUG_MODE
 *
 *  Input : dwtCompNumber is the comparator going to be used 
 *          Possible value :
 *              COMPARATOR_0               DWT Comparator Number 0
 *              COMPARATOR_1               DWT Comparator Number 1
 *              COMPARATOR_2               DWT Comparator Number 2
 *              COMPARATOR_3               DWT Comparator Number 3
 *
 *          address is the address to be compared
 *          addressMask is the mask going to be applied to the address 
 *          Possible value :
 *              WATCHPOINT_MASK_NOTHING  		  Compare all 32 bits of address set in DWT_COMPn 
 *							WATCHPOINT_MASK_BIT0  			  Ignore Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT1_BIT0,		Ignore Bit1 and Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT2_BIT0,		Ignore Bit2 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT3_BIT0,		Ignore Bit3 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT4_BIT0     Ignore Bit4 to Bit 0 of address set in DWT_COMPn during comparison
 *                        ""                                              ""
 *							WATCHPOINT_MASK_BIT12_BIT0		Ignore Bit12 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT13_BIT0		Ignore Bit13 to Bit 0 of address set in DWT_COMPn during comparison
 *							WATCHPOINT_MASK_BIT14_BIT0	  Ignore Bit14 to Bit 0 of address set in DWT_COMPn during comparison
 *
 *          accessMode is the access mode for the watchpoint
 *          Possible value :
 *              WATCHPOINT_READ         Watchpoint on read access
 *              WATCHPOINT_WRITE        Watchpoint on write access
 *              WATCHPOINT_READWRITE    Watchpoint on read/write access
 *
 *  Output :  return 0 if watchpoint is set 
 *            return -1 if invalid comparator is selected
 */
int setAddressWatchpoint(int dwtCompNumber,uint32_t address,Watchpoint_AddressMask addressMask,Watchpoint_AccessMode accessMode)
{ 
  int result = 0 ;
  int valid = checkForValidDWTComparator(dwtCompNumber) ;
  
  if(valid == -1)
    return -1 ;
  
  enableDWTandITM(); //enable global enable for DWT (Needed for reading & writing DWT Register)
  setCoreMode(CORE_DEBUG_MODE);
  
  memoryWriteWord((uint32_t)(&DWT_COMP[dwtCompNumber].FUNCTION),DISABLE_DWTCOMPARATOR); //disable selected comparator first

  memoryWriteWord((uint32_t)(&DWT_COMP[dwtCompNumber].COMP),address);
  memoryWriteWord((uint32_t)(&DWT_COMP[dwtCompNumber].MASK),addressMask);
  
  if(accessMode != DISABLE_DWTCOMPARATOR)//prevent setting to disable mode twice
    memoryWriteWord((uint32_t)(&DWT_COMP[dwtCompNumber].FUNCTION),accessMode);
  
  return result ;
}
Ejemplo n.º 8
0
/**
 *  Disable the selected DWT Comparator
 *
 *  Input : dwtCompNumber is the comparator going to be used 
 *          Possible value :
 *              COMPARATOR_0               DWT Comparator Number 0
 *              COMPARATOR_1               DWT Comparator Number 1
 *              COMPARATOR_2               DWT Comparator Number 2
 *              COMPARATOR_3               DWT Comparator Number 3
 *
 *  Output :  return 0 if the comparator is disabled
 *            return -1 if invalid comparator is selected 
 */
int disableDWTComparator(int dwtCompNumber)
{
  int valid = 0 ;
  
  valid = checkForValidDWTComparator(dwtCompNumber) ;
  if(valid == -1)
    return valid ;
    
  memoryWriteWord((uint32_t)(&DWT_COMP[dwtCompNumber].FUNCTION),DISABLE_DWTCOMPARATOR);
  
  return 0 ;
}
Ejemplo n.º 9
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	uint16_t TempDisposeHandle(void)
	{
		// PROCEDURE TempDisposeHandle (theHandle: Handle; VAR resultCode: OSErr);
		uint32_t theHandle;
		uint32_t resultCode;

		StackFrame<8>(theHandle, resultCode);

		Log("     TempDisposeHandle(%08x, %08x)\n", theHandle, resultCode);

		uint16_t rv = Native::DisposeHandle(theHandle);

		if (resultCode) memoryWriteWord(rv, resultCode);
		return rv;
	}
Ejemplo n.º 10
0
static void cpuFrameGroup2(UWO vector_offset, ULO pcPtr)
{
  // save PC
  cpuSetAReg(7, cpuGetAReg(7) - 4);
  memoryWriteLong(pcPtr, cpuGetAReg(7));

  // save SR
  cpuSetAReg(7, cpuGetAReg(7) - 2);
  memoryWriteWord((UWO)cpuGetSR(), cpuGetAReg(7));

  // fault address, skip ireg
  cpuSetAReg(7, cpuGetAReg(7) - 6);
  memoryWriteLong(memory_fault_address, cpuGetAReg(7));

  cpuSetAReg(7, cpuGetAReg(7) - 2);
  memoryWriteLong(memory_fault_read << 4, cpuGetAReg(7));
}
Ejemplo n.º 11
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	uint16_t TempNewHandle(void)
	{
		// FUNCTION TempNewHandle (logicalSize: Size;
		//                         VAR resultCode: OSErr): Handle;
		uint16_t rv;
		uint32_t logicalSize;
		uint32_t resultCode;
		uint32_t theHandle;

		uint32_t sp = StackFrame<8>(logicalSize, resultCode);

		Log("     TempNewHandle(%08x, %08x)\n", logicalSize, resultCode);

		rv = Native::NewHandle(logicalSize, true, theHandle);

		if (resultCode) memoryWriteWord(rv, resultCode);
		ToolReturn<4>(sp, theHandle);
		return rv;
	}
Ejemplo n.º 12
0
	void ftrap_close(uint16_t trap)
	{
		// returns an mpw_errno
		// close actually checks the error in the File Entry and converts that to unix.
		// (sigh)

		uint32_t d0 = 0;

		uint32_t sp = cpuGetAReg(7);
		uint32_t parm  = memoryReadLong(sp + 4);

		MPWFile f;

		f.flags = memoryReadWord(parm);
		f.error = memoryReadWord(parm + 2);
		f.device = memoryReadLong(parm + 4);
		f.cookie = memoryReadLong(parm + 8);
		f.count = memoryReadLong(parm + 12);
		f.buffer = memoryReadLong(parm + 16);


		Log("%04x Close(%08x)\n", trap, parm);

		if (!parm)
		{
			cpuSetDReg(0, kEINVAL);
			return;
		}


		int fd = f.cookie;

		int rv = OS::Internal::FDEntry::close(fd);

		if (rv < 0)
		{
			f.error = MacOS::notOpenErr;
			d0 = kEINVAL;
		}
		else
		{
			f.error = 0;
			d0 = 0;
		}


#if 0
		if (fd < 0 || fd >= OS::Internal::FDTable.size())
		{
			f.error = OS::notOpenErr;
			d0 = kEINVAL;
		}
		else
		{
			auto &e = OS::Internal::FDTable[fd];
			if (e.refcount == 0)
			{
				f.error = OS::notOpenErr;
				d0 = kEINVAL;
			}
			else
			{
				if (--e.refcount == 0)
				{
					Log("     close(%02x)\n", fd);
					::close(fd);
				}
				f.error = 0;
				d0 = 0;
			}
		}
#endif

		memoryWriteWord(f.error, parm + 2);
		cpuSetDReg(0, 0);
	}
Ejemplo n.º 13
0
Archivo: mpw.cpp Proyecto: iKarith/mpw
	uint16_t Init(int argc, char **argv)
	{
		/*
		FDTable.resize(16);

		FDTable[STDIN_FILENO] = 1;
		FDTable[STDOUT_FILENO] = 1;
		FDTable[STDERR_FILENO] = 1;
		*/

		/*
		OS::Internal::FDTable.resize(3);
		FDTable[STDIN_FILENO].refcount = 1;
		FDTable[STDIN_FILENO].text = true;

		FDTable[STDOUT_FILENO].refcount = 1;
		FDTable[STDOUT_FILENO].text = true;

		FDTable[STDERR_FILENO].refcount = 1;
		FDTable[STDERR_FILENO].text = true;
		*/

		OS::Internal::FDEntry::allocate(STDIN_FILENO).text = true;
		OS::Internal::FDEntry::allocate(STDOUT_FILENO).text = true;
		OS::Internal::FDEntry::allocate(STDERR_FILENO).text = true;


		std::string command = argv[0];

		command = ToolBox::UnixToMac(command);
		//std::replace(command.begin(), command.end(), '/', ':');

		argv[0] = basename(argv[0]);


		// 0x0910 CurApName
		{
			char str32[32];

			char * name = argv[0];
			int l = strlen(name);
			l = std::min(l, 32);
			str32[0] = l;
			std::memcpy(str32 + 1, name, l);
			while (l < 32) str32[l++] = 0;

			std::memcpy(memoryPointer(MacOS::CurApName), str32, 32);
		}


		uint32_t argvptr = 0;
		uint32_t envptr = 0;
		uint32_t ioptr = 0;
		uint32_t devptr = 0;
		uint32_t fptr = 0;

		uint16_t error;

		// create the argv-data.
		{
			uint32_t size = 0;

			size = 4 * (argc + 1); // argv data.

			for (int i = 0; i < argc; ++i)
			{
				int l = strlen(argv[i]) + 1;
				if (l & 0x01) l++;
				size += l;
			}

			error = MM::Native::NewPtr(size, true, argvptr);
			if (error) return error;


			uint8_t *xptr = memoryPointer(argvptr);
			uint32_t offset = 0;

			offset = 4 * (argc + 1);

			for (int i = 0; i < argc; ++i)
			{
				memoryWriteLong(argvptr + offset, argvptr + 4 * i);

				// just use strcat?
				int l = strlen(argv[i]) + 1;
				if (l & 0x01) l++;

				strcpy((char *)xptr + offset, argv[i]);

				offset += l;
			}

			// null-terminate it.
			memoryWriteLong(0, argvptr + 4 * argc);

		}

		// environment
		{
			Environment.emplace(std::string("Command"), command);

			std::deque<std::string> e;

			for (const auto &iter : Environment)
			{
				std::string tmp;
				tmp.append(iter.first);
				tmp.push_back(0);
				tmp.append(iter.second);
				e.emplace_back(std::move(tmp));
			}


			uint32_t size = 0;
			for (const std::string &s : e)
			{
				int l = s.length() + 1;
				if (l & 0x01) l++;
				size = size + l + 4;
			}

			size += 4; // space for null terminator.

			error = MM::Native::NewPtr(size, true, envptr);
			if (error) return error;


			uint8_t *xptr = memoryPointer(envptr);
			uint32_t offset = 0;

			offset = 4 * (e.size() + 1);
			unsigned i = 0;
			for (const std::string &s : e)
			{
				// ptr
				memoryWriteLong(envptr + offset, envptr + i * 4);

				int l = s.length() + 1;

				std::memcpy(xptr + offset, s.c_str(), l);

				if (l & 0x01) l++;
				offset += l;
				++i;
			}


			// null-terminate it.
			memoryWriteLong(0, envptr + 4 * e.size());
		}

		// ftable
		{
			// these are ftraps for emulated/native function ptrs.
			uint32_t size = 6 * 4;

			error = MM::Native::NewPtr(size, true, fptr);

			if (error) return error;

			memoryWriteWord(fQuit, fptr + 0);
			memoryWriteWord(0x4E75, fptr + 2); // rts

			memoryWriteWord(fAccess, fptr + 4);
			memoryWriteWord(0x4E75, fptr + 6); // rts

			memoryWriteWord(fClose, fptr + 8);
			memoryWriteWord(0x4E75, fptr + 10); // rts

			memoryWriteWord(fRead, fptr + 12);
			memoryWriteWord(0x4E75, fptr + 14); // rts

			memoryWriteWord(fWrite, fptr + 16);
			memoryWriteWord(0x4E75, fptr + 18); // rts

			memoryWriteWord(fIOCtl, fptr + 20);
			memoryWriteWord(0x4E75, fptr + 22); // rts

		}


		// dev table
		{
			uint32_t size = 0x78;

			error = MM::Native::NewPtr(size, true, devptr);

			if (error) return error;

			memoryWriteLong(0x46535953, devptr + 0); // 'FSYS'
			memoryWriteLong(fptr + 4, devptr + 4);
			memoryWriteLong(fptr + 8, devptr + 8);
			memoryWriteLong(fptr + 12, devptr + 12);
			memoryWriteLong(fptr + 16, devptr + 16);
			memoryWriteLong(fptr + 20, devptr + 20);

			memoryWriteLong(0x45434f4e, devptr + 24); // 'ECON' -- not implemented.
			memoryWriteLong(0x53595354, devptr + 48); // 'SYST' -- not implemented.

		}

		// io table.
		{

			uint32_t size = 0x3c;
			uint32_t ptr;

			error = MM::Native::NewPtr(size, true, ioptr);

			if (error) return error;

			ptr = ioptr;
			// stdin
			memoryWriteWord(0x0001, ptr + 0); // open flags (read)
			memoryWriteWord(0x0000, ptr + 2); // os err
			memoryWriteLong(devptr, ptr + 4); // -> 'FSYS'
			memoryWriteLong(STDIN_FILENO, ptr + 8); // cookie
			memoryWriteLong(0, ptr + 12); // transfer count.
			memoryWriteLong(0, ptr + 16); // buffer

			ptr = ioptr + 20;
			// stdout
			memoryWriteWord(0x0002, ptr + 0); // open flags (write)
			memoryWriteWord(0x0000, ptr + 2); // os err
			memoryWriteLong(devptr, ptr + 4); // -> 'FSYS'
			memoryWriteLong(STDOUT_FILENO, ptr + 8); // cookie
			memoryWriteLong(0, ptr + 12); // transfer count.
			memoryWriteLong(0, ptr + 16); // buffer

			ptr = ioptr + 40;
			// stderr
			memoryWriteWord(0x0002, ptr + 0); // open flags (write)
			memoryWriteWord(0x0000, ptr + 2); // os err
			memoryWriteLong(devptr, ptr + 4); // -> 'FSYS'
			memoryWriteLong(STDERR_FILENO, ptr + 8); // cookie
			memoryWriteLong(0, ptr + 12); // transfer count.
			memoryWriteLong(0, ptr + 16); // buffer

		}



		uint32_t mpi = 0;

		error = MM::Native::NewPtr(8 + 0x30, true, mpi);
		if (error) return error;

		MacProgramInfo = mpi + 8;

		memoryWriteLong(0x4d50474d, mpi); // 'MPGM' - magic
		memoryWriteLong(mpi + 8, mpi + 4);

		memoryWriteLong(mpi, 0x0316);

		mpi += 8;
		memoryWriteWord(0x5348, mpi + 0x00); // 'SH' - more magic

		memoryWriteLong(argc, mpi + 0x02);
		memoryWriteLong(argvptr, mpi + 0x06);
		memoryWriteLong(envptr, mpi + 0x0a);

		// 0x0e = exit code

		// ??? default fd table size?
		memoryWriteWord(0x190, mpi + 0x1a);

		// io table - stdin/stdout/stderr
		memoryWriteLong(ioptr, mpi + 0x1c);

		// device table
		memoryWriteLong(devptr, mpi + 0x20);


		return 0;
	}
Ejemplo n.º 14
0
/*


	MPW's open logic pseudo code:

	if (flags & 0x1000) { // undocumented - use old tool calls
		oserr = flags & O_RSRC ? PBOPENRF() : PBOPEN();
	} else {
		oserr = flags & O_RSRC ? PBHOPENRF() : PBHOPEN();
	}
	if (!oserr) {
		if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
			errno = EEXIST;
			return;
		}
		return;
	}
	if (oserr == file not found) {
		if (flags & O_CREAT) {
			oserr = PBCreate();
			if (!oserr) {
				oserr = flag & O_RSRC ? PBOpenRF() : PBOpen();
			} 
	}

	PBGETFCBINFO();
	if (file size) {
		if (flags & O_TRUNC) {
			oserr = PBSetEOF();
		}
		if (!permission check) {
			errno = EPERM;
			PBClose();
	}





*/
	uint32_t ftrap_open(uint32_t name, uint32_t parm)
	{
		uint32_t d0;
		int fd;
		std::string sname;

		MPWFile f;
		int nativeFlags = 0;
		std::memset(&f, 0, sizeof(f));

		f.flags = memoryReadWord(parm);


		nativeFlags = 0;
		switch (f.flags & 0x03)
		{
			case 0x01:
				nativeFlags = O_RDONLY;
				break;
			case 0x02:
				nativeFlags = O_WRONLY;
				break;
			case 0x00: // ????
			case 0x03:
				nativeFlags = O_RDWR;
				break;
		}

		if (f.flags & kO_APPEND) nativeFlags |= O_APPEND;
		if (f.flags & kO_CREAT) nativeFlags |= O_CREAT;
		if (f.flags & kO_TRUNC) nativeFlags |= O_TRUNC;
		if (f.flags & kO_EXCL) nativeFlags |= O_EXCL;


		sname = ToolBox::ReadCString(name, true);
		std::string xname = sname;

		Log("     open(%s, %04x)\n", sname.c_str(), f.flags);


		if (f.flags & kO_RSRC) {

			// O_CREAT and O_EXCL apply to the file, not the fork.
			int flags = O_RDONLY | (nativeFlags & (O_CREAT | O_EXCL));

			int parent = ::open(sname.c_str(), flags, 0666);

			fd = -1;
			if (parent >= 0) {

				sname.append(_PATH_RSRCFORKSPEC);

				nativeFlags &= ~O_EXCL;
				// APFS, etc - resource fork doesn't automatically exist so 
				// need O_CREAT.
				if ((nativeFlags & O_ACCMODE) != O_RDONLY) nativeFlags |= O_CREAT;
				fd = ::open(sname.c_str(), nativeFlags, 0666);
				close(parent);
			}

		} else {
			fd = ::open(sname.c_str(), nativeFlags, 0666);
		}

		if (fd < 0)
		{
			// return an errno.
			d0 = 0x40000000 | mpw_errno_from_errno();
			f.error = MacOS::ioErr;
			f.cookie = 0;
		}
		else
		{
			d0 = 0;
			f.error = 0;
			f.cookie = fd;


			// adjust the binary flags...
			// some apps are good about this but
			// dumpobj, makelib, linkiigs don't set O_BINARY (but should)
			// MPW Assembler sets O_BINARY (but shouldn't)

			if (OS::IsTextFile(sname)) f.flags &= ~kO_BINARY;
			if (OS::IsBinaryFile(sname)) f.flags |= kO_BINARY;

			if (f.flags & kO_RSRC) f.flags |= kO_BINARY;

			auto &e = OS::Internal::FDEntry::allocate(fd, std::move(xname));
			e.text = !(f.flags & kO_BINARY);
			e.resource = f.flags & kO_RSRC;
		}

		memoryWriteWord(f.flags, parm + 0);
		memoryWriteWord(f.error, parm + 2);
		memoryWriteLong(f.cookie, parm + 8);

		return d0;
	}