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