Exemple #1
0
bool mapped_malloc (addrbank *ab)
{
	if (ab->allocated_size) {
		write_log(_T("mapped_malloc with memory bank '%s' already allocated!?\n"), ab->name);
	}
	ab->allocated_size = 0;

	if (ab->label && ab->label[0] == '*') {
		if (ab->start == 0 || ab->start == 0xffffffff) {
			write_log(_T("mapped_malloc(*) without start address!\n"));
			return false;
		}
	}

	struct uae_mman_data md = { 0 };
	uaecptr start = ab->start;
	if (uae_mman_info(ab, &md)) {
		start = md.start;
    ab->baseaddr = regs.natmem_offset + start;
	}

	if (ab->baseaddr) {
		if (md.hasbarrier) {
			// fill end of ram with ILLEGAL to catch direct PC falling out of RAM.
			put_long_host(ab->baseaddr + ab->reserved_size, 0x4afc4afc);
		}
		ab->allocated_size = ab->reserved_size;
	  write_log("mapped_malloc(): 0x%08x - 0x%08x (0x%08x - 0x%08x) -> %s (%s)\n", 
	    ab->baseaddr - regs.natmem_offset, ab->baseaddr - regs.natmem_offset + ab->allocated_size,
	    ab->baseaddr, ab->baseaddr + ab->allocated_size, ab->name, ab->label);
	}
  ab->flags |= ABFLAG_DIRECTMAP;
  
  return (ab->baseaddr != NULL);
}
Exemple #2
0
TrapContext *alloc_host_thread_trap_context(void)
{
	if (trap_is_indirect()) {
		int trap_slot = RTAREA_TRAP_DATA_NUM;
		TrapContext *ctx = alloc_host_main_trap_context();
		ctx->host_trap_data = rtarea_bank.baseaddr + RTAREA_TRAP_DATA + trap_slot * RTAREA_TRAP_DATA_SLOT_SIZE;
		ctx->amiga_trap_data = rtarea_base + RTAREA_TRAP_DATA + trap_slot * RTAREA_TRAP_DATA_SLOT_SIZE;
		ctx->host_trap_status = rtarea_bank.baseaddr + RTAREA_TRAP_STATUS + trap_slot * RTAREA_TRAP_STATUS_SIZE;
		ctx->amiga_trap_status = rtarea_base + RTAREA_TRAP_STATUS + trap_slot * RTAREA_TRAP_STATUS_SIZE;
		ctx->trap_mode = 1;

		// Set status to allocated, we are skipping hwtrap_entry()
		put_long_host(ctx->host_trap_status + 4, 0x00000000);
		put_long_host(ctx->host_trap_status, 0x00000080);
		return ctx;
	} else {
		return NULL;
	}
}
Exemple #3
0
uae_u32 trap_call_func(TrapContext *ctx, uaecptr func)
{
	uae_u32 v;
	if (trap_is_indirect_null(ctx)) {
		uae_u8 *p = ctx->host_trap_data + RTAREA_TRAP_DATA_EXTRA;
		for (int i = 0; i < 16; i++) {
			if (ctx->calllib_reg_inuse[i]) {
				put_long_host(p, ctx->calllib_regs[i]);
				ctx->calllib_reg_inuse[i] = 0;
			} else {
				put_long_host(p, ctx->saved_regs.regs[i]);
			}
			p += 4;
		}
		v = call_hardware_trap_back(ctx, TRAPCMD_CALL_FUNC, func, ctx->amiga_trap_data + RTAREA_TRAP_DATA_EXTRA, 0, 0);
	} else {
		uae_u32 storedregs[16];
		bool storedregsused[16];
		for (int i = 0; i < 16; i++) {
			storedregsused[i] = false;
			if (ctx->calllib_reg_inuse[i]) {
				if ((i & 7) >= 2) {
					storedregsused[i] = true;
					storedregs[i] = regs.regs[i];
				}
				regs.regs[i] = ctx->calllib_regs[i];
			}
			ctx->calllib_reg_inuse[i] = 0;
		}
		v = CallFunc(ctx, func);
		for (int i = 0; i < 16; i++) {
			if (storedregsused[i]) {
				regs.regs[i] = storedregs[i];
			}
		}
	}
	return v;
}
Exemple #4
0
// Executes trap from C-code
void trap_callback(TRAP_CALLBACK cb, void *ud)
{
	if (trap_is_indirect()) {
		int trap_slot = RTAREA_TRAP_DATA_NUM;
		TrapContext *ctx = xcalloc(TrapContext, 1);
		ctx->host_trap_data = rtarea_bank.baseaddr + RTAREA_TRAP_DATA + trap_slot * RTAREA_TRAP_DATA_SLOT_SIZE;
		ctx->amiga_trap_data = rtarea_base + RTAREA_TRAP_DATA + trap_slot * RTAREA_TRAP_DATA_SLOT_SIZE;
		ctx->host_trap_status = rtarea_bank.baseaddr + RTAREA_TRAP_STATUS + trap_slot * RTAREA_TRAP_STATUS_SIZE;
		ctx->amiga_trap_status = rtarea_base + RTAREA_TRAP_STATUS + trap_slot * RTAREA_TRAP_STATUS_SIZE;
		ctx->trap_mode = 1;
		ctx->trap_slot = trap_slot;

		// Set status to allocated, we are skipping hwtrap_entry()
		put_long_host(ctx->host_trap_status + 4, 0x00000000);
		put_long_host(ctx->host_trap_status + 0, 0x00000080);

		ctx->callback = cb;
		ctx->callback_ud = ud;
		write_comm_pipe_pvoid(&trap_thread_pipe[trap_slot], ctx, 1);
	} else {
		cb(NULL, ud);
	}
}
Exemple #5
0
void trap_put_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;
			for (int i = 0; i < max; i++) {
				put_long_host(ctx->host_trap_data + RTAREA_TRAP_DATA_EXTRA + i * sizeof(uae_u32), *haddr++);
			}
			call_hardware_trap_back(ctx, TRAPCMD_PUT_LONGS, ctx->amiga_trap_data + RTAREA_TRAP_DATA_EXTRA, addr, max, 0);
			addr += max * sizeof(uae_u32);
			cnt -= max;
		}
	} else {
		uae_u32 *p = (uae_u32*)haddr;
		for (int i = 0; i < cnt; i++) {
			put_long(addr, *p++);
			addr += 4;
		}
	}
}
Exemple #6
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 #7
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 #8
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;
			}
		}
	}
}