; FSR0 Low ISR Low ISR
; PCLATU Always set to 0 Not used
; PCLATH Low ISR Not used
+; t_dolocal Low ISR High ISR
; FSR1 Low ISR High ISR (detect[1])
; FSR2 Low ISR High ISR (detect[1])
;
; interrupt, or any routine run during initialisation.
; May therefore not be used in background loop with
; interrupts enabled. May not be used by high-priority
-; ISR (unless explicitly saved).
+; ISR (unless explicitly saved, eg isrh_fsr0_{save,restore}).
;
; High ISR May be used/trashed by any routine run in high-priority
; interrupt, or any routine run during initialisation.
; Conventional routine names:
;
; <periph>_local_do Process a master-to-slave command to activate
-; a local peripheral (also called on master to
-; activate its own local peripherals)
+; a local peripheral, in High ISR. Also called
+; on master in Low ISR to activate its own
+; local peripherals. NB strange calling convention!
;
; <periph>_local_init Initialises RAM tables for local peripheral
; and arranges for pins to be set in appropriate
;
; <periph>_local_intrl Low ISR service routine for peripheral (see below).
;
-; <periph>_master_do Called when an appropriate message has been
+; command_<periph> Called when an appropriate message has been
; received from the host.
;
; <something>_intrl Low ISR service routine.
mov_ff STKPTR, isr_low_save_stkptr
endm
+intrh_fsr0_save macro
+ mov_ff FSR0L, isr_high_save_fsr0
+ mov_ff FSR0H, isr_high_save_fsr0+1
+ endm
+
+intrh_fsr0_restore macro
+ mov_ff isr_high_save_fsr0, FSR0L
+ mov_ff isr_high_save_fsr0+1, FSR0H
+ endm
+
intrl_handled_core macro ; for internal use only
mov_fw isr_low_save_w
mov_ff isr_low_save_status, STATUS
; GIEH modified appropriately
; everything else preserved
-mask_int_high macro
+intrh_mask macro
bc_f INTCON,GIEH
endm
-unmask_int_high macro
+intrh_unmask macro
bs_f INTCON,GIEH
endm
; Timer 3 Off On, counting up
; pointmsg undefined message from master
-ptix2bitlat equ 0x300
-ptix2bitlat_section udata ptix2bitlat
- res maxpoints * 2 ; bit and LAT*
+ptix2latbit equ 0x300 ; has to be a multiple of 0x100
+ptix2latbit_section udata ptix2latbit
+ res maxpoints * 2 ; LAT* and bit
; for unused point, 0x00 and 0x00
udata_acs
bra point_clash
mov_wf pointmsg ; pointmsg = SS zz zz pp pp pp pp pp
+
+ intrh_fsr0_save ; point_set_pin uses FSR0, see below
rcall point_set_pin
+ intrh_fsr0_restore
clr_f TMR3L ; also copies TMR3H into actual timer register
bs_f T3CON, TMR3ON
- panic morse_UP
return
;----------------------------------------
bra point_spurious_intr
rcall point_set_pin
- mask_int_high
+ intrh_mask
bc_f T3CON, TMR3ON
bc_f PIR2, TMR3IF
- unmask_int_high
+ intrh_unmask
mov_lw b'00100000'
call message_for_master
point_set_pin
; Sets the pin appropriately:
; If we were idle, sets it H (to fire) unless pt0 in which case L
-; If we were firing, sets it L (to stop) unless pt0 in which case H
- mov_lw ptix2bitlat >> 8
+; If we were firing, sets it L (to stop) unless pt0 in which case
+;
+; Called in various contexts, including both High and Low ISR.
+;
+; pointmsg point to start or stop firing preserved
+; Timer 3 enabled iff should stop now not interfered with
+; W,STATUS any undefined
+; FSR0 any undefined
+; all other any not interfered with
+;
+ mov_lw ptix2latbit >> 8
mov_wf FSR0H ; FSR0H -> table
rl_fw pointmsg ; W = point addr, Z iff pt0
mov_wf FSR0L ; FSR0 -> &bit [Z still iff pt0]
bra_z point_set_pin_l
point_set_pin_h
- mov_fw POSTINC0 ; W = bit, FSR0 -> &LAT*
+ mov_fw POSTDEC0 ; W = bit, FSR0 -> &LAT*
bra_z point_nonexistent
mov_ff INDF0, FSR0L ; W = bit, FSR0L -> LAT*
set_f FSR0H ; FSR0 -> LAT*, W = bit (still)
;----------
point_set_pin_l
- com_fw POSTINC0 ; W = ~bit, FSR0 -> &LAT*
+ com_fw POSTDEC0 ; W = ~bit, FSR0 -> &LAT*
mov_ff INDF0, FSR0L ; W = ~bit, FSR0L -> LAT*
set_f FSR0H ; FSR0 -> LAT*, W = bit (still)
mov_ff BSR,FSR0H;qq
- ior_wff INDF0 ; pin = H
+ and_wff INDF0 ; pin = H
point_set_pin_hl
tst_f_ifnz FSR0L ; err, did we just write to 0xf00 ?
return ; no; good.
; We do this in two stages.
; Firstly, we scan the bitmap for this pic, setting
-; ptix2bitlat to 0xff,0x00 for used points and 0x00,0x00
+; ptix2latbit to 0xff,0x00 for used points and 0x00,0x00
; to unused ones.
; Secondly, we scan the bkptix2portnumbitnum, adjusting
-; ptix2bitlat to have actually correct data.
+; ptix2latbit to have actually correct data.
; Doing it like this avoids having to constantly recompute
; individual TBLPTR*'s.
- mov_lfsr ptix2bitlat-1, 0 ; FSR0 -> this bit and LAT*
+ mov_lfsr ptix2latbit-1, 0 ; FSR0 -> this bit and LAT*
; points just at last thing we've filled in
load_perpic_tblptr picno2ptmap, maxpoints/8
tblrd_postinc_fixup ; TABLAT = bitmap data being processed
;...
points_init_bit_loop
- clr_f PREINC0 ; FSR0 -> bit[current] := 0
+ clr_f PREINC0 ; FSR0 -> LAT*[current] := 0
rrc_f TABLAT
bt_f_if1 STATUS,C
- set_f INDF0 ; FSR0 -still-> bit[current] := 0xff
+ set_f INDF0 ; FSR0 -still-> LAT*[current] := 0xff
+
+ clr_f PREINC0 ; FSR0 -> bit[current] := 0
- clr_f PREINC0 ; FSR0 -> LAT*[current] := 0
dec_w_ifnz
bra points_init_bit_loop
dec_f_ifnz t
set_f FSR2H ; FSR2 -> some SFR, will point to LAT/TRIS
mov_ff BSR,FSR2H;qq
mov_lfsr bitnum2bit+7, 1 ; FSR1 -> bitnum2bit+7
- mov_lfsr ptix2bitlat, 0 ; FSR0 -> this bit (and LAT*)
+ mov_lfsr ptix2latbit-1, 0 ; FSR0 -> last bit (and previous LAT*)
mov_lw maxpoints
mov_wf t ; t = loop counter
points_init_portbit_loop
tblrd_postinc_fixup ; TABLAT = portnum4 || bitnum4
- bt_f_if0 POSTINC0,7 ; zero?, FSR0 -> LAT*[this]
+ bt_f_if0 PREINC0,7 ; zero?, FSR0 -> LAT*[this]
bra points_init_portbit_endif_used
;...
points_init_portbit_if_used
mov_fw TABLAT
bra_n point_initing_bad_point
-
+
ior_lw 0xf8 ; W -> bit value for bit
mov_wf FSR1L ; FSR1 -> bit value for bit
swap_fw TABLAT ; W = bitnum4 || portnum4
and_lw 0x0f ; W = portnum4
add_lw qqLATA & 0xff ; W = LAT*
- mov_wf POSTDEC0 ; LAT*[this] := LAT, FSR0 -> bit[this]
+ mov_wf POSTINC0 ; LAT*[this] := LAT, FSR0 -> bit[this]
mov_wf FSR2L ; FSR2 -> LAT*
mov_fw INDF1 ; W = bit
- mov_wf POSTINC0 ; bit[this] = bit, FSR0 -> LAT*[this]
+ mov_wf POSTDEC0 ; bit[this] = bit, FSR0 -> LAT*[this]
com_w ; W = ~bit
and_wff INDF2 ; LAT* &= ~bit, ie pin set to L (still Z)
pin_vh pall_pt0reverse ; but pt0 pin is backwards, set to H
set_f FSR1L ; FSR1 -> bitnum2bit+7, again
points_init_portbit_endif_used
; so now we move on to the next one
- mov_fw POSTINC0 ; FSR0 -> bit[this+1]
+ mov_fw POSTINC0 ; FSR0 -> bit[this]
dec_f_ifnz t
bra points_init_portbit_loop
;----------
polarity_local_do
-; W here polarity msg PP PP v3 v0 v2 v1 v5 v4
+; 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<num> is the reversal bits for point <num>
;
- mov_wf t ; t = PP PP v3 v0 v2 v1 v5 v4
+ 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 ; W = ?? ?? ?? ?? ?? ?? d5 d4
+ 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,1 ; t = SS SS v3 v0 v2 v1 zz v4
- bt_f_if1 t,4 ; t : .. .. .. v0 .. .. .. ..
- bs_f t,1 ; t = SS SS v3 v0 v2 v1 v0 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 ; W = ?? ?? d3 ?? d2 d1 d0 ??
+ 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