Hogwarts Wand Docs: ../server/wparse.inc

Wand Sourcecode: ../server/wparse.inc

;
; 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:24:42 PDT 2007