Пример #1
0
/*
 * Brings the kernel a swift halt displaying a 
 * message AND CPU registers as an added bonus
 * @param format    The format of the message to display
 */
void panic_cpu(struct regs *r, const char *format, ...)
{
    release_all_locks();
    va_list argp;
    va_start(argp, format);
    display_message(format, argp);
    va_end(argp);
    display_registers(r);
    shut_it_down_charlie_brown();
}
Пример #2
0
void SAM(C64 *the_c64)
{
	bool done = false;
	char c;

	TheCPU = the_c64->TheCPU;
	TheCPU1541 = the_c64->TheCPU1541;
	TheVIC = the_c64->TheVIC;
	TheSID = the_c64->TheSID;
	TheCIA1 = the_c64->TheCIA1;
	TheCIA2 = the_c64->TheCIA2;

	// Get CPU registers and current memory configuration
	TheCPU->GetState(&R64);
	TheCPU->ExtConfig = (~R64.ddr | R64.pr) & 7;
	TheCPU1541->GetState(&R1541);

#ifdef __riscos__
	Wimp_CommandWindow((int)"SAM");
#endif

#ifdef AMIGA
	if (!(fin = fout = ferr = fopen("CON:0/0/640/480/SAM", "w+")))
		return;
#else
	fin = stdin;
	fout = stdout;
	ferr = stdout;
#endif

	access_1541 = false;
	address = R64.pc;

	fprintf(ferr, "\n *** SAM - Simple Assembler and Monitor ***\n ***         Press 'h' for help         ***\n\n");
	init_abort();
	display_registers();

	while (!done) {
		if (access_1541)
			fprintf(ferr, "1541> ");
		else
			fprintf(ferr, "C64> ");
		fflush(ferr);
		read_line();
		while ((c = get_char()) == ' ') ;

		switch (c) {
			case 'a':		// Assemble
				get_token();
				assemble();
				break;

			case 'b':		// Binary dump
				get_token();
				binary_dump();
				break;

			case 'c':		// Compare
				get_token();
				compare();
				break;

			case 'd':		// Disassemble
				get_token();
				disassemble();
				break;

			case 'e':       // Interrupt vectors
				int_vectors();
				break;

			case 'f':		// Fill
				get_token();
				fill();
				break;

			case 'h':		// Help
				help();
				break;

			case 'i':		// ASCII dump
				get_token();
				ascii_dump();
				break;

			case 'k':		// Memory configuration
				get_token();
				mem_config();
				break;

			case 'l':		// Load data
				get_token();
				load_data();
				break;

			case 'm':		// Memory dump
				get_token();
				memory_dump();
				break;

			case 'n':		// Screen code dump
				get_token();
				screen_dump();
				break;

			case 'o':		// Redirect output
				get_token();
				redir_output();
				break;

			case 'p':		// Sprite dump
				get_token();
				sprite_dump();
				break;

			case 'r':		// Registers
				get_reg_token();
				registers();
				break;

			case 's':		// Save data
				get_token();
				save_data();
				break;

			case 't':		// Transfer
				get_token();
				transfer();
				break;

			case 'v':		// View machine state
				view_state();
				break;

			case 'x':		// Exit
				done = true;
				break;

			case ':':		// Change memory
				get_token();
				modify();
				break;

			case '1':		// Switch to 1541 mode
				access_1541 = true;
				break;

			case '6':		// Switch to C64 mode
				access_1541 = false;
				break;

			case '?':		// Compute expression
				get_token();
				print_expr();
				break;

			case '\n':		// Blank line
				break;

			default:		// Unknown command
				error("Unknown command");
				break;
		}
	}

	exit_abort();

#ifdef AMIGA
	fclose(fin);
#endif
	if (fout != ferr)
		fclose(fout);

#ifdef __riscos__
	Wimp_CommandWindow(-1);
#endif

	// Set CPU registers
	TheCPU->SetState(&R64);
	TheCPU1541->SetState(&R1541);
}
Пример #3
0
static void registers(void)
{
	enum Token the_reg;
	uint16 value;

	if (the_token != T_END)
		switch (the_reg = the_token) {
			case T_A:
			case T_X:
			case T_Y:
			case T_PC:
			case T_SP:
			case T_DR:
			case T_PR:
				get_token();
				if (!expression(&value))
					return;

				switch (the_reg) {
					case T_A:
						if (access_1541)
							R1541.a = value;
						else
							R64.a = value;
						break;
					case T_X:
						if (access_1541)
							R1541.x = value;
						else
							R64.x = value;
						break;
					case T_Y:
						if (access_1541)
							R1541.y = value;
						else
							R64.y = value;
						break;
					case T_PC:
						if (access_1541)
							R1541.pc = value;
						else
							R64.pc = value;
						break;
					case T_SP:
						if (access_1541)
							R1541.sp = (value & 0xff) | 0x0100;
						else
							R64.sp = (value & 0xff) | 0x0100;
						break;
					case T_DR:
						if (!access_1541)
							R64.ddr = value;
						break;
					case T_PR:
						if (!access_1541)
							R64.pr = value;
						break;
					default:
						break;
				}
				break;

			default:
				return;
		}

	display_registers();
}
Пример #4
0
/*
 *  表示コマンド
 */
static UW
display_command(B *command)
{
	INT    point=0;
	B      cmd=0;
	T_RTST rtst;
	UB     b;
	UH     h;
	UW     w, value1, value2;
	int    no, count;
	char   tstate[TSTATE_LEN];

	count = sizeof(mon_display) / sizeof(struct SUBCOMMAND_TABLE);
	if(command[point]){
		for(no = 0 ; no < count ; no++){
			if(compare_word(mon_display[no].subcommand, command, 0)){
				skip_word(command, &point);
				cmd = mon_display[no].type;
				break;
			}
		}
	}
	switch(cmd){
	default:						/* デフォルト */
		cmd = mon_datatype;
	case MONDISPLAY_BYTE:			/* バイト単位メモリ表示 */
	case MONDISPLAY_HALF:			/* ハーフ単位メモリ表示 */
	case MONDISPLAY_WORD:			/* ワード単位メモリ表示 */
		value2 = 128;
		if(!get_value(command, &point, &value1, HEX_BASE))
			value1 = mon_address;
		value1 = MonAlignAddress(value1);
		if(command[point] == '+'){
			point++;
			if(!get_value(command, &point, &value2, HEX_BASE))
				value2 = 128;
		}
		else{
			if(!get_value(command, &point, &value2, HEX_BASE))
				value2 = value1 + 128;
			value2 -= value1;
		}
		mon_datatype = cmd;
		while((W)value2 > 0){
			printf("%08lx  ", (long)value1);
			for(no = 0 ; no < 16 ; no += mon_datatype){
				if(no == 8)
					putchar(' ');
				switch(mon_datatype){
				case DATA_HALF:
					if(MemoryRead(value1+no, &h, 2) == 0)
						h = -1;
					printf("%04x  ", h);
					break;
				case DATA_WORD:
					if(MemoryRead(value1+no, &w, 4) == 0)
						w = -1;
					printf("%08lx    ", (long)w);
					break;
				default:
					if(MemoryRead(value1+no, &b, 1) == 0)
						b = -1;
					printf("%02x ", b);
					break;
				}
			}
			if(getMemoryType(value1+no, 0) == MEMORY_AREA){
				for(no = 0 ; no < 16 ; no++){
					if(MemoryRead(value1+no, &b, 1)){
						if(b < ' ' || b >= 0xE0)
							b = '.';
						else if(b >= 127 && b < 0xA0)
							b = '.';
					}
					else
						b = '.';
					putchar(b);
				}
			}
			putchar('\n');
			value1 += 16;
			value2 -= 16;
			tslp_tsk(50);
			if(monitor_break())
				value2 = 0;
		}
		mon_address = value1;
		break;
	case MONDISPLAY_TASK:			/* タスク状態表示 */
		printf("cur id  pri state      pc       stack    inistack inisize\n");
		for(no = 0 ; no < tmax_tskid ; no++){
			ref_tst(no+TMIN_TSKID, &rtst);
			if(current_tskid == (no+TMIN_TSKID))
				printf(" * ");
			else
				printf("   ");
			if(MONTASK == (no+TMIN_TSKID))
				printf(" mon");
			else
				printf(" %03d", no+TMIN_TSKID);
			value1 = get_taskstate(rtst.tskstat);
			for(count = 0 ; count < TSTATE_LEN-1 ; count++){
				if((tstate[count] = task_state[value1][count]) == 0)
					tstate[count] = ' ';
			}
			tstate[count] = 0;
			printf(" %3d %s", rtst.tskpri, (VP_INT)tstate);
			if(rtst.tskstat == TTS_RUN)
				printf("         ");
			else
				printf(" %08lx", (unsigned long)rtst.tskpc);
			printf(" %08lx %08lx %5ld\n", (unsigned long)rtst.tsksp, (unsigned long)rtst.inistk, (unsigned long)rtst.inistksz);
		}
		putchar('\n');
		break;
	case MONDISPLAY_REG:			/* レジスタの表示 */
		if(current_tskid != MONTASK)
			display_registers(current_tskid);
		break;
	}
	return 0;
}
Пример #5
0
int callback_emu (
		  struct lws *wsi,
		  //enum lws_callback_reasons reason,
		  enum lws_callback_reasons reason,
		  void *user, void *in, size_t len)
{
  Cpu *cpu = emu->cpu;
  Port_1 *p1 = emu->cpu->p1;
  Debugger *deb = emu->debugger;

  switch (reason) {
    case LWS_CALLBACK_ESTABLISHED: {
      puts("connection established");
      
      // Flip ready flag for the emulator to begin
      deb->web_server_ready = true;

      // get the ball rolling
      //libwebsocket_callback_on_writable(this, wsi);
      lws_callback_on_writable(wsi);
      
      break;
    }
      
    case LWS_CALLBACK_SERVER_WRITEABLE: {
      if ( !packet_queue_empty(emu) ) {
	  Packet p = packet_dequeue(emu);
	  
	  void *msg = p.message;
	  size_t msg_len = p.length;
	  uint8_t op = p.opcode;
	
	  //printf("[%s] of len %u, opcode: %u\n\n",
	  //(char *)msg, (unsigned int)msg_len, op);
	
	  // Leave room for websock header/trailer & opcode
	  size_t pack_len = msg_len + sizeof(op)
	    + LWS_SEND_BUFFER_PRE_PADDING 
	    + LWS_SEND_BUFFER_POST_PADDING;
	
	  void *packet = malloc(pack_len);
	
	  // Zero out our packet
	  memset( (packet + LWS_SEND_BUFFER_PRE_PADDING), 0, 
		  msg_len + sizeof(op) );

	  // Place opcode into packet
	  *((uint8_t *)(packet + LWS_SEND_BUFFER_PRE_PADDING)) = op;
	
	  // Place message into packet
	  memcpy( (packet + LWS_SEND_BUFFER_PRE_PADDING + sizeof(op)),
		  (const void *)p.message, msg_len);

	  /*
	  int i;
	  for (i = 0;i < pack_len;i++){
	    printf( "%02X (%c) | ", *((uint8_t *)(packet+i)),
		    *((char *)(packet+i)) );
	  }
	  puts("\n");
	  */

	  lws_write(wsi, packet+LWS_SEND_BUFFER_PRE_PADDING, 
			     msg_len + sizeof(op), 
			     LWS_WRITE_BINARY);
	  
	  free(p.message);
	  free(packet);
      }

      static bool p1_0_on = false;
      static bool p1_1_on = false;
      static bool p1_2_on = false;
      static bool p1_3_on = false;
      static bool p1_4_on = false;
      static bool p1_5_on = false;
      static bool p1_6_on = false;
      static bool p1_7_on = false;
      
      // P1.0 ON/OFF
      if (p1->DIR_0 == OUT) {
	if (p1->OUT_0 == HIGH) {
	  if (p1_0_on == false) {
	    send_control(emu, P1_0_ON_PACKET, NULL, 0);
	    p1_0_on = true;
	  }
	}
	else if (p1->OUT_0 == LOW) {
	  if (p1_0_on == true) {
	    send_control(emu, P1_0_OFF_PACKET, NULL, 0);
	    p1_0_on = false;
	  }
	}
      }

      // P1.1 ON/OFF
      if (p1->DIR_1 == OUT) {
	if (p1->OUT_1 == HIGH) {	  
	  if (p1_1_on == false) {
	    send_control(emu, P1_1_ON_PACKET, NULL, 0);
	    p1_1_on = true;
	  }
	}
	else if (p1->OUT_1 == LOW) {
	  if (p1_1_on == true) {
	    send_control(emu, P1_1_OFF_PACKET, NULL, 0);
	    p1_1_on = false;
	  }
	}
      }

      // P1.2 ON/OFF
      if (p1->DIR_2 == OUT) {
	if (p1->OUT_2 == HIGH) {	  
	  if (p1_2_on == false) {
	    send_control(emu, P1_2_ON_PACKET, NULL, 0);
	    p1_2_on = true;
	  }
	}
	else if (p1->OUT_2 == LOW) {
	  if (p1_2_on == true) {
	    send_control(emu, P1_2_OFF_PACKET, NULL, 0);
	    p1_2_on = false;
	  }
	}
      }

      // P1.3 ON/OFF
      if (p1->DIR_3 == OUT) {
	if (p1->OUT_3 == HIGH) {	  
	  if (p1_3_on == false) {
	    send_control(emu, P1_3_ON_PACKET, NULL, 0);
	    p1_3_on = true;
	  }
	}
	else if (p1->OUT_3 == LOW) {
	  if (p1_3_on == true) {
	    send_control(emu, P1_3_OFF_PACKET, NULL, 0);
	    p1_3_on = false;
	  }
	}
      }

      // P1.4 ON/OFF
      if (p1->DIR_4 == OUT) {
	if (p1->OUT_4 == HIGH) {	  
	  if (p1_4_on == false) {
	    send_control(emu, P1_4_ON_PACKET, NULL, 0);
	    p1_4_on = true;
	  }
	}
	else if (p1->OUT_4 == LOW) {
	  if (p1_4_on == true) {
	    send_control(emu, P1_4_OFF_PACKET, NULL, 0);
	    p1_4_on = false;
	  }
	}
      }

      // P1.5 ON/OFF
      if (p1->DIR_5 == OUT) {
	if (p1->OUT_5 == HIGH) {	  
	  if (p1_5_on == false) {
	    send_control(emu, P1_5_ON_PACKET, NULL, 0);
	    p1_5_on = true;
	  }
	}
	else if (p1->OUT_5 == LOW) {
	  if (p1_5_on == true) {
	    send_control(emu, P1_5_OFF_PACKET, NULL, 0);
	    p1_5_on = false;
	  }
	}
      }
      
      // P1.6 ON/OFF
      if (p1->DIR_6 == OUT) {
	if (p1->OUT_6 == HIGH) {	  
	  if (p1_6_on == false) {
	    send_control(emu, P1_6_ON_PACKET, NULL, 0);
	    p1_6_on = true;
	  }
	}
	else if (p1->OUT_6 == LOW) {
	  if (p1_6_on == true) {
	    send_control(emu, P1_6_OFF_PACKET, NULL, 0);
	    p1_6_on = false;
	  }
	}
      }

      // P1.7 ON/OFF
      if (p1->DIR_7 == OUT) {
	if (p1->OUT_7 == HIGH) {	  
	  if (p1_7_on == false) {
	    send_control(emu, P1_7_ON_PACKET, NULL, 0);
	    p1_7_on = true;
	  }
	}
	else if (p1->OUT_7 == LOW) {
	  if (p1_7_on == true) {
	    send_control(emu, P1_7_OFF_PACKET, NULL, 0);
	    p1_7_on = false;
	  }
	}
      }      

      lws_callback_on_writable( wsi);
      break;
    }

    case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: {
      puts("Connection Error");
      break;
    }

    case LWS_CALLBACK_CLOSED: {
      puts("Connection Closed");
      exit(0);
      break;
    }

    case LWS_CALLBACK_CLIENT_WRITEABLE: {
      puts("cli writable");
      break;
    }

    case LWS_CALLBACK_RECEIVE: {
      static FILE *fp = NULL;
      static bool upload_in_progress = false;
      static uint32_t uploaded_bytes, file_size;

      char *buf = (char *)in;      
      
      if (upload_in_progress) { // Continue transaction of upload
	int i;
	for (i = 0;i < len;i++){	     
	  fwrite(&buf[i], 1, 1, fp);
	  uploaded_bytes++;

	  if (uploaded_bytes >= file_size) {
	    puts("met bytes");
	    fclose(fp);
	    system("msp430-objcopy -O binary tmp.elf tmp.bin");

	    deb->web_firmware_uploaded = true;
	    upload_in_progress = false;
	    return 0;
	  }
	}
	
	return 0;
      }
      
      unsigned char opcode = buf[0];
      printf("opcode: %02X\n", *(uint8_t*)in);
      
      switch (opcode) {
        case 0x00: { // Upload File
	   uint8_t byte1 = *((uint8_t *)(in+1));
	   uint8_t byte2 = *((uint8_t *)(in+2));
	   uint8_t byte3 = *((uint8_t *)(in+3));
	   uint8_t byte4 = *((uint8_t *)(in+4));

	   file_size = 0;
	   file_size = byte1; file_size <<= 3*8;
	   file_size |= ((0x00000000 | byte2) << 2*8);
	   file_size |= ((0x00000000 | byte3) << 1*8);
	   file_size |= ((0x00000000 | byte4));

	   printf("got in with file_size %u, but got len %d\n", 
		  (unsigned int)file_size, (unsigned int)len);	   

	   if (file_size >= 40000) {
	     exit(1);
	     deb->quit = true;
	   }

	   upload_in_progress = true;
	   uploaded_bytes = 0;
	   fp = fopen("tmp.elf", "wb");

	   // Get Any Bytes that are in with this packet
	   int i;
	   for (i = 5;i < len;i++){	     
	     fwrite(&buf[i], 1, 1, fp);
	     uploaded_bytes++;

	     if (uploaded_bytes >= file_size) {
	       puts("met bytes");
	       fclose(fp);
	       system("msp430-objcopy -O binary tmp.elf tmp.bin");

	       deb->web_firmware_uploaded = true;
	       upload_in_progress = false;
	       return 0;
	     }
	   }

	   break;
	 }

         case 0x01: { // PLAY
	   printf("Got play\n");
	   cpu->running = true;
	   deb->debug_mode = false;
	   update_register_display(emu);

	   return 0;
	 }
      
         case 0x02: { // PAUSE
	   printf("Got pause\n");

	   if (cpu->running) {
	     cpu->running = false;
	     deb->debug_mode = true;

	     // display first round of registers
	     display_registers(emu);
	     disassemble(emu, cpu->pc, 1);
	     update_register_display(emu);
	   }
	   
	   return 0;
	 }

         case 0x03: { // SERIAL DATA
	   if (len > 1000) exit(1);

	   lent = len - 1;
	   data = (uint8_t *) (in + 1);
	   
	   pthread_t t;
	   if( pthread_create(&t, NULL, thrd, (void *)cpu->usci ) ) {
	     fprintf(stderr, "Error creating thread\n");                    
	   }
	   
	   //printf("Got serial data %s ... %d bytes long\n", 
	   //(char *)(in + 1), (unsigned int)len - 1);
	   
	   return 0;
	 }

         case 0x04: { // Console Input Data
	   if (len > 1000) exit(1);

	   buf = buf + 1;	   
	   printf("%s\n", buf);

	   if (!cpu->running && deb->debug_mode) {
	     exec_cmd(emu, buf, len);	  
	     update_register_display(emu);
	   }

	   return 0;
         }
      
         default: break;
      }
    }
  
  default: {
    break;
  }
}
    
  return 0;
}