chiark / gitweb /
mascan compilation wip
[trains.git] / detpic / points.asm
1 ;======================================================================
2 ; POINTS
3
4  include common.inc
5
6 ;----------------------------------------
7 ; LOCAL POINTS - Variables, hardware, etc.
8 ;
9 ;                       Idle            Firing
10 ;       Timer 3         Off             On, counting up
11 ;       pointmsg        undefined       message from master
12
13 ptix2latbit equ 0x300 ; has to be a multiple of 0x100
14 ptix2latbit_section udata ptix2latbit
15  res maxpoints * 2      ; LAT* and bit
16                         ; for unused point, 0x00 and 0x00
17
18  udata_acs
19 pointmsg                res     1
20
21 ;======================================================================
22  code
23
24 ;======================================================================
25 ; LOCAL POINTS
26 ; on slave, or master's own
27
28 ;----------------------------------------------------------------------
29 ; LOCAL POINTS - ACTUALLY DOING
30
31 ;----------------------------------------
32 point_local_do
33 ; On slave, called during i2c receive, ie High ISR
34 ; On master, called during serial receive, ie Low ISR
35 ;               W       fire point msg          undefined
36         bt_f_if1 T3CON, TMR3ON
37         bra     point_clash
38
39         mov_wf  pointmsg        ; pointmsg = SS zz zz pp  pp pp pp pp
40
41         intrh_fsr0_save         ; point_set_pin uses FSR0, see below
42         rcall   point_set_pin
43         intrh_fsr0_restore
44
45         clr_f   TMR3L           ; also copies TMR3H into actual timer register
46         bs_f    T3CON, TMR3ON
47         return
48
49 ;----------------------------------------
50 points_local_intrl
51         bt_f_if0 PIR2, TMR3IF
52         return
53         ; OK, it's us, and we're done changing a point:
54
55         bt_f_if0 T3CON, TMR3ON
56         bra     point_spurious_intr
57
58         rcall   point_set_pin
59         intrh_mask
60         bc_f    T3CON, TMR3ON
61         bc_f    PIR2, TMR3IF
62         intrh_unmask
63
64         mov_lw  b'00100000'
65         call    message_for_master
66         intrl_handled_nostack
67
68 ;----------
69 point_spurious_intr
70         panic   morse_PI
71
72 ;----------
73 point_set_pin
74 ; Toggles the pin.  The effect is:
75 ;       If we were idle, sets it H (to fire) unless pt0 in which case L
76 ;       If we were firing, sets it L (to stop) unless pt0 in which case H
77 ;
78 ; Called in various contexts, including both High and Low ISR.
79 ;
80 ;  pointmsg     point to start or stop firing   preserved
81 ;  W,STATUS     any                             undefined
82 ;  FSR0         any                             undefined
83 ;  all other    any                             not interfered with
84 ;
85         mov_lw  ptix2latbit >> 8
86         mov_wf  FSR0H           ; FSR0H -> table
87         rl_fw   pointmsg        ; W = point addr, Z iff pt0
88         mov_wf  FSR0L           ; FSR0 -> &bit   [Z still iff pt0]
89         mov_fw  POSTDEC0        ; W = bit, FSR0 -> &LAT*
90         bra_z   point_nonexistent
91         mov_ff  INDF0, FSR0L    ; W = bit, FSR0L -> LAT*
92         set_f   FSR0H           ; FSR0 -> LAT*, W = bit (still)
93         xor_wff INDF0           ; pin = !pin
94         return
95
96 point_nonexistent
97         panic   morse_PU
98
99 ;----------
100 point_clash
101         panic   morse_PB
102
103 ;----------------------------------------------------------------------
104 ; LOCAL POINTS - INITIALISATION
105
106 ;----------------------------------------
107 points_local_init
108 ; Initialises tables for points
109 ; Clears TRIS* bits for all points and sets each pin to `not triggering'
110
111         rcall   point_timer_init
112
113 ;       We do this in two stages.
114 ;       Firstly, we scan the bitmap for this pic, setting
115 ;        ptix2latbit to 0xff,0x00 for used points and 0x00,0x00
116 ;        to unused ones.
117 ;       Secondly, we scan the bkptix2portnumbitnum, adjusting
118 ;        ptix2latbit to have actually correct data.
119 ;       Doing it like this avoids having to constantly recompute
120 ;        individual TBLPTR*'s.
121
122         mov_lfsr ptix2latbit-1, 0 ; FSR0 -> this bit and LAT*
123                                   ;  points just at last thing we've filled in
124
125         load_perpic_tblptr picno2ptmap, maxpoints/8
126
127         mov_lw  maxpoints/8
128         mov_wf  t               ; t = byte counter
129 ;...
130 points_init_byte_loop
131         mov_lw  8               ; W = bit counter
132         tblrd_postinc_fixup     ; TABLAT = bitmap data being processed
133 ;...
134 points_init_bit_loop
135         clr_f   PREINC0         ; FSR0 -> LAT*[current] := 0
136         rrc_f   TABLAT
137         bt_f_if1 STATUS,C
138         set_f   INDF0           ; FSR0 -still-> LAT*[current] := 0xff
139
140         clr_f   PREINC0         ; FSR0 -> bit[current] := 0
141
142         dec_w_ifnz
143         bra     points_init_bit_loop
144         dec_f_ifnz t
145         bra     points_init_byte_loop
146 ;... end of loop:
147
148 ;       We've scanned for points used on this board;
149 ;       now find the actual pins.
150
151         mov_lw  bkptix2portnumbitnum & 0xff
152         bt_f_if1 idloc1,idloc1_boarddet
153         add_lw  maxpoints
154         mov_wf  TBLPTRL
155
156         mov_lw  bkptix2portnumbitnum >> 8
157         mov_wf  TBLPTRH         ; TBLPTR* -> point port/bit data
158
159         set_f   FSR2H           ; FSR2 -> some SFR, will point to LAT/TRIS
160         mov_lfsr bitnum2bit+7, 1 ; FSR1 -> bitnum2bit+7
161         mov_lfsr ptix2latbit-1, 0 ; FSR0 -> last bit (and previous LAT*)
162
163         mov_lw  maxpoints
164         mov_wf  t               ; t = loop counter
165 ;...
166 points_init_portbit_loop
167         tblrd_postinc_fixup     ; TABLAT = portnum4 || bitnum4
168
169         bt_f_if0 PREINC0,7      ; zero?, FSR0 -> LAT*[this]
170         bra     points_init_portbit_endif_used
171 ;...
172 points_init_portbit_if_used
173         mov_fw  TABLAT
174         bra_n   point_initing_bad_point
175
176         ior_lw  0xf8            ; W -> bit value for bit
177         mov_wf  FSR1L           ; FSR1 -> bit value for bit
178
179         swap_fw TABLAT          ; W = bitnum4 || portnum4
180         and_lw  0x0f            ; W = portnum4
181         add_lw  LATA & 0xff     ; W = LAT*
182         mov_wf  POSTINC0        ; LAT*[this] := LAT, FSR0 -> bit[this]
183         mov_wf  FSR2L           ; FSR2 -> LAT*
184
185         mov_fw  INDF1           ; W = bit
186         mov_wf  POSTDEC0        ; bit[this] = bit, FSR0 -> LAT*[this]
187         com_w                   ; W = ~bit
188         and_wff INDF2           ; LAT* &= ~bit, ie pin set to L (still Z)
189         pin_vh  pall_pt0reverse ; but pt0 pin is backwards, set to H
190                                 ;  (still Z, unless we've done this already)
191         mov_lw  TRISA-LATA
192         add_wff FSR2L           ; FSR2 -> TRIS*
193         com_fw  INDF1           ; W = ~bit
194         and_wff INDF2           ; TRIS* &= ~bit, ie pin set to not Z
195
196         set_f   FSR1L           ; FSR1 -> bitnum2bit+7, again
197 points_init_portbit_endif_used
198         ; so now we move on to the next one
199         mov_fw  POSTINC0        ; FSR0 -> bit[this]
200
201         dec_f_ifnz t
202         bra     points_init_portbit_loop
203
204         return
205
206 ;----------
207 point_initing_bad_point
208         panic   morse_PF
209
210 ;----------
211 point_timer_init
212         bt_f_if1 idloc1,idloc1_master
213         bra     point_timer_init_if_master
214         ; slave:
215         mov_lw  (1<<RD16)|(1<<T3ECCP1)| points_slave_t3scale; Fcy;!TMR3ON
216         mov_wf  T3CON
217         mov_lw  points_slave_t3inith
218         bra     point_timer_init_endif_masterslave
219 point_timer_init_if_master
220         mov_lw  (1<<RD16)|(1<<T3ECCP1)| points_master_t3scale; Fcy;!TMR3ON
221         mov_wf  T3CON
222         mov_lw  points_master_t3inith
223 point_timer_init_endif_masterslave
224         mov_wf  TMR3H   ; We just leave this here.
225                         ; Since we never read TMR3L, it is never overwritten
226
227         bc_f    PIR2, TMR3IF
228         bs_f    PIE2, TMR3IE
229         bc_f    IPR2, TMR3IP
230         return
231
232 ;======================================================================
233
234 cdu_init        panic   morse_UCI
235 ; For master pic only.  Sorts out the CDU's pin.
236
237 got_pointed     panic   morse_UCP
238
239  include final.inc