Add .lss files for GCC for current Mac CrossPack
authorKevin Rosenberg <kevin@rosenberg.net>
Sun, 6 Jun 2010 17:58:41 +0000 (11:58 -0600)
committerKevin Rosenberg <kevin@rosenberg.net>
Sun, 6 Jun 2010 17:58:41 +0000 (11:58 -0600)
gcc_c/serial_lcd.lss [new file with mode: 0644]
gcc_cpp/serial_lcd_cpp.lss [new file with mode: 0644]

diff --git a/gcc_c/serial_lcd.lss b/gcc_c/serial_lcd.lss
new file mode 100644 (file)
index 0000000..9776ae0
--- /dev/null
@@ -0,0 +1,806 @@
+
+serial_lcd.elf:     file format elf32-avr
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         000002aa  00000000  00000000  00000074  2**1
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .noinit       00000030  00800060  00800060  0000031e  2**0
+                  ALLOC
+  2 .stab         0000069c  00000000  00000000  00000320  2**2
+                  CONTENTS, READONLY, DEBUGGING
+  3 .stabstr      00000082  00000000  00000000  000009bc  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  4 .debug_aranges 00000050  00000000  00000000  00000a3e  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  5 .debug_pubnames 0000003a  00000000  00000000  00000a8e  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  6 .debug_info   00000765  00000000  00000000  00000ac8  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  7 .debug_abbrev 0000026d  00000000  00000000  0000122d  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  8 .debug_line   0000068a  00000000  00000000  0000149a  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  9 .debug_frame  00000080  00000000  00000000  00001b24  2**2
+                  CONTENTS, READONLY, DEBUGGING
+ 10 .debug_str    00000298  00000000  00000000  00001ba4  2**0
+                  CONTENTS, READONLY, DEBUGGING
+ 11 .debug_loc    000001cd  00000000  00000000  00001e3c  2**0
+                  CONTENTS, READONLY, DEBUGGING
+ 12 .debug_ranges 000000a8  00000000  00000000  00002009  2**0
+                  CONTENTS, READONLY, DEBUGGING
+
+Disassembly of section .text:
+
+00000000 <__vectors>:
+   0:  18 c0           rjmp    .+48            ; 0x32 <__ctors_end>
+   2:  1d c0           rjmp    .+58            ; 0x3e <__bad_interrupt>
+   4:  1c c0           rjmp    .+56            ; 0x3e <__bad_interrupt>
+   6:  1b c0           rjmp    .+54            ; 0x3e <__bad_interrupt>
+   8:  1a c0           rjmp    .+52            ; 0x3e <__bad_interrupt>
+   a:  19 c0           rjmp    .+50            ; 0x3e <__bad_interrupt>
+   c:  18 c0           rjmp    .+48            ; 0x3e <__bad_interrupt>
+   e:  42 c0           rjmp    .+132           ; 0x94 <__vector_7>
+  10:  16 c0           rjmp    .+44            ; 0x3e <__bad_interrupt>
+  12:  15 c0           rjmp    .+42            ; 0x3e <__bad_interrupt>
+  14:  14 c0           rjmp    .+40            ; 0x3e <__bad_interrupt>
+  16:  13 c0           rjmp    .+38            ; 0x3e <__bad_interrupt>
+  18:  12 c0           rjmp    .+36            ; 0x3e <__bad_interrupt>
+  1a:  18 c1           rjmp    .+560           ; 0x24c <__vector_13>
+  1c:  10 c0           rjmp    .+32            ; 0x3e <__bad_interrupt>
+  1e:  0f c0           rjmp    .+30            ; 0x3e <__bad_interrupt>
+  20:  0e c0           rjmp    .+28            ; 0x3e <__bad_interrupt>
+  22:  0d c0           rjmp    .+26            ; 0x3e <__bad_interrupt>
+  24:  0c c0           rjmp    .+24            ; 0x3e <__bad_interrupt>
+
+00000026 <BaudLookupTable>:
+  26:  07 17 2f 5f                                         ../_
+
+0000002a <ledPwmPatterns>:
+  2a:  10 11 4a 55 5d ee 7f ff                             ..JU]...
+
+00000032 <__ctors_end>:
+  32:  11 24           eor     r1, r1
+  34:  1f be           out     0x3f, r1        ; 63
+  36:  cf ed           ldi     r28, 0xDF       ; 223
+  38:  cd bf           out     0x3d, r28       ; 61
+  3a:  5c d0           rcall   .+184           ; 0xf4 <main>
+  3c:  34 c1           rjmp    .+616           ; 0x2a6 <_exit>
+
+0000003e <__bad_interrupt>:
+  3e:  e0 cf           rjmp    .-64            ; 0x0 <__vectors>
+
+00000040 <LcdBusyWait>:
+  LCD_CONTROL_PORT &= ~(1<<LCD_E);
+}
+
+unsigned char LcdBusyWait (void) {
+  unsigned char LCDStatus;
+  LCD_DATA_DIR = 0x00; // Set LCD data port to inputs
+  40:  17 ba           out     0x17, r1        ; 23
+  LCD_CONTROL_PORT &= ~(1<<LCD_RS); // Set display to "Register mode"
+  42:  95 98           cbi     0x12, 5 ; 18
+  LCD_CONTROL_PORT |= (1<<LCD_RW); // Put the display in the read mode
+  44:  94 9a           sbi     0x12, 4 ; 18
+  NOP();
+  46:  00 00           nop
+  do {
+    wdt_reset();
+  48:  a8 95           wdr
+    LCD_CONTROL_PORT |= (1<<LCD_E);
+  4a:  96 9a           sbi     0x12, 6 ; 18
+  #else
+    #define ENABLE_WAIT() __delay_cycles(4);
+  #endif
+#elif defined(__GNUC__)
+  static __inline__ void _NOP1 (void) { __asm__ volatile ( "nop    " "\n\t" ); }
+  static __inline__ void _NOP2 (void) { __asm__ volatile ( "rjmp 1f" "\n\t"  "1:" "\n\t" ); }
+  4c:  00 c0           rjmp    .+0             ; 0x4e <LcdBusyWait+0xe>
+    ENABLE_WAIT();
+    LCDStatus = LCD_DATA_PIN_REG;
+  4e:  00 c0           rjmp    .+0             ; 0x50 <LcdBusyWait+0x10>
+  50:  96 b3           in      r25, 0x16       ; 22
+    LCD_CONTROL_PORT &= ~(1<<LCD_E);
+  52:  96 98           cbi     0x12, 6 ; 18
+  } while (LCDStatus & (1<<LCD_BUSY));
+  54:  97 fd           sbrc    r25, 7
+  56:  f8 cf           rjmp    .-16            ; 0x48 <LcdBusyWait+0x8>
+  LCD_CONTROL_PORT &= ~(1<<LCD_RW); // Put display in write mode
+  58:  94 98           cbi     0x12, 4 ; 18
+  LCD_DATA_DIR = 0xFF; // Set LCD data port to outputs
+  5a:  8f ef           ldi     r24, 0xFF       ; 255
+  5c:  87 bb           out     0x17, r24       ; 23
+  return (LCDStatus);
+}
+  5e:  89 2f           mov     r24, r25
+  60:  08 95           ret
+
+00000062 <LcdWriteData>:
+  LCD_CONTROL_PORT &= ~(1<<LCD_E);
+  NOP();
+  LCD_CONTROL_PORT |= (1<<LCD_RS); // Set display to "Character mode"
+}
+
+void LcdWriteData (unsigned char c) {
+  62:  1f 93           push    r17
+  64:  18 2f           mov     r17, r24
+  LcdBusyWait();
+  66:  ec df           rcall   .-40            ; 0x40 <LcdBusyWait>
+  LCD_CONTROL_PORT |= (1<<LCD_RS); // Set display to "Character Mode"
+  68:  95 9a           sbi     0x12, 5 ; 18
+  LCD_DATA_PORT = c;
+  6a:  18 bb           out     0x18, r17       ; 24
+  NOP();
+  6c:  00 00           nop
+  LCD_CONTROL_PORT |= (1<<LCD_E);
+  6e:  96 9a           sbi     0x12, 6 ; 18
+  70:  00 c0           rjmp    .+0             ; 0x72 <LcdWriteData+0x10>
+  ENABLE_WAIT();
+  LCD_CONTROL_PORT &= ~(1<<LCD_E);
+  72:  00 c0           rjmp    .+0             ; 0x74 <LcdWriteData+0x12>
+  74:  96 98           cbi     0x12, 6 ; 18
+}
+  76:  1f 91           pop     r17
+  78:  08 95           ret
+
+0000007a <LcdWriteCmd>:
+    }
+  }
+  MAIN_FUNC_LAST();
+}
+
+void LcdWriteCmd (unsigned char Cmd) {
+  7a:  1f 93           push    r17
+  7c:  18 2f           mov     r17, r24
+  LcdBusyWait();
+  7e:  e0 df           rcall   .-64            ; 0x40 <LcdBusyWait>
+  LCD_DATA_PORT = Cmd;  // BusyWait leaves RS low in "Register mode"
+  80:  18 bb           out     0x18, r17       ; 24
+  NOP();
+  82:  00 00           nop
+  LCD_CONTROL_PORT |= (1<<LCD_E);
+  84:  96 9a           sbi     0x12, 6 ; 18
+  86:  00 c0           rjmp    .+0             ; 0x88 <LcdWriteCmd+0xe>
+  ENABLE_WAIT();
+  LCD_CONTROL_PORT &= ~(1<<LCD_E);
+  88:  00 c0           rjmp    .+0             ; 0x8a <LcdWriteCmd+0x10>
+  8a:  96 98           cbi     0x12, 6 ; 18
+  NOP();
+  8c:  00 00           nop
+  LCD_CONTROL_PORT |= (1<<LCD_RS); // Set display to "Character mode"
+  8e:  95 9a           sbi     0x12, 5 ; 18
+}
+  90:  1f 91           pop     r17
+  92:  08 95           ret
+
+00000094 <__vector_7>:
+#pragma interrupt_handler usart_rx_handler:iv_USART0_RXC
+void usart_rx_handler(void)
+#else
+ISR(USART_RX_vect)
+#endif
+{
+  94:  1f 92           push    r1
+  96:  0f 92           push    r0
+  98:  0f b6           in      r0, 0x3f        ; 63
+  9a:  0f 92           push    r0
+  9c:  11 24           eor     r1, r1
+  9e:  8f 93           push    r24
+  a0:  ef 93           push    r30
+  a2:  ff 93           push    r31
+  UartStoreRx(UDR);
+  a4:  8c b1           in      r24, 0x0c       ; 12
+
+INLINE_FUNC_DECLARE(static void UartStoreRx (uint8_t rx));
+static inline void UartStoreRx (uint8_t rx) {
+  unsigned char tmphead;
+
+  if (UCSRA & (1<<FE)) {
+  a6:  5c 99           sbic    0x0b, 4 ; 11
+  a8:  0d c0           rjmp    .+26            ; 0xc4 <__vector_7+0x30>
+    // some applications may benefit from addind error notification for serial port data overruns
+  }
+#endif
+
+  // Calculate next buffer position.
+  tmphead = sUartRxHead;
+  aa:  e5 2d           mov     r30, r5
+  if (tmphead == UART_RX_BUFFER_SIZE-1)
+  ac:  ef 32           cpi     r30, 0x2F       ; 47
+  ae:  11 f4           brne    .+4             ; 0xb4 <__vector_7+0x20>
+  b0:  e0 e0           ldi     r30, 0x00       ; 0
+  b2:  01 c0           rjmp    .+2             ; 0xb6 <__vector_7+0x22>
+    tmphead = 0;
+  else
+    tmphead++;
+  b4:  ef 5f           subi    r30, 0xFF       ; 255
+  // store in buffer if there is room
+  if (tmphead != sUartRxTail) {
+  b6:  e6 15           cp      r30, r6
+  b8:  29 f0           breq    .+10            ; 0xc4 <__vector_7+0x30>
+    sUartRxHead = tmphead;         // Store new index.
+  ba:  5e 2e           mov     r5, r30
+    sUartRxBuf[tmphead] = rx;
+  bc:  f0 e0           ldi     r31, 0x00       ; 0
+  be:  e0 5a           subi    r30, 0xA0       ; 160
+  c0:  ff 4f           sbci    r31, 0xFF       ; 255
+  c2:  80 83           st      Z, r24
+#else
+ISR(USART_RX_vect)
+#endif
+{
+  UartStoreRx(UDR);
+}
+  c4:  ff 91           pop     r31
+  c6:  ef 91           pop     r30
+  c8:  8f 91           pop     r24
+  ca:  0f 90           pop     r0
+  cc:  0f be           out     0x3f, r0        ; 63
+  ce:  0f 90           pop     r0
+  d0:  1f 90           pop     r1
+  d2:  18 95           reti
+
+000000d4 <WaitRxChar>:
+
+static unsigned char WaitRxChar (void) {
+  // waits for next RX character, then return it
+  unsigned char tail;
+  do {
+    tail = sUartRxTail; // explicitly set order of volatile variable access
+  d4:  86 2d           mov     r24, r6
+    wdt_reset();
+  } while (sUartRxHead == tail); // while buffer is empty
+  d6:  95 2d           mov     r25, r5
+static unsigned char WaitRxChar (void) {
+  // waits for next RX character, then return it
+  unsigned char tail;
+  do {
+    tail = sUartRxTail; // explicitly set order of volatile variable access
+    wdt_reset();
+  d8:  a8 95           wdr
+  } while (sUartRxHead == tail); // while buffer is empty
+  da:  98 17           cp      r25, r24
+  dc:  e9 f3           breq    .-6             ; 0xd8 <WaitRxChar+0x4>
+  // CTS inactive if byte fills buffer after we remove current byte
+  cli();
+#endif
+
+  // increment tail position
+  if (tail == UART_RX_BUFFER_SIZE-1)
+  de:  8f 32           cpi     r24, 0x2F       ; 47
+  e0:  11 f4           brne    .+4             ; 0xe6 <__stack+0x7>
+    sUartRxTail = 0;
+  e2:  66 24           eor     r6, r6
+  e4:  01 c0           rjmp    .+2             ; 0xe8 <__stack+0x9>
+  else
+    sUartRxTail++;
+  e6:  63 94           inc     r6
+#if USE_CTS
+  CTS_PORT |= (1<<CTS_PIN); // Ensure CTS is active since just removed a byte
+  sei();   // Allow UART ISR to read character and change potentially change CTS
+#endif
+
+  return sUartRxBuf[sUartRxTail];
+  e8:  e6 2d           mov     r30, r6
+  ea:  f0 e0           ldi     r31, 0x00       ; 0
+  ec:  e0 5a           subi    r30, 0xA0       ; 160
+  ee:  ff 4f           sbci    r31, 0xFF       ; 255
+  f0:  80 81           ld      r24, Z
+}
+  f2:  08 95           ret
+
+000000f4 <main>:
+  LcdWriteCmd (LCD_ON); // Power up the display
+  LcdWriteCmd (LCD_CLR); // Power up the display
+}
+
+MAIN_FUNC() {
+  MCUSR = 0; // clear all reset flags
+  f4:  14 be           out     0x34, r1        ; 52
+
+  wdt_reset();
+  f6:  a8 95           wdr
+#if defined(__CODEVISIONAVR__)
+#pragma optsize-
+#endif
+  WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)
+  f8:  81 b5           in      r24, 0x21       ; 33
+  fa:  88 61           ori     r24, 0x18       ; 24
+  fc:  81 bd           out     0x21, r24       ; 33
+  WDTCSR = (1<<WDE)|(1<<WDP3)|(1<<WDP0); // 1024K cycles, 8.0sec
+  fe:  89 e2           ldi     r24, 0x29       ; 41
+ 100:  81 bd           out     0x21, r24       ; 33
+#if defined(__CODEVISIONAVR__) && defined(_OPTIMIZE_SIZE_)
+#pragma optsize+
+#endif
+  MCUCR &= ~((1<<SM1)|(1<<SM0)); // use idle sleep mode
+ 102:  85 b7           in      r24, 0x35       ; 53
+ 104:  8f 7a           andi    r24, 0xAF       ; 175
+ 106:  85 bf           out     0x35, r24       ; 53
+
+INLINE_FUNC_DECLARE(static void LedPwmInit (void));
+static inline void LedPwmInit (void) {
+  // setup PWM to run at 1.25ms per interrupt.
+  // This allows 8 levels of brightness at minimum of 100Hz flicker rate.
+  TCCR0A = (1<<WGM01);  // CTC mode
+ 108:  82 e0           ldi     r24, 0x02       ; 2
+ 10a:  80 bf           out     0x30, r24       ; 48
+  TCCR0B = 0;           // timer off
+ 10c:  13 be           out     0x33, r1        ; 51
+  OCR0A = 72;           // 1.25ms with CLK/256 prescaler @ 14.7456MHz
+ 10e:  88 e4           ldi     r24, 0x48       ; 72
+ 110:  86 bf           out     0x36, r24       ; 54
+  TIMSK = (1<<OCIE0A);  // Turn on timer0 COMPA intr (all other timer intr off)
+ 112:  81 e0           ldi     r24, 0x01       ; 1
+ 114:  89 bf           out     0x39, r24       ; 57
+  LED_PORT &= ~(1<<LED_PIN); // Ensure LED is off during initialization
+ 116:  91 98           cbi     0x12, 1 ; 18
+  LED_DIR |= (1<<LED_PIN);   // Ensure LED is output direction
+ 118:  89 9a           sbi     0x11, 1 ; 17
+  BACKLIGHT_OFF();       // note that LED is off
+ 11a:  a0 98           cbi     0x14, 0 ; 20
+  ledPwmPattern = 0xFF; // maximum brightness
+ 11c:  9f ef           ldi     r25, 0xFF       ; 255
+ 11e:  93 bb           out     0x13, r25       ; 19
+
+
+INLINE_FUNC_DECLARE(static void LcdInit (void));
+static inline void LcdInit (void) {
+  // Set BAUD_J2:BAUD_J1 PULL-UPS active
+  LCD_CONTROL_PORT = (1<<BAUD_J2) | (1<<BAUD_J1);
+ 120:  8c e0           ldi     r24, 0x0C       ; 12
+ 122:  82 bb           out     0x12, r24       ; 18
+  // Set LCD_control BAUD_J2:BAUD_J1 to inputs
+  LCD_CONTROL_DIR = 0xF2;
+ 124:  82 ef           ldi     r24, 0xF2       ; 242
+ 126:  81 bb           out     0x11, r24       ; 17
+    milliseconds can be achieved.
+ */
+void
+_delay_loop_2(uint16_t __count)
+{
+       __asm__ volatile (
+ 128:  e0 e0           ldi     r30, 0x00       ; 0
+ 12a:  f8 ed           ldi     r31, 0xD8       ; 216
+ 12c:  31 97           sbiw    r30, 0x01       ; 1
+ 12e:  f1 f7           brne    .-4             ; 0x12c <main+0x38>
+
+  _delay_us(15000);
+  LCD_CONTROL_PORT |= (1<<LCD_RS); // Set LCD_RS HIGH
+ 130:  95 9a           sbi     0x12, 5 ; 18
+
+  // Initialize the LCD Data AVR I/O
+  LCD_DATA_DIR = 0xFF; // Set LCD_DATA_PORT as all outputs
+ 132:  97 bb           out     0x17, r25       ; 23
+  LCD_DATA_PORT = 0x00; // Set LCD_DATA_PORT to logic low
+ 134:  18 ba           out     0x18, r1        ; 24
+
+  // Initialize the LCD controller
+  LCD_CONTROL_PORT &= ~(1<<LCD_RS);
+ 136:  95 98           cbi     0x12, 5 ; 18
+  LcdWriteData (DATA_8);
+ 138:  80 e3           ldi     r24, 0x30       ; 48
+ 13a:  93 df           rcall   .-218           ; 0x62 <LcdWriteData>
+ 13c:  8a e0           ldi     r24, 0x0A       ; 10
+ 13e:  9b e3           ldi     r25, 0x3B       ; 59
+ 140:  01 97           sbiw    r24, 0x01       ; 1
+ 142:  f1 f7           brne    .-4             ; 0x140 <main+0x4c>
+
+  _delay_us(4100);
+  LcdWriteData (DATA_8);
+ 144:  80 e3           ldi     r24, 0x30       ; 48
+ 146:  8d df           rcall   .-230           ; 0x62 <LcdWriteData>
+ 148:  80 e7           ldi     r24, 0x70       ; 112
+ 14a:  91 e0           ldi     r25, 0x01       ; 1
+ 14c:  01 97           sbiw    r24, 0x01       ; 1
+ 14e:  f1 f7           brne    .-4             ; 0x14c <main+0x58>
+
+  _delay_us(100);
+  LcdWriteData (DATA_8);
+ 150:  80 e3           ldi     r24, 0x30       ; 48
+ 152:  87 df           rcall   .-242           ; 0x62 <LcdWriteData>
+  LCD_CONTROL_PORT |= (1<<LCD_RS);
+ 154:  95 9a           sbi     0x12, 5 ; 18
+
+  // The display will be out into 8 bit data mode here
+  LcdWriteCmd (LCD_8_Bit | LCD_4_Line); // Set 8 bit data, 4 display lines
+ 156:  88 e3           ldi     r24, 0x38       ; 56
+ 158:  90 df           rcall   .-224           ; 0x7a <LcdWriteCmd>
+  LcdWriteCmd (LCD_ON); // Power up the display
+ 15a:  8c e0           ldi     r24, 0x0C       ; 12
+ 15c:  8e df           rcall   .-228           ; 0x7a <LcdWriteCmd>
+  LcdWriteCmd (LCD_CLR); // Power up the display
+ 15e:  81 e0           ldi     r24, 0x01       ; 1
+ 160:  8c df           rcall   .-232           ; 0x7a <LcdWriteCmd>
+
+
+INLINE_FUNC_DECLARE(static void UsartInit (void));
+static inline void UsartInit(void) {
+  // Initialize USART
+  UCSRB = 0; // Disable while setting baud rate
+ 162:  1a b8           out     0x0a, r1        ; 10
+  UCSRA = 0;
+ 164:  1b b8           out     0x0b, r1        ; 11
+  UCSRC = (1<<UCSZ1) | (1<<UCSZ0); // 8 bit data
+ 166:  86 e0           ldi     r24, 0x06       ; 6
+ 168:  83 b9           out     0x03, r24       ; 3
+= {BAUD_115200, BAUD_38400, BAUD_19200, BAUD_9600};
+
+INLINE_FUNC_DECLARE(static unsigned char GetUsartBaud (void));
+static inline unsigned char GetUsartBaud (void) {
+  // Get BAUD rate jumper settings
+  unsigned char BaudSelectJumpersValue  = BAUD_PIN_REG;
+ 16a:  e0 b3           in      r30, 0x10       ; 16
+  // Mask off unwanted bits
+  BaudSelectJumpersValue &= (1<<BAUD_J2) | (1<<BAUD_J1);
+ 16c:  ec 70           andi    r30, 0x0C       ; 12
+  // This is two bits too far to the left and the array index will
+  // increment by 4, instead of 1.
+  // Shift BAUD_J2 & BAUD_J1 right by two bit positions for proper array indexing
+  BaudSelectJumpersValue = (BaudSelectJumpersValue >> BAUD_J1);
+
+  return PGM_READ_BYTE (&BaudLookupTable[BaudSelectJumpersValue]);
+ 16e:  e6 95           lsr     r30
+ 170:  e6 95           lsr     r30
+ 172:  f0 e0           ldi     r31, 0x00       ; 0
+ 174:  ea 5d           subi    r30, 0xDA       ; 218
+ 176:  ff 4f           sbci    r31, 0xFF       ; 255
+ 178:  e4 91           lpm     r30, Z+
+static inline void UsartInit(void) {
+  // Initialize USART
+  UCSRB = 0; // Disable while setting baud rate
+  UCSRA = 0;
+  UCSRC = (1<<UCSZ1) | (1<<UCSZ0); // 8 bit data
+  UBRRL = GetUsartBaud (); // Set baud rate
+ 17a:  e9 b9           out     0x09, r30       ; 9
+  UBRRH = 0; // Set baud rate hi
+ 17c:  12 b8           out     0x02, r1        ; 2
+  UCSRB = (1<<RXEN)|(1<<RXCIE); // RXEN = Enable
+ 17e:  80 e9           ldi     r24, 0x90       ; 144
+ 180:  8a b9           out     0x0a, r24       ; 10
+  sUartRxHead = 0; // register variable, need to explicitly zero
+ 182:  55 24           eor     r5, r5
+  sUartRxTail = 0; // register variable, need to explicitly zero
+ 184:  66 24           eor     r6, r6
+  LcdInit ();
+
+  // Initialize the AVR USART
+  UsartInit ();
+
+  sei();
+ 186:  78 94           sei
+  TCCR0B = 0;
+}
+
+INLINE_FUNC_DECLARE(static void LedTimerStart (void));
+static inline void LedTimerStart (void) {
+  TCCR0B = (1<<CS02); // Start with 256 prescaler
+ 188:  14 e0           ldi     r17, 0x04       ; 4
+  UsartInit ();
+
+  sei();
+  while (1) {
+    unsigned char tail = sUartRxTail; // explicitly set order of volatile access
+    if (tail != sUartRxHead) { // Check if UART RX buffer has a character
+ 18a:  65 14           cp      r6, r5
+ 18c:  09 f4           brne    .+2             ; 0x190 <main+0x9c>
+ 18e:  41 c0           rjmp    .+130           ; 0x212 <main+0x11e>
+      unsigned char rx_byte = WaitRxChar();
+ 190:  a1 df           rcall   .-190           ; 0xd4 <WaitRxChar>
+
+      // avoid use of switch statement as ImageCraft and GCC produce signifcantly
+      // more code for a switch statement than a sequence of if/else if
+      if (rx_byte == LED_SW_OFF) {
+ 192:  8d 3f           cpi     r24, 0xFD       ; 253
+ 194:  21 f4           brne    .+8             ; 0x19e <main+0xaa>
+  }
+}
+
+INLINE_FUNC_DECLARE(static void LedPwmSwitchOff (void));
+static inline void LedPwmSwitchOff (void) {
+  LED_PORT &= ~(1<<LED_PIN);
+ 196:  91 98           cbi     0x12, 1 ; 18
+  BACKLIGHT_OFF();
+ 198:  a0 98           cbi     0x14, 0 ; 20
+
+#else
+// Using a platform that has proper inline functions
+INLINE_FUNC_DECLARE(static void LedTimerStop (void));
+static inline void LedTimerStop (void) {
+  TCCR0B = 0;
+ 19a:  13 be           out     0x33, r1        ; 51
+ 19c:  f6 cf           rjmp    .-20            ; 0x18a <main+0x96>
+
+      // avoid use of switch statement as ImageCraft and GCC produce signifcantly
+      // more code for a switch statement than a sequence of if/else if
+      if (rx_byte == LED_SW_OFF) {
+        LedPwmSwitchOff();
+      } else if (rx_byte == LED_SW_ON) {
+ 19e:  8c 3f           cpi     r24, 0xFC       ; 252
+ 1a0:  29 f4           brne    .+10            ; 0x1ac <main+0xb8>
+  LedTimerStop();
+}
+
+INLINE_FUNC_DECLARE(static void LedPwmSwitchOn (void));
+static inline void LedPwmSwitchOn (void) {
+  BACKLIGHT_ON();
+ 1a2:  a0 9a           sbi     0x14, 0 ; 20
+  if (ledPwmPattern == 0xFF) { // maximum brightness, no need for PWM
+ 1a4:  83 b3           in      r24, 0x13       ; 19
+ 1a6:  8f 3f           cpi     r24, 0xFF       ; 255
+ 1a8:  59 f5           brne    .+86            ; 0x200 <main+0x10c>
+ 1aa:  25 c0           rjmp    .+74            ; 0x1f6 <main+0x102>
+      // more code for a switch statement than a sequence of if/else if
+      if (rx_byte == LED_SW_OFF) {
+        LedPwmSwitchOff();
+      } else if (rx_byte == LED_SW_ON) {
+        LedPwmSwitchOn();
+      } else if (rx_byte == LED_SET_BRIGHTNESS) {
+ 1ac:  8b 3f           cpi     r24, 0xFB       ; 251
+ 1ae:  51 f5           brne    .+84            ; 0x204 <main+0x110>
+        rx_byte = WaitRxChar();  // read next byte which will be brightness
+ 1b0:  91 df           rcall   .-222           ; 0xd4 <WaitRxChar>
+
+INLINE_FUNC_DECLARE(static void LedPwmSetBrightness (unsigned char brightness));
+static inline void LedPwmSetBrightness (unsigned char brightness) {
+  unsigned char ledPwmPos;
+
+  if (brightness == 0) { // turn backlight off for 0 brightness
+ 1b2:  88 23           and     r24, r24
+ 1b4:  39 f4           brne    .+14            ; 0x1c4 <main+0xd0>
+    if (IS_BACKLIGHT_ON()) {
+ 1b6:  a0 9b           sbis    0x14, 0 ; 20
+ 1b8:  e8 cf           rjmp    .-48            ; 0x18a <main+0x96>
+
+#else
+// Using a platform that has proper inline functions
+INLINE_FUNC_DECLARE(static void LedTimerStop (void));
+static inline void LedTimerStop (void) {
+  TCCR0B = 0;
+ 1ba:  13 be           out     0x33, r1        ; 51
+  unsigned char ledPwmPos;
+
+  if (brightness == 0) { // turn backlight off for 0 brightness
+    if (IS_BACKLIGHT_ON()) {
+      LedTimerStop();
+      ledPwmPattern = 0;
+ 1bc:  13 ba           out     0x13, r1        ; 19
+      ledPwmCycling = 0;
+ 1be:  77 24           eor     r7, r7
+      LED_PORT &= ~(1<<LED_PIN);
+ 1c0:  91 98           cbi     0x12, 1 ; 18
+ 1c2:  e3 cf           rjmp    .-58            ; 0x18a <main+0x96>
+    }
+    return;
+  }
+
+  ledPwmPos = (brightness * (LED_BRIGHTNESS_LEVELS-1) + (unsigned int) 127) >> 8;
+ 1c4:  90 e0           ldi     r25, 0x00       ; 0
+ 1c6:  67 e0           ldi     r22, 0x07       ; 7
+ 1c8:  70 e0           ldi     r23, 0x00       ; 0
+ 1ca:  5b d0           rcall   .+182           ; 0x282 <__mulhi3>
+ 1cc:  81 58           subi    r24, 0x81       ; 129
+ 1ce:  9f 4f           sbci    r25, 0xFF       ; 255
+ 1d0:  89 2f           mov     r24, r25
+ 1d2:  99 27           eor     r25, r25
+ 1d4:  98 2f           mov     r25, r24
+ 1d6:  88 30           cpi     r24, 0x08       ; 8
+ 1d8:  08 f0           brcs    .+2             ; 0x1dc <main+0xe8>
+ 1da:  97 e0           ldi     r25, 0x07       ; 7
+  // Below is probably not required, but ensures we don't exceed array
+  if (ledPwmPos > LED_BRIGHTNESS_LEVELS - 1)
+    ledPwmPos = LED_BRIGHTNESS_LEVELS - 1;
+
+  ledPwmPattern = PGM_READ_BYTE (&ledPwmPatterns[ledPwmPos]);
+ 1dc:  e9 2f           mov     r30, r25
+ 1de:  f0 e0           ldi     r31, 0x00       ; 0
+ 1e0:  e6 5d           subi    r30, 0xD6       ; 214
+ 1e2:  ff 4f           sbci    r31, 0xFF       ; 255
+ 1e4:  e4 91           lpm     r30, Z+
+ 1e6:  e3 bb           out     0x13, r30       ; 19
+  ledPwmCount = 0;
+ 1e8:  44 24           eor     r4, r4
+  ledPwmCycling = ledPwmPattern;
+ 1ea:  83 b3           in      r24, 0x13       ; 19
+ 1ec:  78 2e           mov     r7, r24
+  if (ledPwmPos >= LED_BRIGHTNESS_LEVELS-1) { // maximum brightness
+ 1ee:  97 30           cpi     r25, 0x07       ; 7
+ 1f0:  29 f4           brne    .+10            ; 0x1fc <main+0x108>
+    // don't need PWM for continuously on
+    if (IS_BACKLIGHT_ON()) {
+ 1f2:  a0 9b           sbis    0x14, 0 ; 20
+ 1f4:  ca cf           rjmp    .-108           ; 0x18a <main+0x96>
+
+#else
+// Using a platform that has proper inline functions
+INLINE_FUNC_DECLARE(static void LedTimerStop (void));
+static inline void LedTimerStop (void) {
+  TCCR0B = 0;
+ 1f6:  13 be           out     0x33, r1        ; 51
+  ledPwmCycling = ledPwmPattern;
+  if (ledPwmPos >= LED_BRIGHTNESS_LEVELS-1) { // maximum brightness
+    // don't need PWM for continuously on
+    if (IS_BACKLIGHT_ON()) {
+      LedTimerStop();
+      LED_PORT |= (1<<LED_PIN);
+ 1f8:  91 9a           sbi     0x12, 1 ; 18
+ 1fa:  c7 cf           rjmp    .-114           ; 0x18a <main+0x96>
+    }
+  } else {
+    if (IS_BACKLIGHT_ON()) {
+ 1fc:  a0 9b           sbis    0x14, 0 ; 20
+ 1fe:  c5 cf           rjmp    .-118           ; 0x18a <main+0x96>
+  TCCR0B = 0;
+}
+
+INLINE_FUNC_DECLARE(static void LedTimerStart (void));
+static inline void LedTimerStart (void) {
+  TCCR0B = (1<<CS02); // Start with 256 prescaler
+ 200:  13 bf           out     0x33, r17       ; 51
+ 202:  c3 cf           rjmp    .-122           ; 0x18a <main+0x96>
+      } else if (rx_byte == LED_SW_ON) {
+        LedPwmSwitchOn();
+      } else if (rx_byte == LED_SET_BRIGHTNESS) {
+        rx_byte = WaitRxChar();  // read next byte which will be brightness
+        LedPwmSetBrightness(rx_byte);
+      } else if (rx_byte == REG_MODE) {
+ 204:  8e 3f           cpi     r24, 0xFE       ; 254
+ 206:  19 f4           brne    .+6             ; 0x20e <main+0x11a>
+        LcdWriteCmd (WaitRxChar()); // Send LCD command character
+ 208:  65 df           rcall   .-310           ; 0xd4 <WaitRxChar>
+ 20a:  37 df           rcall   .-402           ; 0x7a <LcdWriteCmd>
+ 20c:  be cf           rjmp    .-132           ; 0x18a <main+0x96>
+      } else {
+        LcdWriteData (rx_byte); // Send LCD data character
+ 20e:  29 df           rcall   .-430           ; 0x62 <LcdWriteData>
+ 210:  bc cf           rjmp    .-136           ; 0x18a <main+0x96>
+      }
+    } else {
+      // No characters waiting in RX buffer
+
+      cli();
+ 212:  f8 94           cli
+      wdt_reset();
+ 214:  a8 95           wdr
+      MCUSR &= ~(1<<WDRF); // clear any watchdog interrupt flags
+ 216:  84 b7           in      r24, 0x34       ; 52
+ 218:  87 7f           andi    r24, 0xF7       ; 247
+ 21a:  84 bf           out     0x34, r24       ; 52
+
+#if defined(__CODEVISIONAVR__)
+#pragma optsize-
+#endif
+      WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)
+ 21c:  81 b5           in      r24, 0x21       ; 33
+ 21e:  88 61           ori     r24, 0x18       ; 24
+ 220:  81 bd           out     0x21, r24       ; 33
+      WDTCSR &= ~(1<<WDE); // watchdog timer off
+ 222:  81 b5           in      r24, 0x21       ; 33
+ 224:  87 7f           andi    r24, 0xF7       ; 247
+ 226:  81 bd           out     0x21, r24       ; 33
+#if defined(__CODEVISIONAVR__) && defined(_OPTIMIZE_SIZE_)
+#pragma optsize+
+#endif
+
+      sei();
+ 228:  78 94           sei
+
+      sleep_enable();
+ 22a:  85 b7           in      r24, 0x35       ; 53
+ 22c:  80 62           ori     r24, 0x20       ; 32
+ 22e:  85 bf           out     0x35, r24       ; 53
+      sleep_cpu();
+ 230:  88 95           sleep
+      sleep_disable();
+ 232:  85 b7           in      r24, 0x35       ; 53
+ 234:  8f 7d           andi    r24, 0xDF       ; 223
+ 236:  85 bf           out     0x35, r24       ; 53
+
+      cli();
+ 238:  f8 94           cli
+      wdt_reset();
+ 23a:  a8 95           wdr
+
+#if defined(__CODEVISIONAVR__)
+#pragma optsize-
+#endif
+      WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)
+ 23c:  81 b5           in      r24, 0x21       ; 33
+ 23e:  88 61           ori     r24, 0x18       ; 24
+ 240:  81 bd           out     0x21, r24       ; 33
+      WDTCSR &= ~(1<<WDCE);
+ 242:  81 b5           in      r24, 0x21       ; 33
+ 244:  8f 7e           andi    r24, 0xEF       ; 239
+ 246:  81 bd           out     0x21, r24       ; 33
+#if defined(__CODEVISIONAVR__) && defined(_OPTIMIZE_SIZE_)
+#pragma optsize+
+#endif
+
+      sei();
+ 248:  78 94           sei
+ 24a:  9f cf           rjmp    .-194           ; 0x18a <main+0x96>
+
+0000024c <__vector_13>:
+#pragma interrupt_handler timer0_compa_handler:iv_TIMER0_COMPA
+void timer0_compa_handler(void)
+#else
+  ISR(TIMER0_COMPA_vect)
+#endif
+{
+ 24c:  1f 92           push    r1
+ 24e:  0f 92           push    r0
+ 250:  0f b6           in      r0, 0x3f        ; 63
+ 252:  0f 92           push    r0
+ 254:  11 24           eor     r1, r1
+ 256:  8f 93           push    r24
+  sei(); // Okay to allow USART interrupts while controlling LED PWM
+ 258:  78 94           sei
+
+  // Set current LED state based on cycling variable
+  if (ledPwmCycling & 0x01) {
+ 25a:  70 fe           sbrs    r7, 0
+ 25c:  02 c0           rjmp    .+4             ; 0x262 <__vector_13+0x16>
+    LED_PORT |= (1<<LED_PIN);
+ 25e:  91 9a           sbi     0x12, 1 ; 18
+ 260:  01 c0           rjmp    .+2             ; 0x264 <__vector_13+0x18>
+  } else {
+    LED_PORT &= ~(1<<LED_PIN);
+ 262:  91 98           cbi     0x12, 1 ; 18
+  }
+
+  // Update cycling variable for next interrupt
+  if (ledPwmCount >= LED_BRIGHTNESS_LEVELS-1) {
+ 264:  86 e0           ldi     r24, 0x06       ; 6
+ 266:  84 15           cp      r24, r4
+ 268:  20 f4           brcc    .+8             ; 0x272 <__vector_13+0x26>
+    ledPwmCount = 0;
+ 26a:  44 24           eor     r4, r4
+    ledPwmCycling = ledPwmPattern;
+ 26c:  83 b3           in      r24, 0x13       ; 19
+ 26e:  78 2e           mov     r7, r24
+ 270:  02 c0           rjmp    .+4             ; 0x276 <__vector_13+0x2a>
+  } else {
+    ledPwmCount++;
+ 272:  43 94           inc     r4
+    ledPwmCycling >>= 1;
+ 274:  76 94           lsr     r7
+  }
+}
+ 276:  8f 91           pop     r24
+ 278:  0f 90           pop     r0
+ 27a:  0f be           out     0x3f, r0        ; 63
+ 27c:  0f 90           pop     r0
+ 27e:  1f 90           pop     r1
+ 280:  18 95           reti
+
+00000282 <__mulhi3>:
+ 282:  55 27           eor     r21, r21
+ 284:  00 24           eor     r0, r0
+
+00000286 <__mulhi3_loop>:
+ 286:  80 ff           sbrs    r24, 0
+ 288:  02 c0           rjmp    .+4             ; 0x28e <__mulhi3_skip1>
+ 28a:  06 0e           add     r0, r22
+ 28c:  57 1f           adc     r21, r23
+
+0000028e <__mulhi3_skip1>:
+ 28e:  66 0f           add     r22, r22
+ 290:  77 1f           adc     r23, r23
+ 292:  61 15           cp      r22, r1
+ 294:  71 05           cpc     r23, r1
+ 296:  21 f0           breq    .+8             ; 0x2a0 <__mulhi3_exit>
+ 298:  96 95           lsr     r25
+ 29a:  87 95           ror     r24
+ 29c:  00 97           sbiw    r24, 0x00       ; 0
+ 29e:  99 f7           brne    .-26            ; 0x286 <__mulhi3_loop>
+
+000002a0 <__mulhi3_exit>:
+ 2a0:  95 2f           mov     r25, r21
+ 2a2:  80 2d           mov     r24, r0
+ 2a4:  08 95           ret
+
+000002a6 <_exit>:
+ 2a6:  f8 94           cli
+
+000002a8 <__stop_program>:
+ 2a8:  ff cf           rjmp    .-2             ; 0x2a8 <__stop_program>
diff --git a/gcc_cpp/serial_lcd_cpp.lss b/gcc_cpp/serial_lcd_cpp.lss
new file mode 100644 (file)
index 0000000..3eb3b50
--- /dev/null
@@ -0,0 +1,959 @@
+
+serial_lcd_cpp.elf:     file format elf32-avr
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         000002f2  00000000  00000000  00000094  2**1
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .data         0000000c  00800060  000002f2  00000386  2**0
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .bss          00000032  0080006c  0080006c  00000392  2**0
+                  ALLOC
+  3 .stab         0000069c  00000000  00000000  00000394  2**2
+                  CONTENTS, READONLY, DEBUGGING
+  4 .stabstr      00000082  00000000  00000000  00000a30  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  5 .debug_aranges 00000020  00000000  00000000  00000ab2  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  6 .debug_pubnames 00000115  00000000  00000000  00000ad2  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  7 .debug_info   00000fd4  00000000  00000000  00000be7  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  8 .debug_abbrev 0000040f  00000000  00000000  00001bbb  2**0
+                  CONTENTS, READONLY, DEBUGGING
+  9 .debug_line   000006dc  00000000  00000000  00001fca  2**0
+                  CONTENTS, READONLY, DEBUGGING
+ 10 .debug_frame  00000080  00000000  00000000  000026a8  2**2
+                  CONTENTS, READONLY, DEBUGGING
+ 11 .debug_str    00000772  00000000  00000000  00002728  2**0
+                  CONTENTS, READONLY, DEBUGGING
+ 12 .debug_loc    000001e8  00000000  00000000  00002e9a  2**0
+                  CONTENTS, READONLY, DEBUGGING
+ 13 .debug_ranges 00000048  00000000  00000000  00003082  2**0
+                  CONTENTS, READONLY, DEBUGGING
+
+Disassembly of section .text:
+
+00000000 <__vectors>:
+   0:  12 c0           rjmp    .+36            ; 0x26 <__ctors_end>
+   2:  2a c0           rjmp    .+84            ; 0x58 <__bad_interrupt>
+   4:  29 c0           rjmp    .+82            ; 0x58 <__bad_interrupt>
+   6:  28 c0           rjmp    .+80            ; 0x58 <__bad_interrupt>
+   8:  27 c0           rjmp    .+78            ; 0x58 <__bad_interrupt>
+   a:  26 c0           rjmp    .+76            ; 0x58 <__bad_interrupt>
+   c:  25 c0           rjmp    .+74            ; 0x58 <__bad_interrupt>
+   e:  24 c1           rjmp    .+584           ; 0x258 <__vector_7>
+  10:  23 c0           rjmp    .+70            ; 0x58 <__bad_interrupt>
+  12:  22 c0           rjmp    .+68            ; 0x58 <__bad_interrupt>
+  14:  21 c0           rjmp    .+66            ; 0x58 <__bad_interrupt>
+  16:  20 c0           rjmp    .+64            ; 0x58 <__bad_interrupt>
+  18:  1f c0           rjmp    .+62            ; 0x58 <__bad_interrupt>
+  1a:  3c c1           rjmp    .+632           ; 0x294 <__vector_13>
+  1c:  1d c0           rjmp    .+58            ; 0x58 <__bad_interrupt>
+  1e:  1c c0           rjmp    .+56            ; 0x58 <__bad_interrupt>
+  20:  1b c0           rjmp    .+54            ; 0x58 <__bad_interrupt>
+  22:  1a c0           rjmp    .+52            ; 0x58 <__bad_interrupt>
+  24:  19 c0           rjmp    .+50            ; 0x58 <__bad_interrupt>
+
+00000026 <__ctors_end>:
+  26:  11 24           eor     r1, r1
+  28:  1f be           out     0x3f, r1        ; 63
+  2a:  cf ed           ldi     r28, 0xDF       ; 223
+  2c:  cd bf           out     0x3d, r28       ; 61
+
+0000002e <__do_copy_data>:
+  2e:  10 e0           ldi     r17, 0x00       ; 0
+  30:  a0 e6           ldi     r26, 0x60       ; 96
+  32:  b0 e0           ldi     r27, 0x00       ; 0
+  34:  e2 ef           ldi     r30, 0xF2       ; 242
+  36:  f2 e0           ldi     r31, 0x02       ; 2
+  38:  02 c0           rjmp    .+4             ; 0x3e <.do_copy_data_start>
+
+0000003a <.do_copy_data_loop>:
+  3a:  05 90           lpm     r0, Z+
+  3c:  0d 92           st      X+, r0
+
+0000003e <.do_copy_data_start>:
+  3e:  ac 36           cpi     r26, 0x6C       ; 108
+  40:  b1 07           cpc     r27, r17
+  42:  d9 f7           brne    .-10            ; 0x3a <.do_copy_data_loop>
+
+00000044 <__do_clear_bss>:
+  44:  10 e0           ldi     r17, 0x00       ; 0
+  46:  ac e6           ldi     r26, 0x6C       ; 108
+  48:  b0 e0           ldi     r27, 0x00       ; 0
+  4a:  01 c0           rjmp    .+2             ; 0x4e <.do_clear_bss_start>
+
+0000004c <.do_clear_bss_loop>:
+  4c:  1d 92           st      X+, r1
+
+0000004e <.do_clear_bss_start>:
+  4e:  ae 39           cpi     r26, 0x9E       ; 158
+  50:  b1 07           cpc     r27, r17
+  52:  e1 f7           brne    .-8             ; 0x4c <.do_clear_bss_loop>
+  54:  3c d0           rcall   .+120           ; 0xce <main>
+  56:  4b c1           rjmp    .+662           ; 0x2ee <_exit>
+
+00000058 <__bad_interrupt>:
+  58:  d3 cf           rjmp    .-90            ; 0x0 <__vectors>
+
+0000005a <_ZN4Uart10waitRxCharEv>:
+  
+#define UART_UBRR(baud) ((F_CPU+(8*(unsigned long) (baud)))/ (16*((unsigned long) (baud))) - 1)
+const prog_uint8_t Uart::BaudLookupTable[] =
+  {UART_UBRR(115200), UART_UBRR(38400), UART_UBRR(19200), UART_UBRR(9600)};
+
+unsigned char Uart::waitRxChar (void) {
+  5a:  fc 01           movw    r30, r24
+  // waits for next RX character, then return it
+  unsigned char tail;
+  do {
+    tail = sUartRxTail; // explicitly set order of volatile variable access
+  5c:  86 2d           mov     r24, r6
+  {UART_UBRR(115200), UART_UBRR(38400), UART_UBRR(19200), UART_UBRR(9600)};
+
+unsigned char Uart::waitRxChar (void) {
+  // waits for next RX character, then return it
+  unsigned char tail;
+  do {
+  5e:  95 2d           mov     r25, r5
+    WDTCSR &= ~(1<<WDCE);
+    sei();
+  }
+  
+  INLINE_FUNC_DECLARE(static void reset(void)) { 
+    wdt_reset(); 
+  60:  a8 95           wdr
+  {UART_UBRR(115200), UART_UBRR(38400), UART_UBRR(19200), UART_UBRR(9600)};
+
+unsigned char Uart::waitRxChar (void) {
+  // waits for next RX character, then return it
+  unsigned char tail;
+  do {
+  62:  98 17           cp      r25, r24
+  64:  e9 f3           breq    .-6             ; 0x60 <_ZN4Uart10waitRxCharEv+0x6>
+  //  CTS inactive if byte fills buffer after we remove current byte
+  cli();
+#endif
+
+  // increment tail position 
+  if (tail == UART_RX_BUFFER_SIZE-1)
+  66:  8f 32           cpi     r24, 0x2F       ; 47
+  68:  11 f4           brne    .+4             ; 0x6e <_ZN4Uart10waitRxCharEv+0x14>
+    sUartRxTail = 0;
+  6a:  66 24           eor     r6, r6
+  6c:  01 c0           rjmp    .+2             ; 0x70 <_ZN4Uart10waitRxCharEv+0x16>
+  else
+    sUartRxTail++;
+  6e:  63 94           inc     r6
+#if USE_CTS
+  CTS_PORT |= (1<<CTS_PIN); // Ensure CTS is active since just removed a byte
+  sei();   // Allow UART ISR to read character and change potentially change CTS
+#endif
+
+  return m_UartRxBuf[sUartRxTail];
+  70:  e6 0d           add     r30, r6
+  72:  f1 1d           adc     r31, r1
+  74:  80 81           ld      r24, Z
+}
+  76:  08 95           ret
+
+00000078 <_ZN3Lcd8busyWaitEv>:
+  LCD_CONTROL_PORT &= ~(1<<LCD_E);
+}
+
+unsigned char Lcd::busyWait (void) {
+  unsigned char LCDStatus; 
+  LCD_DATA_DIR = 0x00; // Set LCD data port to inputs
+  78:  17 ba           out     0x17, r1        ; 23
+  LCD_CONTROL_PORT |= (1<<LCD_RW);
+  7a:  94 9a           sbi     0x12, 4 ; 18
+  NOP();
+  7c:  00 00           nop
+    WDTCSR &= ~(1<<WDCE);
+    sei();
+  }
+  
+  INLINE_FUNC_DECLARE(static void reset(void)) { 
+    wdt_reset(); 
+  7e:  a8 95           wdr
+  LCD_DATA_DIR = 0x00; // Set LCD data port to inputs
+  LCD_CONTROL_PORT |= (1<<LCD_RW);
+  NOP();
+  do {
+    Watchdog::reset();
+    LCD_CONTROL_PORT |= (1<<LCD_E);    
+  80:  96 9a           sbi     0x12, 6 ; 18
+  #else
+    #define ENABLE_WAIT() __delay_cycles(4);
+  #endif
+#elif defined(__GNUC__)
+  static __inline__ void _NOP1 (void) { __asm__ volatile ( "nop    " "\n\t" ); }
+  static __inline__ void _NOP2 (void) { __asm__ volatile ( "rjmp 1f" "\n\t"  "1:" "\n\t" ); }
+  82:  00 c0           rjmp    .+0             ; 0x84 <_ZN3Lcd8busyWaitEv+0xc>
+    ENABLE_WAIT();
+    LCDStatus = LCD_DATA_PIN_REG;
+  84:  00 c0           rjmp    .+0             ; 0x86 <_ZN3Lcd8busyWaitEv+0xe>
+  86:  96 b3           in      r25, 0x16       ; 22
+    LCD_CONTROL_PORT &= ~(1<<LCD_E);
+  88:  96 98           cbi     0x12, 6 ; 18
+unsigned char Lcd::busyWait (void) {
+  unsigned char LCDStatus; 
+  LCD_DATA_DIR = 0x00; // Set LCD data port to inputs
+  LCD_CONTROL_PORT |= (1<<LCD_RW);
+  NOP();
+  do {
+  8a:  97 fd           sbrc    r25, 7
+  8c:  f8 cf           rjmp    .-16            ; 0x7e <_ZN3Lcd8busyWaitEv+0x6>
+    LCD_CONTROL_PORT |= (1<<LCD_E);    
+    ENABLE_WAIT();
+    LCDStatus = LCD_DATA_PIN_REG;
+    LCD_CONTROL_PORT &= ~(1<<LCD_E);
+  } while (LCDStatus & (1<<LCD_BUSY));
+  LCD_CONTROL_PORT &= ~(1<<LCD_RW);    
+  8e:  94 98           cbi     0x12, 4 ; 18
+  LCD_DATA_DIR = 0xFF; // Set LCD data port to default output state
+  90:  8f ef           ldi     r24, 0xFF       ; 255
+  92:  87 bb           out     0x17, r24       ; 23
+  return (LCDStatus);
+}               
+  94:  89 2f           mov     r24, r25
+  96:  08 95           ret
+
+00000098 <_ZN3Lcd7putCharEh>:
+  LCD_CONTROL_PORT &= ~(1<<LCD_E);
+  NOP();
+  LCD_CONTROL_PORT |= (1<<LCD_RS);
+}
+
+void Lcd::putChar (unsigned char c) {
+  98:  1f 93           push    r17
+  9a:  16 2f           mov     r17, r22
+  LCD_CONTROL_PORT &= ~(1<<LCD_RS);
+  9c:  95 98           cbi     0x12, 5 ; 18
+  busyWait();
+  9e:  ec df           rcall   .-40            ; 0x78 <_ZN3Lcd8busyWaitEv>
+  LCD_CONTROL_PORT |= (1<<LCD_RS);
+  a0:  95 9a           sbi     0x12, 5 ; 18
+  LCD_DATA_PORT = c;
+  a2:  18 bb           out     0x18, r17       ; 24
+  NOP();
+  a4:  00 00           nop
+  LCD_CONTROL_PORT |= (1<<LCD_E);
+  a6:  96 9a           sbi     0x12, 6 ; 18
+  a8:  00 c0           rjmp    .+0             ; 0xaa <_ZN3Lcd7putCharEh+0x12>
+  ENABLE_WAIT();
+  LCD_CONTROL_PORT &= ~(1<<LCD_E);
+  aa:  00 c0           rjmp    .+0             ; 0xac <_ZN3Lcd7putCharEh+0x14>
+  ac:  96 98           cbi     0x12, 6 ; 18
+}
+  ae:  1f 91           pop     r17
+  b0:  08 95           ret
+
+000000b2 <_ZN3Lcd6putCmdEh>:
+    }
+  }
+  MAIN_FUNC_LAST();
+}
+
+void Lcd::putCmd (unsigned char Cmd) {
+  b2:  1f 93           push    r17
+  b4:  16 2f           mov     r17, r22
+  LCD_CONTROL_PORT &= ~(1<<LCD_RS);
+  b6:  95 98           cbi     0x12, 5 ; 18
+  busyWait();
+  b8:  df df           rcall   .-66            ; 0x78 <_ZN3Lcd8busyWaitEv>
+  LCD_DATA_PORT = Cmd; 
+  ba:  18 bb           out     0x18, r17       ; 24
+  NOP();
+  bc:  00 00           nop
+  LCD_CONTROL_PORT |= (1<<LCD_E);
+  be:  96 9a           sbi     0x12, 6 ; 18
+  c0:  00 c0           rjmp    .+0             ; 0xc2 <_ZN3Lcd6putCmdEh+0x10>
+  ENABLE_WAIT();
+  LCD_CONTROL_PORT &= ~(1<<LCD_E);
+  c2:  00 c0           rjmp    .+0             ; 0xc4 <_ZN3Lcd6putCmdEh+0x12>
+  c4:  96 98           cbi     0x12, 6 ; 18
+  NOP();
+  c6:  00 00           nop
+  LCD_CONTROL_PORT |= (1<<LCD_RS);
+  c8:  95 9a           sbi     0x12, 5 ; 18
+}
+  ca:  1f 91           pop     r17
+  cc:  08 95           ret
+
+000000ce <main>:
+  }
+};
+
+
+MAIN_FUNC() {
+  MCUSR = 0; // clear all reset flags
+  ce:  14 be           out     0x34, r1        ; 52
+    WDTCSR &= ~(1<<WDCE);
+    sei();
+  }
+  
+  INLINE_FUNC_DECLARE(static void reset(void)) { 
+    wdt_reset(); 
+  d0:  a8 95           wdr
+
+class Watchdog {
+public:
+  INLINE_FUNC_DECLARE(static void init(void)) {
+    reset();
+    WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)
+  d2:  81 b5           in      r24, 0x21       ; 33
+  d4:  88 61           ori     r24, 0x18       ; 24
+  d6:  81 bd           out     0x21, r24       ; 33
+    WDTCSR = (1<<WDE)|(1<<WDP3)|(1<<WDP0); // 1024K cycles, 8.0sec
+  d8:  89 e2           ldi     r24, 0x29       ; 41
+  da:  81 bd           out     0x21, r24       ; 33
+};
+  
+class SleepMode {
+public:
+  INLINE_FUNC_DECLARE(static void initIdleMode(void)) {
+    MCUCR &= ~((1<<SM1)|(1<<SM0)); // use idle sleep mode
+  dc:  85 b7           in      r24, 0x35       ; 53
+  de:  8f 7a           andi    r24, 0xAF       ; 175
+  e0:  85 bf           out     0x35, r24       ; 53
+
+public:
+  INLINE_FUNC_DECLARE(void init(void)) {
+    // setup PWM to run at 1.25ms per interrupt. 
+    // This allows 8 levels of brightness at minimum of 100Hz flicker rate.
+    TCCR0A = (1<<WGM01); // CTC mode
+  e2:  82 e0           ldi     r24, 0x02       ; 2
+  e4:  80 bf           out     0x30, r24       ; 48
+    TCCR0B = 0; // timer off
+  e6:  13 be           out     0x33, r1        ; 51
+    OCR0A = 72; // 1.25ms with CLK/256 prescaler @ 14.7456MHz
+  e8:  88 e4           ldi     r24, 0x48       ; 72
+  ea:  86 bf           out     0x36, r24       ; 54
+    TIMSK = (1<<OCIE0A); // Turn on timer0 COMPA intr (all other timer intr off)
+  ec:  81 e0           ldi     r24, 0x01       ; 1
+  ee:  89 bf           out     0x39, r24       ; 57
+#if USE_LED_PWM_IO_MEMBERS
+    *m_LedPortPtr &= ~(1<<m_LedPin); // Ensure LED is off during initialization
+    *m_LedDirPtr |= (1<<m_LedPin); // Ensure LED is output port
+#else
+    LED_PORT &= ~(1<<LED_PIN); // Ensure LED is off during initialization
+  f0:  91 98           cbi     0x12, 1 ; 18
+    LED_DIR |= (1<<LED_PIN); // Ensure LED is output port
+  f2:  89 9a           sbi     0x11, 1 ; 17
+#endif
+    BIT_led_on = 0;  // note that LED is off
+  f4:  a0 98           cbi     0x14, 0 ; 20
+    ledPwmPattern = 0xFF;  // maximum brightness
+  f6:  9f ef           ldi     r25, 0xFF       ; 255
+  f8:  93 bb           out     0x13, r25       ; 19
+  static const unsigned char m_DATA_8 = 0x30;
+
+public:
+  INLINE_FUNC_DECLARE(void init(void)) {
+    // Set BAUD_J2:BAUD_J1 PULL-UPS active
+    LCD_CONTROL_PORT = (1<<BAUD_J2) | (1<<BAUD_J1);
+  fa:  8c e0           ldi     r24, 0x0C       ; 12
+  fc:  82 bb           out     0x12, r24       ; 18
+    // Set LCD_control BAUD_J2:BAUD_J1 to inputs       
+    LCD_CONTROL_DIR = 0xF2;
+  fe:  82 ef           ldi     r24, 0xF2       ; 242
+ 100:  81 bb           out     0x11, r24       ; 17
+       __asm__ volatile (
+               "1: sbiw %0,1" "\n\t"
+               "brne 1b"
+               : "=w" (__count)
+               : "0" (__count)
+       );
+ 102:  e0 e0           ldi     r30, 0x00       ; 0
+ 104:  f8 ed           ldi     r31, 0xD8       ; 216
+ 106:  31 97           sbiw    r30, 0x01       ; 1
+ 108:  f1 f7           brne    .-4             ; 0x106 <__stack+0x27>
+    
+    Delay::millisec(15);
+    
+    LCD_CONTROL_PORT |= (1<<LCD_RS); // Set LCD_RS HIGH
+ 10a:  95 9a           sbi     0x12, 5 ; 18
+    
+    // Initialize the AVR controller I/O
+    LCD_DATA_DIR = 0xFF; // Set LCD_DATA_PORT as all outputs
+ 10c:  97 bb           out     0x17, r25       ; 23
+    LCD_DATA_PORT = 0x00; // Set LCD_DATA_PORT to logic low
+ 10e:  18 ba           out     0x18, r1        ; 24
+    
+    // Initialize the LCD controller
+    LCD_CONTROL_PORT &= ~(1<<LCD_RS);
+ 110:  95 98           cbi     0x12, 5 ; 18
+    
+    putChar (m_DATA_8); 
+ 112:  8d e6           ldi     r24, 0x6D       ; 109
+ 114:  90 e0           ldi     r25, 0x00       ; 0
+ 116:  60 e3           ldi     r22, 0x30       ; 48
+ 118:  bf df           rcall   .-130           ; 0x98 <_ZN3Lcd7putCharEh>
+ 11a:  8a e0           ldi     r24, 0x0A       ; 10
+ 11c:  9b e3           ldi     r25, 0x3B       ; 59
+ 11e:  01 97           sbiw    r24, 0x01       ; 1
+ 120:  f1 f7           brne    .-4             ; 0x11e <__stack+0x3f>
+    Delay::millisec(4.1);
+    
+    putChar (m_DATA_8);
+ 122:  8d e6           ldi     r24, 0x6D       ; 109
+ 124:  90 e0           ldi     r25, 0x00       ; 0
+ 126:  60 e3           ldi     r22, 0x30       ; 48
+ 128:  b7 df           rcall   .-146           ; 0x98 <_ZN3Lcd7putCharEh>
+ 12a:  80 e7           ldi     r24, 0x70       ; 112
+ 12c:  91 e0           ldi     r25, 0x01       ; 1
+ 12e:  01 97           sbiw    r24, 0x01       ; 1
+ 130:  f1 f7           brne    .-4             ; 0x12e <__stack+0x4f>
+    Delay::microsec(100);
+    
+    putChar (m_DATA_8);
+ 132:  8d e6           ldi     r24, 0x6D       ; 109
+ 134:  90 e0           ldi     r25, 0x00       ; 0
+ 136:  60 e3           ldi     r22, 0x30       ; 48
+ 138:  af df           rcall   .-162           ; 0x98 <_ZN3Lcd7putCharEh>
+    LCD_CONTROL_PORT |= (1<<LCD_RS);
+ 13a:  95 9a           sbi     0x12, 5 ; 18
+    
+    // The display will be out into 8 bit data mode here
+    putCmd (m_LINE_8x4); // Set 8 bit data, 4 display lines
+ 13c:  8d e6           ldi     r24, 0x6D       ; 109
+ 13e:  90 e0           ldi     r25, 0x00       ; 0
+ 140:  68 e3           ldi     r22, 0x38       ; 56
+ 142:  b7 df           rcall   .-146           ; 0xb2 <_ZN3Lcd6putCmdEh>
+    putCmd (m_PWR_ON); // Power up the display
+ 144:  8d e6           ldi     r24, 0x6D       ; 109
+ 146:  90 e0           ldi     r25, 0x00       ; 0
+ 148:  6c e0           ldi     r22, 0x0C       ; 12
+ 14a:  b3 df           rcall   .-154           ; 0xb2 <_ZN3Lcd6putCmdEh>
+    putCmd (m_CLR_DSP); // Power up the display
+ 14c:  8d e6           ldi     r24, 0x6D       ; 109
+ 14e:  90 e0           ldi     r25, 0x00       ; 0
+ 150:  61 e0           ldi     r22, 0x01       ; 1
+ 152:  af df           rcall   .-162           ; 0xb2 <_ZN3Lcd6putCmdEh>
+  }
+
+public:
+  INLINE_FUNC_DECLARE(void init(void)) {
+    // Initialize UART0 
+    UCSRB = 0; // Disable while setting baud rate
+ 154:  1a b8           out     0x0a, r1        ; 10
+    UCSRA = 0;
+ 156:  1b b8           out     0x0b, r1        ; 11
+    UCSRC = (1<<UCSZ1) | (1<<UCSZ0); // 8 bit data
+ 158:  86 e0           ldi     r24, 0x06       ; 6
+ 15a:  83 b9           out     0x03, r24       ; 3
+
+  INLINE_FUNC_DECLARE(static unsigned char baud()) {
+    unsigned char BaudSelectJumpersValue;
+  
+    // Get BAUD rate jumper settings      
+    BaudSelectJumpersValue  = BAUD_PIN_REG;
+ 15c:  e0 b3           in      r30, 0x10       ; 16
+    BaudSelectJumpersValue &= (1<<BAUD_J2) | (1<<BAUD_J1);
+    // BAUD_J2 = PD.3, BAUD_J1 = PD.2
+    // This is two bits too far to the left and the array index will
+    // increment by 4, instead of 1.
+    // Shift BAUD_J2 & BAUD_J1 right by two bit positions for proper array indexing
+    BaudSelectJumpersValue = (BaudSelectJumpersValue >> BAUD_J1);
+ 15e:  ec 70           andi    r30, 0x0C       ; 12
+    
+    return PGM_READ_BYTE (&BaudLookupTable[BaudSelectJumpersValue]);
+ 160:  e6 95           lsr     r30
+ 162:  e6 95           lsr     r30
+ 164:  f0 e0           ldi     r31, 0x00       ; 0
+ 166:  e8 59           subi    r30, 0x98       ; 152
+ 168:  ff 4f           sbci    r31, 0xFF       ; 255
+ 16a:  e4 91           lpm     r30, Z+
+  INLINE_FUNC_DECLARE(void init(void)) {
+    // Initialize UART0 
+    UCSRB = 0; // Disable while setting baud rate
+    UCSRA = 0;
+    UCSRC = (1<<UCSZ1) | (1<<UCSZ0); // 8 bit data
+    UBRRL = baud();
+ 16c:  e9 b9           out     0x09, r30       ; 9
+    UBRRH = 0; // Set baud rate hi
+ 16e:  12 b8           out     0x02, r1        ; 2
+    UCSRB = (1<<RXEN)|(1<<RXCIE); // RXEN = Enable
+ 170:  80 e9           ldi     r24, 0x90       ; 144
+ 172:  8a b9           out     0x0a, r24       ; 10
+
+    // Init circular buffer pointers
+    sUartRxHead = 0;
+ 174:  55 24           eor     r5, r5
+    sUartRxTail = 0;
+ 176:  66 24           eor     r6, r6
+
+  gLed.init();
+  gLcd.init();
+  gUart.init();   // Initialize the AVR USART  
+
+  sei();
+ 178:  78 94           sei
+
+  INLINE_FUNC_DECLARE(void stop(void)) {
+    TCCR0B = 0;
+  }
+  INLINE_FUNC_DECLARE(void start(void)) {
+    TCCR0B = (1<<CS02);
+ 17a:  14 e0           ldi     r17, 0x04       ; 4
+    return 1;
+  }
+
+  INLINE_FUNC_DECLARE(unsigned char charAvail(void)) {
+    unsigned char tail = sUartRxTail; // explicitly set order of volatile access
+    return (tail != sUartRxHead) ? 1 : 0;
+ 17c:  65 14           cp      r6, r5
+ 17e:  09 f4           brne    .+2             ; 0x182 <__stack+0xa3>
+ 180:  4e c0           rjmp    .+156           ; 0x21e <__stack+0x13f>
+  gUart.init();   // Initialize the AVR USART  
+
+  sei();
+  while (1) {
+    if (gUart.charAvail()) {
+      SerialCommandProcessor::processChar (gUart.waitRxChar());
+ 182:  8e e6           ldi     r24, 0x6E       ; 110
+ 184:  90 e0           ldi     r25, 0x00       ; 0
+ 186:  69 df           rcall   .-302           ; 0x5a <_ZN4Uart10waitRxCharEv>
+ 188:  68 2f           mov     r22, r24
+
+public:
+  INLINE_FUNC_DECLARE(static void processChar(unsigned char ch)) {
+    // avoid use of switch statement as ImageCraft and GCC produce signifcantly
+    // more code for a switch statement than a sequence of if/else if
+    if (ch == m_LED_SW_OFF) {
+ 18a:  8d 3f           cpi     r24, 0xFD       ; 253
+ 18c:  21 f4           brne    .+8             ; 0x196 <__stack+0xb7>
+
+  INLINE_FUNC_DECLARE(void lampOff(void)) {
+#if USE_LED_PWM_IO_MEMBERS
+    *m_LedPortPtr &= ~(1<<m_LedPin);;
+#else
+    LED_PORT &= ~(1<<LED_PIN);;
+ 18e:  91 98           cbi     0x12, 1 ; 18
+    TCCR0B = (1<<CS02);
+  }
+
+  INLINE_FUNC_DECLARE(void switchOff(void)) {
+    lampOff();
+    BIT_led_on = 0;
+ 190:  a0 98           cbi     0x14, 0 ; 20
+    BIT_led_on = 0;  // note that LED is off
+    ledPwmPattern = 0xFF;  // maximum brightness
+  }
+
+  INLINE_FUNC_DECLARE(void stop(void)) {
+    TCCR0B = 0;
+ 192:  13 be           out     0x33, r1        ; 51
+ 194:  f3 cf           rjmp    .-26            ; 0x17c <__stack+0x9d>
+  INLINE_FUNC_DECLARE(static void processChar(unsigned char ch)) {
+    // avoid use of switch statement as ImageCraft and GCC produce signifcantly
+    // more code for a switch statement than a sequence of if/else if
+    if (ch == m_LED_SW_OFF) {
+      gLed.switchOff();
+    } else if (ch == m_LED_SW_ON) {
+ 196:  8c 3f           cpi     r24, 0xFC       ; 252
+ 198:  29 f4           brne    .+10            ; 0x1a4 <__stack+0xc5>
+    BIT_led_on = 0;
+    stop();
+  }
+
+  INLINE_FUNC_DECLARE(void switchOn(void)) {
+    BIT_led_on = 1;
+ 19a:  a0 9a           sbi     0x14, 0 ; 20
+    if (ledPwmPattern == 0xFF) { // maximum brightness, no need for PWM
+ 19c:  83 b3           in      r24, 0x13       ; 19
+ 19e:  8f 3f           cpi     r24, 0xFF       ; 255
+ 1a0:  71 f5           brne    .+92            ; 0x1fe <__stack+0x11f>
+ 1a2:  28 c0           rjmp    .+80            ; 0x1f4 <__stack+0x115>
+    // more code for a switch statement than a sequence of if/else if
+    if (ch == m_LED_SW_OFF) {
+      gLed.switchOff();
+    } else if (ch == m_LED_SW_ON) {
+      gLed.switchOn();
+    } else if (ch == m_LED_SET_BRIGHTNESS) {
+ 1a4:  8b 3f           cpi     r24, 0xFB       ; 251
+ 1a6:  69 f5           brne    .+90            ; 0x202 <__stack+0x123>
+      // read next byte which will be brightness
+      gLed.setBrightness(gUart.waitRxChar());
+ 1a8:  8e e6           ldi     r24, 0x6E       ; 110
+ 1aa:  90 e0           ldi     r25, 0x00       ; 0
+ 1ac:  56 df           rcall   .-340           ; 0x5a <_ZN4Uart10waitRxCharEv>
+      start();
+    }
+  }
+
+  INLINE_FUNC_DECLARE(void setBrightness(unsigned char brightness)) {
+    if (brightness == 0) { // turn backlight off for 0 brightness
+ 1ae:  88 23           and     r24, r24
+ 1b0:  39 f4           brne    .+14            ; 0x1c0 <__stack+0xe1>
+      if (BIT_led_on) {
+ 1b2:  a0 9b           sbis    0x14, 0 ; 20
+ 1b4:  e3 cf           rjmp    .-58            ; 0x17c <__stack+0x9d>
+    BIT_led_on = 0;  // note that LED is off
+    ledPwmPattern = 0xFF;  // maximum brightness
+  }
+
+  INLINE_FUNC_DECLARE(void stop(void)) {
+    TCCR0B = 0;
+ 1b6:  13 be           out     0x33, r1        ; 51
+
+  INLINE_FUNC_DECLARE(void setBrightness(unsigned char brightness)) {
+    if (brightness == 0) { // turn backlight off for 0 brightness
+      if (BIT_led_on) {
+        stop();
+        ledPwmPattern = 0;
+ 1b8:  13 ba           out     0x13, r1        ; 19
+        ledPwmCycling = 0;
+ 1ba:  77 24           eor     r7, r7
+
+  INLINE_FUNC_DECLARE(void lampOff(void)) {
+#if USE_LED_PWM_IO_MEMBERS
+    *m_LedPortPtr &= ~(1<<m_LedPin);;
+#else
+    LED_PORT &= ~(1<<LED_PIN);;
+ 1bc:  91 98           cbi     0x12, 1 ; 18
+ 1be:  de cf           rjmp    .-68            ; 0x17c <__stack+0x9d>
+        lampOff();
+      }
+      return;
+    }
+
+    unsigned char ledPwmPos = (brightness * (LED_BRIGHTNESS_LEVELS-1) + 127) >> 8; 
+ 1c0:  90 e0           ldi     r25, 0x00       ; 0
+ 1c2:  67 e0           ldi     r22, 0x07       ; 7
+ 1c4:  70 e0           ldi     r23, 0x00       ; 0
+ 1c6:  81 d0           rcall   .+258           ; 0x2ca <__mulhi3>
+ 1c8:  81 58           subi    r24, 0x81       ; 129
+ 1ca:  9f 4f           sbci    r25, 0xFF       ; 255
+ 1cc:  89 2f           mov     r24, r25
+ 1ce:  99 0f           add     r25, r25
+ 1d0:  99 0b           sbc     r25, r25
+ 1d2:  98 2f           mov     r25, r24
+ 1d4:  88 30           cpi     r24, 0x08       ; 8
+ 1d6:  08 f0           brcs    .+2             ; 0x1da <__stack+0xfb>
+ 1d8:  97 e0           ldi     r25, 0x07       ; 7
+    LED_PORT &= ~(1<<LED_PIN);;
+#endif
+  }
+
+  INLINE_FUNC_DECLARE(unsigned char pwmPattern(unsigned char pos)) {
+    return PGM_READ_BYTE (&ledPwmPatterns[pos]);
+ 1da:  e9 2f           mov     r30, r25
+ 1dc:  f0 e0           ldi     r31, 0x00       ; 0
+ 1de:  e0 5a           subi    r30, 0xA0       ; 160
+ 1e0:  ff 4f           sbci    r31, 0xFF       ; 255
+ 1e2:  e4 91           lpm     r30, Z+
+
+    unsigned char ledPwmPos = (brightness * (LED_BRIGHTNESS_LEVELS-1) + 127) >> 8; 
+    // Below is probably not required, but ensures we don't exceed array
+    if (ledPwmPos > LED_BRIGHTNESS_LEVELS - 1)
+      ledPwmPos = LED_BRIGHTNESS_LEVELS - 1;
+    ledPwmPattern = pwmPattern(ledPwmPos);
+ 1e4:  e3 bb           out     0x13, r30       ; 19
+    ledPwmCount = 0;
+ 1e6:  44 24           eor     r4, r4
+    ledPwmCycling = ledPwmPattern;
+ 1e8:  83 b3           in      r24, 0x13       ; 19
+ 1ea:  78 2e           mov     r7, r24
+    if (ledPwmPos >= LED_BRIGHTNESS_LEVELS-1) { // maximum brightness
+ 1ec:  97 30           cpi     r25, 0x07       ; 7
+ 1ee:  29 f4           brne    .+10            ; 0x1fa <__stack+0x11b>
+      // don't need PWM to continuously on
+      if (BIT_led_on) {
+ 1f0:  a0 9b           sbis    0x14, 0 ; 20
+ 1f2:  c4 cf           rjmp    .-120           ; 0x17c <__stack+0x9d>
+    BIT_led_on = 0;  // note that LED is off
+    ledPwmPattern = 0xFF;  // maximum brightness
+  }
+
+  INLINE_FUNC_DECLARE(void stop(void)) {
+    TCCR0B = 0;
+ 1f4:  13 be           out     0x33, r1        ; 51
+
+  INLINE_FUNC_DECLARE(void lampOn(void)) {
+#if USE_LED_PWM_IO_MEMBERS
+    *m_LedPortPtr |= (1<<m_LedPin);
+#else
+    LED_PORT |= (1<<LED_PIN);
+ 1f6:  91 9a           sbi     0x12, 1 ; 18
+ 1f8:  c1 cf           rjmp    .-126           ; 0x17c <__stack+0x9d>
+      if (BIT_led_on) {
+        stop();
+        lampOn();
+      }
+    } else {
+      if (BIT_led_on) {
+ 1fa:  a0 9b           sbis    0x14, 0 ; 20
+ 1fc:  bf cf           rjmp    .-130           ; 0x17c <__stack+0x9d>
+
+  INLINE_FUNC_DECLARE(void stop(void)) {
+    TCCR0B = 0;
+  }
+  INLINE_FUNC_DECLARE(void start(void)) {
+    TCCR0B = (1<<CS02);
+ 1fe:  13 bf           out     0x33, r17       ; 51
+ 200:  bd cf           rjmp    .-134           ; 0x17c <__stack+0x9d>
+    } else if (ch == m_LED_SW_ON) {
+      gLed.switchOn();
+    } else if (ch == m_LED_SET_BRIGHTNESS) {
+      // read next byte which will be brightness
+      gLed.setBrightness(gUart.waitRxChar());
+    } else if (ch == m_REG_MODE) {
+ 202:  8e 3f           cpi     r24, 0xFE       ; 254
+ 204:  41 f4           brne    .+16            ; 0x216 <__stack+0x137>
+      gLcd.putCmd (gUart.waitRxChar()); // Send LCD command character
+ 206:  8e e6           ldi     r24, 0x6E       ; 110
+ 208:  90 e0           ldi     r25, 0x00       ; 0
+ 20a:  27 df           rcall   .-434           ; 0x5a <_ZN4Uart10waitRxCharEv>
+ 20c:  68 2f           mov     r22, r24
+ 20e:  8d e6           ldi     r24, 0x6D       ; 109
+ 210:  90 e0           ldi     r25, 0x00       ; 0
+ 212:  4f df           rcall   .-354           ; 0xb2 <_ZN3Lcd6putCmdEh>
+ 214:  b3 cf           rjmp    .-154           ; 0x17c <__stack+0x9d>
+    } else {
+      gLcd.putChar (ch); // Send LCD data character
+ 216:  8d e6           ldi     r24, 0x6D       ; 109
+ 218:  90 e0           ldi     r25, 0x00       ; 0
+ 21a:  3e df           rcall   .-388           ; 0x98 <_ZN3Lcd7putCharEh>
+ 21c:  af cf           rjmp    .-162           ; 0x17c <__stack+0x9d>
+    reset();
+    WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)
+    WDTCSR = (1<<WDE)|(1<<WDP3)|(1<<WDP0); // 1024K cycles, 8.0sec
+  }
+  INLINE_FUNC_DECLARE(static void off(void)) {
+    cli();
+ 21e:  f8 94           cli
+    WDTCSR &= ~(1<<WDCE);
+    sei();
+  }
+  
+  INLINE_FUNC_DECLARE(static void reset(void)) { 
+    wdt_reset(); 
+ 220:  a8 95           wdr
+    WDTCSR = (1<<WDE)|(1<<WDP3)|(1<<WDP0); // 1024K cycles, 8.0sec
+  }
+  INLINE_FUNC_DECLARE(static void off(void)) {
+    cli();
+    reset();
+    MCUSR &= ~(1<<WDRF); // clear any watchdog interrupt flags
+ 222:  84 b7           in      r24, 0x34       ; 52
+ 224:  87 7f           andi    r24, 0xF7       ; 247
+ 226:  84 bf           out     0x34, r24       ; 52
+    WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)
+ 228:  81 b5           in      r24, 0x21       ; 33
+ 22a:  88 61           ori     r24, 0x18       ; 24
+ 22c:  81 bd           out     0x21, r24       ; 33
+    WDTCSR &= ~(1<<WDE); // watchdog timer off
+ 22e:  81 b5           in      r24, 0x21       ; 33
+ 230:  87 7f           andi    r24, 0xF7       ; 247
+ 232:  81 bd           out     0x21, r24       ; 33
+    sei();
+ 234:  78 94           sei
+public:
+  INLINE_FUNC_DECLARE(static void initIdleMode(void)) {
+    MCUCR &= ~((1<<SM1)|(1<<SM0)); // use idle sleep mode
+  }
+  INLINE_FUNC_DECLARE(static void enterSleep()) {
+    sleep_enable();
+ 236:  85 b7           in      r24, 0x35       ; 53
+ 238:  80 62           ori     r24, 0x20       ; 32
+ 23a:  85 bf           out     0x35, r24       ; 53
+    sleep_cpu();
+ 23c:  88 95           sleep
+    sleep_disable();
+ 23e:  85 b7           in      r24, 0x35       ; 53
+ 240:  8f 7d           andi    r24, 0xDF       ; 223
+ 242:  85 bf           out     0x35, r24       ; 53
+    WDTCSR &= ~(1<<WDE); // watchdog timer off
+    sei();
+  }
+  
+  INLINE_FUNC_DECLARE(static void on(void)) {
+    cli();
+ 244:  f8 94           cli
+    WDTCSR &= ~(1<<WDCE);
+    sei();
+  }
+  
+  INLINE_FUNC_DECLARE(static void reset(void)) { 
+    wdt_reset(); 
+ 246:  a8 95           wdr
+  }
+  
+  INLINE_FUNC_DECLARE(static void on(void)) {
+    cli();
+    reset();
+    WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)
+ 248:  81 b5           in      r24, 0x21       ; 33
+ 24a:  88 61           ori     r24, 0x18       ; 24
+ 24c:  81 bd           out     0x21, r24       ; 33
+    WDTCSR &= ~(1<<WDCE);
+ 24e:  81 b5           in      r24, 0x21       ; 33
+ 250:  8f 7e           andi    r24, 0xEF       ; 239
+ 252:  81 bd           out     0x21, r24       ; 33
+    sei();
+ 254:  78 94           sei
+ 256:  92 cf           rjmp    .-220           ; 0x17c <__stack+0x9d>
+
+00000258 <__vector_7>:
+  LCD_DATA_DIR = 0xFF; // Set LCD data port to default output state
+  return (LCDStatus);
+}               
+
+
+ISR(USART_RX_vect)
+ 258:  1f 92           push    r1
+ 25a:  0f 92           push    r0
+ 25c:  0f b6           in      r0, 0x3f        ; 63
+ 25e:  0f 92           push    r0
+ 260:  11 24           eor     r1, r1
+ 262:  8f 93           push    r24
+ 264:  ef 93           push    r30
+ 266:  ff 93           push    r31
+{
+  gUart.storeChar(UDR);
+ 268:  8c b1           in      r24, 0x0c       ; 12
+#endif
+  }
+
+  INLINE_FUNC_DECLARE(unsigned char storeChar(unsigned char rx)) {
+    // Calculate next buffer position.
+    unsigned char tmphead = sUartRxHead;
+ 26a:  e5 2d           mov     r30, r5
+    if (tmphead == UART_RX_BUFFER_SIZE-1)
+ 26c:  ef 32           cpi     r30, 0x2F       ; 47
+ 26e:  11 f4           brne    .+4             ; 0x274 <__vector_7+0x1c>
+ 270:  e0 e0           ldi     r30, 0x00       ; 0
+ 272:  01 c0           rjmp    .+2             ; 0x276 <__vector_7+0x1e>
+      tmphead = 0;
+    else
+      tmphead++;
+ 274:  ef 5f           subi    r30, 0xFF       ; 255
+    
+    // store in buffer if there is room
+    if (tmphead != sUartRxTail) {
+ 276:  e6 15           cp      r30, r6
+ 278:  29 f0           breq    .+10            ; 0x284 <__vector_7+0x2c>
+      sUartRxHead = tmphead;         // Store new index.
+ 27a:  5e 2e           mov     r5, r30
+      m_UartRxBuf[tmphead] = rx;
+ 27c:  f0 e0           ldi     r31, 0x00       ; 0
+ 27e:  e2 59           subi    r30, 0x92       ; 146
+ 280:  ff 4f           sbci    r31, 0xFF       ; 255
+ 282:  80 83           st      Z, r24
+
+
+ISR(USART_RX_vect)
+{
+  gUart.storeChar(UDR);
+}
+ 284:  ff 91           pop     r31
+ 286:  ef 91           pop     r30
+ 288:  8f 91           pop     r24
+ 28a:  0f 90           pop     r0
+ 28c:  0f be           out     0x3f, r0        ; 63
+ 28e:  0f 90           pop     r0
+ 290:  1f 90           pop     r1
+ 292:  18 95           reti
+
+00000294 <__vector_13>:
+
+ISR(TIMER0_COMPA_vect)
+ 294:  1f 92           push    r1
+ 296:  0f 92           push    r0
+ 298:  0f b6           in      r0, 0x3f        ; 63
+ 29a:  0f 92           push    r0
+ 29c:  11 24           eor     r1, r1
+ 29e:  8f 93           push    r24
+{  
+  sei(); // Okay to allow USART interrupts while controlling LED PWM
+ 2a0:  78 94           sei
+      }
+    }
+  }
+
+  INLINE_FUNC_DECLARE(void cyclePwm(void)) {
+    if (ledPwmCycling & 0x01) {   // Set current LED state based on cycling variable
+ 2a2:  70 fe           sbrs    r7, 0
+ 2a4:  02 c0           rjmp    .+4             ; 0x2aa <__vector_13+0x16>
+
+  INLINE_FUNC_DECLARE(void lampOn(void)) {
+#if USE_LED_PWM_IO_MEMBERS
+    *m_LedPortPtr |= (1<<m_LedPin);
+#else
+    LED_PORT |= (1<<LED_PIN);
+ 2a6:  91 9a           sbi     0x12, 1 ; 18
+ 2a8:  01 c0           rjmp    .+2             ; 0x2ac <__vector_13+0x18>
+
+  INLINE_FUNC_DECLARE(void lampOff(void)) {
+#if USE_LED_PWM_IO_MEMBERS
+    *m_LedPortPtr &= ~(1<<m_LedPin);;
+#else
+    LED_PORT &= ~(1<<LED_PIN);;
+ 2aa:  91 98           cbi     0x12, 1 ; 18
+    } else {
+      lampOff();
+    }
+
+    // Update cycling variable for next interrupt
+    if (ledPwmCount >= LED_BRIGHTNESS_LEVELS-1) {
+ 2ac:  86 e0           ldi     r24, 0x06       ; 6
+ 2ae:  84 15           cp      r24, r4
+ 2b0:  20 f4           brcc    .+8             ; 0x2ba <__vector_13+0x26>
+      ledPwmCount = 0;
+ 2b2:  44 24           eor     r4, r4
+      ledPwmCycling = ledPwmPattern;
+ 2b4:  83 b3           in      r24, 0x13       ; 19
+ 2b6:  78 2e           mov     r7, r24
+ 2b8:  02 c0           rjmp    .+4             ; 0x2be <__vector_13+0x2a>
+    } else {
+      ledPwmCount++;
+ 2ba:  43 94           inc     r4
+      ledPwmCycling >>= 1;
+ 2bc:  76 94           lsr     r7
+ISR(TIMER0_COMPA_vect)
+{  
+  sei(); // Okay to allow USART interrupts while controlling LED PWM
+
+  gLed.cyclePwm();
+}
+ 2be:  8f 91           pop     r24
+ 2c0:  0f 90           pop     r0
+ 2c2:  0f be           out     0x3f, r0        ; 63
+ 2c4:  0f 90           pop     r0
+ 2c6:  1f 90           pop     r1
+ 2c8:  18 95           reti
+
+000002ca <__mulhi3>:
+ 2ca:  55 27           eor     r21, r21
+ 2cc:  00 24           eor     r0, r0
+
+000002ce <__mulhi3_loop>:
+ 2ce:  80 ff           sbrs    r24, 0
+ 2d0:  02 c0           rjmp    .+4             ; 0x2d6 <__mulhi3_skip1>
+ 2d2:  06 0e           add     r0, r22
+ 2d4:  57 1f           adc     r21, r23
+
+000002d6 <__mulhi3_skip1>:
+ 2d6:  66 0f           add     r22, r22
+ 2d8:  77 1f           adc     r23, r23
+ 2da:  61 15           cp      r22, r1
+ 2dc:  71 05           cpc     r23, r1
+ 2de:  21 f0           breq    .+8             ; 0x2e8 <__mulhi3_exit>
+ 2e0:  96 95           lsr     r25
+ 2e2:  87 95           ror     r24
+ 2e4:  00 97           sbiw    r24, 0x00       ; 0
+ 2e6:  99 f7           brne    .-26            ; 0x2ce <__mulhi3_loop>
+
+000002e8 <__mulhi3_exit>:
+ 2e8:  95 2f           mov     r25, r21
+ 2ea:  80 2d           mov     r24, r0
+ 2ec:  08 95           ret
+
+000002ee <_exit>:
+ 2ee:  f8 94           cli
+
+000002f0 <__stop_program>:
+ 2f0:  ff cf           rjmp    .-2             ; 0x2f0 <__stop_program>