void ARMAssembler::epilog(uint32_t touched)
{
    touched &= LSAVED;
    if (touched) {
        // write prolog code
        uint32_t* pc = mPC;
        mPC = mPrologPC;
        STM(AL, FD, SP, 1, touched | LLR);
        mPC = pc;
        // write epilog code
        LDM(AL, FD, SP, 1, touched | LLR);
        BX(AL, LR);
    } else {   // heh, no registers to save!
        // write prolog code
        uint32_t* pc = mPC;
        mPC = mPrologPC;
        MOV(AL, 0, R0, R0); // NOP
        mPC = pc;
        // write epilog code
        BX(AL, LR);
    }
}
Beispiel #2
0
// Execute one instruction cycle
//
void one_instruction_cycle(CPU *cpu) {
    // If the CPU isn't running, say so and return.
    // If the pc is out of range, complain and stop running the CPU.
    //
  if ((*cpu).running==0){
    printf("The CPU is not running. \n");
    return;
  }

    // Get instruction and increment pc
    //
  int instr_loc = (*cpu).pc;  // Instruction's location (pc before increment)
  (*cpu).ir = (*cpu).mem[(*cpu).pc];
  (*cpu).pc++;



  // Making sure the instruction is 
  if ((*cpu).reg_R<0 || (*cpu).reg_R>NREG || (*cpu).addr_MM<0 || (*cpu).addr_MM>100 ) {
    printf("Error. The register or memory address given in the instruction is out of bounds.\n");
    return;
  }

  //Decode opcode into opcode, reg_r, addr_MM, and instruction sign
  (*cpu).opcode = abs((*cpu).mem[instr_loc] / 1000);
  (*cpu).reg_R = abs((*cpu).mem[instr_loc] / 100) % 10;
  (*cpu).addr_MM = abs((*cpu).mem[instr_loc] % 100);
  
  // In case first instruction stored in memory is a zero, we need to give it a sign of 0.     
  if((*cpu).mem[instr_loc] != 0) {
    (*cpu).instr_sign = (*cpu).mem[instr_loc] / abs((*cpu).mem[instr_loc]);
  } else{
    (*cpu).instr_sign=0;
  }


 
  // Echo instruction
  printf("At %02d instr %d %d %02d: ", instr_loc, (*cpu).opcode, (*cpu).reg_R, (*cpu).addr_MM);

    switch ((*cpu).opcode) {
	case 0: HALT(cpu); break;
	case 1: LD(cpu); break;
	case 2: ST(cpu); break;
	case 3: ADD(cpu); break;
	case 4: NEG(cpu); break;
	case 5: LDM(cpu); break;
	case 6: ADDM(cpu); break;
	case 7: BR(cpu); break;
	case 8: BRC(cpu); break;
	case 9:
	  switch ((*cpu).reg_R) {
	      case 0: GETC(cpu); break;
	      case 1: OUT(cpu); break;
	      case 2: PUTS(cpu); break;
	      case 3: dump_CPU(cpu); break;
	      case 4: dump_memory(cpu); break;
	      case 5: printf("Ignored"); break;
	      case 6: printf("Ignored"); break;
	      case 7: printf("Ignored"); break;
	      case 8: printf("Ignored"); break;
	      case 9: printf("Ignored"); break;
	  }
	  break;
        default: printf("Bad opcode!? %d\n", (*cpu).opcode);
    }


}