📄 cmd_processing.c
字号:
/*
Open Source BDM - processing of commands received over USB
/* Prominent Notice-This software was modified from TBDML software - 12/05
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "MC68HC908JB16.h"
#include "bdm.h"
#include "cmd_processing.h"
#include "commands.h"
#include "version.h"
#include "usb.h"
#include "led.h"
extern char far __SEG_START_SSTACK[];
/* processes all commands received over USB */
/* the command is expected to be in command_buffer+1 */
/* returns number of bytes left in the buffer to be sent back as response */
unsigned char command_exec(void) {
led_state = LED_BLINK; /* blink the LED to indicate a command */
if (bdm_status.target_type==HC12) {
if (command_buffer[1]==CMD_GET_LAST_STATUS) {
/* need to process this special command before status of the last command is lost */
return(1);
} else {
command_buffer[0] = command_buffer[1]; /* assume the command will execute OK */
switch (command_buffer[1]) {
/* get HW & SW version */
case CMD_GET_VER:
*((unsigned int *)(command_buffer+1)) = VERSION;
return(3); /* return cmd + 2 bytes of version */
/* set target type */
case CMD_SET_TARGET:
bdm_status.target_type = command_buffer[2];
return(1); /* confirm reception by transmitting cmd number back */
/* try to connect to the target */
case CMD_CONNECT:
if (bdm12_connect()) {
command_buffer[0] = CMD_FAILED; /* cannot connect */
}
return(1);
/* reset */
case CMD_RESET:
if (bdm_reset(command_buffer[2])) {
command_buffer[0] = CMD_FAILED; /* reset line stuck */
}
return(1);
/* return status of BDM communication */
case CMD_GET_STATUS:
command_buffer[1]=0; /* intel LSB */
if (bdm_status.ackn==ACKN) command_buffer[1]|=0x01; /* target supports ACKN and the feature is enabled */
if (bdm_status.reset==RESET_DETECTED) {
command_buffer[1]|=0x02; /* the target was resently reset externaly */
if (RESET_IN==1) bdm_status.reset=NO_RESET_ACTIVITY; /* clear the flag if reset pin has gone high already */
}
if (bdm_status.speed==SPEED_USER_SUPPLIED) command_buffer[1]|=0x18; else /* do not blame me if it does not work... */
if (bdm_status.speed==SYNC_SUPPORTED) command_buffer[1]|=0x08; else /* SYNC feature used to detect speed */
if (bdm_status.speed==SPEED_GUESSED) command_buffer[1]|=0x10; /* speed guessed by trial & error */
command_buffer[2]=0; /* intel MSB */
return(2);
/* read BDM byte */
case CMD_READ_BD:
BDM12_CMD_BDREADB((unsigned int)256*command_buffer[3]+command_buffer[2],command_buffer+1);
return(2);
/* write BDM byte */
case CMD_WRITE_BD:
BDM12_CMD_BDWRITEB((unsigned int)256*command_buffer[3]+command_buffer[2],command_buffer[4]);
return(1);
/* stop the target */
case CMD_HALT:
BDM_CMD_BACKGROUND();
return(1);
/* set comm speed to user supplied value */
case CMD_SET_SPEED1:
{
unsigned char bdm_sts;
bdm_status.sync_length=(unsigned int)(256*command_buffer[3]+command_buffer[2]); /* save the speed */
if (bdm_rx_tx_select()) {
command_buffer[0] = CMD_FAILED; /* no Rx or Tx routine for this speed */
bdm_status.speed = NO_INFO; /* connection cannot be established at this speed */
bdm_status.ackn = WAIT; /* clear indication of ACKN feature */
return(1);
}
bdm_status.speed = SPEED_USER_SUPPLIED; /* user told us */
bdm_ackn_init(); /* try the ACKN feature */
BDM12_CMD_BDREADB(BDM12_STS_ADDR,&bdm_sts);
if ((bdm_sts&0x80)==0) BDM12_CMD_BDWRITEB(BDM12_STS_ADDR,0x80|bdm_sts); /* if BDM not enabled yet, enable it so it can be made active */
return(1);
}
/* Read current speed */
case CMD_READ_SPEED1:
command_buffer[2] = (bdm_status.sync_length)>>8; /* store speed in little endian */
command_buffer[1] = (bdm_status.sync_length)&0xff;
return(3);
/* Start code execution */
case CMD_GO1:
BDM_CMD_GO();
return(1);
/* Step over 1 instruction */
case CMD_STEP1:
BDM_CMD_TRACE1();
return(1);
/* read byte */
case CMD_READ_8:
BDM12_CMD_READB((unsigned int)256*command_buffer[3]+command_buffer[2],command_buffer+1);
return(2);
/* read word */
case CMD_READ_16:
BDM12_CMD_READW((unsigned int)256*command_buffer[3]+command_buffer[2],command_buffer+2);
command_buffer[1] = command_buffer[3]; /* swap bytes around for little endian */
return(3);
/* read registers */
case CMD_READ_REGS:
BDM12_CMD_READ_PC(command_buffer+2);
command_buffer[1] = command_buffer[3]; /* swap bytes around for little endian */
BDM12_CMD_READ_SP(command_buffer+4);
command_buffer[3] = command_buffer[5]; /* swap bytes around for little endian */
BDM12_CMD_READ_X(command_buffer+6);
command_buffer[5] = command_buffer[7]; /* swap bytes around for little endian */
BDM12_CMD_READ_Y(command_buffer+8);
command_buffer[7] = command_buffer[9]; /* swap bytes around for little endian */
BDM12_CMD_READ_D(command_buffer+10);
command_buffer[9] = command_buffer[11]; /* swap bytes around for little endian */
BDM12_CMD_BDREADW(BDM12_CCR_ADDR,command_buffer+11); /* CCR is in little endian format already */
return(13);
/* read block of data from memory */
case CMD_READ_BLOCK1:
{
/* NOTE: This command returns block of BYTES, endianism does not matter here!!! */
unsigned char count = command_buffer[4];
unsigned char count_orig = command_buffer[4];
unsigned int addr = (unsigned int)256*command_buffer[3]+command_buffer[2];
unsigned char *data_ptr = command_buffer+1;
if (count>MAX_DATA_SIZE) {
command_buffer[0] = CMD_FAILED; /* requested block is too long to fit into the buffer */
return(1);
}
if (addr&0x0001) {
/* start address is odd, fetch the first byte separately */
BDM12_CMD_READB(addr,data_ptr);
addr++;
data_ptr++;
count--;
}
while(count&0xfe) {
/* while there are at least 2 bytes to fetch */
BDM12_CMD_READW(addr,data_ptr); /* fetch a word */
addr+=2; /* increment address */
data_ptr+=2; /* increment pointer */
count-=2; /* decrement count */
}
if (count) {
/* there is one extra byte to read at the end of the block */
BDM12_CMD_READB(addr,data_ptr);
}
return(count_orig+1);
}
/* write byte */
case CMD_WRITE_8:
BDM12_CMD_WRITEB((unsigned int)256*command_buffer[3]+command_buffer[2],command_buffer[4]);
return(1);
/* write word */
case CMD_WRITE_16:
BDM12_CMD_WRITEW((unsigned int)256*command_buffer[3]+command_buffer[2],(unsigned int)256*command_buffer[5]+command_buffer[4]);
return(1);
/* write block of bytes to memory */
case CMD_WRITE_BLOCK1:
{
unsigned char count = command_buffer[4];
unsigned int addr = (unsigned int)256*command_buffer[3]+command_buffer[2];
unsigned char *data_ptr = command_buffer+5;
if (addr&0x0001) {
/* start address is odd, write the first byte separately */
BDM12_CMD_WRITEB(addr,*data_ptr);
addr++;
data_ptr++;
count--;
}
while(count&0xfe) {
/* while there are at least 2 bytes to fetch */
BDM12_CMD_WRITEW(addr,*((unsigned int*)data_ptr)); /* write a word */
addr+=2; /* increment address */
data_ptr+=2; /* increment pointer */
count-=2; /* decrement count */
}
if (count) {
/* there is one extra byte to write at the end of the block */
BDM12_CMD_WRITEB(addr,*data_ptr);
}
return(1);
}
/* write to PC */
case CMD_WRITE_REG_PC:
BDM12_CMD_WRITE_PC((unsigned int)256*command_buffer[3]+command_buffer[2]);
return(1);
/* write to SP */
case CMD_WRITE_REG_SP:
BDM12_CMD_WRITE_SP((unsigned int)256*command_buffer[3]+command_buffer[2]);
return(1);
/* write to IX */
case CMD_WRITE_REG_X:
BDM12_CMD_WRITE_X((unsigned int)256*command_buffer[3]+command_buffer[2]);
return(1);
/* write to IY */
case CMD_WRITE_REG_Y:
BDM12_CMD_WRITE_Y((unsigned int)256*command_buffer[3]+command_buffer[2]);
return(1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -