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