public Sector south() { return row==0 ? null : new Sector(col, row-4); }
public Sector east() { return col+4>=getWidth() ? null : new Sector(col+4, row); }
public Sector west() { return col==0 ? null : new Sector(col-4, row); }
- public Cell cell() { return Fpslic.this.cell(col, row); }
+ public Cell cell() { return Fpslic.this.cell(col, row); }
}
public final class SectorWire {
return (connect & 0x2)!=0;
}
public SectorWire driverRight() {
- System.out.println("checking " + Integer.toString(code(true), 16) + " " + Integer.toString(_row(), 16) + " " + Integer.toString(_col(), 16));
+ //System.out.println("checking " + Integer.toString(code(true), 16) + " " +
+ //Integer.toString(_row(), 16) + " " + Integer.toString(_col(), 16));
int ret = mode4(z(code(true)), _row(), _col());
ret = (ret >> (global?3:0)) & 0x7;
switch(ret) {
default: throw new Error("multiple drivers on " + this + "!");
}
}
+
+ public boolean touches(Cell c) {
+ return
+ horizontal
+ ? (c.row==_row() && (_col()/4 == c.col/4))
+ : (c.col==_col() && (_row()/4 == c.row/4));
+ }
}
/*
public final class SwitchBox {
this.col = col;
}
+ public Fpslic fpslic() { return Fpslic.this; }
+
// Accessors for Neighbors //////////////////////////////////////////////////////////////////////////////
public SectorWire hwire(int plane) { return new SectorWire(true, plane, col, row); }
public void h(int plane, boolean enable) {
switch(plane) {
- case 0: mode4(0x08, row, col, 2, enable); return;
- case 1: mode4(0x08, row, col, 0, enable); return;
+ case 0: mode4(0x08, row, col, 0, enable); return;
+ case 1: mode4(0x08, row, col, 2, enable); return;
case 2: mode4(0x08, row, col, 5, enable); return;
case 3: mode4(0x08, row, col, 6, enable); return;
case 4: mode4(0x00, row, col, 6, enable); return;
public boolean hx(int plane) {
switch(plane) {
- case 0: return (mode4(0x08, row, col) & (1<<2)) != 0;
- case 1: return (mode4(0x08, row, col) & (1<<0)) != 0;
+ case 0: return (mode4(0x08, row, col) & (1<<0)) != 0;
+ case 1: return (mode4(0x08, row, col) & (1<<2)) != 0;
case 2: return (mode4(0x08, row, col) & (1<<5)) != 0;
case 3: return (mode4(0x08, row, col) & (1<<6)) != 0;
case 4: return (mode4(0x00, row, col) & (1<<6)) != 0;
}
public int t() {
- System.err.println("found " + (mode4(1, row, col) & 0x34));
- switch(mode4(1, row, col) & 0x34) {
- case 0x20: return TMUX_Z;
- case 0x24: return TMUX_W_AND_Z;
- case 0x34: return TMUX_FB;
- case 0x14: return TMUX_W_AND_FB;
+ switch(mode4(1, row, col) & 0x30) {
case 0x00: return TMUX_W;
- //default: throw new RuntimeException("unknown!");
+ case 0x10: return wi()==NONE ? TMUX_FB : TMUX_W_AND_FB;
+ case 0x20: return wi()==NONE ? TMUX_Z : TMUX_W_AND_Z;
+ case 0x30: throw new RuntimeException("illegal!");
default: return TMUX_W;
}
}
public void t(int code) {
int result = 0;
switch(code) {
- case TMUX_Z: result = 0x20; break; // TOTALLYBOGUS throw new Error("not implemented, but should be possible");
- case TMUX_W_AND_Z: result = 0x24; break;
- case TMUX_FB: result = 0x34; break; /* I think this is actually W_AND_FB, sadly */
- case TMUX_W_AND_FB: result = 0x14; break;
case TMUX_W: result = 0x00; break;
- //default: throw new RuntimeException("unknown code! " + code);
+ case TMUX_Z: result = 0x20; break;
+ case TMUX_W_AND_Z: result = 0x20; break;
+ case TMUX_FB: result = 0x10; break;
+ case TMUX_W_AND_FB: result = 0x10; break;
default: result = 0x00; break;
}
- mode4(1, row, col, result, 0x34);
+ mode4(1, row, col, result, 0x30);
}
/*
private void fmux(int source) {
public boolean yo() { return (mode4(1, row, col) & 0x02) != 0; }
public void xo(boolean center) { mode4(1, row, col, 0, center); }
public void yo(boolean center) { mode4(1, row, col, 1, center); }
+
+ public void xo(Cell c) {
+ if (c.row==row || c.col==col) { // use the y-input
+ xlut(LUT_OTHER);
+ yi(c);
+ } else {
+ xlut(LUT_SELF);
+ xi(c);
+ }
+ xo(false);
+ }
+
+ public void yo(Cell c) {
+ if (!(c.row==row || c.col==col)) { // use the x-input
+ ylut(LUT_OTHER);
+ xi(c);
+ } else {
+ ylut(LUT_SELF);
+ yi(c);
+ }
+ yo(false);
+ }
+
public boolean b() { return (mode4(1, row, col) & (1 << 3)) == 0; }
public boolean f() { return (mode4(1, row, col) & (1 << 2)) == 0; }
public boolean x() { return (mode4(1, row, col) & (1 << 1)) != 0; }
case NE: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<6); break;
case SE: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<5); break;
case NW: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<4); break;
- case L4: mode4(0x03, row, col, 4, true); mode4(0x05, row, col, 0); break;
- case L3: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<0); break;
- case L2: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<1); break;
- case L1: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<2); break;
+
case L0: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<3); break;
+ case L1: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<2); break;
+ case L2: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<1); break;
+ case L3: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 1<<0); break;
+ case L4: mode4(0x03, row, col, 4, true); mode4(0x05, row, col, 0); break;
+
case NONE: mode4(0x03, row, col, 4, false); mode4(0x05, row, col, 0); break;
default: throw new RuntimeException("invalid argument");
}
}
+ public void xi(SectorWire sw) {
+ if (!sw.touches(this)) throw new RuntimeException("invalid argument");
+ xi(sw.plane);
+ }
+
+ public void xi(Cell c) {
+ if (c.row==row-1 && c.col==col-1) xi(SW);
+ else if (c.row==row+1 && c.col==col-1) xi(NW);
+ else if (c.row==row-1 && c.col==col+1) xi(SE);
+ else if (c.row==row+1 && c.col==col+1) xi(NE);
+ else throw new RuntimeException("invalid argument");
+ }
+
public int yi() {
if ((mode4(0x02, row, col) & (1<<6))!=0) return L4;
switch(mode4(0x04, row, col) & 0xff) {
}
}
+ public void yi(SectorWire sw) {
+ if (!sw.touches(this)) throw new RuntimeException("invalid argument");
+ yi(sw.plane);
+ }
+
+ public void yi(Cell c) {
+ if (c.row==row-1 && c.col==col) yi(SOUTH);
+ else if (c.row==row+1 && c.col==col) yi(NORTH);
+ else if (c.row==row && c.col==col-1) yi(WEST);
+ else if (c.row==row && c.col==col+1) yi(EAST);
+ else throw new RuntimeException("invalid argument");
+ }
+
+ public void wi(SectorWire sw) {
+ if (!sw.touches(this)) throw new RuntimeException("invalid argument");
+ wi(sw.plane);
+ }
+
public void wi(int source) {
switch(source) {
case L4: mode4(0x03, row, col, 1<<5, 0xEC); break;
}
+ public void zi(SectorWire sw) {
+ if (!sw.touches(this)) throw new RuntimeException("invalid argument");
+ zi(sw.plane);
+ }
+
public void zi(int source) {
switch(source) {
case L4: mode4(0x02, row, col, 1<<7, 0xDB); break;
}
public int zi() {
- switch(mode4(0x02, row, col) & 0xDB) {
+ switch(mode4(0x02, row, col) & 0x9B) {
case (1<<7): return L4;
case (1<<5): return L3;
case (1<<4): return L2;
case (1<<1): return NONE; /* huh? */
case (1<<0): return NONE; /* huh? */
case 0: return NONE;
- default: throw new RuntimeException("invalid argument: zi=="+(mode4(0x02, row, col) & 0xDB));
- }
+ default: throw new RuntimeException("invalid argument: zi=="+(mode4(0x02, row, col) & 0x9B));
+ }
+ }
+
+ public Cell dir(int i) {
+ switch(i) {
+ case NORTH: return north();
+ case SOUTH: return south();
+ case EAST: return east();
+ case WEST: return west();
+ case NW: return nw();
+ case SW: return sw();
+ case SE: return se();
+ case NE: return ne();
+ }
+ return null;
+ }
+ public int dir(Cell c) {
+ if (c.row==row-1 && c.col==col-1) return SW;
+ else if (c.row==row+1 && c.col==col-1) return NW;
+ else if (c.row==row-1 && c.col==col+1) return SE;
+ else if (c.row==row+1 && c.col==col+1) return NE;
+ else if (c.row==row-1 && c.col==col) return SOUTH;
+ else if (c.row==row+1 && c.col==col) return NORTH;
+ else if (c.row==row && c.col==col-1) return WEST;
+ else if (c.row==row && c.col==col+1) return EAST;
+ return -1;
+ }
+
+ public void generalized_c_element() {
+
+ /*
+ ylut(LUT_SELF & (~LUT_OTHER));
+ xlut((~LUT_SELF) | LUT_OTHER);
+ c(ZMUX);
+ zi(L2);
+ //h(L2, true);
+ out(L2, true);
+ xo(true);
+ yo(true);
+ */
+
+ //ylut(0xB2);
+ ylut((LUT_SELF & ~LUT_OTHER) | (LUT_Z & ~LUT_OTHER) | (LUT_Z & LUT_SELF & LUT_OTHER));
+ xlut(LUT_Z);
+ c(YLUT);
+ f(false);
+ b(false);
+ t(false, false, true);
+ yo(false);
+ xo(false);
}
// Relevance //////////////////////////////////////////////////////////////////////////////
+ public boolean relevant() {
+ return xo_relevant() || yo_relevant() || out_relevant();
+ }
public boolean xo_relevant() { return xo_relevant(NE) || xo_relevant(SE) || xo_relevant(NW) || xo_relevant(SW); }
public boolean xo_relevant(int direction) {
switch(direction) {
- case NE: return ne() != null && ne().xi()==SW /*&& ne().xi_relevant()*/;
- case NW: return nw() != null && nw().xi()==SE /*&& nw().xi_relevant()*/;
- case SE: return se() != null && se().xi()==NW /*&& se().xi_relevant()*/;
- case SW: return sw() != null && sw().xi()==NE /*&& sw().xi_relevant()*/;
+ case NE: return ne() != null && ne().xi()==SW;
+ case NW: return nw() != null && nw().xi()==SE;
+ case SE: return se() != null && se().xi()==NW;
+ case SW: return sw() != null && sw().xi()==NE;
default: return false;
}
}
boolean out = false;
boolean connect = false;
for(int i=0; i<4; i++) {
+
+ // FIXME FIXME FIXME
+ if (i==3) continue;
+
if (out(L0+i)) out = true;
if (hx(L0+i)) connect = true;
if (vx(L0+i)) connect = true;
}
return out && connect;
}
+
public boolean fb_relevant() {
+ /*
if (!(zi_to_xlut_relevant()) ||
!(zi_to_ylut_relevant())) return false;
switch(ti()) {
case 0x30: return true;
}
return false;
+ */
+ return true;
}