# $nodes{$node}[$side]{Seg}
# $nodes{$node}[$side]{End}
+our ($maxptixln2) = 5;
+
our ($nextboardnum,@boardtype,%numboards,$nreverses,@sensesin,@sensesbase);
+our (@objkinds,%pin_used);
# @boardtype[$boardnum]
# $numboards{$type}
# $nreverses
# $sensesin[$page]
# $sensesbase[$boardnum]= ($page << 7) | $baselsbyte
+# %pin_used{$objkind}[$objnum] = [ $boardnum, $pin_info, $objonboard ]
$nextboardnum= 0;
$nreverses= 0;
$sensesin[0]= 0;
$sensesbase[$num]= ($page << 7) | $sensesin[$page];
$sensesin[$page] += $sense_count;
- &{"line_board_$type"}($num);
+ &{"line_boards_$type"}($num);
}
-sub line_board_reversers ($) {
+sub line_boards_reversers {
my ($num) = @_;
my ($i,$objnum);
- for ($i=0; $i<5; $i++) {
- $objnum= so_boob('reverse', [ $num,$i ]);
+ for ($i=0; $i<6; $i++) {
+ $objnum= boob2objnum($num,$i,'reverse',0);
$nreverses= $objnum+1 if $objnum >= $nreverses;
}
}
+sub line_boards_detectors { }
sub mistake ($) {
my ($m) = @_;
return [ $1,$2 ];
}
-# so_boob_KIND($boardnum,$objnum,$boardtype,$pininfo) -> global object number
+# boob2objnum_KIND($boardnum,$objnum,$boardtype,$mkused
+# -> global object number
-sub so_boob_pt {
+sub boob2objnum_pt {
my ($boardnum,$obj)=@_;
- mistake("point encoding out of range") if $boardnum>31;
- die if $obj > 31;
- return ($boardnum << 5) | $obj;
+ mistake("point encoding out of range") if
+ $boardnum >= (1 << (10 - $maxptixln2));
+ die if $obj >= (1 << $maxptixln2);
+ return ($boardnum << $maxptixln2) | $obj;
}
-sub so_boob_reverse {
+sub boob2objnum_reverse {
my ($boardnum,$obj,$boardtype)=@_;
# Converts board and object number (in canonical pic number plus
my ($cycle,$boardincycle,$cyclebasebyte,$byte,$bit);
die unless $boardtype eq 'reversers';
- die if $obj > 5;
+ die $obj if $obj > 5;
$obj = sprintf '%d', $obj;
$obj =~ y/302154/543210/; # mapping due to polarity_do_here
$cycle= int(($boardnum+3) / 7);
return $byte*7 + 3 - $bit;
}
-sub so_boob_sense($$$) {
+sub boob2objnum_sense {
my ($boardnum,$obj)=@_;
my ($inpage);
$inpage= $obj + $sensesbase[$boardnum];
return ($boardnum << 7) | $inpage;
}
-sub so_boob ($$) {
- my ($kind,$bo) = @_;
+sub boob2objnum ($$$$) {
+ my ($boardnum,$obj,$kind,$mkused) = @_;
+ my ($type);
+ $type= $boardtype[$boardnum];
+ return &{"boob2objnum_$kind"}($boardnum,$obj,$type,$mkused);
+}
+
+sub boob_used_bit ($$$) {
+ my ($boardnum,$obj,$kind) = @_;
+ my ($objnum);
+ $objnum= boob2objnum($boardnum, $obj, $kind, 0);
+ return defined $pin_used{$kind}[$objnum] ? 1 : 0;
+}
+
+sub so_boob ($$$) {
+ my ($kind,$mkused,$bo) = @_;
+ my ($type,$pi);
if (defined $bo) {
my ($board,$obj)= @$bo;
my ($objnum,$type,$pi);
mistake("object reference $kind $board.$obj out of range for".
" board type $type")
unless defined $pi->[$obj];
- $objnum= &{"so_boob_$kind"}($board,$obj,$type,$pi);
- $pin_used{$kind}[$objnum]= [ $board, $pi->[$obj], $obj ];
+ $objnum= boob2objnum($board,$obj,$kind,$mkused);
+ $pin_used{$kind}[$objnum]= [ $board, $pi->[$obj], $obj ]
+ if $mkused;
return sprintf("%4d /* %d.%-2d*/", $objnum, $board, $obj);
} else {
return " 0 /*none*/ ";
}
}
-sub so_oboob ($$) {
- my ($kind,$obj) = @_;
- return so_boob($kind, defined $obj ? $obj->{BoOb} : undef);
+sub so_objboob ($$$) {
+ my ($kind,$mkused,$obj) = @_;
+ return so_boob($kind,$mkused, defined $obj ? $obj->{BoOb} : undef);
}
sub mainread () {
$delim=' ';
foreach $boob (@{ $ptv->{BoOb} }) {
o($delim);
- o(so_boob('pt',$boob));
+ o(so_boob('pt',1, $boob));
$delim= ', ';
}
o(" };\n");
"\"$seg\",", $segr->{Inv},
$segr->{FeatCount}, ($segr->{FeatCount} ? "mfi_$seg," : '0,'),
$segr->{Posns}, "spci_$seg,",
- so_oboob('sense',$segr),
- so_oboob('reverse', $segr->{Inv} ? $segr : undef));
+ so_objboob('sense',1, $segr),
+ so_objboob('reverse',1, $segr->{Inv} ? $segr : undef));
$delim= ',';
}
o("\n};\n");
# writeasm_KIND()
-sub o_section ($) {
- my ($sec) = @_;
- o("$sec code ${sec}_start");
+sub o_section ($$) {
+ my ($sec,$docstring) = @_;
+ o("\n;----------\n".
+ " org $sec\n");
+ o($docstring);
+}
+sub o_section_end_fill ($$$) {
+ my ($lastnumdone, $fillvalue, $entrysize) = @_;
+ if ($entrysize == 1 and $lastnumdone & 1) {
+ o(", $fillvalue & 0xff\n");
+ $lastnumdone++;
+ } else {
+ o("\n");
+ }
+ o(sprintf " fill %s, %d*(maxpic-%d)\n\n",
+ $fillvalue, $entrysize, $lastnumdone);
+}
+
+sub o_db ($;$) {
+ my ($ix,$every) = @_;
+ $every=16 unless defined $every;
+ o(($every ? $ix % $every : $ix) ? ',' : "\n db ");
}
sub writeasm_sense {
- o_section("pindata_pic2detinfo");
- o("Exists equ 0x8000\n".
- "Detectors equ 0x0080\n".
- "Reversers equ 0x0000\n");
+ my ($num, $base);
+ o_section('pic2detinfo',<<'END');
+; Table indexed by pic no., giving information about sensing
+; Each element is two bytes:
+; 1st byte bit 7 Set iff this board exists for the purposes of sensing
+; bits 6-3 Not used, set to zero
+; bits 2-0 Top 3 bits of sense segment numbers on this board
+; 2nd byte bit 7 Set iff this board is a Detectors board
+; bits 6-0 Base for bottom 7 bits of segment number
+; (per-board segment no. is added to this; carry
+; to upper 3 bits is not permitted)
+END
+ o("SenseExists equ 0x80\n".
+ "Detectors equ 0x80\n".
+ "Reversers equ 0x00\n\n");
for ($num=0; $num<@boardtype; $num++) {
- if (!defined $boardtype[$num]) { o(" dw 0\n"); next; }
+ if (!defined $boardtype[$num]) { o(" dw 0\t\t\t\t; $num\n"); next; }
$base= $sensesbase[$num];
- o(sprintf " dw Exists | %-10s | 0x%02x%02x\n",
- ucfirst($boardtype[$num]), $base >> 7, $base & 0x7f);
+ o(sprintf " db SenseExists | 0x%02x, %12s | 0x%02x\t; %d\n",
+ $base >> 7, ucfirst($boardtype[$num]), $base & 0x7f, $num);
+ }
+ o_section_end_fill($num, 0, 2);
+}
+
+sub writeasm_pt {
+ my ($num, $elemsize, $byte, $bit, $objnum);
+ o_section('picno2ptmap',<<'END');
+; Bitmap indexed first by pic no, and then by point no. on that board,
+; saying whether the point is present or not. Each pic has 4 bytes,
+; ie 32 bits. First byte is points 0 to 7, in bits 0 to 7 respectively
+; so that MSbit of byte 3 (4th byte) is point no.31. Unused boards
+; or boards with no points are all-bits-0.
+END
+ for ($num=0; $num<@boardtype; $num++) {
+ if (!defined $boardtype[$num]) { o(" dw 0\t\t\t\t; $num"); next; }
+ die if $maxptixln2 < 4; # must be whole no. of 16-bit words
+ $elemsize= 1 << ($maxptixln2-3);
+ for ($byte=0; $byte < $elemsize; $byte++) {
+ o_db($byte, 0);
+ o("b'");
+ for ($bit=7; $bit>=0; $bit--) {
+ o(boob_used_bit($num, $byte*8 + $bit, 'pt'));
+ }
+ o("'");
+ }
+ o(" ; $num");
}
- o(sprintf " fill 0, maxboards_count-%d\n", $num);
o("\n");
+ o_section_end_fill($num, 0, $elemsize);
+
+ my($typeix,$type,$pt,$pi);
+ o_section('bkptix2portnumbitnum',<<"END");
+; Table giving physical ports and pins for points for each
+; kind of board. Index is point number (for reversers boards)
+; or point number + 2^$maxptixln2 (for detectors boards).
+; Value is one byte, either 0xff meaning that board type has
+; no such point, or top nybble being port number (0 for A, 1 for B,
+; etc.) and bottom nybble being bit number. Ie,
+; Index: 00Dppppp where D is 1 iff detectors board and p is pt ix
+; Value: 0ppp0bbb where p is port num and b is bit num; or 0xff
+END
+ o(" radix hex\n");
+ for ($typeix=0; $typeix<2; $typeix++) {
+ $type= qw(reversers detectors)[$typeix];
+ die $type unless $pin_info{$type};
+ o("; $type:");
+ for ($pt=0; $pt < (1 << $maxptixln2); $pt++) {
+ o_db($pt);
+ $pi= $pin_info{$type}{'pt'}[$pt];
+ if (defined $pi) {
+ $pi =~ m/^(\d)\,(\d)\,/ or die;
+ o($1.$2);
+ } else {
+ o('ff');
+ }
+ }
+ o("\n");
+ }
+ o(" radix dec\n\n");
+}
+
+sub writeasm_reverse {
+ my ($num,$kc,$bit);
+ o_section('picno2revbits',<<END);
+; Table listing which reversers are connected/enabled.
+; Index is pic number. Value is 0xff for non-reversers boards,
+; or bitmap of connected reversers. LSbit is reverse 0, etc.
+END
+ for ($num=0; $num<@boardtype; $num++) {
+ o_db($num, 4);
+ $kc= $kind_count{$boardtype[$num]}{'reverse'};
+ if ($kc) {
+ die if $kc > 7;
+ o("b'");
+ for ($bit= $kc-1; $bit>=0; $bit--) {
+ o(boob_used_bit($num, $bit, 'reverse'));
+ }
+ o("'");
+ } else {
+ o('0xff');
+ }
+ }
+ o_section_end_fill($num, '0xffff', 1);
}
-# 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");
-# }
-# }
-# }
sub writeasm () {
my ($k,$w,$i,@d,$or,$p,$portnum,$bit,$each);
close STDOUT or die $!;
- open STDOUT, ">$basename-pindata.asm" or die $!;
+ open STDOUT, ">$basename+pindata.asm" or die $!;
o("; autogenerated - do not edit\n");
o(" include pindata.inc\n".
" radix dec\n".
- "X equ 0xff\n");
+ "ff equ 0xff\n");
$each= 10;
for $k (@objkinds) {
&{"writeasm_$k"}();