?? source.c
字號(hào):
/*
Program: revava - Atmel Dis-Assembler
File: Source.C, Copyright (C) 2001 Daniel J. Winker
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.
CHANGES:
14-Mar-2001, Dan Winker
Added op_code_addr. See Bug_0001 in CHANGES.
*/
#include <stdio.h>
#include <string.h>
#include "Avr.h"
#include "Error.h"
#include "Flash.h"
#include "Source.h"
#define FALSE 0
#define TRUE (!FALSE)
//#define DEBUG
char* m8_IO_register_name[] = {
"TWBR",
"TWSR",
"TWAR",
"TWDR",
"ADCL",
"ADCH",
"ADCSRA",
"ADMUX",
"ACSR ",
"UBRRL",
"UCSRB",
"UCSRA",
"UDR",
"SPCR",
"SPSR",
"SPDR",
"PIND",
"DDRD",
"PORTD",
"PINC",
"DDRC",
"PORTC",
"PINB",
"DDRB",
"PORTB",
"Reserved",
"Reserved",
"Reserved",
"EECR",
"EEDR",
"EEARL",
"EEARH",
"UBRRH",
"WDTCR",
"ASSR",
"OCR2",
"TCNT2",
"TCCR2",
"ICR1L",
"ICR1H",
"OCR1BL",
"OCR1BH",
"OCR1AL",
"OCR1AH",
"TCNT1L",
"TCNT1H",
"TCCR1B",
"TCCR1A",
"SFIOR",
"OSCCAL",
"TCNT0",
"TCCR0",
"MCUCSR",
"MCUCR",
"TWCR",
"SPMCR",
"TIFR",
"TIMSK",
"GIFR",
"GICR",
"Reserved",
"SPL",
"SPH",
"SREG"
};
TSourceOut::TSourceOut( const char* OutFile, TFlash* pFlash ){
TAvr Avr;
TAvr::TInstruction Instruction;
int Index;
int line_count;
FILE* pOutFile;
TSourceString* pSourceString_temp;
TSourceString* pSourceString_head;
TSourceString* pSourceString_tail;
int last_line_was_blank = FALSE;
int look_for_new_segment = TRUE;
int code_seg_num = 0;
unsigned short code_word;
unsigned short temp_short;
unsigned long temp_long;
int addr;
int op_code_addr;
int dest = 0;
int have_dest;
int high_byte_written;
int low_byte_written;
char temp_string[ 80 ]; // FIXME - Magic Number
char temp_string2[ 80 ]; // FIXME - Magic Number
char* pLastTab;
char* tabs;
prolog_head = NULL;
prolog_tail = NULL;
body_head = NULL;
body_tail = NULL;
if( 0 == strcmp( "stdout", OutFile ) ){
pOutFile = stdout;
} else {
pOutFile = fopen( OutFile, "w" );
}
if( NULL == pOutFile )
throw TFileError( "Cannot open file for writing:", OutFile );
// FIXME - This probably doesn't belong burried deep withing a function.
// This probably should be much more configurable.
//push_prolog( "#arch AT90S8515" );
push_prolog( "#include \"m8def.inc\" ");
//push_prolog( "#include \"avr.inc\"" );
for( addr = 0; addr < FLASH_SIZE; addr += 2 ){
// Sometimes addr will get bumped because of a double word
// instruction, but we still want to report the address of the
// first word of the instruction. op_code_addr is what is
// reported.
op_code_addr = addr;
code_word = pFlash->get_flash_word(
addr,
&high_byte_written,
&low_byte_written );
#ifdef DEBUG_1
printf( "DEBUG - SourceOut: ##############################\n" );
printf( "DEBUG - SourceOut: addr = %04X\n", addr );
printf( "DEBUG - SourceOut: code_word = %04X\n", code_word );
printf( "DEBUG - SourceOut: high_byte_written = %04X\n", high_byte_written );
printf( "DEBUG - SourceOut: low_byte_written = %04X\n", low_byte_written );
#endif
if( high_byte_written != low_byte_written ){
sprintf(
temp_string,
"TSourceOut: Word Address: %04X: high_byte_written != low_byte_written.",
addr );
throw TGenericError( temp_string );
}
if( high_byte_written ){
if( look_for_new_segment ){
#ifdef DEBUG
printf( "DEBUG - SourceOut: Need Org Statement For: %04X\n", addr );
#endif
//sprintf( temp_string, "\tseg abs=0x%X flash.code%d", addr, code_seg_num );
sprintf( temp_string, "\t.org 0x%X", addr/2);
push_body( "" );
push_body( temp_string );
push_body( "" );
last_line_was_blank = TRUE;
code_seg_num++;
look_for_new_segment = FALSE;
}
// First Time Through
pSourceString_head = NULL;
pSourceString_tail = NULL;
Index = 0;
while( 0 != ( Index = Avr.Word2Instruction(
&Instruction,
code_word,
Index ))){
#ifdef DEBUG
printf( "DEBUG - SourceOut: Index = %d\n", Index);
printf( "DEBUG - SourceOut: Addr:OpCode = %04X:%04X\n", addr, code_word );
printf( "DEBUG - SourceOut: Instruction.name = %s\n", Instruction.name );
printf( "DEBUG - SourceOut: Instruction.arg0_format = %c\n", Instruction.arg0_format );
printf( "DEBUG - SourceOut: Instruction.arg1_format = %c\n", Instruction.arg1_format );
printf( "DEBUG - SourceOut: Instruction.arg0_type = %d\n", Instruction.arg0_format );
printf( "DEBUG - SourceOut: Instruction.arg1_type = %d\n", Instruction.arg1_format );
printf( "DEBUG - SourceOut: Instruction.arg0 = %04X\n", Instruction.arg0 );
printf( "DEBUG - SourceOut: Instruction.arg1 = %04X\n", Instruction.arg1 );
#endif
have_dest = FALSE;
if( TAvr::ARG_longCall == Instruction.arg0_type ){
// These arg types are special because they also use the
// next word as part of the opcode.
// A really paranoid programmer would do a bounds check
// on addr here.
addr += 2;
temp_short = pFlash->get_flash_word(
addr,
&high_byte_written,
&low_byte_written );
if( !high_byte_written || !low_byte_written ){
sprintf(
temp_string,
"TSourceOut: Word Address: %04X: Needed Entire Word Written",
addr );
throw TGenericError( temp_string );
}
temp_long =
( (unsigned long)Instruction.arg0 << 16 ) |
( (unsigned long)temp_short );
sprintf(
temp_string,
"\t%s\t0x%04lX",
Instruction.name,
temp_long );
} else if(
TAvr::ARG_neg64_63 == Instruction.arg0_type ||
TAvr::ARG_neg2KB_2KB == Instruction.arg0_type ) {
// We insist that arg types of ARG_neg64_63 and
// ARG_neg2KB_2KB have an arg format of 'k'.
if( 'k' != Instruction.arg0_format ){
sprintf(
temp_string,
"TSourceOut:\n"
"\t%s instruciton has arg0_type = ARG_neg64_63 or ARG_neg2KB_2KB\n"
"\twith 'k' != ( arg0_format = '%c' )",
Instruction.name,
Instruction.arg0_format );
throw TGenericError( temp_string );
}
// We also insist that arg0 types of ARG_neg64_63 and
// ARG_neg2KB_2KB do not have an arg1.
if( TAvr::ARG_none != Instruction.arg1_type ){
sprintf(
temp_string,
"TSourceOut:\n"
"\t%s instruciton has arg0_type = ARG_neg64_63 or ARG_neg2KB_2KB\n"
"\twith ARG_none != arg1_type",
Instruction.name );
throw TGenericError( temp_string );
}
sprintf(
temp_string,
"\t%s\t%d",
Instruction.name,
(short)Instruction.arg0 );
have_dest = TRUE;
//there is a special case;
if(Instruction.arg0<0 && Instruction.arg0<-2*1024){
unsigned int offset = 0;
offset = addr + 2 + 0x2000 + Instruction.arg0;
offset = offset &0x0000FFFF;
dest = offset;
}else{
dest = addr + 2 + (short)Instruction.arg0;
}
} else if (TAvr::ARG_0_PAIR==Instruction.arg0_type){
sprintf(
temp_string,
"\t%s\tr%d:r%d",
Instruction.name,
Instruction.arg0*2+1,Instruction.arg0*2);
}else{
switch( Instruction.arg0_format ){
case '\0':
// No args to this instruction
sprintf(
temp_string,
"\t%s",
Instruction.name );
break;
case 'd':
case 'r':
//change register name
char r_name[4];
sprintf(r_name,"r%d",Instruction.arg0);
switch(Instruction.arg0){
case 26:
strcpy(r_name,"XL");
break;
case 27:
strcpy(r_name,"XH");
break;
case 28:
strcpy(r_name,"YL");
break;
case 29:
strcpy(r_name,"YH");
break;
case 30:
strcpy(r_name,"ZL");
break;
case 31:
strcpy(r_name,"ZH");
break;
}
sprintf(
temp_string,
"\t%s\t%s",
Instruction.name,
r_name );
break;
case 'k':
case 's':
sprintf(
temp_string,
"\t%s\t%d",
Instruction.name,
(short)Instruction.arg0 );
break;
case 'P':
case 'p':
//need to translate to I/O register name;
/*sprintf(
temp_string,
"\t%s\t0x%X",
Instruction.name,
Instruction.arg0 );*/
sprintf(
temp_string,
"\t%s\t%s",
Instruction.name,
m8_IO_register_name[Instruction.arg0] );
break;
case 'X':
case 'Y':
case 'Z':
if( 0 == strcmp( "std", Instruction.name )){
sprintf(
temp_string,
"\t%s\t%c+%d",
Instruction.name,
Instruction.arg0_format,
Instruction.arg0 );
} else {
// It's a little convoluted how we get the
// information back from TAvr::AdjustArg about
// whether to us "X", "X+", or "-X". In this
// arg_format is 'X'. We differentiate by
// setting the value of arg (which is an
// (unsigned short)) to one of ' ', '+' or '-'.
switch( (char)Instruction.arg0 ){
case ' ':
sprintf(
temp_string,
"\t%s\t%c",
Instruction.name,
Instruction.arg0_format );
break;
case '+':
sprintf(
temp_string,
"\t%s\t%c+",
Instruction.name,
Instruction.arg0_format );
break;
case '-':
sprintf(
temp_string,
"\t%s\t-%c",
Instruction.name,
Instruction.arg0_format );
break;
default:
sprintf(
temp_string,
"TSourceOut:\n"
"\t%s instruction has special arg0_format: '%c'\n"
"\twith unknown arg0 of: 0x%X",
Instruction.name,
Instruction.arg0_format,
Instruction.arg0 );
throw TGenericError( temp_string );
break;
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -