- d->cycle += 1;
- instruction_decode_(d->ram, d->pc, &opcode, &b, &b_data, &a, &a_data, &instr_len);
- d->pc += instr_len;
- TRACE("++ SKIPPED %x words", instr_len);
+ dcpu16_cycle_inc(vm, 1);
+ } else {
+ vm->skip_ = 0;
+ }
+ }
+
+ /* if we're currently servicing interrupts */
+ if (vm->interrupts_deferred_ == 0) {
+ /* and there are interrupts to be serviced */
+ if (vm->interrupts_head_ != vm->interrupts_tail_) {
+ DCPU16_WORD message;
+ message = interrupt_dequeue_(vm);
+
+ TRACE("%s>> %s interrupt IA:0x%04x message:0x%04x",
+ __func__,
+ vm->reg[DCPU16_REG_IA] ? "servicing" : "ignoring",
+ vm->reg[DCPU16_REG_IA],
+ message);
+ if (vm->reg[DCPU16_REG_IA]) {
+ /* then service the next interrupt */
+ vm->interrupts_deferred_ = 1;
+ vm->ram[--vm->reg[DCPU16_REG_SP]] = vm->reg[DCPU16_REG_PC];
+ vm->ram[--vm->reg[DCPU16_REG_SP]] = vm->reg[DCPU16_REG_A];
+ vm->reg[DCPU16_REG_PC] = vm->reg[DCPU16_REG_IA];
+ vm->reg[DCPU16_REG_A] = message;
+ }