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
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user