Example #1
0
void dumpMem1(Cpu_t *cpu)
{
  SYSTEMOUT("dump mem1:");
  uint16_t n;
  for(n=0; n<0x50;n++)SYSTEMOUTHEX(" ",cpu->M[0][n]);
  SYSTEMOUT(" ");
}
Example #2
0
void executeVm(Cpu_t *cpu)
{
  uint16_t tmp;
  uint16_t mode;
  uint16_t instr,k;
  //SYSTEMOUTHEX("\npc:",cpu->Pc);
  tmp=readMemory(cpu,IMM);
  //SYSTEMOUTHEX(" instr code:",tmp);
  //showCpu(cpu);
  //SYSTEMOUTHEX("pc:",cpu->Pc);
  mode=tmp&03000;
  instr=tmp&0777;

  switch(instr)
  {
    // ALU instructions
    // two word instructions
    // instruction with addressing mode, operand
    //#define NOP2   00000 // A->A nop with 2 instructions
    case NOP2:{
      DISASM("NOP2");
      INCPC(cpu);
    }break;
    //#define MINUS  00006 // A-M-1 -> A
    case MINUS:{
      DISASM("MINUS");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->A-=tmp;
      cpu->A--;
      if(cpu->flags&(1<<AF_FLAG))cpu->A++;
      if(cpu->A>0777)cpu->flags|=(1<<AF_FLAG);
      else cpu->flags&=~(1<<AF_FLAG);
      cpu->A&=0777;
    }break;
    //#define PLUS   00011 // A+M -> A
    case PLUS:{
      DISASM("PLUS");
      INCPC(cpu);
      //SYSTEMOUTHEX("@:",cpu->Pc);
      tmp=readMemory(cpu,mode);
      //SYSTEMOUTHEX("plus:",tmp);
      cpu->A+=tmp;
      if(cpu->flags&(1<<AF_FLAG))cpu->A++;
      if(cpu->A>0777)cpu->flags|=(1<<AF_FLAG);
      else cpu->flags&=~(1<<AF_FLAG);
      cpu->A&=0777;
    }break;
    //#define DOUBLE 00014 // A*2 -> A, operand not used
    case DOUBLE:{
      DISASM("DOUBLE");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->A=2*tmp;
      //if(cpu->flags&(1<<AF_FLAG))cpu->A++;
      if(cpu->A>0777)cpu->flags|=(1<<AF_FLAG);
      else cpu->flags&=~(1<<AF_FLAG);
      cpu->A&=0777;
    }break;
    //#define DEC    00017 // A-1 -> A, operand not used
    case DEC:{
      DISASM("DEC");
      INCPC(cpu);
      //tmp=readMemory(cpu,mode);
      cpu->A--;
      //if(cpu->flags&(1<<AF_FLAG))cpu->A++;
      //if(cpu->A>0777)cpu->flags|=(1<<AF_FLAG);
      //else cpu->flags&=~(1<<AF_FLAG);
      cpu->A&=0777;
    }break;
    //#define INV    00020 // NOT A -> A, operand not used
    case INV:{
      DISASM("INV");
      INCPC(cpu);
      cpu->A=~cpu->A;
      cpu->A&=0777;
    }break;
    //#define NOR    00021 // A NOR M -> A
    case NOR:{
      DISASM("NOR");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->A=~(cpu->A|tmp);
      cpu->A&=0777;
    }break;
    //#define ZERO   00023 // 0 -> A -> A
    case ZERO:{
      DISASM("ZERO");
      INCPC(cpu);
      cpu->A=0;
    }break;
    //#define NAND   00024 // A NAND M -> A
    case NAND:{
      DISASM("NAND");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->A=~(cpu->A&tmp);
      cpu->A&=0777;
    }break;
    //#define INVM   00025 // NOT M -> A
    case INVM:{
      DISASM("INVM");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->A=~tmp;
      cpu->A&=0777;
    }break;
    //#define EXOR   00026 // A EXOR M -> A
    case EXOR:{
      DISASM("EXOR");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->A=(cpu->A^tmp);
      cpu->A&=0777;
    }break;
    //#define EXNOR  00031 // A EXNOR M -> A
    case EXNOR:{
      DISASM("EXNOR");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->A=~(cpu->A^tmp);
      cpu->A&=0777;
    }break;
    //#define AND    00033 // A and M -> A
    case AND:{
      DISASM("AND");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->A=(cpu->A&tmp);
      cpu->A&=0777;
    }break;
    //#define ONES   00034 // 0777->A set all ones
    case ONES:{
      DISASM("ZERO");
      INCPC(cpu);
      cpu->A=0777;
    }break;
    //#define OR     00036 // A or M -> A
    case OR:{
      DISASM("OR");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->A=(cpu->A|tmp);
      cpu->A&=0777;
    }break;
    //******************************************************
    // stack instructions
    //******************************************************
    //#define PLPC   00600 // pull PC ( return )
    case PLPC:{
      DISASM("PLPC (return)");
      cpu->Pc=pop(cpu)-1;
    }break;
    //#define PLP    00601 // pull P
    case PLP:{
      DISASM("PLP ( display )");
      cpu->display=pop(cpu)-1;
    }break;
    //#define PLIO   00602 // pull I/O
    case PLIO:{
      DISASM("PLIO (outport)");
      cpu->outport=pop(cpu)-1;
    }break;
    //#define PLA    00603 // pull A
    case PLA:{
      DISASM("PLA");
      cpu->A=pop(cpu)-1;
    }break;
    //#define PHPC   00604 // push PC
    case PHPC:{
      DISASM("PHPC");
      push(cpu,cpu->Pc); // warning: check if original T3 pushes next address
    }break;
    //#define PHP    00614 // push P
    case PHP:{
      DISASM("PHP (keys)");
      push(cpu,cpu->keys);
    }break;
    //#define PHIO   00624 // push I/O
    case PHIO:{
      DISASM("PHIO (outport)");
      push(cpu,cpu->outport);
    }break;
    //#define PHA    00634 // push A
    case PHA:{
      DISASM("PHA");
      push(cpu,cpu->A);
    }break;
    //******************************************************
    // register memory transfer instructions
    //******************************************************
    //#define STPC   00100 // PC -> M
    case STPC:{
      DISASM("STPC");
      INCPC(cpu);
      writeMemory(cpu,mode,cpu->Pc);
    }break;
    //#define STP    00110 // P -> M
    case STP:{
      DISASM("STP");
      INCPC(cpu);
      writeMemory(cpu,mode,cpu->keys);
    }break;
    //#define STIO   00120 // I/O -> M
    case STIO:{
      DISASM("STIO");
      INCPC(cpu);
      writeMemory(cpu,mode,cpu->inport);
    }break;
    //#define STA    00130 // A -> M
    case STA:{
      DISASM("STA");
      INCPC(cpu);
      writeMemory(cpu,mode,cpu->A);
    }break;
    //#define LDPC   00104 // M -> PC
    case LDPC:{
      DISASM("LDA");
      INCPC(cpu);
      cpu->A=readMemory(cpu,mode);
    }break;
    //#define LDP    00105 // M -> P
    case LDP:{
      DISASM("LDP");
      INCPC(cpu);
      cpu->display=readMemory(cpu,mode);
    }break;
    //#define LDIO   00106 // M -> I/O
    case LDIO:{
      DISASM("LDP");
      INCPC(cpu);
      cpu->outport=readMemory(cpu,mode);
    }break;
    //#define LDA    00107 // M -> A
    case LDA:{
      DISASM("LDA");
      INCPC(cpu);
      cpu->A=readMemory(cpu,mode);
    }break;
    // compare instructions
    //******************************************************
    // compare instruction
    //******************************************************
    //#define CMP    00200 // A-M -> FLG
    case CMP:{
      DISASM("CMP");
      INCPC(cpu);
      tmp=readMemory(cpu,mode);
      cpu->flags&=~((1<<EQ_FLAG)|(1<<GT_FLAG)|(1<<SM_FLAG)|(1<<MSB_FLAG));
      //#define EQ_FLAG      0  // A = OPR
      if(tmp==cpu->A)cpu->flags|=(1<<EQ_FLAG);

      //printf("a:%x  dest:%x\n",cpu->A,tmp);
      //#define GT_FLAG      1  // A > OPR
      if(tmp>cpu->A)cpu->flags|=(1<<GT_FLAG);
      //#define SM_FLAG      2  // A < OPR
      if(tmp<cpu->A)cpu->flags|=(1<<SM_FLAG);
      //#define ALU_FLAG     3  //
      //#define MSB_FLAG     4  // MSB of A
      if(cpu->A&0400)cpu->flags|=(1<<MSB_FLAG);
    }break;
    //******************************************************
    // machine control instructions
    //******************************************************
    //#define RST    00400 // 0001->PC
    case RST:{
      DISASM("RST");
      cpu->Pc=1;
    }break;
    //#define STOP   00401 // stop
    case STOP:{
      DISASM("STOP");
      cpu->Pc--;
    }break;
    //#define RSD    00402 // reset display
    case RSD:{
      DISASM("RSD");
      cpu->display=0;
    }break;
    //#define SHIB   00403 // select high bank
    case SHIB:{
      DISASM("select high bank");
      cpu->bank=1;
    }break;
    //#define SLOB   00404 // select low bank
    case SLOB:{
      DISASM("select low bank");
      cpu->bank=0;
    }break;
    //#define RSSP   00405 // 0->SP, reset stack pointer
    case RSSP:{
      DISASM("RSSP");
      cpu->Sp=0;
    }break;
    //#define RSA    00406 // 0->ACCU, reset accumulator
    case RSA:{
      DISASM("RSA");
      cpu->A=0;
    }break;
    //#define STB    00407 // strobe ?
    case STB:{
      DISASM("strobe?");
    }break;
    //SAF    00410 // set accu flag ( AF_FLAG )
    case SAF:{
      DISASM("SAF");
      cpu->flags|=(1<<AF_FLAG);
    }break;
    //#define CAF    00411 // clear accu flag ( AF_FLAG )
    case CAF:{
      DISASM("CAF");
      cpu->flags&=~(1<<AF_FLAG);
    }break;
    //#define SSF    00412 // set shift flag ( SF_FLAG )
    case SSF:{
      DISASM("SSF");
      cpu->flags|=(1<<SF_FLAG);
    }break;
    //#define CSF    00413 // clear shift flag ( SF_FLAG )
    case CSF:{
      DISASM("CSF");
      cpu->flags&=~(1<<SF_FLAG);
    }break;
    //#define NOP1   00414 // one word nop
    case NOP1:{
      DISASM("NOP1");
    }break;
    //******************************************************
    // register register transfer instructions
    //******************************************************
    //#define TPCP   00501 // PC -> P // PC -> display
    case TPCP:{
      DISASM("TPCP");
      cpu->display=cpu->Pc;
    }break;
    //#define TPCIO  00502 // PC -> IO ( outport )
    case TPCIO:{
      DISASM("TPCIO");
      cpu->outport=cpu->Pc;
    }break;
    //#define TPCA   00503 // PC -> A
    case TPCA:{
      DISASM("TPCA");
      cpu->A=cpu->Pc;
    }break;
    //#define TPPC   00510 // (keys) P -> PC
    case TPPC:{
      DISASM("TPPC (keys)");
      cpu->Pc=cpu->keys;
    }break;
    //#define TPP    00511 // P -> P read keyboard, write display
    case TPP:{
      DISASM("TPP (keys->display)");
      cpu->display=cpu->keys;
    }break;
    //#define TPIO   00512 // P -> IO
    case TPIO:{
      DISASM("TPIO (keys->outport)");
      cpu->outport=cpu->keys;
    }break;
    //#define TPA    00513 // P -> A // keys -> A
    case TPA:{
      DISASM("TPIO (keys->outport)");
      cpu->A=cpu->keys;
    }break;
    //#define TIOPC  00520 // IO->PC
    case TIOPC:{
      DISASM("TIOPC (inport->pc)");
      cpu->Pc=cpu->inport;
    }break;
    //#define TIOP   00521 // IO->P
    case TIOP:{
      DISASM("TIOP (inport->display)");
      cpu->display=cpu->inport;
    }break;
    //#define TIOA   00523 // IO->A
    case TIOA:{
      DISASM("TIOA");
      cpu->A=cpu->inport;
    }break;
    //#define TAPC   00530 // A->PC ( variable jump )
    case TAPC:{
      DISASM("TAPC (jmp(A))");
      cpu->Pc=cpu->A;
    }break;
    //#define TAP    00531 // A->P store A in display
    case TAP:{
      DISASM("TAP");
      cpu->display=cpu->A;
    }break;
    //#define TAIO   00532 // A->IO store A in outport
    case TAIO:{
      DISASM("TAIO");
      cpu->outport=cpu->A;
    }break;

    //******************************************************
    // masked functions
    //******************************************************
    default:{
      tmp=instr&JMPMASK;
      uint8_t flags;
      flags=instr&FLAGMASK;
      //ERROR("instr", tmp);
      SYSTEMOUTHEX("flag selector",flags);
      SYSTEMOUTHEX("      cpu.flags",cpu->flags);
SYSTEMOUTCR;
      switch(tmp)
      {
      //******************************************************
      // program flow instructions
      //******************************************************
        case JMPS:{
          DISASM("JMPS");
          INCPC(cpu);
          if(cpu->flags&(1<<flags))
            {
              DISASM("jump");
              cpu->Pc=readMemory(cpu,mode)-1;
            }
        }break;
        case JMPR:{
          DISASM("JMPR");
          INCPC(cpu);
          if(!(cpu->flags&(1<<flags)))
          {
            DISASM("jump");
            cpu->Pc=readMemory(cpu,mode)-1;
          }
        }break;
        case GSBS:{
          DISASM("GSBS");
          INCPC(cpu);
          if(cpu->flags&(1<<flags))
          {
            DISASM(" (call)");
            push(cpu,cpu->Pc+1);
            cpu->Pc=readMemory(cpu,mode)-1;
          }
        }break;
        case GSBR:{
          DISASM("GSBR");
          INCPC(cpu);
          if(!(cpu->flags&(1<<flags)))
          {
            DISASM(" (call)");
            push(cpu,cpu->Pc+1);
            cpu->Pc=readMemory(cpu,mode)-1;
            //dumpMem1(cpu);
          }
        }break;

        default:
        {
          //******************************************************
          // shift instructions
          //******************************************************
          tmp=instr&SHIFTMASK;
          uint8_t shift=instr&07;
          switch(tmp)
          {
            //#define ROL 00700 // rotate left n bits
            case ROL:{
              tmp=cpu->A;
              tmp=tmp<<shift;
              tmp|=cpu->A>>(13-shift);
              if(tmp&010000)cpu->flags|=(1<<SF_FLAG);
              else cpu->flags&=~(1<<SF_FLAG);
              cpu->A=tmp&0777;
            }break;
            //#define ROR 00710 // rotate right n bits
            case ROR:{
              tmp=cpu->A;
              tmp=tmp>>shift;
              tmp|=cpu->A<<(13-shift);
              if(tmp&010000)cpu->flags|=(1<<SF_FLAG);
              else cpu->flags&=~(1<<SF_FLAG);
              cpu->A=tmp&0777;
            }break;
            //#define SFL 00720 // shift left n bits
            case SFL:{
              tmp=cpu->A;
              tmp=tmp<<shift;
              cpu->A=tmp&0777;
              if(tmp&010000)cpu->flags|=(1<<SF_FLAG);
              else cpu->flags&=~(1<<SF_FLAG);
            }break;
            //#define SFR 00730 // shift right n bits
            case SFR:{
              tmp=cpu->A;
              tmp=tmp>>shift;
              cpu->A=tmp&0777;
              if((cpu->A)>>(shift-1)&1)cpu->flags|=(1<<SF_FLAG);
              else cpu->flags&=~(1<<SF_FLAG);
            }break;
            default:
            {
              ERROR("error: unknown instruction",instr);
              simulatorReset(cpu);
              cpu->Pc--;
            }break;
          }
        }
      }
    }break;
  }
Example #3
0
void executeVm(Cpu_t *cpu)
{
	uint8_t temp;
	uint8_t command;
	//SYSTEMOUTHEX("adr",cpu->Pc);
	//SYSTEMOUTHEX("flag",cpu->flag);
	command=cpu->M[cpu->Pc];
	cpu->Pc++;
	switch(command)
	{
		// KA 	K->Ar 	 0, 1 	The pressed key from the hex keypad is saved to the A register.
		// If a key is not pressed, the Flag is set to 1, otherwise it is 0.
		case KA:{
		  DISASM("KA   ");
		  if(KEYHIT())
          {
            cpu->M[AR]=GETKEY();
            cpu->flag=0;
            SYSTEMOUTHEX("Key:",cpu->M[AR]);
          }else {
            SYSTEMOUT("nokey");
            cpu->flag=1;
          }
		}break;
		// AO 	Ar->Op 		1 	The 7-segment readout displays the value currently contained in the A register.
		case AO:{
			DISASM("AO   ");
			//show7Segment(cpu->M[AR]);
			DISPLAYOUTHEX(cpu->M[AR]);
			 //PRINT7SEGMENT(x);
			cpu->flag=1;
		}break;
		// CH 	Ar<=>Br
        // Yr<=>Zr 	1 	Exchange the contents of the A and B registers, and the Y and Z registers.
		case CH:{
			DISASM("CH   ");

			temp=cpu->M[AR];
			cpu->M[AR]=cpu->M[BR];
			cpu->M[BR]=temp;
			temp=cpu->M[YR];
			cpu->M[YR]=cpu->M[ZR];
			cpu->M[ZR]=temp;
			cpu->flag=1;
		}break;
		// CY 	Ar<=>Yr 	1 	Exchange the contents of the A and Y registers.
		case CY:{
			DISASM("CY   ");

			temp=cpu->M[AR];
			cpu->M[AR]=cpu->M[YR];
			cpu->M[YR]=temp;
			cpu->flag=1;
		}break;
		// AM 	Ar->M 		1 	Write the contents of the A register to data memory (memory address is 50 + Y register).
		case AM:{
			DISASM("AM   ");

			cpu->M[((cpu->M[YR])&0xF)+M_OFFSET]=cpu->M[AR];
			cpu->flag=1;
		}break;
		// MA 	M->Ar 		1 	Write the contents of data memory (50 + Y register) to the A register.
		case MA:{
			DISASM("MA   ");

			cpu->M[AR]=cpu->M[((cpu->M[YR])&0xF)+M_OFFSET];
			cpu->flag=1;
		}break;
		// M+ 	M+Ar->Ar 	0, 1 	Add the contents of data memory (50 + Y register) to the A register. If there is overflow, the Flag is set to 1, otherwise 0.
		case MPLUS:{
			DISASM("M+   ");

			cpu->M[AR]+=cpu->M[((cpu->M[YR])&0xF)+M_OFFSET];
			if(((cpu->M[AR])&0x10)!=0)cpu->flag=1;
			else cpu->flag=0;
			cpu->M[AR]&=0x0F;
		}break;
		// M- 	M-Ar->Ar 	0, 1 	Subtract the contents of data memory (50 + Y register) from the A register. If the result is negative, the Flag is set to 1, otherwise 0.
		case MMINUS:{
			DISASM("M-   ");

			cpu->M[AR]-=cpu->M[((cpu->M[YR])&0xF)+M_OFFSET];
			if(((cpu->M[AR])&0x10)!=0)cpu->flag=1;
			else cpu->flag=0;
			cpu->M[AR]&=0x0F;
		}break;
		// TIA [ ] 	[ ] -> Ar 	1 	Transfer immediate to the A register.
		case TIA:{
			DISASM("TIA  ");

			cpu->M[AR]=cpu->M[cpu->Pc];
			cpu->Pc++;
			cpu->flag=1;
		}break;
		// AIA [ ] 	Ar + [ ] -> Ar 	0, 1 	Add immediate to the A register. If there is overflow, the Flag is set to 1, otherwise 0.
		case AIA:{
			DISASM("AIA  ");

			cpu->M[AR]+=cpu->M[cpu->Pc];
			if(((cpu->M[AR])&0x10)!=0)cpu->flag=1;
			else cpu->flag=0;
			cpu->M[AR]&=0x0F;
			cpu->Pc++;
		}break;
		// TIY [ ] 	[ ] -> Yr 	1 	Transfer immediate to the Y register.
		case TIY:{
			DISASM("TIA  ");

			cpu->M[YR]=cpu->M[cpu->Pc];
			cpu->Pc++;
			cpu->flag=1;
		}break;
		// AIY [ ] 	Yr + [ ] -> Yr 	0, 1 	Add immediate to the Y register. If there is overflow, the Flag is set to 1, otherwise 0.
		case AIY:{
			DISASM("AIY  ");

			cpu->M[YR]+=cpu->M[cpu->Pc];
			if(((cpu->M[YR])&0x10)!=0)cpu->flag=1;
			else cpu->flag=0;
			cpu->M[YR]&=0x0F;
			cpu->Pc++;
		}break;
		// CIA [ ] 	Ar != [ ] ? 	0, 1 	Compare immediate to the A register. If equal, Flag reset to 0, otherwise set to 1.
		case CIA:{
			DISASM("CIA  ");

			if(cpu->M[AR]!=cpu->M[cpu->Pc])cpu->flag=0;
			else cpu->flag=1;
			cpu->Pc++;
		}break;
		// CIY [ ] 	Yr != [ ] ? 	0, 1 	Compare immediate to the Y register. If equal, Flag reset to 0, otherwise set to 1.
		case CIY:{
			DISASM("CIY  ");

			if(cpu->M[YR]!=cpu->M[cpu->Pc])cpu->flag=0;
			else cpu->flag=1;
			cpu->Pc++;
		}break;
		//JUMP [ ] [ ] 		1 	Jump to the immediate address if the Flag is 1, otherwise just increment the program counter.
		//The Flag is then set to 1. Note that this is an absolute address. That is, JUMP [0] [2] will change the address pointer to hex address 0x02.
		//You can jump both forward and backward in program space.
		case JUMP:{
			DISASM("JUMP ");

			if((cpu->flag)==1)
			{
				temp=cpu->M[cpu->Pc]<<4;
				cpu->Pc++;
				temp+=cpu->M[cpu->Pc]<<4;
				cpu->Pc=temp;
			}else{
				cpu->Pc++;
				cpu->flag=1;
			}
		}break;
		//      --- 	--- 	--- 	Extended code. See table below.
		case EXTENDED:{
			command=(cpu->M[cpu->Pc])|0xE0;
			SYSTEMOUTHEX("com:",command);
			cpu->Pc++;
			if(cpu->flag==1)switch(command)
			{
				case CAL_RSTO:{
					DISASM("CAL_RSTO  ");
					SYSTEMOUTCHAR(' ');
					//SYSTEMOUT("clear 7 seg");
				}break;
				case CAL_SETR:{
					DISASM("CAL_SETR  ");
					cpu->leds|=(1<<(cpu->M[YR]));
					SHOWLEDS(cpu->leds);
					//SYSTEMOUT("led on");
				}break;
				case CAL_RSTR:{
					DISASM("CAL_RSTR  ");
                    cpu->leds&=~(1<<(cpu->M[YR]));
                    SHOWLEDS(cpu->leds);
					//SYSTEMOUT("led off");
				}break;
				// 0xE4 // 	CAL CMPL 	1 	Complement the A register (1 <=> 0).
				case CAL_CMPL:{
					DISASM("CAL_CMPL  ");

					cpu->M[AR]=(~cpu->M[AR])&0x0F;
					cpu->flag=1;
				}break;
				//0xE5 // 	CAL CHNG 	1 	Swap the A/B/Y/Z registers with A'/B'/Y'/Z'
				case CAL_CHNG:{
					DISASM("CAL_CHNG  ");

					temp=cpu->M[AR];
					cpu->M[AR]=cpu->M[AR_];
					cpu->M[AR_]=temp;

					temp=cpu->M[BR];
					cpu->M[BR]=cpu->M[BR_];
					cpu->M[BR_]=temp;

					temp=cpu->M[YR];
					cpu->M[YR]=cpu->M[YR_];
					cpu->M[YR_]=temp;

					temp=cpu->M[ZR];
					cpu->M[ZR]=cpu->M[ZR_];
					cpu->M[ZR_]=temp;

					cpu->flag=1;

				}break;
				// 0xE6 //	CAL SIFT 	0, 1 	Shift the A register right 1 bit. If the starting value is even (bit 0 = 0), set the Flag to 1, otherwise 0.
				case CAL_SIFT:{
					DISASM("CAL_SIFT  ");

					if((cpu->M[AR])&1)cpu->flag=1;
					else cpu->flag=0;
					cpu->M[AR]=(~cpu->M[AR])>>1;
				}break;
				//0xE7 //	CAL ENDS 	1 	Play the End sound.
				case CAL_ENDS:{
					DISASM("CAL_ENDS  ");
					SOUND(NOTE_D6,80);
					SOUND(NOTE_E6,80);
					SOUND(NOTE_F6,80);
					SOUND(NOTE_G6,80);
					SOUND(NOTE_A6,80);
					SOUND(NOTE_B6,80);
				    //soundf(0);
					//SOUND(440,500);
					SYSTEMOUT("end sound");
					cpu->flag=1;
				}break;
				//0xE8 //	CAL ERRS 	1 	Play the Error sound.
				case CAL_ERRS:{
					DISASM("CAL_ERRS  ");
				    for(int n = 0; n < 6; n++)
				    {
				        SOUND(NOTE_G5,20);
				        SOUND(NOTE_A5,20);
				        SOUND(NOTE_B5,20);
				        SOUND(NOTE_C6,20);
				        SOUND(NOTE_D6,20);
				        SOUND(NOTE_E6,20);
				    }
					//SOUND(200,500);
					SYSTEMOUT("play error sound");
					cpu->flag=1;
				}break;
				//0xE9 //	CAL SHTS 	1 	Play a short "pi" sound.
				case CAL_SHTS:{
					DISASM("CAL_SHTS  ");
					SOUND(NOTE_C5,150);
					SYSTEMOUT("play short peep sound");
					cpu->flag=1;
				}break;
				//0xEA //	CAL LONS 	1 	Play a longer "pi-" sound.
				case CAL_LONS:{
					DISASM("CAL_LONS  ");
					SOUND(NOTE_C5,450);
					SYSTEMOUT("play longer peep sound");
					cpu->flag=1;
				}break;
				//0xEB //	CAL SUND 	1 	Play a note based on the value of the A register
				//(allowed values are 1 - E).
				case CAL_SUND:{

					DISASM("CAL_SUND  ");
					//SOUND(cpu->M[AR],500);
					gmcSound(cpu->M[AR],300);

					SYSTEMOUT("play A reg");
					cpu->flag=1;
				}break;
				//0xEC // 	CAL TIMR 	1
				//Pause for the time calculated by (value of A register +1) * 0.1 seconds.
				case CAL_TIMR:{
					DISASM("CAL_TIMR  ");

					showMatrix(((cpu->M[AR])*100+1));

					cpu->flag=1;
				}break;

				//0xED //	CAL DSPR 	1 	Set the 2-pin LEDs with the value from data memory. The data to display is as follows: the upper three bits come from memory address 5F (bits 0-2), and the lower four from memory address 5E (bits 0-3).
				case CAL_DSPR:{
					DISASM("CAL_DSPR  ");

					SYSTEMOUT("set LED");
					cpu->flag=1;
				}break;
				//0xEE // 	CAL DEM- 	1
				//Subtract the value of the A register from the value in data memory.
				//The new value is stored in data memory as a decimal.
				//Afterwards, the Y register is decremented by 1.
				case CAL_DEMMINUS:{
					DISASM("CAL_DEM-  ");

					//SYSTEMOUT("dem-");
					cpu->M[YR]=cpu->M[YR]-cpu->M[AR];
					cpu->M[YR]++;
					cpu->M[YR]&=0xF;
					cpu->flag=1;
				}break;

				//0xEF //	CAL DEM+ 	1
				//Add the value of the A register to the value in data memory.
				//The new value is stored in memory as a decimal.
				//If the result is overflow, data memory will be automatically adjusted.
				//Afterwards, the Y register is decremented.
				case CAL_DEMPLUS:{
					DISASM("CAL_DEM+  ");

					cpu->M[YR]=cpu->M[YR]+cpu->M[AR];
					cpu->M[YR]--;
					cpu->M[YR]&=0xF;
					cpu->flag=1;
				}break;
			}
		}break;

	}
}