Exemple #1
0
static bool istrapwait(void)
{
	for (int i = 0; i < RTAREA_TRAP_DATA_NUM + RTAREA_TRAP_DATA_SEND_NUM; i++) {
		uae_u8 *data = rtarea_bank.baseaddr + RTAREA_TRAP_DATA + i * RTAREA_TRAP_DATA_SLOT_SIZE;
		uae_u8 *status = rtarea_bank.baseaddr + RTAREA_TRAP_STATUS + i * RTAREA_TRAP_STATUS_SIZE;
		if (get_long_host(data + RTAREA_TRAP_DATA_TASKWAIT) && status[3] && status[2] >= 0x80) {
			return true;
		}
	}
	return false;
}
Exemple #2
0
void trap_get_longs(TrapContext *ctx, uae_u32 *haddr, uaecptr addr, int cnt)
{
	if (cnt <= 0)
		return;
	if (trap_is_indirect_null(ctx)) {
		while (cnt > 0) {
			int max = cnt > RTAREA_TRAP_DATA_EXTRA_SIZE / sizeof(uae_u32) ? RTAREA_TRAP_DATA_EXTRA_SIZE / sizeof(uae_u32) : cnt;
			call_hardware_trap_back(ctx, TRAPCMD_GET_LONGS, addr, ctx->amiga_trap_data + RTAREA_TRAP_DATA_EXTRA, max, 0);
			for (int i = 0; i < max; i++) {
				*haddr++ = get_long_host(ctx->host_trap_data + RTAREA_TRAP_DATA_EXTRA + i * sizeof(uae_u32));
			}
			addr += max * sizeof(uae_u32);
			cnt -= max;
		}
	} else {
		uae_u32 *p = (uae_u32*)haddr;
		for (int i = 0; i < cnt; i++) {
			*p++ = get_long(addr);
			addr += 4;
		}
	}
}
Exemple #3
0
static void hardware_trap_ack(TrapContext *ctx)
{
	uae_u8 *data = ctx->host_trap_data;
	uae_u8 *status = ctx->host_trap_status;
	uaecptr addr = ctx->amiga_trap_status;

	// ack call_hardware_trap
	uaecptr task = get_long_host(data + RTAREA_TRAP_DATA_TASKWAIT);

#if NEW_TRAP_DEBUG
	write_log(_T("TRAP SLOT %d: ACK. TASK = %08x\n"), ctx->trap_slot, task);
#endif

	put_byte_host(status + 2, 0xff);
	if (task && trap_mode == 1) {
		atomic_or(&uae_int_requested, 0x4000);
		set_special_exter(SPCFLAG_UAEINT);
	}
	if (!trap_in_use[ctx->trap_slot])
		write_log(_T("TRAP SLOT %d ACK WIIHOUT ALLOCATION!\n"));
	trap_in_use[ctx->trap_slot] = false;
	xfree(ctx);
}
Exemple #4
0
static uae_u32 call_hardware_trap_back(TrapContext *ctx, uae_u16 cmd, uae_u32 p1, uae_u32 p2, uae_u32 p3, uae_u32 p4)
{
	int trap_slot = ((ctx->amiga_trap_data & 0xffff) - RTAREA_TRAP_DATA) / RTAREA_TRAP_DATA_SLOT_SIZE;
	uae_u8 *data = ctx->host_trap_data + RTAREA_TRAP_DATA_SECOND;
	uae_u8 *status = ctx->host_trap_status + RTAREA_TRAP_STATUS_SECOND;

#if NEW_TRAP_DEBUG
	write_log(_T("TRAP BACK SLOT %d: CMD=%d P=%08x %08x %08x %08x TASK=%08x\n"),
		trap_slot, cmd, p1, p2, p3, p4, get_long_host(ctx->host_trap_data + RTAREA_TRAP_DATA_TASKWAIT));
#endif

	if (trap_slot != ctx->trap_slot)
		write_log(_T("Trap trap slot mismatch %d <> %d!\n"), trap_slot, ctx->trap_slot);

	if (trap_in_use2[trap_slot])
		write_log(_T("Trap slot %d already in use2!\n"), trap_slot);
	trap_in_use2[trap_slot] = true;

	put_long_host(data + 4, p1);
	put_long_host(data + 8, p2);
	put_long_host(data + 12, p3);
	put_long_host(data + 16, p4);
	put_word_host(status, cmd);

	volatile uae_u8 *d = status + 3;

	if (ctx->trap_mode == 2) {
		*d = 0xfe;
		// signal rtarea_bget wait
		uae_sem_post(&hardware_trap_event2[trap_slot]);
	} else if (ctx->trap_mode == 0) {
		*d = 0xfe;
	} else {
		atomic_inc(&hwtrap_waiting);
		atomic_or(&uae_int_requested, 0x2000);
		set_special_exter(SPCFLAG_UAEINT);
		*d = 0xff;
	}

	for (;;) {
		if (hardware_trap_kill[trap_slot] < 0)
			return 0;
		uae_u8 v = *d;
		if (v == 0x01 || v == 0x02 || v == 0x03)
			break;
		if (hardware_trap_kill[trap_slot] == 0) {
			hardware_trap_kill[trap_slot] = 2;
			return  0;
		}
		if (uae_sem_trywait_delay(&hardware_trap_event[trap_slot], 100) == -2) {
			hardware_trap_kill[trap_slot] = 3;
			return 0;
		}
	}

	// get result
	uae_u32 v = get_long_host(data + 4);

	if (!trap_in_use2[trap_slot])
		write_log(_T("Trap slot %d in use2 unexpected release!\n"), trap_slot);
	trap_in_use2[trap_slot] = false;

	put_long_host(status, 0);

#if NEW_TRAP_DEBUG
	write_log(_T("TRAP BACK SLOT %d: RET = %08x TASK = %08x\n"), trap_slot, v, get_long_host(ctx->host_trap_data + RTAREA_TRAP_DATA_TASKWAIT));
#endif

	return v;
}
Exemple #5
0
static void *hardware_trap_thread(void *arg)
{
	int tid = (uae_u32)arg;
	for (;;) {
		TrapContext *ctx = (TrapContext*)read_comm_pipe_pvoid_blocking(&trap_thread_pipe[tid]);
		if (!ctx)
			break;

		if (trap_in_use[ctx->trap_slot]) {
			write_log(_T("TRAP SLOT %d ALREADY IN USE!\n"));
		}
		trap_in_use[ctx->trap_slot] = true;

		uae_u8 *data = ctx->host_trap_data;
		uae_u8 *status = ctx->host_trap_status;
		ctx->tindex = tid;
		ctx->tcnt = ++trap_cnt;

		for (int i = 0; i < 15; i++) {
			uae_u32 v = get_long_host(data + 4 + i * 4);
			ctx->saved_regs.regs[i] = v;
		}
		put_long_host(status + RTAREA_TRAP_STATUS_SECOND, 0);

#if NEW_TRAP_DEBUG
		//if (_tcscmp(trap->name, _T("exter_int_helper")))
			write_log(_T("TRAP SLOT %d: NUM %d\n"), ctx->trap_slot, trap_num);
#endif

		uae_u32 ret;
		struct Trap *trap = NULL;

		if (ctx->trap_done)
			write_log(_T("hardware_trap_thread #1: trap_done set!"));

		if (ctx->callback) {
			ret = ctx->callback(ctx, ctx->callback_ud);
		} else {
			int trap_num = get_word_host(status);
			trap = &traps[trap_num];
			ret = trap->handler(ctx);
		}

		if (ctx->trap_done)
			write_log(_T("hardware_trap_thread #2: trap_done set!"));

		if (!ctx->trap_background) {
			for (int i = 0; i < 15; i++) {
				uae_u32 v = ctx->saved_regs.regs[i];
				put_long_host(data + 4 + i * 4, v);
			}
			if (trap && (trap->flags & TRAPFLAG_NO_RETVAL) == 0) {
				put_long_host(data + 4, ret);
			}
			hardware_trap_ack(ctx);
		} else {
			ctx->trap_done = true;
		}
	}
	hardware_trap_kill[tid] = -1;
	return 0;
}
Exemple #6
0
void trap_multi(TrapContext *ctx, struct trapmd *data, int items)
{
	if (trap_is_indirect_null(ctx)) {
		uae_u8 *p = ctx->host_trap_data + RTAREA_TRAP_DATA_EXTRA;
		for (int i = 0; i < items; i++) {
			struct trapmd *md = &data[i];
			put_word_host(p + 0, md->cmd);
			put_byte_host(p + 2, md->trapmd_index);
			put_byte_host(p + 3, md->parm_num);
			put_long_host(p + 4, md->params[0]);
			put_long_host(p + 8, md->params[1]);
			put_long_host(p + 12, md->params[2]);
			put_long_host(p + 16, md->params[3]);
			p += 5 * 4;
		}
		call_hardware_trap_back(ctx, TRAPCMD_MULTI, ctx->amiga_trap_data + RTAREA_TRAP_DATA_EXTRA, items, 0, 0);
		p = ctx->host_trap_data + RTAREA_TRAP_DATA_EXTRA;
		for (int i = 0; i < items; i++) {
			struct trapmd *md = &data[i];
			md->params[0] = get_long_host(p + 4);
			p += 5 * 4;
		}
	} else {
		uae_u32 v = 0;
		for (int i = 0; i < items; i++) {
			struct trapmd *md = &data[i];
			switch (md->cmd)
			{
				case TRAPCMD_PUT_LONG:
				trap_put_long(ctx, md->params[0], md->params[1]);
				break;
				case TRAPCMD_PUT_WORD:
				trap_put_word(ctx, md->params[0], md->params[1]);
				break;
				case TRAPCMD_PUT_BYTE:
				trap_put_byte(ctx, md->params[0], md->params[1]);
				break;
				case TRAPCMD_GET_LONG:
				v = md->params[0] = trap_get_long(ctx, md->params[0]);
				break;
				case TRAPCMD_GET_WORD:
				v = md->params[0] = trap_get_word(ctx, md->params[0]);
				break;
				case TRAPCMD_GET_BYTE:
				v = md->params[0] = trap_get_byte(ctx, md->params[0]);
				break;
				case TRAPCMD_PUT_BYTES:
				trap_put_bytes(ctx, md->haddr, md->params[0], md->params[1]);
				break;
				case TRAPCMD_GET_BYTES:
				trap_get_bytes(ctx, md->haddr, md->params[0], md->params[1]);
				break;
				case TRAPCMD_PUT_WORDS:
				trap_put_words(ctx, (uae_u16*)md->haddr, md->params[0], md->params[1]);
				break;
				case TRAPCMD_GET_WORDS:
				trap_get_words(ctx, (uae_u16*)md->haddr, md->params[0], md->params[1]);
				break;
				case TRAPCMD_PUT_LONGS:
				trap_put_longs(ctx, (uae_u32*)md->haddr, md->params[0], md->params[1]);
				break;
				case TRAPCMD_GET_LONGS:
				trap_get_longs(ctx, (uae_u32*)md->haddr, md->params[0], md->params[1]);
				break;
				case TRAPCMD_PUT_STRING:
				trap_put_string(ctx, md->haddr, md->params[0], md->params[1]);
				break;
				case TRAPCMD_GET_STRING:
				trap_get_string(ctx, md->haddr, md->params[0], md->params[1]);
				break;
				case TRAPCMD_SET_LONGS:
				trap_set_longs(ctx, md->params[0], md->params[1], md->params[2]);
				break;
				case TRAPCMD_SET_WORDS:
				trap_set_words(ctx, md->params[0], md->params[1], md->params[2]);
				break;
				case TRAPCMD_SET_BYTES:
				trap_set_bytes(ctx, md->params[0], md->params[1], md->params[2]);
				break;
				case TRAPCMD_NOP:
				break;
			}
			if (md->trapmd_index) {
				data[md->trapmd_index].params[md->parm_num] = v;
			}
		}
	}
}
Exemple #7
0
uae_u64 trap_get_quad(TrapContext *ctx, uaecptr addr)
{
	uae_u8 in[8];
	trap_get_bytes(ctx, in, addr, 8);
	return ((uae_u64)get_long_host(in + 0) << 32) | get_long_host(in + 4);
}