;====================================================================== ; MASTER - SCANNING ETC. include common.inc ;---------------------------------------------------------------------- udata_acs b res 1 ; byte just read cslot res 1 ; current slave in slave table, points to flags byte cbyte res 1 ; one of the following: ; 0000 0000 we're expecting the first byte ; M0B1 0000 we're expecting more detection byte 1 ; M010 0000 we're expecting more detection byte 2 ; 1000 0000 we're expecting an extra byte ;---------------------------------------------------------------------- slavetable_section udata 0x280 ste_szln2 equ 3 ; each entry is a number of bytes, at these offsets: ste_slave equ 0 ; slave number ste_flags equ 1 ; flags (stf_...) cslot normally points here ste_detbasel equ 2 ; added to 11111bbb to make 0SSSSSSS; ie first-0xf8 ste_lastd0 equ 3 ; } [o0]* ie every bit is either 0 (for an ste_lastd1 equ 4 ; } irrelevant bit) or o, meaning the ste_lastd2 equ 5 ; } previously seen detection data bit ste_detmsgh equ 7 ; 1 001 1 000 being 1 001 Y SSS ste_size equ (1<_intrl. bt_f_if0 PIR1, SSPIF return call i2cm_interrupt_definite intrl_handled_nostack ;---------------------------------------- i2cmu_done panic morse_MD ;---------------------------------------- i2cmu_write_next_byte panic morse_UI ;====================================================================== ; PROCESSING OF INCOMING BYTES ;---------------------------------------- i2cmu_read_got_byte ; Beforehand At call ; State Reading Reading-Wait ; W data from slave ; ; See detect.asm head comment for protocol info, in particular ; the meaning of these bytes. ; W = received byte mov_wf b ; W = b = received byte mov_lfsr slavetable, 1 mov_ff cslot, FSR1L ; FSR1 -> slave's flags tst_f_ifnz cbyte bra read_got_notfirst ; this is a first (head) byte: bt_f_if0 POSTINC1, stf_detect ; FSR1 -> detbasel bra read_got_first_reversers read_got_first_detectors ; b = MdBBdddd and_lw 0xb0 ; W = M0BB0000 mov_wf cbyte ; cbyte = M0BB0000 mov_lw 0x4f ; W = 01001111 and_wff b ; b = 0d00dddd mov_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0 rcall read_prep_detectbyte ; b = 0d00dddd ; u = 0C00CCCC bt_f_if1 b, 6 ; b bit .d...... bs_f b, 4 ; b = 0d0ddddd ; ^ ^ copies of same bit ; u = (still) 0C00CCCC ; or, using detection segment bit numbers: ; b = z4z43210 ; u = z4zz3210 goto addmsgs_dethead ;---------- read_got_first_reversers bt_f_if1 b, 6 bra read_got_bad_first_reversers and_lw 0x80 ; W = M0000000 mov_wf cbyte ; cbyte = M0000000 bc_f b, 7 ; b = 00dddddd mov_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0 rcall read_prep_detectbyte goto addmsgs_revhead ;----- read_got_bad_first_reversers panic morse_MR ;---------- read_got_detectors_b1 ; b = dddddddd bc_f cbyte, 4 ; cbyte = M0B00000 mov_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0 inc_f FSR1L ; FSR1 -> lastd1 add_lw 5 ; W = detbasel+8 rcall read_prep_detectbyte goto addmsgs_all ;---------- read_got_detectors_b2 ; b = dddddddd bc_f cbyte,5 ; cbyte = M0000000 mov_fw POSTDEC1 ; W = detbasel; FSR1 -> flags bs_f FSR1L, 2 ; FSR1L -> lastd2 add_lw 13 ; W = detbasel+16 rcall read_prep_detectbyte goto addmsgs_all ;---------- read_got_detectbyte_prep_ifsomething ; ; This is a branch of read_got_detectbyte_prep, called if we're doing ; `return' rather than `pop+return'. For conditions on return, see ; read_got_detectbyte_prep; these are supposed to be (basically) the ; same as the entry conditions for addmsgs_. ; ; on entry ; W [C0]* ; t adjdetbasel ; u undefined ; b [d0]* ; lastd [o0]* ; FSR1 -> lastd ; mov_wf u ; u = [C0]* xor_wfw INDF1 ; lastd = [d0]* mov_lw 0x07 ior_wff FSR1L ; FSR1L -> detmsgh return ; to addmsgs_, very shortly ;---------------------------------------- read_got_notfirst bt_f_if1 cbyte, 4 bra read_got_detectors_b1 bt_f_if1 cbyte, 5 bra read_got_detectors_b2 ; it must be an extra byte bt_f_if0 b, 7 ; any more ? bc_f cbyte, 7 bc_f b, 7 rcall process_got_extra bra i2c_arrange_next_byte ;---------------------------------------- process_got_extra mov_fw b loopback_read_byte ;... ; W message xor_lw 0x00 ^ 0x20 bra_z got_pointed xor_lw 0x20 ^ 0xb0 bra_z got_aargh panic morse_MX ;---------- read_got_detectbyte_prep ; ; Sees if anything has changed. If no changes pops one return address ; and branches to i2c_arrange_next_byte; if some changes, returns to ; calling point. ; ; So, caller should be i2cmu_read_got_byte, and next stuff ; should basically be a call to addmsg_ (perhaps preceded ; by a bit of fiddling of b). addmsg_ will finish ; by branching to i2c_arrange_next_byte. ; ; call return pop+return ; W adjdetbasel preserved undefined ; b [d0]* preserved preserved ; FSR1 -> lastd detmsgh preserved ; cbyte set for next read etc. preserved preserved ; u undefined [C0]* preserved ; lastd [o0]* [d0]* preserved = [d0]* ; ; TOS -> (optionally, fiddle b, and then:) goto addmsgs_ ; NOS return address for i2cmu_read_got_byte ; mov_wf t ; t = adjdetbasel mov_fw b ; W = [d0]* xor_wfw INDF1 ; W = [C0]*, Z iff same ; where C set iff change to that detection segment bra_nz read_got_detectbyte_prep_ifsomething ; there's nothing to do pop ;... ;---------------------------------------- i2c_arrange_next_byte tst_f_ifnz cbyte goto i2cm_read_another ;... ;====================================================================== ; DECIDING WHICH SLAVE TO ADDRESS ;... i2c_arrange_something ; figure out what to do next - which pic to address, etc. panic morse_UG ;====================================================================== ; GENERATION OF DETECTION MESSAGES FOR HOST - MAD BT_F_IF1 TABLES addmsg_testbit macro bit bt_f_if1 u, bit fixme need to test something other than w ! rcall addmsg_one endm addmsg_return macro dummy_bit goto i2c_arrange_next_byte endm addmsg_ignore macro dummy_bit nop nop endm addmsg_padding macro dummy_bit nop mov_lw dummy_bit endm ;---------------------------------------- ;addmsgs_ ; ; on entry after first addmsg_one, or when done ; W, STATUS, v, FSR0 undefined trashed ; t adjdetbasel not modified by addmsgs_ or _one ; u [C0]* not modified by addmsgs_ or _one ; b [d0]* not modified by addmsgs_ or _one ; lastd [d0]* (new) not modified by addmsgs_ or _one ; FSR1 -> detmsgh not modified by addmsgs_ or _one ; outbuf, outmsg_* not full, updated appropriately ; all others any not interfered with ; ; (this is all set up by read_prep_detectbyte and ; read_got_detectbyte_prep_ifsomething) ; when done, branches to i2c_arrange_next_byte, rather than returning addmsgs_section code ( 7 )*4 + 0x2100 ; ; A ; |- PCL bbb value after macro - number in this ; V column should increment 1 each line ; addmsgs_revhead addmsg_testbit 0 addmsg_testbit 1 addmsg_testbit 2 addmsg_testbit 3 addmsg_testbit 4 addmsg_testbit 5 addmsg_return 6 addmsgs_all addmsg_testbit 7 addmsg_testbit 0 addmsg_testbit 1 addmsg_testbit 2 addmsg_testbit 3 addmsg_testbit 4 addmsg_testbit 5 addmsg_testbit 6 addmsg_return 7 addmsgs_dethead addmsg_testbit 0 addmsg_testbit 1 addmsg_testbit 2 addmsg_testbit 3 addmsg_testbit 6 ; bit 6 was copied to 4 but only in b, not u addmsg_return 5 ;---------- addmsg_one ; TOS - 4 -> bt_f_if1 w, b'bbb' ; TOSL ???bbb00 ; other conditions on entry and exit as for entry to addmsgs_, above rr_fw TOSL ; W = 0???bbb0 rr_w ; W = 00???bbb ior_fw 0xf8 ; W = 11111bbb mov_wf FSR0L ; FSR0L = 11111bbb clr_f FSR0H ; FSR0 -> bitnum2bit[bbb] add_wfw t ; W = adjdetbasel + 11111bbb ; ie = 0 SSSSSSS (det msg low byte) mov_wf v ; v = 0 SSSSSSS (det msg low byte) mov_fw b ; W = [d0]* and_wfw INDF0 ; train: W = 0x00, Z=1; none: W = 0*d0*, Z=0 bt_f_if0 STATUS, Z mov_lw 0x08 ; train: W = 0 000 0 000; none: W = 0 000 1 000 xor_wfw INDF1 ; W = 1 001 Y SSS (det msg high byte) call serial_addbyte mov_fw v ; W = 0 SSSSSSS (det msg low byte) goto serial_addbyte_another ;====================================================================== include final.inc