Skip to content

Instantly share code, notes, and snippets.

@MrTrick
Created October 30, 2012 13:57
Show Gist options
  • Save MrTrick/3980309 to your computer and use it in GitHub Desktop.
Save MrTrick/3980309 to your computer and use it in GitHub Desktop.
Code for the Widget's Firefly Application
;**********************************************************************
; *
; Filename: firefly.asm *
; Date: 2007-11-22 *
; File Version: 1.0a *
; Author: MrTrick *
; Description: This file provides relocatable code for managing *
; the logic of a group of fireflies, where all the *
; fireflies will 'flash' regularly, and slowly become*
; irregularly synchronised with each other. *
;**********************************************************************
; Notes: *
; *
; This code assumes the same arrangement of fireflies as the LEDs in*
; charlie_round20.asm when calculating neighbours of any firefly. *
; *
; the get_neighbours function uses a lookup table - ensure it does *
; not straddle 0xFF blocks. *
; *
;**********************************************************************
#include <p12F683.inc> ; processor specific variable definitions
#include constants.inc ; project-specific constants
;----Global labels-----
; Externally-accessible functions
global firefly_start, firefly_is_lit, firefly_icon, firefly_button_change
; Dependent Functions/Vars
extern random_init, random_next, delay_short, inc_pointer
extern next_N, next_NE, next_SE, next_S, next_SW, next_NW
extern led_data ; Store firefly counts in led_data
extern event_arg
;----Constants----
FIREFLY_NEIGHBOUR_IMPULSE EQU 0x03
FIREFLY_OFF_THRESHOLD EQU 0x05
FIREFLY_REST_THRESHOLD EQU 0x20
FIREFLY_DELAY EQU 0x42
;----Variables----
program udata_ovr ;(Shared with other programs)
firefly_index res 1 ; Keep an index into the firefly array.
;----Code----
LOOKUP code
; *
; * *
; o o o
; * o
; o * o
; * o
; o o o
; * o
; o
; Update the image.
firefly_icon dt b'00000000', b'11110010', b'10001000'
;----Function definitions
firefly code
firefly_button_change
call firefly_init ; If a button is pressed, scramble the fireflies
return
; Program entry point
firefly_start
;Initialise the program
call random_init
clrf firefly_index
call firefly_init
; Main loop
firefly_main
;movlw FIREFLY_DELAY ; Pause...
call random_next ; DELAY by a random amount of time...
call delay_short ;
call inc_firefly ; Increment a firefly
goto firefly_main ; Repeat.
; Initialise each firefly to a random value.
firefly_init
clrf firefly_index
firefly_init.loop
movfw firefly_index ; Go to led_data[index]
addlw led_data ;
movwf FSR ;
call random_next ; Get a random number
movwf INDF ; Put it in led_data[index]
movlw firefly_index ; Increment the index
call inc_pointer ;
movfw firefly_index ; Initialised all led_data yet?
btfss STATUS, Z ;
goto firefly_init.loop ; No, next.
; Yes.
return
; Given a LED number in W (led_data[W] in *INDF), returns whether that LED should be lit.
; Returns 'true' for fireflies with count 0->THRESHOLD, and 'false' otherwise.
; (This function is a call-back from charlie_round20.asm's display function)
firefly_is_lit
;Add some randomness to when it will light up...
call random_next
andlw b'00000111'
addwf INDF, W
;movfw INDF ;
sublw FIREFLY_OFF_THRESHOLD ; and do W = threshold - count.
btfsc STATUS, C ; Is led_data[W] <= threshold?
retlw 0xFF ; Yes, return 'true' - LED on.
retlw 0x00 ; No, return 'false' - LED off.
; This function moves the index to the next firefly, and increments its count.
inc_firefly
movlw firefly_index ; Increment the firefly index
call inc_pointer ;
movlw led_data ; Move the indirect address to the firefly array, plus the index.
addwf firefly_index, W ;
movwf FSR ; (INDF now references led_data[ index ] )
incfsz INDF,F ; Increment the firefly's count. Is it 0?
return ; No, done for now.
; Yes, the firefly will 'blink'. - increment its neighbours.
movfw firefly_index
call next_N
call inc_neighbour
movfw firefly_index
call next_NE
call inc_neighbour
movfw firefly_index
call next_SE
call inc_neighbour
movfw firefly_index
call next_S
call inc_neighbour
movfw firefly_index
call next_SW
call inc_neighbour
movfw firefly_index
call next_NW
call inc_neighbour
return
; Increment the neighbour at W, unless W is 0xFF
inc_neighbour
xorlw 0xFF
btfsc STATUS, Z ; Is the neighbour argument 0xFF (error) ?
return ; Yes, don't increment any firefly this call.
xorlw 0xFF ;
addlw led_data ; Add W to the start of the led_data array.
movwf FSR ; INDF now references led_data[ W ]
movfw INDF ; Is that neighbour below the rest threshold? (still resting, doesn't increment)
sublw FIREFLY_REST_THRESHOLD
btfsc STATUS, C
return ; Yes, don't increment it.
movlw FIREFLY_NEIGHBOUR_IMPULSE ; Add the IMPULSE to that neighbour firefly.
addwf INDF, F ;
btfss STATUS, C ; Did the neighbour's count overflow?
return ; No, return.
movlw 0xff ; Yes, set it to 0xff (so that it will trigger properly next time it's run.)
movwf INDF ;
return
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment