Index: emu/cpu.c
===================================================================
--- emu/cpu.c	(revision 212bc4cfc05af2d41fae2b2719132ae52a71e45c)
+++ emu/cpu.c	(revision 05e6dbe8b288dd07888f2ffc2ab329f6b96cc97d)
@@ -52,4 +52,9 @@
 } hw_t;
 
+static uint64_t freq;
+static uint64_t quan;
+
+SDL_mutex *cpu_mutex;
+
 static bool reset = true;
 
@@ -69,6 +74,6 @@
 static hw_t hw_map[] = {
 	{ 0x180000, 0x200000, 0, fpu_init, fpu_quit, fpu_exec, fpu_read, fpu_write },
-	{ 0x200000, 0x280000, 0, vid_init, vid_quit, vid_exec, vid_read, vid_write },
-	{ 0x3a0001, 0x3a4001, 4, tim_init, tim_quit, tim_exec, tim_read, tim_write },
+	{ 0x200000, 0x280002, 0, vid_init, vid_quit, vid_exec, vid_read, vid_write },
+	{ 0x3a0001, 0x3a4001, 0, tim_init, tim_quit, tim_exec, tim_read, tim_write },
 	{ 0x3a4001, 0x3a8001, 0, lcd_init, lcd_quit, lcd_exec, lcd_read, lcd_write },
 	{ 0x3a8001, 0x3ac001, 5, ser_init, ser_quit, ser_exec, ser_read, ser_write },
@@ -379,7 +384,8 @@
 	}
 
-	// handle loading midas.abs
+	// once midas.abs gets loaded, activate RAM
 
 	if (addr == APP_START) {
+		ram_data[addr] = (uint8_t)val;
 		ram_rw_beg = APP_START;
 		ram_rw_end = RAM_START + RAM_SIZE;
@@ -462,8 +468,34 @@
 }
 
+uint8_t cpu_peek(int32_t addr)
+{
+	if (addr >= RAM_START && addr <= RAM_START + RAM_SIZE - 1) {
+		return ram_data[addr - RAM_START];
+	}
+
+	if (addr >= ROM_START && addr <= ROM_START + ROM_SIZE - 1) {
+		return rom_data[addr - ROM_START];
+	}
+
+	return 0;
+}
+
+void cpu_poke(int32_t addr, uint8_t val)
+{
+	if (addr >= RAM_START && addr <= RAM_START + RAM_SIZE - 1) {
+		ram_data[addr - RAM_START] = val;
+	}
+
+	if (addr >= ROM_START && addr <= ROM_START + ROM_SIZE - 1) {
+		rom_data[addr - ROM_START] = val;
+	}
+}
+
 static void inst_cb(void)
 {
 	uint32_t pc = m68k_get_reg(NULL, M68K_REG_PC);
 	uint32_t op = m68k_read_memory_16(pc);
+
+	gdb_inst(op == 0x4e4f);
 
 	if (op == 0x4e4d) {
@@ -619,27 +651,43 @@
 }
 
-void cpu_loop(void)
-{
+void cpu_init(void)
+{
+	cpu_mutex = SDL_CreateMutex();
+
+	if (cpu_mutex == NULL) {
+		fail("SDL_CreateMutex() failed: %s", SDL_GetError());
+	}
+
+	freq = SDL_GetPerformanceFrequency();
+	quan = freq / PER_SEC;
+
+	inf("freq %" PRIu64 " quan %" PRIu64, freq, quan);
+
 	hw_init();
 	bios_init();
 
-	inf("entering CPU loop");
 	m68k_init();
 	m68k_set_cpu_type(M68K_CPU_TYPE_68000);
 	m68k_set_instr_hook_callback(inst_cb);
 	m68k_pulse_reset();
-
-	uint64_t freq = SDL_GetPerformanceFrequency();
-	uint64_t quan = freq / PER_SEC;
-	inf("freq %" PRIu64 " quan %" PRIu64, freq, quan);
-
-	bool run = true;
-
-#if defined EMU_LINUX
-	SDL_Scancode down = SDL_SCANCODE_UNKNOWN;
-#endif
-
-	while (run) {
+}
+
+void cpu_quit(void)
+{
+	hw_quit();
+	SDL_DestroyMutex(cpu_mutex);
+}
+
+void cpu_loop(void)
+{
+	inf("entering CPU loop");
+	int32_t count = 0;
+
+	while (SDL_AtomicGet(&run) != 0) {
 		uint64_t until = SDL_GetPerformanceCounter() + quan;
+
+		if (SDL_LockMutex(cpu_mutex) < 0) {
+			fail("SDL_LockMutex() failed: %s", SDL_GetError());
+		}
 
 		m68k_execute(CPU_FREQ / PER_SEC);
@@ -652,45 +700,19 @@
 		m68k_set_irq(irq);
 
-		SDL_Event ev;
-
-		while (SDL_PollEvent(&ev) > 0) {
-#if defined EMU_LINUX
-			// Work around duplicate key-down events on Linux.
-
-			if (ev.type == SDL_KEYDOWN) {
-				if (down == ev.key.keysym.scancode) {
-					continue;
-				}
-
-				down = ev.key.keysym.scancode;
+		if (SDL_UnlockMutex(cpu_mutex) < 0) {
+			fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
+		}
+
+		if ((++count & 0x1ff) == 0) {
+			SDL_Delay(0);
+		}
+
+		while (SDL_GetPerformanceCounter() < until) {
+			for (int32_t i = 0; i < 100; ++i) {
+				_mm_pause();
 			}
-			else if (ev.type == SDL_KEYUP) {
-				down = SDL_SCANCODE_UNKNOWN;
-			}
-#endif
-
-			if (ev.type == SDL_QUIT ||
-					(ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE)) {
-				run = false;
-				continue;
-			}
-
-			if (ev.type == SDL_TEXTINPUT) {
-				ser_text(&ev.text);
-				continue;
-			}
-
-			if (ev.type == SDL_KEYDOWN) {
-				ser_key(&ev.key);
-				continue;
-			}
-		}
-
-		while (SDL_GetPerformanceCounter() < until) {
-			_mm_pause();
 		}
 	}
 
 	inf("leaving CPU loop");
-	hw_quit();
-}
+}
