added thumb assembler example, this is not part of an asm tutorial just

testing the new thumb assembler mods.
This commit is contained in:
David Welch
2012-06-15 13:38:37 -04:00
parent 794354527d
commit ec4a2220f8
7 changed files with 425 additions and 211 deletions

View File

@@ -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.

View File

@@ -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 <reset>
;
; 00000004 <reset>:
; 4: e59fd004 ldr sp, [pc, #4] ; 10 <stack_start>
; 8: e59f0004 ldr r0, [pc, #4] ; 14 <thumb_start_add>
; c: e12fff10 bx r0
;
; 00000010 <stack_start>:
; 10: 08000000
;
; 00000014 <thumb_start_add>:
; 14: 00000021
; 18: 00000000
; 1C: 00000000
;
; 00000020 <thumb_start>:
;
;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 .

18
tas/armstart_source.s Normal file
View File

@@ -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 .

44
tas/blinker01.s Normal file
View File

@@ -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

46
tas/hexstring.s Normal file
View File

@@ -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;

436
tas/tas.c
View File

@@ -7,9 +7,12 @@
#include <stdlib.h>
#include <string.h>
#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<nlabs;lab++)
@@ -413,7 +407,7 @@ int assemble ( void )
}
if(lab<nlabs)
{
printf("<%u> 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<<rx))
{
printf("<%u> 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<<rx);
if(newline[ra]=='}')
@@ -1049,7 +1080,7 @@ int assemble ( void )
}
else
{
printf("<%u> 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<<rx))
{
printf("<%u> 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<<rx);
if(newline[ra]=='}')
@@ -1602,7 +1633,7 @@ int assemble ( void )
{
if(rn!=13)
{
printf("<%u> 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<nlabs;ra++)
{
printf("label%04u: [0x%08X] [%s] %u\n",ra,lab_struct[ra].addr,lab_struct[ra].name,lab_struct[ra].type);
if(lab_struct[ra].type==1)
{
if(strcmp(lab_struct[ra].name,"hexstring")==0)
{
found_hexstring=1;
}
}
if(found_hexstring) break;
}
if(found_hexstring)
{
if(curradd&1)
{
mem[curradd]=0x0000;
mark[curradd]|=0x9000;
curradd++;
}
strcpy(lab_struct[nlabs].name,"hexstring");
lab_struct[nlabs].addr=curradd<<1;
lab_struct[nlabs].line=0;
lab_struct[nlabs].type=0;
nlabs++;
mem[curradd]=0xB5FE; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x4913; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x4e13; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x2420; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x270f; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x2220; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x3c04; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x1c03; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x40e3; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x403b; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x1c1d; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x3530; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x2b09; mark[curradd]=0x8000; curradd++;
mem[curradd]=0xd900; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x3507; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x680b; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x421a; mark[curradd]=0x8000; curradd++;
mem[curradd]=0xd0fc; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x6035; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x2c00; mark[curradd]=0x8000; curradd++;
mem[curradd]=0xd1f0; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x4909; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x2220; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x680b; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x421a; mark[curradd]=0x8000; curradd++;
mem[curradd]=0xd0fc; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x4b07; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x220d; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x4905; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x601a; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x2220; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x680b; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x421a; mark[curradd]=0x8000; curradd++;
mem[curradd]=0xd0fc; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x4b03; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x220a; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x601a; mark[curradd]=0x8000; curradd++;
mem[curradd]=0xbcfe; mark[curradd]=0x8000; curradd++;
mem[curradd]=0xbc01; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x4700; mark[curradd]=0x8000; curradd++;
mem[curradd]=0x5054; mark[curradd]=0x9000; curradd++;
mem[curradd]=0x2021; mark[curradd]=0x9000; curradd++;
mem[curradd]=0x5040; mark[curradd]=0x9000; curradd++;
mem[curradd]=0x2021; mark[curradd]=0x9000; curradd++;
}
currlevel=0;
for(ra=0;ra<nlabs;ra++)
{
@@ -2633,7 +2703,8 @@ int main ( int argc, char *argv[] )
{
rx=lab_struct[rb].addr;
inst=mem[lab_struct[ra].addr];
line=lab_struct[ra].line;
line[currlevel]=lab_struct[ra].line;
strcpy(filename[currlevel],lab_struct[ra].fname);
if((inst&0xF800)==0x0000)
{
//no this really isnt an lsl, using this to
@@ -2641,9 +2712,10 @@ int main ( int argc, char *argv[] )
inst2=mem[lab_struct[ra].addr+1];
if((inst2&0xF800)!=0x0000)
{
printf("<%u> 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<nlabs) ; else
{
printf("<%u> Error: unresolved label\n",lab_struct[ra].line);
printf("<%s:%u> Error: unresolved label\n",filename[currlevel],line[currlevel]);
return(1);
}
}

View File

@@ -1,7 +1,8 @@
.include armstart.s
mov r7,#0
top:
mov r0,r7
bl hexstring
add r7,#1
b top
.include hexstring.s