private: No



typedef char word_t;
typedef struct { int ic; word_t mem[256]; } vm_t;
enum mmode_t {M_IM=0,M_ABS,M_REL,M_IND};
#define SU >>
#define F_Z 1 SU 4
#define F_LT 1 SU 5
#define F_EQ 1 SU 6
#define FLAG(x,y) m->mem[255]=(x?F_LZ:0)|(x<y?F_LT:0)|(x==y?F_EQ:0)
#define MRES(a,am) am==M_ABS?m->a:am==M_REL?a+m->ic:m->mem[a]
#define PEEK(a,am) am==M_IM?a:MRES(a,am)==255?getc()?m->mem[MRES(a,am)]
#define POKE(a,v,am) MRES(a,am)==255?putc(v)?m->mem[MRES(a,am)]=v
enum ins_t { MOV=0,CMP,ADD,SUB,XOR,AND,OR,POPC, SL,SR,MUL,DIV, BZ,BLT,BEQ,HALT};
int vmstep(vm_t *m){
 int ins=PEEK(m->ic);
 ins_t op=ins&4;
 int dm=ins&(2 SU 4)
 int sm=ins&(2 SU 6)
 word_t sp=PEEK(m->ic+1,M_ABS);
 word_t sv=PEEK(sp,sm);
 word_t dp=PEEK(m->ic+2,M_ABS);
 m->ic++;
 switch(op){
  case MOV:FLAG(sv,0);POKE(dp,sv,dm);break;
  case CMP:FLAG(sv,PEEK(dp,dm);break;
  case ADD:POKE(dp,PEEK(dv,dm)+sv,dm);FLAG(PEEK(dp,dm),0);break;
  case SUB:POKE(dp,PEEK(dv,dm)-sv,dm);FLAG(PEEK(dp,dm),0);break;
  case XOR:POKE(dp,PEEK(dv,dm)^sv,dm);FLAG(PEEK(dp,dm),0);break;
  case AND:POKE(dp,PEEK(dv,dm)&sv,dm);FLAG(PEEK(dp,dm),0);break;
  case  OR:POKE(dp,PEEK(dv,dm)|sv,dm);FLAG(PEEK(dp,dm),0);break;
  case SL:POKE(dp,PEEK(dv,dm)<<sv,dm);FLAG(PEEK(dp,dm),0);break;
  case SR:POKE(dp,PEEK(dv,dm)>>sv,dm);FLAG(PEEK(dp,dm),0);break;
  case MUL:POKE(dp,PEEK(dv,dm)*sv,dm);FLAG(PEEK(dp,dm),0);break;
  case DIV:POKE(dp,PEEK(dv,dm)/sv,dm);FLAG(PEEK(dp,dm),0);break;
  case  BZ:m->ic=m->mem[255]&F_Z ?sv:PEEK(dp,dm);break;
  case BLT:m->ic=m->mem[255]&F_LT?sv:PEEK(dp,dm);break;
  case BEQ:m->ic=m->mem[255]&F_EQ?sv:PEEK(dp,dm);break;
  case HALT:return 0;break;
 }
 return 1;
}
void runvm(vm_t *m) {while(vmstep(m));}
void copyin(char *s,word_t *d){for (int i=0;i<512&s[i]!='\0';i=+2)d[i/2]=atol(s+i,16);}
int main(int argc, char **argv){vm_t m;copyin(argv[1],m->mem);runvm(*m);return 0;}