From: ian Date: Sun, 4 Dec 2005 14:26:07 +0000 (+0000) Subject: all-new bit-twiddling and object numbering, wip X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=b3fcdb9be86d68b1861ed80a840598c010abe06b;p=trains.git all-new bit-twiddling and object numbering, wip --- diff --git a/cebpic/README.protocol b/cebpic/README.protocol index 1b91e3c..eb43a4b 100644 --- a/cebpic/README.protocol +++ b/cebpic/README.protocol @@ -145,22 +145,25 @@ The command is of variable length (but at least two bytes): Each byte after the first contains 7 more R bits. The first R bit (most significant R bit in the first byte) corresponds to track -detection segment 1; The next bit (2nd most significant bit in the -first byte) corresponds to track detection segment 2; and so on. +reversal segment 1; The next bit (2nd most significant bit in the +first byte) corresponds to track reversal segment 2; and so on. -Bits which do not correspond to defined track detection segments will -be sent as 0 by the host but may be ignored by the PICs. The host -must send exactly as many bytes as are necessary to include all of the -defined segments. +Bits which do not correspond to defined reversal segments will be +ignored by the PICs. The host must send exactly as many bytes as are +necessary to include all of the reversal segments for each reversers +board (for every potential reversal segment, regardless of whether +that segment is a defined segment corresponding to some actual track). -For example, if there are 14 detection segments (numbered 1 to 14) +For example, if there are 14 reversible segments (numbered 1 to 14) then the following message 1 0010 000 1 000 1000 0 111 1010 Actual message (E RRR) (E RRR RRRR) (E RRR R---) } helpful annotations 1 111 1111 } and commentary 123 456 7890 123 4567 } specifies to reverse segments 7 and 11 to 14. The trailing bits are -for segments 15 to 17 and are ignored. +for segments 15 to 17 and are ignored. (Note that the assignment of +physical segments to segment numbers is complex due to bit-twiddling. +see detpic/reverse.asm and layout/data2safety.) The PIC will reply to POLARITY with POLARISED when the polarity change is complete. The host must not send another POLARITY until then. diff --git a/detpic/detect.asm b/detpic/detect.asm index 1275fd7..0326ff1 100644 --- a/detpic/detect.asm +++ b/detpic/detect.asm @@ -1,5 +1,5 @@ ;====================================================================== -; DETECTION +; DETECTION AND SLAVE I2C ; FSR1 is used as pointer to where to add bytes of message; it ; points to previous byte whose top bit must be set before @@ -27,11 +27,28 @@ ; to be the same as last time (initially: 0) ; zz is a zero bit ; MM indicates that there are extra message byte(s) +; two digits indicates that the bit is the corresponding +; detection information. The bit is clear iff current +; was detected since the last poll by the master. +; The bit value is not defined for unused sense +; segments. ; ; Following that are the zero, one or two more bytes of -; detection data, -; X and Y indicate that further detection bytes exist -; M indicates that more +; detection data: +; 19 09 12 15 18 04 20 17 iff reversers and B1 was set +; 06 01 07 02 11 14 03 00 iff reversers and B2 was set +; +; Finally, zero or more bytes of extra messages: +; MM XX XX XX XX XX XX XX +; where +; MM indicates that further extra message bytes follow; +; it is clear iff this is the last extra message byte. +; XX are the lower 7 bits of a POLARISED or POINTED +; message (see README.protocol). + +; Master may also write to slave. Every written byte is independent: +; +; 11RRRRRR Set reverse to RRRRRR, see reverse.asm ;====================================================================== ; variables and memory organisation diff --git a/detpic/misc.asm b/detpic/misc.asm index 132c569..d42c306 100644 --- a/detpic/misc.asm +++ b/detpic/misc.asm @@ -36,4 +36,14 @@ init_read_idlocs return +init_bitnum2bit +; populate bitnum2bit + mov_lw 0x80 + mov_lfsr bitnum2bit,0 +init_bitnum2bit_loop + rl_w + mov_wf POSTINC0 + bra_nn init_bitnum2bit_loop + return + include final.inc diff --git a/detpic/morse.messages b/detpic/morse.messages index 9219297..b6848c9 100644 --- a/detpic/morse.messages +++ b/detpic/morse.messages @@ -48,3 +48,7 @@ SD i2clib:st ; impr. i2cm_read_done/i2cs_read_data DW ; slave write (nyi) DQ FSR2L,outmsg_end ; previous slave read incomplete DR FSR2L,outmsg_end ; slave read overrun + +# Messages for specific peripherals +PS FSR0L ; POLARITY message too short +PL FSR0L ; POLARITY message too long diff --git a/detpic/reverse.asm b/detpic/reverse.asm new file mode 100644 index 0000000..0a86fc1 --- /dev/null +++ b/detpic/reverse.asm @@ -0,0 +1,108 @@ +;====================================================================== + + +board0 res 1 +gather res 1 + +polarities_waiting res 1 + ; no of 11... entries in reversers_commanded_buffer + +reversers_commanded_buffer res 32 + ; Each byte is: + ; 11RRRRRRR reverse command for slave pic + ; 000000001 this pic is not a reversers pic + ; 000000000 have sent any relevant POLARITY + ; 000000002 sentinel + +;---------- +polarity_decode_message +; message format +; SS zz zz SS ZZ 2f 2e 2d g is board 2 +; MM 2c 0f 0e 0d 0c 0b 0a board 0 +; MM 2b 1f 1e 1d 1c 1b 1a board 1 +; MM 2a 3f 3e 3d 3c 3b 3a g, board 2, complete, also 3 +; MM 9f 4f 4e 4d 4c 4b 4a g is board 9 +; MM 9e 5f 5e 5d 5c 5b 5a +; MM 9d 6f 6e 6d 6c 6b 6a +; MM 9c 7f 7e 7d 7c 7b 7a +; MM 9b 8f 8e 8d 8c 8b 8a +; MM 9a af ae ad ac ab aa +; etc. +; where +; SS bit set +; zz bit zero +; other things are where +; is a for LSb in message to PIC, b for next bit, +; and so on until f for bit 5. (See polarity_do_here, below.) +; + mov_lfsr message_buffer_start,0 + mov_lfsr reversers_commanded_buffer,1 + mov_fw POSTINC0 ; W = 10010RRR + mov_wf gather ; gather = 10010ggg + xor_lw 0b10001000 ; gather = 00011ggg +loop ; exit from this loop is done by board popping and returning + rrc_fw INDF0 ; W = ?Mhhhhhh C = g + rlc_f gather ; gather = 0*11g+ C = ? + bra_nn if_not_gathered + ; ; gather = 11gggggg + mov_fw gather + rcall board + mov_lw 0b00000011 ; W = 00000011 + mov_wf gather ; gather = 00000011 +if_not_gathered ; *INDF0 = Mhhhhhhg + rr_fw INDF0 ; W = gMhhhhhh + or_lw 0b11000000 ; W = 11hhhhhh + rcall board + bt_f_if1 POSTINC0,7 ; *POSTINC0 : M....... + bra loop + ; otherwise: + panic morse_PS + +;---------- +board + mov_wf INDF1 ; *(this pic) = 11RRRRRR + ; FSR1 -> pic we've just filled +;... +board_next_loop + dec_fw PREINC1 ; FSR1 -> pic after one we're testing + ; W = 1??????? existing reverse command + ; 00000000 not a reversers pic + ; ffffffff no existing command + ; 00000001 sentinel + bra_z board_next_loop ; not a reversers pic + bra_nn board_next_none ; sentinel + + bt_f_if0 INDF1,7 ; 1....... existing command + ; 0....... no existing command + inc_f polarities_waiting + return + +;---------- +board_next_none + bt_f_if1 INDF0,7 ; *INDFO : M....... + bra board_next_none_more_message +;... +; now we're exiting from the loop in when_reverse_message_found + pop + return + + +;---------- +polarity_do_here +; W here polarity SS SS v3 v0 v2 v1 v5 v4 + mov_wf input ; input = SS SS v3 v0 v2 v1 v5 v4 + + mov_wf LATE ; W = kk kk kk kk kk kk o5 o4 + xor_wfw input ; W = ?? ?? ?? ?? ?? ?? d5 d4 + and_wfw maske ; W = zz zz zz zz zz zz d5 d4 + xor_wff LATE ; LATA = kk kk kk kk kk kk v5 v4 + + bc_f input,2 ; input = SS SS v3 v0 v2 v1 zz v4 + bt_f_if1 input,4 ; input : .. .. .. v0 .. .. .. .. + bs_f input,2 ; input = SS SS v3 v0 v2 v1 v0 v4 + + mov_wf LATA ; W = kk kk r3 kk r2 r1 r0 kk + xor_wfw input ; W = ?? ?? r3 ?? r2 r1 r0 ?? + and_wfw maska ; W = zz zz r3 zz r2 r1 r0 zz + xor_wff LATA ; LATE = kk kk r3 kk r2 r1 r0 kk + return diff --git a/detpic/variables.asm b/detpic/variables.asm index 9f76900..1fbbd45 100644 --- a/detpic/variables.asm +++ b/detpic/variables.asm @@ -13,6 +13,9 @@ outbuf_szln2 equ 7 outbuf_size equ (1<= $nreverses; + } } } @@ -205,20 +211,78 @@ sub pa_boob ($) { return [ $1,$2 ]; } +# so_boob_KIND($boardnum,$boardtype,$objnum) -> global object number + +sub so_boob_pt($$$) { + my ($boardnum,$boardtype,$obj)=@_; + die if $boardnum>31 || $obj>31; + return ($boardnum << 5) | $obj; +} + +sub so_boob_reverse($$$) { + my ($boardnum,$boardtype,$obj)=@_; + + # Converts board and object number (in canonical pic number plus + # and reverse0...reverse5 as seen on pinout diagrams), to + # object number for POLARITY command numbered as shown in + # README.protocol. + # + # There are three basic stages: + # + # * We invert the on-board mapping; ie, we untangle the + # tangling between the message from master to slave pic + # and the actual pins (see reverse.asm, polarity_do_here) + # + # * We figure out which bit of which message byte the + # object corresponds to. (see reverse.asm, polarity_decode_message) + # + # * We compute the README.protocol bit and byte number. + + my ($cycle); + mistake("reversable segment on non-reversers board $board") + unless $boardtype eq 'reversers'; + mistake("reversable segment out of range") + unless unless $obj>=0 && $obj<6; + $obj = sprintf '%d', $obj; + $obj =~ y/302154/543210/; # mapping due to polarity_do_here + $cycle= int(($boardnum+3) / 7); + $boardincycle= ($boardnum+3) - $cycle*7; + $cyclebasebyte= $cycle*6 - 2; + if ($boardnum==2 && $obj > 2) { + $byte= 0; $bit= $obj-3; + return 3 - $bit; # only these three in byte 0, a special case + } elsif ($boardincycle<5) { + $byte= $cyclebasebyte + $boardincycle; $bit= $obj; + } elsif ($boardincycle==6) { + $byte= $cyclebasebyte + 5; $bit= $obj; + } elsif ($boardincycle==5) { + $byte= $cyclebasebyte + 5 - $bit; $bit= 6; + } else { + die; + } + return $byte*7 + 3 - $bit; +} + +sub so_boob_sense($$$) { + my ($boardnum,$boardtype,$obj)=@_; + + die 'unimplemented'; +} + sub so_boob ($$) { - my ($k,$bo) = @_; + my ($kind,$bo) = @_; if (defined $bo) { my ($board,$obj)= @$bo; my ($objnum,$type,$pi); mistake("unknown board number $board") unless defined $boardtype[$board]; - $objnum= $boardobjbase[$board]{$k} + $obj; $type= $boardtype[$board]; - $pi= $pin_info{$type}{$k}; - mistake("object reference $k $board.$obj out of range for". + $objnum= &{"so_boob_$kind"}($board,$type,$obj); + $pi= $pin_info{$type}{$kind}; + mistake("object reference $kind $board.$obj out of range for". " board type $type") unless defined $pi->[$obj]; - $pin_used{$k}[$objnum]= [ $board, $pi->[$obj], $obj ]; + $pin_used{$kind}[$objnum]= [ $board, $pi->[$obj], $obj ]; return sprintf("%4d /* %d.%-2d*/", $objnum, $board, $obj); } else { return " 0 /*none*/ "; @@ -226,8 +290,8 @@ sub so_boob ($$) { } sub so_oboob ($$) { - my ($k,$obj) = @_; - return so_boob($k, defined $obj ? $obj->{BoOb} : undef); + my ($kind,$obj) = @_; + return so_boob($kind, defined $obj ? $obj->{BoOb} : undef); } sub mainread () { @@ -365,53 +429,54 @@ sub writeasm () { o(" include pindata.inc\n". " radix hex\n". "X equ 0xff\n"); - $each= 10; - for $k (@objkinds) { - for $w (qw(pic port bit)) { - @d=(); - o("\n"); - o("${k}_${w}_data_section org ${k}_${w}_data\n"); - for ($i=0; $i<@{ $pin_used{$k} }; $i++) { - $or= $pin_used{$k}[$i]; - if (defined $or) { - $or->[1] =~ m/^(\d+)\,(\w+)$/; - ($portnum,$bit)= ($1,$2); - $portnum= sprintf "%02x", $portnum + 0x89; # 89=LATA - $bit= sprintf "%02x", hex $bit; - } else { - $portnum=$bit='00'; - } - if ($w eq 'pic') { - if (defined $or) { - push @d, $or->[0]; - } else { - push @d, 'X', - } - } elsif ($w eq 'port') { - push @d, $portnum; - } elsif ($w eq 'bit') { - push @d, $bit; - } else { - die; - } - } - push @d, 'X' if @d^1; - @d= map { s/^[a-f]/0$&/; sprintf "%3s", $_ } @d; - for (;;) { - $d[$each/2] = " $d[$each/2]" if $#d >= $each/2; - last if @d <= $each; - o(" db ". join(',',@d[0..($each-1)]). "\n"); - @d= @d[$each..$#d]; - } - o(" db ".join(',',@d)."\n"); - if ($w eq 'pic') { - o(" if \$ > ${k}_pic_data + ${k}_num_max\n". - " error \"too much ${k}_picdata\"\n". - " endif\n". - " fill 0xffff, ${k}_pic_data + ${k}_num_max - \$\n"); - } - } - } + o(" +# $each= 10; +# for $k (@objkinds) { +# for $w (qw(pic port bit)) { +# @d=(); +# o("\n"); +# o("${k}_${w}_data_section org ${k}_${w}_data\n"); +# for ($i=0; $i<@{ $pin_used{$k} }; $i++) { +# $or= $pin_used{$k}[$i]; +# if (defined $or) { +# $or->[1] =~ m/^(\d+)\,\d+,(\w+)$/; +# ($portnum,$bit)= ($1,$2); +# $portnum= sprintf "%02x", $portnum + 0x89; # 89=LATA +# $bit= sprintf "%02x", hex $bit; +# } else { +# $portnum=$bit='00'; +# } +# if ($w eq 'pic') { +# if (defined $or) { +# push @d, $or->[0]; +# } else { +# push @d, 'X', +# } +# } elsif ($w eq 'port') { +# push @d, $portnum; +# } elsif ($w eq 'bit') { +# push @d, $bit; +# } else { +# die; +# } +# } +# push @d, 'X' if @d^1; +# @d= map { s/^[a-f]/0$&/; sprintf "%3s", $_ } @d; +# for (;;) { +# $d[$each/2] = " $d[$each/2]" if $#d >= $each/2; +# last if @d <= $each; +# o(" db ". join(',',@d[0..($each-1)]). "\n"); +# @d= @d[$each..$#d]; +# } +# o(" db ".join(',',@d)."\n"); +# if ($w eq 'pic') { +# o(" if \$ > ${k}_pic_data + ${k}_num_max\n". +# " error \"too much ${k}_picdata\"\n". +# " endif\n". +# " fill 0xffff, ${k}_pic_data + ${k}_num_max - \$\n"); +# } +# } +# } o("\n end\n"); } mainread(); diff --git a/layout/layout-data.h b/layout/layout-data.h index 38c262d..84391c7 100644 --- a/layout/layout-data.h +++ b/layout/layout-data.h @@ -79,6 +79,8 @@ extern const SegmentInfo info_segments[]; extern const TrainNum info_nsegments; extern const TrainInfo info_trains[]; +extern const BoardObject info_nreverses; /* max. reverse + 1 */ + #define NOTA(x) (~(x##Num)0) #endif /*LAYOUT_DATA_H*/ diff --git a/layout/pin-info-gen b/layout/pin-info-gen index e046dc4..2da9769 100755 --- a/layout/pin-info-gen +++ b/layout/pin-info-gen @@ -16,9 +16,10 @@ for (;;) { $cpin++; } elsif (s/^[ABCDE]\s+//) { $port= ord($&) - ord('A'); - } elsif (s/^([0-9a-f][0-9a-f])\s+//) { + } elsif (s/^([0-7])\s+//) { die unless defined $port; - $pins[$cpin++]= "$port,0x$1"; + $pins[$cpin++]= sprintf "%d,%d,0x%02x", + $port, $1, 1 << $1; } else { die "$_ ?"; } @@ -57,15 +58,15 @@ print "1;\n" __DATA__ # 1..20 - -A 01 02 04 08 10 20 -E 01 02 04 +A 0 1 2 3 4 5 +E 0 1 2 - - - -A 40 -C 01 02 04 08 -D 01 02 -# 21..40 -D 04 08 -C 10 20 40 80 -D 10 20 40 80 +A 6 +C 0 1 2 3 +D 0 1 +# 21..6 +D 2 3 +C 4 5 6 7 +D 4 5 6 7 - - -B 01 02 04 08 10 20 40 80 +B 0 1 2 3 4 5 6 7