;====================================================================== ; REVERSERS include common.inc ;---------------------------------------- ; LOCAL REVERSERS - Variables udata_acs maska res 1 maske res 1 ;---------------------------------------- ; MASTER - Access bank variables and other sections polarity_cmds equ 0x5f polarity_cmds_section udata polarity_cmds res maxpics ; Each byte is: ; 11RRRRRR reverse command for slave, waiting to write ; 00000001 this is not a reversers board ; 00000000 we have written any relevant command ; 01000000 sentinel ;====================================================================== ; LOCAL REVERSERS ; on slave, or master's own near_local_do code ;---------- polarity_local_do @ ; On slave, called during i2c receive, ie High ISR ; On master, called during serial receive, ie Low ISR ; See common.inc ! ; ; W here polarity msg (see below) undefined ; STATUS any undefined ; t_dolocal any undefined ; maska,maske set up correctly preserved ; LATA,LATE any modified appropriately ; all others any preserved ; ; on entry: ; W = PP PP v3 v0 v2 v1 v5 v4 ; ; where PP bits are those specifying that this is a polarity message ; v is the reversal bits for point ; mov_wf t_dolocal ; t = PP PP v3 v0 v2 v1 v5 v4 mov_fw LATE ; W = kk kk kk kk kk kk o5 o4 xor_wfw t_dolocal ; W = ?? ?? ?? ?? ?? ?? d5 d4 and_wfw maske ; W = zz zz zz zz zz zz d5 d4 xor_wff LATE ; LATE = kk kk kk kk kk kk v5 v4 bc_f t_dolocal, 1 ; t = SS SS v3 v0 v2 v1 zz v4 bt_f_if1 t_dolocal, 4 ; t : .. .. .. v0 .. .. .. .. bs_f t_dolocal, 1 ; t = SS SS v3 v0 v2 v1 v0 v4 mov_fw LATA ; W = kk kk o3 kk o2 o1 o0 kk xor_wfw t_dolocal ; W = ?? ?? d3 ?? d2 d1 d0 ?? and_wfw maska ; W = zz zz d3 zz d2 d1 d0 zz xor_wff LATA ; LATA = kk kk v3 kk v2 v1 v0 kk ; where kk is a bit we must keep ; o is old reverse bit ; d is old (+) new ; v is new reverse bit return code ;---------- polarity_local_init @ load_perpic_tblptr picno2revmasks, 2 tblrd_postinc_fixup mov_fw TABLAT mov_wf maska tblrd_postinc_fixup mov_fw TABLAT mov_wf maske clr_w call polarity_local_do com_fw maska and_wff TRISA com_fw maske and_wff TRISE return ;====================================================================== ; MASTER ;---------- command_polarity @ ; message format ; SS zz zz SS ZZ 2f 2e 2d g is board 2 ; MM 0f 0e 0d 0c 0b 0a 2c board 0 ; MM 1f 1e 1d 1c 1b 1a 2b board 1 ; MM 3f 3e 3d 3c 3b 3a 2a g, board 2, complete, also 3 ; MM 4f 4e 4d 4c 4b 4a 9f g is board 9 ; MM 5f 5e 5d 5c 5b 5a 9e ; MM 6f 6e 6d 6c 6b 6a 9d ; MM 7f 7e 7d 7c 7b 7a 9c ; MM 8f 8e 8d 8c 8b 8a 9b ; MM af ae ad ac ab aa 9a ; etc. ; where ; SS bit set ; zz bit zero ; other things are where ; is a for LSb in message to PIC, b for next bit, ; and so on until f for bit 5. (See polarity_do_here, below.) ; ; we accumulate (`gather') the `g' bits in t. mov_lfsr polarity_cmds, 1 mov_fw POSTINC0 ; W = 10010RRR mov_wf t ; t = 10010ggg xor_lw b'10001000' ; t = 00011ggg loop ; Exit from this loop is done by board popping, doing some ; final stuff, and returning. See board_next_none, below. rrc_fw INDF0 ; W = ?Mhhhhhh C = g rlc_f t ; t = 0*11g+ C = ? bra_nn if_not_gathered ; ; t = 11gggggg mov_fw t rcall board mov_lw b'000000011' ; W = 00000011 mov_wf t ; t = 00000011 if_not_gathered ; *INDF0 = Mhhhhhhg rr_fw INDF0 ; W = gMhhhhhh ior_lw b'011000000' ; W = 11hhhhhh rcall board bt_f_if1 POSTINC0,7 ; *POSTINC0 : M....... bra loop ; otherwise: panic morse_RS ;---------- board mov_wf INDF1 ; *(this pic) = 11RRRRRR ; FSR1 -> pic we've just filled ;... board_next_loop dec_fw PREINC1 ; FSR1 -> pic after one we're testing ; W = 1??????? existing reverse command ; 00000000 not a reversers pic ; 11111111 no existing command ; 00111111 sentinel bra_z board_next_loop ; not a reversers pic bra_nn board_next_none ; sentinel return ;---------- board_next_none bt_f_if1 INDF0,7 ; *INDFO : M....... bra board_next_none_more_message ;... ; now we're exiting from the loop in when_reverse_message_found pop ; that disposes of the call to `board' call power_polarising_begin mov_fw polarity_cmds ; there's always a board 0, us call polarity_local_do clr_f polarity_cmds ; we've done ours (this is for form's sake) rcall polarity_needwrite ; does `return' because it will find one return ; ... or maybe not if only 1 rev board ; so do not optimise away rcall/return combination ! ;---------- board_next_none_more_message panic morse_RL ;---------------------------------------------------------------------- polarity_master_init @ load_tblptr picno2revmasks mov_lfsr polarity_cmds - 1, 0 mov_lw maxpics mov_wf t mov_lw 0x01 ; meaning `not a reversers board' polarity_master_init_boardloop mov_wf PREINC0 rcall polarity_master_init_board_mask_check rcall polarity_master_init_board_mask_check dec_f_ifnz t bra polarity_master_init_boardloop bt_f_if1 polarity_cmds, 0 bra polarity_bad_masternotused ; OK, but now we have to work our way back and place ; the sentinel mov_lw 0x40 ; meaning `sentinel' bt_f_if0 INDF0, 0 bra polarity_bad_lastpicused polarity_master_init_truncateloop mov_wf POSTDEC0 ; overwrite with sentinel tst_f_ifnz INDF0 ; previous one is also `not reversers board' ? bra polarity_master_init_truncateloop ; yes ; no. hah, we have truncated it. return polarity_master_init_board_mask_check ; W preserved ; FSR0 unchanged ; INDF0 maybe set to `reversers board but no command' ; TBLPTR* used and advanced ; TABLAT trashed ; STATUS trashed ; everything else preserved tblrd_postinc_fixup tst_f_ifnz TABLAT clr_f INDF0 ; meaning `reversers board but no command to send' return polarity_bad_masternotused panic morse_RF polarity_bad_lastpicused panic morse_RG ;---------------------------------------------------------------------- polarity_needwrite @ ; needwrite_ will see if we need to talk to a slave ; if not it will simply return ; if we _do_, it will put the slave no. in W, and then pop ; and branch to i2c_needwrite. See mascan.asm. ; nb register usage may need to be adjusted for wiring into mascan i2cm_... mov_lfsr polarity_cmds, 0 polarity_needwrite_loop rlc_fw PREINC0 ; W = 1RRRRRR? C=1 reverse command ; W = 0000001? C=0 not a reversers pic ; W = 0000000? C=0 no existing command ; W = 1000000? C=0 sentinel bra_nn polarity_needwrite_loop bt_f_if1 STATUS, C bra polarity_needwrite_found ; we found the sentinel: goto power_polarising_nonetodo polarity_needwrite_found mov_fw FSR0L add_lw -polarity_cmds pop goto i2c_needwrite near_getwritebyteyes code ;---------------------------------------------------------------------- polarity_getwritebyte @ ; getwritebyte_ finds a byte to write to a particular ; slave. If we have something to write, puts the byte in W ; and does `goto getwritebyte_yes'. Otherwise simply returns. ; ; on entry return, `no' branch-away, `yes' ; cwslave slave number preserved preserved ; W undefined trashed byte for slave ; mov_lfsr polarity_cmds, 0 mov_fw cwslave add_wff FSR0L bt_f_if0 INDF0, 7 return ; yes, we have something: mov_fw INDF0 clr_f INDF0 ; we're about to write this bra i2c_getwritebyte_yes ;====================================================================== include final.inc