diff --git a/attic/factory_bootloader.bin b/attic/factory_bootloader.bin
index 1db574dadfd1e458d84febc50358d38c879eeab2..8522877c7bdb9953d844c2fd48838ca7bc5af635 100644
Binary files a/attic/factory_bootloader.bin and b/attic/factory_bootloader.bin differ
diff --git a/ch32v003fun/ch32v003fun.c b/ch32v003fun/ch32v003fun.c
index 18ce488f90546ec317a470f20032a03dd1b70ae2..d472c7df6809f9bd17a96c698d204763459d27f2 100644
--- a/ch32v003fun/ch32v003fun.c
+++ b/ch32v003fun/ch32v003fun.c
@@ -664,7 +664,7 @@ mini_pprintf(int (*puts)(char*s, int len, void* buf), void* buf, const char *fmt
 int main() __attribute__((used));
 void SystemInit( void ) __attribute__((used));
 
-void InterruptVector()         __attribute__((naked)) __attribute((section(".init"))) __attribute__((used));
+void InterruptVector()         __attribute__((naked)) __attribute((section(".init"))) __attribute__((used)) __attribute((weak));
 void handle_reset()            __attribute__((naked)) __attribute((section(".text.handle_reset"))) __attribute__((used));
 void DefaultIRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute__((naked)) __attribute__((used));
 
@@ -760,7 +760,6 @@ void InterruptVector()
 }
 
 
-
 void handle_reset()
 {
 	asm volatile( "\n\
@@ -770,49 +769,55 @@ void handle_reset()
 .option pop\n\
 	la sp, _eusrstack\n"
 	// Setup the interrupt vector, processor status and INTSYSCR.
-"	li t0, 0x80\n\
-	csrw mstatus, t0\n\
-	li t0, 0x3\n\
-	csrw 0x804, t0\n\
-	la t0, InterruptVector\n\
-	ori t0, t0, 3\n\
-	csrw mtvec, t0\n"
- );
+"	li a0, 0x80\n\
+	csrw mstatus, a0\n\
+	c.li a3, 0x3\n\
+	csrw 0x804, a3\n\
+	la a0, InterruptVector\n\
+	c.or a0, a3\n\
+	csrw mtvec, a0\n" );
 
 	// Careful: Use registers to prevent overwriting of self-data.
 	// This clears out BSS.
-	register uint32_t * tempout = _sbss;
-	register uint32_t * tempend = _ebss;
-	while( tempout < tempend )
-		*(tempout++) = 0;
-
-	// Once we get here, it should be safe to execute regular C code.
-
-	// Load data section from flash to RAM 
-	register uint32_t * tempin = _data_lma;
-	tempout = _data_vma;
-	tempend = _edata;
-	while( tempout != tempend )
-		*(tempout++) = *(tempin++); 
-
-	asm volatile("csrw mepc, %0" : : "r"(main));
+asm volatile(
+"	la a0, _sbss\n\
+	la a1, _ebss\n\
+	c.li a2, 0\n\
+	bge a0, a1, 2f\n\
+1:	c.sw a2, 0(a0)\n\
+	c.addi a0, 4\n\
+	blt a0, a1, 1b\n\
+2:"
+	// This loads DATA from FLASH to RAM.
+"	la a0, _data_lma\n\
+	la a1, _data_vma\n\
+	la a2, _edata\n\
+1:	beq a1, a2, 2f\n\
+	c.lw a3, 0(a0)\n\
+	c.sw a3, 0(a1)\n\
+	c.addi a0, 4\n\
+	c.addi a1, 4\n\
+	bne a1, a2, 1b\n\
+2:\n" );
 
 	// set mepc to be main as the root app.
-	asm volatile( "mret\n" );
+asm volatile(
+"	csrw mepc, %[main]\n"
+"	mret\n" : : [main]"r"(main) );
 }
 
 void SystemInit48HSI( void )
 {
 	// Values lifted from the EVT.  There is little to no documentation on what this does.
-	RCC->CTLR  = RCC_HSION | RCC_PLLON; 				// Use HSI, but enable PLL.
-	RCC->CFGR0 = RCC_HPRE_DIV1 | RCC_PLLSRC_HSI_Mul2;	// PLLCLK = HSI * 2 = 48 MHz; HCLK = SYSCLK = APB1
-	FLASH->ACTLR = FLASH_ACTLR_LATENCY_1;				// 1 Cycle Latency
-	RCC->INTR  = 0x009F0000;                            // Clear PLL, CSSC, HSE, HSI and LSI ready flags.
+	RCC->CTLR  = RCC_HSION | RCC_PLLON;               // Use HSI, but enable PLL.
+	RCC->CFGR0 = RCC_HPRE_DIV1 | RCC_PLLSRC_HSI_Mul2; // PLLCLK = HSI * 2 = 48 MHz; HCLK = SYSCLK = APB1
+	FLASH->ACTLR = FLASH_ACTLR_LATENCY_1;             // 1 Cycle Latency
+	RCC->INTR  = 0x009F0000;                          // Clear PLL, CSSC, HSE, HSI and LSI ready flags.
 
 	// From SetSysClockTo_48MHZ_HSI
-	while((RCC->CTLR & RCC_PLLRDY) == 0);														// Wait till PLL is ready
-	RCC->CFGR0 = ( RCC->CFGR0 & ((uint32_t)~(RCC_SW))) | (uint32_t)RCC_SW_PLL;					// Select PLL as system clock source
-	while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08);									// Wait till PLL is used as system clock source
+	while((RCC->CTLR & RCC_PLLRDY) == 0);                                      // Wait till PLL is ready
+	RCC->CFGR0 = ( RCC->CFGR0 & ((uint32_t)~(RCC_SW))) | (uint32_t)RCC_SW_PLL; // Select PLL as system clock source
+	while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08);                // Wait till PLL is used as system clock source
 }
 
 void SetupUART( int uartBRR )
@@ -833,7 +838,7 @@ void SetupUART( int uartBRR )
 	USART1->CTLR1 |= CTLR1_UE_Set;
 }
 
-
+#ifdef STDOUT_UART
 // For debug writing to the UART.
 int _write(int fd, const char *buf, int size)
 {
@@ -843,6 +848,41 @@ int _write(int fd, const char *buf, int size)
 	}
 	return size;
 }
+#else
+// For debug writing to the debug interface.
+int _write(int fd, const char *buf, int size)
+{
+	#define DMDATA0 ((volatile uint32_t*)0xe00000f4)
+	#define DMDATA1 ((volatile uint32_t*)0xe00000f8)
+
+	while( ((*DMDATA0) & 0x80) );
+
+	int remain = size;
+	while( remain > 0 )
+	{
+		int tosend = remain;
+		if( tosend > 7 ) tosend = 7;
+
+		uint32_t dmd1 = 0;
+		if( tosend > 3 ) memcpy( &dmd1, buf + 3, tosend - 3 );
+		uint32_t d1 = (tosend + 4) | 0x80;
+
+		int subsend = tosend;
+		if( subsend > 3 ) subsend = 3;
+		memcpy( ((uint8_t*)(&d1))+1, buf, subsend );
+		*DMDATA1 = dmd1;
+		*DMDATA0 = d1;
+		remain =- tosend;
+	}
+}
+#endif
+
+void SetupDebugPrintf()
+{
+	// Clear out the sending flag.
+	*DMDATA1 = 0x0;
+}
+
 
 void DelaySysTick( uint32_t n )
 {
@@ -853,3 +893,4 @@ void DelaySysTick( uint32_t n )
     while(!(SysTick->SR & (1 << 0)));
     SysTick->CTLR &= ~(1 << 0);
 }
+
diff --git a/ch32v003fun/ch32v003fun.h b/ch32v003fun/ch32v003fun.h
index 92ca4daeb4bb96b0b6dcffa2a28fdbf432b1b995..f25610079e7fb56158838b82216f532bfa578cf9 100644
--- a/ch32v003fun/ch32v003fun.h
+++ b/ch32v003fun/ch32v003fun.h
@@ -4841,6 +4841,8 @@ void SystemInit48HSI( void );
 // Call with SetupUART( UART_BRR )
 void SetupUART( int uartBRR );
 
+void SetupDebugPrintf();
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/ch32v003fun/ch32v003fun.ld b/ch32v003fun/ch32v003fun.ld
index d3d27288f1530e420dafd11ea17d1c93401890c9..b83406385be84e630a04d9c24b7dfcdcde3eef43 100644
--- a/ch32v003fun/ch32v003fun.ld
+++ b/ch32v003fun/ch32v003fun.ld
@@ -1,9 +1,5 @@
 ENTRY( InterruptVector )
 
-__stack_size = 256;
-
-PROVIDE( _stack_size = __stack_size );
-
 MEMORY
 {
 	FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K
@@ -144,15 +140,7 @@ SECTIONS
     PROVIDE( _end = _ebss);
 	PROVIDE( end = . );
 
-	.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
-	{
-	    PROVIDE( _heap_end = . );
-	    . = ALIGN(4);
-	    PROVIDE(_susrstack = . );
-	    . = . + __stack_size;
-	    PROVIDE( _eusrstack = .);
-	} >RAM 
-	
+	PROVIDE( _eusrstack = ORIGIN(RAM) + LENGTH(RAM));	
 }
 
 
diff --git a/examples/blink/Makefile b/examples/blink/Makefile
index e778f4f6b86e37ecd8bd9b8d358b59617d8bc32c..aaddf1dbac01fa6f4b4e66bac09eed1932ba8a7f 100644
--- a/examples/blink/Makefile
+++ b/examples/blink/Makefile
@@ -27,7 +27,7 @@ CFLAGS:= \
 	-I/usr/include/newlib \
 	-I$(CH32V003FUN) \
 	-nostdlib \
-	-I.
+	-I. -DTINYVECTOR
 
 LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections
 
diff --git a/examples/blink/blink.bin b/examples/blink/blink.bin
index fb64e2b23a3be3c7abaadf510116e1e1597f9f46..9d0751d4d385d8b2e2346a9ab16e20ca1628a5d8 100755
Binary files a/examples/blink/blink.bin and b/examples/blink/blink.bin differ
diff --git a/examples/blink/blink.c b/examples/blink/blink.c
index 0029917c298f8edda1a1fae82a1e6c6506bfbf17..450893e40ac7bebb8955555270d681339470eadf 100644
--- a/examples/blink/blink.c
+++ b/examples/blink/blink.c
@@ -15,19 +15,16 @@ int main()
 	// Enable GPIOD.
 	RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
 
-	// GPIO D0 Push-Pull, 10MHz Slew Rate Setting
+	// GPIO D0 Push-Pull, 10MHz Output
 	GPIOD->CFGLR &= ~(0xf<<(4*0));
 	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
 
-	GPIOD->CFGLR &= ~(0xf<<(4*4));
-	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
-
 	while(1)
 	{
-		GPIOD->BSHR = (1<<0) | (1<<4);	 // Turn on GPIOD0 + GPIOD4
-		Delay_Ms( 100 );
-		GPIOD->BSHR = (1<<(16+0)) | (1<<(16+4)); // Turn off GPIOD0 + GPIOD4
-		Delay_Ms( 100 );
+		GPIOD->BSHR = 1;	 // Turn on GPIOD0
+		Delay_Ms( 50 );
+		GPIOD->BSHR = 1<<16; // Turn off GPIOD0
+		Delay_Ms( 50 );
 		count++;
 	}
 }
diff --git a/examples/sandbox/Makefile b/examples/sandbox/Makefile
index b584431f9e85926222f105b606a5d9e44e3e1f4c..d626a3809d6818e66b6801b24f555d89a1245ea6 100644
--- a/examples/sandbox/Makefile
+++ b/examples/sandbox/Makefile
@@ -6,7 +6,7 @@ PREFIX:=riscv64-unknown-elf
 
 GPIO_Toggle:=EXAM/GPIO/GPIO_Toggle/User
 
-EVT:=../../ch32v003evt
+CH32V003FUN:=../../ch32v003CH32V003FUN
 MINICHLINK:=../../minichlink
 
 CFLAGS:= \
@@ -15,13 +15,13 @@ CFLAGS:= \
 	-march=rv32ec \
 	-mabi=ilp32e \
 	-I/usr/include/newlib \
-	-I$(EVT) \
+	-I$(CH32V003FUN) \
 	-nostdlib \
 	-I.
 
-LDFLAGS:=-T $(EVT)/ch32v003.ld -Wl,--gc-sections
+LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections
 
-SYSTEM_C:=$(EVT)/startup_ch32v003.c $(EVT)/embedlibc.c
+SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c
 
 $(TARGET).elf : $(SYSTEM_C) $(TARGET).c
 	$(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
diff --git a/examples/fulldemo/Makefile b/examples/uartdemo/Makefile
similarity index 75%
rename from examples/fulldemo/Makefile
rename to examples/uartdemo/Makefile
index 04a369bce39513c63c4f1ad05e6601860ca02f70..9e1925e9012e971f48a1efb4053a822441823952 100644
--- a/examples/fulldemo/Makefile
+++ b/examples/uartdemo/Makefile
@@ -1,4 +1,4 @@
-TARGET:=fulldemo
+TARGET:=uartdemo
 
 all : flash
 
@@ -6,7 +6,7 @@ PREFIX:=riscv64-unknown-elf
 
 GPIO_Toggle:=EXAM/GPIO/GPIO_Toggle/User
 
-EVT:=../../ch32v003evt
+CH32V003FUN:=../../ch32v003fun
 MINICHLINK:=../../minichlink
 
 CFLAGS:= \
@@ -15,13 +15,13 @@ CFLAGS:= \
 	-march=rv32ec \
 	-mabi=ilp32e \
 	-I/usr/include/newlib \
-	-I$(EVT) \
+	-I$(CH32V003FUN) \
 	-nostdlib \
-	-I.
+	-I. -DSTDOUT_UART
 
-LDFLAGS:=-T $(EVT)/ch32v003.ld -Wl,--gc-sections
+LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections
 
-SYSTEM_C:=$(EVT)/startup_ch32v003.c $(EVT)/embedlibc.c
+SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c
 
 $(TARGET).elf : $(SYSTEM_C) $(TARGET).c
 	$(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
@@ -35,7 +35,7 @@ $(TARGET).bin : $(TARGET).elf
 
 flash : $(TARGET).bin
 	make -C $(MINICHLINK) all
-	$(MINICHLINK)/minichlink -w $< -r
+	$(MINICHLINK)/minichlink -w $< flash -b
 
 clean :
 	rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex
diff --git a/examples/fulldemo/fulldemo.c b/examples/uartdemo/uartdemo.c
similarity index 89%
rename from examples/fulldemo/fulldemo.c
rename to examples/uartdemo/uartdemo.c
index 340da898fbe9fae936d9966bc72d90ca98a5dc51..b7e562c9c81e7666653f36a14a86f8963c7c8246 100644
--- a/examples/fulldemo/fulldemo.c
+++ b/examples/uartdemo/uartdemo.c
@@ -6,9 +6,11 @@
 #define SYSTEM_CORE_CLOCK 48000000
 #define APB_CLOCK SYSTEM_CORE_CLOCK
 
-#include "ch32v00x.h"
+#include "ch32v003fun.h"
 #include <stdio.h>
 
+uint32_t count;
+
 int main()
 {
 	SystemInit48HSI();
@@ -24,9 +26,9 @@ int main()
 	while(1)
 	{
 		GPIOD->BSHR = 1;	 // Turn on GPIOD0
-		puts( "Hello" );
 		Delay_Ms( 50 );
 		GPIOD->BSHR = 1<<16; // Turn off GPIOD0
 		Delay_Ms( 50 );
+		printf( "Count: %d\n", count++ );
 	}
 }
diff --git a/examples/ws2812demo/Makefile b/examples/ws2812demo/Makefile
index 816641bef4916ed5ac99f0b17a7a0f60e57bc614..d387c58f1a82b858685ebcb51b6f2da3ad415f23 100644
--- a/examples/ws2812demo/Makefile
+++ b/examples/ws2812demo/Makefile
@@ -4,9 +4,7 @@ all : flash
 
 PREFIX:=riscv64-unknown-elf
 
-GPIO_Toggle:=EXAM/GPIO/GPIO_Toggle/User
-
-EVT:=../../ch32v003evt
+CH32V003FUN:=../../ch32v003fun
 MINICHLINK:=../../minichlink
 
 CFLAGS:= \
@@ -15,13 +13,13 @@ CFLAGS:= \
 	-march=rv32ec \
 	-mabi=ilp32e \
 	-I/usr/include/newlib \
-	-I$(EVT) \
+	-I$(CH32V003FUN) \
 	-nostdlib \
 	-I.
 
-LDFLAGS:=-T $(EVT)/ch32v003.ld -Wl,--gc-sections
+LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections
 
-SYSTEM_C:=$(EVT)/startup_ch32v003.c $(EVT)/embedlibc.c
+SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c
 
 $(TARGET).elf : $(SYSTEM_C) $(TARGET).c
 	$(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
@@ -35,7 +33,7 @@ $(TARGET).bin : $(TARGET).elf
 
 flash : $(TARGET).bin
 	make -C $(MINICHLINK) all
-	$(MINICHLINK)/minichlink -w $< -r
+	$(MINICHLINK)/minichlink -w $< flash -b
 
 clean :
 	rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex
diff --git a/examples/ws2812demo/ws2812bdemo.c b/examples/ws2812demo/ws2812bdemo.c
index 9f2d407e895ec50f13beafbd7a0d588269c8bb6b..c2661ac5bb3f5d627af9311c51edbad9afb37276 100644
--- a/examples/ws2812demo/ws2812bdemo.c
+++ b/examples/ws2812demo/ws2812bdemo.c
@@ -2,7 +2,7 @@
 #define SYSTEM_CORE_CLOCK 48000000
 #define APB_CLOCK SYSTEM_CORE_CLOCK
 
-#include "ch32v00x.h"
+#include "ch32v003fun.h"
 #include <stdio.h>
 #include <string.h>
 
diff --git a/minichlink/minichlink.c b/minichlink/minichlink.c
index 38660ec81da27567606c8da6773b530596625631..568d12b150207a85582ed28c69207864284e0f07 100644
--- a/minichlink/minichlink.c
+++ b/minichlink/minichlink.c
@@ -107,12 +107,10 @@ keep_going:
 			case 'b': 
 				if( !MCF.HaltMode || MCF.HaltMode( dev, 1 ) )
 					goto unimplemented;
-				must_be_end = 'b';
 				break;
 			case 'e':  //rEsume
 				if( !MCF.HaltMode || MCF.HaltMode( dev, 2 ) )
 					goto unimplemented;
-				must_be_end = 'e';
 				break;
 			case 'E':  //Erase whole chip.
 				if( !MCF.Erase || MCF.Erase( dev, 0, 0, 1 ) )
@@ -120,7 +118,6 @@ keep_going:
 				break;
 			case 'h':
 				if( !MCF.HaltMode || MCF.HaltMode( dev, 0 ) )
-				must_be_end = 'h';
 				break;
 
 			// disable NRST pin (turn it into a GPIO)
@@ -136,6 +133,25 @@ keep_going:
 				else
 					goto unimplemented;
 				break;
+			case 'T':
+			{
+				if( !MCF.PollTerminal )
+					goto unimplemented;
+				do
+				{
+					uint8_t buffer[128];
+					int r = MCF.PollTerminal( dev, buffer, sizeof( buffer ) );
+					if( r < 0 )
+					{
+						fprintf( stderr, "Terminal dead.  code %d\n", r );
+						return -32;
+					}
+					if( r > 0 )
+					{
+						fwrite( buffer, r, 1, stdout ); 
+					}
+				} while( 1 );
+			}
 			// PROTECTION UNTESTED!
 			/*
 			case 'p':
@@ -195,10 +211,10 @@ keep_going:
 				else if( strcmp( fname, "+" ) == 0 )
 					f = stdout, hex = 1;
 				else
-					fopen( fname, "wb" );
+					f = fopen( fname, "wb" );
 				if( !f )
 				{
-					fprintf( stderr, "Error: can't open write file \"%s\"\n", argv[iarg] );
+					fprintf( stderr, "Error: can't open write file \"%s\"\n", fname );
 					return -9;
 				}
 				uint8_t * readbuff = malloc( amount );
@@ -309,7 +325,7 @@ keep_going:
 				uint64_t offset = StringToMemoryAddress( argv[iarg] );
 				if( offset > 0xffffffff )
 				{
-					fprintf( stderr, "Error: Invalid offset\n" );
+					fprintf( stderr, "Error: Invalid offset (%s)\n", argv[iarg] );
 					exit( -44 );
 				}
 				if( status != 1 )
@@ -323,8 +339,6 @@ keep_going:
 					exit( -9 );
 				}
 
-				printf( "%08x %08x\n", offset, len );
-
 				if( MCF.WriteBinaryBlob )
 				{
 					if( MCF.WriteBinaryBlob( dev, offset, len, image ) )
@@ -346,6 +360,9 @@ keep_going:
 		if( argchar && argchar[2] != 0 ) { argchar++; goto keep_going; }
 	}
 
+	if( MCF.FlushLLCommands )
+		MCF.FlushLLCommands( dev );
+
 	if( MCF.Exit )
 		MCF.Exit( dev );
 
@@ -372,6 +389,7 @@ help:
 	fprintf( stderr, " -r [memory address, decimal or 0x, try 0x08000000] [size, decimal or 0x, try 16384] [output binary image]\n" );
 	fprintf( stderr, "   Note: for memory addresses, you can use 'flash' 'launcher' 'bootloader' 'option' 'ram' and say \"ram+0x10\" for instance\n" );
 	fprintf( stderr, "   For filename, you can use - for raw or + for hex.\n" );
+	fprintf( stderr, " -T is a terminal. This MUST be the last argument.  You MUST have resumed or \n" );
 
 	return -1;	
 
@@ -417,10 +435,12 @@ static int64_t SimpleReadNumberInt( const char * number, int64_t defaultNumber )
 static int64_t StringToMemoryAddress( const char * number )
 {
 	uint32_t base = 0;
+
 	if( strncmp( number, "flash", 5 ) == 0 )       base = 0x08000000, number += 5;
 	if( strncmp( number, "launcher", 8 ) == 0 )    base = 0x1FFFF000, number += 8;
 	if( strncmp( number, "bootloader", 10 ) == 0 ) base = 0x1FFFF000, number += 10;
 	if( strncmp( number, "option", 6 ) == 0 )      base = 0x1FFFF800, number += 6;
+	if( strncmp( number, "user", 4 ) == 0 )        base = 0x1FFFF800, number += 4;
 	if( strncmp( number, "ram", 3 ) == 0 )         base = 0x20000000, number += 3;
 
 	if( base )
@@ -460,18 +480,22 @@ static int StaticEnterResetMode( void * dev, struct InternalState * iss, int mod
 		MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Make the debug module work properly.
 		MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Initiate a halt request.
 		MCF.WriteReg32( dev, DMCONTROL, 0x00000001 ); // Clear Halt Request.
+		MCF.FlushLLCommands( dev );
 		break;
 	case 1:
 		MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Make the debug module work properly.
 		MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Initiate a halt request.
-		MCF.WriteReg32( dev, DMCONTROL, 0x00000003 ); // Reboot.
+		MCF.WriteReg32( dev, DMCONTROL, 0x80000003 ); // Reboot.
 		MCF.WriteReg32( dev, DMCONTROL, 0x40000001 ); // resumereq
+		MCF.FlushLLCommands( dev );
+		printf( "Reboot\n" );
 		break;
 	case 2:
 		MCF.WriteReg32( dev, DMCONTROL, 0x40000001 ); // resumereq
+		MCF.FlushLLCommands( dev );
 		break;
 	}
-	iss->processor_is_in_halt = mode;
+	iss->processor_in_mode = mode;
 }
 
 int DefaultSetupInterface( void * dev )
@@ -483,8 +507,6 @@ int DefaultSetupInterface( void * dev )
 	MCF.WriteReg32( dev, DMSHDWCFGR, 0x5aa50000 | (1<<10) ); // Shadow Config Reg
 	MCF.WriteReg32( dev, DMCFGR, 0x5aa50000 | (1<<10) ); // CFGR (1<<10 == Allow output from slave)
 	MCF.WriteReg32( dev, DMCFGR, 0x5aa50000 | (1<<10) ); // Bug in silicon?  If coming out of cold boot, and we don't do our little "song and dance" this has to be called.
-	MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Make the debug module work properly.
-	MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Initiate a halt request.
 
 	// Read back chip status.  This is really baskc.
 	uint32_t reg;
@@ -535,13 +557,13 @@ static int DefaultWriteWord( void * dev, uint32_t address_to_write, uint32_t dat
 	int r;
 	int first = 0;
 
-	if( iss->processor_is_in_halt )
+	if( iss->processor_in_mode )
 	{
 		StaticEnterResetMode( dev, iss, 0 );
 	}
 
 	int is_flash = 0;
-	if( ( address_to_write & 0xff000000 ) == 0x08000000 )
+	if( ( address_to_write & 0xff000000 ) == 0x08000000 || ( address_to_write & 0x1FFFF800 ) == 0x1FFFF000 )
 	{
 		// Is flash.
 		is_flash = 1;
@@ -596,8 +618,7 @@ static int DefaultWriteWord( void * dev, uint32_t address_to_write, uint32_t dat
 		if( (rrv >> 8 ) & 7 )
 		{
 			fprintf( stderr, "Fault writing memory (DMABSTRACTS = %08x)\n", rrv );
-			rrv &= 0xfffff8ff;
-			MCF.WriteReg32( dev, DMABSTRACTCS, rrv );
+			MCF.WriteReg32( dev, DMABSTRACTCS, 0x00000700 );
 		}
 	}
 	else
@@ -646,7 +667,7 @@ int DefaultWriteBinaryBlob( void * dev, uint32_t address_to_write, uint32_t blob
 
 	if( blob_size == 0 ) return 0;
 
-	if( iss->processor_is_in_halt )
+	if( iss->processor_in_mode )
 	{
 		StaticEnterResetMode( dev, iss, 0 );
 	}
@@ -739,7 +760,7 @@ static int DefaultReadWord( void * dev, uint32_t address_to_read, uint32_t * dat
 	int r;
 	int first = 0;
 
-	if( iss->processor_is_in_halt )
+	if( iss->processor_in_mode )
 	{
 		StaticEnterResetMode( dev, iss, 0 );
 	}
@@ -820,7 +841,7 @@ int DefaultErase( void * dev, uint32_t address, uint32_t length, int type )
 	uint32_t rw;
 	uint32_t timeout = 0;
 
-	if( iss->processor_is_in_halt )
+	if( iss->processor_in_mode )
 	{
 		StaticEnterResetMode( dev, iss, 0 );
 	}
@@ -872,7 +893,7 @@ int DefaultReadBinaryBlob( void * dev, uint32_t address_to_read_from, uint32_t r
 {
 	struct InternalState * iss = (struct InternalState*)(((struct ProgrammerStructBase*)dev)->internal);
 
-	if( iss->processor_is_in_halt )
+	if( iss->processor_in_mode )
 	{
 		StaticEnterResetMode( dev, iss, 0 );
 	}
@@ -900,6 +921,50 @@ static int DefaultHaltMode( void * dev, int mode )
 	return 0;
 }
 
+// Returns positive if received text.
+// Returns negative if error.
+// Returns 0 if no text waiting.
+// maxlen MUST be at least 8 characters.  We null terminate.
+int DefaultPollTerminal( void * dev, uint8_t * buffer, int maxlen )
+{
+	int r;
+	uint32_t rr;
+	r = MCF.ReadReg32( dev, DMDATA0, &rr );
+	if( r < 0 ) return r;
+
+	if( maxlen < 8 ) return -9;
+
+	// DMDATA1:
+	//  bits 0..5 = # printf chars.
+	//  bit  6 = host-wants-to-say-something.
+	//  bit  7 = host-acknowledge.
+	if( rr & 0x80 )
+	{
+		int ret = 0;
+		int num_printf_chars = (rr & 0x3f)-4;  // Actaully can't be more than 32.
+		if( num_printf_chars > 0 && num_printf_chars <= 7)
+		{
+			if( num_printf_chars > 3 )
+			{
+				uint32_t r2;
+				r = MCF.ReadReg32( dev, DMDATA1, &r2 );
+				memcpy( buffer+4, &r2, num_printf_chars - 3 );
+			}
+			int firstrem = num_printf_chars;
+			if( firstrem > 3 ) firstrem = 3;
+			memcpy( buffer, ((uint8_t*)&rr)+1, firstrem );
+			buffer[num_printf_chars] = 0;
+			ret = num_printf_chars;
+		}
+		MCF.WriteReg32( dev, DMDATA0, 0x00 ); // Write that we acknowledge the data.
+		return ret;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
 int SetupAutomaticHighLevelFunctions( void * dev )
 {
 	// Will populate high-level functions from low-level functions.
@@ -922,6 +987,9 @@ int SetupAutomaticHighLevelFunctions( void * dev )
 		MCF.Erase = DefaultErase;
 	if( !MCF.HaltMode )
 		MCF.HaltMode = DefaultHaltMode;
+	if( !MCF.PollTerminal )
+		MCF.PollTerminal = DefaultPollTerminal;
+
 
 	struct InternalState * iss = malloc( sizeof( struct InternalState ) );
 	iss->statetag = 0;
diff --git a/minichlink/minichlink.h b/minichlink/minichlink.h
index 93e7f068e7460c681bfb508e117a880236bf8bd9..bd329fda3f5538cc694e5d1d77a344fc1a9523e2 100644
--- a/minichlink/minichlink.h
+++ b/minichlink/minichlink.h
@@ -38,6 +38,11 @@ struct MiniChlinkFunctions
 	// TODO: What about 64-byte block-reads?
 	// TODO: What about byte read/write?
 	// TODO: What about half read/write?
+
+	// Returns positive if received text.
+	// Returns negative if error.
+	// Returns 0 if no text waiting.
+	int (*PollTerminal)( void * dev, uint8_t * buffer, int maxlen );
 };
 
 /** If you are writing a driver, the minimal number of functions you can implement are:
@@ -61,7 +66,7 @@ struct InternalState
 	uint32_t currentstateval;
 	uint32_t flash_unlocked;
 	int lastwriteflags;
-	int processor_is_in_halt;
+	int processor_in_mode;
 };