We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi All, I'm more of a Assembly guy than C. I came across this forum when I am seeking for some quick guide of sharing data registers / variables of different files of C and .a51 in a simple program. Calling each other from C to get the function written in .a51 or vice-versa is completed. Went through c2asm2c.zip, tested and find that it worked perfectly. However, I encounter some trouble when I need to pass on some variables that need to be manipulated from .a51 to .c My case:- Main code is in .a51. Requires to call a function that adds 20 slightly different 8bit data bytes and then take its average (i.e. by division). Writing the function above in .a51 is a pain due to unavailable 16bit-addition in 8051 done under Keil uV2. My solution thought:- is to write the addition function in C so addition can be done much more easily. Problem:- how do I pass the variables/registers defined in .a51 to the C function to be called from .a51 environment? The C function failed to recognize the similar declared register under .a51 before. Do I need to declare them under a new name OR use the similar name of data registers OR can use some global declaration of data registers. But how? Appreciate some really cool advice if available. Cheers, James
Hi James,<br> I've prepared a "short" cookbook - 3 files - C, A51 and H.<br> <br> Here you go:<br> A51 source file (~frame):<br>
#include <test_h.H> ; A51 accepts (with some restrictions) header files with SFR and other definitions ; tell the linker known symbol names: public DataGroup1, DataGroup2 public Char_dataA,Char_dataB, Int_data, Int_dataH, Int_dataL public Long_data, Long_data1, Long_data2, Long_data3, Long_data4 public Flags1, Flags2 public Flag0, Flag1, abc, Flag7 public Bit_var1, Bit_var2 public Char_array public Char_idata, Char_xdata public my_function_A51, _my_regpar_function_A51 ; tell the linker external symbol names needed for this file extrn bit (bit_var1_C, bit_var2_C) ; bit variables defined in a C file and used here extrn data (data_var1_C, data_var2_C) ; data variables defined in a C file and used here extrn idata (idata_var_C) ; idata variables defined in a C file and used here extrn xdata (xdata_var_C) ; xdata variables defined in a C file, also for pdata vars extrn code (func_C, _func_regpar_C) ; function defined in a C file and used here ; for func_C(void) ; and func_regpar_C(..params) - in C without underscore! ;extrn number (MAX, MIN) ; defined in another asm file (here it doesn't exist) ; Absolute ;--- ;These are the "hard" addresses for (only) byte addressable variables DataGroup1 DATA 0x050 ; (why is this simple variable called ..Group?) DataGroup2 DATA 0x051 ;This is the "hard" address for a bit addressable variable: Flags1 DATA 0x020 ;contains Timer0IntHap, sleepingnow and etc ; Relative ; define data, bdata, idata, xdata, pdata relative segments ;--- ; "?BA?BDATA_SEG" is YOUR name of the segment ?BA?BDATA_SEG segment data bitaddressable ; you can specify a bitaddressable ; relocatable data segment this way rseg ?BA?BDATA_SEG ; the specified segment starts here Flags2: ds 1 ; linker will locate it in the bitaddressable ; internal RAM area (20H to 2FH); here probably 21H Flag0 bit Flags2.0 ; you can specify names Flag1 bit Flags2.1 ; for particular bit this way abc bit Flags2.3 ; the same of course for Flags1 defined above ;... Flag7 bit Flags2.7 ;--- ; "?BI?BIT_SEG" is YOUR name of the segment ?BI?BIT_SEG segment bit ; you can specify a relocatable ; bit segment this way rseg ?BI?BIT_SEG ; the specified segment starts here Bit_var1: dbit 1 ; bit variable1, linker will locate it ; in the bitaddressable area 20h to 2FH (bit addresses 0 to 7FH) Bit_var2: dbit 1 ; bit variable2 ;--- ; "?DT?DATA_SEG" is YOUR name of the segment ?DT?DATA_SEG segment data ; you can specify a relocatable data segment ; this way (linker will locate it in 0H to 7FH area) rseg ?DT?DATA_SEG ; the specified data segment starts here Char_dataA: ds 1 ; 1st (unsigned) char variable Char_dataB: ds 1 ; 2nd (unsigned) char variable Int_data: ds 2 ; (unsigned) int variable Int_dataH data Int_data ; MSB (Big Endian manner) Int_dataL data Int_data+1 ; LSB this way you can specify components of longer types Long_data: ds 4 ; (unsigned) long variable Long_data1 data Long_data ; MSB ... Long_data2 data Long_data+1 ; particular components Long_data3 data Long_data+2 ; of long variable Long_data4 data Long_data+3 ; ... LSB Char_array: ds A_LENGTH ; array of chars (size in the included header file) ; just for illustration, needn't be defined char_array0 data Char_array ; 1st - Char_array[0] ;... char_array4 data Char_array+4 ; 5th - Char_array[4] ;--- ; "?ID?IDATA_SEG" is YOUR name of the segment ?ID?IDATA_SEG segment idata ; you can specify a relocatable idata segment ; this way (linker will locate it in 0H to FFH area, if available) ; behind the last DATA segment rseg ?ID?IDATA_SEG ; the specified xdata segment starts here Char_idata: ds 1 ; (unsigned) char variable in IDATA ;--- ; "?XD?XDATA_SEG" is YOUR name of the segment ?XD?XDATA_SEG segment xdata ;inpage ; you can specify a relocatable xdata segment ; this way (linker will locate it in available XRAM area) ; optionable "inpage" (omit the semicolon) tells the linker ; to locate it in a memory page rseg ?XD?XDATA_SEG ; the specified xdata segment starts here Char_xdata: ds 1 ; (unsigned) char variable in XDATA ; define program segment(s) ;--- ; "?PR?PROG_SEG" is YOUR name of the segment ?PR?PROG_SEG segment code ; you can specify a relocatable ; code (program) segment this way rseg ?PR?PROG_SEG ; the specified segment starts here my_function_A51: ; A51 function code (here empty) ret _my_regpar_function_A51: ; name of an "A51 written" function passing parameters ; take the (register) ; in registers starts with the underline character: _ ; passed parameters (here in R7) mov Char_dataB,r7 ; my_regpar_function_A51(uchar x) ; { ; Char_dataB = x; ; } ret ; bla bla ... call func_C ; function without parameters written in C ; prepare actual parameters in appropriate registers call _func_regpar_C ; function with parameters written in C ; bla bla end