📄 myvm.c
字号:
} while (!(ch > ' ' || feof(data) || *ps != running)); if (*ps == running) { if (feof(data)) *ps = nodata; else { switch (ch) { case '-': negative = true; readchar(data, &ch, ps); break; case '+': negative = false; readchar(data, &ch, ps); break; } if (!isxdigit(ch)) *ps = baddata; else { while (isxdigit(ch) && *ps == running) { if (hexdigit(ch) < base && num <= (maxint - hexdigit(ch)) / base) num = base * num + hexdigit(ch); else *ps = baddata; readchar(data, &ch, ps); } } } if (negative) num = -num; if (num > 0) return num % 256; else return (256 - abs(num) % 256) % 256; /* negtive is represented in 2's complement */ } return 0;}/* the core for running machine code in mem */void execute(MC_bytes initpc, FILE * data, FILE * results, bool tracing){ MC_bytes pcnow; /* to save the preceded value of PC while current opcode is been executed */ MC_bytes carry; /* to save carry bit in addition or subtraction operation */ MC_bytes number; cpu.z = false; cpu.p = false; cpu.c = false; /* cpu's flag register initialization */ cpu.a = 0; cpu.x = 0; cpu.sp = 0; /* initialization for sp */ cpu.bp = 0; /* initialization for bp */ cpu.pc = initpc; /* initialization for pc with initpc supplied by caller */ ps = running; /* initialization for cpu's running state */ /* the following loop demonstrates or simulates CPU'S behaviour, code fetching ->analyzing */ /* -> executing, in the process of instruction executing, until the HALT executed or */ /* runtime error occured */ do { cpu.ir = mem[cpu.pc]; /* fetch a opcode from the memory indicated by pc to ir */ pcnow = cpu.pc; /* to save the preceded value of PC */ increment(&cpu.pc); /* PC indicates the next opcode which will be executed */ if (tracing) trace(results, pcnow); /* if trace enable, output cpu's internal registers */ switch (cpu.ir) { /* which opcode is now in cpu.ir */ case MC_nop: break; /* nop, no operation, return directly without any operation */ case MC_clra: /* clear register A */ cpu.a = 0; break; case MC_clrc: /* clear carry bit */ cpu.c = false; break; case MC_clrx: /* clear index register X */ cpu.x = 0; break; case MC_cmc: /* complemented carry bit */ cpu.c = !cpu.c; break; case MC_inc: /* A=A+1, certain flag may be affected */ increment(&cpu.a); setflags(cpu.a); break; case MC_dec: /* A=A-1, certain flag may be affected */ decrement(&cpu.a); setflags(cpu.a); break; case MC_incx: /* X=X+1, certain flag may be affected */ increment(&cpu.x); setflags(cpu.x); break; case MC_decx: /* x=x-1, certain flag may be affected */ decrement(&cpu.x); setflags(cpu.x); break; case MC_tax: /* X=A */ cpu.x = cpu.a; break; case MC_ini: /* get number in decimal and send to A,certain flag may be affected */ cpu.a = getnumber(data, 10, &ps); setflags(cpu.a); break; case MC_inb: /* get number in binary and send to A,certain flag may be affected */ cpu.a = getnumber(data, 2, &ps); setflags(cpu.a); break; case MC_inh: /* get number in hexadecimal and send to A,certain flag may be affected */ cpu.a = getnumber(data, 16, &ps); setflags(cpu.a); break; case MC_ina: /* get ascii char and send to A,certain flag may be affected */ { char ascii; readchar(data, &ascii, &ps); if (feof(data)) ps = nodata; else { cpu.a = ascii; setflags(cpu.a); } } break; case MC_oti: /* output the content of register A in decimal */ if (cpu.a < 128) fprintf(results, "%d ", cpu.a); else fprintf(results, "%d ", cpu.a - 256); if (tracing) putc('\n', results); break; case MC_oth: /* output the content of register A in hexadecimal */ fprintf(results, "%02X ", cpu.a); if (tracing) putc('\n', results); break; case MC_otc: /* output the content of register A in unsigned decimal */ fprintf(results, "%d ", cpu.a); if (tracing) putc('\n', results); break; case MC_otb: /* output the content of register A in unsigned binary */ { int bits[8]; int loop; number = cpu.a; for (loop = 0; loop <= 7; loop++) { bits[loop] = number % 2; number /= 2; } for (loop = 7; loop >= 0; loop--) fprintf(results, "%d", bits[loop]); putc(' ', results); if (tracing) putc('\n', results); } break; case MC_ota: /* output the content of register A in ascii char */ putc(cpu.a, results); if (tracing) putc('\n', results); break; case MC_push: /* push A's content to stack: SP=SP-1,[SP]=A */ decrement(&cpu.sp); mem[cpu.sp] = cpu.a; break; case MC_pop: /* pop stack to A: A=[SP],SP=SP+1, certain flag may be affected */ cpu.a = mem[cpu.sp]; increment(&cpu.sp); setflags(cpu.a); break; case MC_shl: /* A's bit shift leftly in turn, MSB->C bit,certain flag may be affected */ cpu.c = (cpu.a * 2 > 255); cpu.a = cpu.a * 2 % 256; setflags(cpu.a); break; case MC_shr: /* A's bit shift rightly in turn,LSB->C bit ,certain flag may be affected */ cpu.c = cpu.a & 1; cpu.a /= 2; setflags(cpu.a); break; case MC_ret: /* return from callee,PC=[SP], SP=SP+1 */ cpu.pc = mem[cpu.sp]; increment(&cpu.sp); break; case MC_halt: /* halt MYVM */ ps = finished; break; case MC_lda: /* LDA B, A=[B], certain flag may be affected */ cpu.a = mem[mem[cpu.pc]]; increment(&cpu.pc); setflags(cpu.a); break; case MC_ldx: /* LDX B, A=[X+B] , certain flag may be affected */ cpu.a = mem[index()]; increment(&cpu.pc); setflags(cpu.a); break; case MC_ldi: /* LDI B,A=ImmB,certain flag may be affected */ cpu.a = mem[cpu.pc]; increment(&cpu.pc); setflags(cpu.a); break; case MC_lsp: /* LSP B, SP=[ImmB] */ cpu.sp = mem[mem[cpu.pc]]; increment(&cpu.pc); break; case MC_lspi: /* LSPI B,SP=ImmB */ cpu.sp = mem[cpu.pc]; increment(&cpu.pc); break; case MC_sta: /* STA B,[ImmB]=A */ mem[mem[cpu.pc]] = cpu.a; increment(&cpu.pc); break; case MC_stx: /* STX B, [X+B]=A */ mem[index()] = cpu.a; increment(&cpu.pc); break; case MC_add: /* ADD B, A=A+[ImmB],certain flag may be affected */ cpu.c = (cpu.a + mem[mem[cpu.pc]] > 255); cpu.a = (cpu.a + mem[mem[cpu.pc]]) % 256; /* result may be 0~255 */ increment(&cpu.pc); setflags(cpu.a); break; case MC_adx: /* ADX B, A=A+[X+ImmB],certain flag may be affected */ cpu.c = (cpu.a + mem[index()] > 255); cpu.a = (cpu.a + mem[index()]) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_adi: /* ADI B, A=A+ImmB, certain flag may be affected */ cpu.c = (cpu.a + mem[cpu.pc] > 255); cpu.a = (cpu.a + mem[cpu.pc]) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_adc: /* ADC B, A=A+C+[ImmB],certain flag may be affected */ carry = cpu.c; cpu.c = (cpu.a + mem[mem[cpu.pc]] + carry > 255); cpu.a = (cpu.a + mem[mem[cpu.pc]] + carry) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_acx: /* ACX B ,A=A+C+[X+ImmB],certain flag may be affected */ carry = cpu.c; cpu.c = (cpu.a + mem[index()] + carry > 255); cpu.a = (cpu.a + mem[index()] + carry) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_aci: /* ACI B, A=A+C+ImmB, certain flag may be affected */ carry = cpu.c; cpu.c = (cpu.a + mem[cpu.pc] + carry > 255); cpu.a = (cpu.a + mem[cpu.pc] + carry) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_sub: /* SUB B, A=A-[ImmB],certain flag may be affected */ cpu.c = (cpu.a < mem[mem[cpu.pc]]); cpu.a = (cpu.a - mem[mem[cpu.pc]] + 256) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_sbx: /* SBX B, A=A-[X+ImmB],certain flag may be affected */ cpu.c = (cpu.a < mem[index()]); cpu.a = (cpu.a - mem[index()] + 256) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_sbi: /* SBI B, A=A-ImmB, certain flag may be affected */ cpu.c = (cpu.a < mem[cpu.pc]); cpu.a = (cpu.a - mem[cpu.pc] + 256) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_sbc: /* SBC B, A=A-C-[ImmB],certain flag may be affected */ carry = cpu.c; cpu.c = (cpu.a < mem[mem[cpu.pc]] + carry); cpu.a = (cpu.a - mem[mem[cpu.pc]] - carry + 256) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_scx: /* SCX B, A=A-C-[X+ImmB],certain flag may be affected */ carry = cpu.c; cpu.c = (cpu.a < mem[index()] + carry); cpu.a = (cpu.a - mem[index()] - carry + 256) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_sci: /* SCI B, A=A-C-ImmB, certain flag may be affected */ carry = cpu.c; cpu.c = (cpu.a < mem[cpu.pc] + carry); cpu.a = (cpu.a - mem[cpu.pc] - carry + 256) % 256; increment(&cpu.pc); setflags(cpu.a); break; case MC_cmp: /* CMP B, compare A with [B] to affect certain flag */ cpu.c = (cpu.a < mem[mem[cpu.pc]]); setflags((cpu.a - mem[mem[cpu.pc]] + 256) % 256); increment(&cpu.pc); break; case MC_cpx: /* CPX B, compare A with [X+ImmB] to affect certain flag */ cpu.c = (cpu.a < mem[index()]); setflags((cpu.a - mem[index()] + 256) % 256); increment(&cpu.pc); break; case MC_cpi: /* CPI B, compare A with ImmB to affecte certain flag */ cpu.c = (cpu.a < mem[cpu.pc]); setflags((cpu.a - mem[cpu.pc] + 256) % 256); increment(&cpu.pc); break; case MC_ana: /* ANA B, A=A&[ImmB],bitwise and A with [ImmB] to affecte certain flag */ cpu.a &= mem[mem[cpu.pc]]; increment(&cpu.pc); setflags(cpu.a); cpu.c = false; break; case MC_anx: /* ANX B, A=A&[X+ImmB], bitwise and A with [X+ImmB] to affecte certain flag */ cpu.a &= mem[index()]; increment(&cpu.pc); setflags(cpu.a); cpu.c = false; break; case MC_ani: /* ANI B,A=A&ImmB bitwise and A with ImmB to affecte certain flag */ cpu.a &= mem[cpu.pc]; increment(&cpu.pc); setflags(cpu.a); cpu.c = false; break; case MC_ora: /* ORA B, A=A|[ImmB],bitwise and A with [ImmB] to affecte certain flag */ cpu.a |= mem[mem[cpu.pc]]; increment(&cpu.pc); setflags(cpu.a); cpu.c = false; break; case MC_orx: /* ORX B,A=A|[X+ImmB], bitwise or A with [X+ImmB] to affecte certain flag */ cpu.a |= mem[index()]; increment(&cpu.pc); setflags(cpu.a); cpu.c = false; break; case MC_ori: /* ORI B,A=A|ImmB ,bitwiae or A with ImmB to affect certain flag */ cpu.a |= mem[cpu.pc]; increment(&cpu.pc); setflags(cpu.a); cpu.c = false; break; case MC_jmp: /* JMP B, jump to address B unconditionally */ cpu.pc = mem[cpu.pc]; break; case MC_bze: /* BZE B, jmup to address B if Z=1, else goto next instruction */ if (cpu.z) cpu.pc = mem[cpu.pc]; else increment(&cpu.pc); break; case MC_bnz: /* BZE B, jmup to address B if Z=0, else goto next instruction */ if (!cpu.z) cpu.pc = mem[cpu.pc]; else increment(&cpu.pc); break; case MC_bpz: /* BPZ B, jump to address B if P=1(positive),else goto next instruction */ if (cpu.p) cpu.pc = mem[cpu.pc]; else increment(&cpu.pc); break; case MC_bng: /* BNG B, jump to address B if P=0(positive),else goto next instruction */ if (!cpu.p) cpu.pc = mem[cpu.pc]; else increment(&cpu.pc); break; case MC_bcs: /* BCS B, jump to address B if C=1(carried),else goto next instruction */ if (cpu.c) cpu.pc = mem[cpu.pc]; else increment(&cpu.pc); break; case MC_bcc: /* BCC B, jump to address B if C=0(not carried),else goto next instruction */ if (!cpu.c) cpu.pc = mem[cpu.pc]; else increment(&cpu.pc); break; case MC_jsr: /* JSR B, jump subRoutine,push retAddr,B->PC */ decrement(&cpu.sp); mem[cpu.sp] = (cpu.pc + 1) % 256; /* push return address */ cpu.pc = mem[cpu.pc]; break; case MC_tsp: /* TSP, Transfer SP to A, A=SP */ cpu.a = cpu.sp; setflags(cpu.a); break; case MC_lbpi: /* LBPI B,A=[BP+ImmB],Load A with [BP+ImmB] */ cpu.a = mem[cpu.bp + mem[cpu.pc]]; increment(&cpu.pc); setflags(cpu.a); break; case MC_fbpi: /* FBPI B, BP=ImmB ,Feed BP with ImmB */ cpu.bp = mem[cpu.pc]; increment(&cpu.pc); break; case MC_tbp: /* TBP, A=BP, Transfer BP to A */ cpu.a = cpu.bp; setflags(cpu.a); break; case MC_tsb: /* TSB, BP=SP, Transfer Sp to Bp */ cpu.bp = cpu.sp; break; case MC_tabp: /* TABP, BP=A, Transfer A to Bp */ cpu.bp = cpu.a; break; default: ps = badop; break; } } while (ps == running); if (ps != finished) runtime_error(results, pcnow);}void runvm(){ FILE *data, *results; char filename[20]; newsuffix(srcfile, "out", filename); results = fopen(filename, "a"); /* create a new file named filename */ execute(0 % 256, NULL, results, 0); /* do it! */ fclose(results); /* fclose(data); */}static void logo(){ printf("\nMYVM Virtual Machine Premiere, Version 0.11a \n"); printf("\tCopyright under GPL 2002,2003, Snallie@tom.com\n"); printf("\tA contribution dedicated to Snixos, 2004.6\n\n");}#ifdef _NATIVEmain(int argc, char *argv[]){ if (argc > 1) { initMC(); testas(argv[1]); }else { printf("Usage: myvm sourceFile\n"); }}#endif /* _NATIVE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -