; ; AUTOGENERATED FILE - DO NOT EDIT ; ; This file is generated from fmtb_pic.c ; using cpp and sed (with picsim2pic.seds). ; See Makefile wparse.inc rule for exact commands. ; MWN_OCT_MASK equ 0x07 MWN_CNT_MASK equ 0x18 MWN_PULSE equ 0x80 MWN_DIR equ 0x40 MWN_MORE equ 0x20 #define PIC_MWN_END(m) (!((m)&MWN_MORE)) #define PIC_MWN_MORE(m) ((m)&MWN_MORE) #define PIC_MWN_PULSE(m) ((m)&MWN_PULSE) #define PIC_MWN_OCT(m) ((m)&MWN_OCT_MASK) #define PIC_MWN_CNT(m) (PIC_MWN_PULSE(m)?0:((((m)&MWN_CNT_MASK)>>3)+1)) #define PIC_MWN_DIR(m) (PIC_MWN_PULSE(m)?0:(((m)>>6)&1)?-1:1) PIC_MWN_END_SPELLS equ 0xffff #define TOKEN_SHAPE(tok) (((tok)&0x70)>>4) #define TOKEN_DIR(tok) (((tok)&0x80)?-1:1) #define TOKEN_ANGLE(tok) (((tok)&0x0f)<<1) MTOKEN_END equ (0xfe) STOKEN_END equ (0x00) TOK_DIR equ 0x80 TOK_SHAPE_MASK equ 0x70 TOK_ANGLE_MASK equ 0x0f MSHF_PLUS equ 0x01 ; (part of shape) MSHF_PULSE equ 0x04 ; (part of shape) MSHF_CLEAN equ 0x02 ; (part of shape) MSHF_SHP_MASK equ 0x07 ; (all bits of shape) MSHF_FLG_MASK equ (~MSHF_SHP_MASK) ; (flag bits from shape) MSHF_DIR equ 0x08 ; dir (set if cw (negative)) MSHF_CIRCLE equ 0x20 ; MSHF_PREV_PAUSE equ 0x80 ; set if preceded by pause MSHF_MONO equ 0x40 ; MSHF_NEAR_PLUS equ 0x10 ; set if near a plus MSHF_ZERO equ 0x01 ; hit zero ANGLE_END equ 0xc0 ANGLE_START equ 0xa0 ANGLE_MASK equ 0x1f AFLG_END equ 0x40 AFLG_START equ 0x20 AFLG_STARTEND equ 0x80 SSHP_PAUSE equ 0 SSHP_CIRCLE equ 1 SSHP_OCIRCLE equ 2 SSHP_OPULSE equ 3 SSHP_PULSE equ 4 SSHP_WILD equ 5 SSHP_CNT equ 6 MSHP_DIRTY_CIRCLE equ 0 MSHP_DIRTY_CIRCLE_PLUS equ 1 MSHP_CLEAN_CIRCLE equ 2 MSHP_CLEAN_CIRCLE_PLUS equ 3 MSHP_PULSE equ 4 MSHP_PULSE_PLUS equ 5 MSHP_CIRCLE_GAP equ 6 MSHP_PAUSE equ 7 MSHP_CNT equ 8 PIC_CSIM equ 0 ALLOW_GAPS_IN_STRONG_CIRCLES equ 1 FIX_CIRCLE_OCT_COMPARE equ 1 MAX_TOKEN_CNT equ 256 USE_LEDSCAN equ 1 b_MSHF_PLUS equ 0 b_MSHF_ZERO equ 0 b_MSHF_DIR equ 3 b_MSHF_CIRCLE equ 5 b_MSHF_MONO equ 6 b_MSHF_PREV_PAUSE equ 7 b_TOK_DIR equ 7 b_AFLG_END equ 6 b_AFLG_START equ 5 b_MWN_PULSE equ 7 b_MWN_DIR equ 6 b_MWN_MORE equ 5 b_mo1_was_pause equ 0 b_mo1_got_angle equ 1 b_mo1_got_dir equ 2 b_mo2_cnt1b equ 0 b_mo2_added equ 1 b_mo2_savenext equ 2 b_mo7_was_23circle equ 0 b_mo7_was_pulse equ 1 b_mo7_optional equ 2 b_mo7_endspells equ 3 b_mo7_prev_dir equ 6 FAST_SCORE_TOK equ 0 v_mo1_asum equ vaddr vaddr+=1 v_mo1_bits equ vaddr vaddr+=1 v_mo1_dir equ vaddr vaddr+=1 v_mo1_maxdmag equ vaddr vaddr+=1 v_mo1_maxstep equ vaddr vaddr+=1 v_mo1_mo_angle equ vaddr vaddr+=1 v_mo1_mo_flags equ vaddr vaddr+=1 v_mo1_mo_imph equ vaddr vaddr+=1 v_mo1_mo_impl equ vaddr vaddr+=1 v_mo1_mo_maxmag equ vaddr vaddr+=1 v_mo1_mo_minmag equ vaddr vaddr+=1 v_mo1_prev_angle equ vaddr vaddr+=1 v_mo1_prev_oct equ vaddr vaddr+=1 v_mo1_shape_flags equ vaddr vaddr+=1 v_mo1_step equ vaddr vaddr+=1 v_mo2_bits equ vaddr vaddr+=1 v_mo2_cnt0 equ vaddr vaddr+=1 v_mo2_cnt1 equ vaddr vaddr+=1 v_mo2_delta_oct equ vaddr vaddr+=1 v_mo2_gap_oct equ vaddr vaddr+=1 v_mo2_next_mdh equ vaddr vaddr+=1 v_mo2_next_mdl equ vaddr vaddr+=1 v_mo2_next_mh equ vaddr vaddr+=1 v_mo2_next_ml equ vaddr vaddr+=1 v_mo2_shape0 equ vaddr vaddr+=1 v_mo2_total_cnt equ vaddr vaddr+=1 v_mo3_ccnt equ vaddr vaddr+=1 v_mo3_dcnt equ vaddr vaddr+=1 v_mo3_msh equ vaddr vaddr+=1 v_mo3_msl equ vaddr vaddr+=1 v_mo4_best_imp_mh equ vaddr vaddr+=1 v_mo4_best_imp_ml equ vaddr vaddr+=1 v_mo4_best_imph equ vaddr vaddr+=1 v_mo4_best_impl equ vaddr vaddr+=1 v_mo4_best_mag equ vaddr vaddr+=1 v_mo4_best_mag_mh equ vaddr vaddr+=1 v_mo4_best_mag_ml equ vaddr vaddr+=1 v_mo4_next_mh equ vaddr vaddr+=1 v_mo4_next_ml equ vaddr vaddr+=1 v_mo4_prev_angle equ vaddr vaddr+=1 v_mo4_prev_shape equ vaddr vaddr+=1 v_mo4_sum_imph equ vaddr vaddr+=1 v_mo4_sum_impl equ vaddr vaddr+=1 v_mo7_bits equ vaddr vaddr+=1 v_mo7_circle_oct equ vaddr vaddr+=1 v_mo7_cnt0 equ vaddr vaddr+=1 v_mo7_cnt1 equ vaddr vaddr+=1 v_mo9_corner equ vaddr vaddr+=1 v_mo9_dbg_cnt equ vaddr vaddr+=1 v_mo9_minscore equ vaddr vaddr+=1 v_mo9_score equ vaddr vaddr+=1 v_mo_angle equ vaddr vaddr+=1 v_mo_best1_holdoff equ vaddr vaddr+=1 v_mo_best1_id equ vaddr vaddr+=1 v_mo_best1_infoh equ vaddr vaddr+=1 v_mo_best1_infol equ vaddr vaddr+=1 v_mo_best1_maxscore equ vaddr vaddr+=1 v_mo_best1_score equ vaddr vaddr+=1 v_mo_best2_infoh equ vaddr vaddr+=1 v_mo_best2_infol equ vaddr vaddr+=1 v_mo_best2_maxscore equ vaddr vaddr+=1 v_mo_best2_score equ vaddr vaddr+=1 v_mo_holdoff equ vaddr vaddr+=1 v_mo_id equ vaddr vaddr+=1 v_mo_imph equ vaddr vaddr+=1 v_mo_impl equ vaddr vaddr+=1 v_mo_maxmag equ vaddr vaddr+=1 v_mo_maxscore equ vaddr vaddr+=1 v_mo_oct equ vaddr vaddr+=1 v_mo_save_fsr0h equ vaddr vaddr+=1 v_mo_save_fsr0l equ vaddr vaddr+=1 v_mo_save_fsr1h equ vaddr vaddr+=1 v_mo_save_fsr1l equ vaddr vaddr+=1 v_mo_save_fsr2h equ vaddr vaddr+=1 v_mo_save_fsr2l equ vaddr vaddr+=1 v_mo_shape equ vaddr vaddr+=1 v_mo_spellinfoh equ vaddr vaddr+=1 v_mo_spellinfol equ vaddr vaddr+=1 v_moa_match equ vaddr vaddr+=1 v_moa_mignore equ vaddr vaddr+=1 v_moa_mtok equ vaddr vaddr+=1 v_moa_signore equ vaddr vaddr+=1 v_moa_stok equ vaddr vaddr+=1 ;# 1 "fmtb_pic.c" ;# 1 "<built-in>" ;# 1 "<command line>" ;# 1 "fmtb_pic.c" ; ; fmtb_pic.c - This file is the pic code for fmtb_parse.c ; ; Copyright (C) 2006 Nathan (Acorn) Pooley ; ; This program is free software you can redistribute it and/or ; modify it under the terms of the GNU General Public License ; version 2 as published by the Free Software Foundation. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License (gpl.txt) for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program if not, write to the Free Software ; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ; ; You can contact the author, Nathan (Acorn) Pooley, by writing ; to Nathan (Acorn) Pooley, 949 Buckeye Drive, Sunnyvale, CA 94086, USA ; or through the form at http://www.rawbw.com/~acorn/wand/feedback.html ; ;# 35 "fmtb_pic.c" ; ; See wand.asm MEMORY MAP for details ; RAMBUF_MTOKENS equ 0xc00 RAMBUF_MTOKENS_LEN equ 0x100 RAMBUF_M2LIST equ 0x300 RAMBUF_M2LIST_LEN equ 0x500 RAMBUF_M3LIST equ 0x800 RAMBUF_M3LIST_LEN equ 0x500 RAMBUF_ACC equ 0x500 RAMBUF_ACC_LEN equ 0xa00 RAMBUF_STOKENS equ 0xb00 RAMBUF_STOKENS_LEN equ 0x100 RAMBUF_SPELLDATA equ 0x900 RAMBUF_SPELLDATA_LEN equ 0x100 RAMBUF_SD_SPELL_IGNORE equ 0x900 RAMBUF_SD_MOTION_IGNORE equ 0x908 RAMBUF_MMATRIX equ 0xa00 RAMBUF_MMATRIX_LEN equ 0x100 RAMBUF_STBL1 equ 0x800 RAMBUF_STBL1_LEN equ 0x100 RAMBUF_STBL2 equ 0x700 RAMBUF_STBL2_LEN equ 0x100 ;=========================================================================== ; declare global registers ;=========================================================================== ; ; common variables ; ; ; local variables for mo1 ; ; ; locals for mo2 ; ;# 113 "fmtb_pic.c" ;=========================================================================== ; w_a2oct: convert angle (in W) to octant (in W) ;=========================================================================== w_a2oct: addlw 2 rrncf WREG,w rrncf WREG,w andlw 7 return ;=========================================================================== ; w_oct2a: convert octant (in W) to angle (in W) ;=========================================================================== w_oct2a: rlncf WREG,w rlncf WREG,w andlw 0x1f return ;=========================================================================== ; w_adiff: convert angle a1-a0 (in W) to range -16 ... 15 ;=========================================================================== w_adiff: andlw 0x1f btfsc WREG,4 addlw -0x20 return ;=========================================================================== ; w_odiff: convert octant o1-o0 (in W) to range -4 ... 3 ;=========================================================================== w_odiff: andlw 0x07 btfsc WREG,2 addlw -0x08 return ;# 203 "fmtb_pic.c" ;=========================================================================== ; w_mo_read: ;=========================================================================== w_mo_read: ; ; Fills in these registers: ; v_mo1_mo_angle ; v_mo1_mo_maxmag ; v_mo1_mo_minmag ; v_mo1_mo_impl ; v_mo1_mo_imph ; v_mo1_mo_flags ; ; Read as follows from FSR2: ; ; Pause: ; 0 - time (h) ; 1 - time (l) ; 2 - unused (set to 0xff) ; 3 - angle (0xff indicates pause) ; ; Angle: ; 0 - time (h) ; 1 - time (l) ; 2 - max mag ; 3 - angle (0-31) ; 4 - imp (h) ; 5 - imp (l) ; 6 - min mag ; 7 - flags ; movf POSTINC2,w ; timeh movf POSTINC2,w ; timel movf POSTINC2,w movwf v_mo1_mo_maxmag movf POSTINC2,w movwf v_mo1_mo_angle btfsc v_mo1_mo_angle,7 return movf POSTINC2,w movwf v_mo1_mo_imph ; imph movf POSTINC2,w movwf v_mo1_mo_impl ; impl movf POSTINC2,w movwf v_mo1_mo_minmag ; minmag movf POSTINC2,w movwf v_mo1_mo_flags ; flags (only bit0 counts) return ;=========================================================================== ; w_shp_read: read from FSR2 ;=========================================================================== w_shp_read: ; ; read Motion2 from FSR2 ; movf POSTINC2,w movwf v_mo_angle movf POSTINC2,w movwf v_mo_impl movf POSTINC2,w movwf v_mo_imph movf POSTINC2,w movwf v_mo_maxmag movf POSTINC2,w movwf v_mo_shape return ;=========================================================================== ; w_shp_write: write to FSR0 ;=========================================================================== w_shp_write: ; ; write Motion2 to FSR0 ; movf v_mo_angle,w movwf POSTINC0 movf v_mo_impl,w movwf POSTINC0 movf v_mo_imph,w movwf POSTINC0 movf v_mo_maxmag,w movwf POSTINC0 movf v_mo_shape,w movwf POSTINC0 return ;=========================================================================== ; w_shp_prev: - back up to previous motion2 record ;=========================================================================== w_shp_prev: ; ; back up to previous motion2 record ; movlw 5 subwf FSR2L,f movlw 0 subwfb FSR2H,f return ;=========================================================================== ; w_mo1_parse1: ;=========================================================================== w_mo1_parse1: ; ; local variables ; ;# 363 "fmtb_pic.c" lfsr FSR2,RAMBUF_ACC lfsr FSR0,RAMBUF_M2LIST ; ; first motion is STARTT ; movlw ANGLE_START movwf v_mo1_mo_angle movwf POSTINC0 ; angle clrf POSTINC0 ; impl clrf POSTINC0 ; imph clrf POSTINC0 ; maxmag clrf POSTINC0 ; shape clrf v_mo1_dir clrf v_mo1_bits bsf v_mo1_bits,b_mo1_was_pause ; ; these probably do not need to be cleared ; clrf v_mo1_shape_flags w_mo1_outer_loop: movf v_mo1_mo_angle,w movwf v_mo1_prev_angle movf v_mo_oct,w movwf v_mo1_prev_oct clrf v_mo1_step rcall w_mo_read ;# 412 "fmtb_pic.c" movf v_mo1_mo_angle,w rcall w_a2oct movwf v_mo_oct ; ; is it pause or end of buffer? ; btfss v_mo1_mo_angle,7 bra w_mo1_top_checkpause ; ; restart new shape if this is a new pause ; btfss v_mo1_bits,b_mo1_was_pause bra w_mo1_restart ; ; repeated pause? (not end of buffer?) - loop ; btfsc v_mo1_mo_angle,0 bra w_mo1_outer_loop ; ; end of buffer - DONE ; bra w_mo1_done w_mo1_top_checkpause: btfss v_mo1_bits,b_mo1_was_pause bra w_mo1_top_checkangle bcf v_mo1_bits,b_mo1_got_angle bra w_mo1_restart w_mo1_top_checkangle: ; ; calc v_mo1_step & v_mo1_dir ; clrf v_mo1_dir movf v_mo1_prev_angle,w subwf v_mo1_mo_angle,w andlw 0x1f btfss WREG,4 ; check for negative bra w_mo1_top_checkangle2 addlw -0x20 negf WREG bsf v_mo1_dir,b_MSHF_DIR w_mo1_top_checkangle2: movwf v_mo1_step movf v_mo_oct,w subwf v_mo1_prev_oct,w bz w_mo1_bottom ; fall through to restart w_mo1_restart: btfss v_mo1_bits,b_mo1_got_angle bra w_mo1_restart2 ; ; got a motion angle - send a shape ; movf v_mo1_step,w addwf v_mo1_asum,f cpfsgt v_mo1_maxstep movwf v_mo1_maxstep movlw MSHP_PULSE movwf v_mo_shape ; ; clear MONO if no dir was found ; btfss v_mo1_bits,b_mo1_got_dir bcf v_mo1_shape_flags,b_MSHF_MONO ; ; clear MONO if direction changed ; movf v_mo1_dir,w xorwf v_mo1_shape_flags,w btfsc WREG,b_MSHF_DIR bcf v_mo1_shape_flags,b_MSHF_MONO ; ; if !MONO send pulse ; btfss v_mo1_shape_flags,b_MSHF_MONO bra w_mo1_send_shape ; ; if MSHF_PREV_PAUSE send pulse ; if new angle is a pause (or end of buffer) then send pulse ; btfss v_mo1_shape_flags,b_MSHF_PREV_PAUSE btfsc v_mo1_mo_angle,7 bra w_mo1_send_shape ; ; if asum < 4 send pulse ; movf v_mo1_asum,w addlw -4 bnc w_mo1_send_shape ; ; if maxstep >= 6 send pulse ; movf v_mo1_maxstep,w addlw -6 bc w_mo1_send_shape ; ; Not a pulse! dirty circle? ; bcf v_mo_shape,2 ; ; if maxstep >= 4 send dirty circle ; movf v_mo1_maxstep,w addlw -4 bc w_mo1_send_shape ; ; if maxdmag >= 8 send dirty circle ; movf v_mo1_maxdmag,w addlw -8 bc w_mo1_send_shape ; ; if ZERO then send dirty circle ; btfsc v_mo1_shape_flags,b_MSHF_ZERO bra w_mo1_send_shape ; ; send clean circle ; bsf v_mo_shape,1 ; ; SEND THE SHAPE ; w_mo1_send_shape: movf v_mo1_shape_flags,w andlw MSHF_FLG_MASK iorwf v_mo_shape,f ; ; clear dir flag if !MONO ; btfss v_mo_shape,b_MSHF_MONO bcf v_mo_shape,b_MSHF_DIR ;# 596 "fmtb_pic.c" rcall w_shp_write w_mo1_restart2: ; ; are we at the end? ; movf v_mo1_mo_angle,w addlw -0xfe bz w_mo1_done clrf v_mo1_asum clrf v_mo_impl clrf v_mo_imph clrf v_mo1_maxstep clrf v_mo1_maxdmag clrf v_mo_maxmag bcf v_mo1_bits,b_mo1_got_angle movlw MSHF_DIR andwf v_mo1_shape_flags,f bsf v_mo1_shape_flags,b_MSHF_MONO ; ; bottom - after restart ; w_mo1_bottom: btfss v_mo1_mo_angle,7 bra w_mo1_bottom_notpause ; ; pause ; bsf v_mo1_bits,b_mo1_was_pause bra w_mo1_outer_loop w_mo1_bottom_notpause: btfss v_mo1_bits,b_mo1_was_pause bra w_mo1_bottom_angle ; ; was pause last time ; bcf v_mo1_bits,b_mo1_was_pause bcf v_mo1_bits,b_mo1_got_dir bsf v_mo1_shape_flags,b_MSHF_PREV_PAUSE bcf v_mo1_shape_flags,b_MSHF_MONO bra w_mo1_getangle ; ; angle (not the first one) ; w_mo1_bottom_angle: ; ; if !got_dir ; copy DIR bit frim mo_dir ; btfsc v_mo1_bits,b_mo1_got_dir bra w_mo1_checkdir bcf v_mo1_shape_flags,b_MSHF_DIR movf v_mo1_dir,w andlw MSHF_DIR iorwf v_mo1_shape_flags,f w_mo1_checkdir: bsf v_mo1_bits,b_mo1_got_dir movf v_mo1_dir,w xorwf v_mo1_shape_flags,w andlw MSHF_DIR bz w_mo1_getangle ; ; change in direction detected ; xorwf v_mo1_shape_flags,f bcf v_mo1_shape_flags,b_MSHF_MONO w_mo1_getangle: ; ; got an angle - record info from it ; bsf v_mo1_bits,b_mo1_got_angle movf v_mo1_mo_impl,w addwf v_mo_impl,f movf v_mo1_mo_imph,w addwfc v_mo_imph,f bnc w_mo1_impwrap setf v_mo_impl setf v_mo_imph w_mo1_impwrap: movf v_mo1_mo_maxmag,w subwf v_mo_maxmag,w bc w_mo1_notmax movf v_mo1_mo_maxmag,w movwf v_mo_maxmag movf v_mo1_mo_angle,w movwf v_mo_angle w_mo1_notmax: movf v_mo1_mo_flags, w andlw MSHF_ZERO iorwf v_mo1_shape_flags,f ; ; calc dmag & save max ; movf v_mo1_mo_minmag,w subwf v_mo1_mo_maxmag,w btfsc v_mo1_mo_flags,b_MSHF_ZERO movf v_mo1_mo_maxmag,w cpfsgt v_mo1_maxdmag movwf v_mo1_maxdmag movf v_mo1_step,w addwf v_mo1_asum,f cpfsgt v_mo1_maxstep movwf v_mo1_maxstep bra w_mo1_outer_loop ; ; End of loop ; w_mo1_done: movlw ANGLE_END movwf v_mo_angle rcall w_shp_write ; ; write END to last legal buffer slot too, in case we overflowed ; lfsr FSR2,RAMBUF_M2LIST+((256 -1)*5) rcall w_shp_write ; ; done ; return ;=========================================================================== ; w_mo2_savenext: ;=========================================================================== w_mo2_savenext: btfss v_mo2_bits,b_mo2_savenext return bcf v_mo2_bits,b_mo2_savenext movf FSR2H,w movwf v_mo2_next_mh movf FSR2L,w movwf v_mo2_next_ml movf FSR0H,w movwf v_mo2_next_mdh movf FSR0L,w movwf v_mo2_next_mdl return ;=========================================================================== ; w_mo2_fill_circle_gaps: ;=========================================================================== w_mo2_fill_circle_gaps: ; ; local variables ; ;# 833 "fmtb_pic.c" w_mo2_outer_loop: clrf v_mo2_bits clrf v_mo2_total_cnt ; ; copy motions to M3LIST ; lfsr FSR2,RAMBUF_M2LIST lfsr FSR0,RAMBUF_M3LIST w_mo2_copy_loop: rcall w_shp_read rcall w_shp_write incf v_mo2_total_cnt,f ;# 873 "fmtb_pic.c" btfss v_mo_angle,b_AFLG_END bra w_mo2_copy_loop ; ; look for gaps as we copy it back ; lfsr FSR2,RAMBUF_M3LIST+5 lfsr FSR0,RAMBUF_M2LIST+5 w_mo2_look_loop: rcall w_shp_read ;# 903 "fmtb_pic.c" w_mo2_look_loop2: btfsc v_mo_angle,b_AFLG_END bra w_mo2_look_done movff v_mo_shape,v_mo2_shape0 movlw 1-2-1 movwf v_mo2_cnt0 movwf v_mo2_cnt1 movf v_mo_angle,w rcall w_a2oct movwf v_mo_oct ;# 926 "fmtb_pic.c" bsf v_mo2_bits,b_mo2_savenext w_mo2_top_loop: incf v_mo2_cnt0,f rcall w_shp_write ;# 951 "fmtb_pic.c" rcall w_mo2_savenext movff v_mo_oct,v_mo2_delta_oct negf v_mo2_delta_oct rcall w_shp_read ;# 975 "fmtb_pic.c" btfsc v_mo_angle,b_AFLG_END bra w_mo2_look_done btfsc v_mo_shape,b_MSHF_PREV_PAUSE bra w_mo2_look_loop2 ; ; calc delta oct ; movf v_mo_angle,w rcall w_a2oct movwf v_mo_oct addwf v_mo2_delta_oct,f ; ; Do we know what direction this circle is going? ; btfsc v_mo2_shape0,b_MSHF_MONO bra w_mo2_top_check_dir ; ; do not know direction - figure it out ; movlw MSHF_MONO movwf v_mo2_shape0 btfsc v_mo2_delta_oct,2 bsf v_mo2_shape0,b_MSHF_DIR w_mo2_top_check_dir: ; ; delta oct direction ; btfsc v_mo2_shape0,b_MSHF_DIR negf v_mo2_delta_oct movlw 7 andwf v_mo2_delta_oct,f ; ; change of direction? ; if MONO is set and dir bit is different then break ; btfss v_mo_shape,b_MSHF_MONO bra w_mo2_top_checked_dir movf v_mo_shape,w xorwf v_mo2_shape0,w btfsc WREG,b_MSHF_DIR bra w_mo2_look_next w_mo2_top_checked_dir: ; ; is delta_oct ==1? ; dcfsnz v_mo2_delta_oct,f bra w_mo2_top_loop ;picLabel(w_mo2_top_done) ; ; optimization - skip to next if only 1 found ; movf v_mo2_cnt0,f bn w_mo2_look_next ; ; was delta_oct ==2? ; decfsz v_mo2_delta_oct,f bra w_mo2_look_next ; ; gap_oct = dir ? current_oct+1 current_oct-1 ; incf v_mo_oct,w btfss v_mo2_shape0,b_MSHF_DIR addlw -2 andlw 7 movwf v_mo2_gap_oct bcf v_mo2_bits,b_mo2_cnt1b bsf v_mo2_bits,b_mo2_savenext rcall w_mo2_savenext ;# 1072 "fmtb_pic.c" w_mo2_bot_loop: incf v_mo2_cnt1,f rcall w_shp_write ;# 1095 "fmtb_pic.c" movff v_mo_oct,v_mo2_delta_oct negf v_mo2_delta_oct rcall w_shp_read ;# 1117 "fmtb_pic.c" btfsc v_mo_angle,b_AFLG_END bra w_mo2_bot_done btfsc v_mo_shape,b_MSHF_PREV_PAUSE bra w_mo2_bot_done ; ; change of direction? ; if MONO is set and dir bit is different then break ; btfss v_mo_shape,b_MSHF_MONO bra w_mo2_bot_checked_dir movf v_mo_shape,w xorwf v_mo2_shape0,w btfsc WREG,b_MSHF_DIR bra w_mo2_bot_done w_mo2_bot_checked_dir: ; ; find delta oct ; movf v_mo_angle,w rcall w_a2oct movwf v_mo_oct addwf v_mo2_delta_oct,f ; ; delta oct direction ; btfsc v_mo2_shape0,b_MSHF_DIR negf v_mo2_delta_oct movlw 7 andwf v_mo2_delta_oct,f ; ; is delta_oct ==1? ; dcfsnz v_mo2_delta_oct,f bra w_mo2_bot_loop ; is 1 - loop ; ; is delta oct == 2? ; decfsz v_mo2_delta_oct,f bra w_mo2_bot_done ; not 2 - done ; ; delta_oct==2 - keep going if first time ; btg v_mo2_bits,b_mo2_cnt1b btfsc v_mo2_bits,b_mo2_cnt1b bra w_mo2_bot_loop ; first time - loop w_mo2_bot_done: ;# 1186 "fmtb_pic.c" ; ; place pointers at gap ; movlw 5 subwf v_mo2_next_ml,w movwf FSR2L movlw 0 subwfb v_mo2_next_mh,w movwf FSR2H movf v_mo2_next_mdh,w movwf FSR0H movf v_mo2_next_mdl,w movwf FSR0L ; ; check for valid Gap-fill condition ; (cnt0>=2-2 && cnt1>=2-2 && (cnt0+cnt1 >= 6-2-2)) ; movf v_mo2_cnt0,w bn w_mo2_look_loop movf v_mo2_cnt1,w bn w_mo2_look_loop addwf v_mo2_cnt0,w addlw -(6-2-2) bnc w_mo2_look_loop ; no gap - loop ; ; make sure we do not already have 256 motion entries. ; If we do then do not add a gap. ; movf v_mo2_total_cnt,f bz w_mo2_look_loop ; ; Found a Gap!! ; movf v_mo2_shape0,w andlw MSHF_DIR iorlw MSHP_CIRCLE_GAP|MSHF_MONO movwf v_mo_shape clrf v_mo_maxmag clrf v_mo_impl clrf v_mo_imph movf v_mo2_gap_oct,w rcall w_oct2a movwf v_mo_angle incf v_mo2_total_cnt,f ; total # of motion entries rcall w_shp_write ;# 1256 "fmtb_pic.c" bsf v_mo2_bits,b_mo2_added bra w_mo2_look_loop ; ; check starting at next motion ; w_mo2_look_next: movf v_mo2_next_mh,w movwf FSR2H movf v_mo2_next_ml,w movwf FSR2L movf v_mo2_next_mdh,w movwf FSR0H movf v_mo2_next_mdl,w movwf FSR0L bra w_mo2_look_loop ; ; finished with this iteration ; w_mo2_look_done: movlw ANGLE_END movwf v_mo_angle rcall w_shp_write ;# 1308 "fmtb_pic.c" btfsc v_mo2_bits,b_mo2_added bra w_mo2_outer_loop ; ; done ; return ;=========================================================================== ; w_mo3_find_weak_circles: ;=========================================================================== w_mo3_find_weak_circles: ; ; local variables ; ;# 1354 "fmtb_pic.c" ; ; loop through all motions ; lfsr FSR2,RAMBUF_M2LIST+5 w_mo3_loop1: clrf v_mo3_dcnt clrf v_mo3_ccnt clrf v_tmp movff FSR2L,v_mo3_msl movff FSR2H,v_mo3_msh ; ; loop through all motions in circle ; w_mo3_loop2: incf v_tmp,f ;# 1391 "fmtb_pic.c" rcall w_shp_read btfsc v_mo_angle,6 bra w_mo3_loop2_done ;# 1423 "fmtb_pic.c" ; ; what shape is this? ; movf v_mo_shape,w andlw MSHF_SHP_MASK ; ; CIRCLE GAPS do not count, but keep going ; addlw LOW(-MSHP_CIRCLE_GAP) bz w_mo3_loop2 ; ; clean circle? ; incf v_mo3_ccnt,f addlw LOW(MSHP_CIRCLE_GAP-MSHP_CLEAN_CIRCLE) bz w_mo3_loop2 ; ; dirty circle? ; decf v_mo3_ccnt,f incf v_mo3_dcnt,f addlw LOW(MSHP_CLEAN_CIRCLE-MSHP_DIRTY_CIRCLE) bz w_mo3_loop2 decf v_mo3_dcnt,f w_mo3_loop2_done: ;# 1466 "fmtb_pic.c" ; ; if only 1 then it must not be a circle ; dcfsnz v_tmp,f bra w_mo3_non_circle ; ; should not be more than 128 ; ; ; if (ccnt >= 5 || (ccnt>0 && ccnt+dcnt >= 6)) then STRONG CIRCLE ; if (ccnt > 0) then WEAK CIRCLE ; else not a circle at all ; movf v_mo3_ccnt,w bz w_mo3_non_circle movff v_mo3_msl,FSR2L movff v_mo3_msh,FSR2H addlw LOW(-5) bnn w_mo3_strong_circle addwf v_mo3_dcnt,w addlw LOW(5-6) bnn w_mo3_strong_circle ; ; weak circle - make the whole thing be a dirty circle ; w_mo3_weak_circle: rcall w_shp_read movf POSTDEC2,f ; back up to shape ;# 1512 "fmtb_pic.c" movlw 2 subwf INDF2,f ; turn clean circle into dirty movf POSTINC2,w andlw MSHF_SHP_MASK bz w_mo3_weak_next ; ; oops - it was not a clean circle. Put it back ; movlw 2 movf POSTDEC2,f ; back up to shape addwf POSTINC2,f ; putit back the way it was ;# 1535 "fmtb_pic.c" w_mo3_weak_next: decfsz v_tmp,f bra w_mo3_weak_circle bra w_mo3_loop1 ; ; strong circle - set MFLG_CIRCLE ; w_mo3_strong_circle: rcall w_shp_read movf POSTDEC2,f ; back up to shape ;# 1560 "fmtb_pic.c" bsf POSTINC2,5 ; shape - set MFLG_CIRCLE decfsz v_tmp,f bra w_mo3_strong_circle bra w_mo3_loop1 ; ; not a circle ; w_mo3_non_circle: ; ; loop until done ; btfss v_mo_angle,b_AFLG_END bra w_mo3_loop1 ; ; done ; return ;=========================================================================== ; w_mo4_find_best_pulses: ;=========================================================================== w_mo4_find_best_pulses: ; ; local variables ; ;# 1634 "fmtb_pic.c" lfsr FSR2,RAMBUF_M2LIST+5 setf v_mo_shape w_mo4_outer_loop: movf v_mo_shape,w movwf v_mo4_prev_shape rcall w_shp_read ;# 1663 "fmtb_pic.c" btfsc v_mo_angle,b_AFLG_END bra w_mo4_done ; ; keep going if PULSE or (DIRTY_CIRCLE && was not CLEAN_CIRCLE before) ; movf v_mo_shape,w andlw MSHF_SHP_MASK bnz w_mo4_ocheck_pulse ; ; its a DIRTY_CIRCLE - check if previous was a CLEAN_CIRCLE ; movf v_mo4_prev_shape,w andlw MSHF_SHP_MASK addlw -MSHP_CLEAN_CIRCLE bz w_mo4_outer_loop bra w_mo4_start_inner w_mo4_ocheck_pulse: addlw -MSHP_PULSE bnz w_mo4_outer_loop w_mo4_start_inner: movf v_mo_maxmag,w movwf v_mo4_best_mag movf v_mo_impl,w movwf v_mo4_best_impl movwf v_mo4_sum_impl movf v_mo_imph,w movwf v_mo4_best_imph movwf v_mo4_sum_imph movf FSR2L,w movwf v_mo4_best_imp_ml movwf v_mo4_best_mag_ml movf FSR2H,w movwf v_mo4_best_imp_mh movwf v_mo4_best_mag_mh w_mo4_inner_loop: movf v_mo_angle,w movwf v_mo4_prev_angle movf FSR2L,w movwf v_mo4_next_ml movf FSR2H,w movwf v_mo4_next_mh rcall w_shp_read ;# 1736 "fmtb_pic.c" btfsc v_mo_angle,b_AFLG_END bra w_mo4_inner_done ; ; stop if pause detected ; btfsc v_mo_shape,b_MSHF_PREV_PAUSE bra w_mo4_inner_done ; ; keep going if PULSE or (DIRTY_CIRCLE && not MSHF_CIRCLE) ; movf v_mo_shape,w andlw MSHF_SHP_MASK bnz w_mo4_icheck_pulse ; ; its a DIRTY_CIRCLE - check if MSHF_CIRCLE is set ; btfsc v_mo_shape,b_MSHF_CIRCLE bra w_mo4_inner_done bra w_mo4_check_angle w_mo4_icheck_pulse: addlw -MSHP_PULSE bnz w_mo4_inner_done w_mo4_check_angle: ; ; check delta angle < 6 ; movf v_mo4_prev_angle,w subwf v_mo_angle,w rcall w_adiff btfsc WREG,7 negf WREG addlw -6 bc w_mo4_inner_done ; ; check delta oct < 2 ; movf v_mo4_prev_angle,w rcall w_a2oct movwf v_mo4_prev_angle movf v_mo_angle,w rcall w_a2oct subwf v_mo4_prev_angle,w rcall w_odiff btfsc WREG,7 negf WREG decfsz WREG,w bra w_mo4_inner_done ; ; check for max magnitude ; movf v_mo_maxmag,w cpfslt v_mo4_best_mag bra w_mo4_check_imp ; ; this is the best magnitude ; movwf v_mo4_best_mag movf FSR2L,w movwf v_mo4_best_mag_ml movf FSR2H,w movwf v_mo4_best_mag_mh w_mo4_check_imp: ; ; sum impulse ; movf v_mo_impl,w addwf v_mo4_sum_impl,f movf v_mo_imph,w addwfc v_mo4_sum_imph,f btfsc STATUS,C setf v_mo4_sum_imph ; ; check for max impulse ; movf v_mo_impl,w subwf v_mo4_best_impl,w movf v_mo_imph,w subwfb v_mo4_best_imph,w bc w_mo4_inner_loop ; ; this is the best impulse ; movf v_mo_impl,w movwf v_mo4_best_impl movf v_mo_imph,w movwf v_mo4_best_imph movf FSR2L,w movwf v_mo4_best_imp_ml movf FSR2H,w movwf v_mo4_best_imp_mh bra w_mo4_inner_loop ; ; decide whether to set PLUS ; w_mo4_inner_done: ; ; sum of impulse >= 0x500 ; movf v_mo4_sum_imph,w addlw -5 bnc w_mo4_next ; ; best_impulse and best_magnitude should be the same ; movf v_mo4_best_imp_ml,w movwf FSR0L subwf v_mo4_best_mag_ml,w bnz w_mo4_next movf v_mo4_best_imp_mh,w movwf FSR0H subwf v_mo4_best_mag_mh,w bnz w_mo4_next ; ; All conditions met - make it a PLUS ; movf POSTDEC0,w ; back up to preceding shape bsf INDF0,b_MSHF_PLUS w_mo4_next: movf v_mo4_next_ml,w movwf FSR2L movf v_mo4_next_mh,w movwf FSR2H bra w_mo4_outer_loop w_mo4_done: ; ; done ; return ;=========================================================================== ; w_mo5_marklast: ;=========================================================================== w_mo5_marklast: ;# 1919 "fmtb_pic.c" ; ; find end of motions ; lfsr FSR2,RAMBUF_M2LIST+5 w_mo5_loop1: rcall w_shp_read btfss v_mo_angle,6 bra w_mo5_loop1 ; ; mark last 4 entries as non-plus (includes the END entry, so we are ; really only marking 3) ; movlw 4 movf POSTDEC2,f ; point to shape of last entry w_mo5_loop2: bcf POSTDEC2,0 ; turn off MSHF_PLUS bit in shape movf POSTDEC2,f ; maxmag movf POSTDEC2,f ; imph movf POSTDEC2,f ; impl btfsc POSTDEC2,5 ; return if we hit start bra w_mo5_done decfsz WREG,w ; loop until we have done 3 bra w_mo5_loop2 w_mo5_done: return ;=========================================================================== ; w_mo6_tokenize: ;=========================================================================== w_mo6_tokenize: ;# 1986 "fmtb_pic.c" ; ; read each motion and convert to token ; FSR2 points to motions ; FSR2 points to tokens ; lfsr FSR2,RAMBUF_M2LIST+5 lfsr FSR0,RAMBUF_MTOKENS w_mo6_loop: rcall w_shp_read ; ; for sanity, clear dir bit for pulses - NOT NECESSARY!?!?!? ; movf v_mo_shape,w xorlw 0x04 andlw 0x06 btfsc STATUS,Z ; pulse? bcf v_mo_shape,3 ; yes - clear DIR bit rrncf v_mo_angle,w andlw 0x0f movwf INDF0 swapf v_mo_shape,w andlw 0xf0 iorwf POSTINC0,f btfss v_mo_angle,6 bra w_mo6_loop movf POSTDEC0,w setf INDF0 bcf INDF0,0 return ;=========================================================================== ; w_mo7_one_circle: add circle or ocircle token. ;=========================================================================== w_mo7_one_circle: ; ; add a circle token (optional or not) ; oct is calculated from v_mo7_circle_oct ; v_mo7_circle_oct is incremented by dir and stored into v_mo7_circle_oct ; ; ; Note: PICDST_BITb_mo7_endspells is global (end of spells) ; Note: PICDST_BITb_mo7_prev_dir must match PICDST_BITb_MWN_DIR ; movf v_mo7_circle_oct,w btfsc TABLAT,b_MWN_DIR bra w_mo7_one_circle_cw addlw 1 andlw 7 movwf v_mo7_circle_oct addlw 1 andlw 7 rlncf WREG,w iorlw (SSHP_CIRCLE&7)<<4 btfsc v_mo7_bits,b_mo7_optional addlw ((SSHP_OCIRCLE-SSHP_CIRCLE)&7)<<4 movwf POSTINC0 ;# 2090 "fmtb_pic.c" return w_mo7_one_circle_cw: addlw -1 andlw 7 movwf v_mo7_circle_oct addlw -1 andlw 7 rlncf WREG,w iorlw (SSHP_CIRCLE&7)<<4 btfsc v_mo7_bits,b_mo7_optional addlw ((SSHP_OCIRCLE-SSHP_CIRCLE)&7)<<4 bsf WREG,b_TOK_DIR movwf POSTINC0 ;# 2118 "fmtb_pic.c" return ;=========================================================================== ; w_mo7_one_pulse: add pulse or opulse token. W=oct ;=========================================================================== w_mo7_one_pulse: ; ; add pulse in direction of oct ; andlw 7 rlncf WREG,w iorlw (SSHP_OPULSE&7)<<4 btfss v_mo7_bits,b_mo7_optional addlw ((SSHP_PULSE-SSHP_OPULSE)&7)<<4 movwf POSTINC0 ;# 2151 "fmtb_pic.c" return ;=========================================================================== ; w_mo7_load_spell: load the next spell's tokens ;=========================================================================== ; ; Input values ; TBLPTR - ptr to next spell ; Output values ; WREG - 0=end-of-spells, 0xff=got spell ; TBLPTR - ptr to next spell ; w_mo_spellinfol,h - ptr to spellinfo for spell ; w_mo_spell_len - # of tokens in spell ; RAMBUF_STOKENS - contains spell tokens ; w_mo7_load_spell: ;# 2193 "fmtb_pic.c" ; ; parameters & return values ; ; ; locals ; ; ; START ; clrf v_mo7_bits tblrd*+ ; spellinfol movf TABLAT,w movwf v_mo_spellinfol tblrd*+ ; spellinfoh movf TABLAT,w movwf v_mo_spellinfoh ; ; check for end of spells (spellinfo = 0xffff) ; andwf v_mo_spellinfol,w infsnz WREG,w bra w_mo7_end_spells tblrd*+ ; maxscore movf TABLAT,w movwf v_mo_maxscore tblrd*+ ; holdoff movf TABLAT,w movwf v_mo_holdoff tblrd*+ ; id movf TABLAT,w movwf v_mo_id tblrd*+ ; starting octant movf TABLAT,w movwf v_mo_oct lfsr FSR0,RAMBUF_STOKENS ; ; always start with optional pulse in initial direction ; bsf v_mo7_bits,b_mo7_optional rcall w_mo7_one_pulse ; ; first one is special since it follows a pause ; tblrd*+ ; first spell token btfss TABLAT,7 bra w_mo7_add_first_circle ;picLabel(w_mo7_add_first_pulse) bcf v_mo7_bits,b_mo7_optional bra w_mo7_pulse_common w_mo7_add_first_circle: decf v_mo_oct,w btfsc TABLAT,b_MWN_DIR addlw 2 movwf v_mo7_circle_oct ; initial direction movlw 1 movwf v_mo7_cnt0 ; optional circles (leading) movf TABLAT,w andlw MWN_CNT_MASK addlw 2+8-1-2 movwf v_mo7_cnt1 ; required circles bra w_mo7_circle_common w_mo7_outer_loop: ;# 2320 "fmtb_pic.c" bcf v_mo7_bits,b_mo7_optional tblrd*+ ; next spell token btfss TABLAT,7 bra w_mo7_circle ; ; ADDING PULSE ; ;picLabel(w_mo7_pulse) btfss v_mo7_bits,b_mo7_was_pulse bra w_mo7_pulse_was_circle ; ; was pulse or opulse ; ; opposite oct as prev? (same as current oct) ; movf TABLAT,w subwf v_mo_oct,w ; v_mo_oct is curent oct andlw 7 bz w_mo7_pulse_common ; ; same oct as prev? (opposite of current oct) ; andlw 3 bnz w_mo7_pulse_angle bsf v_mo7_bits,b_mo7_optional movf TABLAT,w rcall w_mo7_one_pulse bra w_mo7_pulse_common ; ; some other angle - add circle segments to connect pulses ; w_mo7_pulse_angle: bsf v_mo7_bits,b_mo7_optional movf v_mo_oct,w movwf v_mo7_circle_oct subwf TABLAT,w rcall w_odiff bcf TABLAT,b_MWN_DIR btfsc WREG,7 bsf TABLAT,b_MWN_DIR w_mo7_pulse_angle_loop: rcall w_mo7_one_circle movf v_mo7_circle_oct,w subwf TABLAT,w andlw 7 bnz w_mo7_pulse_angle_loop bcf v_mo7_bits,b_mo7_optional bra w_mo7_pulse_common w_mo7_pulse_was_circle: ; ; a pulse following a circle ; movf POSTDEC0,f ; back up 4 tokens movf POSTDEC0,f movf POSTDEC0,f movf POSTDEC0,f ; ; cnt = -1 ; setf v_mo7_cnt0 ; ; use prev dir for circles ; bcf TABLAT,b_MWN_DIR btfsc v_mo7_bits,b_mo7_prev_dir bsf TABLAT,b_MWN_DIR ; ; v_tmp = -dir (dir ? 1 : -1) ; setf v_tmp btfsc v_mo7_bits,b_mo7_prev_dir negf v_tmp ; ; oct = (last_oct - dir * 2) & 7 ; movf v_mo_oct,w addwf v_tmp,w addwf v_tmp,w ; ; if preceded by more than 1 circle (ie 2 or 3) ; btfss v_mo7_bits,b_mo7_was_23circle bra w_mo7_pulse_circles1 movf POSTDEC0,f ; back up a 5th token decf v_mo7_cnt0,f ; cnt = -2 addwf v_tmp,w ; oct = oct - dir w_mo7_pulse_circles1: movwf v_mo7_circle_oct bra w_mo7_pulse_circles1_loop_start ; ; add circles (preceding the pulse) ; w_mo7_pulse_circles1_loop: rcall w_mo7_one_circle incf v_mo7_cnt0,f w_mo7_pulse_circles1_loop_start: ; ; while((octc+prev_dir)&7) != oct) ; movf v_tmp,w subwf v_mo7_circle_oct,w subwf TABLAT,w andlw 7 bnz w_mo7_pulse_circles1_loop ; ; if less than a full circle then add a whole optional circle ; bsf v_mo7_bits,b_mo7_optional btfss v_mo7_cnt0,7 bra w_mo7_pulse_circles3 movlw 8 movwf v_mo7_cnt0 w_mo7_pulse_circles2_loop: rcall w_mo7_one_circle decfsz v_mo7_cnt0,f bra w_mo7_pulse_circles2_loop w_mo7_pulse_circles3: rcall w_mo7_one_circle ; 2 more optional circles rcall w_mo7_one_circle bcf v_mo7_bits,b_mo7_optional bra w_mo7_pulse_common w_mo7_pulse_common: movf TABLAT,w addlw 4 andlw 7 movwf v_mo_oct rcall w_mo7_one_pulse bcf v_mo7_bits,b_mo7_was_23circle bsf v_mo7_bits,b_mo7_was_pulse bra w_mo7_outer_loop ; ; ADDING CIRCLE ; w_mo7_circle: btfss TABLAT,b_MWN_MORE bra w_mo7_done btfss v_mo7_bits,b_mo7_was_pulse bra w_mo7_circle_was_circle ; ; circle following a pulse ; decf v_mo_oct,w btfsc TABLAT,b_MWN_DIR addlw 2 movwf v_mo7_circle_oct ; initial direction movlw 3 movwf v_mo7_cnt0 ; optional circles (leading) movf TABLAT,w andlw MWN_CNT_MASK addlw 2+8-3-2 movwf v_mo7_cnt1 ; required circles bra w_mo7_circle_common w_mo7_circle_was_circle: ; ; circle following a circle ; movf v_mo7_bits,w xorwf TABLAT,w btfsc WREG,b_MWN_DIR bra w_mo7_circle_was_opposite ; ; circle following a circle in same direction ; movf POSTDEC0,f ; back up 3 tokens movf POSTDEC0,f movf POSTDEC0,f decf v_mo_oct,w btfsc v_mo7_bits,b_mo7_prev_dir addlw 2 movwf v_mo7_circle_oct ; cnt0 = 0 movf TABLAT,w andlw MWN_CNT_MASK addlw 2+8-2 movwf v_mo7_cnt1 ; required circles bra w_mo7_circle_common_no0 w_mo7_circle_was_opposite: ; ; circle following a circle in opposite direction ; bsf v_mo7_bits,b_mo7_optional movf v_mo_oct,w addlw 4 rcall w_mo7_one_pulse ; opulse opposite of last dir movf v_mo_oct,w addlw 5 btfsc v_mo7_bits,b_mo7_prev_dir addlw -2 rcall w_mo7_one_pulse ; same plus prevdir movf v_mo_oct,w addlw 4 rcall w_mo7_one_pulse ; opulse opposite of last dir (again) ; ; oct = last + 4 - dir ; movf v_mo_oct,w addlw 3 btfsc TABLAT,b_MWN_DIR addlw 2 andlw 7 movwf v_mo_oct movwf v_mo7_circle_oct movlw 2 movwf v_mo7_cnt0 ; optional circles (leading) movf TABLAT,w andlw MWN_CNT_MASK addlw 2+8-2-2 movwf v_mo7_cnt1 ; required circles ; fall thru to w_mo7_circle_common ;bra(w_mo7_circle_common) w_mo7_circle_common: bsf v_mo7_bits,b_mo7_optional w_mo7_circle_common0: rcall w_mo7_one_circle decfsz v_mo7_cnt0,f bra w_mo7_circle_common0 w_mo7_circle_common_no0: bcf v_mo7_bits,b_mo7_optional w_mo7_circle_common1: rcall w_mo7_one_circle decfsz v_mo7_cnt1,f bra w_mo7_circle_common1 ; ; last count is always 3 ; bsf v_mo7_bits,b_mo7_optional rcall w_mo7_one_circle rcall w_mo7_one_circle rcall w_mo7_one_circle ; ; set b_mo7_was_23circle (0=1 circle. 1=2 or 3 circles) ; bcf v_mo7_bits,b_mo7_was_23circle movf TABLAT,w andlw MWN_CNT_MASK btfss STATUS,Z bsf v_mo7_bits,b_mo7_was_23circle ; ; set prev dir ; bcf v_mo7_bits,b_mo7_prev_dir btfsc TABLAT,b_MWN_DIR bsf v_mo7_bits,b_mo7_prev_dir bcf v_mo7_bits,b_mo7_was_pulse bra w_mo7_outer_loop w_mo7_done: ; ; last optional pulse to stop motion of wand ; movf v_mo_oct,w addlw 4 bsf v_mo7_bits,b_mo7_optional rcall w_mo7_one_pulse ; ; end of spell marked by 0x00 ; clrf POSTINC0 ;# 2646 "fmtb_pic.c" w_mo7_done2: return w_mo7_end_spells: bsf v_mo7_bits,b_mo7_endspells bra w_mo7_done2 ;=========================================================================== ; w_moa_score_tok: ;=========================================================================== w_moa_score_tok: ;# 2731 "fmtb_pic.c" ; ; score for ignoring spell token ; swapf v_moa_stok,w iorlw 0xf8 movf PLUSW2,w movwf v_moa_signore ; ; score for ignoring motion token ; swapf v_moa_mtok,w andlw 7 movf PLUSW2,w movwf v_moa_mignore ;# 2791 "fmtb_pic.c" setf v_moa_match swapf v_moa_stok,w addlw -1 btfss WREG,1 bra w_moa_circle ; ; Spell is a pulse ; swapf v_moa_mtok,w andlw 7 addlw -MSHP_CIRCLE_GAP bz w_moa_done ;addlw(MSHP_CIRCLE_GAP-MSHP_PAUSE) ;bz(w_moa_done) movf v_moa_stok,w subwf v_moa_mtok,w btfsc WREG,3 negf WREG andlw 0xf addlw -3 bn w_moa_zero ; delta angle <= 45 degrees - score 0 bnz w_moa_done ; big angle - score infinite movlw 6 ; off by 67.5 deg - score 6 movwf v_moa_match return ; ; Spell is a circle ; w_moa_circle: ; ; infinite score if different octant ; movf v_moa_mtok,w subwf v_moa_stok,w btfsc WREG,3 negf WREG andlw 0x0e bnz w_moa_done ; ; does dir match? ; movf v_moa_mtok,w xorwf v_moa_stok,w btfss WREG,b_TOK_DIR bra w_moa_zero ; match - score 0 ; ; only care about dir if mshape is a circle (not a pulse) ; swapf v_moa_mtok,w addlw -MSHP_PULSE andlw 6 btfsc STATUS,Z ; if PULSE score 0 (noskip), else score infinite w_moa_zero: clrf v_moa_match w_moa_done: return ;# 2911 "fmtb_pic.c" ;=========================================================================== ; w_mo9_score_spell: ;=========================================================================== w_mo9_score_spell: ;# 2944 "fmtb_pic.c" ; ; setup matrix ; lfsr FSR1,RAMBUF_STOKENS lfsr FSR0,RAMBUF_MMATRIX clrf INDF0 setf v_mo9_score w_mo9_setup_loop: ;# 2977 "fmtb_pic.c" ; ; find value for ignoring spell token ; swapf POSTINC1,w ; spell token iorlw 0xf8 movf PLUSW2,w ; score for ignoring spell token ; ; add to previous val, then store in next ; addwf POSTINC0,w btfsc STATUS,C setf WREG movwf INDF0 movf INDF1,w bnz w_mo9_setup_loop ; ; Matrix is now set up ; ; ; RAMBUF_STOKENS must be RAMBUF_MMATRIX with 0x100 bit set ; ; ; Loop over motions ; FSR1 points to motion tokens ; FSR0 points to matrix and spell tokens ; lfsr FSR1,RAMBUF_MTOKENS ; ; Get first motion token ; movf POSTINC1,w movwf v_moa_mtok w_mo9_motion_loop: lfsr FSR0,RAMBUF_MMATRIX ; start of matrix (and spell-tokens) movf INDF0,w movwf v_mo9_corner swapf v_moa_mtok,w ; motion token shape andlw 7 movf PLUSW2,w ; score for ignoring motion token addwf v_mo9_corner,w btfsc STATUS,C setf WREG movwf v_mo9_score movwf v_mo9_minscore movwf INDF0 ; store first value in ignore-motion column 0 bsf FSR0H,0 ; point to RAMBUF_STOKENS movf POSTINC0,w ; get first spell token w_mo9_spell_loop: movwf v_moa_stok bcf FSR0H,0 ; point to RAMBUF_MMATRIX rcall w_moa_score_tok ; ; value if spell is ignored ; movf v_moa_signore,w addwf v_mo9_score,f btfsc STATUS,C setf v_mo9_score ; keep best score in v_mo9_score ; ; value if matched ; movf v_mo9_corner,w addwf v_moa_match,w bc w_mo9_check_im cpfslt v_mo9_score ; accumulate minimum into v_mo9_score movwf v_mo9_score ; ; value if motion is ignored ; w_mo9_check_im: movf INDF0,w movwf v_mo9_corner addwf v_moa_mignore,w bc w_mo9_save cpfslt v_mo9_score ; accumulate minimum into v_mo9_score movwf v_mo9_score w_mo9_save: movf v_mo9_score,w movwf INDF0 ; save score into matrix cpfslt v_mo9_minscore movwf v_mo9_minscore ; track min score ;# 3097 "fmtb_pic.c" bsf FSR0H,0 ; point to RAMBUF_STOKENS movf POSTINC0,w ; next spell token bnz w_mo9_spell_loop ; loop (unless end of spell) ; ; if min score in row is greater than best2 score then no point in ; continuing. ; movf v_mo_best2_score,w cpfslt v_mo9_minscore bra w_mo9_abort ; v_mo9_minscore >= v_mo_best2_score ; ; done with spell loop ; ; Get next motion token & check for end. ; movf POSTINC1,w ; motion token movwf v_moa_mtok addlw -MTOKEN_END bnz w_mo9_motion_loop ; ; Done with scoring - v_mo9_score contains final score ; w_mo9_done: return w_mo9_abort: ;# 3148 "fmtb_pic.c" setf v_mo9_score bra w_mo9_done ;=========================================================================== ; w_mo8_load_data_tables: ;=========================================================================== w_mo8_load_data_tables: ;# 3594 "fmtb_pic.c" ; ; RAMBUF_SD_SPELL_IGNORE table ; lfsr FSR2,RAMBUF_SD_SPELL_IGNORE movlw 100 movwf POSTINC2 ; SSHP_PAUSE = 100 movlw 15 movwf POSTINC2 ; SSHP_CIRCLE = 15 clrf POSTINC2 ; SSHP_OCIRCLE = 0 movlw 1 movwf POSTINC2 ; SSHP_OPULSE = 1 movlw 100 movwf POSTINC2 ; SSHP_PULSE = 100 setf POSTINC2 ; SSHP_WILD (unused) setf POSTINC2 ; (unused) setf POSTINC2 ; (unused) ; ; RAMBUF_SD_MOTION_IGNORE table ; movlw 1 movwf POSTINC2 ; 1, = MSHP_DIRTY_CIRCLE, movlw 20 movwf POSTINC2 ; 20, = MSHP_DIRTY_CIRCLE_PLUS, movlw 1 movwf POSTINC2 ; 1, = MSHP_CLEAN_CIRCLE, movlw 100 movwf POSTINC2 ; 100, = MSHP_CLEAN_CIRCLE_PLUS, movlw 1 movwf POSTINC2 ; 1, = MSHP_PULSE, movlw 100 movwf POSTINC2 ; 100, = MSHP_PULSE_PLUS, clrf POSTINC2 ; 0, = MSHP_CIRCLE_GAP, clrf POSTINC2 ; 0, = MSHP_PAUSE, ;# 3654 "fmtb_pic.c" lfsr FSR2,RAMBUF_SD_MOTION_IGNORE return ;=========================================================================== ; w_mo8_check_spells: ;=========================================================================== w_mo8_check_spells: ;# 3686 "fmtb_pic.c" ; ; b_mo7_endspells bit indicates last spell was loaded ; ; ; 1st best spell info ; ; ; 2nd best spell info ; ;# 3726 "fmtb_pic.c" rcall w_mo8_load_data_tables ; ; init results ; movlw 0xfe movwf v_mo9_score movwf v_mo_best1_score movlw MAX_MAXSCORE+MAX_HOLDOFF movwf v_mo_best2_score clrf v_mo_best1_maxscore setf v_mo_best1_holdoff movlw w_spellinfo_default&0xff movwf v_mo_best1_infol movwf v_mo_best2_infol movlw w_spellinfo_default>>8 movwf v_mo_best1_infoh movwf v_mo_best2_infoh clrf v_mo_best1_id clrf v_mo9_dbg_cnt ; ; start of mwaneme spell data ; movlw (w_motion_spells)&0xff movwf TBLPTRL movlw (w_motion_spells)>>8 movwf TBLPTRH w_mo8_outer_loop: ; ; get next spell ; rcall w_mo7_load_spell ; ; debug counter ; btfss RCSTA,SPEN bra w_mo8_skip_sp movff FSR0L,v_mo_save_fsr0l movff FSR0H,v_mo_save_fsr0h movff FSR1L,v_mo_save_fsr1l movff FSR1H,v_mo_save_fsr1h movff FSR2L,v_mo_save_fsr2l movff FSR2H,v_mo_save_fsr2h COUTL 'S' COUTL 'p' movf v_mo9_dbg_cnt,w call kk_outbyte COUTL ' ' movff v_mo_save_fsr0l,FSR0L movff v_mo_save_fsr0h,FSR0H movff v_mo_save_fsr1l,FSR1L movff v_mo_save_fsr1h,FSR1H movff v_mo_save_fsr2l,FSR2L movff v_mo_save_fsr2h,FSR2H w_mo8_skip_sp: incf v_mo9_dbg_cnt,f call w_ledscan ;# 3807 "fmtb_pic.c" ; ; done with all spells? ; btfsc v_mo7_bits,b_mo7_endspells bra w_mo8_done ; ; get spell score ; rcall w_mo9_score_spell btfss RCSTA,SPEN bra w_mo8_skip_sc movff FSR0L,v_mo_save_fsr0l movff FSR0H,v_mo_save_fsr0h movff FSR1L,v_mo_save_fsr1l movff FSR1H,v_mo_save_fsr1h movff FSR2L,v_mo_save_fsr2l movff FSR2H,v_mo_save_fsr2h COUTL 'S' COUTL 'c' COUTL '=' movf v_mo9_score,w call kk_outbyte call kk_outcr DB_FLUSH call w_main_run btfsc bk_rs_halt return movff v_mo_save_fsr0l,FSR0L movff v_mo_save_fsr0h,FSR0H movff v_mo_save_fsr1l,FSR1L movff v_mo_save_fsr1h,FSR1H movff v_mo_save_fsr2l,FSR2L movff v_mo_save_fsr2h,FSR2H w_mo8_skip_sc: ; ; best spell so far? ; movf v_mo9_score,w cpfslt v_mo_best1_score bra w_mo8_new_best1 ; ; same id as best spell? ; movf v_mo_id,w subwf v_mo_best1_id,w bz w_mo8_outer_loop ; ; 2nd best spell so far? ; movf v_mo9_score,w cpfslt v_mo_best2_score bra w_mo8_new_best2 bra w_mo8_outer_loop w_mo8_new_best1: movf v_mo_id,w subwf v_mo_best1_id,w bz w_mo8_new_best1_sameid ;movff(v_mo_best1_maxscore,v_mo_best2_maxscore) movff v_mo_best1_score,v_mo_best2_score movff v_mo_best1_infol,v_mo_best2_infol movff v_mo_best1_infoh,v_mo_best2_infoh w_mo8_new_best1_sameid: movff v_mo9_score,v_mo_best1_score movff v_mo_spellinfol,v_mo_best1_infol movff v_mo_spellinfoh,v_mo_best1_infoh movff v_mo_maxscore,v_mo_best1_maxscore movff v_mo_holdoff,v_mo_best1_holdoff movff v_mo_id,v_mo_best1_id bra w_mo8_outer_loop w_mo8_new_best2: movwf v_mo_best2_score movff v_mo_spellinfol,v_mo_best2_infol movff v_mo_spellinfoh,v_mo_best2_infoh ;movff(v_mo_maxscore,v_mo_best2_maxscore) bra w_mo8_outer_loop w_mo8_done: ; ; maxscore is the threshold. score must be less than or equal to this ; to count. ; ; holdoff is the minimum (best2_score-best1_score) ; ; ; default: no spell ; btfss RCSTA,SPEN bra w_mo8_skip_res movff FSR0L,v_mo_save_fsr0l movff FSR0H,v_mo_save_fsr0h movff FSR1L,v_mo_save_fsr1l movff FSR1H,v_mo_save_fsr1h movff FSR2L,v_mo_save_fsr2l movff FSR2H,v_mo_save_fsr2h call kk_outcr COUTL 'R' COUTL 'e' COUTL 's' COUTL ' ' movf v_mo_best1_score,w call kk_outbyte COUTL ' ' movf v_mo_best2_score,w call kk_outbyte COUTL ' ' COUTL 'x' COUTL ' ' movf v_mo_best1_maxscore,w call kk_outbyte ;COUTL ' ' ;movf(v_mo_best2_maxscore,w) ;call(kk_outbyte) COUTL ' ' COUTL 'h' COUTL ' ' movf v_mo_best1_holdoff,w call kk_outbyte call kk_outcr DB_FLUSH movff v_mo_save_fsr0l,FSR0L movff v_mo_save_fsr0h,FSR0H movff v_mo_save_fsr1l,FSR1L movff v_mo_save_fsr1h,FSR1H movff v_mo_save_fsr2l,FSR2L movff v_mo_save_fsr2h,FSR2H w_mo8_skip_res: ; ; Do we already have a spell (rythm spell)? ; btfsc b_got_spell bra w_mo8_done2 ; ; is score >= maxscore? ; movf v_mo_best1_score,w subwf v_mo_best1_maxscore,w bnc w_mo8_done2 ; no, score too high ;# 3984 "fmtb_pic.c" ; ; is best2_score-best1_score > holdoff ; movf v_mo_best1_score,w subwf v_mo_best2_score,w subwf v_mo_best1_holdoff,w bc w_mo8_done2 ; no - too close ; ; success! spell is good! ; movff v_mo_best1_infol,v_spell_ptrl movff v_mo_best1_infoh,v_spell_ptrh bsf b_got_spell w_mo8_done2: return ;=========================================================================== ; w_check_motion_spell: convert accbuf to motions and check acc spell ;=========================================================================== w_check_motion_spell: call w_mo1_parse1 call w_mo2_fill_circle_gaps call w_mo3_find_weak_circles call w_mo4_find_best_pulses call w_mo5_marklast call w_mo6_tokenize ; ; check for less than 3 motion tokens ; lfsr FSR2,RAMBUF_MTOKENS movf POSTINC2,w addlw -MTOKEN_END bz w_cms_done movf POSTINC2,w addlw -MTOKEN_END bz w_cms_done movf POSTINC2,w addlw -MTOKEN_END bz w_cms_done rcall w_mo8_check_spells w_cms_done: return |
This file Copyright (C) 2006 by Nathan (Acorn) Pooley
Go to TOP Wand page
Go to Acorn's personal webpage
Go to Hogwarts website: www.gotohogwarts.com
Snout: www.snout.org/game
Gadgets of Justice Unlimited
Snout GC (Wiki)
Snout Wiki
File created by do_doc at Wed May 30 03:23:28 PDT 2007