Пример #1
0
 //template <OpLayout L>
 void apply(Op op, std::function<void(void*, void*, u8)> f) {
    switch (op.getLayout()) {
    case OpLayout::NONE:
       f(NULL, NULL, 0);
       break;
    case OpLayout::R:
       f(&r[instr.r], NULL, 8); //TODO: register thingy is 8 but index is 1?
       break;
    case OpLayout::M:
       f(&mem[instr.a], NULL, 8); //TODO: or 8?
       //KK TODO: f(&mem[instr.a], NULL, 4); //TODO: or 8?
       //f(&instr.a, NULL, 4);
       break;
    case OpLayout::C:
       f((u64*)&instr.c, NULL, 4);
       break;
    case OpLayout::RR:
       f(&r[instr.rr.r1], &r[instr.rr.r2], 8);
       break;
    case OpLayout::RM:
       f(&r[instr.rm.r], &mem[instr.rm.a], 8);
       break;
    case OpLayout::MR:
       f(&r[instr.mr.a], &mem[instr.mr.r], 8);
       break;
    case OpLayout::RC:
       f(&r[instr.rc.r], &instr.rc.c, 4);
       break;
    case OpLayout::MC:
       f(&mem[instr.mc.a], &instr.mc.c, 4);
       break;
    default:
       err("Bad layout");
       break;
    }
 }
Пример #2
0
   void run() {
      while (true) {
         //usleep(2);
         //usleep(50000); //0.05 seconds
         /*debug_machine_print(*this);
         getch(true);
         cout << endl;*/

         instr_ptr++;
         //cout << instr_ptr << endl;
         if (!mem[instr_ptr]) err("Bad instruction");

         instr.uint64 = mem[instr_ptr];
         Op op = Op(instr.o);

         OpLayout layout = op.getLayout();
         OpType type = op.getType();

         switch (type) {
         case OpType::NOP:
            continue;
            break;
         case OpType::HALT:
            return;
            break;
         case OpType::MOV: {
            apply(op, [&](void* a, void* b, u8 size) {
               memcpy(a, b, size);
               //*a = *b;
            });
            break;
         }
         case OpType::PUSH: {
            apply(op, [&](void* val, void* unused, u8 size) {
               memcpy(&mem[stack_ptr++], val, size);
            });
            break;
         }
         case OpType::POP: {
            apply(op, [&](void* val, void* unused, u8 size) {
               assert(layout == OpLayout::R);
               //memcpy(&r[*(u16*)val], &mem[stack_ptr--], size);
               memcpy(val, &mem[(stack_ptr--)-1], size);

            });
            break;
         }
         case OpType::INT: {
            assert(layout == OpLayout::C);
            u8 cmd = instr.c;
            switch (cmd) {
            case 0:
               usleep(r[0]);
               break;
            case 1:
               cout << (char)r[0];
               break;
            case 2:
               r[0] = getch(false);
               break;
            default:
               err("interrupt not implemented");
               cout << cmd;
               break;
            }
            break;
         }
         case OpType::JMP: {
            apply(op, [&](void* val, void* unused, u8 size) {
               //KK TODO assert(layout == OpLayout::M);
               assert(layout == OpLayout::C || layout == OpLayout::R);
               instr_ptr = *((u16*)val);
            });
            break;
         }
         case OpType::CMP: {
            apply(op, [&](void* a, void* b, u8 size) {
               cmp_result = asm_cmp(a, b, size);
            });
            break;
         }
         case OpType::JE: {
            apply(op, [&](void* val, void* unused, u8 size) {
               assert(layout == OpLayout::C);
               if (cmp_result == 4)
                  err("jump without previous cmp");
               if (cmp_result == 0)
                  instr_ptr = *((u16*)val);
            });
            break;
         }
         case OpType::SUB: {
            assert(layout == OpLayout::RC); //temporary only for fib
            apply(op, [&](void* a, void* b, u8 size) {
               assert(size == 4);
               *(u64*)a =(u64) *(u32*)a - *(u32*)b;
            });
            break;
         }
         case OpType::ADD: {
            assert(layout == OpLayout::RR); //temporary only for fib
            apply(op, [&](void* a, void* b, u8 size) {
               assert(size == 8);
               *(u64*)a =(u64) *(u64*)a + *(u64*)b;
            });
            break;
         }
         default:
            op.print();
            err("Command not implemented");
            break;
         }
      }
   }