// Processes the instruction, calls printReg with correct params
void processInstr() {
	if (icode != 0) {
		numConsecutiveHalts = 0;
	}
	switch (icode) {
		case 0: 
			instr = "halt";
			
			// if invalid ifun, exit
			assertZeroiFunCode(ifun, icode_ifun);
			
			// set params
			setParams1ByteInstr();
			
			// increment number of consecutive halts
			numConsecutiveHalts++;
			
			break;
		case 1:
			instr = "nop";
			assertZeroiFunCode(ifun, icode_ifun);
			setParams1ByteInstr();
			
			break;
		case 2: 
			// get instr based on ifun
			switch (ifun) {
				case 0:
					instr = "rrmovq";
					break;
				case 1:
					instr = "cmovle";
					break;
				case 2:
					instr = "cmovl";	
					break;
				case 3:
					instr = "cmove";
					break;
				case 4:
					instr = "cmovne";
					break;
				case 5:
					instr = "cmovge";
					break;
				case 6:
					instr = "cmovg";
					break;
				default:
					// Invalid function code
					printf("Invalid function code %.2x at 0x%016llX\n",icode_ifun,PC);
					exit(0);
			}			
			setParams2ByteInstr();	
			
			break;
		case 3:
			instr = "irmovq";			
			assertZeroiFunCode(ifun, icode_ifun);
			setParams10ByteInstr();		
			
			break;
		case 4: 
			instr = "rmmovq";
			assertZeroiFunCode(ifun, icode_ifun);
			setParams10ByteInstr();
		
			break;
		case 5: 
			instr = "mrmovq";
			assertZeroiFunCode(ifun, icode_ifun);
			setParams10ByteInstr();

			break;
		case 6: 
			// get instr based on ifun
			switch (ifun) {
				case 0:
					instr = "addq";
					break;
				case 1:
					instr = "subq";
					break;
				case 2:
					instr = "andq";	
					break;
				case 3:
					instr = "xorq";
					break;
				case 4:
					instr = "mulq";
					break;
				case 5:
					instr = "divq";
					break;
				case 6:
					instr = "modq";
					break;
				default:
					// Invalid function code
					printf("Invalid function code %.2x at 0x%016llX\n",icode_ifun,PC);
					exit(0);
			}
			setParams2ByteInstr();

			break;
		case 7:
			switch (ifun) {
				case 0:
					instr = "jmp";
					break;
				case 1:
					instr = "jle";
					break;
				case 2:
					instr = "jl";
					break;
				case 3:
					instr = "je";
					break;
				case 4:
					instr = "jne";
					break;
				case 5:
					instr = "jge";
					break;
				case 6:
					instr = "jg";
					break;
				default:
					// Invalid function code
					printf("Invalid function code %.2x at 0x%016llX\n",icode_ifun,PC);
					exit(0);
			}
			setParams9ByteInstr();
		
			break;
		case 8: 
			instr = "call";
			assertZeroiFunCode(ifun, icode_ifun);
			setParams9ByteInstr();

			break;
		case 9:
			instr = "ret";
			assertZeroiFunCode(ifun, icode_ifun);
			setParams1ByteInstr();
			
			break;
		case 0xA: 
			instr = "pushq";
			assertZeroiFunCode(ifun, icode_ifun);
			setParams2ByteInstr();

			break;
		case 0xB: 
			instr = "popq";
			assertZeroiFunCode(ifun, icode_ifun);	
			setParams2ByteInstr();
			
			break;
		default:
			// icode not recognized. Print message and exit.
			printf("Invalid opcode %.2x at 0x%016llX", icode_ifun, PC);
			exit(0);
			break;
	}
	// handling case where insufficient bytes to complete instruction fetch
	if (notEnoughBytes) {
		printf("Memory access error at %.X, required %d bytes, read %d bytes.\n", PC, bytesToRead, numBytesCanRead);
		exit(0);
	}	
	// for halt instructions, do not print out more than 5 consecutive.
	if (icode != 0 || numConsecutiveHalts <= 5) {
		printReg(PC,icode,ifun,regsValid,rA,rB,valCValid,valC,b0,b1,b2,b3,b4,b5,b6,b7,valP,instr);
	}
	// set new PC
	PC = valP;
}
Esempio n. 2
0
// NOTE: loc points to 1st or 2nd opcode byte (if any)
void Ez80::disasmAddrMode(ULONG loc,unsigned int mode)
{
  //unsigned int dig=w->getHexDigits();
  //w->setHexDigits(4);
  switch(mode) {
      //
    case Ez80_NONE:
      DEBUG_OUT<<"    ;Ez80_NONE";
      break;
      //
    case Ez80_SPECIAL:
      DEBUG_OUT<<"    ;Ez80_SPECIAL";
      break;
      //
    case Ez80_ILLEGAL:
      DEBUG_OUT<<"    ;Ez80_ILLEGAL";
      break;
      //
    case Ez80_CONST:
      DEBUG_OUT<<"$?const?";
      DEBUG_OUT<<"    ;Ez80_CONST";
      break;
      //
    case Ez80_REGB:
      reg=map->read8(loc)&0x7;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<"    ;Ez80_REGB";
      break;
      //
    case Ez80_REGB2:
      reg=(map->read8(loc)>>3)&0x7;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<"    ;Ez80_REGB2";
      break;
      //
    case Ez80_REGW:
      reg=(map->read8(loc)>>4)&0x3;
      printReg(reg,Ez80_SIZE_WORD);
      DEBUG_OUT<<"    ;Ez80_REGW";
      break;
      //
    case Ez80_A_REGB:
      DEBUG_OUT<<"a,";
      reg=map->read8(loc)&0x7;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<"    ;Ez80_REGB";
      break;
      //
    case Ez80_REGB_REGB:
      reg2=(map->read8(loc)>>3)&0x7;
      printReg(reg2,Ez80_SIZE_BYTE);
      DEBUG_OUT<<",";
      reg=map->read8(loc)&0x7;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<"    ;Ez80_REGB_REGB";
      break;
      //
    case Ez80_REGW_REGW:
      reg2=(map->read8(loc)>>3)&0x7;
      printReg(reg2,Ez80_SIZE_WORD);
      DEBUG_OUT<<",";
      reg=(map->read8(loc)>>4)&0x3;
      printReg(reg,Ez80_SIZE_WORD);
      DEBUG_OUT<<"    ;Ez80_REGW_REGW";
      break;
      //
    case Ez80_REGB_BYTE:
      reg=(map->read8(loc)>>3)&0x7;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<",#$"<<(BYTE)map->read8(loc+1);
      DEBUG_OUT<<"    ;Ez80_REGB_BYTE";
      break;
      //
    case Ez80_REGW_WORD:
      reg=(map->read8(loc)>>4)&0x3;
      printReg(reg,Ez80_SIZE_WORD);
      DEBUG_OUT<<",#$"<<(UINT16)map->read16l(loc+1);
      DEBUG_OUT<<"    ;Ez80_REGW_WORD";
      break;
      //
    case Ez80_INDREGW:
      reg=(map->read8(loc)>>4)&0x3;
      DEBUG_OUT<<"(";
      printReg(reg,Ez80_SIZE_WORD);
      DEBUG_OUT<<")";
      DEBUG_OUT<<"    ;Ez80_INDREGW";
      break;
      //
    case Ez80_INDREGW_BYTE:
      reg=map->read8(loc)&0x3;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<",#$"<<(short)map->read8(loc+1);
      DEBUG_OUT<<"    ;Ez80_INDREGW_BYTE";
      break;
      //
    case Ez80_INDBYTE_REGB:
      reg=(map->read8(loc)>>4)&0x3;
      DEBUG_OUT<<"($"<<(short)map->read8(loc+1)<<"),";
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<"    ;Ez80_INDBYTE_REGB";
      break;
      //
    case Ez80_REGW_INDABS:
      reg=(map->read8(loc)>>4)&0x3;
      printReg(reg,Ez80_SIZE_WORD);
      DEBUG_OUT<<",($"<<map->read16l(loc+1)<<")";
      DEBUG_OUT<<"    ;Ez80_REGW_INDABS";
      break;
      //
    case Ez80_REGW_ABS:
      reg=(map->read8(loc)>>4)&0x3;
      printReg(reg,Ez80_SIZE_WORD);
      DEBUG_OUT<<",$"<<map->read16l(loc+1);
      DEBUG_OUT<<"    ;Ez80_REGW_ABS";
      break;
      //
    case Ez80_INDABS_REGW:
      DEBUG_OUT<<"($"<<map->read16l(loc+1)<<"),";
      reg=(map->read8(loc)>>4)&0x3;
      printReg(reg,Ez80_SIZE_WORD);
      DEBUG_OUT<<"    ;Ez80_INDABS_REGW";
      break;
      //
    case Ez80_INDABS_REGB:
      DEBUG_OUT<<"($"<<map->read16l(loc+1)<<"),";
      reg=(map->read8(loc)>>3)&0x7;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<"    ;Ez80_INDABS_REGB";
      break;
      //
    case Ez80_REGB_INDABS:
      reg=(map->read8(loc)>>3)&0x7;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<",($"<<map->read16l(loc+1)<<")";
      DEBUG_OUT<<"    ;Ez80_REGB_INDABS";
      break;
      //
    case Ez80_REGB_INDREGW:
      reg=(map->read8(loc)>>3)&0x7;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<",(hl)";
      DEBUG_OUT<<"    ;Ez80_REGB_INDREGW";
      break;
      //
    case Ez80_INDREGW_REGB:
      reg=map->read8(loc)&0x7;
      DEBUG_OUT<<"(hl),";
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<"    ;Ez80_INDREGW_REGB";
      break;
      //
    case Ez80_INDREGW_REGW:
      reg=(map->read8(loc)>>3)&0x7;
      DEBUG_OUT<<"(hl),";
      printReg(reg,Ez80_SIZE_WORD);
      DEBUG_OUT<<"    ;Ez80_INDREGW_REGW";
      break;
      //
    case Ez80_BYTE:
      DEBUG_OUT<<"#$"<<(short)map->read8(loc+1);
      DEBUG_OUT<<"    ;Ez80_BYTE";
      break;
      //
    case Ez80_REGB_INDBYTE:
      reg=(map->read8(loc)>>3)&0x7;
      printReg(reg,Ez80_SIZE_BYTE);
      DEBUG_OUT<<",($"<<(short)map->read8(loc+1)<<")";
      DEBUG_OUT<<"    ;Ez80_INDBYTE";
      break;
      //
    case Ez80_DJ_REL:
    case Ez80_J_REL:
      DEBUG_OUT<<"$"<<(short)map->read8(loc+1)<<"  ;"<<(UINT16)((SBYTE)map->read8(loc+1)+loc+2);
      DEBUG_OUT<<"    ;Ez80_J_REL";
      break;
      //
    case Ez80_ABS:
    case Ez80_JABS:
      DEBUG_OUT<<"$"<<map->read16l(loc+1);
      DEBUG_OUT<<"    ;Ez80_ABS";
      break;
      //
    case Ez80_JCC_REL:
      reg=(map->read8(loc)>>3)&0x3;
      printCondCode(reg);
      DEBUG_OUT<<",$"<<(short)map->read8(loc+1)<<"  ;";
      DEBUG_OUT<<(UINT16)((SBYTE)map->read8(loc+1)+loc+2);
      DEBUG_OUT<<"    ;Ez80_JCC_REL";
      break;
      //
    case Ez80_JCC_ABS:
      reg=(map->read8(loc)>>3)&0x7;
      printCondCode(reg);
      DEBUG_OUT<<",$"<<map->read16l(loc+1);
      DEBUG_OUT<<"    ;Ez80_JCC_ABS";
      break;
      //
    default:
      DEBUG_OUT<<"???";
      DEBUG_OUT<<"    ;Ez80_???";
      debugger("bad address mode in disasmAddrMode!");
      break;
  };
  //w->setHexDigits(dig);
}
Esempio n. 3
0
/*
* Main loop used to continuously ask for user input
*/
int mainloop(){

	//Local variables
	int mode = 0;
	char op_code[100];
	uint16_t instAddr;
	uint16_t topAddr;
	uint16_t baseAddr;
	char fileName[100];
	char run = 1;
	char in[100];
	regA.data = 0;
	regSTAT.data = 0;
	nibble currentInst;
	int tempAddress = 0;
	int instrRun = 0;
	struct timespec gettime_now;
	struct timespec newTime = {0, 0};
	long totalFirstTime;
	long totalSecondTime;
	long firstTime;
	long secondTime;
	long period = 200000;
	char step = 0;




	while(run){

		if(mode == USERMODE)
			printf("Input: ");
		fgets(in, 99, stdin);
		sscanf(in, "%s %hu %hu", op_code, &instAddr, &topAddr);

		//Process input
		if(!strcmp(op_code, "~q")){
			printf("Halting\n");
			run = 0;
		}
		else if(!strcmp(op_code, "~pm")){
			printMem(instAddr, topAddr);
		}
		else if(!strcmp(op_code, "~pr")){
			printReg();
		}
		else if(!strcmp(op_code, "~in")){
			printf("Enter file name, followed by an address to load at: ");
        	        scanf("%s %hu", fileName, &baseAddr);
			puts("WARNING, make sure the base address is set correctly when assembling file");
			while(getchar()!= '\n');
			if(readBin(fileName, baseAddr) == -1){
                        	printf("Entering User Input Mode");
   				mode = USERMODE;
			}
		}
		else if(!strcmp(op_code, "~run")){
			regPC = instAddr;
			instrRun = 0;
			regSTAT.data &= 0xD;
			mode = FILEMODE;
			step = 0;
		}
		else if(!strcmp(op_code, "~step")){
			if(instAddr != NULL)
			{
				regPC = instAddr;
				regSTAT.data &= 0xD;
			}
			instrRun = 0;
			mode = FILEMODE;
			step = 1;
		}
		else if(!strcmp(op_code, "~cp")){
                        printf("Enter period: ");
                        scanf("%li", &period);
                        while(getchar()!= '\n');
		}
		else if(!strcmp(op_code, "~rm")){
			freeMem();
			initMem();
		}
		else {
			if(mode == USERMODE)
				decode(op_code, instAddr);
		}

		if(mode == FILEMODE){
			if(step == 0)
			{
				puts("Program started...");
			}
			else if (step == 1)
			{
				puts("Stepping forward...");
			}

			//Runs while HLT is off
			while(!(regSTAT.data & 0x2)){

				//Start of file code

				//EXECUTE FIRST 4 BITS
				currentInst = readMem(regPC);

                                clock_gettime(CLOCK_REALTIME, &gettime_now);
                                firstTime = gettime_now.tv_nsec;
                                waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_CLR = 1<<CLKPIN;
								#endif
				
				clock_gettime(CLOCK_REALTIME, &gettime_now);
                                firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_SET = 1<<CLKPIN;
								#endif
				
				//EXECUTE SECOND 4 BITS
				instAddr = 0;
				tempAddress = 0;
				tempAddress = readMem(++regPC).data;
				instAddr |= (tempAddress << 12);

                                clock_gettime(CLOCK_REALTIME, &gettime_now);
				firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2);
								#ifdef RPI
                                GPIO_CLR = 1 <<CLKPIN;
								#endif
								
				clock_gettime(CLOCK_REALTIME, &gettime_now);
                                firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_SET = 1<<CLKPIN;
								#endif

				//EXECUTE THIRD 4 BITS
	                        tempAddress = readMem(++regPC).data;
       		                instAddr |= (tempAddress << 8);


                                clock_gettime(CLOCK_REALTIME, &gettime_now);
				firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_CLR = 1<<CLKPIN;
								#endif
								
				clock_gettime(CLOCK_REALTIME, &gettime_now);
                                firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_SET = 1<<CLKPIN;
								#endif
				//EXECUTE FOURTH 4 BITS
                        	tempAddress = readMem(++regPC).data;
                        	instAddr |= (tempAddress << 4);

                                clock_gettime(CLOCK_REALTIME, &gettime_now);
				firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2 );
				#ifdef RPI
				GPIO_CLR = 1 <<CLKPIN;
				#endif

				clock_gettime(CLOCK_REALTIME, &gettime_now);
                                firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_SET = 1<<CLKPIN;
								#endif
								
				//EXECUTE FIFTH 4 BITS
                      		tempAddress = readMem(++regPC).data;
	                        instAddr |= (tempAddress);
				regPC++;

                                clock_gettime(CLOCK_REALTIME, &gettime_now);
                                firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_CLR = 1<<CLKPIN;
								#endif
								
				clock_gettime(CLOCK_REALTIME, &gettime_now);
                                firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_SET = 1<<CLKPIN;
								#endif	
								
	                        if(currentInst.data == HLT)
        	                        decode("HLT", instAddr);
                	        else if(currentInst.data == LOD)
                        	        decode("LOD", instAddr);
	                        else if(currentInst.data == STR)
        	                       	decode("STR", instAddr);
                	        else if(currentInst.data == ADD)
                        	        decode("ADD", instAddr);
	                        else if(currentInst.data == NOP)
        	                        decode("NOP", instAddr);
                	        else if(currentInst.data == NND)
                        	        decode("NND", instAddr);
	                        else if(currentInst.data == CXA)
        	                       	decode("CXA", instAddr);
                	        else if(currentInst.data == JMP)
                        	        decode("JMP", instAddr);
	                        else
									#ifndef __MINGW32__
        	                        shutdown(UNKNOWNINSTRUCTIONERROR);
									#endif
									#ifdef __MINGW32__
									shutdown_vm4(UNKNOWNINSTRUCTIONERROR);
									#endif

                                clock_gettime(CLOCK_REALTIME, &gettime_now);
                                firstTime = gettime_now.tv_nsec;
                                waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_CLR = 1 <<CLKPIN;
								#endif
								
				clock_gettime(CLOCK_REALTIME, &gettime_now);
                                firstTime = gettime_now.tv_nsec;
				waitForPeriod(firstTime,gettime_now,period/2 );
								#ifdef RPI
                                GPIO_SET = 1<<CLKPIN;
								#endif

				if(step == 1)
				{
					break;
				}

			}
		if((regSTAT.data & 0x2) && step)
		{
			puts("Computer halted");
		}
		mode = USERMODE;
		if(step == 0)
		{
			puts("Program finished");
			printf("Instructions run %d\n", instrRun);
			#ifdef RPI
			GPIO_CLR = 1 << CLKPIN;
			#endif
		}
		}

	}

	return 1;
}