Ejemplo n.º 1
0
/**
 * Set retval to internal ID for requested Native Feature,
 * or zero if feature is unknown/unsupported.
 * 
 * Return true if caller is to proceed normally,
 * false if there was an exception.
 */
bool NatFeat_ID(Uint32 stack, Uint32 *retval)
{
	const char *name;
	Uint32 ptr;
	int i;

	ptr = STMemory_ReadLong(stack);
	if (!STMemory_ValidArea(ptr, FEATNAME_MAX)) {
		M68000_BusError(ptr, BUS_ERROR_READ);
		return false;
	}

	name = (const char *)STRAM_ADDR(ptr);
	Dprintf(("NF ID(0x%x)\n", ptr));
	Dprintf(("   \"%s\"\n", name));

	for (i = 0; i < ARRAYSIZE(features); i++) {
		if (strcmp(features[i].name, name) == 0) {
			*retval = IDX2MASTERID(i);
			return true;
		}
	}
	/* unknown feature */
	*retval = 0;
	return true;
}
Ejemplo n.º 2
0
/**
 * Copy given memory area safely to Atari RAM.
 * If the memory area isn't fully within RAM, only the valid parts are written.
 * Useful for all kinds of IO operations.
 * 
 * addr - destination Atari RAM address
 * src - source Hatari memory address
 * len - number of bytes to copy
 * name - name / description if this memory copy for error messages
 * 
 * Return true if whole copy was safe / valid.
 */
bool STMemory_SafeCopy(Uint32 addr, Uint8 *src, unsigned int len, const char *name)
{
	Uint32 end;

	if (STMemory_ValidArea(addr, len))
	{
		memcpy(&STRam[addr], src, len);
		return true;
	}
	Log_Printf(LOG_WARN, "Invalid '%s' RAM range 0x%x+%i!\n", name, addr, len);

	for (end = addr + len; addr < end; addr++, src++)
	{
		if (STMemory_ValidArea(addr, 1))
			STRam[addr] = *src;
	}
	return false;
}
Ejemplo n.º 3
0
/**
 * DebugInfo_GetSysbase: get and validate system base
 * return on success sysbase address (+ set rombase), on failure return zero
 */
static Uint32 DebugInfo_GetSysbase(Uint32 *rombase)
{
	Uint32 sysbase = STMemory_ReadLong(OS_SYSBASE);

	if (!STMemory_ValidArea(sysbase, OS_HEADER_SIZE)) {
		fprintf(stderr, "Invalid TOS sysbase RAM address (0x%x)!\n", sysbase);
		return 0;
	}
	/* under TOS, sysbase = os_beg = TosAddress, but not under MiNT -> use os_beg */
	*rombase = STMemory_ReadLong(sysbase+0x08);
	if (!STMemory_ValidArea(*rombase, OS_HEADER_SIZE)) {
		fprintf(stderr, "Invalid TOS sysbase ROM address (0x%x)!\n", *rombase);
		return 0;
	}
	if (*rombase != TosAddress) {
		fprintf(stderr, "os_beg (0x%x) != TOS address (0x%x), header in RAM not set up yet?\n",
			*rombase, TosAddress);
		return 0;
	}
	return sysbase;
}
Ejemplo n.º 4
0
static bool nf_stderr(Uint32 stack, Uint32 subid, Uint32 *retval)
{
	const char *str;
	Uint32 ptr;

	ptr = STMemory_ReadLong(stack);
	//Dprintf(("NF stderr(0x%x)\n", ptr));

	if (!STMemory_ValidArea(ptr, 1)) {
		M68000_BusError(ptr, BUS_ERROR_READ);
		return false;
	}
	str = (const char *)STRAM_ADDR(ptr);
	*retval = fprintf(stderr, "%s", str);
	fflush(stderr);
	return true;
}
Ejemplo n.º 5
0
static bool nf_name(Uint32 stack, Uint32 subid, Uint32 *retval)
{
	Uint32 ptr, len;
	const char *str;
	char *buf;

	ptr = STMemory_ReadLong(stack);
	len = STMemory_ReadLong(stack + SIZE_LONG);
	Dprintf(("NF name[%d](0x%x, %d)\n", subid, ptr, len));

	if (!STMemory_ValidArea(ptr, len)) {
		M68000_BusError(ptr, BUS_ERROR_WRITE);
		return false;
	}
	if (subid) {
		str = PROG_NAME;
	} else {
		str = "Hatari";
	}
	buf = (char *)STRAM_ADDR(ptr);
	*retval = snprintf(buf, len, "%s", str);
	return true;
}
Ejemplo n.º 6
0
/**
 * Check whether this is VDI/AES call and see if we need to re-direct
 * it to our own routines. Return true if VDI_Complete() function
 * needs to be called on OS call exit, otherwise return false.
 *
 * We enter here with Trap #2, so D0 tells which OS call it is (VDI/AES)
 * and D1 is pointer to VDI/AES vectors, i.e. Control, Intin, Ptsin etc...
 */
bool VDI_AES_Entry(void)
{
	Uint16 call = Regs[REG_D0];
	Uint32 TablePtr = Regs[REG_D1];

#if ENABLE_TRACING
	/* AES call? */
	if (call == 0xC8)
	{
		if (!STMemory_ValidArea(TablePtr, 24))
		{
			Log_Printf(LOG_WARN, "AES call failed due to invalid parameter block address 0x%x+%i\n", TablePtr, 24);
			return false;
		}
		/* store values for debugger "info aes" command */
		AESControl = STMemory_ReadLong(TablePtr);
		AESGlobal  = STMemory_ReadLong(TablePtr+4);
		AESIntin   = STMemory_ReadLong(TablePtr+8);
		AESIntout  = STMemory_ReadLong(TablePtr+12);
		AESAddrin  = STMemory_ReadLong(TablePtr+16);
		AESAddrout = STMemory_ReadLong(TablePtr+20);
		AESOpCode  = STMemory_ReadWord(AESControl);
		LOG_TRACE(TRACE_OS_AES, "AES call %3hd (%s)\n",
			  AESOpCode, AES_Opcode2Name(AESOpCode));

		/* using same special opcode trick doesn't work for
		 * both VDI & AES as AES functions can be called
		 * recursively and VDI calls happen inside AES calls.
		 */
		return false;
	}
#endif

	/* VDI call? */
	if (call == 0x73)
	{
		if (!STMemory_ValidArea(TablePtr, 20))
		{
			Log_Printf(LOG_WARN, "VDI call failed due to invalid parameter block address 0x%x+%i\n", TablePtr, 20);
			return false;
		}
		/* store values for extended VDI resolution handling
		 * and debugger "info vdi" command
		 */
		VDIControl = STMemory_ReadLong(TablePtr);
		VDIIntin   = STMemory_ReadLong(TablePtr+4);
		VDIPtsin   = STMemory_ReadLong(TablePtr+8);
		VDIIntout  = STMemory_ReadLong(TablePtr+12);
		VDIPtsout  = STMemory_ReadLong(TablePtr+16);
		VDIOpCode  = STMemory_ReadWord(VDIControl);
#if ENABLE_TRACING
		{
		Uint16 subcode = STMemory_ReadWord(VDIControl+2*5);
		LOG_TRACE(TRACE_OS_VDI, "VDI call %3hd/%3hd (%s)\n",
			  VDIOpCode, subcode,
			  VDI_Opcode2Name(VDIOpCode, subcode));
		}
#endif
		/* Only workstation open needs to be handled at trap return */
		return bUseVDIRes && VDI_isWorkstationOpen(VDIOpCode);
	}

	LOG_TRACE((TRACE_OS_VDI|TRACE_OS_AES), "Trap #2 with D0 = 0x%hX\n", call);
	return false;
}