Created
October 30, 2012 13:57
-
-
Save MrTrick/3980309 to your computer and use it in GitHub Desktop.
Code for the Widget's Firefly Application
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;********************************************************************** | |
; * | |
; 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