Beispiel #1
0
	uint16_t HandleZone(uint16_t trap)
	{
		// FUNCTION HandleZone (h: Handle): THz;
		/*
		 * on entry:
		 * A0 Handle whose zone is to be found
		 *
		 * on exit:
		 * A0 Pointer to handle’s heap zone
		 * D0 Result code
		 *
		 */

		uint32_t h = cpuGetAReg(0);

		Log("%04x HandleZone(%08x)\n", trap, h);


		if (HandleMap.find(h) == HandleMap.end())
		{
			cpuSetAReg(0, 0);
			return SetMemError(MacOS::memWZErr);
		}

		cpuSetAReg(0, 0);
		return SetMemError(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));
}
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));
}
static void cpuFrame2(UWO vector_offset, ULO pc)
{
  // save inst address
  cpuSetAReg(7, cpuGetAReg(7) - 4);
  memoryWriteLong(cpuGetOriginalPC(), cpuGetAReg(7));
  cpuFrame4Words(0x2000, vector_offset, pc);
}
Beispiel #5
0
void cpuSetUpInterrupt(ULO new_interrupt_level)
{
  UWO vector_offset = (UWO) (0x60 + new_interrupt_level*4);
  ULO vector_address = memoryReadLong(cpuGetVbr() + vector_offset);

  cpuActivateSSP(); // Switch to using ssp or msp. Loads a7 and preserves usp if we came from user-mode.

  cpuStackFrameGenerate(vector_offset, cpuGetPC()); // This will end up on msp if master is enabled, or on the ssp/isp if not.

  cpuSetSR(cpuGetSR() & 0x38ff);  // Clear interrupt level
  cpuSetSR(cpuGetSR() | 0x2000);  // Set supervisor mode
  cpuSetSR(cpuGetSR() | (UWO)(new_interrupt_level << 8)); // Set interrupt level

#ifdef CPU_INSTRUCTION_LOGGING
  cpuCallInterruptLoggingFunc(new_interrupt_level, vector_address);
#endif

  if (cpuGetModelMajor() >= 2 && cpuGetModelMajor() < 6)
  {
    if (cpuGetFlagMaster())
    { // If the cpu was in master mode, preserve msp, and switch to using ssp (isp) in a7.
      ULO oldA7 = cpuGetAReg(7);
      cpuSetMspDirect(oldA7);
      cpuSetAReg(7, cpuGetSspDirect());
      cpuFrame1(vector_offset, cpuGetPC());   // Make the throwaway frame on ssp/isp
      cpuSetSR(cpuGetSR() & 0xefff);  // Clear master bit
    }
  }
  cpuInitializeFromNewPC(vector_address);
  cpuSetStop(FALSE);
  cpuSetRaiseInterrupt(FALSE);
}
Beispiel #6
0
	uint16_t Gestalt(uint16_t trap)
	{
		// FUNCTION Gestalt (selector: OSType; VAR response: LongInt): OSErr;

		/*
		 * on entry:
		 * D0 Selector code
		 *
		 * on exit:
		 * A0 Response
		 * D0 Result code
		 *
		 */

		uint32_t selector = cpuGetDReg(0);
		uint32_t response;

		Log("%04x Gestalt('%s')\n", trap, ToolBox::TypeToString(selector).c_str());

		auto iter = GestaltMap.find(selector);

		if (iter == GestaltMap.end()) return gestaltUndefSelectorErr;
		response = iter->second;
		cpuSetAReg(0, response);

		return 0;
	}
Beispiel #7
0
	uint16_t NewHandle(uint16_t trap)
	{
		/*
		 * on entry:
		 * D0 Number of logical bytes requested
		 *
		 * on exit:
		 * A0 Address of the new handle or NIL
		 * D0 Result code
		 *
		 */

		uint32_t hh = 0;
		uint16_t error;

		bool clear = trap & (1 << 9);
		//bool sys = trap & (1 << 10);

		uint32_t size = cpuGetDReg(0);

		Log("%04x NewHandle(%08x)\n", trap, size);

		error = Native::NewHandle(size, clear, hh);

		cpuSetAReg(0, hh);
		return error;
	}
Beispiel #8
0
	uint16_t NewPtr(uint16_t trap)
	{
		/*
		 * on entry:
		 * D0 Number of logical bytes requested
		 *
		 * on exit:
		 * A0 Address of the new block or NIL
		 * D0 Result code
		 *
		 */


		bool clear = trap & (1 << 9);
		//bool sys = trap & (1 << 10);

		uint32_t size = cpuGetDReg(0);

		Log("%04x NewPtr(%08x)\n", trap, size);

		// todo -- separate pools for sys vs non-sys?
		// todo -- NewPtr(0) -- null or empty ptr?

		uint32_t mcptr;
		uint16_t error;
		error = Native::NewPtr(size, clear, mcptr);

		cpuSetAReg(0, mcptr);
		return error; //SetMemError(error);
	}
Beispiel #9
0
	uint16_t HandToHand(uint16_t trap)
	{
		/*
		 * on entry:
		 * A0 source Handle
		 *
		 * on exit:
		 * A0 destination Handle
		 * D0 Result code
		 *
		 */

		uint32_t srcHandle = cpuGetAReg(0);

		Log("%04x HandToHand(%08x)\n", trap, srcHandle);

		auto iter = HandleMap.find(srcHandle);
		if (iter == HandleMap.end())
			return SetMemError(MacOS::memWZErr);


		auto const info = iter->second;


		uint32_t destHandle;
		uint32_t destPtr;
		uint32_t d0 = Native::NewHandle(info.size, false, destHandle, destPtr);
		if (d0 == 0)
		{
			std::memmove(memoryPointer(destPtr), memoryPointer(info.address), info.size);
		}

		cpuSetAReg(0, destHandle);
		return d0; // SetMemError called by Native::NewHandle.
	}
Beispiel #10
0
	uint16_t PtrToHand(uint16_t trap)
	{
		/*
		 * on entry:
		 * A0 source Pointer
		 * D0 size
		 *
		 * on exit:
		 * A0 destination pointer
		 * D0 Result code
		 *
		 */

		uint32_t mcptr = cpuGetAReg(0);
		uint32_t size = cpuGetDReg(0);

		Log("%04x PtrToHand(%08x, %08x)\n", trap, mcptr, size);

		uint32_t destHandle;
		uint32_t destPtr;
		uint32_t d0 = Native::NewHandle(size, false, destHandle, destPtr);
		if (d0 == 0)
		{
			std::memmove(memoryPointer(destPtr), memoryPointer(mcptr), size);
		}

		cpuSetAReg(0, destHandle);
		return d0; // SetMemError called by Native::NewHandle.
	}
Beispiel #11
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));
}
Beispiel #12
0
/// <summary>
/// Sets the interrupt stack pointer. ssp is used as isp.
/// </summary>
void cpuSetIspAutoMap(ULO new_isp)
{
  if (cpuGetFlagSupervisor() && !cpuGetFlagMaster())
  {
    cpuSetAReg(7, new_isp);
  }
  else
  {
    cpuSetSspDirect(new_isp);
  }
}
Beispiel #13
0
	uint16_t SwapDataCache()
	{
		// FUNCTION SwapDataCache (cacheEnable: Boolean): Boolean;
		// boolean value sent/returned via a0.
		// c.f. mpw DumpObj -m SWAPDATACACHE Interface.o

		uint16_t cacheEnable = cpuGetAReg(0) & 0xff;

		Log("     SwapDataCache(%02x)\n", cacheEnable);
		cpuSetAReg(0, 0);
		return 0;
	}
Beispiel #14
0
	uint32_t PurgeSpace(uint16_t trap)
	{
		// PROCEDURE PurgeSpace (VAR total: LongInt; VAR contig: LongInt);

		/*
		 * Registers on exit:
		 * A0 Maximum number of contiguous bytes after purge
		 * D0 Total free memory after purge
		 */

		Log("%04x PurgeSpace()\n", trap);

		 SetMemError(0);
		 cpuSetAReg(0, mplite_maxmem(&pool));
		 return mplite_freemem(&pool);
	}
Beispiel #15
0
	uint16_t PtrAndHand(uint16_t trap)
	{
		// FUNCTION PtrAndHand (pntr: Ptr; hndl: Handle; size: LongInt): OSErr;

		/*
		 * on entry:
		 * A0 source Pointer
		 * A1 dest Handle
		 * D0 number of bytes to concatenate
		 *
		 * on exit:
		 * A0 destination Handle
		 * D0 Result code
		 *
		 */

		uint32_t ptr = cpuGetAReg(0);
		uint32_t handle = cpuGetAReg(1);
		uint32_t size = cpuGetDReg(0);

		Log("%04x PtrAndHand(%08x, %08x, %08x)\n", trap, ptr, handle, size);

		cpuSetAReg(0, handle);

		uint32_t oldSize = 0;
		uint32_t d0;

		d0 = Native::GetHandleSize(handle, oldSize);
		if (d0) return d0;

		if ((uint64_t)oldSize + (uint64_t)size > UINT32_MAX)
			return SetMemError(MacOS::memFullErr);


		d0 = Native::SetHandleSize(handle, oldSize + size);
		if (d0) return d0;

		auto iter = HandleMap.find(handle);
		if (iter == HandleMap.end())
			return SetMemError(MacOS::memWZErr);

		auto const info = iter->second;

		std::memmove(memoryPointer(info.address + oldSize), memoryPointer(ptr), size);

		return SetMemError(0);
	}
Beispiel #16
0
	uint16_t GetZone(uint16_t trap)
	{
		// FUNCTION GetZone: THz;

		/*
		 * on entry:
		 *
		 * on exit:
		 * A0 Pointer to current heap zone
		 * D0 Result code
		 */

		 Log("%04x GetZone()\n", trap);

		 cpuSetAReg(0, 0);
		 return 0;
	}
Beispiel #17
0
	uint32_t RecoverHandle(uint16_t trap)
	{
		// FUNCTION RecoverHandle (p: Ptr): Handle;

		/*
		 * on entry:
		 * A0 Master pointer
		 *
		 * on exit:
		 * A0 Handle to master pointer’s relocatable block
		 * D0 Unchanged
		 *
		 */


		uint32_t p = cpuGetAReg(0);
		uint32_t hh = 0;

		Log("%04x RecoverHandle(%08x)\n", trap, p);

		uint16_t error = MacOS::memBCErr;
		for (const auto kv : HandleMap)
		{
			const HandleInfo &info = kv.second;

			if (!info.address) continue;

			uint32_t begin = info.address;
			uint32_t end = info.address + info.size;
			if (!info.size) end++;
			if (p >= begin && p < end)
			{
				hh = kv.first;
				error = MacOS::noErr;
				break;
			}
		}

		SetMemError(error);
		cpuSetAReg(0, hh);

		// return d0 register unchanged.
		return cpuGetDReg(0);
	}
Beispiel #18
0
ULO cpuActivateSSP(void)
{
  ULO currentSP = cpuGetAReg(7);

  // check supervisor bit number (bit 13) within the system byte of the status register
  if (!cpuGetFlagSupervisor())
  {
    // we are in user mode, thus save user stack pointer (USP)
    cpuSetUspDirect(currentSP);
    currentSP = cpuGetSspDirect();

    if (cpuGetModelMajor() >= 2)
    {
      if (cpuGetFlagMaster())
      {
        currentSP = cpuGetMspDirect();
      }
    }
    cpuSetAReg(7, currentSP);
  }
  return currentSP;
}
Beispiel #19
0
static void cpuFrame8(UWO vector_offset, ULO pc)
{
  cpuSetAReg(7, cpuGetAReg(7) - 50);
  cpuFrame4Words(0x8000, vector_offset, pc);
}
Beispiel #20
0
static void cpuFrameA(UWO vector_offset, ULO pc)
{
  // save vector_offset offset
  cpuSetAReg(7, cpuGetAReg(7) - 24);
  cpuFrame4Words(0xa000, vector_offset, pc);
}