使用Java中的按位运算进行案例评估

时间:2013-09-05 08:08:47

标签: java switch-statement emulation case opcode

我目前正在Java中创建一个8080模拟器作为一个丰富项目,我正在尝试创建一个开关/案例表来获取操作码,然后做一些东西,因为它似乎是一种有效的方式来获取PC字节和做东西

例如,0b01000000到0b01111111是除了0b01110110(HALT)之外的所有MOV指令。

因此,我希望能够按照

的方式创建一些代码
public void decode(){
    switch(PC){
        case 0b01110110: halt(); break;
        case (PC & 0B01000000): mov(); break;
    }
}

可悲的是,案例必须是静态的,无法在表中进行评估。有办法解决这个问题吗?我想尽量避免使用if()语句,因为我觉得如果通过做一些在电路中无法做到的事情就会失去项目的完整性。

到目前为止,我只使用nand gate实现了算术和逻辑核心,我想保留简约主题,但如果没有追索权,我愿意放弃它。

1 个答案:

答案 0 :(得分:0)

我建议您通过位掩码选择mov函数,并延迟hlt的检测,直到逻辑进一步向下。

public static final int MOVMatch = 0b01000000;
public static final int MOVMask = 0b00111111;
// I am guessing 3 bits per register - check this in the spec.
public static final int MOVFrom = 0b00111000;
public static final int MOVTo = 0b00000111;
public static final int MOVHLT = 0b00110110;
if ( (PC & MOVMatch) == MOVMatch) {
  if ( (PC & MOVMatch) != MOVHLT ) {
    int movFrom = PC & MOVFrom;
    int movTo = PC & MOVTo;
    // ...
  } else {
    // HLT!
  }

}

另一种模式是将进程编码为一组命令。这样的事情可能是一个公平的起点:

public class Test {
  enum Reg {
    A, B, C, D, E, H, L, M, None;
  }

  static class Op {
    final Act act;
    final Reg f;
    final Reg t;

    // Default missing params to none.
    public Op(Act act, Reg f) {
      this(act, f, Reg.None);
    }

    public Op(Act act) {
      this(act, Reg.None, Reg.None);
    }

    public Op(Act act, Reg f, Reg t) {
      this.act = act;
      this.f = f;
      this.t = t;
    }

    // Perform the action.
    public void act() {
      act.act(f, t);
    }

  }

  enum Act {
    Mov {
      @Override
      void act(Reg f, Reg t) {
        // Do something to the state of machine state that emulates a move from f to t.
        // For demo, just print.
        super.act(f, t);
      }

    },
    Hlt {
      @Override
      void act(Reg f, Reg t) {
        // Do something to the state of machine state that halts.
        // For demo, just print.
        super.act(f, t);
      }

    };

    // All instructions should have an action.
    void act(Reg f, Reg t) {
      // Default action just prints.
      System.out.println(this + " " + f + "," + t);
    }

  }

  enum Inst {
    b01000000(new Op(Act.Mov, Reg.B, Reg.B)),
    b01000001(new Op(Act.Mov, Reg.B, Reg.C)),
    b01110110(new Op(Act.Hlt));
    final Op op;

    Inst(Op op) {
      this.op = op;
    }

    void act () {
      op.act();
    }
  }

  public void test() {
    for ( Inst i : Inst.values() ) {
      i.act();
    }
  }

  public static void main(String args[]) {
    try {
      new Test().test();
    } catch (Throwable t) {
      t.printStackTrace(System.err);
    }
  }

}