This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Accessing far memory, linking problem

Former Member
Former Member

I have a serial EEPROM used as a far memory expansion. Writing and reading routines for an i2c bus are in a C-code:

void start_write (void far * w_addr) {

        wait_smb_free ();
        smb_address = (unsigned int)w_addr;     // EEPROM address
}

void write_page (unsigned char w_count) {

        data_number = w_count;                          // number of data bytes.
        wait_smb_free ();
}

//      write into an EEPROM

void from_mem_into_eeprom (unsigned char far * wr_addr, unsigned int wr_count, unsigned char * wr_dataptr) {
        unsigned char   wr_ii;

        while (wr_count) {
                smb_buffer[wr_ii] = *wr_dataptr;
                start_write (wr_addr);                  // cnt bytes
                if (wr_count < 8)
                        wr_ii = wr_count;
                write_page (wr_ii);                             // cnt byte(s)
                wr_count -= wr_ii;
        }
}

void byte_into_eeprom (unsigned char far * bw_addr, unsigned char out_b) {

        start_write (bw_addr);
        smb_buffer[0] = out_b;                  // Data byte
        write_page (1);                                 // 1 byte
}

void word_into_eeprom (unsigned int far * ww_addr, unsigned int out_w) {

        from_mem_into_eeprom ((void *)ww_addr, sizeof(int), (void *)&out_w);
}



void read_eeprom (void far * rd_addr, unsigned char rd_count) {

        wait_smb_free (SMB_Wait_Error);
        smb_address = (unsigned int)rd_addr;    // EEPROM address
        data_number = rd_count;                         // number of data bytes.
        wait_smb_free ();               // Wait for transfer to finish
}

unsigned char byte_from_eeprom (unsigned char far * br_addr) {

        read_eeprom (br_addr, sizeof(char));
        return (smb_buffer[0]);
}

unsigned int word_from_eeprom (unsigned int far * wr_addr) {

        read_eeprom (wr_addr, sizeof(int));
        return (*(unsigned int *)smb_buffer);
}

XBANKING.A51 is something like this:

        NAME    ?C?XBANKING     ; 'far' Memory Access Support


PUBLIC ?B?SMEM, ?B?TMEM, ?B?UMEM, ?B?VMEM ;PUBLIC ?C?XPAGE1SFR, ?C?XPAGE1RST PUBLIC ?C?CLDXPTR, ?C?CSTXPTR, ?C?ILDXPTR, ?C?ISTXPTR PUBLIC ?C?PLDXPTR, ?C?PSTXPTR, ?C?LLDXPTR, ?C?LSTXPTR
EXTRN CODE (_byte_from_eeprom, _byte_into_eeprom) EXTRN CODE (_word_from_eeprom, _word_into_eeprom)
?C?LIB_CODE SEGMENT CODE RSEG ?C?LIB_CODE
;---------------------------------------------------------------------- ; CLDXPTR: Load BYTE in A via Address given in R1/R2/R3 ?C?CLDXPTR: LCALL _byte_from_eeprom MOV A, R7 RET
;---------------------------------------------------------------------- ; CSTXPTR: Store BYTE in A via Address given in R1/R2/R3 ?C?CSTXPTR: MOV R5, A LCALL _byte_into_eeprom RET
;---------------------------------------------------------------------- ; ILDXPTR: Load WORD in A(LSB)/B(HSB) via Address given in R1/R2/R3 ?C?ILDXPTR: LCALL _word_from_eeprom RET
;---------------------------------------------------------------------- ; ISTXPTR: Store WORD in A(HSB)/B(LSB) via Address given in R1/R2/R3 ?C?ISTXPTR: MOV R5, B MOV R4, A LCALL _word_into_eeprom RET
END

If I used direct calls to the routines, linking would done without failures:

                byte_into_eeprom ((void *)&test_block_e.test_byte, 0x30);
                if (byte_from_eeprom ((void *)&test_block_e.test_byte) != 0x30)
                        jj++;
                word_into_eeprom ((void *)&test_block_e.test_word, 0x60A1);
                if (word_from_eeprom ((void *)&test_block_e.test_word) != 0x60A1)
                        jj++;

However, I’d like to assign a value to a variable:

void self_test_1 (void) {
        unsigned int    result1, temp1;

        temp1 = meas_uct_cC();
        result1 = 0;
        result1 |= check_value (test_block_e.battV = meas_bat_mV(),11000,13750);
        result1 |= check_value (test_block_e.vd3V = meas_3vd_mV(), 3150, 3450) << 2;
        result1 |= check_value (test_block_e.vd5V = meas_5vd_mV(), 4750, 5250) << 4;

        if (temp1 > 6000)
                hw_error |= OverHeat;
        test_block_e.hw_result |= result1;
}

Test_block_e is a sample structure in the far memory.
In this case local variables (result1 and temp1) are overwritten by local variable (out_w) in EEPROM writing routine.
Linker makes only one byte difference:

      00000001H   SYMBOL    DATA     ---       ww_addr
      00000019H   SYMBOL    DATA     WORD      out_w

      00000018H   SYMBOL    DATA     WORD      result1
      0000001AH   SYMBOL    DATA     WORD      temp1

Are there any requirements if an external routine is called in XBANKING.A51?

Parents
  • Former Member
    0 Former Member in reply to HansBernhard Broeker

    Unfortunately, dedicated C code is difficult task for the linker also.

    *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS
        NAME:    _BYTE_INTO_EEPROM/SMB
    
    *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS
        NAME:    _WORD_INTO_EEPROM/SMB
    
    *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS
        NAME:    _BYTE_FROM_EEPROM/SMB
    
    *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS
        NAME:    _WORD_FROM_EEPROM/SMB
    


    As a workaround I'll skip XBANKING.A51 and direct accessing/assigning so far.

Reply
  • Former Member
    0 Former Member in reply to HansBernhard Broeker

    Unfortunately, dedicated C code is difficult task for the linker also.

    *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS
        NAME:    _BYTE_INTO_EEPROM/SMB
    
    *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS
        NAME:    _WORD_INTO_EEPROM/SMB
    
    *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS
        NAME:    _BYTE_FROM_EEPROM/SMB
    
    *** WARNING L57: UNCALLED FUNCTION, IGNORED FOR OVERLAY PROCESS
        NAME:    _WORD_FROM_EEPROM/SMB
    


    As a workaround I'll skip XBANKING.A51 and direct accessing/assigning so far.

Children
No data