chiark / gitweb /
provide info_segmentmap
[trains.git] / layout / data2safety
index ce477e9202868114fb2ca2fbb04402572598a5ad..5c7df3702d3637d3f3f83d2857059d413f2f3acd 100755 (executable)
@@ -30,16 +30,15 @@ our (%nodes);
 
 our ($maxptixln2) = 5;
 
-our ($nextboardnum,@boardtype,%numboards,$nreverses,@sensesin,@sensesbase);
-our (@objkinds,%pin_used);
-# @boardtype[$boardnum]
-# $numboards{$type}
-# $nreverses
+our ($nextboardnum,@boardtype,@sensesin,$maxreverseobjnum);
+our (@reversersboardnum,@sensesbase,@objkinds,%pin_used);
+# $boardtype[$boardnum]
 # $sensesin[$page]
+# $maxreverseobjnum
+# $reversersboardnum[$boardnum]  # undef => none; -1 => not yet determined
 # $sensesbase[$boardnum]= ($page << 7) | $baselsbyte
-# %pin_used{$objkind}[$objnum] = [ $boardnum, $pin_info, $objonboard ]
+# $pin_used{$objkind}[$objnum] = [ $boardnum, $pin_info, $objonboard ]
 $nextboardnum= 0;
-$nreverses= 0;
 $sensesin[0]= 0;
 @objkinds= qw(pt sense reverse);
 
@@ -104,13 +103,15 @@ sub line_segment () {
     m/^\s+(\w+)\s+(\d+\.\d+)$/ or return syntaxerror();
     ($seg,$boob)=($1,$2);
     mistake("duplicate topology for $seg") if exists $segs{$seg};
+    $boob= pa_boob($boob);
     $segs{$seg}= {
-       BoOb => pa_boob($boob),
+       BoOb => $boob,
        Inv => $invertible,
        Posns => 1,
        Feats => { },
        FeatCount => 0
     };
+    &{"line_segment_".($invertible?'invertible':'vanilla')}($boob);
 }
 
 sub begin_endwiring () {
@@ -127,7 +128,6 @@ sub line_boards () {
 
     $nextboardnum++;
     $boardtype[$num]= $type;
-    $numboards{$type}++;
     require "./$type.pin-info";
 
     my ($sense_count, $page);
@@ -146,15 +146,13 @@ sub line_boards () {
     &{"line_boards_$type"}($num);
 }
 
-sub line_boards_reversers {
-    my ($num) = @_;
-    my ($i,$objnum);
-    for ($i=0; $i<6; $i++) {
-       $objnum= boob2objnum($num,$i,'reverse',0);
-       $nreverses= $objnum+1 if $objnum >= $nreverses;
-    }
-}
+sub line_boards_reversers { }
 sub line_boards_detectors { }
+sub line_segment_vanilla ($) { }
+sub line_segment_invertible ($) {
+    my ($boob) = @_;
+    $reversersboardnum[$boob->[0]]= -1;
+}
 
 sub mistake ($) {
     my ($m) = @_;
@@ -247,45 +245,56 @@ sub boob2objnum_pt {
 }
 
 sub boob2objnum_reverse {
-    my ($boardnum,$obj,$boardtype)=@_;
-
+    my ($orgboardnum,$obj,$boardtype)=@_;
     # 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
+    # and reverse0...reverse5 as seen on pinout diagrams), to the
+    # segment 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)
+    #    and the actual pins (see reverse.asm, polarity_local_do)
     #
     #  * We figure out which bit of which message byte the
-    #    object corresponds to.  (see reverse.asm, polarity_decode_message)
+    #    object corresponds to.  (see reverse.asm, command_polarity)
     #
-    #  * We compute the README.protocol bit and byte number.
+    #  * We compute the README.protocol segment number.
     
-    my ($cycle,$boardincycle,$cyclebasebyte,$byte,$bit);
+    my ($cycle,$boardincycle,$cyclebasebyte,$byte,$bit,$boardnum,$rv);
+    $boardnum= $reversersboardnum[$orgboardnum];
+    die "$orgboardnum $boardnum" unless defined $boardnum;
+    die "$orgboardnum $boardnum" unless $boardnum >= 0;
     die unless $boardtype eq 'reversers';
     die $obj if $obj > 5;
+#print STDERR "data2safety $boardnum.$obj ";
     $obj = sprintf '%d', $obj;
     $obj =~ y/302154/543210/; # mapping due to polarity_do_here
+#print STDERR " obj=$obj";
     $cycle= int(($boardnum+3) / 7);
+#print STDERR " cycle=$cycle";
     $boardincycle= ($boardnum+3) - $cycle*7;
+#print STDERR " boardin=$boardincycle";
     $cyclebasebyte= $cycle*6 - 2;
+#print STDERR " baseby=$cyclebasebyte";
     if ($boardnum==2 && $obj > 2) {
        $byte= 0; $bit= $obj-3;
-       return 3 - $bit; # only these three in byte 0, a special case
+       $rv= 3 - $bit; # only these three in byte 0, a special case;
+#print STDERR " special bit=$bit => $rv\n";
+       return $rv;
     } elsif ($boardincycle<5) {
-       $byte= $cyclebasebyte + $boardincycle; $bit= $obj;
+       $byte= $cyclebasebyte + $boardincycle; $bit= $obj + 1;
     } elsif ($boardincycle==6) {
-       $byte= $cyclebasebyte + 5; $bit= $obj;
+       $byte= $cyclebasebyte + 5; $bit= $obj + 1;
     } elsif ($boardincycle==5) {
-       $byte= $cyclebasebyte + 5 - $bit; $bit= 6;
+       $byte= $cyclebasebyte + 5 - $bit; $bit= 0;
     } else {
        die;
     }
-    return $byte*7 + 3 - $bit;
+    $rv= $byte*7 + 3 - $bit;
+#print STDERR " ordinary byte=$byte bit=$bit => $rv\n";
+    return $rv;
 }
 
 sub boob2objnum_sense {
@@ -315,8 +324,8 @@ sub boob_used_bit ($$$) {
     return defined boob_used($boardnum,$obj,$kind) ? 1 : 0;
 }
 
-sub so_boob ($$$) {
-    my ($kind,$mkused,$bo) = @_;
+sub so_boob ($$$;$) {
+    my ($kind,$mkused,$bo, $objnum_rr) = @_;
     my ($type,$pi);
     if (defined $bo) {
        my ($board,$obj)= @$bo;
@@ -329,17 +338,25 @@ sub so_boob ($$$) {
                " board type $type")
            unless defined $pi->[$obj];
        $objnum= boob2objnum($board,$obj,$kind,$mkused);
+#print "so_boob >$objnum_rr|$$objnum_rr< = $objnum\n";
+       $$objnum_rr= $objnum;
        $pin_used{$kind}[$objnum]= [ $board, $pi->[$obj], $obj ]
            if $mkused;
-       return sprintf("%4d /* %d.%-2d*/", $objnum, $board, $obj);
+       return sprintf("%#5x /* %d.%-2d*/", $objnum, $board, $obj);
     } else {
+#print "so_boob >$objnum_rr|$$objnum_rr< -\n";
        return "   0 /*none*/ ";
     }
 }
 
-sub so_objboob ($$$) {
-    my ($kind,$mkused,$obj) = @_;
-    return so_boob($kind,$mkused, defined $obj ? $obj->{BoOb} : undef);
+sub so_objboob ($$$;$) {
+    my ($kind,$mkused,$obj, $objnum_rr) = @_;
+#    return so_boob($kind,$mkused, defined $obj ? $obj->{BoOb} : undef );
+#print "so_objboob >$objnum_rr|$$objnum_rr<\n";
+    return so_boob($kind,$mkused,
+                  defined $obj ? $obj->{BoOb} : undef
+                  , $objnum_rr
+                  );
 }
 
 sub mainread () {
@@ -362,6 +379,21 @@ sub mainread () {
     }
 }
 
+sub redaction () {
+    my ($num,$mappednum,$i,$objnum);
+    $maxreverseobjnum= 0;
+    for ($num=0, $mappednum=0; $num<@boardtype; $num++) {
+       next unless defined $reversersboardnum[$num];
+       die if $reversersboardnum[$num] != -1;
+       $reversersboardnum[$num]= $mappednum;
+       for ($i=0; $i<6; $i++) {
+           $objnum= boob2objnum($mappednum,$i,'reverse',0);
+           $maxreverseobjnum= $objnum+1 if $objnum >= $maxreverseobjnum;
+       }
+       $mappednum++;
+    }
+}    
+
 sub nummap ($) {
     my ($p) = @_;
     $p =~ s/\d{1,6}/ sprintf "%06d%d",$&,$& /ge;
@@ -379,7 +411,6 @@ sub writeout () {
        push @segs, $seg;
     }
     o(sprintf
-      "#define NUM_TRAINS 1000000\n".
       "#define NUM_SEGMENTS %s\n\n".
       "#include \"layout-data.h\"\n\n",
       scalar @segs);
@@ -398,7 +429,7 @@ sub writeout () {
            }
            o("$delim\n");
            o(sprintf "  { %-8s %4d",
-             '"'.$seg.(length $pi ? '/' : '').$pi.'",',
+             '"'.$pi.'",',
              $segr->{Dist}[$comb]);
            for ($end=0; $end<2; $end++) {
                o(", { ");
@@ -446,7 +477,7 @@ sub writeout () {
            $ptv= $segr->{Feats}{$pt};
            next if exists $ptv->{Fixed};
            o("$delim\n");
-           o("  { \"$seg/$pt\", mfk_".lc($ptv->{Kind}).",".
+           o("  { \"$pt\", mfk_".lc($ptv->{Kind}).",".
              " $ptv->{Posns}, $ptv->{Weight}, mfbo_${seg}_$pt }");
            $delim=',';
        }
@@ -454,7 +485,9 @@ sub writeout () {
     }
     o("const SegmentNum info_nsegments=NUM_SEGMENTS;\n");
     o("const SegmentInfo info_segments[NUM_SEGMENTS]= {");
+    my (@sensemap,$segnum,$sensenum,$i,$j);
     $delim= '';
+    $segnum= 0;
     foreach $seg (@segs) {
        $segr= $segs{$seg};
        o("$delim\n");
@@ -462,11 +495,27 @@ sub writeout () {
          "\"$seg\",", $segr->{Inv},
          $segr->{FeatCount}, ($segr->{FeatCount} ? "mfi_$seg," : '0,'),
          $segr->{Posns}, "spci_$seg,",
-         so_objboob('sense',1, $segr),
+         so_objboob('sense',1, $segr, \$sensenum),
          so_objboob('reverse',1, $segr->{Inv} ? $segr : undef));
        $delim= ',';
+       o("/* sensmap[$sensenum]=$segnum */");
+       $sensemap[$sensenum]= $segnum++;
     }
     o("\n};\n");
+    o("const BoardObject info_maxreverse= $maxreverseobjnum;\n");
+    o("#define U -1\n");
+    o("const SegmentNumInMap info_segmentmap[]= {\n");
+    $i=0; $j=0;
+    foreach $seg (@sensemap) {
+       o(!$i ? ' ' :
+         (grep { $i == $_ } @sensesbase) ? ($j=0,"\n ") :
+         !(++$j % 30) ? ",\n  " :
+         ",");
+       o($seg || 'U');
+       $i++;
+    }
+    o("\n};\n".
+      "const int info_segmentmaplen= ".scalar(@sensemap).";\n");
 }
 
 # writeasm_KIND()
@@ -616,5 +665,6 @@ sub writeasm () {
     o("\n  end\n");
 }
 mainread();
+redaction();
 writeout();
 writeasm();