diff --git a/tas/README b/tas/README index 321ad3d..f7115d4 100644 --- a/tas/README +++ b/tas/README @@ -3,20 +3,25 @@ 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. +I added the .include directive in the original thumbulator this one has +a base address, still flushing that out. -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. +This is headed towards a learn assembly tutorial using this easy to +compile tool if building binutils is not working for you or too +intimidating right now. Also binutils separates assemble and link +and linker scripts are a programming language themselves. -One simple test program provided, thats it +by adding .include things like the little bit of arm code needed to +get you into thumb mode. And a pre-compiled implementation of hexstring +and uart_init so you dont have to have tools or understand how that +code works to get started in the environment I invision for a learn +asm tutorial. -./tas test.s +If you dont have anything to talk to the uart (see top level readme) +then the blinker example should work at a minimum -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. +./tas blinker01.s + +gives you blinker01.s.bin which you should be able to copy to kernel.img +on your sd card and when you power cycle it should come up and blink the +led. diff --git a/tas/armstart.s b/tas/armstart.s index 3a2727e..3edbaea 100644 --- a/tas/armstart.s +++ b/tas/armstart.s @@ -1,18 +1,46 @@ -.globl _start -_start: - b reset -reset: - ldr sp,stack_start - ldr r0,thumb_start_add - bx r0 +; 00000000 <_start>: +; 0: eaffffff b 4 +; +; 00000004 : +; 4: e59fd004 ldr sp, [pc, #4] ; 10 +; 8: e59f0004 ldr r0, [pc, #4] ; 14 +; c: e12fff10 bx r0 +; +; 00000010 : +; 10: 08000000 +; +; 00000014 : +; 14: 00000021 +; 18: 00000000 +; 1C: 00000000 +; +; 00000020 : +; +;0x00000000 +.hword 0xFFFF +.hword 0xEAFF +;0x00000004 +.hword 0xD004 +.hword 0xE59F +;0x00000008 +.hword 0x0004 +.hword 0xE59F +;0x0000000C +.hword 0xFF10 +.hword 0xE12F +;0x00000010 +.hword 0x0000 +.hword 0x0800 +;0x00000014 +.hword 0x8021 +.hword 0x0000 +;0x00000018 +.hword 0x0000 +.hword 0x0000 +;0x0000001C +.hword 0x0000 +.hword 0x0000 +;0x00000020 -stack_start: .word 0x1000 -thumb_start_add: .word thumb_start -.word 0 -.word 0 -.thumb -.thumb_func -thumb_start: - b . diff --git a/tas/armstart_source.s b/tas/armstart_source.s new file mode 100644 index 0000000..3a2727e --- /dev/null +++ b/tas/armstart_source.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/blinker01.s b/tas/blinker01.s new file mode 100644 index 0000000..d0b38e2 --- /dev/null +++ b/tas/blinker01.s @@ -0,0 +1,44 @@ + +.include armstart.s + +;configure gpio as an output + ldr r0,GPFSEL1 + ldr r1,[r0] + + ;ra&=~(7<<18); zero bits 18,19,20 + mov r2,#0x7 + lsl r2,r2,#18 + bic r1,r2 + ;ra|=1<<18; set bit 18 + mov r2,#0x1 + lsl r2,r2,#18 + orr r1,r2 + str r1,[r0] + + ;prepare registers for loop + ldr r0,GPSET0 + ldr r1,GPCLR0 + mov r2,#1 + lsl r3,r2,#16 ;(1<<16) + lsl r4,r2,#24 ;start count for counting loop +top: + str r3,[r0] + + mov r5,r4 +on: + sub r5,#1 + bne on + + str r3,[r1] + + mov r5,r4 +off: + sub r5,#1 + bne off + + b top + +.align +GPFSEL1: .word 0x20200004 +GPSET0: .word 0x2020001C +GPCLR0: .word 0x20200028 diff --git a/tas/hexstring.s b/tas/hexstring.s new file mode 100644 index 0000000..c68cd1c --- /dev/null +++ b/tas/hexstring.s @@ -0,0 +1,46 @@ +.align +hexstring: +.hword 0xB5FE; +.hword 0x4913; +.hword 0x4e13; +.hword 0x2420; +.hword 0x270f; +.hword 0x2220; +.hword 0x3c04; +.hword 0x1c03; +.hword 0x40e3; +.hword 0x403b; +.hword 0x1c1d; +.hword 0x3530; +.hword 0x2b09; +.hword 0xd900; +.hword 0x3507; +.hword 0x680b; +.hword 0x421a; +.hword 0xd0fc; +.hword 0x6035; +.hword 0x2c00; +.hword 0xd1f0; +.hword 0x4909; +.hword 0x2220; +.hword 0x680b; +.hword 0x421a; +.hword 0xd0fc; +.hword 0x4b07; +.hword 0x220d; +.hword 0x4905; +.hword 0x601a; +.hword 0x2220; +.hword 0x680b; +.hword 0x421a; +.hword 0xd0fc; +.hword 0x4b03; +.hword 0x220a; +.hword 0x601a; +.hword 0xbcfe; +.hword 0xbc01; +.hword 0x4700; +.hword 0x5054; +.hword 0x2021; +.hword 0x5040; +.hword 0x2021; diff --git a/tas/tas.c b/tas/tas.c index d6d8e66..f0054b3 100644 --- a/tas/tas.c +++ b/tas/tas.c @@ -7,9 +7,12 @@ #include #include +#define MAXINCLUDES 10 +#define FNAMELEN 255 -FILE *fpin; +FILE *fpin[MAXINCLUDES]; FILE *fpout; +unsigned char filename[FNAMELEN][MAXINCLUDES]; unsigned int rd,rm,rn,rx; unsigned int bl_upper; @@ -19,8 +22,10 @@ unsigned int is_const,is_label; unsigned short mem[ADDMASK+1]; unsigned short mark[ADDMASK+1]; +unsigned int baseadd; unsigned int curradd; -unsigned int line; +unsigned int line[MAXINCLUDES]; +unsigned int currlevel; char cstring[1024]; char newline[1024]; @@ -35,6 +40,7 @@ struct unsigned int addr; unsigned int line; unsigned int type; + char fname[FNAMELEN]; } lab_struct[MAX_LABS]; unsigned int nlabs; unsigned int lab; @@ -101,7 +107,7 @@ 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); + printf("<%s:%u> Error: garbage at end of line\n",filename[currlevel],line[currlevel]); return(1); } return(0); @@ -138,7 +144,7 @@ unsigned int parse_immed ( unsigned int ra ) if(newline[ra]==0x20) break; if(!hexchar[newline[ra]]) { - printf("<%u> Error: invalid number\n",line); + printf("<%s:%u> Error: invalid number\n",filename[currlevel],line[currlevel]); return(0); } cstring[rb++]=newline[ra]; @@ -146,7 +152,7 @@ unsigned int parse_immed ( unsigned int ra ) cstring[rb]=0; if(rb==0) { - printf("<%u> Error: invalid number\n",line); + printf("<%s:%u> Error: invalid number\n",filename[currlevel],line[currlevel]); return(0); } rx=strtoul(cstring,NULL,16); @@ -161,7 +167,7 @@ unsigned int parse_immed ( unsigned int ra ) if(newline[ra]==0x20) break; if(!numchar[newline[ra]]) { - printf("<%u> Error: invalid number\n",line); + printf("<%s:%u> Error: invalid number\n",filename[currlevel],line[currlevel]); return(0); } cstring[rb++]=newline[ra]; @@ -169,7 +175,7 @@ unsigned int parse_immed ( unsigned int ra ) cstring[rb]=0; if(rb==0) { - printf("<%u> Error: invalid number\n",line); + printf("<%s:%u> Error: invalid number\n",filename[currlevel],line[currlevel]); return(0); } rx=strtoul(cstring,NULL,10); @@ -195,7 +201,7 @@ unsigned int parse_reg ( unsigned int ra ) cstring[rb]=0; if(get_reg_number(cstring,&rx)) { - printf("<%u> Error: not a register\n",line); + printf("<%s:%u> Error: not a register\n",filename[currlevel],line[currlevel]); return(0); } for(;newline[ra];ra++) if(newline[ra]!=0x20) break; @@ -220,12 +226,12 @@ unsigned int parse_low_reg ( unsigned int ra ) cstring[rb]=0; if(get_reg_number(cstring,&rx)) { - printf("<%u> Error: not a register\n",line); + printf("<%s:%u> Error: not a register\n",filename[currlevel],line[currlevel]); return(0); } if(rx>7) { - printf("<%u> Error: invalid (high) register\n",line); + printf("<%s:%u> Error: invalid (high) register\n",filename[currlevel],line[currlevel]); return(0); } for(;newline[ra];ra++) if(newline[ra]!=0x20) break; @@ -237,7 +243,7 @@ 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); + printf("<%s:%u> Error: syntax error\n",filename[currlevel],line[currlevel]); return(0); } ra++; @@ -250,7 +256,7 @@ 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); + printf("<%s:%u> Error: syntax error\n",filename[currlevel],line[currlevel]); return(0); } ra++; @@ -298,13 +304,13 @@ unsigned int parse_branch_label ( unsigned int ra ) rc=rb-ra; if(rc==0) { - printf("<%u> Error: Invalid label\n",line); + printf("<%s:%u> Error: Invalid label\n",filename[currlevel],line[currlevel]); return(0); } rc--; if(rc>=LABLEN) { - printf("<%u> Error: Label too long\n",line); + printf("<%s:%u> Error: Label too long\n",filename[currlevel],line[currlevel]); return(0); } for(rb=0;rb<=rc;rb++) @@ -313,7 +319,8 @@ unsigned int parse_branch_label ( unsigned int ra ) } lab_struct[nlabs].name[rb]=0; lab_struct[nlabs].addr=curradd; - lab_struct[nlabs].line=line; + lab_struct[nlabs].line=line[currlevel]; + strcpy(lab_struct[nlabs].fname,filename[currlevel]); lab_struct[nlabs].type=1; nlabs++; rx=0; @@ -322,40 +329,26 @@ unsigned int parse_branch_label ( unsigned int ra ) return(ra); }//------------------------------------------------------------------- //------------------------------------------------------------------- -int assemble ( void ) +int assemble ( unsigned int level ) { unsigned int ra; unsigned int rb; unsigned int rc; + int ret; +printf("assemble(%u)\n",level); - curradd=0; - nlabs=0; - memset(mem,0x00,sizeof(mem)); - memset(mark,0x00,sizeof(mark)); + currlevel=level; - //.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)) + if(level>=MAXINCLUDES) { - line++; + printf("<%s:%u> Error: too many levels of include\n",filename[currlevel],line[currlevel]); + return(1); + } + + while(fgets(newline,sizeof(newline)-1,fpin[level])) + { + line[level]++; //tabs to spaces and other things for(ra=0;newline[ra];ra++) { @@ -388,13 +381,13 @@ int assemble ( void ) rc=rb-ra; if(rc==0) { - printf("<%u> Error: Invalid label\n",line); + printf("<%s:%u> Error: Invalid label\n",filename[currlevel],line[currlevel]); return(1); } rc--; if(rc>=LABLEN) { - printf("<%u> Error: Label too long\n",line); + printf("<%s:%u> Error: Label too long\n",filename[currlevel],line[currlevel]); return(1); } for(rb=0;rb<=rc;rb++) @@ -403,7 +396,8 @@ int assemble ( void ) } lab_struct[nlabs].name[rb]=0; lab_struct[nlabs].addr=curradd<<1; - lab_struct[nlabs].line=line; + lab_struct[nlabs].line=line[currlevel]; + strcpy(lab_struct[nlabs].fname,filename[currlevel]); 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); + printf("<%s:%u> Error: label [%s] already defined on line %u\n",filename[currlevel],line[currlevel],lab_struct[lab].name,lab_struct[lab].line); return(1); } nlabs++; @@ -421,6 +415,43 @@ int assemble ( void ) for(;newline[ra];ra++) if(newline[ra]!=0x20) break; if(newline[ra]==0) continue; } +// .include ----------------------------------------------------------- + if(strncmp(&newline[ra],".include ",9)==0) + { + if((level+1)>=MAXINCLUDES) + { + printf("<%s:%u> Error: too many levels of include\n",filename[currlevel],line[currlevel]); + return(1); + } + ra+=9; + for(;newline[ra];ra++) if(newline[ra]!=0x20) break; + for(rd=0;newline[ra];ra++,rd++) + { + if(rd>=FNAMELEN) + { + printf("<%s:%u> Error: filename too long\n",filename[currlevel],line[currlevel]); + return(1); + } + filename[level+1][rd]=newline[ra]; + if(newline[ra]==0x20) break; + } + filename[level+1][rd]=0; + if(rest_of_line(ra)) return(1); + fpin[level+1]=fopen(filename[level+1],"rt"); + if(fpin[level+1]==NULL) + { + printf("<%s:%u> Error opening file [%s]\n",filename[currlevel],line[currlevel],filename[level+1]); + return(1); + } + line[level+1]=0; + ret=assemble(level+1); + fclose(fpin[level+1]); + if(ret) + { + return(1); + } + continue; + } // .align ----------------------------------------------------------- if(strncmp(&newline[ra],".align",6)==0) { @@ -428,7 +459,7 @@ int assemble ( void ) if(rest_of_line(ra)) return(1); if(curradd&1) { - printf("<%u> Adding halfword to align on a word boundary\n",line); + printf("<%s:%u> Adding halfword to align on a word boundary\n",filename[currlevel],line[currlevel]); mem[curradd]=0x0000; mark[curradd]|=0x9000; curradd++; @@ -441,7 +472,7 @@ int assemble ( void ) ra+=6; if(curradd&1) { - printf("<%u> Error: not word aligned\n",line,lab_struct[lab].name,lab_struct[lab].line); + printf("<%s:%u> Error: not word aligned\n",filename[currlevel],line[currlevel]); return(1); } for(;newline[ra];ra++) if(newline[ra]!=0x20) break; @@ -451,7 +482,7 @@ int assemble ( void ) ra=parse_branch_label(ra); if(ra==0) return(1); if((is_const)||(!is_label)) { - printf("<%u> Error: expecting a label\n",line); + printf("<%s:%u> Error: expecting a label\n",filename[currlevel],line[currlevel]); return(1); } mem[curradd]=0x0000; @@ -488,7 +519,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0xFFFF)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } mem[curradd]=rx; @@ -535,7 +566,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x1FC)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //add sp,#immed_7*4 @@ -562,7 +593,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0xFF)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //add rd,#immed_8 @@ -584,7 +615,7 @@ int assemble ( void ) ra=parse_comma(ra); if(ra==0) return(1); if(newline[ra]!='#') { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } if(rm==15) @@ -593,7 +624,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x3FC)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //add rd,pc,#immed_8*4 @@ -608,7 +639,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x3FC)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //add rd,pc,#immed_8*4 @@ -618,7 +649,7 @@ int assemble ( void ) } else { - printf("<%u> Error: Invalid second register\n",line); + printf("<%s:%u> Error: Invalid second register\n",filename[currlevel],line[currlevel]); return(1); } } @@ -642,7 +673,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x7)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //add rd,rm,#immed_3 @@ -693,7 +724,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx<1)||(rx>32)) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } rx&=0x1F; @@ -704,7 +735,7 @@ int assemble ( void ) } else { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } } @@ -741,7 +772,7 @@ int assemble ( void ) { if((rd&rm)!=rm) { - printf("<%u> Error: Branch destination too far\n",line); + printf("<%s:%u> Error: Branch destination too far\n",filename[currlevel],line[currlevel]); return(1); } } @@ -790,7 +821,7 @@ int assemble ( void ) { if((rd&rm)!=rm) { - printf("<%u> Error: Branch destination too far\n",line); + printf("<%s:%u> Error: Branch destination too far\n",filename[currlevel],line[currlevel]); return(1); } } @@ -823,7 +854,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0xFF)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } mem[curradd]=0xBE00|rx; @@ -858,7 +889,7 @@ int assemble ( void ) { if((rd&rm)!=rm) { - printf("<%u> Error: Branch destination too far\n",line); + printf("<%s:%u> Error: Branch destination too far\n",filename[currlevel],line[currlevel]); return(1); } } @@ -917,7 +948,7 @@ int assemble ( void ) { if(rm==15) { - printf("<%u> Error: Not wise to use r15 in this way\n",line); + printf("<%s:%u> Error: Not wise to use r15 in this way\n",filename[currlevel],line[currlevel]); return(1); } //cmp rn,rm one or the other high @@ -941,7 +972,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0xFF)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //cmp rn,#immed_8 @@ -957,7 +988,7 @@ int assemble ( void ) { if(rm==15) { - printf("<%u> Error: Not wise to use r15 in this way\n",line); + printf("<%s:%u> Error: Not wise to use r15 in this way\n",filename[currlevel],line[currlevel]); return(1); } //cmp rn,rm one or the other high @@ -1006,7 +1037,7 @@ int assemble ( void ) ra=parse_low_reg(ra); if(ra==0) return(1); if(rm&(1< Warning: You already specified r%u\n",line,rx); + printf("<%s:%u> Warning: You already specified r%u\n",filename[currlevel],line[currlevel],rx); } rm|=(1< Error: Invalid base register\n",line); + printf("<%s:%u> Error: Invalid base register\n",filename[currlevel],line[currlevel]); return(1); } if(newline[ra]==']') @@ -1063,7 +1094,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x3FC)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } } @@ -1088,7 +1119,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x7C)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } ra=parse_character(ra,']'); if(ra==0) return(1); @@ -1122,7 +1153,7 @@ int assemble ( void ) ra=parse_branch_label(ra); if(ra==0) return(1); if(is_const) { - printf("<%u> Error: not a label",line); + printf("<%s:%u> Error: not a label",filename[currlevel],line[currlevel]); return(1); } mem[curradd]=0x4800|(rd<<8)|0; @@ -1154,7 +1185,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x1F)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } ra=parse_character(ra,']'); if(ra==0) return(1); @@ -1206,7 +1237,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&(0x1F<<1))!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } ra=parse_character(ra,']'); if(ra==0) return(1); @@ -1296,7 +1327,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx<1)||(rx>32)) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } rx&=0x1F; @@ -1333,7 +1364,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx<1)||(rx>32)) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } rx&=0x1F; @@ -1379,7 +1410,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0xFF)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //mov rd,#immed_8 @@ -1419,7 +1450,7 @@ int assemble ( void ) 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); + printf("<%s:%u> Warning: using the same register might not work\n",filename[currlevel],line[currlevel]); } mem[curradd]=0x4340|(rm<<3)|rd; mark[curradd]=0x8000; @@ -1477,7 +1508,7 @@ int assemble ( void ) { if(rx!=15) { - printf("<%u> Error: Invalid Register\n",line); + printf("<%s:%u> Error: Invalid Register\n",filename[currlevel],line[currlevel]); return(1); } rx=8; @@ -1510,7 +1541,7 @@ int assemble ( void ) { if(rx!=14) { - printf("<%u> Error: Invalid Register\n",line); + printf("<%s:%u> Error: Invalid Register\n",filename[currlevel],line[currlevel]); return(1); } rx=8; @@ -1569,7 +1600,7 @@ int assemble ( void ) ra=parse_low_reg(ra); if(ra==0) return(1); if(rm&(1< Warning: You already specified r%u\n",line,rx); + printf("<%s:%u> Warning: You already specified r%u\n",filename[currlevel],line[currlevel],rx); } rm|=(1< Error: Invalid base register\n",line); + printf("<%s:%u> Error: Invalid base register\n",filename[currlevel],line[currlevel]); return(1); } if(newline[ra]==']') @@ -1616,7 +1647,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x3FC)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } } @@ -1638,7 +1669,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x7C)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } ra=parse_character(ra,']'); if(ra==0) return(1); @@ -1691,7 +1722,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x1F)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } ra=parse_character(ra,']'); if(ra==0) return(1); @@ -1743,7 +1774,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&(0x1F<<1))!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } ra=parse_character(ra,']'); if(ra==0) return(1); @@ -1793,7 +1824,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x1FC)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //sub sp,#immed_7*4 @@ -1803,7 +1834,7 @@ int assemble ( void ) } else { - printf("<%u> Error: Invalid rd register\n",line); + printf("<%s:%u> Error: Invalid rd register\n",filename[currlevel],line[currlevel]); return(1); } } @@ -1816,7 +1847,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0xFF)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //sub rd,#immed_8 @@ -1839,7 +1870,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0x7)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } //sub rd,rm,#immed_3 @@ -1871,7 +1902,7 @@ int assemble ( void ) ra=parse_immed(ra); if(ra==0) return(1); if((rx&0xFF)!=rx) { - printf("<%u> Error: Invalid immediate\n",line); + printf("<%s:%u> Error: Invalid immediate\n",filename[currlevel],line[currlevel]); return(1); } mem[curradd]=0xDF00|rx; @@ -1909,14 +1940,114 @@ int assemble ( void ) // ----------------------------------------------------------- - printf("<%u> Error: syntax error\n",line); + printf("<%s:%u> Error: syntax error\n",filename[currlevel],line[currlevel]); 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++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1111; mark[curradd]=0x8000; curradd++; + + + //mem[curradd]=0xb5f0; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4657; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x464e; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4645; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0xb4e0; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x688b; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x680e; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x684d; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x68cf; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x491a; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x6804; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x6842; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x469c; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x46b1; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x46a8; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x2300; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x468a; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4e17; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x0115; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x199e; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x18b1; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x444d; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x404d; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x0951; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4441; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x404d; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1965; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x012c; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x0969; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4464; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x19c9; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x19ae; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4061; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4071; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4c0f; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x1851; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x191b; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x010c; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x185a; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x444c; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x094e; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4054; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4446; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4074; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x192c; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x0126; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x0962; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4466; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x19d2; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4072; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x18e5; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x406a; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x188a; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4553; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0xd1d9; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x6004; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x6042; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0xbc1c; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4690; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x4699; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x46a2; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0xbdf0; mark[curradd]=0x8000; curradd++; + //mem[curradd]=0x3720; mark[curradd]=0x9000; curradd++; + //mem[curradd]=0xc6ef; mark[curradd]=0x9000; curradd++; + //mem[curradd]=0x79b9; mark[curradd]=0x9000; curradd++; + //mem[curradd]=0x9e37; mark[curradd]=0x9000; curradd++; + //mem[curradd]=0xf372; mark[curradd]=0x9000; curradd++; + //mem[curradd]=0x3c6e; mark[curradd]=0x9000; curradd++; + + + + + + + + + + + + + + + + + + return(0); } @@ -2526,100 +2657,39 @@ int main ( int argc, char *argv[] ) unsigned int rb; unsigned int inst; unsigned int inst2; - unsigned int found_hexstring; if(argc!=2) { - printf("mas filename\n"); + printf("tas filename\n"); return(1); } - fpin=fopen(argv[1],"rt"); - if(fpin==NULL) +baseadd=0x8000; + + currlevel=0; + curradd=0; + nlabs=0; + memset(mem,0x00,sizeof(mem)); + memset(mark,0x00,sizeof(mark)); + + strcpy(filename[0],argv[1]); + + fpin[0]=fopen(argv[1],"rt"); + if(fpin[0]==NULL) { printf("Error opening file [%s]\n",argv[1]); return(1); } - ret=assemble(); - fclose(fpin); + line[0]=0; + ret=assemble(0); + fclose(fpin[0]); if(ret) { - printf("failed %u\n",line); + printf("failed %u\n",line[0]); return(1); } - found_hexstring=0; - for(ra=0;ra Error: expecting a .word\n",line); + printf("<%s:%u> Error: expecting a .word\n",filename[currlevel],line[currlevel]); return(1); } + rx+=baseadd; inst=rx&0xFFFF; inst2=(rx>>16)&0xFFFF; mem[lab_struct[ra].addr+1]=inst2; @@ -2666,7 +2738,7 @@ int main ( int argc, char *argv[] ) { if((rd&rm)!=rm) { - printf("<%u> Error: Load destination too far\n",line); + printf("<%s:%u> Error: Load destination too far\n",filename[currlevel],line[currlevel]); return(1); } } @@ -2683,7 +2755,7 @@ int main ( int argc, char *argv[] ) { if((rd&rm)!=rm) { - printf("<%u> Error: Branch destination too far\n",line); + printf("<%s:%u> Error: Branch destination too far\n",filename[currlevel],line[currlevel]); return(1); } } @@ -2700,7 +2772,7 @@ int main ( int argc, char *argv[] ) { if((rd&rm)!=rm) { - printf("<%u> Error: Branch destination too far\n",line); + printf("<%s:%u> Error: Branch destination too far\n",filename[currlevel],line[currlevel]); return(1); } } @@ -2712,7 +2784,7 @@ int main ( int argc, char *argv[] ) 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); + printf("<%s:%u> Error: bl should be a pair of instructions (internal error)\n",filename[currlevel],line[currlevel]); return(1); } rd=rx-((lab_struct[ra].addr<<1)+4); @@ -2722,7 +2794,7 @@ int main ( int argc, char *argv[] ) { if((rd&rm)!=rm) { - printf("<%u> Error: Branch destination too far\n",line); + printf("<%s:%u> Error: Branch destination too far\n",filename[currlevel],line[currlevel]); } } inst|=(rd>>12)&0x7FF; @@ -2732,7 +2804,7 @@ int main ( int argc, char *argv[] ) } if(lab_struct[ra].type==1) { - printf("<%u> Error: internal error, unknown instruction 0x%08X\n",lab_struct[ra].line,inst); + printf("<%s:%u> Error: internal error, unknown instruction 0x%08X\n",filename[currlevel],line[currlevel],inst); return(1); } mem[lab_struct[ra].addr]=inst; @@ -2741,7 +2813,7 @@ int main ( int argc, char *argv[] ) } if(rb Error: unresolved label\n",lab_struct[ra].line); + printf("<%s:%u> Error: unresolved label\n",filename[currlevel],line[currlevel]); return(1); } } diff --git a/tas/test.s b/tas/test.s index d8fe3d5..b81883b 100644 --- a/tas/test.s +++ b/tas/test.s @@ -1,7 +1,8 @@ +.include armstart.s mov r7,#0 top: mov r0,r7 bl hexstring add r7,#1 b top - +.include hexstring.s