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)|(xa: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 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;}