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); }
void debug_set_pc_address(uint32_t address) { cpu_flush(address, cpu.ADL); }
/* 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; }