Index: emu/all.h
===================================================================
--- emu/all.h	(revision 5fa53696c42d276435b389efd40733f2a9cfa4c2)
+++ emu/all.h	(revision 149c3e0464040679e4af59c66cbe353c99af13a5)
@@ -73,5 +73,5 @@
 extern void gdb_quit(void);
 extern void gdb_loop(void);
-extern void gdb_inst(void);
+extern void gdb_inst(bool bp);
 
 extern SDL_mutex *cpu_mutex;
Index: emu/cpu.c
===================================================================
--- emu/cpu.c	(revision 5fa53696c42d276435b389efd40733f2a9cfa4c2)
+++ emu/cpu.c	(revision 149c3e0464040679e4af59c66cbe353c99af13a5)
@@ -494,8 +494,8 @@
 static void inst_cb(void)
 {
-	gdb_inst();
-
 	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) {
Index: emu/gdb.c
===================================================================
--- emu/gdb.c	(revision 5fa53696c42d276435b389efd40733f2a9cfa4c2)
+++ emu/gdb.c	(revision 149c3e0464040679e4af59c66cbe353c99af13a5)
@@ -39,4 +39,5 @@
 #define LOCK_REQ 1
 #define LOCK_ACK 2
+#define LOCK_BP 3
 
 typedef enum {
@@ -97,9 +98,9 @@
 }
 
-void gdb_inst(void)
+void gdb_inst(bool bp)
 {
 	ver3("gdb inst");
 
-	if (SDL_AtomicGet(&lock) == LOCK_NONE) {
+	if (!bp && SDL_AtomicGet(&lock) == LOCK_NONE) {
 		return;
 	}
@@ -107,4 +108,13 @@
 	if (SDL_UnlockMutex(cpu_mutex) < 0) {
 		fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
+	}
+
+	if (bp) {
+		ver2("-> lock bp");
+		SDL_AtomicSet(&lock, LOCK_BP);
+
+		while (SDL_AtomicGet(&lock) != LOCK_REQ) {
+			SDL_Delay(100);
+		}
 	}
 
@@ -124,4 +134,13 @@
 }
 
+static void wait_cpu(void)
+{
+	while (SDL_AtomicGet(&lock) != LOCK_ACK) {
+		SDL_Delay(100);
+	}
+
+	ver2("<- lock ack");
+}
+
 static void stop_cpu(void)
 {
@@ -129,9 +148,5 @@
 	SDL_AtomicSet(&lock, LOCK_REQ);
 
-	while (SDL_AtomicGet(&lock) != LOCK_ACK) {
-		SDL_Delay(100);
-	}
-
-	ver2("<- lock ack");
+	wait_cpu();
 }
 
@@ -140,19 +155,4 @@
 	ver2("-> lock none");
 	SDL_AtomicSet(&lock, LOCK_NONE);
-}
-
-static void step_cpu(void)
-{
-	ver2("-> lock req");
-	SDL_AtomicSet(&lock, LOCK_REQ);
-}
-
-static void wait_cpu(void)
-{
-	while (SDL_AtomicGet(&lock) != LOCK_ACK) {
-		SDL_Delay(100);
-	}
-
-	ver2("<- lock ack");
 }
 
@@ -215,8 +215,6 @@
 
 	cont_cpu();
-	wait_cpu();
-
-	// 0x05 = SIGTRAP
-	return RES_DAT("S05", 3);
+
+	return RES_OK;
 }
 
@@ -227,6 +225,5 @@
 	}
 
-	step_cpu();
-	wait_cpu();
+	stop_cpu();
 
 	// 0x05 = SIGTRAP
@@ -455,4 +452,8 @@
 	}
 
+	if (res.out == NULL) {
+		return RES_OK;
+	}
+
 	static const uint8_t *hex = (uint8_t *)"0123456789abcdef";
 	static uint8_t buf[SZ_BUF];
@@ -487,4 +488,10 @@
 
 	ver3("input %c st %d n %d", byte, (int32_t)state, n_buf);
+
+	if (state == STATE_HEAD && byte == 0x03) {
+		stop_cpu();
+		state = STATE_ACK;
+		return RES_DAT("$S05#b8", 7);
+	}
 
 	switch (state) {
@@ -552,4 +559,9 @@
 		}
 
+		if (res.out == NULL) {
+			state = STATE_HEAD;
+			return RES_OK;
+		}
+
 		state = STATE_ACK;
 		return RES_DAT(res.out, res.n_out);
@@ -588,8 +600,23 @@
 
 	while (SDL_AtomicGet(&run) != 0) {
-		int32_t n_act = SDLNet_CheckSockets(set, 250);
+		int32_t n_act = SDLNet_CheckSockets(set, 100);
 
 		if (n_act < 0) {
 			fail("SDLNet_CheckSockets() failed: %s", SDLNet_GetError());
+		}
+
+		if (SDL_AtomicGet(&lock) == LOCK_BP) {
+			ver2("<- lock bp");
+			stop_cpu();
+			state = STATE_ACK;
+
+			if (SDLNet_TCP_Send(con, "$S05#b8", 7) != 7) {
+				err("connection error");
+				con_close(con);
+				con = NULL;
+				continue;
+			}
+
+			continue;
 		}
 
