void gameboy_t::run() { typedef boost::thread thread; struct cpu_runner_t { cpu_runner_t(cpu_t& cpu_, membus_t& memory_) : cpu(cpu_) , memory(memory_) {} cpu_t& cpu; membus_t& memory; void operator()(){ while(!(cpu.is_panicked() || memory.is_panicked())){ cpu.run(); } throw std::runtime_error("CPU panicked"); } }; cpu_runner_t cpu_runner(cpu, memory); thread cpu_thread(cpu_runner); while( !videodec.is_panicked() ) { videodec.run(); if(videodec.requesting_debug()){ cpu.print(); } } throw std::runtime_error("Videodec panicked"); cpu_thread.join(); }
int ApplicationRunner::run() { cpu.set_disassembler(&disassembler); cpu.set_use_undocumented(options.use_undocumented); fdc.disk_directory(options.disk_dir.c_str()); fdc.mount_all_drives(options.drive); pia2v5.disk_directory(options.disk_dir.c_str()); pia2v5.mount_all_drives(options.mdcrDrives); terminalIO.init(options.reset_key); if (!(options.term_mode && terminalIO.is_terminal_supported())) { inout.create_gui( joystickIO, keyboardIO, terminalIO, pia1, memory, scheduler, cpu, vico1, vico2, guiOptions); } AddIoDevicesToMemory(); if (!LoadMonitorFileIntoRom()) { return 1; } memory.reset_io(); cpu.reset(); if (options.term_mode && terminalIO.is_terminal_supported()) { terminalIO.set_startup_command(options.startup_command.c_str()); } else { keyboardIO.set_startup_command(options.startup_command.c_str()); } // start CPU thread std::thread cpu_thread(&Scheduler::run, &scheduler); inout.main_loop(); cpu_thread.join(); // wait for termination of CPU thread return 0; }
bool test() { // define inputs and output const int vecSize = 8; const int loopCount = 1024 * 1024; const int cpuSleepMsec = 50; std::atomic_int table_a[vecSize]; auto ptr_a = &table_a[0]; std::atomic_bool done(false); auto ptr_done = &done; // initialize test data for (int i = 0; i < vecSize; ++i) { table_a[i].store(0); } // fire CPU thread std::thread cpu_thread([=]() { std::cout << "Enter CPU monitor thread..." << std::endl; std::chrono::milliseconds dura( cpuSleepMsec ); while (!*ptr_done) { for (int i = 0; i < vecSize; ++i) { std::cout << std::setw(8) << (ptr_a + i)->load(std::memory_order_acquire); if (i < vecSize - 1) { std::cout << ", "; } else { std::cout << std::endl; } } std::this_thread::sleep_for( dura ); } std::cout << "Leave CPU monitor thread." << std::endl; }); // launch kernel Concurrency::extent<1> e(vecSize); parallel_for_each( e, [=](Concurrency::index<1> idx) restrict(amp) { int tid = idx[0]; int counter = 0; while (++counter <= loopCount) { (ptr_a + tid)->fetch_add(1, std::memory_order_release); } });
int main(int argc, char *argv[]) { if(argc < 2) { cerr << "usage: dcpu <flags> <filename>\n"; return 1; } bool debug = false; int time_to_kill_ms = 0; // -d runs in debug mode, prints out memory dump at end for(int a = 1; a < argc - 1; a++) { if(!strcmp(argv[a], "-d")) { debug = true; }else { cerr << "invalid command <" << argv[a] << ">. ignoring\n"; } } ifstream inFile(argv[argc - 1], ios::in); if(!inFile.good()) { cerr << "Could not open <" << argv[argc - 1] << ">\n"; return 1; } Dcpu cpu(inFile, debug); sf::Thread cpu_thread(&start, &cpu); sf::RenderWindow app(sf::VideoMode(TERMINAL_WIDTH * 4 * 4, TERMINAL_HEIGHT * 8 * 4), "DCPPU: DCPU-16 Emulator"); app.SetFramerateLimit(30); // Getting 1500 fps on somthing this simple seems wasteful sf::Image font; if(!font.LoadFromFile("font.png")) { cerr << "Could not load font\n"; return 1; } unsigned short *buf = cpu.GetScreenBuffer(); buf += TERMINAL_WIDTH * TERMINAL_HEIGHT; // load and encode character set into RAM for(int char_off = 0; char_off < 128; char_off++) { int font_off_x = (char_off * 4) % 128; int font_off_y = ((char_off * 4) / 128) * 8; unsigned int font_char = 0; int x_ = 0; int y_ = 0; for(int x = font_off_x; x < font_off_x + 4; x++) { for(int y = font_off_y; y < font_off_y + 8; y++) { sf::Color pix = font.GetPixel(x, y); if(pix != sf::Color(2, 1, 2)) font_char |= 1 << (31-((y_ * 4) + x_)); y_++; } x_++; } unsigned short lowerword = font_char & 0xffff; unsigned short upperword = (font_char >> 16) & 0xffff; buf[char_off * 2] = upperword; buf[char_off * 2 + 1] = lowerword; } sf::Image screen; screen.Create(128, 96); // create black image screen.SetSmooth(false); sf::Sprite screen_sprite(screen); screen_sprite.SetScale(4.0, 4.0); cpu_thread.Launch(); bool running = true; while(running) { sf::Event Event; while(app.GetEvent(Event)) { if(Event.Type == sf::Event::Closed) { cpu.kill(); running = false; app.Close(); } if (Event.Type == sf::Event::TextEntered) { if (Event.Text.Unicode < 128) { char c = static_cast<char>(Event.Text.Unicode); cpu.PushInBuff(c); } } } app.Clear(); unsigned short *buffer = cpu.GetScreenBuffer(); for(int y = 0; y < TERMINAL_HEIGHT; y++) { for(int x = 0; x < TERMINAL_WIDTH; x++) { unsigned short sc = buffer[y * 32 + x]; int fg_off = (sc >> 12) & 0xf; int bg_off = (sc >> 8) & 0xf; sf::Color fg = color_table[fg_off]; sf::Color bg = color_table[bg_off]; char c = sc & 0x7f; bool blink = (sc & 0x80) == 0x80 && (time(0) % 2 == 0); // if bit 15 set, blink on for 1 sec, off for 1 sec DrawCharacter(screen, buffer + (TERMINAL_WIDTH*TERMINAL_HEIGHT), c, fg, bg, blink, x, y); } } app.Draw(screen_sprite); app.Display(); } return 0; }