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