示例#1
0
文件: run88.cpp 项目: fantomid/libcpu
int
main(int ac, char **av, char **ep)
{
	int rc;
	cpu_t *cpu;
	xec_guest_info_t guest_info;
	xec_mem_if_t *mem_if;
	xec_monitor_t *monitor;
	xec_us_syscall_if_t *us_syscall;
	m88k_uintptr_t stack_top;
	nix_env_t *env;
	bool debugging = false;

	aspace_lock();

	if (ac < 2) {
		fprintf(stderr, "usage: %s <executable> [args...]\n", *av);
		exit(EXIT_FAILURE);
	}

	/* Initialize xec, nix and loader. */
	xec_init();
	obsd41_init();
	loader_init();

	/* Create CPU */
	cpu = cpu_new(CPU_ARCH_M88K, CPU_FLAG_ENDIAN_BIG, 0);
	if (cpu == NULL) {
		fprintf(stderr, "error: failed initializing M88K architecture.\n");
		exit(EXIT_FAILURE);
	}

	/* Create XEC bridge mem-if */
	mem_if = run88_new_mem_if();

	/* Create the XEC US Syscall */
	us_syscall = obsd41_us_syscall_create(mem_if);
	if (us_syscall == NULL) {
		fprintf(stderr, "error: failed creating xec userspace syscall.\n");
		exit(EXIT_FAILURE);
	}

	/* Create NIX env */
	env = nix_env_create(mem_if);
	if (env == NULL) {
		fprintf(stderr, "error: failed creating nix environment.\n");
		exit(EXIT_FAILURE);
	}

	/* Load the executable */
	rc = loader_load(mem_if, av[1]);
	if (rc != LOADER_SUCCESS) {
		fprintf(stderr, "error: cannot load executable '%s', error=%d.\n", av[1], rc);
		exit(EXIT_FAILURE);
	}

	/* Setup arguments */
	g_uframe_log = xec_log_register("uframe");

#ifndef DEBUGGER
	xec_log_disable("nix");
	xec_log_disable("openbsd41");
	xec_log_disable("uframe");
	xec_log_disable(NULL);
#endif

	openbsd_m88k_setup_uframe(cpu, mem_if, ac - 1, av + 1, ep, &stack_top);

	/* Setup the CPU */
	cpu_set_flags_codegen(cpu, CPU_CODEGEN_OPTIMIZE|CPU_CODEGEN_TAG_LIMIT);
	cpu_set_flags_debug(cpu, CPU_DEBUG_NONE);
	//cpu_set_flags_debug(cpu, CPU_DEBUG_SINGLESTEP_BB);
	cpu_set_flags_hint(cpu, CPU_HINT_TRAP_RETURNS_TWICE);
	cpu_set_ram(cpu, RAM);

	/* Create XEC bridge monitor */
	guest_info.name = cpu->info.name;
	guest_info.endian = (cpu->info.common_flags & CPU_FLAG_ENDIAN_MASK)
		== CPU_FLAG_ENDIAN_BIG ? XEC_ENDIAN_BIG : XEC_ENDIAN_LITTLE;
	guest_info.byte_size = cpu->info.byte_size;
	guest_info.word_size = cpu->info.word_size;
	guest_info.page_size = cpu->info.default_page_size;
	monitor = xec_monitor_create(&guest_info, mem_if, cpu->rf.grf, NULL);
	if (monitor == NULL) {
		fprintf(stderr, "error: failed createc xec monitor.\n");
		exit(EXIT_FAILURE);
	}

	/* Setup registers for execution */
	PC = g_ahdr.entry;

	R[31] = stack_top; // Stack Pointer
	R[1]  = -1;        // Return Address

	cpu->code_start = g_ahdr.tstart;
	cpu->code_end   = g_ahdr.tstart + g_ahdr.tsize;
	cpu->code_entry = g_ahdr.entry;

	cpu_tag(cpu, cpu->code_entry);

	dump_state(RAM, (m88k_grf_t*)cpu->rf.grf);

#ifdef DEBUGGER
	debugging = true;
#else
	fprintf(stderr, "Translating..."); fflush(stderr);
	cpu_translate(cpu);
	fprintf(stderr, "done.\n");
#endif

	aspace_unlock();

	for (;;) {
		if (debugging) {
			rc = cpu_debugger(cpu, debug_function);
			if (rc < 0) {
				debugging = false;
				continue;
			}
		} else {
			rc = cpu_run(cpu, debug_function);
		}

		switch (rc) {
			case JIT_RETURN_NOERR: /* JIT code wants us to end execution */
				break;

			case JIT_RETURN_FUNCNOTFOUND:
#ifndef DEBUGGER
				fprintf(stderr, "%s: error: 0x%llX not found!\n", __func__, (unsigned long long)PC);
				fprintf(stderr, "Translating..."); fflush(stderr);
				cpu_tag(cpu, PC);
				cpu_flush(cpu);
				cpu_translate(cpu);
				fprintf(stderr, "done.\n");
#else
				dump_state(RAM, (m88k_grf_t*)cpu->rf.grf);

				if (PC == (uint32_t)(-1U))
					goto exit_loop;

				// bad :(
				fprintf(stderr, "%s: warning: 0x%llX not found!\n", __func__, (unsigned long long)PC);
				fprintf(stderr, "PC: ");
				for (size_t i = 0; i < 16; i++)
					fprintf(stderr, "%02X ", RAM[PC+i]);
				fprintf(stderr, "\n");
				exit(EXIT_FAILURE);
#endif
				break;

			case JIT_RETURN_TRAP:
//				printf("TRAP %u / %u!\n", TRAPNO, R[13]);
				if (TRAPNO == 0x80 && R[13] == 1) // exit
					goto exit_loop;

//				printf("BEFORE:\n");
//				dump_state(RAM, (m88k_grf_t*)cpu->rf.grf);
				xec_us_syscall_dispatch(us_syscall, monitor);
//				printf("AFTER:\n");
//				dump_state(RAM, (m88k_grf_t*)cpu->rf.grf);
				break;

			case JIT_RETURN_SINGLESTEP:
				break;

			default:
				fprintf(stderr, "unknown return code: %d\n", rc);
				goto exit_loop;
		}

		if (cpu->flags_debug & (CPU_DEBUG_SINGLESTEP | CPU_DEBUG_SINGLESTEP_BB))
			cpu_flush(cpu);
	}

exit_loop:
	cpu_free(cpu);

	fprintf(stderr, ">> run88 success\n");
	exit(EXIT_SUCCESS);
}
示例#2
0
文件: debug.c 项目: vanloswang/CEmu
void debug_set_pc_address(uint32_t address) {
    cpu_flush(address, cpu.ADL);
}
示例#3
0
文件: link.c 项目: vanloswang/CEmu
/* Proper USB emulation should really be a thing at some point :P */
bool sendVariableLink(const char *var_name) {
    FILE *file;
    uint8_t tmp_buf[0x80];

    uint32_t save_cycles,
             save_next;

    uint8_t var_size_low,
            var_size_high,
            var_type,
            var_arc;

    uint8_t *run_asm_safe = phys_mem_ptr(safe_ram_loc, 1),
            *cxCurApp     = phys_mem_ptr(0xD007E0, 1),
            *op1          = phys_mem_ptr(0xD005F8, 1),
            *var_ptr;

    uint16_t var_size;

    const size_t h_size = sizeof(header_data);
    const size_t op_size = 9;

    /* Return if we are at an error menu */
    if(*cxCurApp == 0x52) {
        return false;
    }

    file = fopen_utf8(var_name,"rb");
    if (!file) {
        return false;
    }

    if (fread(tmp_buf, 1, h_size, file) != h_size)        goto r_err;
    if (memcmp(tmp_buf, header_data, h_size))             goto r_err;

    if (fseek(file, 0x39, 0))                             goto r_err;
    if (fread(&var_size_low, 1, 1, file) != 1)            goto r_err;
    if (fread(&var_size_high, 1, 1, file) != 1)           goto r_err;

    if (fseek(file, 0x3B, 0))                             goto r_err;
    if (fread(&var_type, 1, 1, file) != 1)                goto r_err;

    if (fseek(file, 0x45, 0))                             goto r_err;
    if (fread(&var_arc, 1, 1, file) != 1)                 goto r_err;

    save_cycles = cpu.cycles;
    save_next = cpu.next;

    cpu.halted = cpu.IEF_wait = 0;
    memcpy(run_asm_safe, jforcegraph, sizeof(jforcegraph));
    cpu_flush(safe_ram_loc, 1);
    cpu.cycles = 0;
    cpu.next = 5000000;
    cpu_execute();

    if (fseek(file, 0x3B, 0))                            goto r_err;
    if (fread(op1, 1, op_size, file) != op_size)         goto r_err;
    cpu.halted = cpu.IEF_wait = 0;
    run_asm_safe[0] = 0x21;
    run_asm_safe[1] = var_size_low;
    run_asm_safe[2] = var_size_high;
    run_asm_safe[3] = 0x00;
    run_asm_safe[4] = 0x3E;
    run_asm_safe[5] = var_type;
    memcpy(&run_asm_safe[6], pgrm_loader, sizeof(pgrm_loader));
    cpu_flush(safe_ram_loc, 1);
    cpu.cycles = 0;
    cpu.next = 10000000;
    cpu_execute();

    var_ptr = phys_mem_ptr(get_ptr(safe_ram_loc), 1);

    var_size = (var_size_high << 8) | var_size_low;

    if (fseek(file, 0x48, 0))                           goto r_err;
    if (fread(var_ptr, 1, var_size, file) != var_size)  goto r_err;

    if (var_arc == 0x80) {
        cpu.halted = cpu.IEF_wait = 0;
        memcpy(run_asm_safe, archivevar, sizeof(archivevar));
        cpu_flush(safe_ram_loc, 1);
        cpu.cycles = 0;
        cpu.next = 1000000;
        cpu_execute();
    }

    cpu.halted = cpu.IEF_wait = 0;
    memcpy(run_asm_safe, jforcehome, sizeof(jforcehome));
    cpu_flush(safe_ram_loc, 1);
    cpu.cycles = 0;
    cpu.next = 5000000;
    cpu_execute();

    cpu.cycles = save_cycles;
    cpu.next = save_next;

    return !fclose(file);

r_err:
    fclose(file);
    return false;
}