clr_f TBLPTRU ; TBLPTR* -> our point data
endm
+;----------------------------------------
+; invocation macro for outpins_local_init_part{1,2}, see misc.asm
+outputs_local_init macro picno2thingmap, maxthings, thingix2latbit, bkthingix2portnumbitnum
+
+ load_perpic_tblptr picno2thingmap, maxthings/8
+ mov_lfsr thingix2latbit-1, 0
+ mov_lw maxthings/8
+
+ call outpins_local_init_part1
+
+ mov_lw bkthingix2portnumbitnum >> 8
+ mov_wf TBLPTRH ; TBLPTR* -> point port/bit data
+ mov_lw bkthingix2portnumbitnum & 0xff
+ mov_wf TBLPTRL
+
+ mov_lfsr thingix2latbit-1, 0 ; FSR0 -> last bit (and previous LAT*)
+ mov_lw maxthings
+
+ call outpins_local_init_part2
+
+ endm
+
;----------------------------------------------------------------------
; PINSPECS stuff
;
mov_ff dsave_fsr0+1, FSR0H
return
+;------------------------------------------------------------
+outpins_local_init_part1 @
+; Initialises a table of output pins
+; TBLPTR picno2<thing>map (presence bitmap)
+; FSR0 <thing>ix2latbit - 1 (start of output table)
+; W max<thing>s / 8 (table sizes)
+; outpins_local_init_part2 @
+; TBLPTR bk<thing>ix2portnumbitnum (phys pins)
+; FSR0 <thing>ix2latbit - 1 (start of output table)
+; W max<thing>s (table sizes)
+; Caller must use both, and set variables as above on each entry.
+;
+; Input table is as made by writeasm_outpin
+; Result table is series of 2-byte entries,
+; 0th byte is bottom byte of LAT* address
+; 1st byte is single-bit mask for the relevant pin
+
+; Internals:
+; We do this in two stages.
+; Firstly, we scan the bitmap for this pic, setting
+; <thing>ix2latbit to 0xff,0x00 for used points and 0x00,0x00
+; to unused ones.
+; Secondly, we scan the bk<thing>ix2portnumbitnum, adjusting
+; <thing>ix2latbit to have actually correct data.
+; Doing it like this avoids having to constantly recompute
+; individual TBLPTR*'s.
+
+; On entry FSR0 -> this bit and LAT*
+; points just at last thing we've filled in
+
+ mov_wf t ; t = byte counter
+;...
+outpins_init_byte_loop
+ mov_lw 8 ; W = bit counter
+ tblrd_postinc_fixup ; TABLAT = bitmap data being processed
+;...
+outpins_init_bit_loop
+ clr_f PREINC0 ; FSR0 -> LAT*[current] := 0
+ rrc_f TABLAT
+ bt_f_if1 STATUS,C
+ set_f INDF0 ; FSR0 -still-> LAT*[current] := 0xff
+
+ clr_f PREINC0 ; FSR0 -> bit[current] := 0
+
+ dec_w_ifnz
+ bra outpins_init_bit_loop
+ dec_f_ifnz t
+ bra outpins_init_byte_loop
+;... end of loop:
+
+
+; We've scanned for points used on this board;
+; now find the actual pins.
+
+ return ; caller will reset
+outpins_local_init_part2 @ ; TBLPTR, FSR0 and W (see above)
+
+ bt_f_if1 idloc1,idloc1_boarddet
+ add_wff TBLPTRL
+
+ set_f FSR2H ; FSR2 -> some SFR, will point to LAT/TRIS
+ mov_lfsr bitnum2bit+7, 1 ; FSR1 -> bitnum2bit+7
+
+ mov_wf t ; t = loop counter
+;...
+outpins_init_portbit_loop
+ tblrd_postinc_fixup ; TABLAT = portnum4 || bitnum4
+
+ bt_f_if0 PREINC0,7 ; zero?, FSR0 -> LAT*[this]
+ bra outpins_init_portbit_endif_used
+;...
+outpins_init_portbit_if_used
+ mov_fw TABLAT
+ bra_n outpins_initing_bad_object
+
+ 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 LATA & 0xff ; W = LAT*
+ mov_wf POSTINC0 ; LAT*[this] := LAT, FSR0 -> bit[this]
+ mov_wf FSR2L ; FSR2 -> LAT*
+
+ mov_fw INDF1 ; W = bit
+ 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
+ ; (still Z, unless we've done this already)
+ ; (we don't care about doing this far too
+ ; many times here.)
+ mov_lw TRISA-LATA
+ add_wff FSR2L ; FSR2 -> TRIS*
+ com_fw INDF1 ; W = ~bit
+ and_wff INDF2 ; TRIS* &= ~bit, ie pin set to not Z
+
+ set_f FSR1L ; FSR1 -> bitnum2bit+7, again
+outpins_init_portbit_endif_used
+ ; so now we move on to the next one
+ mov_fw POSTINC0 ; FSR0 -> bit[this]
+
+ dec_f_ifnz t
+ bra outpins_init_portbit_loop
+
+ return
+
+;----------
+outpins_initing_bad_object
+ panic morse_OF
+
include final.inc
# Miscellaneous
E ; `expected'; we were told to panic
T ; master paniced because slave paniced
+OF ::t,TBLPTRH ; Flash mentions object not on board
# Regarding communications from the host
HX ::t ; host sent unknown command
PU points:pointmsg ; Firing nonexistent point
PC ; Firing point when CDU empty
PS points:pointslave,points:pointmsg ; Firing point on nonexistent board
-PF ::t ; Flash mentions point not on board
PX ; Host sent >2-byte POINT command
PA ; POINTED when already firing
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
+ res maxpoints * 2 ; as produced by outpin_local_init
udata_acs
pointslave res 1
rcall point_timer_init
-; We do this in two stages.
-; Firstly, we scan the bitmap for this pic, setting
-; ptix2latbit to 0xff,0x00 for used points and 0x00,0x00
-; to unused ones.
-; Secondly, we scan the bkptix2portnumbitnum, adjusting
-; ptix2latbit to have actually correct data.
-; Doing it like this avoids having to constantly recompute
-; individual TBLPTR*'s.
-
- 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
-
- mov_lw maxpoints/8
- mov_wf t ; t = byte counter
-;...
-points_init_byte_loop
- mov_lw 8 ; W = bit counter
- tblrd_postinc_fixup ; TABLAT = bitmap data being processed
-;...
-points_init_bit_loop
- clr_f PREINC0 ; FSR0 -> LAT*[current] := 0
- rrc_f TABLAT
- bt_f_if1 STATUS,C
- set_f INDF0 ; FSR0 -still-> LAT*[current] := 0xff
-
- clr_f PREINC0 ; FSR0 -> bit[current] := 0
-
- dec_w_ifnz
- bra points_init_bit_loop
- dec_f_ifnz t
- bra points_init_byte_loop
-;... end of loop:
-
-; We've scanned for points used on this board;
-; now find the actual pins.
-
- mov_lw bkptix2portnumbitnum & 0xff
- bt_f_if1 idloc1,idloc1_boarddet
- add_lw maxpoints
- mov_wf TBLPTRL
-
- mov_lw bkptix2portnumbitnum >> 8
- mov_wf TBLPTRH ; TBLPTR* -> point port/bit data
-
- set_f FSR2H ; FSR2 -> some SFR, will point to LAT/TRIS
- mov_lfsr bitnum2bit+7, 1 ; FSR1 -> bitnum2bit+7
- 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 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 LATA & 0xff ; W = LAT*
- mov_wf POSTINC0 ; LAT*[this] := LAT, FSR0 -> bit[this]
- mov_wf FSR2L ; FSR2 -> LAT*
-
- mov_fw INDF1 ; W = bit
- 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
- ; (still Z, unless we've done this already)
- mov_lw TRISA-LATA
- add_wff FSR2L ; FSR2 -> TRIS*
- com_fw INDF1 ; W = ~bit
- and_wff INDF2 ; TRIS* &= ~bit, ie pin set to not Z
-
- 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]
-
- dec_f_ifnz t
- bra points_init_portbit_loop
+ outputs_local_init picno2ptmap, maxpoints, ptix2latbit, bkptix2portnumbitnum
return
-;----------
-point_initing_bad_point
- panic morse_PF
-
;----------
point_timer_init
bt_f_if1 idloc1,idloc1_master