1 ;======================================================================
2 ; MASTER - SCANNING ETC.
6 ;----------------------------------------------------------------------
9 ; for reading and detection:
10 b res 1 ; byte just read
11 cslot res 1 ; current slave in slave table, points to flags byte
13 ; one of the following:
14 ; 0000 0000 we're expecting the first byte
15 ; M0B1 0000 we're expecting more detection byte 1
16 ; M010 0000 we're expecting more detection byte 2
17 ; 1000 0000 we're expecting an extra byte
18 ; ???? ???1 reading halted due to lack of buffer space:
19 cbyte_halted equ 0 ; also set briefly while we decide what to do next
21 wslave res 1 ; slave we need to write to
22 outmsg_targetlen res 1 ;
24 ;======================================================================
25 ; HANDLING OF I2C EVENTS
27 near_getwritebyteyes code
28 ;----------------------------------------
29 i2c_getwritebyte_yes @
30 pop ; we don't care where we were in i2cmu_write_next_byte
31 bc_f STATUS, Z ; yes, we want to write this byte
32 return ; from i2cmu_write_next_byte
35 ;----------------------------------------
40 ; add calls to getwritebyte_<foo> here:
45 call polarity_getwritebyte
50 call points_getwritebyte
55 ; end of list of calls to getwritebyte_<foo>
56 ; so, no-one wants this slave:
60 ;----------------------------------------
62 ; handles i2c interrupt using i2cm_interrupt[_definite],
63 ; according to the rules for <something>_intrl.
67 call i2cm_interrupt_definite
70 ;======================================================================
71 ; PROCESSING OF INCOMING BYTES - CORE AND DETECTION
73 ;----------------------------------------
76 ; State Reading Reading-Wait
79 ; See detect.asm head comment for protocol info, in particular
80 ; the meaning of these bytes.
82 mov_wf b ; W = b = received byte
91 mov_lfsr slavetable, 1
92 mov_ff cslot, FSR1L ; FSR1 -> slave's flags
96 ; this is a first (head) byte:
98 bt_f_if0 POSTINC1, stf_detect ; FSR1 -> detbasel
99 bra read_got_first_reversers
100 read_got_first_detectors ; b = MdBBdddd
101 and_lw 0xb0 ; W = M0BB0000
102 mov_wf cbyte ; cbyte = M0BB0000
103 mov_lw 0x4f ; W = 01001111
104 and_wff b ; b = 0d00dddd
105 mov_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0
106 rcall read_got_detectbyte_prep ; b = 0d00dddd
109 bt_f_if1 b, 6 ; b bit .d......
110 bs_f b, 4 ; b = 0d0ddddd
111 ; ^ ^ copies of same bit
112 ; u = (still) 0C00CCCC
113 ; or, using detection segment bit numbers:
119 read_got_first_reversers
121 bra read_got_bad_first_reversers
122 and_lw 0x80 ; W = M0000000
123 mov_wf cbyte ; cbyte = M0000000
124 bc_f b, 7 ; b = 00dddddd
125 mov_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0
126 rcall read_got_detectbyte_prep
130 read_got_bad_first_reversers panic morse_MR
133 read_got_detectors_b1 ; b = dddddddd
134 ; ; W = detbasel; FSR1 -> detbasel
135 add_lw 5 ; W = adjdetbasel
136 bs_f FSR1L, 2 ; FSR1L -> lastd1
137 bc_f cbyte, 4 ; cbyte = M0B00000
138 mov_ff xdebug+4, xdebug+5
139 mov_ff xdebug+3, xdebug+4
141 rcall read_got_detectbyte_prep
145 read_got_detectors_b2 ; b = dddddddd
146 ; ; W = detbasel; FSR1 -> detbasel
147 add_lw 13 ; W = adjdetbasel
148 inc_f FSR1L ; FSR1 -> lastd0
149 inc_f FSR1L ; FSR1 -> lastd2
150 bc_f cbyte,5 ; cbyte = M0000000
151 rcall read_got_detectbyte_prep
155 read_got_detectbyte_prep_ifsomething
157 ; This is a branch of read_got_detectbyte_prep, called if we're doing
158 ; `return' rather than `pop+return'. For conditions on return, see
159 ; read_got_detectbyte_prep; these are supposed to be (basically) the
160 ; same as the entry conditions for addmsgs_<kind>.
176 xor_wff INDF1 ; lastd<n> = [d0]*
177 ; to force test of repeated detection notification,
178 ; comment out previous line
180 ior_wff FSR1L ; FSR1L -> detmsgh
181 return ; to addmsgs_<something>, very shortly
183 ;----------------------------------------
186 mov_fw PREINC1 ; W = detbasel; FSR1 -> detbasel
188 bra read_got_detectors_b1
190 bra read_got_detectors_b2
191 ; it must be an extra byte
193 bt_f_if0 b, 7 ; any more ?
196 call process_got_extra
197 bra i2c_arrange_next_byte
200 read_got_detectbyte_prep
202 ; Sees if anything has changed. If no changes pops one return address
203 ; and branches to i2c_arrange_next_byte; if some changes, returns to
206 ; So, caller should be i2cmu_read_got_byte, and next stuff
207 ; should basically be a call to addmsg_<something> (perhaps preceded
208 ; by a bit of fiddling of b). addmsg_<something> will finish
209 ; by branching to i2c_arrange_next_byte.
211 ; call return pop+return
212 ; W adjdetbasel preserved undefined
213 ; b [d0]* preserved preserved
214 ; FSR1 -> lastd<n> detmsgh preserved
215 ; cbyte set for next read etc. preserved preserved
216 ; u undefined [C0]* preserved
217 ; lastd<n> [o0]* [d0]* preserved = [d0]*
219 ; TOS -> (optionally, fiddle b, and then:) goto addmsgs_<something>
220 ; NOS return address for i2cmu_read_got_byte
222 mov_wf t ; t = adjdetbasel
228 xor_wfw INDF1 ; W = [C0]*, Z iff same
229 ; where C set iff change to that detection segment
230 bra_nz read_got_detectbyte_prep_ifsomething
231 ; there's nothing to do
234 ;----------------------------------------
235 i2c_arrange_next_byte
237 goto i2cm_read_another
239 ;======================================================================
240 ; DECIDING WHICH SLAVE TO ADDRESS
242 i2c_arrange_something
244 ; figure out what to do next - which pic to address, etc.
245 bs_f cbyte, cbyte_halted
247 tst_f_ifnz wslave ; anyone asked to write ?
250 ; Anyone else to write to ?
251 ; add calls to needwrite_<foo> here:
252 call polarity_needwrite
253 call points_needwrite
254 ; end of list of calls to needwrite_<foo>
256 ; no, if we're here, no-one wants to write:
259 ; no writing needed, we consider reading:
260 bt_f_if1 flags, flags_polarising
261 return ; do not scan while booster PWM is off while polarising
262 ; to avoid all trains disappearing and reappearing
266 and_lw outbuf_size - 1
267 cmp_fw_ifle outmsg_targetlen
268 return ; target len < actual len, do not add anything
269 ; ok, there's space, go ahead:
270 bc_f cbyte, cbyte_halted
273 add_wff cslot ; cslot -> next ste_flags
274 mov_lfsr slavetable, 1 ; FSR1H -> slavetable
275 mov_ff cslot, FSR1L ; FSR1 -> new ste_flags
277 bt_f_if1 POSTDEC1, stf_sentinel ; FSR1 -> ste_slave
278 bra nextslave_looparound
279 ; Ok, we have a slave:
282 mov_fw INDF1 ; W = new slave number
292 ; now we do our own detection
293 mov_lw (slavetable + ste_flags) & 0xff ; select our own slot
296 call read_detection_head_master
297 goto i2cmu_read_got_byte
302 ;----------------------------------------
304 ; Informs mascan that we need to write to some slave.
305 ; Some time after this, mascan will call getwritebyte_<everything>
306 ; and this must yield at least one byte to write.
307 ; W slave that we must write to
309 bt_f_if0 cbyte, cbyte_halted
310 return ; we're currently doing something
314 ; wslave slave to write to
315 bc_f cbyte, cbyte_halted
319 goto i2cm_write_start
321 ;----------------------------------------
322 i2c_consider_restartread @
323 bt_f_if0 cbyte, cbyte_halted
325 bra nextslave_nowrite
327 ;======================================================================
331 mov_lw (slavetable + ste_flags) & 0xff
332 ; pretend we've just done us, to start with 1st actual slave
335 bs_f cbyte, cbyte_halted ; serial output of `hello' will start us up
339 mov_lfsr slavetable, 0 ; FSR0 -> slavetable
340 load_tblptr pic2detinfo ; TBLPTR* -> pic2detinfo
341 clr_f t ; t = loop counter
343 tblrd_postinc_fixup ; TABLAT = EOOOOSSS
344 mov_fw TABLAT ; W = EOOOOSSS, N = E
346 tblrd_postinc_fixup ; TABLAT = DSSSSSSS, N (still) = E
347 bra_nn mascan_init_ifabsent ; E.......
349 mov_ff t, POSTINC0 ; ste_slave = slave
350 mov_wf u ; u = 1OOOOSSS
352 bra_nz mascan_bad_detinfo0
355 mov_fw TABLAT ; W = DSSSSSSS
356 and_lw 0x80 ; W = D0000000
357 mov_wf POSTINC0 ; ste_flags = D0000000
359 mov_fw TABLAT ; W = DSSSSSSS
360 bc_w 7 ; W = 0SSSSSSS = first
361 add_lw -0xf8 ; W = first - 0xf8 = detbasel
362 mov_wf POSTINC0 ; detbasel
364 clr_f POSTINC0 ; lastd0
365 clr_f POSTINC0 ; lastd2
366 set_f POSTINC0 ; unused
367 clr_f POSTINC0 ; lastd1
369 mov_fw u ; W = 10000SSS
370 xor_lw b'10011000' ^ 0x80 ; W = detmsgh
371 mov_wf POSTINC0 ; detmsgh
375 bt_f_if0 t, maxpics_ln2
377 ; we've read the whole flash table
379 if slavetable == 0x400
381 bra mascan_bad_toomany
384 clr_f POSTINC0 ; ste_slave
385 mov_lw (1<<stf_detect)|(1<<stf_sentinel)
386 mov_wf POSTINC0 ; ste_flags
387 ; rest of final entry, and rest of table, is undefined
389 ; at 9600, it's about 1ms per char.
390 ; we allow 1ms to scan 2 pics via i2c.
391 ; so our target len is (no of pics)/2
392 ; plus 2 bytes of slop
395 mov_wf outmsg_targetlen
399 mascan_bad_detinfo0 panic morse_DF
400 mascan_bad_toomany panic morse_DG
402 ;======================================================================
403 ; PROCESSING OF INCOMING BYTES - EXTRA (NON-DETECTION)
406 ;----------------------------------------
418 ;======================================================================
419 ; GENERATION OF DETECTION MESSAGES FOR HOST - MAD BT_F_IF1 TABLES
421 addmsg_testbit macro addmsg_macro_bit
422 bt_f_if1 u, addmsg_macro_bit
426 addmsg_return macro dummy_addmsg_macro_bit
427 goto i2c_arrange_next_byte
430 addmsg_ignore macro dummy_addmsg_macro_bit
435 addmsg_padding macro dummy_addmsg_macro_bit
437 mov_lw dummy_addmsg_macro_bit
440 ;----------------------------------------
443 ; on entry after first addmsg_one, or when done
444 ; W, STATUS, v, FSR0 undefined trashed
445 ; t adjdetbasel not modified by addmsgs_<kind> or _one
446 ; u [C0]* not modified by addmsgs_<kind> or _one
447 ; b [d0]* not modified by addmsgs_<kind> or _one
448 ; lastd<n> [d0]* (new) not modified by addmsgs_<kind> or _one
449 ; FSR1 -> detmsgh not modified by addmsgs_<kind> or _one
450 ; outbuf, outmsg_* not full, updated appropriately
451 ; all others any not interfered with
453 ; (this is all set up by read_prep_detectbyte and
454 ; read_got_detectbyte_prep_ifsomething)
455 ; when done, branches to i2c_arrange_next_byte, rather than returning
457 addmsgs_section code ( 7 )*4 + 0x2100
460 ; |- PCL bbb value after macro - number in this
461 ; V column should increment 1 each line
463 addmsgs_revhead addmsg_testbit 0
471 addmsgs_all addmsg_testbit 7
481 addmsgs_dethead addmsg_testbit 0
485 addmsg_testbit 6 ; bit 6 was copied to 4 but only in b, not u
490 ; TOS - 4 -> bt_f_if1 u, b'bbb'
492 ; other conditions on entry and exit as for entry to addmsgs_<kind>, above
498 rr_fw TOSL ; W = 0???bbb0
500 ior_lw 0xf8 ; W = 11111bbb
501 mov_wf FSR0L ; FSR0L = 11111bbb
502 clr_f FSR0H ; FSR0 -> bitnum2bit[bbb]
503 add_wfw t ; W = adjdetbasel + 11111bbb
504 ; ie = 0 SSSSSSS (det msg low byte)
505 mov_wf v ; v = 0 SSSSSSS (det msg low byte)
509 and_wfw INDF0 ; train: W = 0x00, Z=1; none: W = 0*d0*, Z=0
511 mov_lw 0x08 ; train: W = 0 000 0 000; none: W = 0 000 1 000
512 xor_wfw INDF1 ; W = 1 001 Y SSS (det msg high byte)
516 ;bt_f_if1 xdebug+6, 0
519 mov_fw v ; W = 0 SSSSSSS (det msg low byte)
521 goto serial_addbyte_another
523 addmsg_bad panic morse_DJ
527 ;======================================================================