This works without a problem, except I have to look up the structure of the call every time I add one. Also the readability is not exactly great. a structure in upper 64 k of "code flash" in a SILabs f122typedef struct { U32 MSFC_tag; // 'MSFC' Multi-Size Font Collection // MSFC U32 MSFC_idno; // random unique font id number (referenced by subfonts if split) // fb06c05c U8 MSFC_ver; // file version (set to 1) // 01 U8 MSFC_tblcnt; // number of table dir entries following // 03 U8 MSFC_sftcnt; // number of subfonts contained in / belonging to this collection // 01 U8 MSFC_flags; // 0 for standard CBFs (bit0=1 for vertical font) // 01 U16 MSFC_fsiz; // Complete size of the file (max size is 65534 (= 0xfffe) bytes) // 061a } STR_MSFC; a function //////////////////////////////////////////////////////////// // // // FUNCTION U32 ReadFlashLong (U8 code * RFSaddr) // // read high flash // U32 ReadFlashLong (U8 code *RFSaddr) { U8 RFCintsav; U8 RFCdata; U8 code * RFSadds; U32 RFScomp; RFCintsav = SG_IE; SG_IE = 0; SG_SFRPAGE = 0; if (RFSaddr > 0x7fff) { SG_PSBANK = 0x30; } else { SG_PSBANK = 0x20; RFSaddr += 0x8000 ; } RFSadds = RFSaddr; for (RFCdata = 0 ; RFCdata < 4 ;RFCdata++, RFSadds++) { RFScomp <<= 8; RFScomp |= (U32) *RFSadds; } SG_IE = RFCintsav; return (RFScomp) ; } the call s_msfc = 0 ; if ( FFS_CfntNo == 2) { s_msfc = 0x8000 ; } FFSLtemp = ReadFlashLong ((U8 code *) &s_msfc->MSFC_tag); what would be "natural" FFSLtemp = ReadFlashLong (s_msfc->MSFC_tag) gives error; is there a simpler way to make the call without specifying a pointer to something now specified as a pointer (asx seen in bold above). I am NOT interested in a suggestion about using "banking" my other routines do not have the time to go through a bank check/switch. I am using a 100Mips '51 and can hardly keep up. Also, the shorts and longs are in the wrong order because the files with these structures are generated on a PC so, even using "banking" would not totally solve the problem. Erik
I think you really should check back on what xdata banking actually does before you continue this campaign. There's absolutely no overhead involved in parts of the program that don't themselves use objects in far memory. in this context, what is an "object" another issue is that I doubt that banking will include the needed code to read the f12x high code area. it is a lot more than setting an address bit Erik FYI, here is what is required
//////////////////////////////////////////////////////////// // // // FUNCTION U8 ReadFlashChar (U8 code * RFSaddr) // // read high flash // U8 ReadFlashChar (U8 code * RFSaddr) { U8 RFCintsav; U8 RFCdata; RFCintsav = SG_IE; SG_IE = 0; SG_SFRPAGE = 0; if (RFSaddr > 0x7fff) { SG_PSBANK = 0x30; } else { SG_PSBANK = 0x20; RFSaddr += 0x8000 ; } RFCdata = *RFSaddr; SG_PSBANK = 0x10 ; SG_IE = RFCintsav; return (RFCdata) ; }
in this context, what is an "object" "Object" is C standard terminology for "a variable or a function". In the given context, a variable. I.e. code that doesn't touch 'far' variables won't even notice that xdata banking exists, much less suffer any overhead from it. I doubt that banking will include the needed code to read the f12x high code area. Not automagically all by itself, of course. But xdata banking is exactly the way you can get the compiler to help you with this kind of work. Keil basically offers you the opportunity to teach the runtime library new tricks here, so you can use perfectly ordinary C operations to access variables in that memory space. It won't cover the endian-ness conversion, but it'll allow you to access that struct in the simplest and most obvious way imagineable:
some_var = msft.MSFT_field;