--- /dev/null
+; This .inc file is included by the autogenerated ours-pindata.asm
+; and should define the things that ours-pindata.asm needs.
+
+; ours-pindata.asm contains data specifying which PIC pins correspond
+; to which points (`pt'), section reversers (`reverse') and section
+; detections (`sense').
+;
+; Objects are numbered starting at 1; object number 0 is always
+; unused/undefined.
+;
+; For each object kind KIND there are three data areas in
+; to the flash program memory, starting at
+; KIND_pic_data
+; KIND_port_data
+; KIND_pin_data
+; (all of which must be defined by this file, pindata.inc,
+; or something it includes - they're in common.inc at the moment).
+;
+; Each of these data areas is an array of bytes, one per object. The
+; first byte (at KIND_pic_data) is for object no.0, the next (at
+; KIND_pic_data+1) is for object no.1, etc. (Object no.0 is never
+; used.)
+;
+; The byte values in each section are as follows:
+;
+; KIND_pic_data PIC number which controls this object (0 for the
+; master PIC, etc.). 0xff if this object number is
+; undefined/unused. The KIND_pic_data array is
+; filled up to but not including KIND_pic_data +
+; KIND_num_max. (KIND_num_max must be defined by
+; pindata.inc ie in common.inc).
+;
+; KIND_port_data Low byte of address of the relevant LATx for the
+; object. If the object number is unused, the
+; value in flash is undefined (ie it may be
+; anything).
+;
+; KIND_pin_data Byte with exactly one bit, being the relevant
+; bit of the LATx/PORTx/TRISx. If the object
+; number is unused, the value in flash is undefined
+; (ie it may be anything).
+
+ include common.inc
use strict qw(vars);
+our ($basename);
+$basename= @ARGV ? $ARGV[0] : 'safety';
+die if $basename =~ m/^\-/;
+$basename =~ s/\.wiring$//;
+
our ($mistakes, $currentline);
our (%segs);
# $nodes{$node}[$side]{Seg}
# $nodes{$node}[$side]{End}
+our ($nextboardnum,@objkinds,@boardobjbase,@boardtype,%pin_used);
+# @boardtype[$boardnum]
+# $boardobjbase[$boardnum]{$kind}
+# %pin_used{$objkind}[$objnum] = [ $boardnum, $pin_info, $objonboard ]
+$nextboardnum= 0;
+@objkinds= qw(pt sense reverse);
+map { $boardobjbase[0]{$_}= 1; } @objkinds;
+
+our (%kind_count,%pin_info); # from BOARD.pin-info
+
our ($mode,$invertible);
$mode= 'barf';
sub begin_endwiring () {
}
+sub begin_boards () {
+}
+sub line_boards () {
+ my ($num,$type,$k);
+ m/^\s+(\d+)\s+(\w+)$/ or return syntaxerror();
+ ($num,$type)=($1,$2);
+ mistake("board $num when expected $nextboardnum")
+ if $num != $nextboardnum;
+ $nextboardnum++;
+ require "./$type.pin-info";
+ $boardtype[$num]= $type;
+ foreach $k (@objkinds) {
+ $boardobjbase[$nextboardnum]{$k}=
+ $boardobjbase[$num]{$k} + $kind_count{$type}{$k};
+ }
+}
+
sub mistake ($) {
my ($m) = @_;
print STDERR "mistake: $m\n in $mode, \`$currentline'\n";
sub so_boob ($$) {
my ($k,$bo) = @_;
- return sprintf "%5d /* %d.%-2d*/", $bo->[0] * 1000 + $bo->[1],
- $bo->[0], $bo->[1];
+ 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".
+ " board type $type")
+ unless defined $pi->[$obj];
+ $pin_used{$k}[$objnum]= [ $board, $pi->[$obj], $obj ];
+ return sprintf("%4d /* %d.%-2d*/", $objnum, $board, $obj);
+ } else {
+ return " 0 /*none*/ ";
+ }
}
sub so_oboob ($$) {
my ($k,$obj) = @_;
- return so_boob($k,$obj->{BoOb});
+ return so_boob($k, defined $obj ? $obj->{BoOb} : undef);
}
sub mainread () {
s/\s+$//;
next unless m/\S/;
last if m/^end$/;
- if (m/^(invertible|vanilla|points|fixed|endwiring)$/) {
+ if (m/^(invertible|vanilla|points|fixed|endwiring|boards)$/) {
$mode= $1;
$invertible= ($mode eq 'invertible');
$mode= 'segment' if $mode =~ m/^(?:vanilla|invertible)$/;
foreach $seg (@segs) {
$segr= $segs{$seg};
- o("static const SegPosCombInfo spci_${seg}[]= {");
+ o("static const SegPosCombInfo spci_${seg}"."[]= {");
$delim='';
for ($comb=0; $comb < $segr->{Posns}; $comb++) {
$pi='';
for $pt (keys %{ $segr->{Feats} }) {
$ptv= $segr->{Feats}{$pt};
next if exists $ptv->{Fixed};
- o("static const BoardObject mfbo_${seg}_${pt}[]= {");
+ o("static const BoardObject mfbo_${seg}_${pt}"."[]= {");
$delim=' ';
foreach $boob (@{ $ptv->{BoOb} }) {
o($delim);
o(" };\n");
}
- o("static const MovFeatInfo mfi_${seg}[]= {");
+ o("static const MovFeatInfo mfi_${seg}"."[]= {");
$delim='';
for $pt (keys %{ $segr->{Feats} }) {
$ptv= $segr->{Feats}{$pt};
foreach $seg (@segs) {
$segr= $segs{$seg};
o("$delim\n");
- o(sprintf " { %-7s %d, %2d,%-9s %3d,%-10s %-6s }",
+ o(sprintf " { %-7s %d, %2d,%-9s %3d,%-10s %-6s,%-6s }",
"\"$seg\",", $segr->{Inv},
$segr->{FeatCount}, ($segr->{FeatCount} ? "mfi_$seg," : '0,'),
$segr->{Posns}, "spci_$seg,",
- so_oboob('sense',$segr), so_oboob('reverse',$segr));
+ so_oboob('sense',$segr),
+ so_oboob('reverse', $segr->{Inv} ? $segr : undef));
$delim= ',';
}
o("\n};\n");
}
+sub writeasm () {
+ my ($k,$w,$i,@d,$or,$p,$portnum,$bit,$each);
+ close STDOUT or die $!;
+ open STDOUT, ">$basename-pindata.asm" or die $!;
+ o("; autogenerated - do not edit\n");
+ 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("\n end\n");
+}
mainread();
writeout();
+writeasm();
--- /dev/null
+#!/usr/bin/perl
+# usage:
+# pinout-gen BOARDNAME
+
+use IO::Handle;
+
+@ARGV==1 or die $!;
+$board= shift @ARGV;
+
+$cpin=1; $_='';
+for (;;) {
+ if (!length) { $_= <DATA>; last unless length; $_.=' '; s/^\s+//; }
+ if (m/^\#/) {
+ $_='';
+ } elsif (s/^\-\s+//) {
+ $cpin++;
+ } elsif (s/^[ABCDE]\s+//) {
+ $port= ord($&) - ord('A');
+ } elsif (s/^([0-9a-f][0-9a-f])\s+//) {
+ die unless defined $port;
+ $pins[$cpin++]= "$port,0x$1";
+ } else {
+ die "$_ ?";
+ }
+}
+die unless $cpin==41;
+
+print "our (\%pin_info,\%kind_count);\n"
+ or die $!;
+
+$kinds= 'pt|sense|reverse';
+
+open B, "../pcb/$board.net" or die $!;
+while (<B>) {
+ if (s/\\$//) { $_.= <B>; }
+ m/^(\w+)\s+[A-Z]\w+\s+([-_A-Z0-9 \t]+)$/;
+ $net= $1; $pins= $2; $pin= undef;
+ map { $pin=$1 if m/PIC-(\d+)/; } split /\s+/, $pins;
+ next unless defined $pin;
+ next unless $net =~ m/^(?:.*__)?($kinds)(\d+)(?:__.*)?$/;
+ $kind= $1; $num= $2;
+ die "$pin $kind $num ?" unless defined $pins[$pin];
+ print "\$pin_info{'$board'}{'$kind'}[$num]= '$pins[$pin]';\n"
+ or die $!;
+ $count{$kind}= $num+1 if $num>=$count{$kind};
+}
+B->error and die $!;
+
+for $kind (split /\|/, $kinds) {
+ printf("\$kind_count{'%s'}{'%s'}= %d;\n",
+ $board, $kind, $count{$kind})
+ or die $!;
+}
+print "1;\n"
+ or die $!;
+
+__DATA__
+# 1..20
+-
+A 01 02 04 08 10 20
+E 01 02 04
+- - -
+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
+- -
+B 01 02 04 08 10 20 40 80