chiark / gitweb /
7d4e76d050ec23d69b1fc0a0320832924e99df5e
[trains.git] / detpic / reverse.asm
1 ;======================================================================
2 ; REVERSERS
3
4  include common.inc
5
6 ;----------------------------------------
7 ; LOCAL REVERSERS - Variables
8
9  udata_acs
10 maska                           res     1
11 maske                           res     1
12
13 ;----------------------------------------
14 ; MASTER - Access bank variables and other sections
15
16 polarity_cmds equ 0x5f
17 polarity_cmds_section udata polarity_cmds
18  res maxpics
19         ; Each byte is:
20         ;       11RRRRRR        reverse command for slave, waiting to write
21         ;       00000001        this is not a reversers board
22         ;       00000000        we have written any relevant command
23         ;       01000000        sentinel
24
25 ;======================================================================
26 ; LOCAL REVERSERS
27 ; on slave, or master's own
28
29 near_local_do code
30 ;----------
31 polarity_local_do
32 ; On slave, called during i2c receive, ie High ISR
33 ; On master, called during serial receive, ie Low ISR
34 ; See common.inc !
35 ;
36 ;  W            here polarity msg (see below)           undefined
37 ;  STATUS       any                                     undefined
38 ;  t_dolocal    any                                     undefined
39 ;  maska,maske  set up correctly                        preserved
40 ;  LATA,LATE    any                                     modified appropriately
41 ;  all others   any                                     preserved
42 ;
43 ;       on entry:               ; W =           PP PP v3 v0  v2 v1 v5 v4
44 ;
45 ; where PP bits are those specifying that this is a polarity message
46 ;       v<num> is the reversal bits for point <num>
47 ;
48         mov_wf  t_dolocal       ; t =           PP PP v3 v0  v2 v1 v5 v4
49
50         mov_fw  LATE            ; W =           kk kk kk kk  kk kk o5 o4
51         xor_wfw t_dolocal       ; W =           ?? ?? ?? ??  ?? ?? d5 d4
52         and_wfw maske           ; W =           zz zz zz zz  zz zz d5 d4
53         xor_wff LATE            ; LATE =        kk kk kk kk  kk kk v5 v4
54
55         bc_f    t_dolocal, 1    ; t =           SS SS v3 v0  v2 v1 zz v4
56         bt_f_if1 t_dolocal, 4   ; t :           .. .. .. v0  .. .. .. ..
57         bs_f    t_dolocal, 1    ; t =           SS SS v3 v0  v2 v1 v0 v4
58
59         mov_fw  LATA            ; W =           kk kk o3 kk  o2 o1 o0 kk
60         xor_wfw t_dolocal       ; W =           ?? ?? d3 ??  d2 d1 d0 ??
61         and_wfw maska           ; W =           zz zz d3 zz  d2 d1 d0 zz
62         xor_wff LATA            ; LATA =        kk kk v3 kk  v2 v1 v0 kk
63
64                                 ; where kk is a bit we must keep
65                                 ;       o<n> is old reverse bit
66                                 ;       d<n> is old (+) new
67                                 ;       v<n> is new reverse bit
68         return
69
70  code
71 ;----------
72 polarity_local_init
73         load_perpic_tblptr picno2revmasks, 2
74
75         tblrd_postinc_fixup
76         mov_fw  TABLAT
77         mov_wf  maska
78
79         tblrd_postinc_fixup
80         mov_fw  TABLAT
81         mov_wf  maske
82
83         clr_w
84         call    polarity_local_do
85
86         com_fw  maska
87         and_wff TRISA
88
89         com_fw  maske
90         and_wff TRISE
91
92         return
93
94 ;======================================================================
95 ; MASTER
96
97 ;----------
98 command_polarity
99 ; message format
100 ;               SS zz zz SS  ZZ 2f 2e 2d        g is board 2
101 ;               MM 2c 0f 0e  0d 0c 0b 0a        board 0
102 ;               MM 2b 1f 1e  1d 1c 1b 1a        board 1
103 ;               MM 2a 3f 3e  3d 3c 3b 3a        g, board 2, complete, also 3
104 ;               MM 9f 4f 4e  4d 4c 4b 4a        g is board 9
105 ;               MM 9e 5f 5e  5d 5c 5b 5a
106 ;               MM 9d 6f 6e  6d 6c 6b 6a
107 ;               MM 9c 7f 7e  7d 7c 7b 7a
108 ;               MM 9b 8f 8e  8d 8c 8b 8a
109 ;               MM 9a af ae  ad ac ab aa
110 ;               etc.
111 ; where
112 ;       SS      bit set
113 ;       zz      bit zero
114 ;       other things are <board><segment> where <segment>
115 ;               is a for LSb in message to PIC, b for next bit,
116 ;               and so on until f for bit 5.  (See polarity_do_here, below.)
117 ;
118 ; we accumulate (`gather') the `g' bits in t.
119         mov_lfsr polarity_cmds, 1
120         mov_fw  POSTINC0        ; W =           10010RRR
121         mov_wf  t               ; t =           10010ggg
122         xor_lw  b'10001000'     ; t =           00011ggg
123 loop ; Exit from this loop is done by board popping, doing some
124      ; final stuff, and returning.   See board_next_none, below.
125         rrc_fw  INDF0           ; W =           ?Mhhhhhh  C = g
126         rlc_f   t               ; t =           0*11g+    C = ?
127         bra_nn  if_not_gathered
128         ;                       ; t =           11gggggg
129         mov_fw  t
130         rcall   board
131         mov_lw  b'000000011'    ; W =           00000011
132         mov_wf  t               ; t =           00000011
133 if_not_gathered                 ; *INDF0 =      Mhhhhhhg
134         rr_fw   INDF0           ; W =           gMhhhhhh
135         ior_lw  b'011000000'    ; W =           11hhhhhh
136         rcall   board
137         bt_f_if1 POSTINC0,7     ; *POSTINC0 :   M.......
138         bra     loop
139         ; otherwise:
140         panic   morse_RS
141
142 ;----------
143 board
144         mov_wf  INDF1           ; *(this pic) = 11RRRRRR
145                                 ; FSR1 -> pic we've just filled
146 ;...
147 board_next_loop
148         dec_fw  PREINC1         ; FSR1 -> pic after one we're testing
149                                 ; W = 1???????  existing reverse command
150                                 ;     00000000  not a reversers pic
151                                 ;     11111111  no existing command
152                                 ;     00111111  sentinel
153         bra_z   board_next_loop ; not a reversers pic
154         bra_nn  board_next_none ; sentinel
155         return
156
157 ;----------
158 board_next_none
159         bt_f_if1 INDF0,7        ; *INDFO :      M.......
160         bra     board_next_none_more_message
161 ;...
162 ; now we're exiting from the loop in when_reverse_message_found
163         pop      ; that disposes of the call to `board'
164
165         call    power_polarising_begin
166
167         mov_fw  polarity_cmds ; there's always a board 0, us
168         call    polarity_local_do
169         rcall   polarity_needwrite ; does `return' because it will find one
170         return                     ; ... or maybe not if only 1 rev board
171
172 ;----------
173 board_next_none_more_message
174         panic   morse_RL
175
176 ;----------------------------------------------------------------------
177 polarity_master_init
178
179         load_tblptr picno2revmasks
180         mov_lfsr polarity_cmds - 1, 0
181         mov_lw  maxpics
182         mov_wf  t
183         mov_lw  0x01 ; meaning `not a reversers board'
184 polarity_master_init_boardloop
185         mov_wf  PREINC0
186         rcall   polarity_master_init_board_mask_check
187         rcall   polarity_master_init_board_mask_check
188         dec_f_ifnz t
189         bra     polarity_master_init_boardloop
190
191         bt_f_if1 polarity_cmds, 0
192         bra     polarity_bad_masternotused
193
194         ; OK, but now we have to work our way back and place
195         ; the sentinel
196         mov_lw  0x40 ; meaning `sentinel'
197         bt_f_if0 INDF0, 0
198         bra     polarity_bad_lastpicused
199 polarity_master_init_truncateloop
200         mov_wf  POSTDEC0 ; overwrite with sentinel
201         tst_f_ifnz INDF0 ; previous one is also `not reversers board' ?
202         bra     polarity_master_init_truncateloop ; yes
203         ; no.  hah, we have truncated it.
204
205         return
206
207 polarity_master_init_board_mask_check
208 ;  W                    preserved
209 ;  FSR0                 unchanged
210 ;  INDF0                maybe set to `reversers board but no command'
211 ;  TBLPTR*              used and advanced
212 ;  TABLAT               trashed
213 ;  STATUS               trashed
214 ;  everything else      preserved
215         tblrd_postinc_fixup
216         tst_f_ifnz TABLAT
217         clr_f   INDF0 ; meaning `reversers board but no command to send'
218         return
219
220 polarity_bad_masternotused panic morse_RF
221 polarity_bad_lastpicused panic morse_RG
222
223 ;----------------------------------------------------------------------
224 polarity_needwrite
225 ;  needwrite_<something> will see if we need to talk to a slave
226 ;    if not it will simply return
227 ;    if we _do_, it will put the slave no. in W, and then pop
228 ;     and branch to i2c_needwrite.  See mascan.asm.
229 ;  nb register usage may need to be adjusted for wiring into mascan i2cm_...
230         mov_lfsr polarity_cmds, 0
231 polarity_needwrite_loop
232         rlc_fw  PREINC1         ; W = 1RRRRRR? C=1  reverse command
233                                 ; W = 0000001? C=0  not a reversers pic
234                                 ; W = 0000000? C=0  no existing command
235                                 ; W = 1000000? C=0  sentinel
236         bra_nn  polarity_needwrite_loop
237         bt_f_if1 STATUS, C
238         bra     polarity_needwrite_found
239         ; we found the sentinel:
240
241         bt_f_if0 flags, flags_polarising
242         return
243         goto    power_polarising_settling
244
245 polarity_needwrite_found
246         mov_fw  FSR1L
247         add_lw  -polarity_cmds
248         pop
249         goto    i2c_needwrite
250
251 near_getwritebyteyes code
252 ;----------------------------------------------------------------------
253 polarity_getwritebyte
254 ;  getwritebyte_<something> finds a byte to write to a particular
255 ;   slave.  If we have something to write, puts the byte in W
256 ;   and does `goto getwritebyte_yes'.  Otherwise simply returns.
257 ;
258 ;               on entry                return, `no'    branch-away, `yes'
259 ;  cwslave      slave number            preserved       preserved
260 ;  W            undefined               trashed         byte for slave
261 ;
262         mov_lfsr polarity_cmds, 0
263         mov_fw  cwslave
264         add_wff FSR0L
265         mov_fw  INDF0
266         bra_n   i2c_getwritebyte_yes
267         ; no:
268         return
269
270 ;======================================================================
271  include final.inc