Index: emu/tim.c
===================================================================
--- emu/tim.c	(revision 52c84012f7a4ebeb51fd0644b159bad8e7d2f161)
+++ emu/tim.c	(revision 9e0cd12edc14538a2d9b9041dd45ca742d5617a9)
@@ -22,16 +22,5 @@
 #define ver3(...) _ver(tim_verbose, 2, __VA_ARGS__)
 
-typedef struct {
-	uint32_t irq;
-	bool run;
-	uint32_t latch;
-	uint32_t count;
-} state_timer;
-
-static state_timer timers[] = {
-		{.irq = 0, .run = false, .latch = 32, .count = 32},
-		{.irq = 0, .run = false, .latch = 3200, .count = 3200},
-		{.irq = 0, .run = false, .latch = 801, .count = 801}
-};
+int32_t tim_verbose = 0;
 
 #define REG_CRX 0
@@ -44,5 +33,23 @@
 #define REG_T3L 7
 
-int32_t tim_verbose = 0;
+#define COUNT_1 32
+#define COUNT_2 3200
+#define COUNT_3 801
+
+typedef struct {
+	bool irq_e;
+	bool irq;
+	int32_t latch;
+	int32_t count;
+} state_timer;
+
+static state_timer timers[] = {
+		{ .irq_e = false, .irq = false, .latch = COUNT_1, .count = COUNT_1 },
+		{ .irq_e = false, .irq = false, .latch = COUNT_2, .count = COUNT_2 },
+		{ .irq_e = false, .irq = false, .latch = COUNT_3, .count = COUNT_3 }
+};
+
+static bool wr_cr1 = false;
+static bool oper = false;
 
 void tim_init(void)
@@ -58,12 +65,17 @@
 bool tim_exec(void)
 {
-	for (int32_t i = 0; i < ARRAY_COUNT(timers); ++i) {
-		if(timers[i].run == true) {
+	if (oper) {
+		for (int32_t i = 0; i < ARRAY_COUNT(timers); ++i) {
 			--timers[i].count;
-			if(timers[i].count == 0) {
+
+			if (timers[i].count == 0) {
+				ver2("tim %d zero", i + 1);
 				timers[i].count = timers[i].latch;
-				timers[i].irq = 1;
+
+				if (timers[i].irq_e) {
+					ver2("tim %d irq", i + 1);
+					timers[i].irq = true;
+				}
 			}
-			//ver2("tim%d %u", i, timers[i].count);
 		}
 	}
@@ -75,43 +87,43 @@
 {
 	ver2("tim rd %u:%d", off, sz * 8);
-	uint32_t rv;
-	rv = 0;
-	switch(off) {
-	case REG_CRX:
-		break;
 
+	if (sz != 1 || off > 7) {
+		fail("invalid tim rd %u:%d", off, sz * 8);
+	}
+
+	uint32_t rv = 0x00;
+
+	switch (off) {
 	case REG_CR2:
-		rv |= (timers[0].irq << 0);
-		rv |= (timers[1].irq << 1);
-		rv |= (timers[2].irq << 2);
-		ver2("tim plc %u fc %u rtc %u", timers[0].irq, timers[1].irq, timers[2].irq);
-		//ver2("tim rv %u", rv);
-		break;
+		rv |= (uint32_t)timers[0].irq << 0;
+		rv |= (uint32_t)timers[1].irq << 1;
+		rv |= (uint32_t)timers[2].irq << 2;
 
-	case REG_T1H:
-		rv = 0;
+		ver2("tim irqs %u %u %u",
+				(uint32_t)timers[0].irq, (uint32_t)timers[1].irq, (uint32_t)timers[2].irq);
 		break;
 
 	case REG_T1L:
-		rv = 31;
-		timers[0].irq = 0;
-		break;
+		if (timers[0].irq) {
+			ver2("tim 1 !irq");
+			timers[0].irq = false;
+		}
 
-	case REG_T2H:
-		rv = 12;
 		break;
 
 	case REG_T2L:
-		rv = 127;
-		timers[1].irq = 0;
-		break;
+		if (timers[1].irq) {
+			ver2("tim 2 !irq");
+			timers[1].irq = false;
+		}
 
-	case REG_T3H:
-		rv = 3;
 		break;
 
 	case REG_T3L:
-		rv = 32;
-		timers[2].irq = 0;
+		if (timers[2].irq) {
+			ver2("tim 3 !irq");
+			timers[2].irq = false;
+		}
+
 		break;
 
@@ -126,8 +138,32 @@
 {
 	ver2("tim wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
-	if( off == 0 && (val & (1 << 7)) ) {
-		timers[0].run = true;
-		timers[1].run = true;
-		timers[2].run = true;
+
+	if (sz != 1 || off > 7) {
+		fail("invalid tim wr %u:%d", off, sz * 8);
+	}
+
+	switch (off) {
+	case REG_CRX:
+		if (wr_cr1) {
+			if ((val & 0x01) == 0) {
+				ver2("tim start");
+				oper = true;
+			}
+
+			timers[0].irq_e = (val & 0x40) != 0;
+		}
+		else {
+			timers[2].irq_e = (val & 0x40) != 0;
+		}
+
+		break;
+
+	case REG_CR2:
+		wr_cr1 = (val & 0x01) != 0;
+		timers[1].irq_e = (val & 0x40) != 0;
+		break;
+
+	default:
+		break;
 	}
 }
