diff --git a/tas/Makefile b/tas/Makefile new file mode 100644 index 0000000..53c580f --- /dev/null +++ b/tas/Makefile @@ -0,0 +1,12 @@ + +tas : tas.c + gcc -o tas tas.c + +clean : + rm -f tas + rm -f *.bin + rm -f *.hex + rm -f *.s.s + rm -f *.s.diss + + diff --git a/tas/README b/tas/README new file mode 100644 index 0000000..321ad3d --- /dev/null +++ b/tas/README @@ -0,0 +1,22 @@ + +This is a thumb assembler derived directly from the assembler in my +thumbulator project. The thumulator version remains the primary +version/home. + +I added some hardcoded machine code up front to get from arm to thumb +and then if you bl hexstring, I tack on machine code to implement that +function. hexstring takes r0 and prints it out on the uart in ascii. + +Since I got it working I dont want to just discard it, but not sure +what I want to do with this...I provided binaries for the bootloaders +so that you dont have to have arm tools, which is why you would use tas +because you want to try asm but dont want to try or have failed to build +gnu binutils. tas should build most anywhere. + +One simple test program provided, thats it + +./tas test.s + +then use a bootloader to load test.s.bin. Since the test program + tas +require the mini uart to be initialized simply copying test.s.bin to +kernel.img wont do you any good. diff --git a/tas/armstart.s b/tas/armstart.s new file mode 100644 index 0000000..3a2727e --- /dev/null +++ b/tas/armstart.s @@ -0,0 +1,18 @@ + +.globl _start +_start: + b reset +reset: + ldr sp,stack_start + ldr r0,thumb_start_add + bx r0 + +stack_start: .word 0x1000 +thumb_start_add: .word thumb_start +.word 0 +.word 0 + +.thumb +.thumb_func +thumb_start: + b . diff --git a/tas/hexstring.c b/tas/hexstring.c new file mode 100644 index 0000000..de7aebb --- /dev/null +++ b/tas/hexstring.c @@ -0,0 +1,30 @@ + +void uart_send ( unsigned int ); +void hexstring ( unsigned int d ) +{ + //unsigned int ra; + unsigned int rb; + unsigned int rc; + + rb=32; + while(1) + { + rb-=4; + rc=(d>>rb)&0xF; + if(rc>9) rc+=0x37; else rc+=0x30; + uart_send(rc); + if(rb==0) break; + } + uart_send(0x0D); + uart_send(0x0A); +} +#define AUX_MU_IO_REG (*((volatile unsigned int *)0x20215040)) +#define AUX_MU_LSR_REG (*((volatile unsigned int *)0x20215054)) +void uart_send ( unsigned int x ) +{ + while(1) + { + if(AUX_MU_LSR_REG&0x20) break; + } + AUX_MU_IO_REG=x; +} diff --git a/tas/tas.c b/tas/tas.c new file mode 100644 index 0000000..d6d8e66 --- /dev/null +++ b/tas/tas.c @@ -0,0 +1,2863 @@ + +//------------------------------------------------------------------- +// Copyright (C) 2012 David Welch +//------------------------------------------------------------------- + +#include +#include +#include + + +FILE *fpin; +FILE *fpout; + +unsigned int rd,rm,rn,rx; +unsigned int bl_upper; +unsigned int is_const,is_label; + +#define ADDMASK 0xFFFF +unsigned short mem[ADDMASK+1]; +unsigned short mark[ADDMASK+1]; + +unsigned int curradd; +unsigned int line; + +char cstring[1024]; +char newline[1024]; + + +#define LABLEN 64 + +#define MAX_LABS 65536 +struct +{ + char name[LABLEN]; + unsigned int addr; + unsigned int line; + unsigned int type; +} lab_struct[MAX_LABS]; +unsigned int nlabs; +unsigned int lab; + + +#define NREGNAMES (19) +struct +{ + char name[4]; + unsigned char num; +} reg_names[NREGNAMES]= +{ + {"r0",0},{"r1",1},{"r2",2},{"r3",3},{"r4",4},{"r5",5},{"r6",6},{"r7",7}, + {"r8",8},{"r9",9},{"r10",10},{"r11",11},{"r12",12},{"r13",13},{"r14",14},{"r15",15}, + {"sp",13},{"lr",14},{"pc",15} +}; + + +unsigned char hexchar[256]= +{ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, +0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +unsigned char numchar[256]= +{ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +//------------------------------------------------------------------- +//------------------------------------------------------------------- +//------------------------------------------------------------------- +int rest_of_line ( unsigned int ra ) +{ + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + if(newline[ra]) + { + printf("<%u> Error: garbage at end of line\n",line); + return(1); + } + return(0); +} +//------------------------------------------------------------------- +int get_reg_number ( char *s, unsigned int *rx ) +{ + unsigned int ra; + + for(ra=0;ra Error: invalid number\n",line); + return(0); + } + cstring[rb++]=newline[ra]; + } + cstring[rb]=0; + if(rb==0) + { + printf("<%u> Error: invalid number\n",line); + return(0); + } + rx=strtoul(cstring,NULL,16); + } + else + { + rb=0; + for(;newline[ra];ra++) + { + if(newline[ra]==',') break; + if(newline[ra]==']') break; + if(newline[ra]==0x20) break; + if(!numchar[newline[ra]]) + { + printf("<%u> Error: invalid number\n",line); + return(0); + } + cstring[rb++]=newline[ra]; + } + cstring[rb]=0; + if(rb==0) + { + printf("<%u> Error: invalid number\n",line); + return(0); + } + rx=strtoul(cstring,NULL,10); + } + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + return(ra); +} +//------------------------------------------------------------------- +unsigned int parse_reg ( unsigned int ra ) +{ + unsigned int rb; + + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + rb=0; + for(;newline[ra];ra++) + { + if(newline[ra]==',') break; + if(newline[ra]==']') break; + if(newline[ra]=='}') break; + if(newline[ra]==0x20) break; + cstring[rb++]=newline[ra]; + } + cstring[rb]=0; + if(get_reg_number(cstring,&rx)) + { + printf("<%u> Error: not a register\n",line); + return(0); + } + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + return(ra); +} +//------------------------------------------------------------------- +unsigned int parse_low_reg ( unsigned int ra ) +{ + unsigned int rb; + + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + rb=0; + for(;newline[ra];ra++) + { + if(newline[ra]==',') break; + if(newline[ra]=='!') break; + if(newline[ra]=='}') break; + if(newline[ra]==']') break; + if(newline[ra]==0x20) break; + cstring[rb++]=newline[ra]; + } + cstring[rb]=0; + if(get_reg_number(cstring,&rx)) + { + printf("<%u> Error: not a register\n",line); + return(0); + } + if(rx>7) + { + printf("<%u> Error: invalid (high) register\n",line); + return(0); + } + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + return(ra); +} +//------------------------------------------------------------------- +unsigned int parse_comma ( unsigned int ra ) +{ + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + if(newline[ra]!=',') + { + printf("<%u> Error: syntax error\n",line); + return(0); + } + ra++; + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + return(ra); +} +//------------------------------------------------------------------- +unsigned int parse_character ( unsigned int ra, unsigned char ch ) +{ + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + if(newline[ra]!=ch) + { + printf("<%u> Error: syntax error\n",line); + return(0); + } + ra++; + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + return(ra); +} +//------------------------------------------------------------------- +unsigned int no_spaces ( unsigned int ra ) +{ + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + return(ra); +} +//------------------------------------------------------------------- +unsigned int parse_two_regs ( unsigned int ra ) +{ + ra=parse_low_reg(ra); if(ra==0) return(0); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(0); + ra=parse_low_reg(ra); if(ra==0) return(0); + rm=rx; + return(ra); +} +//------------------------------------------------------------------- +unsigned int parse_branch_label ( unsigned int ra ) +{ + unsigned int rb; + unsigned int rc; + + is_const=0; + is_label=0; + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + if(numchar[newline[ra]]) + { + ra=parse_immed(ra); if(ra==0) return(0); + is_const=1; + } + else + { + //assume label, find space or eol. + for(rb=ra;newline[rb];rb++) + { + if(newline[rb]==0x20) break; //no spaces in labels + } + //got a label + rc=rb-ra; + if(rc==0) + { + printf("<%u> Error: Invalid label\n",line); + return(0); + } + rc--; + if(rc>=LABLEN) + { + printf("<%u> Error: Label too long\n",line); + return(0); + } + for(rb=0;rb<=rc;rb++) + { + lab_struct[nlabs].name[rb]=newline[ra++]; + } + lab_struct[nlabs].name[rb]=0; + lab_struct[nlabs].addr=curradd; + lab_struct[nlabs].line=line; + lab_struct[nlabs].type=1; + nlabs++; + rx=0; + is_label=1; + } + return(ra); +}//------------------------------------------------------------------- +//------------------------------------------------------------------- +int assemble ( void ) +{ + unsigned int ra; + unsigned int rb; + unsigned int rc; + + + curradd=0; + nlabs=0; + memset(mem,0x00,sizeof(mem)); + memset(mark,0x00,sizeof(mark)); + + //.word 0xEAFFFFFF + //.word 0xE59FD004 + //.word 0xE59F0004 + //.word 0xE12FFF10 + //.word 0x00100000 + //.word 0x00000021 + //.word 0x00000000 + //.word 0x00000000 + + mem[curradd]=0xFFFF; mark[curradd]=0x9000; curradd++; mem[curradd]=0xEAFF; mark[curradd]=0x9000; curradd++; + mem[curradd]=0xD004; mark[curradd]=0x9000; curradd++; mem[curradd]=0xE59F; mark[curradd]=0x9000; curradd++; + mem[curradd]=0x0004; mark[curradd]=0x9000; curradd++; mem[curradd]=0xE59F; mark[curradd]=0x9000; curradd++; + mem[curradd]=0xFF10; mark[curradd]=0x9000; curradd++; mem[curradd]=0xE12F; mark[curradd]=0x9000; curradd++; + mem[curradd]=0x0000; mark[curradd]=0x9000; curradd++; mem[curradd]=0x0010; mark[curradd]=0x9000; curradd++; + mem[curradd]=0x0021; mark[curradd]=0x9000; curradd++; mem[curradd]=0x0000; mark[curradd]=0x9000; curradd++; + mem[curradd]=0x0000; mark[curradd]=0x9000; curradd++; mem[curradd]=0x0000; mark[curradd]=0x9000; curradd++; + mem[curradd]=0x0000; mark[curradd]=0x9000; curradd++; mem[curradd]=0x0000; mark[curradd]=0x9000; curradd++; + + line=0; + while(fgets(newline,sizeof(newline)-1,fpin)) + { + line++; + //tabs to spaces and other things + for(ra=0;newline[ra];ra++) + { + if(newline[ra]<0x20) newline[ra]=0x20; + if(newline[ra]>=0x7F) newline[ra]=0; + } + + //various ways to comment lines + for(ra=0;newline[ra];ra++) + { + if(newline[ra]==';') newline[ra]=0; + if(newline[ra]=='@') newline[ra]=0; + if((newline[ra]=='/')&&(newline[ra+1]=='/')) newline[ra]=0; + if(newline[ra]==0) break; + } + + //skip spaces + for(ra=0;newline[ra];ra++) if(newline[ra]!=0x20) break; + if(newline[ra]==0) continue; + + //look for a label? + for(rb=ra;newline[rb];rb++) + { + if(newline[rb]==0x20) break; //no spaces in labels + if(newline[rb]==':') break; + } + if(newline[rb]==':') + { + //got a label + rc=rb-ra; + if(rc==0) + { + printf("<%u> Error: Invalid label\n",line); + return(1); + } + rc--; + if(rc>=LABLEN) + { + printf("<%u> Error: Label too long\n",line); + return(1); + } + for(rb=0;rb<=rc;rb++) + { + lab_struct[nlabs].name[rb]=newline[ra++]; + } + lab_struct[nlabs].name[rb]=0; + lab_struct[nlabs].addr=curradd<<1; + lab_struct[nlabs].line=line; + lab_struct[nlabs].type=0; + ra++; + for(lab=0;lab Error: label [%s] already defined on line %u\n",line,lab_struct[lab].name,lab_struct[lab].line); + return(1); + } + nlabs++; + //skip spaces + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + if(newline[ra]==0) continue; + } +// .align ----------------------------------------------------------- + if(strncmp(&newline[ra],".align",6)==0) + { + ra+=6; + if(rest_of_line(ra)) return(1); + if(curradd&1) + { + printf("<%u> Adding halfword to align on a word boundary\n",line); + mem[curradd]=0x0000; + mark[curradd]|=0x9000; + curradd++; + } + continue; + } +// .word ----------------------------------------------------------- + if(strncmp(&newline[ra],".word ",6)==0) + { + ra+=6; + if(curradd&1) + { + printf("<%u> Error: not word aligned\n",line,lab_struct[lab].name,lab_struct[lab].line); + return(1); + } + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + if(newline[ra]=='=') + { + ra=parse_character(ra,'='); if(ra==0) return(1); + ra=parse_branch_label(ra); if(ra==0) return(1); + if((is_const)||(!is_label)) + { + printf("<%u> Error: expecting a label\n",line); + return(1); + } + mem[curradd]=0x0000; + mark[curradd]|=0x9000; + curradd++; + mem[curradd]=0x0000; + mark[curradd]|=0x9000; + curradd++; + } + else + { + while(1) + { + ra=parse_immed(ra); if(ra==0) return(1); + mem[curradd]=rx&0xFFFF; + mark[curradd]|=0x9000; + curradd++; + mem[curradd]=(rx>>16)&0xFFFF; + mark[curradd]|=0x9000; + curradd++; + if(newline[ra]!=',') break; + ra=parse_comma(ra); if(ra==0) return(1); + } + } + if(rest_of_line(ra)) return(1); + continue; + } +// .hword ----------------------------------------------------------- + if(strncmp(&newline[ra],".hword ",7)==0) + { + ra+=7; + while(1) + { + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0xFFFF)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + mem[curradd]=rx; + mark[curradd]|=0x9000; + curradd++; + if(newline[ra]!=',') break; + ra=parse_comma(ra); if(ra==0) return(1); + } + if(rest_of_line(ra)) return(1); + continue; + } +// adc ----------------------------------------------------------- + if(strncmp(&newline[ra],"adc ",4)==0) + { + ra+=4; + //adc rd,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + mem[curradd]=0x4140|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// add ----------------------------------------------------------- + if(strncmp(&newline[ra],"add ",4)==0) + { + ra+=4; + //add rd,rm,#immed_3 + //add rd,#immed_8 + //add rd,rn,rm + //add rd,rm one or both high + //add rd,pc,#immed_8*4 + //add rd,sp,#immed_8*4 + //add sp,#immed_7*4 + ra=parse_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + if(rd>7) + { + //add rdhi, + if((rd==13)&&(newline[ra]=='#')) + { + ra++; + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x1FC)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //add sp,#immed_7*4 + mem[curradd]=0xB000|(rx>>2); + mark[curradd]=0x8000; + curradd++; + } + else + { + ra=parse_reg(ra); if(ra==0) return(1); + rm=rx; + //add rd,rm one or both high + mem[curradd]=0x4400|((rd&8)<<4)|(rm<<3)|(rd&7); + mark[curradd]=0x8000; + curradd++; + } + } + else + { + //add rdlo, + if(newline[ra]=='#') + { + ra++; + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0xFF)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //add rd,#immed_8 + mem[curradd]=0x3000|(rd<<8)|rx; + mark[curradd]=0x8000; + curradd++; + } + else + { + //add rdlo,r? + ra=parse_reg(ra); if(ra==0) return(1); + rm=rx; + if(rm>7) + { + //add rdlo,rhi + if(newline[ra]==',') + { + //add rdlo,rhi, + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]!='#') + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + if(rm==15) + { + ra++; + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x3FC)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //add rd,pc,#immed_8*4 + mem[curradd]=0xA000|(rd<<8)|(rx>>2); + mark[curradd]=0x8000; + curradd++; + } + else + if(rm==13) + { + ra++; + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x3FC)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //add rd,pc,#immed_8*4 + mem[curradd]=0xA800|(rd<<8)|(rx>>2); + mark[curradd]=0x8000; + curradd++; + } + else + { + printf("<%u> Error: Invalid second register\n",line); + return(1); + } + } + else + { + //add rdlo,rdhi + //add rd,rm one or both high + mem[curradd]=0x4400|((rd&8)<<4)|(rm<<3)|(rd&7); + mark[curradd]=0x8000; + curradd++; + } + } + else + { + //add rlo,rlo + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]=='#') + { + rn=rm; + ra++; + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x7)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //add rd,rm,#immed_3 + mem[curradd]=0x1C00|(rx<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + rn=rm; + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + mem[curradd]=0x1800|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + } + } + if(rest_of_line(ra)) return(1); + continue; + } +// and ----------------------------------------------------------- + if(strncmp(&newline[ra],"and ",4)==0) + { + ra+=4; + //and rd,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + mem[curradd]=0x4000|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// asr ----------------------------------------------------------- + if(strncmp(&newline[ra],"asr ",4)==0) + { + ra+=4; + //asr rd,rm,#immed_5 + //asr rd,rs + ra=parse_two_regs(ra); if(ra==0) return(1); + if(newline[ra]==',') + { + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]=='#') + { + ra++; + ra=parse_immed(ra); if(ra==0) return(1); + if((rx<1)||(rx>32)) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + rx&=0x1F; + //asr rd,rm,#immed_5 + mem[curradd]=0x1000|(rx<<6)|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + } + else + { + //asr rd,rs + mem[curradd]=0x4100|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + if(rest_of_line(ra)) return(1); + continue; + } +// b ----------------------------------------------------------- + if(strncmp(&newline[ra],"b ",2)==0) + { + ra+=2; + //b label + //b immed + ra=parse_branch_label(ra); if(ra==0) return(1); + if(rest_of_line(ra)) return(1); + if(is_label) + { + mem[curradd]=0xE000; + mark[curradd]=0x8002; + curradd++; + continue; + } + if(is_const) + { + rd=rx-((curradd<<1)+4); + rm=0xFFFFFFFF<<11; + if(rd&rm) + { + if((rd&rm)!=rm) + { + printf("<%u> Error: Branch destination too far\n",line); + return(1); + } + } + //ignore even/odd address? + rm=(rd>>1)&0x7FF; + mem[curradd]=0xE000|rm; + mark[curradd]=0x8002; + curradd++; + continue; + } + } +// bcond ----------------------------------------------------------- + rn=0; + if(strncmp(&newline[ra],"beq ",4)==0) rn=0x10; + if(strncmp(&newline[ra],"bne ",4)==0) rn=0x11; + if(strncmp(&newline[ra],"bcs ",4)==0) rn=0x12; + if(strncmp(&newline[ra],"bcc ",4)==0) rn=0x13; + if(strncmp(&newline[ra],"bmi ",4)==0) rn=0x14; + if(strncmp(&newline[ra],"bpl ",4)==0) rn=0x15; + if(strncmp(&newline[ra],"bvs ",4)==0) rn=0x16; + if(strncmp(&newline[ra],"bvc ",4)==0) rn=0x17; + if(strncmp(&newline[ra],"bhi ",4)==0) rn=0x18; + if(strncmp(&newline[ra],"bls ",4)==0) rn=0x19; + if(strncmp(&newline[ra],"bge ",4)==0) rn=0x1A; + if(strncmp(&newline[ra],"blt ",4)==0) rn=0x1B; + if(strncmp(&newline[ra],"bgt ",4)==0) rn=0x1C; + if(strncmp(&newline[ra],"ble ",4)==0) rn=0x1D; + if(strncmp(&newline[ra],"bal ",4)==0) rn=0x1E; + if(rn) + { + ra+=3; + ra=parse_branch_label(ra); if(ra==0) return(1); + if(rest_of_line(ra)) return(1); + if(is_label) + { + mem[curradd]=0xD000|(rn<<8); + mark[curradd]=0x8002; + curradd++; + continue; + } + if(is_const) + { + rd=rx-((curradd<<1)+4); + rm=0xFFFFFFFF<<8; + if(rd&rm) + { + if((rd&rm)!=rm) + { + printf("<%u> Error: Branch destination too far\n",line); + return(1); + } + } + //ignore even/odd address? + rm=(rd>>1)&0xFF; + rn&=0xF; + mem[curradd]=0xD000|(rn<<8)|rm; + mark[curradd]=0x8002; + curradd++; + continue; + } + } +// bic ----------------------------------------------------------- + if(strncmp(&newline[ra],"bic ",4)==0) + { + ra+=4; + //bic rd,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + mem[curradd]=0x4380|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// bkpt ----------------------------------------------------------- + if(strncmp(&newline[ra],"bkpt ",5)==0) + { + ra+=5; + //bkpt immed_8 + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0xFF)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + mem[curradd]=0xBE00|rx; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// bl ----------------------------------------------------------- + if(strncmp(&newline[ra],"bl ",3)==0) + { + ra+=3; + //bl label + //bl immed + ra=parse_branch_label(ra); if(ra==0) return(1); + if(rest_of_line(ra)) return(1); + if(is_label) + { + mem[curradd]=0xF000; + mark[curradd]=0x8002; + curradd++; + mem[curradd]=0xF800; + mark[curradd]=0x8002; + curradd++; + continue; + } + if(is_const) + { + rd=rx-((curradd<<1)+4); + rm=0xFFFFFFFF<<22; + if(rd&rm) + { + if((rd&rm)!=rm) + { + printf("<%u> Error: Branch destination too far\n",line); + return(1); + } + } + //ignore even/odd address? + rn=(rd>>12)&0x7FF; + rm=(rd>>1)&0x7FF; + mem[curradd]=0xF000|rn; + mark[curradd]=0x8002; + curradd++; + mem[curradd]=0xF800|rm; + mark[curradd]=0x8002; + curradd++; + continue; + } + } +// bx ----------------------------------------------------------- + if(strncmp(&newline[ra],"bx ",3)==0) + { + ra+=3; + //bx rm + ra=parse_reg(ra); if(ra==0) return(1); + rm=rx; + mem[curradd]=0x4700|(rm<<3); + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// cmn ----------------------------------------------------------- + if(strncmp(&newline[ra],"cmn ",4)==0) + { + ra+=4; + //cmn rn,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + mem[curradd]=0x42C0|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// cmp ----------------------------------------------------------- + if(strncmp(&newline[ra],"cmp ",4)==0) + { + ra+=4; + //cmp rn,#immed_8 + //cmp rn,rm both low + //cmp rn,rm one or the other high + ra=parse_reg(ra); if(ra==0) return(1); + rn=rx; + ra=parse_comma(ra); if(ra==0) return(1); + if(rn>7) + { + ra=parse_reg(ra); if(ra==0) return(1); + rm=rx; + if(rm>7) + { + if(rm==15) + { + printf("<%u> Error: Not wise to use r15 in this way\n",line); + return(1); + } + //cmp rn,rm one or the other high + mem[curradd]=0x4500|((rn&8)<<4)|(rm<<3)|rn; + mark[curradd]=0x8000; + curradd++; + } + else + { + //cmp rn,rm both low + mem[curradd]=0x4280|(rm<<3)|rn; + mark[curradd]=0x8000; + curradd++; + } + } + else + { + if(newline[ra]=='#') + { + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0xFF)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //cmp rn,#immed_8 + mem[curradd]=0x2800|(rn<<8)|rx; + mark[curradd]=0x8000; + curradd++; + } + else + { + ra=parse_reg(ra); if(ra==0) return(1); + rm=rx; + if(rm>7) + { + if(rm==15) + { + printf("<%u> Error: Not wise to use r15 in this way\n",line); + return(1); + } + //cmp rn,rm one or the other high + mem[curradd]=0x4500|((rn&8)<<4)|(rm<<3)|rn; + mark[curradd]=0x8000; + curradd++; + } + else + { + //cmp rn,rm both low + mem[curradd]=0x4280|(rm<<3)|rn; + mark[curradd]=0x8000; + curradd++; + } + + } + } + if(rest_of_line(ra)) return(1); + continue; + } +// eor ----------------------------------------------------------- + if(strncmp(&newline[ra],"eor ",4)==0) + { + ra+=4; + //eor rd,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + mem[curradd]=0x4040|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// ldmia ----------------------------------------------------------- + if(strncmp(&newline[ra],"ldmia ",6)==0) + { + ra+=6; + //ldmia rn!,{r0,r1,...,r7} + ra=parse_low_reg(ra); if(ra==0) return(1); + rn=rx; + ra=parse_character(ra,'!'); if(ra==0) return(1); + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'{'); if(ra==0) return(1); + rm=0; + while(1) + { + ra=parse_low_reg(ra); if(ra==0) return(1); + if(rm&(1< Warning: You already specified r%u\n",line,rx); + } + rm|=(1<7) + { + if(rn==15) + { + } + else + if(rn==13) + { + } + else + { + printf("<%u> Error: Invalid base register\n",line); + return(1); + } + if(newline[ra]==']') + { + rx=0; + } + else + { + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x3FC)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + } + ra=parse_character(ra,']'); if(ra==0) return(1); + //ldr rd,[pc,#immed_8*4] + //ldr rd,[sp,#immed_8*4] + mem[curradd]=0x0000|(rd<<8)|(rx>>2); + if(rn==15) mem[curradd]|=0x4800; + if(rn==13) mem[curradd]|=0x9800; + mark[curradd]=0x8000; + curradd++; + } + else + { + if(newline[ra]==',') + { + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]=='#') + { + //ldr rd,[rn,#immed_5*4] + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x7C)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x6800|((rx>>2)<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + //ldr rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x5800|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + else + { + //ldr rd,[rn] immed_5 = 0 + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x6800|(0<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + } + else + { + ra=parse_branch_label(ra); if(ra==0) return(1); + if(is_const) + { + printf("<%u> Error: not a label",line); + return(1); + } + mem[curradd]=0x4800|(rd<<8)|0; + mark[curradd]=0x8000; + curradd++; + } + if(rest_of_line(ra)) return(1); + continue; + } +// ldrb ----------------------------------------------------------- + if(strncmp(&newline[ra],"ldrb ",5)==0) + { + ra+=5; + //ldrb rd,[rn,#immed_5] + //ldrb rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'['); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rn=rx; + if(newline[ra]==',') + { + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]=='#') + { + //ldrb rd,[rn,#immed_5] + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x1F)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x7800|((rx>>0)<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + //ldrb rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x5C00|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + else + { + //ldrb rd,[rn] immed_5 = 0 + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x7800|(0<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + if(rest_of_line(ra)) return(1); + continue; + } +// ldrh ----------------------------------------------------------- + if(strncmp(&newline[ra],"ldrh ",5)==0) + { + ra+=5; + //ldrh rd,[rn,#immed_5] + //ldrh rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'['); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rn=rx; + if(newline[ra]==',') + { + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]=='#') + { + //ldrh rd,[rn,#immed_5] + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&(0x1F<<1))!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x8800|((rx>>1)<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + //ldrb rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x5A00|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + else + { + //ldrh rd,[rn] immed_5 = 0 + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x8800|(0<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + if(rest_of_line(ra)) return(1); + continue; + } +// ldrsb ----------------------------------------------------------- + if(strncmp(&newline[ra],"ldrsb ",6)==0) + { + ra+=6; + //ldrsb rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'['); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rn=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x5600|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// ldrsh ----------------------------------------------------------- + if(strncmp(&newline[ra],"ldrsh ",6)==0) + { + ra+=6; + //ldrsh rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'['); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rn=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x5E00|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// lsl ----------------------------------------------------------- + if(strncmp(&newline[ra],"lsl ",4)==0) + { + ra+=4; + //lsl rd,rm,#immed_5 + //lsl rd,rs + ra=parse_low_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + if(newline[ra]==',') + { + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx<1)||(rx>32)) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + rx&=0x1F; + //lsl rd,rm,#immed_5 + mem[curradd]=0x0000|(rx<<6)|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + //lsl rd,rs + mem[curradd]=0x4080|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + if(rest_of_line(ra)) return(1); + continue; + } +// lsr ----------------------------------------------------------- + if(strncmp(&newline[ra],"lsr ",4)==0) + { + ra+=4; + //lsr rd,rm,#immed_5 + //lsr rd,rs + ra=parse_low_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + if(newline[ra]==',') + { + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx<1)||(rx>32)) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + rx&=0x1F; + //lsr rd,rm,#immed_5 + mem[curradd]=0x0800|(rx<<6)|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + //lsr rd,rs + mem[curradd]=0x40C0|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + if(rest_of_line(ra)) return(1); + continue; + } +// mov ----------------------------------------------------------- + if(strncmp(&newline[ra],"mov ",4)==0) + { + ra+=4; + //mov rd,#immed_8 + //mov rd,rn low + //mov rd,rm one or both high + ra=parse_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + if(rd>7) + { + ra=parse_reg(ra); if(ra==0) return(1); + rm=rx; + //mov rd,rm + mem[curradd]=0x4600|((rd&8)<<4)|(rm<<3)|(rd&7); + mark[curradd]=0x8000; + curradd++; + } + else + { + if(newline[ra]=='#') + { + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0xFF)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //mov rd,#immed_8 + mem[curradd]=0x2000|(rd<<8)|rx; + mark[curradd]=0x8000; + curradd++; + } + else + { + ra=parse_reg(ra); if(ra==0) return(1); + if(rx>7) + { + rm=rx; + //mov rd,rm + mem[curradd]=0x4600|((rd&8)<<4)|(rm<<3)|(rd&7); + mark[curradd]=0x8000; + curradd++; + } + else + { + rn=rx; + //mov rd,rn both low + mem[curradd]=0x1C00|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + } + if(rest_of_line(ra)) return(1); + continue; + } +// mul ----------------------------------------------------------- + if(strncmp(&newline[ra],"mul ",4)==0) + { + ra+=4; + //mul rd,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + if(rd==rm) + { + printf("<%u> Warning: using the same register might not work\n",line); + } + mem[curradd]=0x4340|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// mvn ----------------------------------------------------------- + if(strncmp(&newline[ra],"mvn ",4)==0) + { + ra+=4; + //mvn rd,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + mem[curradd]=0x43C0|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// neg ----------------------------------------------------------- + if(strncmp(&newline[ra],"neg ",4)==0) + { + ra+=4; + //neg rd,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + mem[curradd]=0x4240|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// orr ----------------------------------------------------------- + if(strncmp(&newline[ra],"orr ",4)==0) + { + ra+=4; + //orr rd,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + mem[curradd]=0x4300|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// pop ----------------------------------------------------------- + if(strncmp(&newline[ra],"pop ",4)==0) + { + ra+=4; + //pop {r0,r1,...,r7} + ra=parse_character(ra,'{'); if(ra==0) return(1); + rm=0; + while(1) + { + ra=parse_reg(ra); if(ra==0) return(1); + if(rx>7) + { + if(rx!=15) + { + printf("<%u> Error: Invalid Register\n",line); + return(1); + } + rx=8; + } + rm|=(1<7) + { + if(rx!=14) + { + printf("<%u> Error: Invalid Register\n",line); + return(1); + } + rx=8; + } + rm|=(1< Warning: You already specified r%u\n",line,rx); + } + rm|=(1<7) + { + if(rn!=13) + { + printf("<%u> Error: Invalid base register\n",line); + return(1); + } + if(newline[ra]==']') + { + rx=0; + } + else + { + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x3FC)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + } + ra=parse_character(ra,']'); if(ra==0) return(1); + //str rd,[sp,#immed_8*4] + mem[curradd]=0x9000|(rd<<8)|(rx>>2); + mark[curradd]=0x8000; + curradd++; + } + else + { + if(newline[ra]==',') + { + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]=='#') + { + //str rd,[rn,#immed_5*4] + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x7C)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x6000|((rx>>2)<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + //str rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x5000|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + else + { + //str rd,[rn] immed_5 = 0 + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x6000|(0<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + if(rest_of_line(ra)) return(1); + continue; + } +// strb ----------------------------------------------------------- + if(strncmp(&newline[ra],"strb ",5)==0) + { + ra+=5; + //strb rd,[rn,#immed_5] + //strb rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'['); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rn=rx; + if(newline[ra]==',') + { + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]=='#') + { + //strb rd,[rn,#immed_5] + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x1F)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x7000|((rx>>0)<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + //strb rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x5400|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + else + { + //strb rd,[rn] immed_5 = 0 + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x7000|(0<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + if(rest_of_line(ra)) return(1); + continue; + } +// strh ----------------------------------------------------------- + if(strncmp(&newline[ra],"strh ",5)==0) + { + ra+=5; + //strh rd,[rn,#immed_5*2] + //strh rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + ra=parse_character(ra,'['); if(ra==0) return(1); + ra=parse_low_reg(ra); if(ra==0) return(1); + rn=rx; + if(newline[ra]==',') + { + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]=='#') + { + //strh rd,[rn,#immed_5*2] + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&(0x1F<<1))!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x8000|((rx>>1)<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + //strh rd,[rn,rm] + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x5200|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + else + { + //strh rd,[rn] immed_5 = 0 + ra=parse_character(ra,']'); if(ra==0) return(1); + mem[curradd]=0x8000|(0<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + if(rest_of_line(ra)) return(1); + continue; + } +// sub ----------------------------------------------------------- + if(strncmp(&newline[ra],"sub ",4)==0) + { + ra+=4; + //sub rd,rm,#immed_3 + //sub rd,#immed_8 + //sub rd,rn,rm + //sub sp,#immed_7*4 + ra=parse_reg(ra); if(ra==0) return(1); + rd=rx; + ra=parse_comma(ra); if(ra==0) return(1); + if(rd>7) + { + //sub rdhi, + if((rd==13)&&(newline[ra]=='#')) + { + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x1FC)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //sub sp,#immed_7*4 + mem[curradd]=0xB080|(rx>>2); + mark[curradd]=0x8000; + curradd++; + } + else + { + printf("<%u> Error: Invalid rd register\n",line); + return(1); + } + } + else + { + //sub rdlo, + if(newline[ra]=='#') + { + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0xFF)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //sub rd,#immed_8 + mem[curradd]=0x3800|(rd<<8)|rx; + mark[curradd]=0x8000; + curradd++; + } + else + { + //sub rdlo,r? + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + { + //sub rlo,rlo + ra=parse_comma(ra); if(ra==0) return(1); + if(newline[ra]=='#') + { + rn=rm; + ra=parse_character(ra,'#'); if(ra==0) return(1); + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0x7)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + //sub rd,rm,#immed_3 + mem[curradd]=0x1E00|(rx<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + else + { + //sub rd,rn,rm + rn=rm; + ra=parse_low_reg(ra); if(ra==0) return(1); + rm=rx; + mem[curradd]=0x1A00|(rm<<6)|(rn<<3)|rd; + mark[curradd]=0x8000; + curradd++; + } + } + } + } + if(rest_of_line(ra)) return(1); + continue; + } +// swi ----------------------------------------------------------- + if(strncmp(&newline[ra],"swi ",4)==0) + { + ra+=4; + //swi immed_8 + ra=parse_immed(ra); if(ra==0) return(1); + if((rx&0xFF)!=rx) + { + printf("<%u> Error: Invalid immediate\n",line); + return(1); + } + mem[curradd]=0xDF00|rx; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +// tst ----------------------------------------------------------- + if(strncmp(&newline[ra],"tst ",4)==0) + { + ra+=4; + //tst rn,rm + ra=parse_two_regs(ra); if(ra==0) return(1); + mem[curradd]=0x4200|(rm<<3)|rd; + mark[curradd]=0x8000; + curradd++; + if(rest_of_line(ra)) return(1); + continue; + } +//------------------------------------------------------------------- +// pseudo instructions +//------------------------------------------------------------------- +// nop ----------------------------------------------------------- + if(strncmp(&newline[ra],"nop",3)==0) + { + ra+=3; + if(rest_of_line(ra)) return(1); + //nop, encode mov r8,r8 + mem[curradd]=0x46C0; + mark[curradd]=0x8000; + curradd++; + continue; + } + + +// ----------------------------------------------------------- + printf("<%u> Error: syntax error\n",line); + return(1); + } + + mem[curradd]=0xE7FE; mark[curradd]=0x8000; curradd++; + mem[curradd]=0xE7FE; mark[curradd]=0x8000; curradd++; + mem[curradd]=0xE7FE; mark[curradd]=0x8000; curradd++; + mem[curradd]=0xE7FE; mark[curradd]=0x8000; curradd++; + + return(0); +} +//------------------------------------------------------------------- +void dissassemble ( FILE *fp, unsigned int addr, unsigned short inst ) +{ + if((inst&0xFFC0)==0x4140) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"adc r%u,r%u",rd,rm); + return; + } + if((inst&0xFE00)==0x1C00) + { + rd=inst&7; + rn=(inst>>3)&7; + rx=(inst>>6)&7; + fprintf(fp,"add r%u,r%u,#%u",rd,rn,rx); + return; + } + if((inst&0xF800)==0x3000) + { + rd=(inst>>8)&7; + rx=inst&0xFF; + fprintf(fp,"add r%u,#0x%02X ; %u",rd,rx,rx); + return; + } + if((inst&0xFE00)==0x1800) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"add r%u,r%u,r%u",rd,rn,rm); + return; + } + if((inst&0xFF00)==0x4400) + { + rd=inst&7; + rd|=(inst>>4)&8; + rm=(inst>>3)&0xF; + fprintf(fp,"add r%u,r%u",rd,rm); + return; + } + if((inst&0xF800)==0xA000) + { + rd=(inst>>8)&7; + rx=inst&0xFF; + rx<<=2; + fprintf(fp,"add r%u,pc,#0x%03X ; %u",rd,rx,rx); + return; + } + if((inst&0xF800)==0xA800) + { + rd=(inst>>8)&7; + rx=inst&0xFF; + rx<<=2; + fprintf(fp,"add r%u,sp,#0x%03X ; %u",rd,rx,rx); + return; + } + if((inst&0xFF80)==0xB000) + { + rx=inst&0x7F; + rx<<=2; + fprintf(fp,"add sp,#0x%03X ; %u",rx,rx); + return; + } + if((inst&0xFFC0)==0x4000) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"and r%u,r%u",rd,rm); + return; + } + if((inst&0xF800)==0x1000) + { + rd=inst&7; + rm=(inst>>3)&7; + rx=(inst>>6)&0x1F; + if(rx==0) rx=32; + fprintf(fp,"asr r%u,r%u,#%u",rd,rm,rx); + return; + } + if((inst&0xFFC0)==0x4100) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"asr r%u,r%u",rd,rm); + return; + } + if((inst&0xF000)==0xD000) + { + rx=inst&0xFF; + rm=(inst>>8)&0xF; + if(rx&0x80) rd=0xFFFFFFFF; + else rd=0x00000000; + rd<<=9; + rd|=rx<<1; + rd+=addr+4; + switch(rm) + { + case 0x0: fprintf(fp,"beq 0x%08X",rd); return; + case 0x1: fprintf(fp,"bne 0x%08X",rd); return; + case 0x2: fprintf(fp,"bcs 0x%08X",rd); return; + case 0x3: fprintf(fp,"bcc 0x%08X",rd); return; + case 0x4: fprintf(fp,"bmi 0x%08X",rd); return; + case 0x5: fprintf(fp,"bpl 0x%08X",rd); return; + case 0x6: fprintf(fp,"bvs 0x%08X",rd); return; + case 0x7: fprintf(fp,"bvc 0x%08X",rd); return; + case 0x8: fprintf(fp,"bhi 0x%08X",rd); return; + case 0x9: fprintf(fp,"bls 0x%08X",rd); return; + case 0xA: fprintf(fp,"bge 0x%08X",rd); return; + case 0xB: fprintf(fp,"blt 0x%08X",rd); return; + case 0xC: fprintf(fp,"bgt 0x%08X",rd); return; + case 0xD: fprintf(fp,"ble 0x%08X",rd); return; + case 0xE: fprintf(fp,"bal 0x%08X",rd); return; + //case 0xF: + } + } + if((inst&0xFFC0)==0x4380) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"bic r%u,r%u",rd,rm); + return; + } + if((inst&0xFF00)==0xBE00) + { + rx=inst&0xFF; + fprintf(fp,"bkpt 0x%02X ; %u",rx,rx); + return; + } + if((inst&0xE000)==0xE000) + { + rx=inst&0x07FF; + rm=(inst>>11)&0x3; + switch(rm) + { + case 0: + { + if(rx&(1<<10)) rd=0xFFFFFFFF; + else rd=0x00000000; + rd<<=12; + rd|=rx<<1; + rd+=addr+4; + fprintf(fp,"b 0x%08X",rd); + return; + } + case 2: + { + fprintf(fp,";bl upper"); + bl_upper=rx; + return; + } + case 3: + { + if(bl_upper&(1<<10)) rd=0xFFFFFFFF; + else rd=0x00000000; + rd<<=11; + rd|=bl_upper; + rd<<=12; + rd|=rx<<1; + rd+=addr+(4-2); + fprintf(fp,"bl 0x%08X",rd); + return; + } + } + } + if((inst&0xFF87)==0x4700) + { + rm=(inst>>3)&0xF; + fprintf(fp,"bx r%u",rm); + return; + } + if((inst&0xFFC0)==0x42C0) + { + rn=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"cmn r%u,r%u",rn,rm); + return; + } + if((inst&0xF800)==0x2800) + { + rx=inst&0xFF; + rn=(inst>>8)&7; + fprintf(fp,"cmp r%u,#0x%02X ; %u",rn,rx,rx); + return; + } + if((inst&0xFFC0)==0x4280) + { + rn=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"cmp r%u,r%u",rn,rm); + return; + } + if((inst&0xFF00)==0x4500) + { + rn=inst&7; + rn|=(inst>>4)&8; + rm=(inst>>3)&0xF; + fprintf(fp,"cmp r%u,r%u",rn,rm); + return; + } + if((inst&0xFFC0)==0x4040) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"eor r%u,r%u",rd,rm); + return; + } + if((inst&0xF800)==0xC800) + { + rm=inst&0xFF; + rn=(inst>>8)&7; + fprintf(fp,"ldmia r%u!,{",rn); + for(rx=0;rx<8;rx++) + { + if(rm&(1<>3)&7; + rx=(inst>>6)&0x1F; rx<<=2; + if(rx==0) fprintf(fp,"ldr r%u,[r%u]",rd,rm); + else fprintf(fp,"ldr r%u,[r%u,#0x%02X] ; %u",rd,rm,rx,rx); + return; + } + if((inst&0xFE00)==0x5800) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"ldr r%u,[r%u,r%u]",rd,rn,rm); + return; + } + if((inst&0xF800)==0x4800) + { + rx=inst&0xFF; rx<<=2; + rd=(inst>>8)&7; + if(rx&0x200) rm=0xFFFFFFFF<<10; else rm=0; + rm=addr+4+rx; + if(rx==0) fprintf(fp,"ldr r%u,[pc] ; [0x%04X]",rd,rm); + else fprintf(fp,"ldr r%u,[pc,#0x%03X] ; %u [0x%04X]",rd,rx,rx,rm); + return; + } + if((inst&0xF800)==0x9800) + { + rx=inst&0xFF; rx<<=2; + rd=(inst>>8)&7; + if(rx==0) fprintf(fp,"ldr r%u,[sp]",rd); + else fprintf(fp,"ldr r%u,[sp,#0x%03X] ; %u",rd,rx,rx); + return; + } + if((inst&0xF800)==0x7800) + { + rd=inst&7; + rm=(inst>>3)&7; + rx=(inst>>6)&0x1F; rx<<=0; + if(rx==0) fprintf(fp,"ldrb r%u,[r%u]",rd,rm); + else fprintf(fp,"ldrb r%u,[r%u,#0x%02X] ; %u",rd,rm,rx,rx); + return; + } + if((inst&0xFE00)==0x5C00) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"ldrb r%u,[r%u,r%u]",rd,rn,rm); + return; + } + if((inst&0xF800)==0x8800) + { + rd=inst&7; + rm=(inst>>3)&7; + rx=(inst>>6)&0x1F; rx<<=1; + if(rx==0) fprintf(fp,"ldrh r%u,[r%u]",rd,rm); + else fprintf(fp,"ldrh r%u,[r%u,#0x%02X] ; %u",rd,rm,rx,rx); + return; + } + if((inst&0xFE00)==0x5A00) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"ldrh r%u,[r%u,r%u]",rd,rn,rm); + return; + } + if((inst&0xFE00)==0x5600) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"ldrsb r%u,[r%u,r%u]",rd,rn,rm); + return; + } + if((inst&0xFE00)==0x5E00) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"ldrsh r%u,[r%u,r%u]",rd,rn,rm); + return; + } + if((inst&0xF800)==0x0000) + { + rd=inst&7; + rm=(inst>>3)&7; + rx=(inst>>6)&0x1F; if(rx==0) rx=32; + fprintf(fp,"lsl r%u,r%u,#%u",rd,rm,rx); + return; + } + if((inst&0xFFC0)==0x4080) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"lsl r%u,r%u",rd,rm); + return; + } + if((inst&0xF800)==0x0800) + { + rd=inst&7; + rm=(inst>>3)&7; + rx=(inst>>6)&0x1F; if(rx==0) rx=32; + fprintf(fp,"lsr r%u,r%u,#%u",rd,rm,rx); + return; + } + if((inst&0xFFC0)==0x40C0) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"lsr r%u,r%u",rd,rm); + return; + } + if((inst&0xF800)==0x2000) + { + rx=inst&0xFF; + rd=(inst>>8)&7; + fprintf(fp,"mov r%u,#0x%02X ; %u",rd,rx,rx); + return; + } + if((inst&0xFFC0)==0x1C00) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"mov r%u,r%u",rd,rm); + return; + } + if((inst&0xFF00)==0x4600) + { + rd=inst&7; + rd|=(inst>>4)&8; + rm=(inst>>3)&0xF; + fprintf(fp,"mov r%u,r%u",rd,rm); + return; + } + if((inst&0xFFC0)==0x4340) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"mul r%u,r%u",rd,rm); + return; + } + if((inst&0xFFC0)==0x43C0) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"mvn r%u,r%u",rd,rm); + return; + } + if((inst&0xFFC0)==0x4240) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"neg r%u,r%u",rd,rm); + return; + } + if((inst&0xFFC0)==0x4300) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"orr r%u,r%u",rd,rm); + return; + } + if((inst&0xFE00)==0xBC00) + { + rm=inst&0xFF; + rn=inst&0x100; + fprintf(fp,"pop {"); + for(rx=0;rx<8;rx++) + { + if(rm&(1<>3)&7; + fprintf(fp,"ror r%u,r%u",rd,rm); + return; + } + if((inst&0xFFC0)==0x4180) + { + rd=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"sbc r%u,r%u",rd,rm); + return; + } + if((inst&0xF800)==0xC000) + { + rm=inst&0xFF; + rn=(inst>>8)&7; + fprintf(fp,"stmia r%u!,{",rn); + for(rx=0;rx<8;rx++) + { + if(rm&(1<>3)&7; + rx=(inst>>6)&0x1F; rx<<=2; + if(rx==0) fprintf(fp,"str r%u,[r%u]",rd,rm); + else fprintf(fp,"str r%u,[r%u,#0x%02X] ; %u",rd,rm,rx,rx); + return; + } + if((inst&0xFE00)==0x5000) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"str r%u,[r%u,r%u]",rd,rn,rm); + return; + } + if((inst&0xF800)==0x9000) + { + rx=inst&0xFF; rx<<=2; + rd=(inst>>8)&7; + if(rx==0) fprintf(fp,"str r%u,[sp]",rd); + else fprintf(fp,"str r%u,[sp,#0x%03X] ; %u",rd,rx,rx); + return; + } + if((inst&0xF800)==0x7000) + { + rd=inst&7; + rm=(inst>>3)&7; + rx=(inst>>6)&0x1F; rx<<=0; + if(rx==0) fprintf(fp,"strb r%u,[r%u]",rd,rm); + else fprintf(fp,"strb r%u,[r%u,#0x%02X] ; %u",rd,rm,rx,rx); + return; + } + if((inst&0xFE00)==0x5400) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"strb r%u,[r%u,r%u]",rd,rn,rm); + return; + } + if((inst&0xF800)==0x8000) + { + rd=inst&7; + rm=(inst>>3)&7; + rx=(inst>>6)&0x1F; rx<<=1; + if(rx==0) fprintf(fp,"strh r%u,[r%u]",rd,rm); + else fprintf(fp,"strh r%u,[r%u,#0x%02X] ; %u",rd,rm,rx,rx); + return; + } + if((inst&0xFE00)==0x5200) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"strh r%u,[r%u,r%u]",rd,rn,rm); + return; + } + if((inst&0xFE00)==0x1E00) + { + rd=inst&7; + rn=(inst>>3)&7; + rx=(inst>>6)&7; + fprintf(fp,"sub r%u,r%u,#%u",rd,rn,rx); + return; + } + if((inst&0xF800)==0x3800) + { + rd=(inst>>8)&7; + rx=inst&0xFF; + fprintf(fp,"sub r%u,#0x%02X ; %u",rd,rx,rx); + return; + } + if((inst&0xFE00)==0x1A00) + { + rd=inst&7; + rn=(inst>>3)&7; + rm=(inst>>6)&7; + fprintf(fp,"sub r%u,r%u,r%u",rd,rn,rm); + return; + } + if((inst&0xFF80)==0xB080) + { + rx=inst&0x7F; + rx<<=2; + fprintf(fp,"sub sp,#0x%03X ; %u",rx,rx); + return; + } + if((inst&0xFF00)==0xDF00) + { + rx=inst&0x7F; + fprintf(fp,"swi 0x%02X ; %u",rx,rx); + return; + } + if((inst&0xFFC0)==0x4200) + { + rn=inst&7; + rm=(inst>>3)&7; + fprintf(fp,"tst r%u,r%u",rn,rm); + return; + } + + + + + + + fprintf(fp,"UNKNOWN"); +} +//------------------------------------------------------------------- +int main ( int argc, char *argv[] ) +{ + int ret; + unsigned int ra; + unsigned int rb; + unsigned int inst; + unsigned int inst2; + unsigned int found_hexstring; + + if(argc!=2) + { + printf("mas filename\n"); + return(1); + } + + fpin=fopen(argv[1],"rt"); + if(fpin==NULL) + { + printf("Error opening file [%s]\n",argv[1]); + return(1); + } + ret=assemble(); + fclose(fpin); + if(ret) + { + printf("failed %u\n",line); + return(1); + } + + found_hexstring=0; + for(ra=0;ra Error: expecting a .word\n",line); + return(1); + } + inst=rx&0xFFFF; + inst2=(rx>>16)&0xFFFF; + mem[lab_struct[ra].addr+1]=inst2; + lab_struct[ra].type++; + } + if((inst&0xF800)==0x4800) + { + //ldr rd,[pc,#immed_8] + if(lab_struct[ra].addr&1) + { + rd=rx-((lab_struct[ra].addr<<1)+2); + } + else + { + rd=rx-((lab_struct[ra].addr<<1)+4); + } + rm=0xFFFFFFFF; + rm<<=8; //I think this is wrong by two or four + if(rd&rm) + { + if((rd&rm)!=rm) + { + printf("<%u> Error: Load destination too far\n",line); + return(1); + } + } + inst|=(rd>>2)&0x7FF; + lab_struct[ra].type++; + } + if((inst&0xF000)==0xD000) + { + //bcond signed_immed_8 + rd=rx-((lab_struct[ra].addr<<1)+4); + rm=0xFFFFFFFF; + rm<<=8; + if(rd&rm) + { + if((rd&rm)!=rm) + { + printf("<%u> Error: Branch destination too far\n",line); + return(1); + } + } + inst|=(rd>>1)&0xFF; + lab_struct[ra].type++; + } + if((inst&0xF000)==0xE000) + { + //b signed_immed_11 + rd=rx-((lab_struct[ra].addr<<1)+4); + rm=0xFFFFFFFF; + rm<<=11; + if(rd&rm) + { + if((rd&rm)!=rm) + { + printf("<%u> Error: Branch destination too far\n",line); + return(1); + } + } + inst|=(rd>>1)&0x7FF; + lab_struct[ra].type++; + } + if((inst&0xF800)==0xF000) + { + inst2=mem[lab_struct[ra].addr+1]; + if((inst2&0xF800)!=0xF800) + { + printf("<%u> Error: bl should be a pair of instructions (internal error)\n",line); + return(1); + } + rd=rx-((lab_struct[ra].addr<<1)+4); + rm=0xFFFFFFFF; + rm<<=22; + if(rd&rm) + { + if((rd&rm)!=rm) + { + printf("<%u> Error: Branch destination too far\n",line); + } + } + inst|=(rd>>12)&0x7FF; + inst2|=(rd>>1)&0x7FF; + mem[lab_struct[ra].addr+1]=inst2; + lab_struct[ra].type++; + } + if(lab_struct[ra].type==1) + { + printf("<%u> Error: internal error, unknown instruction 0x%08X\n",lab_struct[ra].line,inst); + return(1); + } + mem[lab_struct[ra].addr]=inst; + break; + } + } + if(rb Error: unresolved label\n",lab_struct[ra].line); + return(1); + } + } + } + + sprintf(newline,"%s.hex",argv[1]); + fpout=fopen(newline,"wt"); + if(fpout==NULL) + { + printf("Error creating file [%s]\n",newline); + return(1); + } + + for(ra=0;ra<=ADDMASK;ra++) + { + curradd=(ra<<1); + if(mark[ra]&0x8000) + { + printf("0x%08X: 0x%04X ",curradd,mem[ra]); + if(mark[ra]&0x1000) + { + fprintf(stdout,"data"); + } + else + { + dissassemble(stdout,curradd,mem[ra]); + } + printf("\n"); + + //rb=0x04; + //rb+=(curradd>>8)&0xFF; + //rb+=(curradd>>0)&0xFF; + //rb+=0x00; + //rb+=(mem[ra]>>24)&0xFF; + //rb+=(mem[ra]>>16)&0xFF; + //rb+=(mem[ra]>> 8)&0xFF; + //rb+=(mem[ra]>> 0)&0xFF; + //rb=(-rb)&0xFF; + //fprintf(fpout,":%02X%04X%02X%08X%02X\n",0x04,curradd&0xFFFF,0x00,mem[ra],rb); + } + } + + fclose(fpout); + + + sprintf(newline,"%s.s",argv[1]); + fpout=fopen(newline,"wt"); + if(fpout==NULL) + { + printf("Error creating file [%s]\n",newline); + return(1); + } + for(ra=0;ra<=ADDMASK;ra++) + { + curradd=(ra<<1); + if(mark[ra]&0x8000) + { + //fprintf(fpout,"0x%08X: 0x%04X ",curradd,mem[ra]); + if(mark[ra]&0x1000) + { + fprintf(fpout,"data"); + } + else + { + dissassemble(fpout,curradd,mem[ra]); + } + fprintf(fpout,"\n"); + } + } + fclose(fpout); + + sprintf(newline,"%s.diss",argv[1]); + fpout=fopen(newline,"wt"); + if(fpout==NULL) + { + printf("Error creating file [%s]\n",newline); + return(1); + } + for(ra=0;ra<=ADDMASK;ra++) + { + curradd=(ra<<1); + if(mark[ra]&0x8000) + { + fprintf(fpout,"0x%08X: 0x%04X ",curradd,mem[ra]); + if(mark[ra]&0x1000) + { + fprintf(fpout,"data"); + } + else + { + dissassemble(fpout,curradd,mem[ra]); + } + fprintf(fpout,"\n"); + } + } + fclose(fpout); + + rb=0; + for(ra=0;ra<=ADDMASK;ra++) + { + if(mark[ra]&0x8000) rb=ra; + } + sprintf(newline,"%s.bin",argv[1]); + fpout=fopen(newline,"wb"); + if(fpout==NULL) + { + printf("Error creating file [%s]\n",newline); + return(1); + } + fwrite(mem,2,rb+1,fpout); + fclose(fpout); + + return(0); +} +//------------------------------------------------------------------- +//------------------------------------------------------------------- +//------------------------------------------------------------------- + + diff --git a/tas/test.s b/tas/test.s new file mode 100644 index 0000000..d8fe3d5 --- /dev/null +++ b/tas/test.s @@ -0,0 +1,7 @@ + mov r7,#0 +top: + mov r0,r7 + bl hexstring + add r7,#1 + b top +