chiark / gitweb /
more peco part numbers and some info about pecofguess_l
[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 0f 0e  0d 0c 0b 0a 2c        board 0
102 ;               MM 1f 1e  1d 1c 1b 1a 2b        board 1
103 ;               MM 3f 3e  3d 3c 3b 3a 2a        g, board 2, complete, also 3
104 ;               MM 4f 4e  4d 4c 4b 4a 9f        g is board 9
105 ;               MM 5f 5e  5d 5c 5b 5a 9e
106 ;               MM 6f 6e  6d 6c 6b 6a 9d
107 ;               MM 7f 7e  7d 7c 7b 7a 9c
108 ;               MM 8f 8e  8d 8c 8b 8a 9b
109 ;               MM af ae  ad ac ab aa 9a
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         clr_f   polarity_cmds ; we've done ours (this is for form's sake)
170         rcall   polarity_needwrite ; does `return' because it will find one
171         return                     ; ... or maybe not if only 1 rev board
172         ; so do not optimise away rcall/return combination !
173
174 ;----------
175 board_next_none_more_message
176         panic   morse_RL
177
178 ;----------------------------------------------------------------------
179 polarity_master_init @
180
181         load_tblptr picno2revmasks
182         mov_lfsr polarity_cmds - 1, 0
183         mov_lw  maxpics
184         mov_wf  t
185         mov_lw  0x01 ; meaning `not a reversers board'
186 polarity_master_init_boardloop
187         mov_wf  PREINC0
188         rcall   polarity_master_init_board_mask_check
189         rcall   polarity_master_init_board_mask_check
190         dec_f_ifnz t
191         bra     polarity_master_init_boardloop
192
193         bt_f_if1 polarity_cmds, 0
194         bra     polarity_bad_masternotused
195
196         ; OK, but now we have to work our way back and place
197         ; the sentinel
198         mov_lw  0x40 ; meaning `sentinel'
199         bt_f_if0 INDF0, 0
200         bra     polarity_bad_lastpicused
201 polarity_master_init_truncateloop
202         mov_wf  POSTDEC0 ; overwrite with sentinel
203         tst_f_ifnz INDF0 ; previous one is also `not reversers board' ?
204         bra     polarity_master_init_truncateloop ; yes
205         ; no.  hah, we have truncated it.
206
207         return
208
209 polarity_master_init_board_mask_check
210 ;  W                    preserved
211 ;  FSR0                 unchanged
212 ;  INDF0                maybe set to `reversers board but no command'
213 ;  TBLPTR*              used and advanced
214 ;  TABLAT               trashed
215 ;  STATUS               trashed
216 ;  everything else      preserved
217         tblrd_postinc_fixup
218         tst_f_ifnz TABLAT
219         clr_f   INDF0 ; meaning `reversers board but no command to send'
220         return
221
222 polarity_bad_masternotused panic morse_RF
223 polarity_bad_lastpicused panic morse_RG
224
225 ;----------------------------------------------------------------------
226 polarity_needwrite @
227 ;  needwrite_<something> will see if we need to talk to a slave
228 ;    if not it will simply return
229 ;    if we _do_, it will put the slave no. in W, and then pop
230 ;     and branch to i2c_needwrite.  See mascan.asm.
231 ;  nb register usage may need to be adjusted for wiring into mascan i2cm_...
232         mov_lfsr polarity_cmds, 0
233 polarity_needwrite_loop
234         rlc_fw  PREINC0         ; W = 1RRRRRR? C=1  reverse command
235                                 ; W = 0000001? C=0  not a reversers pic
236                                 ; W = 0000000? C=0  no existing command
237                                 ; W = 1000000? C=0  sentinel
238         bra_nn  polarity_needwrite_loop
239         bt_f_if1 STATUS, C
240         bra     polarity_needwrite_found
241         ; we found the sentinel:
242
243         goto    power_polarising_nonetodo
244
245 polarity_needwrite_found
246         mov_fw  FSR0L
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         bt_f_if0 INDF0, 7
266         return
267         ; yes, we have something:
268
269         mov_fw  INDF0
270         clr_f   INDF0 ; we're about to write this
271         bra     i2c_getwritebyte_yes
272
273 ;======================================================================
274   include final.inc