Released under GPL2: An 8051-8052 2 pass assembler for the Linux OS.

Released under GPL2: An 8051-8052 2 pass assembler for the Linux OS.

formatting link

This is a very simple assembler, and has less features then all the big macro ones. But it has one feature all other ones do not have as far as I know: It can generate binary output in MCS-52 BASIC data statements. this makes writing inline asm easy in MCS-BASIC. For example the code in q2.asm: org $6000 lcall mysub ret mysub: mov $20.0,c ret when assembled like this: a52 q2.asm -l -b1000

generates these BASIC lines:

1000 rem code from q2 1002 data 18,96,4 1004 data 34 1006 data 146,0 1008 data 34 1010 org=24576 1012 for i=0 to 6 1014 read a:xby(org+i)=a:next 1016 return

You can then and do a gosub 1000 in MCS-BASIC to call the asm.

Have fun.

Reply to
Jan Panteltje
Loading thread data ...

Heh, when writing assembly in BASIC (QB specifically), I often assign everything to an array then execute it. e.g.,

DIM Code(10) 'AS INTEGER implied by DEFINT A-Z Code(0) = &H1234 ... Code(10) = &HF00F

DEF SEG = VARSEG(Code(0)) CALL ABSOLUTE(VARPTR(Code(0)), stuff) DEF SEG

That looks ugly after more than a few lines, so most of the time I read from a file as a first-run initialization. Also lots easier to maintain. Fine for simple routines that don't need to change.

I don't really like DATA, it's the idea of having something and no way to access it. I suppose assigning entries of an array is the closest thing to predefined data (as in C or ASM), but I'm willing to bet it still executes an awful lot of lines to do it. Stupid QB...

Tim

--
Deep Friar: a very philosophical monk.
Website: http://webpages.charter.net/dawill/tmoranwms
 Click to see the full signature
Reply to
Tim Williams

PowerBasic (the DOS and Console Compiler versions) have inline assembly, and it's easy to make links between the BASIC and assembly. For exaample, you can name or dim a variable in Basic and just refer to it in assembly.

John

Reply to
John Larkin

Yup, and (AFAIK) newer versions e.g. FreeBASIC, QB64 etc. also support extended features including proper OOP, inline everything, proper modern datatypes, etc. Not to mention the Windows versions supporting everything Windows.

It's really a shame Microsoft shipped their crappiest "language" with DOS. It was a computational abomination. But it was either QBasic or DEBUG, so I chose QBasic. ;^)

Tim

--
Deep Friar: a very philosophical monk.
Website: http://webpages.charter.net/dawill/tmoranwms
Reply to
Tim Williams

On a sunny day (Sun, 10 Jan 2010 19:16:49 -0600) it happened "Tim Williams" wrote in :

I am not very familiar with all those BASIC dialects, but the 8052AH has MCS-52 BASIC build in ROM. It has some limitations on array size I think. It also has the 'CALL" instruction, that selects the correct register bank, and then calls asm from BASIC. The procedure is then :

10 ....init stuff ---- 20 call 1000 : REM code to RAM at org 6000H 100 ... main program ... 200 ... do something ... 300 xby(7000h)=A : REM some data to RAM for the ASM 310 CALL 6000H : REM call the asm routine 320 B=xby(7000H) : REM get data from RAM from the asm 400 ... do something ... 500 end

1000 rem code from q2

1002 data 18,96,4 1004 data 34 1006 data 146,0 1008 data 34 1010 org=24576 1012 for i=0 to 6 1014 read a:xby(org+i)=a:next 1016 return

I did a I2C driver that way long time ago, lost the asm source (5/14/ inch floppies), first wrote a program to convert data in BASIC data statements to a binary file, then ran an open source 8051 disassembler on the binary. That gave me back the original asm, and then changed that very unclear asm code so it was my original code and added comments each line.... When disassembling it with D52 8052 Disassembler V3.4.1 Copyright (C) 1995-2007 by J. L. Post Released under the GNU General Public License Version 3 and assembling it again with my own assembler, the generated code was different. :-(

So I tried an other open source assembler, and that was even more different. Then I looked in the manual for MSC BASIC and it was again different.... Anyways, I could no longer find the bit to register mapping for that chip to check, until late last night (Sunday night), and of course the error was in my assembler's handling of bits in a register, so I fixed that and made a new release. The old release was from 1988, hardly ever used....

21 yeas for a bug to live, every code worked perfectly, just that the bits flipped were somewhere else then where you though they were... With so much on chip RAM (256 bytes), never noticed! That is why disclaimers are added to the released code...

I am thinking about adding the asm instructions as REM statement after the DATA fields like this:

1000 rem code from q2 at 6000h 1002 data 18,96,4 : REM lcall mysub 1004 data 34 :REM ret 1006 data 146,0 : REM mov $20.0,c 1008 data 34 : REM ret

Makes it more clear in case I lose the asm again :-)

Reply to
Jan Panteltje

On a sunny day (Sun, 10 Jan 2010 18:28:49 -0800) it happened John Larkin wrote in :

But does PowerBasic run on a 8051 or 8052? Or is it even native in a 8052 ROM?

Reply to
Jan Panteltje

acro ones.

I think I will ask again at work if I can publish my 8052 sim program. What format does your program make its output in?

Basic run down of what my Sim52 does:

You describe the hardware complete with perhaps more than one 8052. It "event by event" simulates the hardware including the 8052s Very advanced break point system with 16 break points Examine registers etc Assemble new code Disassemble existing code Symbols substitute for values.

Reply to
MooseFET

On a sunny day (Mon, 11 Jan 2010 06:44:29 -0800 (PST)) it happened MooseFET wrote in :

That would be nice, as I tried the ucsim that comes with sdcc: ~/compile/sdcc/sdcc/sim/ucsim it lives under the name 's51', and I have been unable to make it do *anything*, as all I get is 'cannot open file', although the files exist. The README seems to be the only documentation and this is the contents of the README: grml: ~/compile/sdcc/sdcc/sim # cat README sdcc/simulator

--------------

I have no idea :)

-- Michael

Intel Hex format, the BASIC program, and a list file.

Nice :-)

Reply to
Jan Panteltje

ET

g m=3D

hing*,

the README:

I raised the question. The Boss is thinking about it. Technically they only own part of it. I did some work on the clock but most was off the clock. We will see if anything comes of it.

I have also been thinking of making a few other projects for the 8052 public.

(1) The Intel 8051 assembler had a preprocessor ability. I have thought it would be nice to be able to take that sort of source code in and make a reformatted output that worked on a GPLed assembler.

(2) Most C for the 8051 really sucks. This is because the convert each source file to an object file and then link. This loses some information that could be used to great advantage on the

8051 processor.

2-A The type of jump and call used can be adapted based on where the code ends up in memory.

2-B They do a fairly poor job of economizing on stack use. While not doing extra Xdata transfers.

2-C Many of them store things MS then LS and end up doing a whole bunch of extra instructions because the 8051 doesn't have a DEC DPTR With LS-MS you can do this:

MOVX A,@DPTR ; Add 1234 to FOO ADD A,#34H MOVX @DPTR,A INC DPTR MOVX A,@DPTR ADDC A,#12H MOVX @DPTR,A

Reply to
MooseFET

On a sunny day (Mon, 11 Jan 2010 18:36:20 -0800 (PST)) it happened MooseFET wrote in :

Great.

The 8051 assembler was very expensive, I had it on the job, 2500$ or so? So, I could not take that home, so I wrote my own in C, on my clone CP/M system that I also wrote myself in Z80 asm. :-) So that preprocessor would indeed be a possible project.

Tell me something, I am in the middle of it. I use sdcc (open source), it has a C compiler and an assembler. It can target 8051, Z80, PIC16, and also PIC18, but only some the latter I think. What I wanted to do is compile some universal routines that take a RAM address as input, and an other RAM address as output, at org

that use all vars in RAM, so I can write real C, and start that main() from a BASIC call, and including floating point and math libs. I am halfway there, but the C looks weird full of stuff like volatile __xdata __at (0x7000) unsigned char ival1; So, why should it not be possible. But anyways that sdcc C compiler should work OK with the EPROM versions 8749? Not sure if I still have one. I still have an EPROM eraser bulb though :-)

Have a look at 'sdcc', it is big.

formatting link
It has a *lot* of command line optimising options, just beginning to investigate them all. I prefer C, as MCS-BASIC sucks anyways with those line numbers..., and is slow. I was looking last night at the asm sdcc generates, and indeed your example below is an example of that :-)

I know, this is from the 8052AH BASIC FAQ: QUESTION I am writing in assembly language and I notice that the 8052AH has no decrement DPTR instruction. What is the easiest. shortest or simplest way to decrement the DPTR? ANSWER The shortest one we know is: XCH A, DPL ; SWAPADPL JNZ DECDP ; DPH = DPH-1 IF DPL = O DEC DPH DECDP: DEC A ; DPL = DPL-1 XCH A, DPL This routine affects no flags or registers (except the DPTR) either!

Reply to
Jan Panteltje

ET

[... 8051 and C compilers ...]

I also have written my own. It started off as just a project to add a feature to an existing one but I discovered that the existing one was a complete "pigs breakfast" internally. It obviously had been written by patching bugs.

It is actually not that hard to make a 8051 assembler because each line is processed independently of the others except for the symbol values.

I think.

org

om

My idea was to cause the "C compiler" to output a predigested intermediate version and not a fully compiled result. The "linker" would be what actually makes it into machine language.

I think you don't want a space between the "_at" and the "(". You can supply an include file that looks like this:

#define __xdata__at(foo) #define __code__at(foo) ... etc ...

If you include this file, the normal C compiler will like the code because it doesn't have any weird stuff in it after the preprocessor is done with it.

[...]

stigate them all.

I have looked at sdcc several times and then gone back to assembly. At this point my code is mostly calls to existing routines. I have a nice 32 bit math library. RS-232 routines and the like. One very nice routine I have takes a 32 or 64 bit number and formats it with a decimal place etc. The input values are something like:

R0 A work space of 10 bytes R1 The number to be processed R2 The nature of the number: D7 The number is signed D6 The number is 64 bit D3..0 The number of digits below the decimal of the number its self R3 The format: D7..D4 The number of digits before the decimal D3..D0 The number of digits after the decimal R4 The options: D7 Put a plus sign on positive values D6 Remove leading zeros down to "0." D5 Remove trailing zeros up to ".0" D4 Remove ".0" if not needed D3 Right justify result \ Both means D2 Left justify result / squash out spaces

slow.

I used the basic in a product I shipped. I rewrote it later in assembler. The Basic version couldn't keep up in a few cases. The customer for the first ones didn't care. The later customers really did.

le below is an example of that :-)

rement DPTR instruction.

=A0 A, DPL =A0 =A0 =A0 =A0 =A0; SWAPADPL

=A0 DECDP =A0 =A0 =A0 =A0 =A0 ; DPH =3D DPH-1 IF DPL =3D O

=A0 DPH

=A0 =A0 =A0 =A0 =A0 =A0 =A0 ; DPL =3D DPL-1

=A0 A, DPL

Yes this is very like what I do in the rare cases I need it. On the silabs this may be faster:

XRL DPL,#0FFH XRL DPH,#0FFH INC DPTR XRL DPL,#0FFH XRL DPH,#0FFH

The Silabs machines slow down if a jump takes you to a new 4 byte hunk of memory that doesn't happen to be in cache. I currently have some code running that uses 95% of CPU time so I care about a machine cycle or two. The 95% is in interrupt routines. It is great fun to trouble shoot so I write with great care.

Reply to
MooseFET

On a sunny day (Tue, 12 Jan 2010 06:55:56 -0800 (PST)) it happened MooseFET wrote in :

I have been trying some more sdcc calls from MCS-BASIC. So far the code seems to execute, but somehow then BASIC messes up baudrate and I cannot see the result. So obviously some registers are used by sdcc that are also used by MSC-BASIC. A puzzle. Will try some more later ... :-) Indeed asm rules, at least you know what happens. So I disassemble the code generated by sdcc for inspection to see what it does.

Also wrote a program to make data statements in MSC-BASIC from Intel format hexfiles, so I can just upload the code as BASIC lines. The line number is the is now address!

10 gosub 24574 : REM sdcc code to RAM 20 xby(7000h)=111 : REM value to be worked on by sdcc code 30 call 24576 : REM call sdcc code 40 print xby(7001h) : REM print result 50 end

24574 REM code from file.bas by hxl from file.hex

24572 REM org=24576 last address used=24693 24576 DATA 2 24577 DATA 96 ..... 4691 DATA 130 24692 DATA 0 24693 DATA 34 24694 FOR I=24576 TO 24693 24695 READ A : XBY(I)=A : NEXT 24696 RETURN

With one byte per data statement, for short routines this should do. The 'hxl' program is still being developed, if anyone wants a copy ask me.

Reply to
Jan Panteltje

On a sunny day (Tue, 12 Jan 2010 19:09:55 GMT) it happened Jan Panteltje wrote in :

OK, cracked it. The sdcc sets a new stackpointer, if you call the routine you write 'main'. Have to call it something else and it works!

#include #include #include

int dmain() { volatile __xdata __at (0x7000) unsigned char ival1; volatile __xdata __at (0x7001) unsigned char uval1; uval1 = ival1+3; return 1; }

10 GOSUB 24572 20 XBY(7000H)=111 30 PRINT XBY(7001H) 40 CALL 24576 50 PRINT XBY(7001H) 60 END 24572 REM org=24576 last address used=24591 24574 REM code from file.bas by hxl from file.hex 24576 DATA 144 24577 DATA 112 24578 DATA 0 24579 DATA 224 24580 DATA 250 24581 DATA 144 24582 DATA 112 24583 DATA 1 24584 DATA 116 24585 DATA 3 24586 DATA 42 24587 DATA 240 24588 DATA 144 24589 DATA 0 24590 DATA 1 24591 DATA 34 24592 FOR I=24576 TO 24591 24593 READ A : XBY(I)=A : NEXT 24594 RETURN

READY

0 114

READY

Here is the Makefile I used:

# GNU Makefile example using SDCC ######################################################################## # GNU Makefile demonstrating combination of C and assembly source files # File Name: makefile # All targets in the makefile are processed sequentially by SDCC # To create the file File.hex' using GNU make, just execute Make' ########################################################################

# The following lines defines additional directories to search for include files #INCLUDES := -I"C:\Your Directory\Lab3\"

# The following line defines flags given to the SDCC C compiler CFLAGS := -c --main-return --model-large $(INCLUDES)

# The following line defines flags given to the SDCC linker # Non-specific: ­code-loc 0x6000 ­xram-loc 0xB000 ­model-large #LFLAGS := --code-loc 0x6000 --code-size 0x5000 --xram-loc 0x000 --xram-size

0x8000 --model-large LFLAGS := --code-loc 0x6000 --model-large --xstack #LFLAGS := --code-loc 0x6000 --model-large

# The following line specifies the default target(s) to build all: file.hex

# The following line specifies the object files that are to be linked together OBJECTS := file.rel # another_file.rel assembly_file.rel

# The following lines define a rule that sends the object files through the linker to # create file.ihx which then has to be processed by packihx to create file.hex file.hex : $(OBJECTS) sdcc $(LFLAGS) $^ packihx file.ihx > file.hex

# The following rule sends each C file through the preprocessor and creates the asm file # that is then assembled to create the rel file. %.rel : %.c sdcc $(CFLAGS) $<

# The following rule sends each asm file (Not the asm files created by SDCC as an # intermediate output of the compilation process.) through the assembler to create a rel # file. %.rel : %.asm asx8051 ­losa $<

# The following rule will clean all the derived objects from your directory. This will # save you from accidentally tying Rm *' if you are developing on a UNIX platform. # Note: To execute this rule type Make clean' clean: # rm *.rel *.lst *.rst *.hex *.ihx rm *.sym *.asm *.mem *.map *.lnk *.lst *.hex *.ihx *.rel

# call my hxl program to make a BASIC listing from the hexfile bas: hxl -i file.hex -b file.bas

:-)

Reply to
Jan Panteltje

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.