diff -ur brickos-0.9.0/boot/config.h brickos-0.9.0-fast/boot/config.h
--- boot/config.h	2004-01-25 05:33:45.000000000 +0100
+++ boot/config.h	2008-08-19 00:38:41.000000000 +0200
@@ -75,6 +75,7 @@
 #define CONF_DMOTOR                     //!< direct motor
 // #define CONF_DMOTOR_HOLD               //!< experimental: use hold mode PWM instead of coast mode.
 #define CONF_DSENSOR                    //!< direct sensor
+#define CONF_DSENSOR_FAST               //!< poll all sensors in 1 ms
 #define CONF_DSENSOR_ROTATION           //!< rotation sensor
 //#define CONF_DSENSOR_VELOCITY           //!< rotation sensor velocity
 //#define CONF_DSENSOR_MUX                //!< sensor multiplexor
diff -ur brickos-0.9.0/ChangeLog brickos-0.9.0-fast/ChangeLog
--- ChangeLog	2005-01-18 04:34:41.000000000 +0100
+++ ChangeLog	2008-08-19 00:38:41.000000000 +0200
@@ -1,3 +1,30 @@
+2006-06-26  Jochen Hoenicke  <hoenicke@users.sourceforge.net>
+
+  * Added option CONF_DSENSOR_FAST:
+    Poll all four sensor every ms.  The timer interrupt triggers
+    polling of the first sensor (starting with sensor 3).  While a
+    sensor is polled, the next sensor is deactivated, so the settling
+    time is the time to poll one sensor.
+
+    This allows the rotation sensor to detect up to 500 pulses per
+    millisecond.
+
+  * Don't poll the sensors the whole time.  This did in fact use
+    66 % computation time.
+
+2004-08-17  Jochen Hoenicke  <hoenicke@users.sourceforge.net>
+
+  * Reworked timer interrupts:
+    Watchdog timer is now free for other (user defined) purposes.
+    OCRA fires every 1 msec again, OCRB fires shortly after.
+    OCRA increases sys_time, turns off active sensors for polling
+    OCRB starts polling and calls sub-system handlers.
+    All times were multiplied by 2 again since handler is now called
+    every msec.
+
+  * Don't poll the sensors the whole time.  This did in fact use
+    66 % computation time.
+
 2005-01-17  Stephen M Moraco <stephmo@users.sourceforge.net>
 
   * Releasing current state as 0.9.0 - coincident with a
diff -ur brickos-0.9.0/include/dsound.h brickos-0.9.0-fast/include/dsound.h
--- include/dsound.h	2004-01-04 01:32:27.000000000 +0100
+++ include/dsound.h	2008-08-19 00:38:41.000000000 +0200
@@ -217,7 +217,7 @@
 extern unsigned dsound_16th_ms;   	      	 //!< length of 1/16 note in ms
 extern unsigned dsound_internote_ms;  	      	 //!< length of internote spacing in ms
 extern volatile note_t *dsound_next_note;     	 //!< pointer to current note
-extern volatile time_t dsound_next_time;      	 //!< when to play next note
+extern volatile unsigned dsound_next_time;     	 //!< when to play next note
 
 extern const note_t *dsound_system_sounds[];  	 //!< system sound data
 
@@ -233,7 +233,7 @@
 //! play a sequence of notes
 static inline void dsound_play(const note_t *notes) {
   dsound_next_note=(volatile note_t*) notes;
-  dsound_next_time=0;
+  dsound_next_time=1;
 }
 
 //! play a system sound
diff -ur brickos-0.9.0/include/lnp/sys/lnp-logical.h brickos-0.9.0-fast/include/lnp/sys/lnp-logical.h
--- include/lnp/sys/lnp-logical.h	2002-10-12 05:22:26.000000000 +0200
+++ include/lnp/sys/lnp-logical.h	2008-08-19 00:38:41.000000000 +0200
@@ -56,7 +56,7 @@
 #define LNP_BYTE_TIME           MSECS_TO_TICKS(5) //!< time to transmit a byte
 #endif
 
-#define LNP_BYTE_TIMEOUT        (3*LNP_BYTE_TIME/2) //!< timeout waiting for a byte
+#define LNP_BYTE_TIMEOUT        (3*LNP_BYTE_TIME) //!< timeout waiting for a byte
 #define LNP_BYTE_SAFE       (4*LNP_BYTE_TIME) //!< delay before transmitting a byte
 
 #define LNP_WAIT_TXOK       (2*LNP_BYTE_TIMEOUT) //!< delay after good transmit
diff -ur brickos-0.9.0/kernel/battery.c brickos-0.9.0-fast/kernel/battery.c
--- kernel/battery.c	2002-09-16 07:44:19.000000000 +0200
+++ kernel/battery.c	2008-08-19 00:38:41.000000000 +0200
@@ -35,10 +35,12 @@
 // Global Variables
 //
 ///////////////////////////////////////////////////////////////////////
+#ifndef CONF_VIS
 #ifdef CONF_BATTERY_INDICATOR
 unsigned int battery_refresh_counter = 0; //!< counter for lcd refresh in ms
 unsigned int battery_refresh_period  = 2000;  //!< LCD refresh period in ms
 #endif
+#endif
 
 ///////////////////////////////////////////////////////////////////////
 //
@@ -55,22 +57,20 @@
 }
 #endif // CONF_DSENSOR
 
+#ifndef CONF_VIS
 #ifdef CONF_BATTERY_INDICATOR
 // battery indicator handed by kernel task when CONF_TM
 #ifndef CONF_TM
 //! battery indicator handler, called from system timer interrupt
-#ifdef CONF_RCX_COMPILER
 void battery_refresh(void) {
-#else // CONF_RCX_COMPILER
-HANDLER_WRAPPER("battery_refresh","battery_refresh_core");
-void battery_refresh_core(void) {
-#endif // CONF_RCX_COMPILER
-    int bmv = get_battery_mv();
-
-    if (bmv > BATTERY_NORMAL_THRESHOLD_MV)
-  dlcd_hide(LCD_BATTERY_X);
-    else if (bmv > BATTERY_LOW_THRESHOLD_MV)
-  dlcd_show(LCD_BATTERY_X);
+  int bmv = get_battery_mv();
+  
+  if (bmv > BATTERY_NORMAL_THRESHOLD_MV)
+    dlcd_hide(LCD_BATTERY_X);
+  else if (bmv > BATTERY_LOW_THRESHOLD_MV)
+    dlcd_show(LCD_BATTERY_X);
+  battery_refresh_counter = battery_refresh_period;
 }
 #endif // CONF_TM
 #endif // CONF_BATTERY_INDICATOR
+#endif // !CONF_VIS
diff -ur brickos-0.9.0/kernel/conio.c brickos-0.9.0-fast/kernel/conio.c
--- kernel/conio.c	2004-01-02 11:52:32.000000000 +0100
+++ kernel/conio.c	2008-08-19 00:38:41.000000000 +0200
@@ -201,15 +201,24 @@
 //! uncalibrated delay loop
 /*! \param ms approximate time in ms
  */
-void delay(unsigned ms)
-{
-  unsigned i;
+extern void delay(unsigned ms);
 
-  while (ms-- > 0)
-    for (i = 0; i < 600; i++)	// not well calibrated.
-      ;
-
-}
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+__asm__("\n\
+.text\n\
+.align 1\n\
+.global _delay\n\
+\n\
+_delay:\n\
+1:	mov.w #614, r1\n\
+2:	subs  #1, r1\n\
+	mov.w r1, r1\n\
+	bne   2b\n\
+	subs  #1, r0\n\
+	mov.w r0, r0\n\
+	bne   1b\n\
+	rts\n");
+#endif
 
 #ifdef CONF_CONIO
 
diff -ur brickos-0.9.0/kernel/dsensor.c brickos-0.9.0-fast/kernel/dsensor.c
--- kernel/dsensor.c	2004-01-09 02:44:56.000000000 +0100
+++ kernel/dsensor.c	2008-08-20 18:36:23.000000000 +0200
@@ -538,38 +538,24 @@
         "\n\
    inc r6l			; next channel\n\
    and #0x03,r6l		; limit to 0-3\n\
-\n\
-   mov.b @_ds_activation,r6h	; r6h = activation bitmask\n\
-   btst r6l,r6h			; activate output?\n\
-   beq ds_nounset\n\
-      bclr r6l,@_PORT6:8		; set output inactive for reading\n\
- ds_nounset:\n\
-\n\
-   ; The settle time for reading the value from active sensor start here\n\
-\n\
-   ; moved here for helping timing problems\n\
-   mov.b r6l,@_ds_channel	; store next channel\n\
-\n\
-   ; Added a delay loop for sensor settle time\n\
-\n\
-   mov.b #0x04, r6h		; delay loop\n\
-settle:\n\
-   nop				; each nop is a 2 state clock delay\n\
-   dec.b r6h			; 2 states ?\n\
-   bne settle			; 4 states\n\
-\n\
-   ; Total loop delay 32 states (?)\n\
-\n\
-   mov.b @_AD_CSR:8,r6h		; r6h = A/D CSR\n\
-   and.b #0x7c,r6h		; reset scanmode and channel num\n\
-   or.b  r6l,r6h		; scan next channel\n\
-   mov.b r6h,@_AD_CSR:8		; put r6h back on A/D CSR\n\
-\n\
-   ; The settle time for reading the value from active sensor finish here\n\
-\n\
-   bset #0x5,@_AD_CSR:8		; go!\n\
-\n\
-   rts\n\
+   mov.b r6l, @_ds_channel	; save channel\n\
+	mov.b @_AD_CSR:8,r6h		; r6h = A/D CSR\n\
+	and.b #0x7c,r6h		; reset interrupt flag and channel num\n\
+	or.b  r6l,r6h		; scan next channel\n\
+	mov.b r6h,@_AD_CSR:8		; put r6h back on A/D CSR\n\
+\n"
+#ifdef CONF_DSENSOR_FAST
+	"\n\
+        inc r6l\n\
+        cmp #3, r6l\n\
+        bhi ds_finished         ; we polled all 4 channels\n\
+        beq ds_nounset          ; no need to deactivate channel #3 (battery)\n\
+        bclr r6l,@_PORT6:8      ; deactivate next channel\n\
+ds_nounset:\n\
+        bset #5,@_AD_CSR:8      ; start polling this channel \n\
+ds_finished:\n"
+#endif
+"   rts\n\
 ");
 #endif // DOXYGEN_SHOULD_SKIP_THIS
 
@@ -597,12 +583,6 @@
   AD_CR &=~ADCR_EXTERN;
   AD_CSR =ADCSR_TIME_266 | ADCSR_GROUP_0 | ADCSR_AN_0  |
           ADCSR_ENABLE_IRQ | ADCSR_START;
-
-#ifdef CONF_CONIO
-    delay(10);				// wait for initial A/D
-#else
-# warning "Rotation initialization might fail."
-#endif
 }
 
 
diff -ur brickos-0.9.0/kernel/dsound.c brickos-0.9.0-fast/kernel/dsound.c
--- kernel/dsound.c	2004-01-04 01:32:27.000000000 +0100
+++ kernel/dsound.c	2008-08-19 00:38:41.000000000 +0200
@@ -73,7 +73,7 @@
 unsigned dsound_16th_ms;   	      	      	//!< length of 1/16 note in ms
 unsigned dsound_internote_ms; 		      	//!< length of internote spacing in ms
 volatile note_t *dsound_next_note;     	      	//!< pointer to current note
-volatile time_t dsound_next_time;      	      	//!< when to play next note
+volatile unsigned dsound_next_time;    	      	//!< when to play next note
 
 static volatile int internote; 	      	      	//!< internote delay flag
 
@@ -119,42 +119,32 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 //! sound handler, called from system timer interrupt
-#ifdef CONF_RCX_COMPILER
 void dsound_handler(void) {
-#else
-HANDLER_WRAPPER("dsound_handler","dsound_core");
-//! sound core, called from ????
-void dsound_core(void) {
-#endif
-  if (get_system_up_time() >= dsound_next_time) {
+  if(internote && dsound_internote_ms) {
+    play_pause();
+    dsound_next_time = dsound_internote_ms;
+    
+    internote=0;
+    return;
+  }
+
+  if(dsound_next_note) {
+    unsigned char pitch =dsound_next_note->pitch;
     
-    if(internote) {
-      play_pause();
-      dsound_next_time = get_system_up_time() + dsound_internote_ms;
+    if(pitch<PITCH_MAX) {
+      if(pitch!=PITCH_PAUSE)
+	play_freq(pitch2freq[pitch]);
+      else
+	play_pause();
       
-      internote=0;
+      dsound_next_time = dsound_16th_ms * dsound_next_note->length
+	- dsound_internote_ms;
+      dsound_next_note++;
+      internote=1;
       return;
-    } 
-         
-    if(dsound_next_note) {
-      unsigned char pitch =dsound_next_note->pitch;
-      
-      if(pitch<PITCH_MAX) {
-	if(pitch!=PITCH_PAUSE)
-  	  play_freq(pitch2freq[pitch]);
-	else
-	  play_pause();
-	
-	dsound_next_time = get_system_up_time() + dsound_16th_ms * dsound_next_note->length
-	                          - dsound_internote_ms;
-	dsound_next_note++;
-	internote=1;
-	return;
-      }
     }
-    
-    dsound_stop();
-  }  
+  }
+  dsound_stop();
 }
 
 //! initialize sound driver
@@ -181,7 +171,7 @@
 void dsound_stop(void) {
   play_pause();
   dsound_next_note=0;  
-  dsound_next_time=0xffffffff;
+  dsound_next_time=0xffff;
   internote=0;
 }
 
diff -ur brickos-0.9.0/kernel/kmain.c brickos-0.9.0-fast/kernel/kmain.c
--- kernel/kmain.c	2004-01-09 02:44:56.000000000 +0100
+++ kernel/kmain.c	2008-08-19 00:38:41.000000000 +0200
@@ -55,7 +55,7 @@
 //! firmware recognition string
 /*! the ROM checks for this string when validating new firmware
  */
-unsigned char *firmware_string = "Do you byte, when I knock?";
+const unsigned char *firmware_string = "Do you byte, when I knock?";
 
 extern char __bss;		//!< the start of the uninitialized data segment
 extern char __bss_end;	//!< the end of the uninitialized data segment
@@ -176,9 +176,6 @@
 #ifdef CONF_DSOUND
     dsound_init();
 #endif
-#ifdef CONF_TIME
-    systime_init();
-#endif
 #ifdef CONF_DSENSOR
     ds_init();
 #endif
@@ -189,6 +186,9 @@
     lnp_init();
     lnp_logical_init();
 #endif
+#ifdef CONF_TIME
+    systime_init();
+#endif
 #ifdef CONF_TM
     tm_init();
 #endif
diff -ur brickos-0.9.0/kernel/lcd.c brickos-0.9.0-fast/kernel/lcd.c
--- kernel/lcd.c	2004-01-09 02:44:56.000000000 +0100
+++ kernel/lcd.c	2008-08-19 00:38:41.000000000 +0200
@@ -39,9 +39,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #ifdef CONF_LCD_REFRESH
-unsigned char lcd_refresh_counter;    //!< counter for lcd refresh in ms
-unsigned char lcd_byte_counter;       //!< LCD byte to refresh
-unsigned char lcd_refresh_period = 2; //!< LCD refresh period in ms
+unsigned char lcd_refresh_counter = 1; //!< counter for lcd refresh in ms
+unsigned char lcd_byte_counter;        //!< LCD byte to refresh
+unsigned char lcd_refresh_period = 6;  //!< LCD refresh period in ms
 #endif
 
 //! lcd_shadow buffer:
@@ -219,18 +219,10 @@
     resulting in a complete LCD update every 54ms, which is a
     refresh rate of 18 updates per second.
 */
-#ifdef CONF_RCX_COMPILER
 void lcd_refresh_next_byte(void)
-#else
-HANDLER_WRAPPER("lcd_refresh_next_byte", "lcd_refresh_next_byte_core");
-//! alternate name for the refresh next byte routine
-/*! \todo find a better description for this
-*/
-void lcd_refresh_next_byte_core(void)
-#endif
 {
     unsigned char byte;
-
+    lcd_refresh_counter = lcd_refresh_period;
     byte = lcd_byte_counter++;
     if (lcd_byte_counter >= LCD_DATA_SIZE)
         lcd_byte_counter = 0;
diff -ur brickos-0.9.0/kernel/lnp.c brickos-0.9.0-fast/kernel/lnp.c
--- kernel/lnp.c	2004-01-02 13:27:40.000000000 +0100
+++ kernel/lnp.c	2008-08-19 00:38:41.000000000 +0200
@@ -441,12 +441,7 @@
 }
 
 //! reset the integrity layer on error or timeout.
-#if defined(CONF_RCX_COMPILER) || defined(CONF_HOST)
 void lnp_integrity_reset(void) {
-#else
-HANDLER_WRAPPER("lnp_integrity_reset","lnp_integrity_reset_core");
-void lnp_integrity_reset_core(void) {
-#endif
 #ifndef CONF_HOST
   if(tx_state>TX_IDLE) {
     txend_handler();
@@ -464,6 +459,7 @@
 #endif
 #endif
   }
+  lnp_timeout_counter = lnp_timeout; /* reset timeout */
 }
 
 //! return whether a packet is currently being received
diff -ur brickos-0.9.0/kernel/systime.c brickos-0.9.0-fast/kernel/systime.c
--- kernel/systime.c	2004-01-09 02:44:56.000000000 +0100
+++ kernel/systime.c	2008-08-20 19:40:50.000000000 +0200
@@ -82,183 +82,201 @@
 //
 ///////////////////////////////////////////////////////////////////////////////
 
-//! clock handler triggered on the WDT overflow (every msec) on the NMI
-/*! this is the system clock
- */
-extern void clock_handler(void);
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-__asm__("\n\
-.text\n\
-.align 1\n\
-.global _clock_handler\n\
-        _clock_handler:\n\
-                mov.w #0x5a07,r6                ; reset wd timer to 6\n\
-                mov.w r6,@0xffa8\n\
-\n\
-                mov.w @_sys_time+2,r6           ; lower 8 bits\n\
-                add.b #0x1,r6l                  ; inc lower 4 bits\n\
-                addx  #0x0,r6h                  ; add carry to top 4 bits\n\
-                mov.w r6,@_sys_time+2\n\
-                bcc sys_nohigh                  ; if carry, inc upper 8 bits\n\
-                  mov.w @_sys_time,r6           ; \n\
-                  add.b #0x1,r6l                ; inc lower 4 bits\n\
-                  addx  #0x0,r6h                ; add carry to top 4 bits\n\
-                  mov.w r6,@_sys_time\n\
-              sys_nohigh: \n\
-                rts\n\
-       ");
-#endif // DOXYGEN_SHOULD_SKIP_THIS
 
-//! subsystem handler for every 2nd msec
+//! subsystem handler for every msec
 /*! this is the pulse of the system (subsystems).
+    It just increases sys_time and turns off active sensors to
+    settle down.  The remaining functions are done in secondary
+    handler.
+*/
+extern void subsystem_handler(void);
+//! subsystem handler for every msec
+/*! this is the other part of the pulse of the system.
     sound, motor and lcd driver calls are initiated here.
     task_switch_handler is called from here as well.
 */
-extern void subsystem_handler(void);
+extern void secondary_handler(void);
 
-//! task switch handler called every msec
-/*! handles swapping between tasks
- */
-extern void task_switch_handler(void);
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 __asm__("\n\
 .text\n\
 .align 1\n\
 .global _subsystem_handler\n\
-.global _task_switch_handler\n\
+.global _secondary_handler\n\
 .global _systime_tm_return\n\
+\n\
 _subsystem_handler:\n\
-               ; r6 saved by ROM\n\
+	; r6 saved by ROM\n\
 \n\
-                push r0                         ; both motors & task\n\
-                                                ; switcher need this reg.\n\
-        "
-
+	mov.w @_sys_time+2,r6           ; lower 16 bits\n\
+	adds  #1,r6                     ; inc lower 16 bits\n\
+	mov.w r6,@_sys_time+2\n\
+	bne   sys_nohigh                ; if carry, inc upper 8 bits\n\
+	mov.w @_sys_time,r6             ; \n\
+	adds  #1,r6                     ; inc upper 16 bits\n\
+	mov.w r6,@_sys_time\n\
+sys_nohigh: \n\
+\n"
+#if defined(CONF_DSENSOR) && !defined(CONF_DSENSOR_FAST)
+"	; disable active sensor so it can be read.\n\
+	mov.b @_ds_channel,r6l	; r6l = current channel\n\
+	bclr r6l,@_PORT6:8		; set output inactive for reading\n\
+	; the actual reading is startet in secondary_handler\n\
+	; this allows the sensor to settle\n\
+	bclr  #3,@0x91:8                ; reset compare A IRQ flag\n\
+	rts\n\n\
+	\n\
+.text\n\
+.align 1\n"
+#else
+"	bclr  #3,@0x91:8                ; reset compare A IRQ flag\n"
+#endif
+".global _secondary_handler\n\
+\n\
+_secondary_handler:\n\
+\n"
+#if defined(CONF_DSENSOR) && !defined(CONF_DSENSOR_FAST)
+"	; The settle time for reading the value from active sensor\n\
+	; finish here.  Now start sampling the sensor.\n\
+\n\
+	;\n\
+	mov.b @_ds_channel,r6l	; r6l = current channel\n\
+\n\
+	bset #0x5,@_AD_CSR:8		; go!\n"
+#endif
+"\n\
+	push r0                         ; this reg isn't saved by rom\n\
+	push r1                         ; this reg isn't saved by rom\n\
+	push r2                         ; this reg isn't saved by rom\n\
+	push r3                         ; this reg isn't saved by rom\n\
+"
 #ifdef CONF_DSOUND
         "\n\
-                jsr _dsound_handler             ; call sound handler\n\
-        "
+	mov.w @_dsound_next_time,r6     ; check sound timeout counter\n\
+        subs  #1,r6\n\
+        mov.w r6,@_dsound_next_time\n\
+	bne sys_nosound\n\
+\n\
+	jsr _dsound_handler             ; call sound handler\n\
+sys_nosound:\n"
 #endif // CONF_DSOUND
 
 #ifdef CONF_LNP
         "\n\
-                mov.w @_lnp_timeout_counter,r6  ; check LNP timeout counter\n\
-                subs #0x1,r6\n\
-                mov.w r6,r6                     ; subs doesn't change flags!\n\
-                bne sys_noreset\n\
-                \n\
-                  jsr _lnp_integrity_reset\n\
-                  mov.w @_lnp_timeout,r6        ; reset timeout\n\
+	mov.w @_lnp_timeout_counter,r6  ; check LNP timeout counter\n\
+	subs #0x1,r6\n\
+	mov.w r6,@_lnp_timeout_counter\n\
+	bne sys_noreset\n\
 \n\
-              sys_noreset:\n\
-                mov.w r6,@_lnp_timeout_counter\n\
-        "
+	jsr _lnp_integrity_reset\n\
+\n\
+sys_noreset:\n"
 #endif // CONF_LNP
 
 #ifdef CONF_DKEY
         "\n\
-                jsr _dkey_handler\n\
-        "
+	jsr _dkey_handler\n"
 #endif // CONF_DKEY
 
 #ifndef CONF_TM
+#ifndef CONF_VIS
 #ifdef CONF_BATTERY_INDICATOR
         "\n\
-                mov.w @_battery_refresh_counter,r6\n\
-                subs #0x1,r6\n\
-                bne batt_norefresh\n\
+	mov.w @_battery_refresh_counter,r6\n\
+	subs #0x1,r6\n\
+	mov.w r6,@_battery_refresh_counter\n\
+	bne batt_norefresh\n\
 \n\
-                  jsr _battery_refresh\n\
-                  mov.w @_battery_refresh_period,r6\n\
+	jsr _battery_refresh\n\
 \n\
-              batt_norefresh:\n\
-                mov.w r6,@_battery_refresh_counter\n\
-        "
+batt_norefresh:\n"
 #endif // CONF_BATTERY_INDICATOR
-#endif // CONF_TM
+#endif // !CONF_VIS
+#endif // !CONF_TM
 
 #ifdef CONF_AUTOSHUTOFF
         "\n\
-                mov.w @_auto_shutoff_counter,r6\n\
-                subs  #0x1,r6\n\
-                bne auto_notshutoff\n\
-\n\
-                  jsr _autoshutoff_check\n\
-                  mov.w @_auto_shutoff_period,r6\n\
-                  \n\
-              auto_notshutoff:\n\
-                  mov.w r6,@_auto_shutoff_counter\n\
+	mov.w @_auto_shutoff_counter,r6\n\
+	subs  #0x1,r6\n\
+	mov.w r6,@_auto_shutoff_counter\n\
+	bne auto_notshutoff\n\
+\n\
+	jsr _autoshutoff_check\n\
+\n\
+auto_notshutoff:\n\
         "
 #endif // CONF_AUTOSHUTOFF
 
 #ifdef CONF_VIS
         "\n\
-                mov.b @_vis_refresh_counter,r6l\n\
-                dec r6l\n\
-                bne vis_norefresh\n\
-                \n\
-                  jsr _vis_handler\n\
-                  mov.b @_vis_refresh_period,r6l\n\
-                  \n\
-              vis_norefresh:\n\
-                mov.b r6l,@_vis_refresh_counter\n\
-        "
+	mov.b @_vis_refresh_counter,r6l\n\
+	dec r6l\n\
+	mov.b r6l,@_vis_refresh_counter\n\
+	bne vis_norefresh\n\
+\n\
+	jsr _vis_handler\n\
+\n\
+vis_norefresh:\n"
 #endif // CONF_VIS
 
 #ifdef CONF_LCD_REFRESH
         "\n\
-                mov.b @_lcd_refresh_counter,r6l\n\
-                dec r6l\n\
-                bne lcd_norefresh\n\
-                \n\
-                  jsr _lcd_refresh_next_byte\n\
-                  mov.b @_lcd_refresh_period,r6l\n\
-                  \n\
-              lcd_norefresh:\n\
-                mov.b r6l,@_lcd_refresh_counter\n\
+	mov.b @_lcd_refresh_counter,r6l\n\
+	dec r6l\n\
+	mov.b r6l,@_lcd_refresh_counter\n\
+	bne lcd_norefresh\n\
+\n\
+	jsr _lcd_refresh_next_byte\n\
+	\n\
+lcd_norefresh:\n\
         "
 #endif // CONF_LCD_REFRESH
-        "\n\
-                bclr  #2,@0x91:8                ; reset compare B IRQ flag\n\
-        "
+
+#ifdef CONF_DSENSOR_FAST
+"	; Start sampling the third sensor and set zeroth inactive.\n\
+\n\
+	;\n\
+	bclr #0x0,@_PORT6:8		; set output 0 inactive for reading\n\
+	bset #0x5,@_AD_CSR:8		; poll third sensor!\n"
+#endif
+
 #ifdef CONF_TM
         "\n\
-                pop r0                          ; if fallthrough, pop r0\n\
-              _task_switch_handler:\n\
-                push r0                         ; save r0\n\
-\n\
-                mov.b @_tm_current_slice,r6l\n\
-                dec r6l\n\
-                bne sys_noswitch                ; timeslice elapsed?\n\
-\n\
-                  mov.w @_kernel_critsec_count,r6 ; check critical section\n\
-                  beq sys_switch                ; ok to switch\n\
-                  mov.b #1,r6l                  ; wait another tick\n\
-                  jmp sys_noswitch              ; don't switch\n\
-\n\
-                sys_switch:\n\
-                  mov.w @_tm_switcher_vector,r6\n\
-                  jsr @r6                       ; call task switcher\n\
-                  \n\
-              _systime_tm_return:\n\
-                mov.b @_tm_timeslice,r6l        ; new timeslice\n\
+	mov.b @_tm_current_slice,r6l\n\
+	dec r6l\n\
+	bne sys_noswitch                ; timeslice elapsed?\n\
+\n\
+	mov.w @_kernel_critsec_count,r6 ; check critical section\n\
+	beq sys_switch                ; ok to switch\n\
+	mov.b #1,r6l                  ; wait another tick\n\
+	jmp sys_noswitch              ; don't switch\n\
+\n\
+sys_switch:\n\
+	mov.w @_tm_switcher_vector,r6\n\
+	jsr @r6                       ; call task switcher\n\
 \n\
-              sys_noswitch:\n\
-                mov.b r6l,@_tm_current_slice\n\
-        "
+_systime_tm_return:\n\
+	mov.b @_tm_timeslice,r6l        ; new timeslice\n\
+\n\
+sys_noswitch:\n\
+	mov.b r6l,@_tm_current_slice\n"
 #endif // CONF_TM
 
 #ifdef CONF_DMOTOR
         "\n\
-                jsr _dm_handler                 ; call motor driver\n\
-        "
+	jsr _dm_handler                 ; call motor driver\n"
 #endif // CONF_DMOTOR
 
         "\n\
-                pop r0\n\
-                bclr  #3,@0x91:8                ; reset compare A IRQ flag\n\
-                rts\n\
-        "
+	pop r3\n\
+	pop r2\n\
+	pop r1\n\
+	pop r0\n\
+\n"
+#ifndef CONF_DSENSOR_FAST
+"	bclr  #2,@0x91:8                ; reset compare B IRQ flag\n"
+#endif
+"	rts\n"
 );
 #endif // DOXYGEN_SHOULD_SKIP_THIS
 
@@ -277,38 +295,40 @@
   tm_switcher_vector=&rom_dummy_handler;        // empty handler
 #endif
 
-#ifdef CONF_DMOTOR
-  dm_shutdown();
-#endif
-
+#if defined(CONF_DSENSOR) && !defined(CONF_DSENSOR_FAST)
   // configure 16-bit timer
-  // compare B IRQ will fire after one msec
-  // compare A IRQ will fire after another msec
+  // compare B IRQ will fire after   10 usec
+  // compare A IRQ will fire after 1000 usec
   // counter is then reset
   //
   T_CSR  = TCSR_RESET_ON_A;
   T_CR   = TCR_CLOCK_32;
-  T_OCR &= ~TOCR_OCRB;
-  T_OCRA = 1000;
-  T_OCR &= ~TOCR_OCRA;
-  T_OCR |= TOCR_OCRB; 
-  T_OCRB = 500;
-
-#if defined(CONF_TM)
-  ocia_vector = &task_switch_handler;
-#else // CONF_TM
+  T_OCR &= ~TOCR_OCRB;  /* select register A */
+  T_OCRA = 500;
+  T_OCR |= TOCR_OCRB;   /* select register B */
+  T_OCRB =   5;
+  T_CNT  =   6;
+  T_CSR &= ~TCSR_OCA;
+  T_CSR &= ~TCSR_OCB;
+
   ocia_vector = &subsystem_handler;
-#endif // CONF_TM
-  ocib_vector = &subsystem_handler;
+  ocib_vector = &secondary_handler;
   T_IER |= (TIER_ENABLE_OCB | TIER_ENABLE_OCA);
+#else
+  // configure 16-bit timer
+  // compare A IRQ will fire after 1000 usec
+  // counter is then reset
+  //
+  T_CSR  = TCSR_RESET_ON_A;
+  T_CR   = TCR_CLOCK_32;
+  T_OCR &= ~TOCR_OCRB;  /* select register A */
+  T_OCRA = 500;
+  T_CNT  =   1;
+  T_CSR &= ~TCSR_OCA;
 
-  nmi_vector = &clock_handler;
-  WDT_CSR = WDT_CNT_PASSWORD | WDT_CNT_MSEC_64;   // trigger every msec 
-  WDT_CSR = WDT_CSR_PASSWORD
-        | WDT_CSR_CLOCK_64
-	| WDT_CSR_WATCHDOG_NMI
-        | WDT_CSR_ENABLE
-        | WDT_CSR_MODE_WATCHDOG; 
+  ocia_vector = &subsystem_handler;
+  T_IER |= (TIER_ENABLE_OCA);
+#endif
 }
 
 //! shutdown system timer
diff -ur brickos-0.9.0/kernel/timeout.c brickos-0.9.0-fast/kernel/timeout.c
--- kernel/timeout.c	2002-10-12 05:22:26.000000000 +0200
+++ kernel/timeout.c	2008-08-19 00:38:41.000000000 +0200
@@ -29,8 +29,8 @@
 #include <sys/timeout.h>
 
 #ifdef CONF_AUTOSHUTOFF
-volatile unsigned int auto_shutoff_counter = 0;   //<! current count - used by the system timer
-unsigned int auto_shutoff_period = 500;  //<! milliseconds between shutoff checks
+volatile unsigned int auto_shutoff_counter = 1;   //<! current count - used by the system timer
+unsigned int auto_shutoff_period = 1000;  //<! milliseconds between shutoff checks
 unsigned int auto_shutoff_secs = DEFAULT_SHUTOFF_TIME;  //<! seconds of idle to auto shutoff
 volatile unsigned int auto_shutoff_elapsed = 0;   //<! idle seconds elapsed
 volatile unsigned int idle_powerdown = 0;   //<! true if a auto-shutoff should occur
@@ -46,12 +46,7 @@
   idle_powerdown = 0;
 }
 
-#ifdef CONF_RCX_COMPILER
 void autoshutoff_check(void) {
-#else
-HANDLER_WRAPPER("autoshutoff_check","autoshutoff_check_core");
-void autoshutoff_check_core(void) {
-#endif
 #ifdef CONF_TM
   if (nb_tasks <= nb_system_tasks) {
 #endif // CONF_TM
@@ -60,9 +55,10 @@
       idle_powerdown = 1;
 #ifdef CONF_TM
   }
-   else
+  else
     shutoff_restart();
 #endif // CONF_TM
+  auto_shutoff_counter = auto_shutoff_period;
 }
 
 #endif
diff -ur brickos-0.9.0/kernel/tm.c brickos-0.9.0-fast/kernel/tm.c
--- kernel/tm.c	2004-01-09 02:44:56.000000000 +0100
+++ kernel/tm.c	2008-08-19 00:38:41.000000000 +0200
@@ -109,11 +109,8 @@
 .globl _tm_switcher\n\
 _tm_switcher:\n\
       ; r6 saved by ROM\n\
-      ; r0 saved by system timer handler\n\
+      ; r0 .. r3 saved by system timer handler\n\
 \n\
-      mov.w r1,@-r7                           ; save registers\n\
-      mov.w r2,@-r7 \n\
-      mov.w r3,@-r7 \n\
       mov.w r4,@-r7 \n\
       mov.w r5,@-r7 \n\
 \n\
@@ -126,11 +123,8 @@
 \n\
       mov.w @r7+,r5\n\
       mov.w @r7+,r4\n\
-      mov.w @r7+,r3\n\
-      mov.w @r7+,r2\n\
-      mov.w @r7+,r1\n\
 \n\
-      ; r0 will be restored by system timer handler\n\
+      ; r0..r3 will be restored by system timer handler\n\
       ; r6 will be restored by ROM\n\
 \n\
       rts                                     ; return to new task\n\
@@ -285,6 +279,9 @@
       push    r0\n\
 \n\
       push    r0                     ; store r0 (destroyed by call.)\n\
+      push    r1\n\
+      push    r2\n\
+      push    r3\n\
 \n\
       mov.w   #_systime_tm_return,r0 ; store systime return addr\n\
       push    r0\n\
@@ -307,47 +304,6 @@
 ");
 #endif  // DOXYGEN_SHOULD_SKIP_THIS
 
-#ifdef CONF_VIS
-//! the man system task
-/*! infinite loop; when program running, update the man (stand/run)
-*/
-int tm_man_task(int argc, char **argv)
-{
-  int state=0;
-
-  while (!shutdown_requested()) {
-    if(nb_tasks > nb_system_tasks) state ^= 1; else state=0;
-    lcd_show(state == 0 ? man_stand : man_run);
-#ifndef CONF_LCD_REFRESH
-    lcd_refresh();
-#endif // CONF_LCD_REFRESH
-    msleep(500);
-  }
-  return 0;
-}
-
-#ifdef CONF_BATTERY_INDICATOR
-//! the battery system task
-/*! updates the battery low indicator when necessary
-*/
-int tm_battery_task(int argc, char **argv) {
-  int bmv;
-
-  while (!shutdown_requested()) {
-    bmv=get_battery_mv();
-
-    if(bmv>BATTERY_NORMAL_THRESHOLD_MV)
-      dlcd_hide(LCD_BATTERY_X);
-    else if(bmv<BATTERY_LOW_THRESHOLD_MV)
-      dlcd_show(LCD_BATTERY_X);
-
-    msleep(2000);
-  }
-  return 0;
-}
-#endif // CONF_BATTERY_INDICATOR
-#endif // CONF_VIS
-
 //! initialize task management
 /*! initialize tasking variables and start the system tasks
 !*! (called in single tasking mode before task setup.)
@@ -372,16 +328,8 @@
   td_idle=(tdata_t*)execi(&tm_idle_task,0,NULL,0,IDLE_STACK_SIZE);
   td_idle->tflags |= T_IDLE;
 
-#ifdef CONF_VIS
-  execi(&tm_man_task, 0, NULL, 1, IDLE_STACK_SIZE);
-
-#ifdef CONF_BATTERY_INDICATOR
-  execi(&tm_battery_task, 0, NULL, 1, IDLE_STACK_SIZE);
-#endif // CONF_BATTERY_INDICATOR
-#endif // CONF_VIS
-
   systime_set_timeslice(TM_DEFAULT_SLICE);
-} 
+}
 
 
 //! start task management 
@@ -463,13 +411,13 @@
   *(--sp)=(size_t)
           &rom_ocia_return;         // ROM return < rts in systime_handler
 
-  *(--sp)=(size_t) argc;              // r0     < pop r0 in systime handler
+  *(--sp)=(size_t) argc;              // r0      < pop r0 in systime handler
+  *(--sp)=(size_t) argv;              // r1..r3  < pop r1 in systime handler
+  *(--sp)=0;
+  *(--sp)=0;
   *(--sp)=(size_t)              
           &systime_tm_return;       // systime return < rts in tm_switcher
 
-  *(--sp)=(size_t) argv;              // r1..r5 < pop r1..r5 in tm_switcher
-  *(--sp)=0;
-  *(--sp)=0;
   *(--sp)=0;
   *(--sp)=0;
 
diff -ur brickos-0.9.0/kernel/vis.c brickos-0.9.0-fast/kernel/vis.c
--- kernel/vis.c	2002-10-12 05:22:26.000000000 +0200
+++ kernel/vis.c	2008-08-19 00:38:41.000000000 +0200
@@ -33,6 +33,7 @@
 #include <dmotor.h>
 #include <sys/program.h>
 #include <sys/tm.h>
+#include <sys/battery.h>
 
 ///////////////////////////////////////////////////////////////////////////////
 //
@@ -40,8 +41,11 @@
 //
 ///////////////////////////////////////////////////////////////////////////////
 
-unsigned char vis_refresh_counter = 0;
-unsigned char vis_refresh_period = 50;
+unsigned char vis_refresh_counter =   1; //!< counter; decreased every ms
+unsigned char vis_refresh_period  = 100; //!< VIS refresh period in ms
+
+unsigned char vis_animated_man;
+unsigned char vis_animated_man_ctr;
 
 ///////////////////////////////////////////////////////////////////////////////
 //
@@ -49,12 +53,7 @@
 //
 ///////////////////////////////////////////////////////////////////////////////
 
-#ifdef CONF_RCX_COMPILER
 void vis_handler(void) {
-#else
-HANDLER_WRAPPER("vis_handler","vis_core");
-void vis_core(void) {
-#endif
 #ifdef CONF_DSENSOR
   bit_iload(AD_C_H,0x7);
   dlcd_store(LCD_S1_ACTIVE);
@@ -72,8 +71,27 @@
       cputc_hex_0(cprog+1);
     else
       cputc_0('-');
+    vis_animated_man = 0;
+    lcd_show(man_stand);
+  } else {
+    if (vis_animated_man_ctr-- == 0) {
+      vis_animated_man ^= 1;
+      vis_animated_man_ctr = 4;
+      lcd_show(vis_animated_man == 0 ? man_stand : man_run);
+    }
   }
 #endif
+
+#ifdef CONF_BATTERY_INDICATOR
+  {
+   int bmv = get_battery_mv();
+   if (bmv > BATTERY_NORMAL_THRESHOLD_MV)
+     dlcd_hide(LCD_BATTERY_X);
+   else if (bmv < BATTERY_LOW_THRESHOLD_MV)
+     dlcd_show(LCD_BATTERY_X);
+  }
+#endif // CONF_BATTERY_INDICATOR
+  vis_refresh_counter = vis_refresh_period;
 }
 
 #endif  // CONF_VIS
