Ejemplo n.º 1
0
static void fhfileOpen(void) {
  if (cpuGetDReg(0) < FHFILE_MAX_DEVICES) {
    memoryWriteByte(7, cpuGetAReg(1) + 8);                     /* ln_type (NT_REPLYMSG) */
    memoryWriteByte(0, cpuGetAReg(1) + 31);                    /* io_error */
    memoryWriteLong(cpuGetDReg(0), cpuGetAReg(1) + 24);                 /* io_unit */
    memoryWriteLong(memoryReadLong(cpuGetAReg(6) + 32) + 1, cpuGetAReg(6) + 32);  /* LIB_OPENCNT */
    cpuSetDReg(0, 0);                              /* ? */
  }
  else {
    memoryWriteLong(-1, cpuGetAReg(1) + 20);            
    memoryWriteByte(-1, cpuGetAReg(1) + 31);                   /* io_error */
    cpuSetDReg(0, -1);                             /* ? */
  }
}
Ejemplo n.º 2
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;
	}
Ejemplo n.º 3
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	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.
	}
Ejemplo n.º 4
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	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;
	}
Ejemplo n.º 5
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	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);
	}
Ejemplo n.º 6
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	uint16_t SetPtrSize(uint16_t trap)
	{
		/*
		 * on entry:
		 * A0 pointer
		 * D0 new size
		 *
		 * on exit:
		 * D0 Result code
		 *
		 */

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

		Log("%08x SetPtrSize(%08x, %08x)\n", trap, mcptr, newSize);

		auto iter = PtrMap.find(mcptr);

		if (iter == PtrMap.end()) return SetMemError(MacOS::memWZErr);

		uint8_t *ptr = mcptr + Memory;

		if (mplite_resize(&pool, ptr, mplite_roundup(&pool, newSize)) < 0)
		{
			return SetMemError(MacOS::memFullErr);
		}

		// update the size.
		iter->second = newSize;

		return SetMemError(0);
	}
Ejemplo n.º 7
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	uint16_t HSetState(uint16_t trap)
	{
		/*
		 * on entry:
		 * A0 Handle
		 * D0 flags
		 *
		 * on exit:
		 * D0 flag byte
		 *
		 */

		uint32_t hh = cpuGetAReg(0);
		uint16_t flags = cpuGetDReg(0);

		Log("%04x HSetState(%08x, %04x)\n", trap, hh, flags);

		auto iter = HandleMap.find(hh);

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

		auto &info = iter->second;

		info.resource = (flags & (1 << 5));
		info.purgeable = (flags & (1 << 6));
		info.locked = (flags & (1 << 7));


		return SetMemError(0);
	}
Ejemplo n.º 8
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	/*
	 * ReallocHandle (h: Handle; logicalSize: Size);
	 *
	 * ReallocHandle allocates a new relocatable block with a logical
	 * size of logicalSize bytes. It then updates handle h by setting
	 * its master pointer to point to the new block. The main use of
	 * this procedure is to reallocate space for a block that has
	 * been purged. Normally h is an empty handle, but it need not
	 * be: If it points to an existing block, that block is released
	 * before the new block is created.
	 *
	 * In case of an error, no new block is allocated and handle h is
	 * left unchanged.
	 */
	uint16_t ReallocHandle(uint16_t trap)
	{
		/*
		 * on entry:
		 * A0 Handle to be disposed of
		 * D0 Logical Size
		 *
		 * on exit:
		 * D0 Result code
		 *
		 */

		uint32_t hh = cpuGetAReg(0);
		uint32_t logicalSize = cpuGetDReg(0);

		Log("%04x ReallocHandle(%08x, %08x)\n", trap, hh, logicalSize);

		return Native::ReallocHandle(hh, logicalSize);

#if 0
		auto iter = HandleMap.find(hh);

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

		auto& info = iter->second;

		if (info.locked) return SetMemError(MacOS::memLockedErr);

		if (info.address)
		{
			void *address = Memory + info.address;

			mplite_free(&pool, address);

			info.address = 0;
			info.size = 0;
			memoryWriteLong(0, hh);
		}

		// allocate a new block...
		if (logicalSize == 0) return SetMemError(0);

		void *address = mplite_malloc(&pool, logicalSize);
		if (!address) return SetMemError(MacOS::memFullErr);

		uint32_t mcptr = (uint8_t *)address - Memory;

		info.size = logicalSize;
		info.address = mcptr;

		memoryWriteLong(mcptr, hh);

		// lock?  clear purged flag?

		return 0;
#endif
	}
Ejemplo n.º 9
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.º 10
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	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);
	}
Ejemplo n.º 11
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	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);
	}
Ejemplo n.º 12
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	uint32_t CompactMem(uint16_t trap)
	{
		// todo -- add function to check pool for largest block?

		/*
		 * on entry:
		 * D0: cbNeeded (long word)
		 *
		 * on exit:
		 * D0: function result (long word)
		 *
		 */
		 uint32_t cbNeeded = cpuGetDReg(0);

		 Log("%04x CompactMem(%08x)\n", trap, cbNeeded);


		 SetMemError(0);
		 return mplite_maxmem(&pool);
	}
Ejemplo n.º 13
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	uint16_t SetHandleSize(uint16_t trap)
	{

		/*
		 * on entry:
		 * A0 pointer
		 * D0 new size
		 *
		 * on exit:
		 * D0 Result code
		 *
		 */


		uint32_t hh = cpuGetAReg(0);
		uint32_t newSize = cpuGetDReg(0);

		Log("%04x SetHandleSize(%08x, %08x)\n", trap, hh, newSize);

		return Native::SetHandleSize(hh, newSize);
	}
Ejemplo n.º 14
0
	uint16_t HWPriv(uint16_t trap)
	{

		uint16_t selector;
		uint16_t d0 = 0;

		selector = cpuGetDReg(0) & 0xffff;
		Log("%04x HWTrap(%04x)\n", trap, selector);


		switch(selector)
		{
			case 0x0000:
				d0 = SwapInstructionCache();
				break;

			case 0x0001:
				d0 = FlushInstructionCache();
				break;

			case 0x0002:
				d0 = SwapDataCache();
				break;

			case 0x0003:
				d0 = FlushDataCache();
				break;

			case 0x0009:
				d0 = FlushCodeCacheRange();
				break;

			default:
				fprintf(stderr, "HWTrap selector %04x not yet supported\n", selector);
				exit(1);
		}

		return d0;

	}
Ejemplo n.º 15
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	uint16_t ReserveMem(uint16_t trap)
	{
		/*
		 * on entry:
		 * D0: cbNeeded (long word)
		 *
		 * on exit:
		 * D0: Result code.
		 *
		 */

		uint32_t cbNeeded = cpuGetDReg(0);
		uint32_t available;

		Log("%04x ReserveMem($%08x)\n", trap, cbNeeded);

		available = mplite_maxmem(&pool);
		// TODO -- if available < cbNeeded, purge handle and retry?
		if (available < cbNeeded) return SetMemError(MacOS::memFullErr);

		return SetMemError(0);
	}
Ejemplo n.º 16
0
	uint16_t AliasDispatch(uint16_t trap)
	{

		uint16_t selector = cpuGetDReg(0);

		Log("%04x AliasDispatch($%04x)\n", trap, selector);

		switch (selector)
		{

			case 0x000c:
				return ResolveAliasFile();
				break;

			default:
					fprintf(stderr, "AliasDispatch: selector $%04x not implemented\n", 
					selector);
				exit(1);		
		}


		return 0;
	}
Ejemplo n.º 17
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	uint32_t StripAddress(uint16_t trap)
	{
		/*
		 * on entry:
		 * d0 Address to strip
		 *
		 * on exit:
		 * D0 Address that has been stripped.
		 *
		 */

		// TODO -- in 32-bit mode, this is a nop.
		// have a --24 / --32 flag?

		uint32_t address = cpuGetDReg(0);

		Log("%04x StripAddress(%08x)\n", trap, address);

		if (MemorySize <= 0x00ffffff)
			address &= 0x00ffffff;

		return address;
	}
Ejemplo n.º 18
0
Archivo: mm.cpp Proyecto: iKarith/mpw
	uint16_t BlockMove(uint16_t trap)
	{
		// also implements BlockMoveData.
		// BlockMove will flush caches, BlockMoveData will not.

		/*
		 * on entry:
		 * A0 Pointer to source
		 * A1 Pointer to destination
		 * D0 Number of bytes to copy
		 *
		 * on exit:
		 * A0 Address of the new block or NIL
		 * D0 Result code
		 *
		 */

		uint32_t source = cpuGetAReg(0);
		uint32_t dest = cpuGetAReg(1);
		uint32_t count = cpuGetDReg(0);

		Log("%04x BlockMove(%08x, %08x, %08x)\n",
			trap, source, dest, count);

		// TODO -- 32-bit clean?
		// TODO -- verify within MemorySize?

		#if 0
		if (source == 0 || dest == 0 || count == 0)
			return 0;
		#endif

		std::memmove(Memory + dest, Memory + source, count);

		return 0;
	}