void * runCen64(void * p) { struct bus_controller *bus = (struct bus_controller *) p; struct vr4300 vr4300; vr4300_init(&vr4300, bus); vr4300.pipeline.icrf_latch.pc = 0xFFFFFFFF801E4B10ULL; // Prime the pipeline... while (vr4300.pipeline.dcwb_latch.common.pc != 0xFFFFFFFF801E4B10ULL || (vr4300.pipeline.dcwb_latch.common.fault || vr4300.pipeline.dcwb_latch.common.killed)) vr4300_cycle(&vr4300); //printf("cmips starts at 0x%.8X... PRIMED!!\n",bus->emu->pc); unsigned steps_compld = 0; uint8_t *mem_at_wb = malloc(64 * 1024 * 1024); uint8_t *mem_at_commit = malloc(64 * 1024 * 1024); if (mem_at_wb == NULL || mem_at_commit == NULL) { printf("MOAR mammaries required!!\n"); abort(); } memcpy(mem_at_wb, bus->emu->mem, 64 * 1024 * 1024); memcpy(mem_at_commit, bus->emu->mem, 64 * 1024 *1024); while (1) { int i; if(pthread_mutex_lock(&emu_mutex)) { puts("mutex failed lock, exiting"); exit(1); } for (i = 0; i < 10000; i++) { #if 0 //printf("."); //fflush(stdout); // printf("step_mips, pc: 0x%.8X\n", bus->emu->pc); uint32_t cmp_pc = bus->emu->pc; step_mips(bus->emu); do { vr4300_cycle(&vr4300); } while(vr4300.pipeline.last_pipe_result.fault || vr4300.pipeline.last_pipe_result.killed); vr4300.pipeline.last_pipe_result.fault = ~0; if (cmp_pc != (uint32_t) vr4300.pipeline.last_pipe_result.pc) { printf("PC mismatch detected @ %u steps!\n", steps_compld); printf("cmips: 0x%.8X, cen64: 0x%.8X\n", bus->emu->pc, vr4300.pipeline.last_pipe_result.pc); abort(); } size_t ri; for (ri = 1; ri < 32; ri++) { if ((uint32_t) vr4300.regs[ri] != bus->emu->regs[ri]) { printf("GPR[%u] mismatch detected @ 0x%.8X/%u steps!\n", ri, cmp_pc, steps_compld); printf("cmips: 0x%.8X, cen64: 0x%.8X\n", bus->emu->regs[ri], vr4300.regs[ri]); abort(); } } #if 0 else { printf("cmips: 0x%.8X, cen64: 0x%.8X\n", bus->emu->pc, vr4300.pipeline.last_pipe_result.pc); } #endif // this is too slow #if 1 if (steps_compld > 242180) { //memcpy(mem_at_commit, bus->mem, 64 * 1024 * 1024); if (steps_compld > 242182 && memcmp(mem_at_commit, bus->emu->mem, 64 * 1024 * 1024)) { size_t k; bool false_alarm; for (k = 0; k < 64 * 1024 * 1024 / 4; k++) { uint32_t cm, cm1, cm2; memcpy(&cm, mem_at_commit + k * 4, sizeof(cm)); memcpy(&cm1, mem_at_wb + k * 4, sizeof(cm1)); memcpy(&cm2, bus->mem + k * 4, sizeof(cm2)); if (cm != bus->emu->mem[k] && cm1 != bus->emu->mem[k] && cm2 != bus->emu->mem[k]) { printf("Memory mismatch detected @ %u steps!\n", steps_compld); printf(" -> @addr=0x%.8X ... cmips=0x%.8X, cen64=0x%.8X\n", (unsigned) (k * 4), bus->emu->mem[k], cm); false_alarm = false; break; } else { false_alarm = true; break; } } if (!false_alarm) abort(); } memcpy(mem_at_commit, mem_at_wb, 64 * 1024 * 1024); memcpy(mem_at_wb, bus->mem, 64 * 1024 * 1024); } #endif steps_compld++; #else vr4300_cycle(&vr4300); #endif } if(pthread_mutex_unlock(&emu_mutex)) { puts("mutex failed unlock, exiting"); exit(1); } }
// Creates and initializes a device. struct cen64_device *device_create(struct cen64_device *device, const struct rom_file *ddipl, const struct rom_file *ddrom, const struct rom_file *pifrom, const struct rom_file *cart, const struct save_file *eeprom, const struct save_file *sram, const struct save_file *flashram, const struct controller *controller, bool no_audio, bool no_video) { // Initialize the bus. device->bus.ai = &device->ai; device->bus.dd = &device->dd; device->bus.pi = &device->pi; device->bus.ri = &device->ri; device->bus.si = &device->si; device->bus.vi = &device->vi; device->bus.rdp = &device->rdp; device->bus.rsp = &device->rsp; device->bus.vr4300 = &device->vr4300; // Initialize the bus. if (bus_init(&device->bus)) { debug("create_device: Failed to initialize the bus.\n"); return NULL; } // Initialize the AI. if (ai_init(&device->ai, &device->bus, no_audio)) { debug("create_device: Failed to initialize the AI.\n"); return NULL; } // Initialize the DD. if (dd_init(&device->dd, &device->bus, ddipl->ptr, ddrom->ptr, ddrom->size)) { debug("create_device: Failed to initialize the DD.\n"); return NULL; } // Initialize the PI. if (pi_init(&device->pi, &device->bus, cart->ptr, cart->size, sram, flashram)) { debug("create_device: Failed to initialize the PI.\n"); return NULL; } // Initialize the RI. if (ri_init(&device->ri, &device->bus)) { debug("create_device: Failed to initialize the RI.\n"); return NULL; } // Initialize the SI. if (si_init(&device->si, &device->bus, pifrom->ptr, cart->ptr, ddipl->ptr != NULL, eeprom->ptr, eeprom->size, controller)) { debug("create_device: Failed to initialize the SI.\n"); return NULL; } // Initialize the VI. if (vi_init(&device->vi, &device->bus, no_video)) { debug("create_device: Failed to initialize the VI.\n"); return NULL; } // Initialize the RDP. if (rdp_init(&device->rdp, &device->bus)) { debug("create_device: Failed to initialize the RDP.\n"); return NULL; } // Initialize the RSP. if (rsp_init(&device->rsp, &device->bus)) { debug("create_device: Failed to initialize the RSP.\n"); return NULL; } // Initialize the VR4300. if (vr4300_init(&device->vr4300, &device->bus)) { debug("create_device: Failed to initialize the VR4300.\n"); return NULL; } return device; }