Exemplo n.º 1
0
Arquivo: psg.c Projeto: denizt/hatari
/**
 * Write byte to 0xff8803. Set content of YM's data register under conditions.
 * Address 0xff8803 is a shadow version of 0xff8802, so both addresses can't be written
 * at the same time by the same instruction. This means only a .B access or
 * a movep will have a valid effect, other accesses are ignored.
 */
void PSG_ff8803_WriteByte(void)
{
	if ( nIoMemAccessSize == SIZE_BYTE )		/* byte access or movep */
	{	
		M68000_WaitState(1);			/* [NP] FIXME not 100% accurate, but gives good results */
	
		if (LOG_TRACE_LEVEL(TRACE_PSG_WRITE))
		{
			int FrameCycles, HblCounterVideo, LineCycles;
			Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
			LOG_TRACE_PRINT("ym write %x=0x%x video_cyc=%d %d@%d pc=%x instr_cycle %d\n",
					IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress],
					FrameCycles, LineCycles, HblCounterVideo, M68000_GetPC(), CurrentInstrCycles);
		}
		
		PSG_Set_DataRegister ( IoMem[IoAccessCurrentAddress] );
	}

	else
	{						/* do nothing, just a trace if needed */
		if (LOG_TRACE_LEVEL(TRACE_PSG_WRITE))
		{
			int FrameCycles, HblCounterVideo, LineCycles;
			Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
			LOG_TRACE_PRINT("ym write ignored %x=0x%x video_cyc=%d %d@%d pc=%x instr_cycle %d\n",
					IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress],
					FrameCycles, LineCycles, HblCounterVideo, M68000_GetPC(), CurrentInstrCycles);
		}
	}
}
Exemplo n.º 2
0
/**
 * This is called after completion of each VDI call
 */
unsigned long OpCode_VDI(uae_u32 opcode)
{
	Uint32 pc = M68000_GetPC();

	/* this is valid only after VDI trap, called from cartridge code */
	if (VDI_OldPC && pc >= 0xfa0000 && pc < 0xfc0000)
	{
		VDI_Complete();

		/* Set PC back to where originated from to continue instruction decoding */
		m68k_setpc(VDI_OldPC);
		VDI_OldPC = 0;
	}
	else
	{
		/* illegal instruction */
		op_illg(opcode);
	}

	get_word_prefetch (0);
	regs.ir = regs.irc;
	get_word_prefetch(2);

	return 4 * CYCLE_UNIT / 2;
}
Exemplo n.º 3
0
/**
 * Handle word read access from IO memory.
 */
uae_u32 IoMem_wget(uaecptr addr)
{
	Uint32 idx;
	Uint16 val;

	/* Check if access is made by a new instruction or by the same instruction doing multiple word accesses */
	if ( IoAccessInstrPrevClock == CyclesGlobalClockCounter )
		IoAccessInstrCount++;			/* Same instruction, increase access count */
	else
	{
		IoAccessInstrPrevClock = CyclesGlobalClockCounter;
		if ( ( table68k[ M68000_CurrentOpcode ].size == 1 )
		  && ( OpcodeFamily != i_MVMEL ) && ( OpcodeFamily != i_MVMLE ) )
			IoAccessInstrCount = 0;		/* Instruction size is word and not a movem : no multiple accesses */
		else
			IoAccessInstrCount = 1;		/* 1st access of a long or movem.w */
	}

	addr &= 0x00ffffff;                           /* Use a 24 bit address */

	if (addr < 0xff8000 || !regs.s)
	{
		/* invalid memory addressing --> bus error */
		M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
		return -1;
	}
	if (addr > 0xfffffe)
	{
		fprintf(stderr, "Illegal IO memory access: IoMem_wget($%x)\n", addr);
		return -1;
	}

	IoAccessBaseAddress = addr;                   /* Store for exception frame */
	nIoMemAccessSize = SIZE_WORD;
	nBusErrorAccesses = 0;
	idx = addr - 0xff8000;

	IoAccessCurrentAddress = addr;
	pInterceptReadTable[idx]();                   /* Call 1st handler */

	if (pInterceptReadTable[idx+1] != pInterceptReadTable[idx])
	{
		IoAccessCurrentAddress = addr + 1;
		pInterceptReadTable[idx+1]();             /* Call 2nd handler */
	}

	/* Check if we completely read from a bus-error region */
	if (nBusErrorAccesses == 2)
	{
		M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
		return -1;
	}

	val = IoMem_ReadWord(addr);

	LOG_TRACE(TRACE_IOMEM_RD, "IO read.w $%06x = $%04x pc=%x\n", addr, val, M68000_GetPC());

	return val;
}
Exemplo n.º 4
0
/**
 * Default information on entering the debugger
 */
static void DebugInfo_Default(Uint32 dummy)
{
	int hbl, fcycles, lcycles;
	Video_GetPosition(&fcycles, &hbl, &lcycles);
	fprintf(stderr, "\nCPU=$%x, VBL=%d, FrameCycles=%d, HBL=%d, LineCycles=%d, DSP=",
		M68000_GetPC(), 0, fcycles, hbl, lcycles);
		fprintf(stderr, "N/A\n");
}
Exemplo n.º 5
0
/**
 * Dissassemble - arg = starting address, or PC.
 */
int DebugCpu_DisAsm(int nArgc, char *psArgs[])
{
	Uint32 disasm_upper = 0;
	int insts, max_insts;
	uaecptr nextpc;
	FILE* mydebugOutput=debugOutput;

	if (nArgc > 1)
	{
		switch (Eval_Range(psArgs[1], &disasm_addr, &disasm_upper, false))
		{
		case -1:
			/* invalid value(s) */
			return DEBUGGER_CMDDONE;
		case 0:
			/* single value */
			break;
		case 1:
			/* range */
			break;
		}
		if (nArgc > 2) {
			mydebugOutput=fopen(psArgs[2],"w");
			if (mydebugOutput==NULL)
			{
				fprintf(debugOutput,"Cannot open %s abort\n",psArgs[2]);
				return DEBUGGER_CMDDONE;
			}
		}
	}
	else
	{
		/* continue */
		if(!disasm_addr)
			disasm_addr = M68000_GetPC();
	}

	/* limit is topmost address or instruction count */
	if (disasm_upper) {
		max_insts = INT_MAX;
	} else {
//		max_insts = ConfigureParams.Debugger.nDisasmLines;
		max_insts    = 5;
        disasm_upper = 0xFFFFFFFF;
	}

	/* output a range */
	for (insts = 0; insts < max_insts && disasm_addr < disasm_upper; insts++)
	{
        DebugCpu_ShowAddressInfo(disasm_addr);
        Disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, 1, DISASM_ENGINE_EXT);
		disasm_addr = nextpc;
	}
	fflush(mydebugOutput);
	if (mydebugOutput!=debugOutput) {fclose(mydebugOutput);}

	return DEBUGGER_CMDCONT;
}
Exemplo n.º 6
0
/**
 * Handle long-word write access to IO memory.
 */
void IoMem_lput(uaecptr addr, uae_u32 val)
{
	Uint32 idx;
	int n;

	/* Check if access is made by a new instruction or by the same instruction doing multiple long accesses */
	if ( IoAccessInstrPrevClock == CyclesGlobalClockCounter )
		IoAccessInstrCount++;			/* Same instruction, increase access count */
	else
	{
		IoAccessInstrPrevClock = CyclesGlobalClockCounter;
		if ( ( OpcodeFamily != i_MVMEL ) && ( OpcodeFamily != i_MVMLE ) )
			IoAccessInstrCount = 0;		/* Instruction is not a movem : no multiple accesses */
		else
			IoAccessInstrCount = 1;		/* 1st access of a movem.l */
	}

	addr &= 0x00ffffff;                           /* Use a 24 bit address */

	LOG_TRACE(TRACE_IOMEM_WR, "IO write.l $%06x = $%08x pc=%x\n", addr, val, M68000_GetPC());

	if (addr < 0xff8000 || !regs.s)
	{
		/* invalid memory addressing --> bus error */
		M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
		return;
	}
	if (addr > 0xfffffc)
	{
		fprintf(stderr, "Illegal IO memory access: IoMem_lput($%x)\n", addr);
		return;
	}

	IoAccessBaseAddress = addr;                   /* Store for exception frame, just in case */
	nIoMemAccessSize = SIZE_LONG;
	nBusErrorAccesses = 0;

	IoMem_WriteLong(addr, val);
	idx = addr - 0xff8000;

	IoAccessCurrentAddress = addr;
	pInterceptWriteTable[idx]();                  /* Call first handler */

	for (n = 1; n < nIoMemAccessSize; n++)
	{
		if (pInterceptWriteTable[idx+n] != pInterceptWriteTable[idx+n-1])
		{
			IoAccessCurrentAddress = addr + n;
			pInterceptWriteTable[idx+n]();   /* Call n-th handler */
		}
	}

	/* Check if we wrote to a bus-error region */
	if (nBusErrorAccesses == 4)
	{
		M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
	}
}
Exemplo n.º 7
0
/**
 * Initialize CPU profiling when necessary.  Return true if profiling.
 */
bool Profile_CpuStart(void)
{
	int size;

	Profile_FreeCallinfo(&(cpu_callinfo));
	if (cpu_profile.sort_arr) {
		/* remove previous results */
		free(cpu_profile.sort_arr);
		free(cpu_profile.data);
		cpu_profile.sort_arr = NULL;
		cpu_profile.data = NULL;
		printf("Freed previous CPU profile buffers.\n");
	}
	if (!cpu_profile.enabled) {
		return false;
	}
	/* zero everything */
	memset(&cpu_profile, 0, sizeof(cpu_profile));

	/* Shouldn't change within same debug session */
	size = (STRamEnd + 0x20000 + TosSize) / 2;

	/* Add one entry for catching invalid PC values */
	cpu_profile.data = calloc(size + 1, sizeof(*cpu_profile.data));
	if (!cpu_profile.data) {
		perror("ERROR, new CPU profile buffer alloc failed");
		return false;
	}
	printf("Allocated CPU profile buffer (%d MB).\n",
	       (int)sizeof(*cpu_profile.data)*size/(1024*1024));
	cpu_profile.size = size;

	Profile_AllocCallinfo(&(cpu_callinfo), Symbols_CpuCount(), "CPU");

	/* special hack for EmuTOS */
	etos_switcher = PC_UNDEFINED;
	if (cpu_callinfo.sites && bIsEmuTOS &&
	    (!Symbols_GetCpuAddress(SYMTYPE_TEXT, "_switchto", &etos_switcher) || etos_switcher < TosAddress)) {
		etos_switcher = PC_UNDEFINED;
	}

	cpu_profile.prev_cycles = Cycles_GetCounter(CYCLES_COUNTER_CPU);
	cpu_profile.prev_family = OpcodeFamily;
	cpu_profile.prev_pc = M68000_GetPC() & 0xffffff;

	cpu_profile.loop_start = PC_UNDEFINED;
	cpu_profile.loop_end = PC_UNDEFINED;
	cpu_profile.loop_count = 0;
	Profile_LoopReset();

	cpu_profile.disasm_addr = 0;
	cpu_profile.processed = false;
	cpu_profile.enabled = true;
	return cpu_profile.enabled;
}
Exemplo n.º 8
0
/**
 * Dissassemble - arg = starting address, or PC.
 */
int DebugCpu_DisAsm(int nArgc, char *psArgs[])
{
	Uint32 disasm_upper = 0;
	int insts, max_insts;
	uaecptr nextpc;

	if (nArgc > 1)
	{
		switch (Eval_Range(psArgs[1], &disasm_addr, &disasm_upper, false))
		{
		case -1:
			/* invalid value(s) */
			return DEBUGGER_CMDDONE;
		case 0:
			/* single value */
			break;
		case 1:
			/* range */
			break;
		}
	}
	else
	{
		/* continue */
		if(!disasm_addr)
			disasm_addr = M68000_GetPC();
	}

	/* limit is topmost address or instruction count */
	if (disasm_upper)
	{
		max_insts = INT_MAX;
	}
	else
	{
		disasm_upper = 0xFFFFFFFF;
		max_insts = ConfigureParams.Debugger.nDisasmLines;
	}

	/* output a range */
	for (insts = 0; insts < max_insts && disasm_addr < disasm_upper; insts++)
	{
		DebugCpu_ShowAddressInfo(disasm_addr);
		Disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, 1);
		disasm_addr = nextpc;
	}
	fflush(debugOutput);

	return DEBUGGER_CMDCONT;
}
Exemplo n.º 9
0
/**
 * XBIOS Scrdmp
 * Call 20
 */
static bool XBios_Scrdmp(Uint32 Params)
{
	LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x14 Scrdmp() at PC 0x%X\n" , M68000_GetPC());

	if (!bXBiosCommands)
		return false;

	ScreenSnapShot_SaveScreen();

	/* Correct return code? */
	Regs[REG_D0] = 0;

	return true;
}
Exemplo n.º 10
0
Arquivo: psg.c Projeto: denizt/hatari
/**
 * Read byte from 0xff8801/02/03. Return 0xff.
 */
void PSG_ff880x_ReadByte(void)
{
	M68000_WaitState(1);				/* [NP] FIXME not 100% accurate, but gives good results */

	IoMem[IoAccessCurrentAddress] = 0xff;

	if (LOG_TRACE_LEVEL(TRACE_PSG_READ))
	{
		int FrameCycles, HblCounterVideo, LineCycles;
		Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
		LOG_TRACE_PRINT("ym read void %x=0x%x video_cyc=%d %d@%d pc=%x instr_cycle %d\n",
		                IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress],
		                FrameCycles, LineCycles, HblCounterVideo, M68000_GetPC(), CurrentInstrCycles);
	}
}
Exemplo n.º 11
0
/**
 * Command: Step CPU, but proceed through subroutines
 * Does this by temporary conditional breakpoint
 */
static int DebugCpu_Next(int nArgc, char *psArgv[])
{
	char command[40];
	if (nArgc > 1)
	{
		int optype;
		if(strcmp(psArgv[1], "branch") == 0)
			optype = CALL_BRANCH;
		else if(strcmp(psArgv[1], "exception") == 0)
			optype = CALL_EXCEPTION;
		else if(strcmp(psArgv[1], "exreturn") == 0)
			optype = CALL_EXCRETURN;
		else if(strcmp(psArgv[1], "subcall") == 0)
			optype = CALL_SUBROUTINE;
		else if (strcmp(psArgv[1], "subreturn") == 0)
			optype = CALL_SUBRETURN;
		else if (strcmp(psArgv[1], "return") == 0)
			optype = CALL_SUBRETURN | CALL_EXCRETURN;
		else
		{
			fprintf(stderr, "Unrecognized opcode type given!\n");
			return DEBUGGER_CMDDONE;
		}
		sprintf(command, "CpuOpcodeType & $%x > 0 :once :quiet\n", optype);
	}
	else
	{
		Uint32 optype, nextpc;

		optype = DebugCpu_OpcodeType();
		/* can this instruction be stepped normally? */
		if (optype != CALL_SUBROUTINE && optype != CALL_EXCEPTION)
		{
			nCpuSteps = 1;
			return DEBUGGER_END;
		}

		nextpc = Disasm_GetNextPC(M68000_GetPC());
		sprintf(command, "pc=$%x :once :quiet\n", nextpc);
	}
	/* use breakpoint, not steps */
	if (BreakCond_Command(command, false))
	{
		nCpuSteps = 0;
		return DEBUGGER_END;
	}
	return DEBUGGER_CMDDONE;
}
Exemplo n.º 12
0
/**
 * XBIOS Devconnect
 * Call 139
 */
static bool XBios_Devconnect(Uint32 Params)
{
	Uint16 src,dst,clk,prescale,protocol;

	/* Read details from stack */
	src = STMemory_ReadWord(Params);
	dst = STMemory_ReadWord(Params+SIZE_WORD);
	clk = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD);
	prescale = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_WORD);
	protocol = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_WORD+SIZE_WORD);

	LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x8B Devconnect(%hd, 0x%hx, %hd, %hd, %hd) at PC 0x%X\n",
		  src, dst, clk, prescale, protocol ,
		  M68000_GetPC() );
	return false;
}
Exemplo n.º 13
0
Arquivo: psg.c Projeto: denizt/hatari
/**
 * Write byte to 0xff8802. Set content of YM's data register.
 */
void PSG_ff8802_WriteByte(void)
{
//	M68000_WaitState(4);
	M68000_WaitState(1);				/* [NP] FIXME not 100% accurate, but gives good results */

	if (LOG_TRACE_LEVEL(TRACE_PSG_WRITE))
	{
		int FrameCycles, HblCounterVideo, LineCycles;
		Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
		LOG_TRACE_PRINT("ym write %x=0x%x video_cyc=%d %d@%d pc=%x instr_cycle %d\n",
				IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress],
				FrameCycles, LineCycles, HblCounterVideo, M68000_GetPC(), CurrentInstrCycles);
	}

	PSG_Set_DataRegister ( IoMem[IoAccessCurrentAddress] );
}
Exemplo n.º 14
0
/**
 * Handle byte read access from IO memory.
 */
uae_u32 IoMem_bget(uaecptr addr)
{
	Uint8 val;

	/* Check if access is made by a new instruction or by the same instruction doing multiple byte accesses */
	if ( IoAccessInstrPrevClock == CyclesGlobalClockCounter )
		IoAccessInstrCount++;			/* Same instruction, increase access count */
	else
	{
		IoAccessInstrPrevClock = CyclesGlobalClockCounter;
		if ( table68k[ M68000_CurrentOpcode ].size == 0 )
			IoAccessInstrCount = 0;		/* Instruction size is byte : no multiple accesses */
		else
			IoAccessInstrCount = 1;		/* 1st access */
	}

	addr &= 0x00ffffff;                           /* Use a 24 bit address */

	if (addr < 0xff8000 || !regs.s)
	{
		/* invalid memory addressing --> bus error */
		M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
		return -1;
	}

	IoAccessBaseAddress = addr;                   /* Store access location */
	nIoMemAccessSize = SIZE_BYTE;
	nBusErrorAccesses = 0;

	IoAccessCurrentAddress = addr;
	pInterceptReadTable[addr-0xff8000]();         /* Call handler */

	/* Check if we read from a bus-error region */
	if (nBusErrorAccesses == 1)
	{
		M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
		return -1;
	}

	val = IoMem[addr];

	LOG_TRACE(TRACE_IOMEM_RD, "IO read.b $%06x = $%02x pc=%x\n", addr, val, M68000_GetPC());

	return val;
}
Exemplo n.º 15
0
/**
 * XBIOS RsConf
 * Call 15
 */
static bool XBios_Rsconf(Uint32 Params)
{
	Sint16 Baud,Ctrl,Ucr;
#if ENABLE_TRACING
	Sint16 Rsr,Tsr,Scr;
#endif

	Baud = STMemory_ReadWord(Params);
	Ctrl = STMemory_ReadWord(Params+SIZE_WORD);
	Ucr = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD);
#if ENABLE_TRACING
	Rsr = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_WORD);
	Tsr = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_WORD+SIZE_WORD);
	Scr = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_WORD+SIZE_WORD+SIZE_WORD);
	LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x0F Rsconf(%d, %d, %d, %d, %d, %d) at PC 0x%X\n",
		   Baud, Ctrl, Ucr, Rsr, Tsr, Scr,
		   M68000_GetPC());
#endif
	if (!bXBiosCommands)
		return false;
	
	if (!ConfigureParams.RS232.bEnableRS232)
		return false;

	/* Set baud rate and other configuration, if RS232 emaulation is enabled */
	if (Baud >= 0 && Baud < ARRAYSIZE(BaudRates))
	{
		/* Convert ST baud rate index to value */
		int BaudRate = BaudRates[Baud];
		/* And set new baud rate: */
		RS232_SetBaudRate(BaudRate);
	}

	if (Ucr != -1)
	{
		RS232_HandleUCR(Ucr);
	}

	if (Ctrl != -1)
	{
		RS232_SetFlowControl(Ctrl);
	}

	return true;
}
Exemplo n.º 16
0
/**
 * XBIOS Floppy Write
 * Call 9
 */
static bool XBios_Flopwr(Uint32 Params)
{
	Uint32 pBuffer;
	Uint16 Dev,Sector,Side,Track,Count;

	/* Read details from stack */
	pBuffer = STMemory_ReadLong(Params);
	Dev = STMemory_ReadWord(Params+SIZE_LONG+SIZE_LONG); /* skip reserved long */
	Sector = STMemory_ReadWord(Params+SIZE_LONG+SIZE_LONG+SIZE_WORD);
	Track = STMemory_ReadWord(Params+SIZE_LONG+SIZE_LONG+SIZE_WORD+SIZE_WORD);
	Side = STMemory_ReadWord(Params+SIZE_LONG+SIZE_LONG+SIZE_WORD+SIZE_WORD+SIZE_WORD);
	Count = STMemory_ReadWord(Params+SIZE_LONG+SIZE_LONG+SIZE_WORD+SIZE_WORD+SIZE_WORD+SIZE_WORD);

	LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x09 Flopwr(0x%x, %d, %d, %d, %d, %d) at PC 0x%X for: %s\n",
		  pBuffer, Dev, Sector, Track, Side, Count,
		  M68000_GetPC(), EmulationDrives[Dev].sFileName);
	return false;
}
Exemplo n.º 17
0
/**
 * Handle byte write access to IO memory.
 */
void IoMem_bput(uaecptr addr, uae_u32 val)
{
	/* Check if access is made by a new instruction or by the same instruction doing multiple byte accesses */
	if ( IoAccessInstrPrevClock == CyclesGlobalClockCounter )
		IoAccessInstrCount++;			/* Same instruction, increase access count */
	else
	{
		IoAccessInstrPrevClock = CyclesGlobalClockCounter;
		if ( table68k[ M68000_CurrentOpcode ].size == 0 )
			IoAccessInstrCount = 0;		/* Instruction size is byte : no multiple accesses */
		else
			IoAccessInstrCount = 1;		/* 1st access */
	}

	addr &= 0x00ffffff;                           /* Use a 24 bit address */

	LOG_TRACE(TRACE_IOMEM_WR, "IO write.b $%06x = $%02x pc=%x\n", addr, val&0xff, M68000_GetPC());

	if (addr < 0xff8000 || !regs.s)
	{
		/* invalid memory addressing --> bus error */
		M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
		return;
	}

	IoAccessBaseAddress = addr;                   /* Store for exception frame, just in case */
	nIoMemAccessSize = SIZE_BYTE;
	nBusErrorAccesses = 0;

	IoMem[addr] = val;

	IoAccessCurrentAddress = addr;
	pInterceptWriteTable[addr-0xff8000]();        /* Call handler */

	/* Check if we wrote to a bus-error region */
	if (nBusErrorAccesses == 1)
	{
		M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
	}
}
Exemplo n.º 18
0
Arquivo: psg.c Projeto: denizt/hatari
/**
 * Write byte to the YM address register (usually 0xff8800). This is used
 * as a selector for when we read/write the YM data register (0xff8802).
 */
void PSG_Set_SelectRegister(Uint8 val)
{
	/* Store register used to read/write in $ff8802. This register */
	/* is 8 bits on the YM2149, this means it should not be masked */
	/* with 0xf. Instead, we keep the 8 bits, but we must ignore */
	/* read/write to ff8802 when PSGRegisterSelect >= 16 */
	PSGRegisterSelect = val;

	/* When address register is changed, a read from $ff8800 should */
	/* return the masked value of the register. We set the value here */
	/* to be returned in case PSG_Get_DataRegister is called */
	PSGRegisterReadData = PSGRegisters[PSGRegisterSelect];

	if (LOG_TRACE_LEVEL(TRACE_PSG_WRITE))
	{
		int FrameCycles, HblCounterVideo, LineCycles;
		Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
		LOG_TRACE_PRINT("ym write reg=0x%x video_cyc=%d %d@%d pc=%x instr_cycle %d\n",
		                PSGRegisterSelect, FrameCycles, LineCycles, HblCounterVideo,
		                M68000_GetPC(), CurrentInstrCycles);
	}
}
Exemplo n.º 19
0
/**
 * This function is called after each CPU instruction when debugging is enabled.
 */
void DebugCpu_Check(void)
{
    if (bCpuProfiling)
    {
        Profile_CpuUpdate();
    }
	if (LOG_TRACE_LEVEL(TRACE_CPU_DISASM))
	{
		DebugCpu_ShowAddressInfo(M68000_GetPC());
	}
	if (nCpuActiveCBs)
	{
		if (BreakCond_MatchCpu())
			DebugUI();
	}
	if (nCpuSteps)
	{
		nCpuSteps -= 1;
		if (nCpuSteps == 0)
			DebugUI();
	}
}
Exemplo n.º 20
0
/**
 * This function is called after each CPU instruction when debugging is enabled.
 */
void DebugCpu_Check(void)
{
	nCpuInstructions++;
	if (bCpuProfiling)
	{
		Profile_CpuUpdate();
	}
	if (LOG_TRACE_LEVEL((TRACE_CPU_DISASM|TRACE_CPU_SYMBOLS)))
	{
		DebugCpu_ShowAddressInfo(M68000_GetPC());
	}
	if (nCpuActiveCBs)
	{
		if (BreakCond_MatchCpu())
		{
			DebugUI(REASON_CPU_BREAKPOINT);
			/* make sure we don't decrease step count
			 * below, before even even getting out of here
			 */
			if (nCpuSteps)
				nCpuSteps++;
		}
	}
	if (nCpuSteps)
	{
		nCpuSteps--;
		if (nCpuSteps == 0)
			DebugUI(REASON_CPU_STEPS);
	}
	if (History_TrackCpu())
	{
		History_AddCpu();
	}
	if (ConOutDevice != CONOUT_DEVICE_NONE)
	{
		Console_Check();
	}
}
Exemplo n.º 21
0
Arquivo: psg.c Projeto: denizt/hatari
/**
 * Reset variables used in PSG
 */
void PSG_Reset(void)
{
        int     i;

	if (LOG_TRACE_LEVEL(TRACE_PSG_WRITE))
	{
		int FrameCycles, HblCounterVideo, LineCycles;
		Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
		LOG_TRACE_PRINT("ym reset video_cyc=%d %d@%d pc=%x instr_cycle %d\n",
		                FrameCycles, LineCycles, HblCounterVideo, M68000_GetPC(), CurrentInstrCycles);
	}

	PSGRegisterSelect = 0;
	PSGRegisterReadData = 0;
	memset(PSGRegisters, 0, sizeof(PSGRegisters));
	PSGRegisters[PSG_REG_IO_PORTA] = 0xff;			/* no drive selected + side 0 after a reset */

	/* Update sound's emulation registers */
        for ( i=0 ; i < NUM_PSG_SOUND_REGISTERS; i++ )
		Sound_WriteReg ( i , 0 );

	LastStrobe=0;
}
Exemplo n.º 22
0
/* helper to get instruction type */
Uint32 DebugCpu_OpcodeType(void)
{
	/* cannot use OpcodeFamily like profiler does,
	 * as that's for previous instructions
	 */
	Uint16 opcode = STMemory_ReadWord(M68000_GetPC());

	if (opcode == 0x4e74 ||			/* RTD */
	    opcode == 0x4e75 ||			/* RTS */
	    opcode == 0x4e77)			/* RTR */
		return CALL_SUBRETURN;

	if (opcode == 0x4e73)			/* RTE */
		return CALL_EXCRETURN;

	/* NOTE: BSR needs to be matched before BRA/BCC! */
	if ((opcode & 0xff00) == 0x6100 ||	/* BSR */
	    (opcode & 0xffc0) == 0x4e80)	/* JSR */
		return CALL_SUBROUTINE;

	/* TODO: ftrapcc, chk2? */
	if (opcode == 0x4e72 ||			/* STOP */
	    opcode == 0x4afc ||			/* ILLEGAL */
	    opcode == 0x4e76 ||			/* TRAPV */
	    (opcode & 0xfff0) == 0x4e40 ||	/* TRAP */
	    (opcode & 0xf1c0) == 0x4180 ||	/* CHK */
	    (opcode & 0xfff8) == 0x4848)	/* BKPT */
		return CALL_EXCEPTION;

	/* TODO: fbcc, fdbcc */
	if ((opcode & 0xf000) == 0x6000 ||	/* BRA / BCC */
	    (opcode & 0xffc0) == 0x4ec0 ||	/* JMP */
	    (opcode & 0xf0f8) == 0x50c8)	/* DBCC */
		return CALL_BRANCH;

	return CALL_UNKNOWN;
}
Exemplo n.º 23
0
Arquivo: psg.c Projeto: denizt/hatari
/**
 * Write byte to YM's register (0xff8802), store according to PSG select register (0xff8800)
 */
void PSG_Set_DataRegister(Uint8 val)
{
	if (LOG_TRACE_LEVEL(TRACE_PSG_WRITE))
	{
		int FrameCycles, HblCounterVideo, LineCycles;
		Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
		LOG_TRACE_PRINT("ym write data reg=0x%x val=0x%x video_cyc=%d %d@%d pc=%x instr_cycle %d\n",
		                PSGRegisterSelect, val, FrameCycles, LineCycles,
		                HblCounterVideo, M68000_GetPC(), CurrentInstrCycles);
	}

	/* Is a valid PSG register currently selected ? */
	if ( PSGRegisterSelect >= MAX_PSG_REGISTERS )
		return;					/* not valid, ignore write and do nothing */

	/* Create samples up until this point with current values */
	Sound_Update(false);

	/* When a read is made from $ff8800 without changing PSGRegisterSelect, we should return */
	/* the non masked value. */
	PSGRegisterReadData = val;			/* store non masked value for PSG_Get_DataRegister */

	/* Copy value to PSGRegisters[] */
	PSGRegisters[PSGRegisterSelect] = val;

	/* Clear unused bits for some regs */
	if ( ( PSGRegisterSelect == PSG_REG_CHANNEL_A_COARSE ) || ( PSGRegisterSelect == PSG_REG_CHANNEL_B_COARSE )
		|| ( PSGRegisterSelect == PSG_REG_CHANNEL_C_COARSE ) || ( PSGRegisterSelect == PSG_REG_ENV_SHAPE ) )
	  PSGRegisters[PSGRegisterSelect] &= 0x0f;	/* only keep bits 0 - 3 */

	else if ( ( PSGRegisterSelect == PSG_REG_CHANNEL_A_AMP ) || ( PSGRegisterSelect == PSG_REG_CHANNEL_B_AMP )
		|| ( PSGRegisterSelect == PSG_REG_CHANNEL_C_AMP ) || ( PSGRegisterSelect == PSG_REG_NOISE_GENERATOR ) )
	  PSGRegisters[PSGRegisterSelect] &= 0x1f;	/* only keep bits 0 - 4 */


	if ( PSGRegisterSelect < NUM_PSG_SOUND_REGISTERS )
	{
		/* Copy sound related registers 0..13 to the sound module's internal buffer */
		Sound_WriteReg ( PSGRegisterSelect , PSGRegisters[PSGRegisterSelect] );
	}

	else if ( PSGRegisterSelect == PSG_REG_IO_PORTA )
	{
	/*
	 * FIXME: This is only a prelimary dirty hack!
	 * Port B (Printer port) - writing here needs to be dispatched to the printer
	 * STROBE (Port A bit5) does a short LOW and back to HIGH when the char is valid
	 * To print you need to write the character byte to IOB and you need to toggle STROBE
	 * (like EmuTOS does).
	 */
		/* Printer dispatching only when printing is activated */
		if (ConfigureParams.Printer.bEnablePrinting)
		{
			/* Bit 5 - Centronics strobe? If STROBE is low and the LastStrobe was high,
					then print/transfer to the emulated Centronics port.
			 */
			if (LastStrobe && ( (PSGRegisters[PSG_REG_IO_PORTA]&(1<<5)) == 0 ))
			{
				/* Seems like we want to print something... */
				Printer_TransferByteTo(PSGRegisters[PSG_REG_IO_PORTB]);
				/* Initiate a possible GPIP0 Printer BUSY interrupt */
				MFP_InputOnChannel ( MFP_INT_GPIP0 , 0 );
				/* Initiate a possible GPIP1 Falcon ACK interrupt */
				if (ConfigureParams.System.nMachineType == MACHINE_FALCON)
					MFP_InputOnChannel ( MFP_INT_GPIP1 , 0 );
			}
		}
		LastStrobe = PSGRegisters[PSG_REG_IO_PORTA]&(1<<5);

		/* Bit 0-2 : side and drive select */
		if ( (PSGRegisters[PSG_REG_IO_PORTA]&(1<<1)) == 0 )
		{
			/* floppy drive A is ON */
			Statusbar_SetFloppyLed(DRIVE_LED_A, LED_STATE_ON);
		}
		else
		{
			Statusbar_SetFloppyLed(DRIVE_LED_A, LED_STATE_OFF);
		}
		if ( (PSGRegisters[PSG_REG_IO_PORTA]&(1<<2)) == 0 )
		{
			/* floppy drive B is ON */
			Statusbar_SetFloppyLed(DRIVE_LED_B, LED_STATE_ON);
		}
		else
		{
			Statusbar_SetFloppyLed(DRIVE_LED_B, LED_STATE_OFF);
		}

		/* Bit 3 - Centronics as input */
		if(PSGRegisters[PSG_REG_IO_PORTA]&(1<<3))
		{
			/* FIXME: might be needed if we want to emulate sound sampling hardware */
		}
		
		/* handle Falcon specific bits in PORTA of the PSG */
		if (ConfigureParams.System.nMachineType == MACHINE_FALCON)
		{
			/* Bit 4 - DSP reset? */
			if(PSGRegisters[PSG_REG_IO_PORTA]&(1<<4))
			{
				Log_Printf(LOG_DEBUG, "Calling DSP_Reset?\n");
#if ENABLE_DSP_EMU
				if (ConfigureParams.System.nDSPType == DSP_TYPE_EMU) {
					DSP_Reset();
				}
#endif
			}
			/* Bit 6 - Internal Speaker control */
			if(PSGRegisters[PSG_REG_IO_PORTA]&(1<<6))
			{
				/*Log_Printf(LOG_DEBUG, "Falcon: Internal Speaker state\n");*/
				/* FIXME: add code to handle? (if we want to emulate the speaker at all? */
			}
			/* Bit 7 - Reset IDE? */
			if(PSGRegisters[PSG_REG_IO_PORTA]&(1<<7))
			{
				Log_Printf(LOG_DEBUG, "Falcon: Reset IDE subsystem\n");
				/* FIXME: add code to handle IDE reset */
			}
		}
	
	}
}
Exemplo n.º 24
0
/**
 * Update CPU cycle and count statistics for PC address.
 *
 * This gets called after instruction has executed and PC
 * has advanced to next instruction.
 */
void Profile_CpuUpdate(void)
{
	counters_t *counters = &(cpu_profile.all);
	Uint32 pc, prev_pc, idx, cycles, misses;
	cpu_profile_item_t *prev;

	prev_pc = cpu_profile.prev_pc;
	/* PC may have extra bits, they need to be masked away as
	 * emulation itself does that too when PC value is used
	 */
	cpu_profile.prev_pc = pc = M68000_GetPC() & 0xffffff;

	if (unlikely(profile_loop.fp)) {
		if (pc < prev_pc) {
			if (pc == cpu_profile.loop_start && prev_pc == cpu_profile.loop_end) {
				cpu_profile.loop_count++;
			} else {
				cpu_profile.loop_start = pc;
				cpu_profile.loop_end = prev_pc;
				cpu_profile.loop_count = 1;
			}
		} else {
			if (pc > cpu_profile.loop_end) {
				log_last_loop();
				cpu_profile.loop_end = 0xffffffff;			
				cpu_profile.loop_count = 0;
			}
		}
	}

	idx = address2index(prev_pc);
	assert(idx <= cpu_profile.size);
	prev = cpu_profile.data + idx;

	if (likely(prev->count < MAX_CPU_PROFILE_VALUE)) {
		prev->count++;
	}

#if USE_CYCLES_COUNTER
	/* Confusingly, with DSP enabled, cycle counter is for this instruction,
	 * without DSP enabled, it's a monotonically increasing counter.
	 */
	if (bDspEnabled) {
		cycles = Cycles_GetCounter(CYCLES_COUNTER_CPU);
	} else {
		Uint32 newcycles = Cycles_GetCounter(CYCLES_COUNTER_CPU);
		cycles = newcycles - cpu_profile.prev_cycles;
		cpu_profile.prev_cycles = newcycles;
	}
#else
	cycles = CurrentInstrCycles + nWaitStateCycles;
#endif
	/* cycles are based on 8Mhz clock, change them to correct one */
	cycles <<= nCpuFreqShift;

	if (likely(prev->cycles < MAX_CPU_PROFILE_VALUE - cycles)) {
		prev->cycles += cycles;
	} else {
		prev->cycles = MAX_CPU_PROFILE_VALUE;
	}

#if ENABLE_WINUAE_CPU
	misses = CpuInstruction.iCacheMisses;
	assert(misses < MAX_MISS);
	cpu_profile.miss_counts[misses]++;
	if (likely(prev->misses < MAX_CPU_PROFILE_VALUE - misses)) {
		prev->misses += misses;
	} else {
		prev->misses = MAX_CPU_PROFILE_VALUE;
	}
#else
	misses = 0;
#endif
	if (cpu_callinfo.sites) {
		collect_calls(prev_pc, counters);
	}
	/* counters are increased after caller info is processed,
	 * otherwise cost for the instruction calling the callee
	 * doesn't get accounted to caller (but callee).
	 */
	counters->misses += misses;
	counters->cycles += cycles;
	counters->count++;

#if DEBUG
	if (unlikely(OpcodeFamily == 0)) {
		Uint32 nextpc;
		fputs("WARNING: instruction opcode family is zero (=i_ILLG) for instruction:\n", stderr);
		Disasm(stderr, prev_pc, &nextpc, 1);
	}
	/* catch too large (and negative) cycles for other than STOP instruction */
	if (unlikely(cycles > 512 && OpcodeFamily != i_STOP)) {
		Uint32 nextpc;
		fprintf(stderr, "WARNING: cycles %d > 512:\n", cycles);
		Disasm(stderr, prev_pc, &nextpc, 1);
	}
	if (unlikely(cycles == 0)) {
		Uint32 nextpc;
		fputs("WARNING: Zero cycles for an opcode:\n", stderr);
		Disasm(stderr, prev_pc, &nextpc, 1);
	}
#endif
}
Exemplo n.º 25
0
/**
 * XBIOS remote control interface for Hatari
 * Call 255
 */
static bool XBios_HatariControl(Uint32 Params)
{
	const char *pText;
	pText = (const char *)STRAM_ADDR(STMemory_ReadLong(Params));
	LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02X HatariControl(%s) at PC 0x%X\n", HATARI_CONTROL_OPCODE, pText, M68000_GetPC());

	if (!bXBiosCommands)
		return false;

	Control_ProcessBuffer(pText);
	Regs[REG_D0] = 0;
	return true;
}
Exemplo n.º 26
0
/**
 * Check if we need to re-direct XBios call to our own routines
 */
bool XBios(void)
{
	Uint32 Params;
	Uint16 XBiosCall;

	/* Find call */
	Params = Regs[REG_A7];
	XBiosCall = STMemory_ReadWord(Params);
	Params += SIZE_WORD;

	switch (XBiosCall)
	{
		/* commands with special handling */
	case 8:
		return XBios_Floprd(Params);
	case 9:
		return XBios_Flopwr(Params);
	case 15:
		return XBios_Rsconf(Params);
	case 20:
		return XBios_Scrdmp(Params);
	case 139:
		return XBios_Devconnect(Params);
	case HATARI_CONTROL_OPCODE:
		return XBios_HatariControl(Params);

	case 2:		/* Physbase */
	case 3:		/* Logbase */
	case 4:		/* Getrez */
	case 17:	/* Random */
	case 23:	/* Gettime */
	case 24:	/* Bioskeys */
	case 34:	/* Kbdvbase */
	case 37:	/* Vsync */
	case 39:	/* Puntaes */
	case 81:	/* EgetShift */
	case 89:	/* VgetMonitor */
	case 103:	/* Dsp_GetWordSize */
	case 104:	/* Dsp_Lock */
	case 105:	/* Dsp_Unlock */
	case 113:	/* Dsp_RequestUniqueAbility */
	case 114:	/* Dsp_GetProgAbility */
	case 115:	/* Dsp_FlushSubroutines */
	case 121:	/* Dsp_Hf2 */
	case 122:	/* Dsp_Hf3 */
	case 125:	/* Dsp_Hstat */
	case 128:	/* Locksnd */
	case 129:	/* Unlocksnd */
		/* commands with no args */
		LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX %s() at PC 0x%X\n",
			  XBiosCall, XBios_Call2Name(XBiosCall),
			  M68000_GetPC());
		return false;
		
	case 1:		/* Ssbrk */
	case 14:	/* Iorec */
	case 26:	/* Jdisint */
	case 27:	/* Jenabint */
	case 29:	/* Offgibit */
	case 30:	/* Ongibit */
	case 33:	/* Setprt */
	case 44:	/* Bconmap */
	case 64:	/* Blitmode */
	case 80:	/* EsetShift */
	case 82:	/* EsetBank */
	case 86:	/* EsetGray */
	case 87:	/* EsetSmear */
	case 88:	/* VsetMode */
	case 90:	/* VsetSync */
	case 91:	/* VgetSize */
	case 102:	/* Dsp_RemoveInterrupts */
	case 112:	/* Dsp_TriggerHC */
	case 117:	/* Dsp_InqSubrAbility */
	case 118:	/* Dsp_RunSubroutine */
	case 119:	/* Dsp_Hf0 */
	case 120:	/* Dsp_Hf1 */
	case 132:	/* Setmode */
	case 134:	/* Setmontracks */
	case 136:	/* Buffoper */
	case 140:	/* Sndstatus */
		/* ones taking single word */
		LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX %s(0x%hX) at PC 0x%X\n",
			  XBiosCall, XBios_Call2Name(XBiosCall),
			  STMemory_ReadWord(Params),
			  M68000_GetPC());
		return false;

	case 6:		/* Setpalette */
	case 22:	/* Settime */
	case 32:	/* Dosound */
	case 36:	/* Ptrblt */
	case 38:	/* Supexec */
	case 48:	/* Metainit */
	case 141:	/* Buffptr */
		/* ones taking long or pointer */
		LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX %s(0x%X) at PC 0x%X\n",
			  XBiosCall, XBios_Call2Name(XBiosCall),
			  STMemory_ReadLong(Params),
			  M68000_GetPC());
		return false;

	case 7:		/* Setcolor */
	case 21:	/* Cursconf */
	case 28:	/* Giaccess */
	case 35:	/* Kbrate */
	case 41:	/* Floprate */
	case 83:	/* EsetColor */
	case 130:	/* Soundcmd */
	case 133:	/* Settracks */
	case 137:	/* Dsptristate */
	case 135:	/* Setinterrupt */
	case 138:	/* Gpio */
		/* ones taking two words */
		LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX %s(0x%hX, 0x%hX) at PC 0x%X\n",
			  XBiosCall, XBios_Call2Name(XBiosCall),
			  STMemory_ReadWord(Params),
			  STMemory_ReadWord(Params+SIZE_WORD),
			  M68000_GetPC());
		return false;

	case 12:	/* Midiws */
	case 13:	/* Mfpint */
	case 25:	/* Ikbdws */
		/* ones taking word length/index and pointer */
		LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX %s(%hd, 0x%X) at PC 0x %X\n",
			  XBiosCall, XBios_Call2Name(XBiosCall),
			  STMemory_ReadWord(Params),
			  STMemory_ReadLong(Params+SIZE_WORD),
			  M68000_GetPC());
		return false;

	case 11:	/* Dbmsg */
	case 84:	/* EsetPalette */
	case 85:	/* EgetPalette */
	case 93:	/* VsetRGB */
	case 94:	/* VgetRGB */
		/* ones taking word, word and long/pointer */
		LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX %s(0x%hX, 0x%hX, 0x%X) at PC 0x%X\n",
			  XBiosCall, XBios_Call2Name(XBiosCall),
			  STMemory_ReadWord(Params),
			  STMemory_ReadWord(Params+SIZE_WORD),
			  STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD),
			  M68000_GetPC());
		return false;

	case 106:	/* Dsp_Available */
	case 107:	/* Dsp_Reserve */
	case 111:	/* Dsp_LodToBinary */
	case 126:	/* Dsp_SetVectors */
		/* ones taking two longs/pointers */
		LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX %s(0x%X, 0x%X) at PC 0x%X\n",
			  XBiosCall, XBios_Call2Name(XBiosCall),
			  STMemory_ReadLong(Params),
			  STMemory_ReadLong(Params+SIZE_LONG),
			  M68000_GetPC());
		return false;

	case 5:		/* Setscreen */
		if (STMemory_ReadWord(Params+SIZE_LONG+SIZE_LONG) == 3) {
			/* actually VSetscreen with extra parameter */
			LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX VsetScreen(0x%X, 0x%X, 3, 0x%hX) at PC 0x%X\n",
				  XBiosCall, STMemory_ReadLong(Params),
				  STMemory_ReadLong(Params+SIZE_LONG),
				  STMemory_ReadWord(Params+SIZE_LONG+SIZE_LONG+SIZE_WORD),
				  M68000_GetPC());
			return false;			
		}
	case 109:	/* Dsp_ExecProg */
	case 110:	/* Dsp_ExecBoot */
	case 116:	/* Dsp_LoadSubroutine */
	case 150:	/* VsetMask */
		/* ones taking two longs/pointers and a word */
		LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX %s(0x%X, 0x%X, 0x%hX) at PC 0x%X\n",
			  XBiosCall, XBios_Call2Name(XBiosCall),
			  STMemory_ReadLong(Params),
			  STMemory_ReadLong(Params+SIZE_LONG),
			  STMemory_ReadWord(Params+SIZE_LONG+SIZE_LONG),
			  M68000_GetPC());
		return false;

	default:  /* rest of XBios calls */
		LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02hX (%s)\n",
			  XBiosCall, XBios_Call2Name(XBiosCall));
		return false;
	}
}
Exemplo n.º 27
0
/**
 * Parse unsigned register/symbol/number value and set it to "number"
 * and the number base used for parsing to "base".
 * Return how many characters were parsed or zero for error.
 */
static int getValue(const char *str, Uint32 *number, int *base, bool bForDsp)
{
	char name[64];
	const char *end;
	Uint32 mask, *addr;
	int len;

	for (end = str; *end == '_' || isalnum(*end); end++);
	
	len = end-str;
	if (len >= (int)sizeof(name)) {
		fprintf(stderr, "ERROR: symbol name at '%s' too long (%d chars)\n", str, len);
		return 0;
	}
	memcpy(name, str, len);
	name[len] = '\0';

	*base = 0; /* no base (e.g. variable) */

	/* internal Hatari variable? */
	if (BreakCond_GetHatariVariable(name, number)) {
		return len;
	}

	if (bForDsp) {
		int regsize = DSP_GetRegisterAddress(name, &addr, &mask);
		/* DSP register or symbol? */
		switch (regsize) {
		case 16:
			*number = (*((Uint16*)addr) & mask);
			return len;
		case 32:
			*number = (*addr & mask);
			return len;
		default:
			if (Symbols_GetDspAddress(SYMTYPE_ALL, name, number)) {
				return len;
			}
		}
	} else {
		/* a special case CPU register? */
		if (strcasecmp(name, "PC") == 0) {
			*number = M68000_GetPC();
			return len;
		}
		if (strcasecmp(name, "SR") == 0) {
			*number = M68000_GetSR();
			return len;
		}
		/* a normal CPU  register or symbol? */
		if (DebugCpu_GetRegisterAddress(name, &addr)) {
			*number = *addr;
			return len;
		}
		if (Symbols_GetCpuAddress(SYMTYPE_ALL, name, number)) {
			return len;
		}
	}

	/* none of above, assume it's a number */
	return getNumber(str, number, base);
}
Exemplo n.º 28
0
/**
 * Should be called when debugger is re-entered to reset
 * relevant CPU debugging variables.
 */
void DebugCpu_InitSession(void)
{
	disasm_addr = M68000_GetPC();
	Profile_CpuStop();
}