+ public Sector north() { return row+4>=height ? null : new Sector(col, row+4); }
+ public Sector south() { return row==0 ? null : new Sector(col, row-4); }
+ public Sector east() { return col+4>=width ? null : new Sector(col+4, row); }
+ public Sector west() { return col==0 ? null : new Sector(col-4, row); }
+ public Cell cell() { return At40k.this.cell(col, row); }
+ }
+
+ public final class SectorWire {
+ public final boolean global;
+ public final boolean horizontal;
+ public final int plane;
+ public final int row;
+ public final int col;
+ public SectorWire(boolean horizontal, int plane, int col, int row) {
+ this.horizontal=horizontal;
+ this.global = false;
+ this.plane=plane;
+ this.col= horizontal ? (col & ~0x3) : col;
+ this.row=!horizontal ? (row & ~0x3) : row;
+ }
+ public boolean isDriven() {
+ // FIXME: bridging connections (horiz-to-vert)
+ for(int i=0; i<4; i++)
+ if (cell(horizontal ? col+i : col,
+ horizontal ? row : row+i).out(plane)) return true;
+ // FIXME: sector switchbox drivers
+ return false;
+ }
+ private int z(int z) { return (horizontal ? 0x30 : 0x20) | z; }
+ public int code(boolean topleft) {
+ switch(plane) {
+ case 0: return z(6)+(topleft?0:1);
+ case 1: return z(8)+(topleft?0:1);
+ case 2: return z(2*(4-plane))+(topleft?0:1);
+ case 3: return z(2*(4-plane))+(topleft?0:1);
+ case 4: return z(2*(4-plane))+(topleft?0:1);
+ }
+ throw new Error();
+ }
+
+ private final int fine() { return horizontal ? row : col; }
+ public final int coarse() { return horizontal ? col : row; }
+ private int _row() { return horizontal ? row : ((row)>>2); }
+ private int _col() { return horizontal ? ((col)>>2) : col; }
+
+ public SectorWire west() { return !horizontal ? null : col-4<0 ? null : new SectorWire(horizontal, plane, col-4, row); }
+ public SectorWire east() { return !horizontal ? null : col+4>=width ? null : new SectorWire(horizontal, plane, col+4, row); }
+ public SectorWire north() { return horizontal ? null : row+4>=height ? null : new SectorWire(horizontal, plane, col, row+4); }
+ public SectorWire south() { return horizontal ? null : row-4<0 ? null : new SectorWire(horizontal, plane, col, row-4); }
+
+ public String toString() {
+ return
+ (horizontal?(col+":"+(col+3)):(""+col))+","+
+ (horizontal?(row+"") :(row+":"+(row+3)))+
+ "x"+plane;
+ }
+
+ /** returns the ZYX0 coordinate of the byte controlling the switchbox that allows <tt>w</tt> to drive this wire */
+ public int switchbox(SectorWire w) {
+ if (w.horizontal==horizontal) {
+ if (w.plane!=plane) throw new Error();
+ if (Math.abs(w.coarse()-coarse())!=4) throw new Error(w.coarse() + " -- " + coarse());
+ boolean topleft = horizontal ? (w.coarse() < coarse()) : (w.coarse() > coarse());
+ int col = _col() + (( horizontal && !topleft) ? 1 : 0);
+ int row = _row() + ((!horizontal && topleft) ? 1 : 0);
+ return (code(topleft) << 24) | (row<<16) | (col<<8);
+ }
+ throw new Error("not implemented");
+ }
+
+ public void drives(SectorWire w, boolean enable) {
+ dev.mode4zyx(switchbox(w), enable?0x02:0x00, 0x07);
+ }
+
+ public boolean drives(SectorWire w) {
+ int connect = (dev.mode4zyx(switchbox(w)) >> (global?3:0)) & 0x7;
+ return (connect & 0x2)!=0;
+ }
+ public SectorWire driverRight() {
+ System.out.println("checking " + Integer.toString(code(true), 16) + " " + Integer.toString(_row(), 16) + " " + Integer.toString(_col(), 16));
+ int ret = dev.mode4(z(code(true)), _row(), _col());
+ ret = (ret >> (global?3:0)) & 0x7;
+ switch(ret) {
+ case 0: return null;
+ case 1: return null; /* global wire on same side */
+ case 2: return new SectorWire(horizontal, plane, horizontal?(col+4):col, horizontal?row:(row+4));
+ case 4: return null; /* global wire on other side */
+ default: throw new Error("multiple drivers on " + this + "!");
+ }
+ }
+ }
+ /*
+ public final class SwitchBox {
+ public final boolean h;
+ public final int col;
+ public final int row;
+ public final int plane;
+ public SwitchBox(boolean h, int col, int row, int plane) { this.h = h; this.col = col; this.row = row; this.plane = plane; }
+ public SectorWire west(boolean global) { return !h ? null : global ? null : new SectorWire(h, col-4, row, plane); }
+ public SectorWire east(boolean global) { return !h ? null : global ? null : new SectorWire(h, col+4, row, plane); }
+ public SectorWire north(boolean global) { return !h ? null : global ? null : new SectorWire(h, col, row-4, plane); }
+ public SectorWire south(boolean global) { return !h ? null : global ? null : new SectorWire(h, col, row+4, plane); }
+ }
+ */
+
+ public Cell cell(int col, int row) {
+ if (col<0) return null;
+ if (row<0) return null;
+ if (col>=width) return null;
+ if (row>=height) return null;
+ return new Cell(col, row);