A nudge in the right direction to fix this much appreciated:

SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08
2.5.6 # (Jun 14 2007) (UNIX)
gpasm-0.13.3 beta
gplink-0.13.3 alpha

Here is my program main.c

#include "pic18fregs.h"

#pragma stack 0x200 64

void ledon(void);
void addtask(int);

typedef struct t_tasks {
        void (*fp)();
};

struct t_tasks mytasks[2];

void main(void) {
        addtask(0);
}

void ledon(void) {
        PORTBbits.RB4 = 1;
}

void addtask(int a) {
        int j = 0;

        mytasks[0].fp = ledon;
        mytasks[j].fp = ledon;
        mytasks[a].fp = ledon;
}

and Makefile

main.hex: main.o
        gplink -w -r -o main.hex -m main.o -I /usr/share/sdcc/lib/pic16
pic18f248.lib libsdcc.lib crt0i.o

main.o: main.asm
        gpasm -c -a inhx32 main.asm

main.asm: main.c main.h Makefile
        sdcc -S main.c -mpic16 -p18f248 --pstack-model=large

clean:
        $(RM) *.asm *.cod *.lst *.hex *.p *.d *.lnk *~ *.o *.cof *.map

prog:
        picp /dev/ttyS0 18f248 -ef -wp main.hex

sim:
        cp .gpsim ~
        gpsim -p18f248 main.cod

Here is the assembler generated

;--------------------------------------------------------
; File Created by SDCC : FreeWare ANSI-C Compiler
; Version 2.5.6 # (Jun 14 2007)
; This file generated Tue Jul 10 10:56:13 2007
;--------------------------------------------------------
; PIC16 port for the Microchip 16-bit core micros
;--------------------------------------------------------
        list    p=18f248

        radix dec

;--------------------------------------------------------
; extern variables in this module
;--------------------------------------------------------
        extern _RXF0SIDHbits
        extern _RXF0SIDLbits
        extern _RXF0EIDHbits
        extern _RXF0EIDLbits
        extern _RXF1SIDHbits
        extern _RXF1SIDLbits
        extern _RXF1EIDHbits
        extern _RXF1EIDLbits
        extern _RXF2SIDHbits
        extern _RXF2SIDLbits
        extern _RXF2EIDHbits
        extern _RXF2EIDLbits
        extern _RXF3SIDHbits
        extern _RXF3SIDLbits
        extern _RXF3EIDHbits
        extern _RXF3EIDLbits
        extern _RXF4SIDHbits
        extern _RXF4SIDLbits
        extern _RXF4EIDHbits
        extern _RXF4EIDLbits
        extern _RXF5SIDHbits
        extern _RXF5SIDLbits
        extern _RXF5EIDHbits
        extern _RXF5EIDLbits
        extern _RXM0SIDHbits
        extern _RXM0SIDLbits
        extern _RXM0EIDHbits
        extern _RXM0EIDLbits
        extern _RXM1SIDHbits
        extern _RXM1SIDLbits
        extern _RXM1EIDHbits
        extern _RXM1EIDLbits
        extern _TXB2CONbits
        extern _TXB2SIDHbits
        extern _TXB2SIDLbits
        extern _TXB2EIDHbits
        extern _TXB2EIDLbits
        extern _TXB2DLCbits
        extern _TXB2D0bits
        extern _TXB2D1bits
        extern _TXB2D2bits
        extern _TXB2D3bits
        extern _TXB2D4bits
        extern _TXB2D5bits
        extern _TXB2D6bits
        extern _TXB2D7bits
        extern _CANSTATRO4bits
        extern _TXB1CONbits
        extern _TXB1SIDHbits
        extern _TXB1SIDLbits
        extern _TXB1EIDHbits
        extern _TXB1EIDLbits
        extern _TXB1DLCbits
        extern _TXB1D0bits
        extern _TXB1D1bits
        extern _TXB1D2bits
        extern _TXB1D3bits
        extern _TXB1D4bits
        extern _TXB1D5bits
        extern _TXB1D6bits
        extern _TXB1D7bits
        extern _CANSTATRO3bits
        extern _TXB0CONbits
        extern _TXB0SIDHbits
        extern _TXB0SIDLbits
        extern _TXB0EIDHbits
        extern _TXB0EIDLbits
        extern _TXB0DLCbits
        extern _TXB0D0bits
        extern _TXB0D1bits
        extern _TXB0D2bits
        extern _TXB0D3bits
        extern _TXB0D4bits
        extern _TXB0D5bits
        extern _TXB0D6bits
        extern _TXB0D7bits
        extern _CANSTATRO2bits
        extern _RXB1CONbits
        extern _RXB1SIDHbits
        extern _RXB1SIDLbits
        extern _RXB1EIDHbits
        extern _RXB1EIDLbits
        extern _RXB1DLCbits
        extern _RXB1D0bits
        extern _RXB1D1bits
        extern _RXB1D2bits
        extern _RXB1D3bits
        extern _RXB1D4bits
        extern _RXB1D5bits
        extern _RXB1D6bits
        extern _RXB1D7bits
        extern _CANSTATRO1bits
        extern _RXB0CONbits
        extern _RXB0SIDHbits
        extern _RXB0SIDLbits
        extern _RXB0EIDHbits
        extern _RXB0EIDLbits
        extern _RXB0DLCbits
        extern _CANSTATbits
        extern _CANCONbits
        extern _BRGCON1bits
        extern _BRGCON2bits
        extern _BRGCON3bits
        extern _CIOCONbits
        extern _COMSTATbits
        extern _RXERRCNTbits
        extern _TXERRCNTbits
        extern _PORTAbits
        extern _PORTBbits
        extern _PORTCbits
        extern _LATAbits
        extern _LATBbits
        extern _LATCbits
        extern _TRISAbits
        extern _TRISBbits
        extern _TRISCbits
        extern _PIE1bits
        extern _PIR1bits
        extern _IPR1bits
        extern _PIE2bits
        extern _PIR2bits
        extern _IPR2bits
        extern _PIE3bits
        extern _PIR3bits
        extern _IPR3bits
        extern _EECON1bits
        extern _RCSTAbits
        extern _TXSTAbits
        extern _T3CONbits
        extern _CCP1CONbits
        extern _ADCON1bits
        extern _ADCON0bits
        extern _SSPCON2bits
        extern _SSPCON1bits
        extern _SSPSTATbits
        extern _T2CONbits
        extern _T1CONbits
        extern _RCONbits
        extern _WDTCONbits
        extern _LVDCONbits
        extern _OSCCONbits
        extern _STATUSbits
        extern _INTCON3bits
        extern _INTCON2bits
        extern _INTCONbits
        extern _STKPTRbits
        extern _RXF0SIDH
        extern _RXF0SIDL
        extern _RXF0EIDH
        extern _RXF0EIDL
        extern _RXF1SIDH
        extern _RXF1SIDL
        extern _RXF1EIDH
        extern _RXF1EIDL
        extern _RXF2SIDH
        extern _RXF2SIDL
        extern _RXF2EIDH
        extern _RXF2EIDL
        extern _RXF3SIDH
        extern _RXF3SIDL
        extern _RXF3EIDH
        extern _RXF3EIDL
        extern _RXF4SIDH
        extern _RXF4SIDL
        extern _RXF4EIDH
        extern _RXF4EIDL
        extern _RXF5SIDH
        extern _RXF5SIDL
        extern _RXF5EIDH
        extern _RXF5EIDL
        extern _RXM0SIDH
        extern _RXM0SIDL
        extern _RXM0EIDH
        extern _RXM0EIDL
        extern _RXM1SIDH
        extern _RXM1SIDL
        extern _RXM1EIDH
        extern _RXM1EIDL
        extern _TXB2CON
        extern _TXB2SIDH
        extern _TXB2SIDL
        extern _TXB2EIDH
        extern _TXB2EIDL
        extern _TXB2DLC
        extern _TXB2D0
        extern _TXB2D1
        extern _TXB2D2
        extern _TXB2D3
        extern _TXB2D4
        extern _TXB2D5
        extern _TXB2D6
        extern _TXB2D7
        extern _CANSTATRO4
        extern _TXB1CON
        extern _TXB1SIDH
        extern _TXB1SIDL
        extern _TXB1EIDH
        extern _TXB1EIDL
        extern _TXB1DLC
        extern _TXB1D0
        extern _TXB1D1
        extern _TXB1D2
        extern _TXB1D3
        extern _TXB1D4
        extern _TXB1D5
        extern _TXB1D6
        extern _TXB1D7
        extern _CANSTATRO3
        extern _TXB0CON
        extern _TXB0SIDH
        extern _TXB0SIDL
        extern _TXB0EIDH
        extern _TXB0EIDL
        extern _TXB0DLC
        extern _TXB0D0
        extern _TXB0D1
        extern _TXB0D2
        extern _TXB0D3
        extern _TXB0D4
        extern _TXB0D5
        extern _TXB0D6
        extern _TXB0D7
        extern _CANSTATRO2
        extern _RXB1CON
        extern _RXB1SIDH
        extern _RXB1SIDL
        extern _RXB1EIDH
        extern _RXB1EIDL
        extern _RXB1DLC
        extern _RXB1D0
        extern _RXB1D1
        extern _RXB1D2
        extern _RXB1D3
        extern _RXB1D4
        extern _RXB1D5
        extern _RXB1D6
        extern _RXB1D7
        extern _CANSTATRO1
        extern _RXB0CON
        extern _RXB0SIDH
        extern _RXB0SIDL
        extern _RXB0EIDH
        extern _RXB0EIDL
        extern _RXB0DLC
        extern _RXB0D0
        extern _RXB0D1
        extern _RXB0D2
        extern _RXB0D3
        extern _RXB0D4
        extern _RXB0D5
        extern _RXB0D6
        extern _RXB0D7
        extern _CANSTAT
        extern _CANCON
        extern _BRGCON1
        extern _BRGCON2
        extern _BRGCON3
        extern _CIOCON
        extern _COMSTAT
        extern _RXERRCNT
        extern _TXERRCNT
        extern _PORTA
        extern _PORTB
        extern _PORTC
        extern _LATA
        extern _LATB
        extern _LATC
        extern _TRISA
        extern _TRISB
        extern _TRISC
        extern _PIE1
        extern _PIR1
        extern _IPR1
        extern _PIE2
        extern _PIR2
        extern _IPR2
        extern _PIE3
        extern _PIR3
        extern _IPR3
        extern _EECON1
        extern _EECON2
        extern _EEDATA
        extern _EEADR
        extern _RCSTA
        extern _TXSTA
        extern _TXREG
        extern _RCREG
        extern _SPBRG
        extern _T3CON
        extern _TMR3L
        extern _TMR3H
        extern _CCP1CON
        extern _CCPR1L
        extern _CCPR1H
        extern _ADCON1
        extern _ADCON0
        extern _ADRESL
        extern _ADRESH
        extern _SSPCON2
        extern _SSPCON1
        extern _SSPSTAT
        extern _SSPADD
        extern _SSPBUF
        extern _T2CON
        extern _PR2
        extern _TMR2
        extern _T1CON
        extern _TMR1L
        extern _TMR1H
        extern _RCON
        extern _WDTCON
        extern _LVDCON
        extern _OSCCON
        extern _T0CON
        extern _TMR0L
        extern _TMR0H
        extern _STATUS
        extern _FSR2L
        extern _FSR2H
        extern _PLUSW2
        extern _PREINC2
        extern _POSTDEC2
        extern _POSTINC2
        extern _INDF2
        extern _BSR
        extern _FSR1L
        extern _FSR1H
        extern _PLUSW1
        extern _PREINC1
        extern _POSTDEC1
        extern _POSTINC1
        extern _INDF1
        extern _WREG
        extern _FSR0L
        extern _FSR0H
        extern _PLUSW0
        extern _PREINC0
        extern _POSTDEC0
        extern _POSTINC0
        extern _INDF0
        extern _INTCON3
        extern _INTCON2
        extern _INTCON
        extern _PRODL
        extern _PRODH
        extern _TABLAT
        extern _TBLPTRL
        extern _TBLPTRH
        extern _TBLPTRU
        extern _PCL
        extern _PCLATH
        extern _PCLATU
        extern _STKPTR
        extern _TOSL
        extern _TOSH
        extern _TOSU
        extern __mulint

;--------------------------------------------------------
; public variables in this module
;--------------------------------------------------------
        global _stack
        global _stack_end
        global _ledon
        global _addtask
        global _mytasks
        global _main
;--------------------------------------------------------
;       Equates to used internal registers
;--------------------------------------------------------
STATUS  equ     0xfd8
FSR0L   equ     0xfe9
FSR0H   equ     0xfea
FSR1L   equ     0xfe1
FSR1H   equ     0xfe2
FSR2L   equ     0xfd9
FSR2H   equ     0xfda
INDF0   equ     0xfef
POSTINC0        equ     0xfee
POSTDEC1        equ     0xfe5
PREINC1 equ     0xfe4
PLUSW2  equ     0xfdb
PRODL   equ     0xff3


; Internal registers
.registers      udata_ovr       0x0000
r0x00   res     1
r0x01   res     1

udata_main_0    udata
_mytasks        res     6


ustat_main_00   udata   0X0200
_stack  res     63
_stack_end      res     1

;--------------------------------------------------------
; interrupt vector
;--------------------------------------------------------

;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
; I code from now on!
; ; Starting pCode block
S_main__main    code
_main:
;       .line   15; main.c      addtask(0);
        MOVLW   0x00
        MOVWF   POSTDEC1
        MOVLW   0x00
        MOVWF   POSTDEC1
        CALL    _addtask
        MOVLW   0x02
        ADDWF   FSR1L, F
        BTFSC   STATUS, 0
        INCF    FSR1H, F
        RETURN  

; ; Starting pCode block
S_main__addtask code
_addtask:
;       .line   22; main.c      void addtask(int a) {
        MOVFF   FSR2H, POSTDEC1
        MOVFF   FSR2L, POSTDEC1
        MOVFF   FSR1L, FSR2L
        MOVFF   FSR1H, FSR2H
        MOVFF   r0x00, POSTDEC1
        MOVFF   r0x01, POSTDEC1
        MOVLW   0x03
        MOVFF   PLUSW2, r0x00
        MOVLW   0x04
        MOVFF   PLUSW2, r0x01
;       .line   25; main.c      mytasks[0].fp = ledon;
        MOVLW   LOW(_ledon)
        BANKSEL _mytasks
        MOVWF   _mytasks, B
        MOVLW   HIGH(_ledon)
        BANKSEL (_mytasks + 1)
        MOVWF   (_mytasks + 1), B
        MOVLW   UPPER(_ledon)
        BANKSEL (_mytasks + 2)
        MOVWF   (_mytasks + 2), B
;       .line   26; main.c      mytasks[j].fp = ledon;
        MOVLW   LOW(_ledon)
        BANKSEL _mytasks
        MOVWF   _mytasks, B
        MOVLW   HIGH(_ledon)
        BANKSEL (_mytasks + 1)
        MOVWF   (_mytasks + 1), B
        MOVLW   UPPER(_ledon)
        BANKSEL (_mytasks + 2)
        MOVWF   (_mytasks + 2), B
;       .line   27; main.c      mytasks[a].fp = ledon;
        MOVLW   0x00
        MOVWF   POSTDEC1
        MOVLW   0x03
        MOVWF   POSTDEC1
        MOVF    r0x01, W
        MOVWF   POSTDEC1
        MOVF    r0x00, W
        MOVWF   POSTDEC1
        CALL    __mulint
        MOVWF   r0x00
        MOVFF   PRODL, r0x01
        MOVLW   0x04
        ADDWF   FSR1L, F
        BTFSC   STATUS, 0
        INCF    FSR1H, F
        MOVLW   LOW(_mytasks)
        ADDWF   r0x00, F
        MOVLW   HIGH(_mytasks)
        ADDWFC  r0x01, F
        MOVFF   r0x00, FSR0L
        MOVFF   r0x01, FSR0H
        MOVFF   LOW(_ledon), POSTINC0
        MOVFF   HIGH(_ledon), POSTINC0
        MOVFF   UPPER(_ledon), INDF0
        MOVFF   PREINC1, r0x01
        MOVFF   PREINC1, r0x00
        MOVFF   PREINC1, FSR2H
        MOVFF   PREINC1, FSR2L
        RETURN  

; ; Starting pCode block
S_main__ledon   code
_ledon:
;       .line   18; main.c      void ledon(void) {
        MOVFF   FSR2H, POSTDEC1
        MOVFF   FSR2L, POSTDEC1
        MOVFF   FSR1L, FSR2L
        MOVFF   FSR1H, FSR2H
;       .line   19; main.c      PORTBbits.RB4 = 1;
        BSF     _PORTBbits, 4
        MOVFF   PREINC1, FSR2H
        MOVFF   PREINC1, FSR2L
        RETURN  



; Statistics:
; code size:      202 (0x00ca) bytes ( 0.15%)
;                 101 (0x0065) words
; udata size:      70 (0x0046) bytes (13.67%)
; access size:      2 (0x0002) bytes


        end

Line 25 works
Line 26 works
Line 27 does now work

26      mytasks[0].fp = ledon;
27      mytasks[j].fp = ledon;
28      mytasks[a].fp = ledon;

Using gpsim I check where mytasks is located 0x0060 and look at the ram

After completing line 26 the address of ledon is stored in 0x0060 as follows:

0x0060 02 02 00 ...

After completing line 27 the address of ledon is stored correctly.
When I single step through the assembler for line 28 I end up with the
following:

0x0060 00 00 60

I don't know why. I have tried various options like optimization,
__reentrant, #pragma nooverlay and still can't get any joy.

A little light in the right area much appreciated.

Jonathan

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to