
.include "msp430g2x31.inc"

LED0_LEN equ 0x200
LED1_LEN equ 0x202
LED2_LEN equ 0x204
LED3_LEN equ 0x206
LED4_LEN equ 0x208
LED5_LEN equ 0x20a
LED6_LEN equ 0x20c

LED0_DIR equ 0x210
LED1_DIR equ 0x212
LED2_DIR equ 0x214
LED3_DIR equ 0x216
LED4_DIR equ 0x218
LED5_DIR equ 0x21a

  org 0xf800
start:
  ;; Turn off watchdog
  mov.w #0x5a80, &WDTCTL

  ;; Please don't interrupt me
  dint

  ;; Set up stack pointer
  mov.w #0x0280, SP

  ;; Set up crystal
  mov.b #(DCO_3), &DCOCTL
  mov.b #(RSEL_15), &BCSCTL1
  mov.b #0, &BCSCTL2

  ;; Set up output pins
  mov.b #0x73, &P1DIR        ; P1.0 P1.1
  mov.b #0x00, &P1OUT
  mov.b #0x40, &P2DIR        ; P1.0 P1.1
  mov.b #0x00, &P2OUT
  mov.b #0x00, &P2SEL

  ;; Set up A/D
  ;mov.w #(ADC10ON), &ADC10CTL0
  ;mov.w #(INCH_2|ADC10SSEL_2), &ADC10CTL1

  ;; Set up Timer
  mov.w #3000, &TACCR0
  mov.w #(TASSEL_2|MC_1), &TACTL ; SMCLK, DIV1, COUNT to TACCR0
  mov.w #CCIE, &TACCTL0
  mov.w #0, &TACCTL1

  mov.w #100, &LED0_LEN
  mov.w #500, &LED1_LEN
  mov.w #200, &LED2_LEN
  mov.w #900, &LED3_LEN
  mov.w #700, &LED4_LEN
  mov.w #300, &LED5_LEN

  mov.w #1, &LED0_DIR
  mov.w #-1, &LED1_DIR
  mov.w #1, &LED2_DIR
  mov.w #-1, &LED3_DIR
  mov.w #1, &LED4_DIR
  mov.w #-1, &LED5_DIR

  ;; Okay, I can be interrupted now
  eint

  mov.w #1, r10    ; count direction
  mov.w #1, r12    ; update flag

main:
  ;cmp.w #5, r12
  ;jeq main
  cmp.w #0x73, &P1OUT
  jeq main

update_led0:
  cmp.w &LED0_LEN, &TAR
  jl update_led1
  bis.b #0x01, &P1OUT
  ;inc.w r12

update_led1:
  cmp.w &LED1_LEN, &TAR
  jl update_led2
  bis.b #0x02, &P1OUT
  ;inc.w r12

update_led2:
  cmp.w &LED2_LEN, &TAR
  jl update_led3
  bis.b #0x10, &P1OUT
  ;inc.w r12

update_led3:
  cmp.w &LED3_LEN, &TAR
  jl update_led4
  bis.b #0x20, &P1OUT
  ;inc.w r12

update_led4:
  cmp.w &LED4_LEN, &TAR
  jl update_led5
  bis.b #0x40, &P1OUT
  ;inc.w r12

update_led5:
  cmp.w &LED5_LEN, &TAR
  jl main
  bis.b #0x40, &P2OUT
  ;inc.w r12

  jmp main

timer_interrupt:
  mov.b #0x00, &P1OUT
  mov.b #0x00, &P2OUT
  ;mov.w #0, r12

.if 0
  add.w r10, &LED0_LEN
  cmp.w #1093, &LED0_LEN
  jne not_top
  mov.w #-1, r10
not_top:
  cmp.w #0, &LED0_LEN
  jne not_bottom
  mov.w #1, r10
not_bottom:
.endif

  mov.w #LED0_LEN, r5
  mov.w #LED0_DIR, r6
inc_loop:
  add.w @r6, 0(r5)
  cmp.w #3000, 0(r5)
  jne not_top
  mov.w #-1, 0(r6)
not_top:
  cmp.w #0, 0(r5)
  jne not_bottom
  mov.w #1, 0(r6)
not_bottom:
  add.w #2, r5
  add.w #2, r6
  cmp.w #LED6_LEN, r5
  jne inc_loop

exit_interrupt:
  reti

  org 0xffe8
vectors:
  dw 0
  dw 0
  dw 0
  dw 0
  dw 0
  dw timer_interrupt       ; Timer_A2 TACCR0, CCIFG
  dw 0
  dw 0
  dw 0
  dw 0
  dw 0
  dw start                 ; Reset


