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! I'm using XBANKING.a51 from "Keil\C51\Examples\FarMemory\3 XData Areas on T89C51RD2" for access to various types of memory MCU Atmel AT89C5131. I'm define memory model - Large, "User Classes" as: XDATA (X:0x008000-X:0x009FFE) // off-chip XRAM HDATA_EEPROM (X:0x020000-X:0x0207FF) // on-chip EEPROM HDATA (X:0x010000-X:0x0103FF) // on-chip XRAM And variables as: in file MAIN.c unsigned char *Pointer1, *Pointer2; unsigned char far onBufer; // on-chip XRAM unsigned char xdata offBufer; // off-chip XRAM unsigned code cBufer = "Welcome"; // on-chip ROM in file EEPROM.c #pragma USERCLASS (HDATA = EEPROM) unsigned char far EEBufer; // on-chip EEPROM I'm programming next code: Pointer1 = onBufer; // pointer to 0x01AABB Pointer2 = cBuffer; // pointer to 0xFFCCDD memcpy(Pointer1, Pointer2, 20); Compiling my program and view "Disassembly Window": ... Pointer1 = onBuffer; 908010 MOV DPTR,#Pointer1(0x8010) 7402 MOV A,#0x02 // on-chip EEPROM area !!! F0 MOVX @DPTR,A A3 INC DPTR 74AA MOV A,#0xAA F0 MOVX @DPTR,A A3 INC DPTR 74BB MOV A,#0xBB F0 MOVX @DPTR,A Pointer2 = cBuffer; A3 INC DPTR 74FF MOV A,#0xFF F0 MOVX @DPTR,A A3 INC DPTR 74CC MOV A,#0xCC F0 MOVX @DPTR,A A3 INC DPTR 74DD MOV A,#0xDD F0 MOVX @DPTR,A memcpy(Pointer1, Pointer2, 20); ... Where the bug or my error?
According to the code that you posted, "onBufer" is a character and not a pointer. The assignment statement would be incorrect, and you should get a warning (from lint if not the compiler -- you are using lint, right?) when you assign a charater to a pointer.
unsigned char *Pointer1, *Pointer2; unsigned char far onBufer; // on-chip XRAM unsigned code cBufer = "Welcome"; // on-chip ROM Pointer1 = onBufer; // pointer to 0x01AABB Pointer2 = cBuffer; // pointer to 0xFFCCDD
I suspect these are just typos, though. (In general, when posting code to the forum, it's a good idea to cut and paste to avoid introducing any differences by retyping the code.)
From this line
7402 MOV A,#0x02 // on-chip EEPROM area !!!
I suspect what is really confusing you is the Keil tagging scheme. A far pointer is not a 24-bit address. It's a structured value with the first byte used as a tag byte to indicate the memory space (data, xdata, far, etc) and a 16-bit value that is the address in that memory space.
The tag scheme is a bit unfortunate in that a tag value of 0 was used to mean "data" memory, not xdata. Then the tag for xdata is 1, and far memory is 2..7F. So, the tag value for all of the xdata/far memory is 1 higher than you would expect from a 3-byte address.
Offset 0000H in xdata is represented as 010000H. Offset 0000H in the first segment of far data (the 64KB just beyond "xdata") is 020000H. But you probably want to think of that as "xdata address 010000H". If you want to think of addresses that way, then the far pointer representation is like a flat address, except that it's 10000H higher than you expect.
See the FVAR and FARRAY macros in absacc.h. Also, see the comments in XBANKING.A51.
; R3 Value | Memory Type | Memory Class | Address Range * ; -----------------------+--------------+-------------------------- * ; 00 | data/idata | DATA/IDATA | I:0x00 .. I:0xFF * ; 01 | xdata | XDATA | X:0x0000 .. X:0xFFFF * ; 02..7F | far | HDATA | X:0x010000 .. X:0x7E0000 * ; 81..FD | far const | HCONST | C:0x800000 .. C:0xFC0000 (see note) * ; FE | pdata | XDATA | one 256-byte page in XDATA memory * ; FF | code | CODE | C:0x0000 .. C:0xFFFF
Excuse, this mistake has turned out at creation of a question: Should be: unsigned char far onBufer[20]; unsigned char xdata offBufer[20]; unsigned char far EEBufer[20]; Value of Pointer1 in "Hint" of Dedug windows is 0x01AABB. If R3 - memory type, then how to define simultaneously two types of far (EEPROM, on-chip XRAM). In function memcpy(Pointer1,Pointer1,20) disassembler check: C?CSTPTR: C:0x0DA0 BB0106 CJNE R3,#Test(0x01),C:0DA9 //if r3<>r1 is not HXDATA area C:0x0DA3 8982 MOV DP0L(0x82),R1 C:0x0DA5 8A83 MOV DP0H(0x83),R2 C:0x0DA7 F0 MOVX @DPTR,A C:0x0DA8 22 RET C:0x0DA9 5002 JNC C:0DAD C:0x0DAB F7 MOV @R1,A C:0x0DAC 22 RET C:0x0DAD BBFE02 CJNE R3,#CCAP4H(0xFE),C:0DB2 C:0x0DB0 F3 MOVX @R1,A C:0x0DB1 22 RET C:0x0DB2 50FD JNC C:0DB1 C:0x0DB4 020AD6 LJMP C?CSTXPTR(C:0AD6) // write to EEPROM or off-chip XRAM
Did you notice that the EEPROM variables are defined in a USER_CLASS.
#pragma ORDER // keep variables in order of definition #pragma USERCLASS (HDATA = EEPROM) // use HDATA_EEPROM for E2PROM area #define DECLARE #include <eeprom.h> // include all variables
OK, I have understood, it turns out, that memory and indexes are allocated as follows:
+----------------+--------------+------------------------+--------------+-----------+ | Memory Type | Memory Class | Define in C language | Address in C | R3 in ASM | +----------------+--------------+------------------------+--------------+-----------+ | on-chip XDATA | HDATA | far | X:0x010000 | 0x02 | | off-chip XDATA | XDATA | xdata | X:0x000000 | 0x01 | | CODE | CODE | code | X:0x0000 | 0xFF | | EEPROM | HDATA_EEPROM | far & (HDATA = EEPROM) | C:0x0000 | 0x03 | +----------------+--------------+------------------------+--------------+-----------+ * using standard files XBANKING.a51 and EEPROM.c
There is another problem. In the menu "Options for Target" I choose "Memory Model = Lage: variables in XDATA". I have function in my program char Test (char value1, char *value2, char value3) in which parameters transferred through XDATA memory, but not through registers. XDATA memory is an off-chip. How to transfer parameters through on-chip XRAM?
There is no particular reason why on-chip XDATA has to be HDATA, while off-chip is XDATA.
Presumably, you are looking at some specific case where this happened to be (or seem) convenient to whoever set it up?
I shall ask on another. I define variables as:
char xdata A; // locate in off-chip XDATA char far B; // locate in on-chip XDATA
If the model of memory LARGE and a variable is defined as char C; , then where is placed a variable? It is necessary for me that in on-chip XDATA.
"It is necessary for me that in on-chip XDATA."
If it is necessary, then just specify it explicitly. Simple.