@macro op_branch(name, condition)
  void {class}::op_{name}() {
    rd = op_readpc();
    if({condition}) return;
    op_io();
    op_io();
    regs.pc += (int8_t)rd;
  }
@endmacro

@macro op_bitbranch(name, bit, condition)
  void {class}::op_{name}() {
    dp = op_readpc();
    sp = op_readdp(dp);
    rd = op_readpc();
    op_io();
    if((sp & {bit}) {condition} {bit}) return;
    op_io();
    op_io();
    regs.pc += (int8_t)rd;
  }
@endmacro

@macro op_cbne_dp()
  void {class}::op_cbne_dp() {
    dp = op_readpc();
    sp = op_readdp(dp);
    rd = op_readpc();
    op_io();
    if(regs.a == sp) return;
    op_io();
    op_io();
    regs.pc += (int8_t)rd;
  }
@endmacro

@macro op_cbne_dpx()
  void {class}::op_cbne_dpx() {
    dp = op_readpc();
    op_io();
    sp = op_readdp(dp + regs.x);
    rd = op_readpc();
    op_io();
    if(regs.a == sp) return;
    op_io();
    op_io();
    regs.pc += (int8_t)rd;   
  }
@endmacro

@macro op_dbnz_dp()
  void {class}::op_dbnz_dp() {
    dp = op_readpc();
    wr = op_readdp(dp);
    op_writedp(dp, --wr);
    rd = op_readpc();
    if(wr == 0) return;
    op_io();
    op_io();
    regs.pc += (int8_t)rd;
  }
@endmacro

@macro op_dbnz_y()
  void {class}::op_dbnz_y() {
    rd = op_readpc();
    op_io();
    regs.y--;
    op_io();
    if(regs.y == 0) return;
    op_io();
    op_io();
    regs.pc += (int8_t)rd;
  }
@endmacro

@macro op_jmp_addr()
  void {class}::op_jmp_addr() {
    rd  = op_readpc() << 0;
    rd |= op_readpc() << 8;
    regs.pc = rd;
  }
@endmacro

@macro op_jmp_iaddrx()
  void {class}::op_jmp_iaddrx() {
    dp  = op_readpc() << 0;
    dp |= op_readpc() << 8;
    op_io();
    dp += regs.x;
    rd  = op_readaddr(dp + 0) << 0;
    rd |= op_readaddr(dp + 1) << 8;
    regs.pc = rd;
  }
@endmacro

@macro op_call()
  void {class}::op_call() {
    rd  = op_readpc() << 0;
    rd |= op_readpc() << 8;
    op_io();
    op_io();
    op_io();
    op_writestack(regs.pc >> 8);
    op_writestack(regs.pc >> 0);
    regs.pc = rd;
  }
@endmacro

@macro op_pcall()
  void {class}::op_pcall() {
    rd = op_readpc();
    op_io();
    op_io();
    op_writestack(regs.pc >> 8);
    op_writestack(regs.pc >> 0);
    regs.pc = 0xff00 | rd;
  }
@endmacro

@macro op_tcall(bit)
  void {class}::op_tcall_{bit}() {
    dp  = 0xffde - ({bit} << 1);
    rd  = op_readaddr(dp + 0) << 0;
    rd |= op_readaddr(dp + 1) << 8;
    op_io();
    op_io();
    op_io();
    op_writestack(regs.pc >> 8);
    op_writestack(regs.pc >> 0);
    regs.pc = rd;
  }
@endmacro

@macro op_brk()
  void {class}::op_brk() {
    rd  = op_readaddr(0xffde) << 0;
    rd |= op_readaddr(0xffdf) << 8;
    op_io();
    op_io();
    op_writestack(regs.pc >> 8);
    op_writestack(regs.pc >> 0);
    op_writestack(regs.p);
    regs.pc = rd;
    regs.p.b = 1;
    regs.p.i = 0;
  }
@endmacro

@macro op_ret()
  void {class}::op_ret() {
    rd  = op_readstack() << 0;
    rd |= op_readstack() << 8;
    op_io();
    op_io();
    regs.pc = rd;
  }
@endmacro

@macro op_reti()
  void {class}::op_reti() {
    regs.p = op_readstack();
    rd  = op_readstack() << 0;
    rd |= op_readstack() << 8;
    op_io();
    op_io();
    regs.pc = rd;
  }
@endmacro

