chiark / gitweb /
move slavetable to variables.asm
[trains.git] / detpic / mascan.asm
1 ;======================================================================
2 ; MASTER - SCANNING ETC.
3
4  include common.inc
5
6 ;----------------------------------------------------------------------
7  udata_acs
8
9 b       res     1       ; byte just read
10 cslot   res     1       ; current slave in slave table, points to flags byte
11 cbyte   res     1
12         ; one of the following:
13         ;       0000 0000       we're expecting the first byte
14         ;       M0B1 0000       we're expecting more detection byte 1
15         ;       M010 0000       we're expecting more detection byte 2
16         ;       1000 0000       we're expecting an extra byte
17
18  code
19 ;======================================================================
20 ; HANDLING OF I2C EVENTS
21
22 ;----------------------------------------
23 i2cm_intrl
24 ; handles i2c interrupt using i2cm_interrupt[_definite],
25 ; according to the rules for <something>_intrl.
26         bt_f_if0 PIR1, SSPIF
27         return
28         call    i2cm_interrupt_definite
29         intrl_handled_nostack
30
31 ;----------------------------------------
32 i2cmu_done      panic   morse_MD
33
34 ;----------------------------------------
35 i2cmu_write_next_byte
36         panic   morse_UI
37
38 ;======================================================================
39 ; PROCESSING OF INCOMING BYTES - CORE AND DETECTION
40
41 ;----------------------------------------
42 i2cmu_read_got_byte
43 ;               Beforehand      At call
44 ;   State       Reading         Reading-Wait
45 ;   W                           data from slave
46 ;
47 ; See detect.asm head comment for protocol info, in particular
48 ; the meaning of these bytes.
49                                 ; W =           received byte
50         mov_wf  b               ; W = b =       received byte
51
52         mov_lfsr slavetable, 1
53         mov_ff  cslot, FSR1L    ; FSR1 ->       slave's flags
54
55         tst_f_ifnz cbyte
56         bra     read_got_notfirst
57         ; this is a first (head) byte:
58
59         bt_f_if0 POSTINC1, stf_detect ; FSR1 -> detbasel
60         bra     read_got_first_reversers
61 read_got_first_detectors        ; b =           MdBBdddd
62         and_lw  0xb0            ; W =           M0BB0000
63         mov_wf  cbyte           ; cbyte =       M0BB0000
64         mov_lw  0x4f            ; W =           01001111
65         and_wff b               ; b =           0d00dddd
66         mov_fw  POSTINC1        ; W = detbasel; FSR1 -> lastd0
67         rcall   read_got_detectbyte_prep ; b =  0d00dddd
68                                          ; u =  0C00CCCC
69         bt_f_if1 b, 6           ; b bit         .d......
70         bs_f    b, 4            ; b =           0d0ddddd
71                                 ;                ^ ^ copies of same bit
72                                 ; u = (still)   0C00CCCC
73                                 ; or, using detection segment bit numbers:
74                                 ; b =           z4z43210
75                                 ; u =           z4zz3210
76         goto    addmsgs_dethead
77
78 ;----------
79 read_got_first_reversers
80         bt_f_if1 b, 6
81         bra     read_got_bad_first_reversers
82         and_lw  0x80            ; W =           M0000000
83         mov_wf  cbyte           ; cbyte =       M0000000
84         bc_f    b, 7            ; b =           00dddddd
85         mov_fw  POSTINC1        ; W = detbasel; FSR1 -> lastd0
86         rcall   read_got_detectbyte_prep
87         goto    addmsgs_revhead
88
89 ;-----
90 read_got_bad_first_reversers panic morse_MR
91
92 ;----------
93 read_got_detectors_b1           ; b =           dddddddd
94         bc_f    cbyte, 4        ; cbyte =       M0B00000
95         mov_fw  POSTINC1        ; W = detbasel; FSR1 -> lastd0
96         inc_f   FSR1L           ; FSR1 -> lastd1
97         add_lw  5               ; W = detbasel+8
98         rcall   read_got_detectbyte_prep
99         goto    addmsgs_all
100
101 ;----------
102 read_got_detectors_b2           ; b =           dddddddd
103         bc_f    cbyte,5         ; cbyte =       M0000000
104         mov_fw  POSTDEC1        ; W = detbasel; FSR1 -> flags
105         bs_f    FSR1L, 2        ; FSR1L ->      lastd2
106         add_lw  13              ; W = detbasel+16
107         rcall   read_got_detectbyte_prep
108         goto    addmsgs_all
109
110 ;----------
111 read_got_detectbyte_prep_ifsomething
112 ;
113 ; This is a branch of read_got_detectbyte_prep, called if we're doing
114 ; `return' rather than `pop+return'.  For conditions on return, see
115 ; read_got_detectbyte_prep; these are supposed to be (basically) the
116 ; same as the entry conditions for addmsgs_<kind>.
117 ;
118 ;               on entry
119 ;  W            [C0]*
120 ;  t            adjdetbasel
121 ;  u            undefined
122 ;  b            [d0]*
123 ;  lastd<n>     [o0]*
124 ;  FSR1 ->      lastd<n>
125 ;
126         mov_wf  u               ; u =           [C0]*
127         xor_wfw INDF1           ; lastd<n> =    [d0]*
128         mov_lw  0x07
129         ior_wff FSR1L           ; FSR1L ->      detmsgh
130         return ; to addmsgs_<something>, very shortly
131
132 ;----------------------------------------
133 read_got_notfirst
134         bt_f_if1 cbyte, 4
135         bra     read_got_detectors_b1
136         bt_f_if1 cbyte, 5
137         bra     read_got_detectors_b2
138         ; it must be an extra byte
139
140         bt_f_if0 b, 7           ; any more ?
141         bc_f    cbyte, 7
142         bc_f    b, 7
143         call    process_got_extra
144         bra     i2c_arrange_next_byte
145
146 ;----------
147 read_got_detectbyte_prep
148 ;
149 ; Sees if anything has changed.  If no changes pops one return address
150 ; and branches to i2c_arrange_next_byte; if some changes, returns to
151 ; calling point.
152 ;
153 ; So, caller should be i2cmu_read_got_byte, and next stuff
154 ; should basically be a call to addmsg_<something> (perhaps preceded
155 ; by a bit of fiddling of b).  addmsg_<something> will finish
156 ; by branching to i2c_arrange_next_byte.
157 ;
158 ;               call                    return          pop+return
159 ;  W            adjdetbasel             preserved       undefined
160 ;  b            [d0]*                   preserved       preserved
161 ;  FSR1 ->      lastd<n>                detmsgh         preserved
162 ;  cbyte        set for next read etc.  preserved       preserved
163 ;  u            undefined               [C0]*           preserved
164 ;  lastd<n>     [o0]*                   [d0]*           preserved = [d0]*
165 ;
166 ;  TOS ->       (optionally, fiddle b, and then:) goto addmsgs_<something>
167 ;  NOS          return address for i2cmu_read_got_byte
168 ;
169         mov_wf  t               ; t =           adjdetbasel
170         mov_fw  b               ; W =           [d0]*
171         xor_wfw INDF1           ; W =           [C0]*, Z iff same
172                         ;  where C set iff change to that detection segment
173         bra_nz  read_got_detectbyte_prep_ifsomething
174         ; there's nothing to do
175         pop
176 ;...
177 ;----------------------------------------
178 i2c_arrange_next_byte
179         tst_f_ifnz cbyte
180         goto    i2cm_read_another
181 ;...
182 ;======================================================================
183 ; DECIDING WHICH SLAVE TO ADDRESS
184 ;...
185 i2c_arrange_something
186 ; figure out what to do next - which pic to address, etc.
187         panic   morse_UG
188
189 ;======================================================================
190 ; PROCESSING OF INCOMING BYTES - EXTRA (NON-DETECTION)
191
192 near_gots code
193 ;----------------------------------------
194 process_got_extra
195         mov_fw  b
196 loopback_read_byte
197 ;...
198 ;  W            message
199         xor_lw  0x00 ^ 0x20
200         bra_z   got_pointed
201         xor_lw  0x20 ^ 0xb0
202         bra_z   got_aargh
203         panic   morse_MX
204
205 ;======================================================================
206 ; GENERATION OF DETECTION MESSAGES FOR HOST - MAD BT_F_IF1 TABLES
207
208 addmsg_testbit macro bit
209         bt_f_if1 u, bit
210         rcall   addmsg_one
211         endm
212
213 addmsg_return macro dummy_bit
214         goto    i2c_arrange_next_byte
215         endm
216
217 addmsg_ignore macro dummy_bit
218         nop
219         nop
220         endm
221
222 addmsg_padding macro dummy_bit
223         nop
224         mov_lw  dummy_bit
225         endm
226
227 ;----------------------------------------
228 ;addmsgs_<kind>
229 ;
230 ;                       on entry        after first addmsg_one, or when done
231 ;  W, STATUS, v, FSR0   undefined       trashed
232 ;  t                    adjdetbasel     not modified by addmsgs_<kind> or _one
233 ;  u                    [C0]*           not modified by addmsgs_<kind> or _one
234 ;  b                    [d0]*           not modified by addmsgs_<kind> or _one
235 ;  lastd<n>             [d0]* (new)     not modified by addmsgs_<kind> or _one
236 ;  FSR1 ->              detmsgh         not modified by addmsgs_<kind> or _one
237 ;  outbuf, outmsg_*     not full, updated appropriately
238 ;  all others           any             not interfered with
239 ;  
240 ; (this is all set up by read_prep_detectbyte and
241 ;  read_got_detectbyte_prep_ifsomething)
242 ; when done, branches to i2c_arrange_next_byte, rather than returning
243
244 addmsgs_section code (          7       )*4 + 0x2100
245 ;
246 ;                               A
247 ;                               |- PCL bbb value after macro - number in this
248 ;                               V       column should increment 1 each line
249 ;
250 addmsgs_revhead addmsg_testbit  0
251                 addmsg_testbit  1
252                 addmsg_testbit  2
253                 addmsg_testbit  3
254                 addmsg_testbit  4
255                 addmsg_testbit  5
256                 addmsg_return   6
257
258 addmsgs_all     addmsg_testbit  7
259                 addmsg_testbit  0
260                 addmsg_testbit  1
261                 addmsg_testbit  2
262                 addmsg_testbit  3
263                 addmsg_testbit  4
264                 addmsg_testbit  5
265                 addmsg_testbit  6
266                 addmsg_return   7
267
268 addmsgs_dethead addmsg_testbit  0
269                 addmsg_testbit  1
270                 addmsg_testbit  2
271                 addmsg_testbit  3
272                 addmsg_testbit  6 ; bit 6 was copied to 4 but only in b, not u
273                 addmsg_return   5
274
275 ;----------
276 addmsg_one
277 ;  TOS - 4 ->   bt_f_if1 w, b'bbb'
278 ;  TOSL         ???bbb00
279 ; other conditions on entry and exit as for entry to addmsgs_<kind>, above
280         rr_fw   TOSL            ; W =           0???bbb0
281         rr_w                    ; W =           00???bbb
282         ior_wfw 0xf8            ; W =           11111bbb
283         mov_wf  FSR0L           ; FSR0L =       11111bbb
284         clr_f   FSR0H           ; FSR0 ->       bitnum2bit[bbb]
285         add_wfw t               ; W =           adjdetbasel + 11111bbb
286                                 ;  ie =         0 SSSSSSS (det msg low byte)
287         mov_wf  v               ; v =           0 SSSSSSS (det msg low byte)
288
289         mov_fw  b               ; W =           [d0]*
290         and_wfw INDF0           ; train: W = 0x00, Z=1; none: W = 0*d0*, Z=0
291         bt_f_if0 STATUS, Z
292         mov_lw  0x08            ; train: W = 0 000 0 000; none: W = 0 000 1 000
293         xor_wfw INDF1           ; W =           1 001 Y SSS (det msg high byte)
294         call    serial_addbyte
295
296         mov_fw  v               ; W =           0 SSSSSSS (det msg low byte)
297         goto    serial_addbyte_another
298
299 ;======================================================================
300  include final.inc