diff --git a/apps/app_dumpchan.c b/apps/app_dumpchan.c
index aa8854620f06e626ee9069c0856840e781a8cb70..5124cc2c4263227d55814170789c4233d02c10bb 100644
--- a/apps/app_dumpchan.c
+++ b/apps/app_dumpchan.c
@@ -114,8 +114,8 @@ static int ast_serialize_showchan(struct ast_channel *c, char *buf, size_t size)
 			 c->nativeformats,
 			 c->writeformat,
 			 c->readformat,
-			 c->fds[0], c->fin & 0x7fffffff, (c->fin & 0x80000000) ? " (DEBUGGED)" : "",
-			 c->fout & 0x7fffffff, (c->fout & 0x80000000) ? " (DEBUGGED)" : "", (long)c->whentohangup,
+			 c->fds[0], c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
+			 c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", (long)c->whentohangup,
 			 hour,
 			 min,
 			 sec,
diff --git a/channel.c b/channel.c
index 6a2d4f6e69f77740c69a24938393261c30e423ee..80b1109baab92a008bae8b532024ec6f110e50d0 100644
--- a/channel.c
+++ b/channel.c
@@ -2049,12 +2049,9 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
 	}
 
 	/* High bit prints debugging */
-	if (chan->fin & 0x80000000)
+	if (chan->fin & DEBUGCHAN_FLAG)
 		ast_frame_dump(chan->name, f, "<<");
-	if ((chan->fin & 0x7fffffff) == 0x7fffffff)
-		chan->fin &= 0x80000000;
-	else
-		chan->fin++;
+	chan->fin = FRAMECOUNT_INC(chan->fin);
 
 done:
 	ast_mutex_unlock(&chan->lock);
@@ -2272,30 +2269,28 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
 
 	/* Stop if we're a zombie or need a soft hangup */
 	ast_channel_lock(chan);
-	if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))  {
-		ast_channel_unlock(chan);
-		return -1;
-	}
+	if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
+		goto done;
+
 	/* Handle any pending masquerades */
 	if (chan->masq && ast_do_masquerade(chan)) {
 		ast_log(LOG_WARNING, "Failed to perform masquerade\n");
-		ast_channel_unlock(chan);
-		return -1;
+		goto done;
 	}
 	if (chan->masqr) {
-		ast_channel_unlock(chan);
-		return 0;
+		res = 0;	/* XXX explain, why 0 ? */
+		goto done;
 	}
 	if (chan->generatordata) {
 		if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
 			ast_deactivate_generator(chan);
 		else {
-			ast_channel_unlock(chan);
-			return 0;
+			res = 0;	/* XXX explain, why 0 ? */
+			goto done;
 		}
 	}
 	/* High bit prints debugging */
-	if (chan->fout & 0x80000000)
+	if (chan->fout & DEBUGCHAN_FLAG)
 		ast_frame_dump(chan->name, fr, ">>");
 	CHECK_BLOCKING(chan);
 	switch(fr->frametype) {
@@ -2348,6 +2343,7 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
 				queue_frame_to_spies(chan, f, SPY_WRITE);
 
 			if (chan->monitor && chan->monitor->write_stream) {
+				/* XXX must explain this code */
 #ifndef MONITOR_CONSTANT_DELAY
 				int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
 				if (jump >= 0) {
@@ -2383,11 +2379,9 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
 	if (res < 0)
 		chan->_softhangup |= AST_SOFTHANGUP_DEV;
 	else {
-		if ((chan->fout & 0x7fffffff) == 0x7fffffff)
-			chan->fout &= 0x80000000;
-		else
-			chan->fout++;
+		chan->fout = FRAMECOUNT_INC(chan->fout);
 	}
+done:
 	ast_channel_unlock(chan);
 	return res;
 }
diff --git a/cli.c b/cli.c
index 591652d3e75078add9327dc7449486e5c4edff84..8aa7b8ac23b5285376617d7c90e0b0ccd12d15c7 100644
--- a/cli.c
+++ b/cli.c
@@ -626,7 +626,6 @@ static int handle_debuglevel(int fd, int argc, char *argv[])
 	return RESULT_SUCCESS;
 }
 
-#define	DEBUGCHAN_FLAG	0x80000000
 /* XXX todo: merge next two functions!!! */
 static int handle_debugchan(int fd, int argc, char *argv[])
 {
@@ -756,8 +755,10 @@ static int handle_showchan(int fd, int argc, char *argv[])
 		ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats), 
 		ast_getformatname_multiple(wf, sizeof(wf), c->writeformat), 
 		ast_getformatname_multiple(rf, sizeof(rf), c->readformat),
-		c->fds[0], c->fin & 0x7fffffff, (c->fin & 0x80000000) ? " (DEBUGGED)" : "",
-		c->fout & 0x7fffffff, (c->fout & 0x80000000) ? " (DEBUGGED)" : "", (long)c->whentohangup,
+		c->fds[0],
+		c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
+		c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
+		(long)c->whentohangup,
 		cdrtime, c->_bridge ? c->_bridge->name : "<none>", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "<none>", 
 		c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ),
 		( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 3096d16567559dc6e8976b87b468ca4e69fc650c..1fdec4ed3bc00ad13165802c8f1e9f334cac0a48 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -403,9 +403,13 @@ struct ast_channel {
 	unsigned long insmpl;
 	unsigned long outsmpl;
 
-	/* Frames in/out counters */
+	/* Frames in/out counters. The high bit is a debug mask, so
+	 * the counter is only in the remaining bits
+	 */
 	unsigned int fin;
 	unsigned int fout;
+#define	DEBUGCHAN_FLAG  0x80000000
+#define	FRAMECOUNT_INC(x)	( ((x) & DEBUGCHAN_FLAG) | ((x++) & ~DEBUGCHAN_FLAG) )
 
 	/* Why is the channel hanged up */
 	int hangupcause;