@nataliapc/mcp-openmsx 1.2.10 → 1.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -2
- package/dist/chunker.js +187 -0
- package/dist/embedder.js +250 -0
- package/dist/server.js +6 -1
- package/dist/server_tools.js +6 -5
- package/dist/vectordb.js +94 -35
- package/package.json +4 -8
- package/resources/audio/chipsfmpacpr1_en.md +209 -0
- package/resources/audio/chipsfmpacpr2_en.md +170 -0
- package/resources/audio/toc.json +12 -0
- package/resources/book--msx-top-secret-3/MTS3-Appendix-English-Upd2.pdf +0 -0
- package/resources/book--msx-top-secret-3/MTS3-Complete-English.pdf +0 -0
- package/resources/book--msx2-technical-handbook/toc.json +1 -1
- package/resources/book--the-msx-red-book/Chapter1_Programmable_Peripheral_Interface.md +112 -0
- package/resources/book--the-msx-red-book/Chapter2_Video_Display_Processor.md +308 -0
- package/resources/book--the-msx-red-book/Chapter3_Programmable_Sound_Generator.md +168 -0
- package/resources/book--the-msx-red-book/Chapter4_ROM_BIOS.md +2528 -0
- package/resources/book--the-msx-red-book/Chapter5_ROM_BASIC_Interpreter.md +3975 -0
- package/resources/book--the-msx-red-book/Chapter6_Memory_Map.md +1963 -0
- package/resources/book--the-msx-red-book/Chapter7_Machine_Code_Programs.md +1238 -0
- package/resources/book--the-msx-red-book/Introduction.md +104 -0
- package/resources/book--the-msx-red-book/toc.json +38 -3
- package/resources/processors/toc.json +3 -3
- package/resources/processors/z80-undocumented.md +141 -0
- package/resources/sdcc/1_Introduction.md +199 -0
- package/resources/sdcc/2_Installing_SDCC.md +533 -0
- package/resources/sdcc/3_Using_SDCC.md +1758 -0
- package/resources/sdcc/4_Notes_on_supported_Processors.md +1638 -0
- package/resources/sdcc/5_Debugging.md +210 -0
- package/resources/sdcc/6_Tips_and_Support.md +258 -0
- package/resources/sdcc/7_SDCC_Technical_Data.md +489 -0
- package/resources/sdcc/8_Compiler_internals.md +477 -0
- package/resources/sdcc/toc.json +44 -2
- package/vector-db/msxdocs.lance/_indices/4d3bd360-e3c6-408d-b0ff-a4d6bd9580cb/metadata.lance +0 -0
- package/vector-db/msxdocs.lance/_indices/4d3bd360-e3c6-408d-b0ff-a4d6bd9580cb/part_0_docs.lance +0 -0
- package/vector-db/msxdocs.lance/_indices/4d3bd360-e3c6-408d-b0ff-a4d6bd9580cb/part_0_invert.lance +0 -0
- package/vector-db/msxdocs.lance/_indices/4d3bd360-e3c6-408d-b0ff-a4d6bd9580cb/part_0_tokens.lance +0 -0
- package/vector-db/msxdocs.lance/_transactions/0-6f47c9fc-3657-40f0-9dd4-c7226b2a4805.txn +0 -0
- package/vector-db/msxdocs.lance/_transactions/1-2bb7426e-a4b0-40ea-9a58-00c4985fc6a9.txn +0 -0
- package/vector-db/msxdocs.lance/_versions/18446744073709551613.manifest +0 -0
- package/vector-db/msxdocs.lance/_versions/18446744073709551614.manifest +0 -0
- package/vector-db/msxdocs.lance/_versions/latest_version_hint.json +1 -0
- package/vector-db/msxdocs.lance/data/110001110001011010001000876c134b8296fbc47762d1e1ab.lance +0 -0
- package/resources/book--the-msx-red-book/the_msx_red_book.md +0 -10349
- package/resources/processors/z80-undocumented.tex +0 -5617
- package/resources/sdcc/lyx2md.py +0 -745
- package/resources/sdcc/sdccman.lyx +0 -81574
- package/resources/sdcc/sdccman.md +0 -5557
- package/vector-db/index.json +0 -1
|
@@ -0,0 +1,1638 @@
|
|
|
1
|
+
# SDCC Compiler User Guide
|
|
2
|
+
|
|
3
|
+
## Notes on supported Processors
|
|
4
|
+
|
|
5
|
+
### MCS51 variants range none pageformat default MCS51 variants
|
|
6
|
+
|
|
7
|
+
MCS51 processors are available from many vendors and come in many different flavours. While they might differ considerably in respect to Special Function Registers the core MCS51 is usually not modified or is kept compatible.
|
|
8
|
+
|
|
9
|
+
#### pdata access by SFR
|
|
10
|
+
|
|
11
|
+
With the upcome of devices with internal xdata and flash memory devices using port P2 range none pageformat default P2 (mcs51 sfr) as dedicated I/O port is becoming more popular. Switching the high byte for __pdata range none pageformat default pdata (mcs51, ds390 named address space) access which was formerly done by port P2 is then achieved by a Special Function Register range none pageformat default sfr. In well-established MCS51 tradition the address of this *sfr* is where the chip designers decided to put it. Needless to say that they didn't agree on a common name either. So that the startup code can correctly initialize xdata variables, you should define an sfr with the name _XPAGE range none pageformat default XPAGE (mcs51) at the appropriate location if the default, port P2, is not used for this. Some examples are:
|
|
12
|
+
```c
|
|
13
|
+
__sfr __at (0x85) _XPAGE; /* Ramtron VRS51 family a.k.a. MPAGE */
|
|
14
|
+
|
|
15
|
+
__sfr __at (0x92) _XPAGE; /* Cypress EZ-USB family, Texas Instruments (Chipcon) a.k.a. MPAGE */
|
|
16
|
+
|
|
17
|
+
__sfr __at (0x91) _XPAGE; /* Infineon (Siemens) C500 family a.k.a. XPAGE */
|
|
18
|
+
|
|
19
|
+
__sfr __at (0xaf) _XPAGE; /* some Silicon Labs (Cygnal) chips a.k.a. EMI0CN */
|
|
20
|
+
|
|
21
|
+
__sfr __at (0xaa) _XPAGE; /* some Silicon Labs (Cygnal) chips a.k.a. EMI0CN */
|
|
22
|
+
```
|
|
23
|
+
There are also devices without anything resembling _XPAGE, but luckily they usually have dual data-pointers. For these devices a different method can be used to correctly initialize xdata variables. A default implementation is already in crtxinit.asm but it needs to be assembled manually with DUAL_DPTR set to 1.
|
|
24
|
+
|
|
25
|
+
For more exotic implementations further customizations may be needed. See section MCS51/DS390 Startup Code for other possibilities.
|
|
26
|
+
|
|
27
|
+
#### Other Features available by SFR
|
|
28
|
+
|
|
29
|
+
Some MCS51 variants offer features like Dual DPTR range none pageformat default DPTR, multiple DPTR, decrementing DPTR, 16x16 Multiply. These are currently not used for the MCS51 port. If you absolutely need them you can fall back to inline assembly or submit a patch to SDCC.
|
|
30
|
+
|
|
31
|
+
#### Bankswitching
|
|
32
|
+
|
|
33
|
+
Bankswitching range none pageformat default Bankswitching (a.k.a. code banking range none pageformat default code banking) is a technique to increase the code space above the 64k limit of the 8051.
|
|
34
|
+
|
|
35
|
+
##### Hardware
|
|
36
|
+
|
|
37
|
+
| 8000-FFFF | bank1 | bank2 | bank3 |
|
|
38
|
+
| --- | --- | --- | --- |
|
|
39
|
+
| 0000-7FFF | common | | |
|
|
40
|
+
| SiLabs C8051F120 example | | | |
|
|
41
|
+
| SiLabs C8051F120 example | | | |
|
|
42
|
+
|
|
43
|
+
Usually the hardware uses some sfr (an output port or an internal sfr) to select a bank and put it in the banked area of the memory map. The selected bank usually becomes active immediately upon assignment to this sfr and when running inside a bank it will switch out this code it is currently running. Therefor you cannot jump or call directly from one bank to another and need to use a so-called trampoline in the common area. For SDCC an example trampoline is in crtbank.asm and you may need to change it to your 8051 derivative or schematic. The presented code is written for the C8051F120.
|
|
44
|
+
|
|
45
|
+
When calling a banked function SDCC will put the LSB of the functions address in register R0, the MSB in R1 and the bank in R2 and then call this trampoline *__sdcc_banked_call*. The current selected bank is saved on the stack, the new bank is selected and an indirect jump is made. When the banked function returns it jumps to *__sdcc_banked_ret* which restores the previous bank and returns to the caller.
|
|
46
|
+
|
|
47
|
+
##### Software
|
|
48
|
+
|
|
49
|
+
When writing banked software using SDCC you need to use some special keywords and options. You also need to take over a bit of work from the linker.
|
|
50
|
+
|
|
51
|
+
To create a function that can be called from another bank it requires the keyword *__banked* range none pageformat default banked. The caller must see this in the prototype of the callee and the callee needs it for a proper return. Called functions within the same bank as the caller do not need the *__banked* keyword nor do functions in the common area. Beware: SDCC does not know or check if functions are in the same bank. This is your responsibility!
|
|
52
|
+
|
|
53
|
+
Normally all functions you write end up in the segment CSEG. If you want a function explicitly to reside in the common area put it in segment HOME. This applies for instance to interrupt service routines as they should not be banked.
|
|
54
|
+
|
|
55
|
+
Functions that need to be in a switched bank must be put in a named segment. The name can be mostly anything up to eight characters (e.g. BANK1). To do this you either use --codeseg BANK1 (See Other Options) on the command line when compiling or #pragma codeseg BANK1 (See Pragmas) at the top of the C source file. The segment name always applies to the whole source file and generated object so functions for different banks need to be defined in different source files.
|
|
56
|
+
|
|
57
|
+
When linking your objects you need to tell the linker where to put your segments. To do this you use the following command line option to SDCC:-Wl-b BANK1=0x18000 (See Linker Options). This sets the virtual start address of this segment. It sets the banknumber to 0x01 and maps the bank to 0x8000 and up. The linker will not check for overflows, again this is your responsibility.
|
|
58
|
+
|
|
59
|
+
#### MCS51/DS390 Startup Code
|
|
60
|
+
|
|
61
|
+
The compiler triggers the linker to link certain initialization modules from the runtime library range none pageformat default Runtime library called crt<something>. Only the necessary ones are linked, for instance crtxstack.asm (GSINIT1, GSINIT5) is not linked unless the - -xstack option is used. These modules are highly entangled by the use of special segments/areas, but a common layout is shown below:
|
|
62
|
+
|
|
63
|
+
**(main.asm)**
|
|
64
|
+
```asm
|
|
65
|
+
.area HOME (CODE)
|
|
66
|
+
__interrupt_vect:
|
|
67
|
+
ljmp __sdcc_gsinit_startup
|
|
68
|
+
```
|
|
69
|
+
**(crtstart.asm)**
|
|
70
|
+
```asm
|
|
71
|
+
.area GSINIT0 (CODE)
|
|
72
|
+
__sdcc_gsinit_startup::
|
|
73
|
+
mov sp,#__start__stack - 1
|
|
74
|
+
```
|
|
75
|
+
**(crtxstack.asm)**
|
|
76
|
+
```asm
|
|
77
|
+
.area GSINIT1 (CODE)
|
|
78
|
+
__sdcc_init_xstack::
|
|
79
|
+
; Need to initialize in GSINIT1 in case the user's __sdcc_external_startup uses the xstack.
|
|
80
|
+
mov __XPAGE,#(__start__xstack >> 8)
|
|
81
|
+
mov _spx,#__start__xstack
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**(crtstart.asm)**
|
|
85
|
+
```asm
|
|
86
|
+
.area GSINIT2 (CODE)
|
|
87
|
+
lcall ___sdcc_external_startup
|
|
88
|
+
mov a,dpl
|
|
89
|
+
jz __sdcc_init_data
|
|
90
|
+
ljmp __sdcc_program_startup
|
|
91
|
+
__sdcc_init_data:
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**(crtxinit.asm)**
|
|
95
|
+
```asm
|
|
96
|
+
.area GSINIT3 (CODE)
|
|
97
|
+
__mcs51_genXINIT::
|
|
98
|
+
mov r1,#l_XINIT
|
|
99
|
+
mov a,r1
|
|
100
|
+
orl a,#(l_XINIT >> 8)
|
|
101
|
+
jz 00003$
|
|
102
|
+
mov r2,#((l_XINIT+255) >> 8)
|
|
103
|
+
mov dptr,#s_XINIT
|
|
104
|
+
mov r0,#s_XISEG
|
|
105
|
+
mov __XPAGE,#(s_XISEG >> 8)
|
|
106
|
+
00001$: clr a
|
|
107
|
+
movc a,@a+dptr
|
|
108
|
+
movx @r0,a
|
|
109
|
+
inc dptr
|
|
110
|
+
inc r0
|
|
111
|
+
cjne r0,#0,00002$
|
|
112
|
+
inc __XPAGE
|
|
113
|
+
00002$: djnz r1,00001$
|
|
114
|
+
djnz r2,00001$
|
|
115
|
+
mov __XPAGE,#0xFF
|
|
116
|
+
00003$:
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**(crtclear.asm)**
|
|
120
|
+
```asm
|
|
121
|
+
.area GSINIT4 (CODE)
|
|
122
|
+
__mcs51_genRAMCLEAR::
|
|
123
|
+
clr a
|
|
124
|
+
mov r0,#(l_IRAM-1)
|
|
125
|
+
00004$: mov @r0,a
|
|
126
|
+
djnz r0,00004$
|
|
127
|
+
; _mcs51_genRAMCLEAR() end
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**(crtxclear.asm)**
|
|
131
|
+
|
|
132
|
+
```asm
|
|
133
|
+
.area GSINIT4 (CODE)
|
|
134
|
+
__mcs51_genXRAMCLEAR::
|
|
135
|
+
mov r0,#l_PSEG
|
|
136
|
+
mov a,r0
|
|
137
|
+
orl a,#(l_PSEG >> 8)
|
|
138
|
+
jz 00006$
|
|
139
|
+
mov r1,#s_PSEG
|
|
140
|
+
mov __XPAGE,#(s_PSEG >> 8)
|
|
141
|
+
clr a
|
|
142
|
+
00005$: movx @r1,a
|
|
143
|
+
inc r1
|
|
144
|
+
djnz r0,00005$
|
|
145
|
+
00006$:
|
|
146
|
+
mov r0,#l_XSEG
|
|
147
|
+
mov a,r0
|
|
148
|
+
orl a,#(l_XSEG >> 8)
|
|
149
|
+
jz 00008$
|
|
150
|
+
mov r1,#((l_XSEG + 255) >> 8)
|
|
151
|
+
mov dptr,#s_XSEG
|
|
152
|
+
clr a
|
|
153
|
+
00007$: movx @dptr,a
|
|
154
|
+
inc dptr
|
|
155
|
+
djnz r0,00007$
|
|
156
|
+
djnz r1,00007$
|
|
157
|
+
00008$:
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**(crtxstack.asm)**
|
|
161
|
+
```asm
|
|
162
|
+
.area GSINIT5 (CODE)
|
|
163
|
+
; Need to initialize in GSINIT5 because __mcs51_genXINIT modifies __XPAGE
|
|
164
|
+
; and __mcs51_genRAMCLEAR modifies _spx.
|
|
165
|
+
mov __XPAGE,#(__start__xstack >> 8)
|
|
166
|
+
mov _spx,#__start__xstack
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**(application modules)**
|
|
170
|
+
```asm
|
|
171
|
+
.area GSINIT (CODE)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**(main.asm)**
|
|
175
|
+
```asm
|
|
176
|
+
.area GSFINAL (CODE)
|
|
177
|
+
ljmp __sdcc_program_startup
|
|
178
|
+
;--------------------------------------------------------
|
|
179
|
+
; Home
|
|
180
|
+
;--------------------------------------------------------
|
|
181
|
+
.area HOME (CODE)
|
|
182
|
+
.area CSEG (CODE)
|
|
183
|
+
__sdcc_program_startup:
|
|
184
|
+
lcall _main
|
|
185
|
+
; return from main will lock up
|
|
186
|
+
sjmp.
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
On some mcs51 variants __xdata range none pageformat default xdata (mcs51, ds390 named address space memory has to be explicitly enabled before it can be accessed or if the watchdog range none pageformat default watchdog needs to be disabled, this is the place to do it. The startup code clears all internal data memory, 256 bytes by default, but from 0 to n-1 if *--iram-size range none pageformat default --iram-size <Value>* is used. (recommended for Chipcon CC1010).
|
|
190
|
+
|
|
191
|
+
See also the compiler option *--no-xinit*- *opt* range none pageformat default --no-xinit-opt and section MCS51 variants about MCS51-variants.
|
|
192
|
+
|
|
193
|
+
While these initialization modules are meant as generic startup code there might be the need for customization. Let's assume the return value of *__sdcc_external_startup()* in *crtstart.asm* should not be checked (or *__sdcc_external_startup()* should not be called at all). The recommended way would be to copy *crtstart.asm* (f.e. from http://svn.code.sf.net/p/sdcc/code/trunk/sdcc/device/lib/mcs51/crtstart.asm) into the source directory, adapt it there, then assemble it with *sdas8051 -plosgff "-plosgff" are the assembler options used in http://sdcc.svn.sourceforge.net/viewvc/sdcc/trunk/sdcc/device/lib/mcs51/Makefile.in?view=markup crtstart.asm* and when linking your project explicitly specify *crtstart.rel*. As a bonus a listing of the relocated object file *crtstart.rst* is generated.
|
|
194
|
+
|
|
195
|
+
#### Interfacing with Assembler Code range none pageformat default Assembler routines
|
|
196
|
+
|
|
197
|
+
##### Global Registers used for Parameter Passing range none pageformat default Parameter passing
|
|
198
|
+
|
|
199
|
+
The compiler always uses the global registers *DPL, DPH range none pageformat default DPTR, DPH, DPL range none pageformat default DPTR, B range none pageformat default B (mcs51, ds390 register)* and *ACC range none pageformat default ACC (mcs51, ds390 register)* to pass the first (non-bit, non-struct) parameter to a function, and also to pass the return value range none pageformat default return value of function; according to the following scheme: one byte return value in *DPL*, two byte value in *DPL* (LSB) and *DPH* (MSB). three byte values (generic pointers) in *DPH*, *DPL* and *B*, and four byte values in *DPH*, *DPL*, *B* and *ACC*. Generic pointers range none pageformat default generic pointer contain type of accessed memory in *B*: **0x00** --xdata/far, **0x40** --idata/near --, **0x60** --pdata, **0x80** -- code This might not be the case of certain memory models (medium???).
|
|
200
|
+
|
|
201
|
+
Further such parameters (and all struct parameters, as well as the bit parameters from the 9th onwards) are either allocated on the stack (for reentrant routines or if --stack-auto is used) or in data/xdata memory (depending on the memory model).
|
|
202
|
+
|
|
203
|
+
The first 8 bit parameters are passed in a virtual register called 'bits' in bit-addressable space for reentrant functions or allocated directly in bit memory otherwise.
|
|
204
|
+
|
|
205
|
+
Functions (with two or more parameters or bit parameters) that are called through function pointers range none pageformat default function pointers must therefor be reentrant so the compiler knows how to pass the parameters.
|
|
206
|
+
|
|
207
|
+
##### Register usage
|
|
208
|
+
|
|
209
|
+
Unless the called function is declared as _naked range none pageformat default naked, or the --callee-saves range none pageformat default --callee-saves /--all-callee-saves command line option or the corresponding callee_saves pragma are used, the caller will save the registers (*R0-R7*) around the call, so the called function can destroy they content freely.
|
|
210
|
+
|
|
211
|
+
If the called function is not declared as _naked, the caller will swap register banks around the call, if caller and callee use different register banks (having them defined by the __using modifier).
|
|
212
|
+
|
|
213
|
+
The called function can also use *DPL*, *DPH*, *B* and *ACC* observing that they are used for parameter/return value passing.
|
|
214
|
+
|
|
215
|
+
##### Assembler Routine (non-reentrant)
|
|
216
|
+
|
|
217
|
+
In the following example range none pageformat default reentrant range none pageformat default Assembler routines (non-reentrant) the function c_func calls an assembler routine asm_func, which takes two parameters range none pageformat default function parameter.
|
|
218
|
+
```c
|
|
219
|
+
extern int asm_func(unsigned char, unsigned char);
|
|
220
|
+
|
|
221
|
+
int c_func (unsigned char i, unsigned char j)
|
|
222
|
+
{
|
|
223
|
+
return asm_func(i,j);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
int main()
|
|
227
|
+
{
|
|
228
|
+
return c_func(10,9);
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
The corresponding assembler function is:
|
|
232
|
+
```asm
|
|
233
|
+
.globl _asm_func_PARM_2
|
|
234
|
+
.globl _asm_func
|
|
235
|
+
.area OSEG
|
|
236
|
+
_asm_func_PARM_2:
|
|
237
|
+
.ds 1
|
|
238
|
+
.area CSEG
|
|
239
|
+
_asm_func:
|
|
240
|
+
mov a,dpl
|
|
241
|
+
add a,_asm_func_PARM_2
|
|
242
|
+
mov dpl,a
|
|
243
|
+
mov dph range none pageformat default DPTR, DPH, DPL,#0x00
|
|
244
|
+
ret
|
|
245
|
+
```
|
|
246
|
+
The parameter naming convention is _<function_name>_PARM_<n>, where n is the parameter number starting from 1, and counting from the left. The first parameter is passed in *DPH*, *DPL*, *B* and *ACC* according to the description above. The variable name for the second parameter will be _<function_name>_PARM_2.
|
|
247
|
+
|
|
248
|
+
Assemble the assembler routine with the following command:
|
|
249
|
+
|
|
250
|
+
**sdas8051 -losg asmfunc.asm
|
|
251
|
+
|
|
252
|
+
** Then compile and link the assembler routine to the C source file with the following command:
|
|
253
|
+
|
|
254
|
+
**sdcc cfunc.c asmfunc.rel
|
|
255
|
+
|
|
256
|
+
##### Assembler Routine (reentrant)
|
|
257
|
+
|
|
258
|
+
In this case range none pageformat default reentrant range none pageformat default Assembler routines (reentrant) the second parameter range none pageformat default function parameter onwards will be passed on the stack, the parameters are pushed from right to left i.e. before the call the second leftmost parameter will be on the top of the stack (the leftmost parameter is passed in registers). Here is an example:
|
|
259
|
+
```c
|
|
260
|
+
extern int asm_func(unsigned char, unsigned char, unsigned char) reentrant;
|
|
261
|
+
|
|
262
|
+
int c_func (unsigned char i, unsigned char j, unsigned char k) reentrant
|
|
263
|
+
{
|
|
264
|
+
return asm_func(i,j,k);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
int main()
|
|
268
|
+
{
|
|
269
|
+
return c_func(10,9,8);
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
The corresponding (unoptimized) assembler routine is:
|
|
274
|
+
```asm
|
|
275
|
+
.globl _asm_func
|
|
276
|
+
_asm_func:
|
|
277
|
+
push _bp
|
|
278
|
+
mov _bp,sp;stack contains: _bp, return address, second parameter, third parameter
|
|
279
|
+
mov r2,dpl
|
|
280
|
+
mov a,_bp
|
|
281
|
+
add a,#0xfd;calculate pointer to the second parameter
|
|
282
|
+
mov r0,a
|
|
283
|
+
mov a,_bp
|
|
284
|
+
add a,#0xfc;calculate pointer to the rightmost parameter
|
|
285
|
+
mov r1,a
|
|
286
|
+
mov a,@r0
|
|
287
|
+
add a,@r1
|
|
288
|
+
add a,r2;calculate the result (= sum of all three parameters)
|
|
289
|
+
mov dpl,a;return value goes into dptr (cast into int)
|
|
290
|
+
mov dph,#0x00
|
|
291
|
+
mov sp,_bp
|
|
292
|
+
pop _bp
|
|
293
|
+
ret
|
|
294
|
+
```
|
|
295
|
+
The compiling and linking procedure remains the same, however note the extra entry & exit linkage required for the assembler code, _bp is the stack frame pointer and is used to compute the offset into the stack for parameters and local variables.
|
|
296
|
+
|
|
297
|
+
### DS400 port
|
|
298
|
+
|
|
299
|
+
The DS80C400 range none pageformat default DS80C400 range none pageformat default DS400 microcontroller has a rich set of peripherals. In its built-in ROM library it includes functions to access some of the features, among them is a TCP stack with IP4 and IP6 support. Library headers (currently in beta status) and other files are provided at ftp://ftp.dalsemi.com/pub/tini/ds80c400/c_libraries/sdcc/index.html.
|
|
300
|
+
|
|
301
|
+
### The Z80, Z180, Rabbit 2000, Rabbit 2000A, Rabbit 3000A, SM83 (GameBoy), eZ80, TLCS-90 and R800 ports
|
|
302
|
+
|
|
303
|
+
SDCC can target the Z80 range none pageformat default Z80, Z180, eZ80 in Z80 mode, Rabbit 2000, Rabbit 2000A, Rabbit 3000A and LR35902, the Sharp SM83 (used.e.g in the Nintendo GameBoy) sm83 range none pageformat default sm83 (GameBoy Z80).
|
|
304
|
+
|
|
305
|
+
When a frame pointer is used, it resides in IX. Register A, B, C, D, E, H, L and IY are used as a temporary registers for holding variables.
|
|
306
|
+
|
|
307
|
+
When enabling optimizations using --opt-code size and a sufficiently high value for --max-allocs-per-node SDCC typically generates much better code for these architectures than many other compilers. A comparison of compilers for these architecture can be found at http://sdcc.sourceforge.net/wiki/index.php/Z80_code_size.
|
|
308
|
+
|
|
309
|
+
#### Startup Code
|
|
310
|
+
|
|
311
|
+
On the Z80 range none pageformat default Z80 the startup code is inserted by linking with crt0.rel which is generated from sdcc/device/lib/z80/crt0.s. If you need a different startup code you can use the compiler option *- -no-std-crt0* range none pageformat default --no-std-crt0 and provide your own crt0.rel. When using a custom crt0.rel it needs to be listed first when linking.
|
|
312
|
+
|
|
313
|
+
#### Rabbit ports
|
|
314
|
+
|
|
315
|
+
SDCC has three Rabbit-supporting ports: r2k for the Rabbit 2000, r2ka for the Rabbit 2000A, 2000B, 2000C and 3000, r3ka for the Rabbit 3000A, 4000 and 6000. Some Rabbits support different memory types (Rabbit 4000 and later), different memory access modes (Rabbit 5000 and later), different instruction modes (Rabbit 4000 and later). All SDCC ports assume 8-bit memories, 8-bit memory access mode, 00/default instruction set mode (the code generated is also compatible with 10 and 01 instruction set mode, but not 11/enhanced instruction set mode).
|
|
316
|
+
|
|
317
|
+
##### Port choice
|
|
318
|
+
|
|
319
|
+
| Ports vs. Device | R2K | R2KA | R2KB | R2KC | R3K | R3KA | R4K | R5K | R6K |
|
|
320
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
321
|
+
| r2k | Y | y | y | y | y | y | y | N | N |
|
|
322
|
+
| r2ka | n | Y | Y | Y | y | y | y | N | N |
|
|
323
|
+
| r3ka | N | N | N | N | N | Y | Y | N | N |
|
|
324
|
+
| r3ka | N | N | N | N | N | Y | Y | N | N |
|
|
325
|
+
|
|
326
|
+
Legend:
|
|
327
|
+
|
|
328
|
+
Y - The code this port generates is the best for this CPU.
|
|
329
|
+
|
|
330
|
+
y - The code this port generates will work on this CPU.
|
|
331
|
+
|
|
332
|
+
N - The code this port generates will not work on this CPU.
|
|
333
|
+
|
|
334
|
+
n - The code this port generates will typically not work on this CPU.
|
|
335
|
+
|
|
336
|
+
There are multiple wait state bugs present in some of the the Rabbits. The difference between the r2k and r2ka port is additional wait state bug workarounds. If all memory used has zero wait states, code from the r2ka backend can be safely run on the original Rabbit 2000.
|
|
337
|
+
|
|
338
|
+
The r2k and r2ka port assume that the whole stack has the same number of wait states (code from the r2k and r2ka ports can fail is the stack spans memories with a different amount of wait states).
|
|
339
|
+
|
|
340
|
+
The Rabbit 2000 has some wait state bugs that SDCC does not work around. These bugs result in the number of wait states used being one less than configured for some instructions. The workaround has to be supplied by the user, by configuring all memories that do use wait states to use on additional wait state.
|
|
341
|
+
|
|
342
|
+
For all Rabbit ports, SDCC assumes that all data memory is at least as fast (i.e. does not need more wait states) as all code memory. Code where this is not the case (e.g. code in fast Flash writing into slow battery-backed SRAM) will have to be written in assembler by hand.
|
|
343
|
+
|
|
344
|
+
##### Rabbit hardware bugs
|
|
345
|
+
|
|
346
|
+
| Bug | R2K | R2KA | R2KB | R2KC | R3K | R3KA | R4K | R5K | R6K |
|
|
347
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
348
|
+
| ioi / ioe prefix bug | x | | | | | | | | |
|
|
349
|
+
| ddcb / fdcb wait state bug | U | | | | | | | | |
|
|
350
|
+
| conditional jump wait state bug | U | | | | | | | | |
|
|
351
|
+
| ldir / lddr wait state bug | U | | | | | | | | |
|
|
352
|
+
| mul wait state bug | w | | | | | | | | |
|
|
353
|
+
| ldir / lddr split bug | | S | | | | | | | |
|
|
354
|
+
| new ldir / lddr wait state bug | w | w | w | w | w | | | | |
|
|
355
|
+
| 16-bit mode alignment bug | | | | | | | | X | |
|
|
356
|
+
| ioi / ioe bit bug | | | | | | | | x | x |
|
|
357
|
+
| ret cc bug | | | | | | | | X | X |
|
|
358
|
+
| rmw wait state bug | W | W | W | W | W | W | W | W | |
|
|
359
|
+
| 16-bit vs. 8-bit wait state bug | | | | | | | W | | |
|
|
360
|
+
| dma vs stack prot. bug | | | | | | | X | | |
|
|
361
|
+
| 16-bit dma vs. ldir / lddr / etc. bug | | | | | | | X | | |
|
|
362
|
+
| cplx bug | | | | | | | | | x |
|
|
363
|
+
| dma match bug | | | | | | | | | X |
|
|
364
|
+
| ex jkhl, bcde alt reg bug | | | | | | | | | x |
|
|
365
|
+
| ldbyte bug | | | | | | | | | x |
|
|
366
|
+
| puma bug | | | | | | | | | x |
|
|
367
|
+
| puma bug | | | | | | | | | x |
|
|
368
|
+
|
|
369
|
+
Legend:
|
|
370
|
+
|
|
371
|
+
x s w u - bug present, worked around by SDCC.
|
|
372
|
+
|
|
373
|
+
X S W U - bug present, not worked around by SDCC.
|
|
374
|
+
|
|
375
|
+
w W u U - wait state bug, only relevant when the Rabbit is configured to have wait states for some memory.
|
|
376
|
+
|
|
377
|
+
s S - instruction / data split bug, only relevant when instruction / data split is enabled, which is currently not supported by SDCC.
|
|
378
|
+
|
|
379
|
+
u U - bug can be worked around by the user by configuring memory that needs wait states to use one additional wait state.
|
|
380
|
+
|
|
381
|
+
The 16-bit mode alignment bug only affects 16-bit mode, which is not currently supported by SDCC.
|
|
382
|
+
|
|
383
|
+
The rmw wait state bug is only relevant when executing fast code writing to slow memory, such as code in fast RAM writing to slow battery-backed SRAM.
|
|
384
|
+
|
|
385
|
+
The 16-bit vs. 8-bit wait state bug is only relevant when the target system uses both 16-bit and 8-bit memories for code, and the 8-bit memory requires wait states.
|
|
386
|
+
|
|
387
|
+
The 16-bit dma vs. ldir / lddr / etc. bug is only relevant when using DMA and the target system uses 16-bit memory for code. Since SDCC uses the block move instructions like ldir, lddr, etc. without applying a workaround, this means that code execution and DMA may then not happen at the same time. A possible user workaround is to not use DMA when using 16-bit memory for code. Among all Rabbit 4000-based RCM and BL modules, only the RCM4000 and the RCM4010 use 16-bit memories.
|
|
388
|
+
|
|
389
|
+
The dma match bug is only relevant when a DMA termination mask register is set to a nonzero value.
|
|
390
|
+
|
|
391
|
+
#### Z80, Z180, Z80N and R800 calling conventions
|
|
392
|
+
|
|
393
|
+
The current default is the SDCC calling convention, version 1. Using the command-line option --sdcccall 0, the default can be changed to version 0. There are three other calling conventions supported, which can be specified using the keywords __smallc, __z88dk_fastcall and __z88dk_callee. They are primarily intended for compatibility with libraries written for other compilers. For __z88dk_fastcall, there may be only one parameter of at most 32 bits, which is passed the same way as the return value of __sdcccall(0). For __z88dk_callee, the stack is not adjusted for stack parameters the parameters after the call (thus the callee has to do this instead). __z88dk_callee can be combined with __smallc, __sdcccall(0) or __sdcccall(1).
|
|
394
|
+
|
|
395
|
+
##### Z80 SDCC calling convention, version 1
|
|
396
|
+
|
|
397
|
+
This calling convention can be chosen per function via __sdcccall(1). 8-bit return values are passed in a, 16-bit values in de, 24-bit values in lde, 32-bit values in hlde. Larger return values (as well as struct and union independent of their size) are passed in memory in a location specified by the caller through a hidden pointer argument.
|
|
398
|
+
|
|
399
|
+
For functions that have variable arguments: All parameters are passed on the stack. The stack is not adjusted for the parameters by the callee (thus the caller has to do this instead).
|
|
400
|
+
|
|
401
|
+

|
|
402
|
+
|
|
403
|
+
For Functions that do not have variable arguments: the first parameter is passed in a if it has 8 bits. If it has 16 bits it is passed in hl. If it has 32 bits, it is passed in hlde. If the first parameter is in a, and the second has 8 bits, it is passed in l; if the first is passed in a or hl, and the second has 16 bits, it is passed in de; all other parameters are passed on the stack, right-to-left. Independent of their size, struct / union parameters and all following parameters are always passed on the stack.
|
|
404
|
+
|
|
405
|
+

|
|
406
|
+
|
|
407
|
+
If __z88dk_callee is not used, after the call, the stack parameters are cleaned up by the caller, with the following exceptions: functions that do not have variable arguments and return void or a type of at most 16 bits, or have both a first parameter of type float and a return value of type float.
|
|
408
|
+
|
|
409
|
+
##### Z80 SDCC calling convention, version 0
|
|
410
|
+
|
|
411
|
+
This calling convention can be chosen per function via __sdcccall(0). All parameters are passed on the stack, right-to-left. 8-bit return values are passed in l, 16-bit values in hl, 24-bit values in ehl, 32-bit values in dehl. Except for the SM83, where 8-bit values are passed in e, 16-bit values in de, 32-bit values in hlde. Larger return values (as well as struct and union independent of their size) are passed in a memory in a location specified by the caller through a hidden pointer argument. Unless __z88dk_callee is used, all stack parameters are cleaned up by the caller.
|
|
412
|
+
|
|
413
|
+
#### Rabbit 2000, Rabbit 2000A, Rabbit 3000A, eZ80 and TLCS-90 calling conventions
|
|
414
|
+
|
|
415
|
+
The current default is the Rabbit calling convetion desribed here, version 1. Using the command-line option --sdcccall 8, the default can be changed to version 0 of the Z80 calling convention, described above. There are four other calling conventions supported, which can be specified using the keywords __smallc, __z88dk_fastcall and __z88dk_callee. They are primarily intended for compatibility with libraries written for other compilers. For __z88dk_fastcall, there may be only one parameter of at most 32 bits, which is passed the same way as the return value. For __z88dk_callee, the stack is not adjusted for stack parameters the parameters after the call (thus the callee has to do this instead). __z88dk_callee can be combined with __smallc, __sdcccall(0) or __sdcccall(1).
|
|
416
|
+
|
|
417
|
+
##### Rabbit SDCC calling convention, version 1
|
|
418
|
+
|
|
419
|
+
This calling convention can be chosen per function via __sdcccall(1). 8-bit return values are passed in a, 16-bit values in hl, 24-bit values in lde, 32-bit values in hlde. Larger return values (as well as struct and union independent of their size) are passed in memory in a location specified by the caller through a hidden pointer argument.
|
|
420
|
+
|
|
421
|
+
For functions that have variable arguments: All parameters are passed on the stack. The stack is not adjusted for the parameters by the callee (thus the caller has to do this instead).
|
|
422
|
+
|
|
423
|
+

|
|
424
|
+
|
|
425
|
+
For Functions that do not have variable arguments: the first parameter is passed in a if it has 8 bits. If it has 16 bits it is passed in hl. If it has 32 bits, it is passed in hlde. If the first parameter is in a, and the second has 8 bits, it is passed in l; if the first is in hl or hlde, and the second has 8 bits, it is passed in a; if the first is in a, and the second has 16 bits, it is passed in hl; all other parameters are passed on the stack, right-to-left. Independent of their size, struct / union parameters and all following parameters are always passed on the stack.
|
|
426
|
+
|
|
427
|
+

|
|
428
|
+
|
|
429
|
+
If __z88dk_callee is not used, after the call, the stack parameters are cleaned up by the caller, with the following exceptions: functions that do not have variable arguments and return void or a type of at most 16 bits, or have both a first parameter of type float and a return value of type float.
|
|
430
|
+
|
|
431
|
+
#### SM83 calling conventions
|
|
432
|
+
|
|
433
|
+
The current default is the SDCC calling convention, version 1. Using the command-line option --sdcccall 0, the default can be changed to version 0.
|
|
434
|
+
|
|
435
|
+
##### SM83 SDCC calling convention, version 1
|
|
436
|
+
|
|
437
|
+
This calling convention can be chosen per function via __sdcccall(1).
|
|
438
|
+
|
|
439
|
+
8-bit return values are passed in a, 16-bit values in bc, 32-bit values in debc. Larger return values (as well as struct and union independent of their size) are passed in memory in a location specified by the caller through a hidden pointer argument.
|
|
440
|
+
|
|
441
|
+
For functions that have variable arguments: All parameters are passed on the stack. The stack is not adjusted for the parameters by the callee (thus the caller has to do this instead).
|
|
442
|
+
|
|
443
|
+

|
|
444
|
+
|
|
445
|
+
For Functions that do not have variable arguments: the first parameter is passed in a if it has 8 bits. If it has 16 bits it is passed in de. If it has 32 bits, it is passed in debc. If the first parameter is in a, and the second has 8 bits, it is passed in e; if the first is in bc or debc, and the second has 8 bits, it is passed in a; if the first is passed in a, and the second has 16 bits, it is passed in bc; if the first is passed in de, and the second has 16 bits, it is passed in bc; all other parameters are passed on the stack, right-to-left. Independent of their size, struct / union parameters and all following parameters are always passed on the stack. The stack is adjusted by the callee (thus explicitly specifying __z88dk_callee does not make a difference), unless the functionhas variable arguments.
|
|
446
|
+
|
|
447
|
+
##### SM83 SDCC calling convention, version 0
|
|
448
|
+
|
|
449
|
+
This calling convention can be chosen per function via __sdcccall(0). 8-bit return values are passed in e, 16-bit values in de, 32-bit values in hlde. Larger return values (as well as struct and union independent of their size) are passed in memory in a location specified by the caller through a hidden pointer argument. All parameters are passed on the stack. The stack is not adjusted for the parameters by the callee (thus the caller has to do this instead), unless __z88dk_callee is specified. __sdcccall(0) can be combined with __z88dk_callee.
|
|
450
|
+
|
|
451
|
+
#### Small-C calling convention
|
|
452
|
+
|
|
453
|
+
Functions declared as __smallc are called using the Small-C calling convention (passing arguments on-stack left-to-right, 1 byte arguments are passed as 2 bytes, with the value in the lower byte). 8-bit return values are passed in a, 16-bit values in de, 32-bit values in hlde. Larger return values (as well as struct and union independent of their size) are passed in memory in a location specified by the caller through a hidden pointer argument. This way assembler routines originally written for Small-C or code generated by Small-C can be called from SDCC. Currently variable arguments are not yet supported (neither on the caller nor on the callee side).
|
|
454
|
+
|
|
455
|
+
#### Complex instructions
|
|
456
|
+
|
|
457
|
+
The Z80 and some derivatives support complex instructions, such as ldir, cpir,.... SDCC only emits these instructions for functions in the standard library. Thus, e.g. copying one array into another is more efficient when using memcpy() than by using a a user-written loop.
|
|
458
|
+
|
|
459
|
+
Depending on the target, code generation options and the parameters to the call, SDCC emits ldir for memcpy(), ldir or lsidr for memset(), ldi for strcpy(), ldi for strncpy(). Other library functions use the complex instructions as well, but for those, function calls are generated.
|
|
460
|
+
|
|
461
|
+
#### Unsafe reads
|
|
462
|
+
|
|
463
|
+
Usually, Z80-based systems (except for the SM83 and TLCS-90) have separate I/O and memory spaces, and any normal memory location can be read without side-effects. For such systems, the option --allow-unsafe-reads can be used to enable some extra optimizations that rely on this.
|
|
464
|
+
|
|
465
|
+
#### Z80 banked calls
|
|
466
|
+
|
|
467
|
+
Banked calls are supported via __banked. Banked calls are done via a trampoline (__sdcc_bcall if --legacy-banking is specified, __sdcc_bcall_abc for z88dk_fastcall, __sdcc_bcall_ehl for other calls). Default trampolines are provided in the library. The default trampolines calls user supplied helper functions set_bank and get_bank that set the current bank to the value in register a, or return the current bank in register a.
|
|
468
|
+
|
|
469
|
+
For banked functions, the calling convention is slightly different: the stack is always cleared up by the caller. Unless __z88dk_fastcall is used, all parameters are passed on the stack.
|
|
470
|
+
|
|
471
|
+
### The HC08 and S08 ports
|
|
472
|
+
|
|
473
|
+
The port to the Freescale/Motorola HC08 range none pageformat default HC08 and S08 does not yet generate code as compact as that generated by some non-free compilers. A comparison of compilers for these architecture can be found at http://sdcc.sourceforge.net/wiki/index.php/Hc08_code_size.
|
|
474
|
+
|
|
475
|
+
#### Startup Code
|
|
476
|
+
|
|
477
|
+
The HC08 range none pageformat default HC08 startup code follows the same scheme as the MCS51 startup code.
|
|
478
|
+
|
|
479
|
+
### The STM8 port
|
|
480
|
+
|
|
481
|
+
#### Calling conventions
|
|
482
|
+
|
|
483
|
+
By default, the SDCC calling convention, version 1 is used. Using the option --sdcccall 0, the default can be changed to version 0.
|
|
484
|
+
|
|
485
|
+
Arguments are passed on the stack right-to-left. Return values are in a (8 bit), x (16 bit), xyl (24 bit), xy (32 bit) or use a hidden extra pointer parameter pointing to the location (anything wider than 32 bit, and all struct / union).
|
|
486
|
+
|
|
487
|
+
##### SDCC calling convention, version 1
|
|
488
|
+
|
|
489
|
+

|
|
490
|
+
|
|
491
|
+
For functions that have variable arguments, all parameters are passed on the stack. For other functions, if the first parameter has 8 or 16 bits, it is passed in a or x. If the first parameter is passed in a, and the second has 16 bits, the second is passed in x. If the first parameter is passed in x, and the second has 8 bits, the second is passed in a. All other parameters are passed on the stack. Independent of their size, struct / union parameters and all following parameters are always passed on the stack. If __z88dk_callee is specified, the stack is always adjusted by the callee. Otherwise, for the large memory model, the stack is always adjusted by the caller. For the medium memory model the stack is adjusted by the caller, with the following exceptions: functions that do not have variable arguments and return void or a type of at most 16 bits, or have both a first parameter of type float and a return value of type float.
|
|
492
|
+
|
|
493
|
+
##### SDCC calling convention, version 0
|
|
494
|
+
|
|
495
|
+
This calling convention can be chosen per function via __sdcccall(0) (e.g. for compatibility with functions written in assembler for use with older versions of SDCC). All parameters are passed on the stack. The stack is not adjusted for the parameters by the callee (thus the caller has to do this instead), unless __z88dk_callee is specified.
|
|
496
|
+
|
|
497
|
+
##### Raisonance calling convention
|
|
498
|
+
|
|
499
|
+
For compatibility with the Raisonance STM8 compiler, the __raisonance calling convention is supported. If the first parameter is 8 or 16 bits, it is passed in a or x. If the first parameter is 8 bits, and the second 16 bits, the second is passed in x. If the first parameter is 16 bits, and the second is 8 bits, the second is passed in a. All other parameters are passed on the stack. If the return value is 8 bits, it is passed in a. If it is 16 bits, it is passed in x. Raisonance passes larger return values in pseudoregisters, which is not supported by SDCC.
|
|
500
|
+
|
|
501
|
+
##### IAR calling convention
|
|
502
|
+
|
|
503
|
+
For compatibility with the IAR STM8 compiler, the __iar calling convention is supported. The first 8-bit parameter is passed in a, the first 16-bit parameter in x, the second 16-bit parameter in y. Further parameters of up to 32 bits are passed in pseudoregisters, which is not supported by SDCC. All other parameters are passed on the stack. If the return value is 8 bits, it is passed in a. If it is 16 bits, it is passed in x. IAR passes larger return values in pseudoregisters, which is not supported by SDCC.
|
|
504
|
+
|
|
505
|
+
##### Cosmic calling convention
|
|
506
|
+
|
|
507
|
+
For compatibility with the Cosmic STM8 compiler, the __cosmic calling convention is supported. If the first parameter is 8 or 16 bits, it is passed in a or x. If the return value is 8 bits, it is passed in a. If it is 16 bits, it is passed in x. Cosmic passes larger return values in pseudoregisters, which is not supported by SDCC. Even for the medium memory model, __cosmic functions use a 24-bit return address in their stack frame, and are called using callf.
|
|
508
|
+
|
|
509
|
+
### The f8 port
|
|
510
|
+
|
|
511
|
+
#### Calling convention
|
|
512
|
+
|
|
513
|
+
If the the function does not have variable arguments, and the first argument is not a struct or union and has 8 or 16 bits, it is passed in xl (8 bits) or y (16 bits). All other arguments are passed on the stack right-to-left. Return values are in xl (8 bit), x (16 bit), xxl (24 bit), yx (32 bit) or use a hidden extra pointer parameter pointing to the location (anything wider than 32 bit, and all struct / union). The stack is not adjusted for the parameters by the callee (thus the caller has to do this instead).
|
|
514
|
+
|
|
515
|
+
### The MOS6502 and WDC65C02 ports
|
|
516
|
+
|
|
517
|
+
The mos6502 range none pageformat default MOS6502 port can target the original MOS Technology NMOS 6502, and the CMOS Rockwell/WDC 65C02 with enhanched instruction set.
|
|
518
|
+
|
|
519
|
+
#### Startup Code
|
|
520
|
+
|
|
521
|
+
On the MOS6502 range none pageformat default MOS6502 the startup code is inserted by linking with crt0.rel which is generated from sdcc/device/lib/mos6502/crt0.s. If you need a different startup code you can use the compiler option *- -no-std-crt0* range none pageformat default --no-std-crt0 and provide your own crt0.rel. When using a custom crt0.rel it needs to be listed first when linking.
|
|
522
|
+
|
|
523
|
+
#### Hooking up interrupts
|
|
524
|
+
|
|
525
|
+
ISR can be written in C using SDCC. However, to hook interrupts is necessary to customize crt0.asm and have the interrupt vectors point to the C functions.
|
|
526
|
+
|
|
527
|
+
#### Reentrancy
|
|
528
|
+
|
|
529
|
+
Due to the very limited stack space, the MOS6502 port by default generates non-reentrant code. Re-entrant functions should be declared using the __reentrant keyword. Alternatively the entire program can be compiled using --stack-auto. On the MOS6502 re-entrant code is, in general, much less efficient.
|
|
530
|
+
|
|
531
|
+
#### Code and Data placement
|
|
532
|
+
|
|
533
|
+
The compiler can pass segment location to the linker. On the MOS6502 the following switches are supported:
|
|
534
|
+
|
|
535
|
+
--code-loc: start address of the code segment
|
|
536
|
+
|
|
537
|
+
--data-loc: start address of the zero page
|
|
538
|
+
|
|
539
|
+
--xram-loc: start address of the data segment
|
|
540
|
+
|
|
541
|
+
### The PIC14 range none pageformat default PIC14 port
|
|
542
|
+
|
|
543
|
+
The PIC14 port adds support for Microchip range none pageformat default Microchip $^{\text{TM}}$ PIC range none pageformat default PIC14 $^{\text{TM}}$ MCUs with 14 bit wide instructions. This port is not yet mature and still lacks many features. However, it can work for simple code.
|
|
544
|
+
|
|
545
|
+
Currently supported devices include:
|
|
546
|
+
|
|
547
|
+
10F320, 10F322, 10LF320, 10LF322
|
|
548
|
+
|
|
549
|
+
12F609, 12F615, 12F617, 12F629, 12F635, 12F675, 12F683
|
|
550
|
+
|
|
551
|
+
12F752
|
|
552
|
+
|
|
553
|
+
12HV752
|
|
554
|
+
|
|
555
|
+
16C62, 16C63A, 16C65B
|
|
556
|
+
|
|
557
|
+
16C71, 16C72, 16C73B, 16C74B
|
|
558
|
+
|
|
559
|
+
16C432, 16C433
|
|
560
|
+
|
|
561
|
+
16C554, 16C557, 16C558
|
|
562
|
+
|
|
563
|
+
16C620, 16C620A, 16C621, 16C621A, 16C622, 16C622A
|
|
564
|
+
|
|
565
|
+
16C710, 16C711, 16C715, 16C717, 16C745, 16C765, 16C770, 16C771, 16C773, 16C774, 16C781, 16C782
|
|
566
|
+
|
|
567
|
+
16C925, 16C926
|
|
568
|
+
|
|
569
|
+
16CR73, 16CR74, 16CR76, 16CR77
|
|
570
|
+
|
|
571
|
+
16CR620A
|
|
572
|
+
|
|
573
|
+
16F72,16F73, 16F74, 16F76, 16F77
|
|
574
|
+
|
|
575
|
+
16F84, 16F84A, 16F87, 16F88
|
|
576
|
+
|
|
577
|
+
16F610, 16F616, 16F627, 16F627A, 16F628, 16F628A, 16F630, 16F631, 16F636, 16F639, 16F648A
|
|
578
|
+
|
|
579
|
+
16F676, 16F677, 16F684, 16F685, 16F687, 16F688, 16F689, 16F690
|
|
580
|
+
|
|
581
|
+
16F707, 16F716, 16F720, 16F721, 16F722, 16F722A, 16F723, 16F723A, 16F724, 16F726, 16F727
|
|
582
|
+
|
|
583
|
+
16F737, 16F747, 16F753, 16F767, 16F777, 16F785
|
|
584
|
+
|
|
585
|
+
16F818, 16F819, 16F870, 16F871, 16F872, 16F873, 16F873A, 16F874, 16F874A, 16F876, 16F876A
|
|
586
|
+
|
|
587
|
+
16F877, 16F877A, 16F882, 16F883, 16F884, 16F886, 16F887
|
|
588
|
+
|
|
589
|
+
16F913, 16F914, 16F916, 16F917, 16F946
|
|
590
|
+
|
|
591
|
+
16LF74, 16LF76, 16LF77
|
|
592
|
+
|
|
593
|
+
16LF84, 16LF84A, 16LF87, 16LF88
|
|
594
|
+
|
|
595
|
+
16LF627, 16LF627A, 16LF628, 16LF628A, 16LF648A
|
|
596
|
+
|
|
597
|
+
16LF707, 16LF720, 16LF721, 16LF722, 16LF722A, 16LF723, 16LF723A, 16LF724, 16LF726, 16LF727
|
|
598
|
+
|
|
599
|
+
16LF747, 16LF767, 16LF777
|
|
600
|
+
|
|
601
|
+
16LF818, 16LF819, 16LF870, 16LF871, 16LF872, 16LF873, 16LF873A, 16LF874, 16LF874A
|
|
602
|
+
|
|
603
|
+
16LF876, 16LF876A, 16LF877, 16LF877A
|
|
604
|
+
|
|
605
|
+
16HV610, 16HV616, 16HV753, 16HV785
|
|
606
|
+
|
|
607
|
+
Supported devices with enhanced cores:
|
|
608
|
+
|
|
609
|
+
12F1501, 12F1571, 12F1572, 12F1612, 12F1822, 12F1840
|
|
610
|
+
|
|
611
|
+
12LF1501, 12LF1552, 12LF1571, 12LF1572, 12LF1612, 12LF1822, 12LF1840, 12LF1840T39A, 12LF1840T48A
|
|
612
|
+
|
|
613
|
+
16F1454, 16F1455, 16F1458, 16F1459
|
|
614
|
+
|
|
615
|
+
16F1503, 16F1507, 16F1508, 16F1509, 16F1512, 16F1513, 16F1516, 16F1517, 16F1518, 16F1519
|
|
616
|
+
|
|
617
|
+
16F1526, 16F1527, 16F1574, 16F1575, 16F1578, 16F1579
|
|
618
|
+
|
|
619
|
+
16F1613, 16F1614, 16F1615, 16F1618, 16F1619
|
|
620
|
+
|
|
621
|
+
16F1703, 16F1704, 16F1705, 16F1707, 16F1708, 16F1709, 16F1713, 16F1716, 16F1717, 16F1718, 16F1719
|
|
622
|
+
|
|
623
|
+
16F1764, 16F1765, 16F1768, 16F1769, 16F1773, 16F1776, 16F1777, 16F1778, 16F1779
|
|
624
|
+
|
|
625
|
+
16F1782, 16F1783, 16F1784, 16F1786, 16F1787, 16F1788, 16F1789
|
|
626
|
+
|
|
627
|
+
16F1823, 16F1824, 16F1825, 16F1826, 16F1827, 16F1828, 16F1829, 16F1829LIN, 16F1847
|
|
628
|
+
|
|
629
|
+
16F1933, 16F1934, 16F1936, 16F1937, 16F1938, 16F1939, 16F1946, 16F1947
|
|
630
|
+
|
|
631
|
+
16F18313, 16F18323, 16F18324, 16F18325, 16F18344, 16F18345,
|
|
632
|
+
|
|
633
|
+
16F18855, 16F18875
|
|
634
|
+
|
|
635
|
+
16LF1454, 16LF1455, 16LF1458, 16LF1459
|
|
636
|
+
|
|
637
|
+
16LF1503, 16LF1507, 16LF1508, 16LF1509, 16LF1512, 16LF1513, 16LF1516, 16LF1517, 16LF1518, 16LF1519,
|
|
638
|
+
|
|
639
|
+
16LF1526, 16LF1527
|
|
640
|
+
|
|
641
|
+
16LF1554, 16LF1559, 16LF1566, 16LF1567, 16LF1574, 16LF1575, 16LF1578, 16LF1579
|
|
642
|
+
|
|
643
|
+
16LF1613, 16LF1614, 16LF1615, 16LF1618, 16LF1619
|
|
644
|
+
|
|
645
|
+
16LF1703, 16LF1704, 16LF1705, 16LF1707, 16LF1708, 16LF1709, 16LF1713, 16LF1716, 16LF1717, 16LF1718, 16LF1719
|
|
646
|
+
|
|
647
|
+
16LF1764, 16LF1765, 16LF1768, 16LF1769, 16LF1773, 16LF1776, 16LF1777, 16LF1778, 16LF1779
|
|
648
|
+
|
|
649
|
+
16LF1782, 16LF1783, 16LF1784, 16LF1786, 16LF1787, 16LF1788, 16LF1789,
|
|
650
|
+
|
|
651
|
+
16LF1823, 16LF1824, 16LF1824T39A
|
|
652
|
+
|
|
653
|
+
16LF1825, 16LF1826, 16LF1827, 16LF1828, 16LF1829, 16LF1847
|
|
654
|
+
|
|
655
|
+
16LF1902, 16LF1903, 16LF1904, 16LF1906, 16LF1907
|
|
656
|
+
|
|
657
|
+
16LF1933, 16LF1934, 16LF1936, 16LF1937, 16LF1938, 16LF1939, 16LF1946, 16LF1947
|
|
658
|
+
|
|
659
|
+
16LF18313, 16LF18323, 16LF18324, 16LF18325, 16LF18344, 16LF18345
|
|
660
|
+
|
|
661
|
+
16LF18855, 16LF18875
|
|
662
|
+
|
|
663
|
+
An up-to-date list of currently supported devices can be obtained via sdcc -mpic14 -phelp foo.c (foo.c must exist...).
|
|
664
|
+
|
|
665
|
+
#### PIC Code Pages range none pageformat default code page (pic14) and Memory Banks range none pageformat default Memory bank (pic14)
|
|
666
|
+
|
|
667
|
+
The linker organizes allocation for the code page and RAM banks. It does not have intimate knowledge of the code flow. It will put all the code section of a single.asm file into a single code page. In order to make use of multiple code pages, separate asm files must be used. The compiler assigns all *static* functions of a single.c file into the same code page.
|
|
668
|
+
|
|
669
|
+
To get the best results, follow these guidelines:
|
|
670
|
+
|
|
671
|
+
1. Make local functions static, as non static functions require code page selection overhead.
|
|
672
|
+
Due to the way SDCC handles functions, place called functions prior to calling functions in the file wherever possible: Otherwise SDCC will insert unnecessary pagesel directives around the call, believing that the called function is externally defined.
|
|
673
|
+
2. For devices that have multiple code pages it is more efficient to use the same number of files as pages: Use up to 4 separate.c files for the 16F877, but only 2 files for the 16F874. This way the linker can put the code for each file into different code pages and there will be less page selection overhead.
|
|
674
|
+
3. And as for any 8 bit micro (especially for PIC14 as they have a very simple instruction set), use `unsigned char' wherever possible instead of `int'.
|
|
675
|
+
|
|
676
|
+
#### Adding New Devices to the Port
|
|
677
|
+
|
|
678
|
+
Adding support for a new 14 bit PIC MCU requires the following steps:
|
|
679
|
+
|
|
680
|
+
1. Create a new device description.
|
|
681
|
+
Each device is described in two files: pic16f*.h and pic16f*.c. These files primarily define SFRs, structs to access their bits, and symbolic configuration options. Both files can be generated from gputils'.inc files using the perl script support/scripts/inc2h.pl. This file also contains further instructions on how to proceed.
|
|
682
|
+
2. Copy the.h file into SDCC's include path and either add the.c file to your project or copy it to device/lib/pic/libdev. Afterwards, rebuild and install the libraries.
|
|
683
|
+
3. Edit pic14devices.txt in SDCC's include path (device/include/pic/ in the source tree or /usr/local/share/sdcc/include/pic after installation).
|
|
684
|
+
You need to add a device specification here to make the memory layout (code banks, RAM, aliased memory regions,...) known to the compiler. Probably you can copy and modify an existing entry. The file format is documented at the top of the file.
|
|
685
|
+
|
|
686
|
+
#### Interrupt Code
|
|
687
|
+
|
|
688
|
+
For the interrupt function, use the keyword *__interrupt* range none pageformat default PIC14!interrupt with level number of 0 (PIC14 only has 1 interrupt so this number is only there to avoid a syntax error - it ought to be fixed). E.g.:
|
|
689
|
+
```c
|
|
690
|
+
void Intr(void) __interrupt (0)
|
|
691
|
+
{
|
|
692
|
+
T0IF = 0; /* Clear timer interrupt */
|
|
693
|
+
}
|
|
694
|
+
```
|
|
695
|
+
#### Configuration Bits
|
|
696
|
+
|
|
697
|
+
Configuration bits (also known as fuses) can be configured using ` __code ' and ` __at ' modifiers. Possible options should be ANDed and can be found in your processor header file. Example for PIC16F88:
|
|
698
|
+
```c
|
|
699
|
+
#include <pic16f88.h> //Contains config addresses and options
|
|
700
|
+
#include <stdint.h> //Needed for uint16_t
|
|
701
|
+
|
|
702
|
+
static __code uint16_t __at (_CONFIG1) configword1 = _INTRC_IO &
|
|
703
|
+
_CP_ALL & _WDT_OFF & [...];
|
|
704
|
+
static __code uint16_t __at (_CONFIG2) configword2 = [...];
|
|
705
|
+
```
|
|
706
|
+
Although data type is ignored if the address (__at()) refers to a config word location, using a type large enough for the configuration word (uint16_t in this case) is recommended to prevent changes in the compiler (implicit, early range check and enforcement) from breaking the definition.
|
|
707
|
+
|
|
708
|
+
If your processor header file doesn't contain config addresses you can declare it manually or use a literal address:
|
|
709
|
+
```c
|
|
710
|
+
static __code uint16_t __at (0x2007) configword1 = _INTRC_IO &
|
|
711
|
+
_CP_ALL & _WDT_OFF & [...];
|
|
712
|
+
```
|
|
713
|
+
#### Linking and Assembling
|
|
714
|
+
|
|
715
|
+
For assembling you can use either GPUTILS' range none pageformat default gputils (pic tools) gpasm.exe or MPLAB's mpasmwin.exe. GPUTILS are available from http://sourceforge.net/projects/gputils. For linking you can use either GPUTILS' gplink or MPLAB's mplink.exe. If you use MPLAB and an interrupt function then the linker script file vectors section will need to be enlarged to link with mplink.
|
|
716
|
+
|
|
717
|
+
Pic device specific header and c source files are automatically generated from MPLAB include files, which are published by Microchip with a special requirement that they are only to be used with authentic Microchip devices. This reqirement prevents to publish generated header and c source files under the GPL compatible license, so they are located in non-free directory (see section Search Paths). In order to include them in include and library search paths, the **--use-non-free range none pageformat default --use-non-free** command line option should be defined.
|
|
718
|
+
|
|
719
|
+
NOTE: the compiled code, which use non-free pic device specific libraries, is not GPL compatible!
|
|
720
|
+
|
|
721
|
+
Here is a Makefile using GPUTILS:
|
|
722
|
+
|
|
723
|
+
.c.o:
|
|
724
|
+
sdcc -V --use-non-free -mpic14 -p16f877 -c $<
|
|
725
|
+
|
|
726
|
+
$(PRJ).hex: $(OBJS)
|
|
727
|
+
gplink -m -s $(PRJ).lkr -o $(PRJ).hex $(OBJS) libsdcc.lib
|
|
728
|
+
|
|
729
|
+
Here is a Makefile using MPLAB:
|
|
730
|
+
|
|
731
|
+
.c.o:
|
|
732
|
+
sdcc -S -V --use-non-free -mpic14 -p16f877 $<
|
|
733
|
+
mpasmwin /q /o $*.asm
|
|
734
|
+
|
|
735
|
+
$(PRJ).hex: $(OBJS)
|
|
736
|
+
mplink /v $(PRJ).lkr /m $(PRJ).map /o $(PRJ).hex $(OBJS) libsdcc.lib
|
|
737
|
+
|
|
738
|
+
Please note that indentations within a Makefile have to be done with a tabulator character.
|
|
739
|
+
|
|
740
|
+
#### Command-Line Options
|
|
741
|
+
|
|
742
|
+
Besides the switches common to all SDCC backends, the PIC14 port accepts the following options (for an updated list see sdcc --help):
|
|
743
|
+
|
|
744
|
+
--debug-xtra range none pageformat default PIC14!Options!--debug-extra emit debug info in assembly output
|
|
745
|
+
|
|
746
|
+
--no-pcode-opt range none pageformat default PIC14!Options!--no-pcode-opt disable (slightly faulty) optimization on pCode
|
|
747
|
+
|
|
748
|
+
--stack-loc range none pageformat default PIC14!Options!--stack-loc sets the lowest address of the argument passing stack (defaults to a suitably large shared databank to reduce BANKSEL overhead)
|
|
749
|
+
|
|
750
|
+
--stack-size range none pageformat default PIC14!Options!--stack-size sets the size if the argument passing stack (default: 16, minimum: 4)
|
|
751
|
+
|
|
752
|
+
--use-non-free range none pageformat default PIC14!Options!--use-non-free make non-free device headers and libraries available in the compiler's search paths (implicit -I and -L options)
|
|
753
|
+
|
|
754
|
+
--no-extended-instructions forbid use of the extended instruction set (e.g., ADDFSR)
|
|
755
|
+
|
|
756
|
+
#### Environment Variables
|
|
757
|
+
|
|
758
|
+
The PIC14 port recognizes the following environment variables:
|
|
759
|
+
|
|
760
|
+
SDCC_PIC14_SPLIT_LOCALS range none pageformat default PIC14!Environment variables!SDCC PIC14 SPLIT LOCALS range none pageformat default SDCC!Environment variables!SDCC PIC14 SPLIT LOCALS If set and not empty, sdcc will allocate each temporary register (the ones called r0xNNNN) in a section of its own. By default (if this variable is unset), sdcc tries to cluster registers in sections in order to reduce the BANKSEL overhead when accessing them.
|
|
761
|
+
|
|
762
|
+
#### The Library
|
|
763
|
+
|
|
764
|
+
The PIC14 library currently only contains support routines required by the compiler to implement multiplication, division, and floating point support. No libc-like replacement is available at the moment, though many of the common sdcc library sources (in device/lib) should also compile with the PIC14 port.
|
|
765
|
+
|
|
766
|
+
##### Enhanced cores
|
|
767
|
+
|
|
768
|
+
SDCC/PIC14 has experimental support for devices with the enhanced 14-bit cores (such as pic12f1822). Due to differences in required code, the libraries provided with SDCC (libm.lib and libsdcc.lib) are now provided in two variants: libm.lib and libsdcc.lib are compiled for the regular, non-enhanced devices. libme.lib and libsdcce.lib (note the trailing ' e ') are compiled for enhanced devices. When linking manually, make sure to select the proper variant!
|
|
769
|
+
|
|
770
|
+
When SDCC is used to invoke the linker, SDCC will automatically select the libsdcc.lib-variant suitable for the target device. However, no such magic has been conjured up for libm.lib!
|
|
771
|
+
|
|
772
|
+
##### Accessing bits of special function registers
|
|
773
|
+
|
|
774
|
+
Individual bits within SFRs can be accessed either using or using a shorthand, which is defined in the respective device header for all s. In order to avoid polluting the global namespace with the names of all the bits, you can #define NO_BIT_DEFINES before inclusion of the device header file.
|
|
775
|
+
|
|
776
|
+
##### Naming of special function registers
|
|
777
|
+
|
|
778
|
+
If NO_BIT_DEFINES is used, individual bits of the SFRs can be accessed as. With the 3.1.0 release, the previously used (note the underscore) is deprecated. This was done to align the naming conventions with the PIC16 port and competing compiler vendors. To avoid polluting the global namespace with the legacy names, you can prevent their definition using #define NO_LEGACY_NAMES prior to the inclusion of the device header.
|
|
779
|
+
|
|
780
|
+
You **must** also #define NO_BIT_DEFINES in order to access SFRs as, otherwise will expand to, yielding the undefined expression.
|
|
781
|
+
|
|
782
|
+
##### error: missing definition for symbol ``__gptrget1''
|
|
783
|
+
|
|
784
|
+
The PIC14 port uses library routines to provide more complex operations like multiplication, division/modulus and (generic) pointer dereferencing. In order to add these routines to your project, you must link with PIC14's libsdcc.lib. For single source file projects this is done automatically, more complex projects must add libsdcc.lib to the linker's arguments. Make sure you also add an include path for the library (using the -I switch to the linker)!
|
|
785
|
+
|
|
786
|
+
##### Processor mismatch in file ``XXX''.
|
|
787
|
+
|
|
788
|
+
This warning can usually be ignored due to the very good compatibility amongst 14 bit PIC range none pageformat default PIC14 devices.
|
|
789
|
+
|
|
790
|
+
You might also consider recompiling the library for your specific device by changing the ARCH=p16f877 (default target) entry in device/lib/pic/Makefile.in and device/lib/pic/Makefile to reflect your device. This might even improve performance for smaller devices as unnecessary BANKSELs might be removed.
|
|
791
|
+
|
|
792
|
+
#### Known Bugs
|
|
793
|
+
|
|
794
|
+
##### Function arguments
|
|
795
|
+
|
|
796
|
+
Functions with variable argument lists (like printf) are not yet supported. Similarly, taking the address of the first argument passed into a function does not work: It is currently passed in WREG and has no address...
|
|
797
|
+
|
|
798
|
+
##### Regression tests fail
|
|
799
|
+
|
|
800
|
+
Though the small subset of regression tests in src/regression passes, SDCC regression test suite does not, indicating that there are still major bugs in the port. However, many smaller projects have successfully used SDCC in the past...
|
|
801
|
+
|
|
802
|
+
### The PIC16 range none pageformat default PIC16 port
|
|
803
|
+
|
|
804
|
+
The PIC16 port adds support for Microchip range none pageformat default Microchip $^{\text{TM}}$ PIC range none pageformat default PIC $^{\text{TM}}$ MCUs with 16 bit wide instructions. This port is not yet mature and still lacks many features. However, it can work for simple code. Currently this family of microcontrollers contains the PIC18Fxxx and PIC18Fxxxx; devices supported by the port include:
|
|
805
|
+
|
|
806
|
+
18F13K22 18F13K50
|
|
807
|
+
|
|
808
|
+
18F14K22 18F14K50
|
|
809
|
+
|
|
810
|
+
18F23K20 18F23K22
|
|
811
|
+
|
|
812
|
+
18F24J10 18F24J11 18F24J50 18F24K20 18F24K22 18F24K50
|
|
813
|
+
|
|
814
|
+
18F25J10 18F25J11 18F25J50 18F25K20 18F25K22 18F25K50 18F25K80
|
|
815
|
+
|
|
816
|
+
18F26J11 18F26J13 18F26J50 18F26J53 18F26K20 18F26K22 18F26K80
|
|
817
|
+
|
|
818
|
+
18F27J13 18F27J53
|
|
819
|
+
|
|
820
|
+
18F43K20 18F43K22
|
|
821
|
+
|
|
822
|
+
18F44J10 18F44J11 18F44J50 18F44K20 18F44K22
|
|
823
|
+
|
|
824
|
+
18F45J10 18F45J11 18F45J50 18F45K20 18F45K22 18F45K50 18F45K80
|
|
825
|
+
|
|
826
|
+
18F46J11 18F46J13 18F46J50 18F46J53 18F46K20 18F46K22 18F46K80
|
|
827
|
+
|
|
828
|
+
18F47J13 18F47J53
|
|
829
|
+
|
|
830
|
+
18F63J11 18F63J90
|
|
831
|
+
|
|
832
|
+
18F64J11 18F64J90
|
|
833
|
+
|
|
834
|
+
18F65J10 18F65J11 18F65J15 18F65J50 18F65J90 18F65J94 18F65K22 18F65K80 18F65K90
|
|
835
|
+
|
|
836
|
+
18F66J10 18F66J11 18F66J15 18F66J16 18F66J50 18F66J55 18F66J60 18F66J65
|
|
837
|
+
|
|
838
|
+
18F66J90 18F66J93 18F66J94 18F66J99 18F66K22 18F66K80 18F66K90
|
|
839
|
+
|
|
840
|
+
18F67J10 18F67J11 18F67J50 18F67J60 18F67J90 18F67J93 18F67J94 18F67K22 18F67K90
|
|
841
|
+
|
|
842
|
+
18F83J11 18F83J90
|
|
843
|
+
|
|
844
|
+
18F84J11 18F84J90
|
|
845
|
+
|
|
846
|
+
18F85J10 18F85J11 18F85J15 18F85J50 18F85J90 18F85J94 18F85K22 18F85K90
|
|
847
|
+
|
|
848
|
+
18F86J10 18F86J11 18F86J15 18F86J16 18F86J50 18F86J55 18F86J60 18F86J65
|
|
849
|
+
|
|
850
|
+
18F86J72 18F86J90 18F86J93 18F86J94 18F86J99 18F86K22 18F86K90
|
|
851
|
+
|
|
852
|
+
18F87J10 18F87J11 18F87J50 18F87J60 18F87J72 18F87J90 18F87J93 18F87J94 18F87K22 18F87K90
|
|
853
|
+
|
|
854
|
+
18F95J94 18F96J60 18F96J65 18F96J94 18F96J99
|
|
855
|
+
|
|
856
|
+
18F97J60 18F97J94
|
|
857
|
+
|
|
858
|
+
18F242 18F248 18F252 18F258
|
|
859
|
+
|
|
860
|
+
18F442 18F448 18F452 18F458
|
|
861
|
+
|
|
862
|
+
18F1220 18F1230
|
|
863
|
+
|
|
864
|
+
18F1320 18F1330
|
|
865
|
+
|
|
866
|
+
18F2220 18F2221
|
|
867
|
+
|
|
868
|
+
18F2320 18F2321 18F2331
|
|
869
|
+
|
|
870
|
+
18F2410 18F2420 18F2423 18F2431 18F2439 18F2450 18F2455 18F2458 18F2480
|
|
871
|
+
|
|
872
|
+
18F2510 18F2515 18F2520 18F2523 18F2525 18F2539 18F2550 18F2553 18F2580 18F2585
|
|
873
|
+
|
|
874
|
+
18F2610 18F2620 18F2680 18F2682 18F2685
|
|
875
|
+
|
|
876
|
+
18F4220 18F4221
|
|
877
|
+
|
|
878
|
+
18F4320 18F4321 18F4331
|
|
879
|
+
|
|
880
|
+
18F4410 18F4420 18F4423 18F4431 18F4439 18F4450 18F4455 18F4458 18F4480
|
|
881
|
+
|
|
882
|
+
18F4510 18F4515 18F4520 18F4523 18F4525 18F4539 18F4550 18F4553 18F4580 18F4585
|
|
883
|
+
|
|
884
|
+
18F4610 18F4620 18F4680 18F4682 18F4685
|
|
885
|
+
|
|
886
|
+
18F6310 18F6390 18F6393
|
|
887
|
+
|
|
888
|
+
18F6410 18F6490 18F6493
|
|
889
|
+
|
|
890
|
+
18F6520 18F6525 18F6527 18F6585
|
|
891
|
+
|
|
892
|
+
18F6620 18F6621 18F6622 18F6627 18F6628 18F6680
|
|
893
|
+
|
|
894
|
+
18F6720 18F6722 18F6723
|
|
895
|
+
|
|
896
|
+
18F8310 18F8390 18F8393
|
|
897
|
+
|
|
898
|
+
18F8410 18F8490 18F8493
|
|
899
|
+
|
|
900
|
+
18F8520 18F8525 18F8527 18F8585
|
|
901
|
+
|
|
902
|
+
18F8620 18F8621 18F8622 18F8627 18F8628 18F8680
|
|
903
|
+
|
|
904
|
+
18F8720 18F8722 18F8723
|
|
905
|
+
|
|
906
|
+
18LF13K22 18LF13K50
|
|
907
|
+
|
|
908
|
+
18LF14K22 18LF14K50
|
|
909
|
+
|
|
910
|
+
18LF23K22 18LF24J10 18LF24J11 18LF24J50 18LF24K22 18LF24K50
|
|
911
|
+
|
|
912
|
+
18LF25J10 18LF25J11 18LF25J50 18LF25K22 18LF25K50 18LF25K80
|
|
913
|
+
|
|
914
|
+
18LF26J11 18LF26J13 18LF26J50 18LF26J53 18LF26K22 18LF26K80
|
|
915
|
+
|
|
916
|
+
18LF27J13 18LF27J53
|
|
917
|
+
|
|
918
|
+
18LF43K22
|
|
919
|
+
|
|
920
|
+
18LF44J10 18LF44J11 18LF44J50 18LF44K22
|
|
921
|
+
|
|
922
|
+
18LF45J10 18LF45J11 18LF45J50 18LF45K22 18LF45K50 18LF45K80
|
|
923
|
+
|
|
924
|
+
18LF46J11 18LF46J13 18LF46J50 18LF46J53 18LF46K22 18LF46K80
|
|
925
|
+
|
|
926
|
+
18LF47J13 18LF47J53
|
|
927
|
+
|
|
928
|
+
18LF65K80
|
|
929
|
+
|
|
930
|
+
18LF66K80
|
|
931
|
+
|
|
932
|
+
18LF242 18LF248 18LF252 18LF258
|
|
933
|
+
|
|
934
|
+
18LF442 18LF448 18LF452 18LF458
|
|
935
|
+
|
|
936
|
+
18LF1220 18LF1230
|
|
937
|
+
|
|
938
|
+
18LF1320 18LF1330
|
|
939
|
+
|
|
940
|
+
18LF2220 18LF2221
|
|
941
|
+
|
|
942
|
+
18LF2320 18LF2321 18LF2331
|
|
943
|
+
|
|
944
|
+
18LF2410 18LF2420 18LF2423 18LF2431 18LF2439 18LF2450 18LF2455 18LF2458 18LF2480
|
|
945
|
+
|
|
946
|
+
18LF2510 18LF2515 18LF2520 18LF2523 18LF2525 18LF2539 18LF2550 18LF2553 18LF2580 18LF2585
|
|
947
|
+
|
|
948
|
+
18LF2610 18LF2620 18LF2680 18LF2682 18LF2685
|
|
949
|
+
|
|
950
|
+
18LF4220 18LF4221
|
|
951
|
+
|
|
952
|
+
18LF4320 18LF4321 18LF4331
|
|
953
|
+
|
|
954
|
+
18LF4410 18LF4420 18LF4423 18LF4431 18LF4439 18LF4450 18LF4455 18LF4458 18LF4480
|
|
955
|
+
|
|
956
|
+
18LF4510 18LF4515 18LF4520 18LF4523 18LF4525 18LF4539 18LF4550 18LF4553 18LF4580 18LF4585
|
|
957
|
+
|
|
958
|
+
18LF4610 18LF4620 18LF4680 18LF4682 18LF4685
|
|
959
|
+
|
|
960
|
+
18LF6310 18LF6390 18LF6393
|
|
961
|
+
|
|
962
|
+
18LF6410 18LF6490 18LF6493
|
|
963
|
+
|
|
964
|
+
18LF6520 18LF6525 18LF6527 18LF6585
|
|
965
|
+
|
|
966
|
+
18LF6620 18LF6621 18LF6622 18LF6627 18LF6628 18LF6680
|
|
967
|
+
|
|
968
|
+
18LF6720 18LF6722 18LF6723
|
|
969
|
+
|
|
970
|
+
18LF8310 18LF8390 18LF8393
|
|
971
|
+
|
|
972
|
+
18LF8410 18LF8490 18LF8493
|
|
973
|
+
|
|
974
|
+
18LF8520 18LF8525 18LF8527 18LF8585
|
|
975
|
+
|
|
976
|
+
18LF8620 18LF8621 18LF8622 18LF8627 18LF8628 18LF8680
|
|
977
|
+
|
|
978
|
+
18LF8720 18LF8722 18LF8723
|
|
979
|
+
|
|
980
|
+
An up-to-date list of supported devices is also available via ' sdcc -mpic16 -plist '.
|
|
981
|
+
|
|
982
|
+
#### Global Options
|
|
983
|
+
|
|
984
|
+
PIC16 port supports the standard command line arguments as supposed, with the exception of certain cases that will be mentioned in the following list:
|
|
985
|
+
|
|
986
|
+
--callee-saves range none pageformat default PIC16!Options!--callee-saves See --all-callee-saves
|
|
987
|
+
|
|
988
|
+
--use-non-free range none pageformat default PIC16!Options!--use-non-free Make non-free device headers and libraries available in the compiler's search paths (implicit -I and -L options).
|
|
989
|
+
|
|
990
|
+
#### Port Specific Options range none pageformat default Options PIC16
|
|
991
|
+
|
|
992
|
+
The port specific options appear after the global options in the sdcc --help output.
|
|
993
|
+
|
|
994
|
+
##### Code Generation Options
|
|
995
|
+
|
|
996
|
+
These options influence the generated assembler code.
|
|
997
|
+
|
|
998
|
+
--pstack-model=[model] Used in conjunction with the command above. Defines the stack model to be used, valid stack models are:
|
|
999
|
+
|
|
1000
|
+
*small* Selects small stack model. 8 bit stack and frame pointers. Supports 256 bytes stack size.
|
|
1001
|
+
|
|
1002
|
+
*large* Selects large stack model. 16 bit stack and frame pointers. Supports 65536 bytes stack size.
|
|
1003
|
+
|
|
1004
|
+
--pno-banksel Do not generate BANKSEL assembler directives.
|
|
1005
|
+
|
|
1006
|
+
--extended Enable extended instruction set/literal offset addressing mode. Use with care!
|
|
1007
|
+
|
|
1008
|
+
##### Optimization Options
|
|
1009
|
+
|
|
1010
|
+
--obanksel=n Set optimization level for inserting BANKSELs.
|
|
1011
|
+
|
|
1012
|
+
0 no optimization
|
|
1013
|
+
|
|
1014
|
+
1 checks previous used register and if it is the same then does not emit BANKSEL, accounts only for labels.
|
|
1015
|
+
|
|
1016
|
+
2 tries to check the location of (even different) symbols and removes BANKSELs if they are in the same bank.
|
|
1017
|
+
*Important: There might be problems if the linker script has data sections across bank borders!
|
|
1018
|
+
|
|
1019
|
+
--denable-peeps Force the usage of peepholes. Use with care.
|
|
1020
|
+
|
|
1021
|
+
--no-optimize-goto Do not use (conditional) BRA instead of GOTO.
|
|
1022
|
+
|
|
1023
|
+
--optimize-cmp Try to optimize some compares.
|
|
1024
|
+
|
|
1025
|
+
--optimize-df Analyze the dataflow of the generated code and improve it.
|
|
1026
|
+
|
|
1027
|
+
##### Assembling Options
|
|
1028
|
+
|
|
1029
|
+
--asm= Sets the full path and name of an external assembler to call.
|
|
1030
|
+
|
|
1031
|
+
--mplab-comp MPLAB range none pageformat default PIC16!MPLAB compatibility option. Currently only suppresses special gpasm directives.
|
|
1032
|
+
|
|
1033
|
+
##### Linking Options
|
|
1034
|
+
|
|
1035
|
+
--link= Sets the full path and name of an external linker to call.
|
|
1036
|
+
|
|
1037
|
+
--preplace-udata-with=[kword] Replaces the default udata keyword for allocating unitialized data variables with [kword]. Valid keywords are: "udata_acs", "udata_shr", "udata_ovr".
|
|
1038
|
+
|
|
1039
|
+
--ivt-loc=n Place the interrupt vector table at address *n*. Useful for bootloaders.
|
|
1040
|
+
|
|
1041
|
+
--nodefaultlibs Do not link default libraries when linking.
|
|
1042
|
+
|
|
1043
|
+
--use-crt= Use a custom run-time module instead of the default (crt0i).
|
|
1044
|
+
|
|
1045
|
+
--no-crt Don't link the default run-time modules
|
|
1046
|
+
|
|
1047
|
+
##### Debugging Options
|
|
1048
|
+
|
|
1049
|
+
Debugging options enable extra debugging information in the output files.
|
|
1050
|
+
|
|
1051
|
+
--debug-xtra Similar to --debug range none pageformat default --debug, but dumps more information.
|
|
1052
|
+
|
|
1053
|
+
--debug-ralloc Force register allocator to dump <source>.d file with debugging information.
|
|
1054
|
+
|
|
1055
|
+
--pcode-verbose Enable pcode debugging information in translation.
|
|
1056
|
+
|
|
1057
|
+
--calltree Dump call tree in.calltree file.
|
|
1058
|
+
|
|
1059
|
+
--gstack Trace push/pops for stack pointer overflow.
|
|
1060
|
+
|
|
1061
|
+
#### Environment Variables
|
|
1062
|
+
|
|
1063
|
+
There is a number of environmental variables that can be used when running SDCC to enable certain optimizations or force a specific program behaviour. these variables are primarily for debugging purposes so they can be enabled/disabled at will.
|
|
1064
|
+
|
|
1065
|
+
Currently there is only two such variables available:
|
|
1066
|
+
|
|
1067
|
+
OPTIMIZE_BITFIELD_POINTER_GET range none pageformat default PIC16!Environment variables!OPTIMIZE BITFIELD POINTER GET range none pageformat default SDCC!Environment variables!OPTIMIZE BITFIELD POINTER GET (PIC16) When this variable exists, reading of structure bit-fields is optimized by directly loading FSR0 with the address of the bit-field structure. Normally SDCC will cast the bit-field structure to a bit-field pointer and then load FSR0. This step saves data ram and code space for functions that make heavy use of bit-fields. (i.e., 80 bytes of code space are saved when compiling malloc.c with this option).
|
|
1068
|
+
|
|
1069
|
+
NO_REG_OPT range none pageformat default PIC16!Environment variables!NO REG OPT range none pageformat default SDCC!Environment variables!NO REG OPT Do not perform pCode registers optimization. This should be used for debugging purposes. If bugs in the pcode optimizer are found, users can benefit from temporarily disabling the optimizer until the bug is fixed.
|
|
1070
|
+
|
|
1071
|
+
#### Preprocessor Macros range none pageformat default Preprocessor!PIC16 Macros
|
|
1072
|
+
|
|
1073
|
+
PIC16 range none pageformat default PIC16 port defines the following preprocessor macros while translating a source.
|
|
1074
|
+
|
|
1075
|
+
| Macro | Description |
|
|
1076
|
+
| --- | --- |
|
|
1077
|
+
| __SDCC_pic16 range none pageformat default status collapsed SDCC!Defines!__SDCC pic16 | Port identification |
|
|
1078
|
+
| pic18fxxxx range none pageformat default status collapsed PIC16!Defines!pic18fxxxx | MCU Identification. xxxx is the microcontrol identification number, i.e. 452, 6620, etc |
|
|
1079
|
+
| _ _18Fxxxx range none pageformat default status collapsed PIC16!Defines! pic18fxxxx | MCU Identification (same as above) |
|
|
1080
|
+
| STACK_MODEL_nnn range none pageformat default status collapsed PIC16!Defines!STACK MODEL nnn | nnn = SMALL or LARGE respectively according to the stack model used |
|
|
1081
|
+
| STACK_MODEL_nnn range none pageformat default status collapsed PIC16!Defines!STACK MODEL nnn | nnn = SMALL or LARGE respectively according to the stack model used |
|
|
1082
|
+
|
|
1083
|
+
In addition the following macros are defined when calling assembler:
|
|
1084
|
+
|
|
1085
|
+
| Macro | Description |
|
|
1086
|
+
| --- | --- |
|
|
1087
|
+
| __18Fxxxx | MCU Identification. xxxx is the microcontrol identification number, i.e. 452, 6620, etc |
|
|
1088
|
+
| __SDCC_MODEL_nnn | nnn = SMALL or LARGE respectively according to the memory model used for SDCC |
|
|
1089
|
+
| STACK_MODEL_nnn | nnn = SMALL or LARGE respectively according to the stack model used |
|
|
1090
|
+
| STACK_MODEL_nnn | nnn = SMALL or LARGE respectively according to the stack model used |
|
|
1091
|
+
|
|
1092
|
+
#### Directories
|
|
1093
|
+
|
|
1094
|
+
PIC16 range none pageformat default PIC16 port uses the following directories for searching header files and libraries.
|
|
1095
|
+
|
|
1096
|
+
| Directory | Description | Target | Command prefix |
|
|
1097
|
+
| --- | --- | --- | --- |
|
|
1098
|
+
| PREFIX/sdcc/include/pic16 | PIC16 specific headers | Compiler | -I |
|
|
1099
|
+
| PREFIX/sdcc/lib/pic16 | PIC16 specific libraries | Linker | -L |
|
|
1100
|
+
| PREFIX/sdcc/lib/pic16 | PIC16 specific libraries | Linker | -L |
|
|
1101
|
+
|
|
1102
|
+
If the **--use-non-free range none pageformat default --use-non-free** command line option is specified, non-free directories are searched:
|
|
1103
|
+
|
|
1104
|
+
| Directory | Description | Target | Command prefix |
|
|
1105
|
+
| --- | --- | --- | --- |
|
|
1106
|
+
| PREFIX/sdcc/non-free/include/pic16 | PIC16 specific non-free headers | Compiler | -I |
|
|
1107
|
+
| PREFIX/sdcc/non-free/lib/pic16 | PIC16 specific non-free libraries | Linker | -L |
|
|
1108
|
+
| PREFIX/sdcc/non-free/lib/pic16 | PIC16 specific non-free libraries | Linker | -L |
|
|
1109
|
+
|
|
1110
|
+
#### Pragmas
|
|
1111
|
+
|
|
1112
|
+
The PIC16 range none pageformat default PIC16 port currently supports the following pragmas:
|
|
1113
|
+
|
|
1114
|
+
stack range none pageformat default PIC16!Pragmas! pragma stack This forces the code generator to initialize the stack & frame pointers at a specific address. This is an ad hoc solution for cases where no STACK directive is available in the linker script or gplink is not instructed to create a stack section.
|
|
1115
|
+
The stack pragma should be used only once in a project. Multiple pragmas may result in indeterminate behaviour of the program. The old format (ie. #pragma stack 0x5ff) is deprecated and will cause the stack pointer to cross page boundaries (or even exceed the available data RAM) and crash the program. Make sure that stack does not cross page boundaries when using the SMALL stack model.
|
|
1116
|
+
The format is as follows:
|
|
1117
|
+
|
|
1118
|
+
#pragma stack bottom_address [stack_size]
|
|
1119
|
+
|
|
1120
|
+
*bottom_address* is the lower bound of the stack section. The stack pointer initially will point at address (bottom_address+stack_size-1).
|
|
1121
|
+
|
|
1122
|
+
Example:
|
|
1123
|
+
|
|
1124
|
+
/* initializes stack of 100 bytes at RAM address 0x200 */
|
|
1125
|
+
|
|
1126
|
+
#pragma stack 0x200 100
|
|
1127
|
+
|
|
1128
|
+
If the stack_size field is omitted then a stack is created with the default size of 64. This size might be enough for most programs, but its not enough for operations with deep function nesting or excessive stack usage.
|
|
1129
|
+
|
|
1130
|
+
code range none pageformat default PIC16!Pragmas! pragma code Force a function to a static FLASH address.
|
|
1131
|
+
|
|
1132
|
+
Example:
|
|
1133
|
+
|
|
1134
|
+
/* place function test_func at 0x4000 */
|
|
1135
|
+
|
|
1136
|
+
#pragma code test_func 0x4000
|
|
1137
|
+
|
|
1138
|
+
library range none pageformat default PIC16!Pragmas! pragma library instructs the linker to use a library module.
|
|
1139
|
+
Usage:
|
|
1140
|
+
|
|
1141
|
+
#pragma library module_name
|
|
1142
|
+
|
|
1143
|
+
*module_name* can be any library or object file (including its path). Note that there are four reserved keywords which have special meaning. These are:
|
|
1144
|
+
|
|
1145
|
+
| Keyword | Description | Module to link |
|
|
1146
|
+
| --- | --- | --- |
|
|
1147
|
+
| ignore | ignore all library pragmas | (none) |
|
|
1148
|
+
| c | link the C library | libc18f.lib |
|
|
1149
|
+
| math | link the Math libarary | libm18f.lib |
|
|
1150
|
+
| io | link the I/O library | libio18f*.lib |
|
|
1151
|
+
| debug | link the debug library | libdebug.lib |
|
|
1152
|
+
| debug | link the debug library | libdebug.lib |
|
|
1153
|
+
|
|
1154
|
+
* is the device number, i.e. 452 for PIC18F452 MCU.
|
|
1155
|
+
|
|
1156
|
+
This feature allows for linking with specific libraries without having to explicit name them in the command line. Note that the ignore keyword will reject all modules specified by the library pragma.
|
|
1157
|
+
|
|
1158
|
+
udata range none pageformat default PIC16!Pragmas! pragma udata The pragma udata instructs the compiler to emit code so that linker will place a variable at a specific memory bank.
|
|
1159
|
+
|
|
1160
|
+
Example:
|
|
1161
|
+
|
|
1162
|
+
/* places variable foo at bank2 */
|
|
1163
|
+
|
|
1164
|
+
#pragma udata bank2 foo
|
|
1165
|
+
|
|
1166
|
+
char foo;
|
|
1167
|
+
|
|
1168
|
+
In order for this pragma to work extra SECTION directives should be added in the.lkr script. In the following example a sample.lkr file is shown:
|
|
1169
|
+
|
|
1170
|
+
// Sample linker script for the PIC18F452 processor
|
|
1171
|
+
|
|
1172
|
+
LIBPATH.
|
|
1173
|
+
|
|
1174
|
+
CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED
|
|
1175
|
+
|
|
1176
|
+
CODEPAGE NAME=page START=0x2A END=0x7FFF
|
|
1177
|
+
|
|
1178
|
+
CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED
|
|
1179
|
+
|
|
1180
|
+
CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED
|
|
1181
|
+
|
|
1182
|
+
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
|
|
1183
|
+
|
|
1184
|
+
CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED
|
|
1185
|
+
|
|
1186
|
+
ACCESSBANK NAME=accessram START=0x0 END=0x7F
|
|
1187
|
+
|
|
1188
|
+
DATABANK NAME=gpr0 START=0x80 END=0xFF
|
|
1189
|
+
|
|
1190
|
+
DATABANK NAME=gpr1 START=0x100 END=0x1FF
|
|
1191
|
+
|
|
1192
|
+
DATABANK NAME=gpr2 START=0x200 END=0x2FF
|
|
1193
|
+
|
|
1194
|
+
DATABANK NAME=gpr3 START=0x300 END=0x3FF
|
|
1195
|
+
|
|
1196
|
+
DATABANK NAME=gpr4 START=0x400 END=0x4FF
|
|
1197
|
+
|
|
1198
|
+
DATABANK NAME=gpr5 START=0x500 END=0x5FF
|
|
1199
|
+
|
|
1200
|
+
ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED
|
|
1201
|
+
|
|
1202
|
+
SECTION NAME=CONFIG ROM=config
|
|
1203
|
+
|
|
1204
|
+
SECTION NAME=bank0 RAM=gpr0 # these SECTION directives
|
|
1205
|
+
|
|
1206
|
+
SECTION NAME=bank1 RAM=gpr1 # should be added to link
|
|
1207
|
+
|
|
1208
|
+
SECTION NAME=bank2 RAM=gpr2 # section name 'bank?' with
|
|
1209
|
+
|
|
1210
|
+
SECTION NAME=bank3 RAM=gpr3 # a specific DATABANK name
|
|
1211
|
+
|
|
1212
|
+
SECTION NAME=bank4 RAM=gpr4
|
|
1213
|
+
|
|
1214
|
+
SECTION NAME=bank5 RAM=gpr5
|
|
1215
|
+
|
|
1216
|
+
The linker will recognise the section name set in the pragma statement and will position the variable at the memory bank set with the RAM field at the SECTION line in the linker script file.
|
|
1217
|
+
|
|
1218
|
+
config range none pageformat default PIC16!Pragmas! pragma config The pragma config instructs the compiler to emit config directive.
|
|
1219
|
+
The format is as follows:
|
|
1220
|
+
|
|
1221
|
+
#pragma config setting=value [, setting=value]
|
|
1222
|
+
|
|
1223
|
+
Multiple settings may be defined on a single line, separated by commas. Settings for a single configuration byte may also be defined on separate lines.
|
|
1224
|
+
|
|
1225
|
+
Example:
|
|
1226
|
+
|
|
1227
|
+
#pragma config CP0=OFF,OSCS=ON,OSC=LP,BOR=ON,BORV=25,WDT=ON,WDTPS=128,CCP2MUX=ON
|
|
1228
|
+
|
|
1229
|
+
#pragma config STVR=ON
|
|
1230
|
+
|
|
1231
|
+
#### Header Files and Libraries
|
|
1232
|
+
|
|
1233
|
+
Pic device specific header and c source files are automatically generated from MPLAB include files, which are published by Microchip with a special requirement that they are only to be used with authentic Microchip devices. This requirement prevents to publish generated header and c source files under the GPL compatible license, so they are located in the non-free directory (see section Search Paths). In order to include them in include and library search paths, the **--use-non-free range none pageformat default --use-non-free** command line option should be defined.
|
|
1234
|
+
|
|
1235
|
+
NOTE: the compiled code, which use non-free pic device specific libraries, is not GPL compatible!
|
|
1236
|
+
|
|
1237
|
+
#### Header Files
|
|
1238
|
+
|
|
1239
|
+
There is one main header file range none pageformat default PIC16!Header files that can be included to the source files using the pic16 range none pageformat default PIC16 port. That file is the **pic18fregs.h**. This header file contains the definitions for the processor special registers, so it is necessary if the source accesses them. It can be included by adding the following line in the beginning of the file:
|
|
1240
|
+
|
|
1241
|
+
#include <pic18fregs.h>
|
|
1242
|
+
|
|
1243
|
+
The specific microcontroller is selected within the pic18fregs.h automatically, so the same source can be used with a variety of devices.
|
|
1244
|
+
|
|
1245
|
+
#### Libraries
|
|
1246
|
+
|
|
1247
|
+
The libraries range none pageformat default PIC16!Libraries that PIC16 range none pageformat default PIC16 port depends on are the microcontroller device libraries which contain the symbol definitions for the microcontroller special function registers. These libraries have the format pic18fxxxx.lib, where *xxxx* is the microcontroller identification number. The specific library is selected automatically by the compiler at link stage according to the selected device.
|
|
1248
|
+
|
|
1249
|
+
Libraries are created with gplib which is part of the gputils package http://sourceforge.net/projects/gputils.
|
|
1250
|
+
|
|
1251
|
+
Building the libraries
|
|
1252
|
+
|
|
1253
|
+
Before using SDCC/pic16 there are some libraries that need to be compiled. This process is done automatically if gputils are found at SDCC's compile time. Should you require to rebuild the pic16 libraries manually (e.g. in order to enable output of float values range none pageformat default printf()!PIC16 Floating point support via printf(), see below), these are the steps required to do so under Linux or Mac OS X (cygwin might work as well, but is untested):
|
|
1254
|
+
|
|
1255
|
+
cd device/lib/pic16
|
|
1256
|
+
|
|
1257
|
+
./configure.gnu
|
|
1258
|
+
|
|
1259
|
+
cd..
|
|
1260
|
+
|
|
1261
|
+
make model-pic16
|
|
1262
|
+
|
|
1263
|
+
su -c 'make install' # install the libraries, you need the root password
|
|
1264
|
+
|
|
1265
|
+
cd../..
|
|
1266
|
+
|
|
1267
|
+
If you need to install the headers too, do:
|
|
1268
|
+
|
|
1269
|
+
cd device/include
|
|
1270
|
+
|
|
1271
|
+
su -c 'make install' # install the headers, you need the root password
|
|
1272
|
+
|
|
1273
|
+
Output of float values via printf()
|
|
1274
|
+
|
|
1275
|
+
The library is normally built without support for displaying float values, only <NO FLOAT> range none pageformat default range none pageformat default printf()!PIC16 floating point support will appear instead of the value. To change this, rebuild the library as stated above, but call./configure.gnu --enable-floats instead of just./configure.gnu. Also make sure that at least libc/stdio/vfprintf.c is actually recompiled, e.g. by touch ing it after the configure run or deleting its.o file.
|
|
1276
|
+
|
|
1277
|
+
The more common approach of compiling vfprintf.c manually with-DUSE_FLOATS=1 should also work, but is untested.
|
|
1278
|
+
|
|
1279
|
+
#### Adding New Devices to the Port
|
|
1280
|
+
|
|
1281
|
+
Adding support for a new 16 bit PIC MCU requires the following steps:
|
|
1282
|
+
|
|
1283
|
+
1. Create picDEVICE.c and picDEVICE.h from pDEVICE.inc using
|
|
1284
|
+
perl /path/to/sdcc/support/scripts/inc2h-pic16.pl\
|
|
1285
|
+
/path/to/gputils/header/pDEVICE.inc
|
|
1286
|
+
2. mv picDEVICE.h /path/to/sdcc/device/non-free/include/pic16
|
|
1287
|
+
3. mv picDEVICE.c /path/to/sdcc/device/non-free/lib/pic16/libdev
|
|
1288
|
+
4. Either
|
|
1289
|
+
5. add the new device to /path/to/sdcc/device/lib/pic16/libio/*.ignore to suppress building any of the I/O libraries for the new device In fact, the.ignore files are only used when auto-generating Makefile.am using the.../libio/mkmk.sh script., or
|
|
1290
|
+
6. add the device (family) to /path/to/sdcc/support/scripts/pic18fam-h-gen.pl to assign I/O styles, run the pic18fam-h-gen.pl script to generate pic18fam.h.gen, replace your existing pic18fam.h with the generated file, and (if required) implement new I/O styles in /path/to/sdcc/device/include/pic16/{adc,i2c,usart}.h and /path/to/sdcc/device/lib/pic16/libio/*/*.
|
|
1291
|
+
7. Edit /path/to/sdcc/device/include/pic16/pic18fregs.h
|
|
1292
|
+
The file format is self-explanatory, just add
|
|
1293
|
+
#elif defined(picDEVICE)
|
|
1294
|
+
# include <picDEVICE.h>
|
|
1295
|
+
at the right place (keep the file sorted, please).
|
|
1296
|
+
8. Edit /path/to/sdcc/device/include/pic16devices.txt
|
|
1297
|
+
Copy and modify an existing entry or create a new one and insert it at the correct place (keep the file sorted, please).
|
|
1298
|
+
9. (cd /path/to/sdcc/device/non-free/lib/pic16 && sh update.sh)
|
|
1299
|
+
10. Recompile the pic16 libraries as described in Libraries or just configure and build sdcc again from scratch (recommended).
|
|
1300
|
+
|
|
1301
|
+
#### Memory Models
|
|
1302
|
+
|
|
1303
|
+
The following memory models are supported by the PIC16 port:
|
|
1304
|
+
|
|
1305
|
+
- small model
|
|
1306
|
+
- large model
|
|
1307
|
+
Memory model affects the default size of pointers within the source. The sizes are shown in the next table:
|
|
1308
|
+
|
|
1309
|
+
| Pointer sizes according to memory model | small model | large model |
|
|
1310
|
+
| --- | --- | --- |
|
|
1311
|
+
| code pointers | 16-bits | 24-bits |
|
|
1312
|
+
| data pointers | 16-bits | 16-bits |
|
|
1313
|
+
| data pointers | 16-bits | 16-bits |
|
|
1314
|
+
|
|
1315
|
+
It is advisable that all sources within a project are compiled with the same memory model. If one wants to override the default memory model, this can be done by declaring a pointer as **far** or **near**. Far selects large memory model's pointers, while near selects small memory model's pointers.
|
|
1316
|
+
|
|
1317
|
+
The standard device libraries (see Header Files) contain no reference to pointers, so they can be used with both memory models.
|
|
1318
|
+
|
|
1319
|
+
#### Stack
|
|
1320
|
+
|
|
1321
|
+
The stack range none pageformat default PIC16!stack implementation for the PIC16 port uses two indirect registers, FSR1 and FSR2.
|
|
1322
|
+
|
|
1323
|
+
FSR1 is assigned as stack pointer
|
|
1324
|
+
|
|
1325
|
+
FSR2 is assigned as frame pointer
|
|
1326
|
+
|
|
1327
|
+
The following stack models are supported by the PIC16 port
|
|
1328
|
+
|
|
1329
|
+
- small model
|
|
1330
|
+
- large model
|
|
1331
|
+
Small model means that only the FSRxL byte is used to access stack and frame, while *large* uses both FSRxL and FSRxH registers. The following table shows the stack/frame pointers sizes according to stack model and the maximum space they can address:
|
|
1332
|
+
|
|
1333
|
+
| Stack & Frame pointer sizes according to stack model | small | large |
|
|
1334
|
+
| --- | --- | --- |
|
|
1335
|
+
| Stack pointer FSR1 | 8-bits | 16-bits |
|
|
1336
|
+
| Frame pointer FSR2 | 8-bits | 16-bits |
|
|
1337
|
+
| Frame pointer FSR2 | 8-bits | 16-bits |
|
|
1338
|
+
|
|
1339
|
+
Large stack model is currently not working properly throughout the code generator. So its use is not advised. Also there are some other points that need special care:
|
|
1340
|
+
|
|
1341
|
+
1. Do not create stack sections with size more than one physical bank (that is 256 bytes)
|
|
1342
|
+
2. Stack sections should no cross physical bank limits (i.e. #pragma stack 0x50 0x100)
|
|
1343
|
+
These limitations are caused by the fact that only FSRxL is modified when using SMALL stack model, so no more than 256 bytes of stack can be used. This problem will disappear after LARGE model is fully implemented.
|
|
1344
|
+
|
|
1345
|
+
#### Functions
|
|
1346
|
+
|
|
1347
|
+
In addition to the standard SDCC function keywords, PIC16 range none pageformat default PIC16 port makes available two more:
|
|
1348
|
+
|
|
1349
|
+
__wparam range none pageformat default PIC16!wparam Use the WREG to pass one byte of the first function argument. This improves speed but you may not use this for functions with arguments that are called via function pointers, otherwise the first byte of the first parameter will get lost. Usage:
|
|
1350
|
+
|
|
1351
|
+
void func_wparam(int a) __wparam
|
|
1352
|
+
|
|
1353
|
+
{
|
|
1354
|
+
|
|
1355
|
+
/* WREG hold the lower part of a */
|
|
1356
|
+
|
|
1357
|
+
/* the high part of a is stored in FSR2+2 (or +3 for large stack model) */
|
|
1358
|
+
|
|
1359
|
+
...
|
|
1360
|
+
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
__shadowregs range none pageformat default PIC16!shadowregs When entering/exiting an ISR, it is possible to take advantage of the PIC18F hardware shadow registers which hold the values of WREG, STATUS and BSR registers. This can be done by adding the keyword *__shadowregs* before the *__interrupt* keyword in the function's header.
|
|
1364
|
+
|
|
1365
|
+
void isr_shadow(void) __shadowregs __interrupt (1)
|
|
1366
|
+
|
|
1367
|
+
{
|
|
1368
|
+
|
|
1369
|
+
...
|
|
1370
|
+
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
*__shadowregs* instructs the code generator not to store/restore WREG, STATUS, BSR when entering/exiting the ISR.
|
|
1374
|
+
|
|
1375
|
+
#### Function return values
|
|
1376
|
+
|
|
1377
|
+
Return values from functions are placed to the appropriate registers following a modified Microchip policy optimized for SDCC. The following table shows these registers:
|
|
1378
|
+
|
|
1379
|
+
| size | destination register |
|
|
1380
|
+
| --- | --- |
|
|
1381
|
+
| 8 bits | WREG |
|
|
1382
|
+
| 16 bits | PRODL:WREG |
|
|
1383
|
+
| 24 bits | PRODH:PRODL:WREG |
|
|
1384
|
+
| 32 bits | FSR0L:PRODH:PRODL:WREG |
|
|
1385
|
+
| >32 bits | on stack, FSR0 points to the beginning |
|
|
1386
|
+
| >32 bits | on stack, FSR0 points to the beginning |
|
|
1387
|
+
|
|
1388
|
+
#### Interrupts
|
|
1389
|
+
|
|
1390
|
+
An interrupt range none pageformat default PIC16!interrupt service routine (ISR) is declared using the *__interrupt* keyword.
|
|
1391
|
+
|
|
1392
|
+
void isr(void) __interrupt *(n)
|
|
1393
|
+
|
|
1394
|
+
{
|
|
1395
|
+
|
|
1396
|
+
...
|
|
1397
|
+
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
*n* is the interrupt number, which for PIC18F devices can be:
|
|
1401
|
+
|
|
1402
|
+
| n | Interrupt Vector | Interrupt Vector Address |
|
|
1403
|
+
| --- | --- | --- |
|
|
1404
|
+
| 0 | RESET vector | 0x000000 |
|
|
1405
|
+
| 1 | HIGH priority interrupts | 0x000008 |
|
|
1406
|
+
| 2 | LOW priority interrupts | 0x000018 |
|
|
1407
|
+
| 2 | LOW priority interrupts | 0x000018 |
|
|
1408
|
+
|
|
1409
|
+
1. this is a HIGH interrupt ISR and LOW interrupts are *disabled* or not used.
|
|
1410
|
+
2. when the ISR is small enough not to reach the next interrupt's vector address.
|
|
1411
|
+
When generating assembly code for ISR the code generator places a goto instruction at the *Interrupt Vector Address* which points at the generated ISR. This single GOTO instruction is part of an automatically generated *interrupt entry point* function. The actual ISR code is placed as normally would in the code space. Upon interrupt request, the GOTO instruction is executed which jumps to the ISR code. When declaring interrupt functions as _naked this GOTO instruction is **not** generated. The whole interrupt functions is therefore placed at the Interrupt Vector Address of the specific interrupt. This is not a problem for the LOW priority interrupts, but it is a problem for the RESET and the HIGH priority interrupts because code may be written at the next interrupt's vector address and cause indeterminate program behaviour if that interrupt is raised. This is not a problem when
|
|
1412
|
+
|
|
1413
|
+
*n* may be omitted. This way a function is generated similar to an ISR, but it is not assigned to any interrupt.
|
|
1414
|
+
|
|
1415
|
+
When entering an interrupt, currently the PIC16 range none pageformat default PIC16 port automatically saves the following registers:
|
|
1416
|
+
|
|
1417
|
+
- WREG
|
|
1418
|
+
- STATUS
|
|
1419
|
+
- BSR
|
|
1420
|
+
- PROD (PRODL and PRODH)
|
|
1421
|
+
- FSR0 (FSR0L and FSR0H)
|
|
1422
|
+
These registers are restored upon return from the interrupt routine. NOTE that when the _naked attribute is specified for an interrupt routine, then NO registers are stored or restored.
|
|
1423
|
+
|
|
1424
|
+
#### Generic Pointers
|
|
1425
|
+
|
|
1426
|
+
Generic pointers are implemented in PIC16 port as 3-byte (24-bit) types. There are 3 types of generic pointers currently implemented data, code and eeprom pointers. They are differentiated by the value of the 7th and 6th bits of the upper byte:
|
|
1427
|
+
|
|
1428
|
+
| pointer type | 7th bit | 6th bit | rest of the pointer | description |
|
|
1429
|
+
| --- | --- | --- | --- | --- |
|
|
1430
|
+
| data | 1 | 0 | uuuuuu uuuuxxxx xxxxxxxx | a 12-bit data pointer in data RAM memory |
|
|
1431
|
+
| code | 0 | 0 | uxxxxx xxxxxxxx xxxxxxxx | a 21-bit code pointer in FLASH memory |
|
|
1432
|
+
| eeprom | 0 | 1 | uuuuuu uuuuuuxx xxxxxxxx | a 10-bit eeprom pointer in EEPROM memory |
|
|
1433
|
+
| (unimplemented) | 1 | 1 | xxxxxx xxxxxxxx xxxxxxxx | unimplemented pointer type |
|
|
1434
|
+
| (unimplemented) | 1 | 1 | xxxxxx xxxxxxxx xxxxxxxx | unimplemented pointer type |
|
|
1435
|
+
|
|
1436
|
+
Generic pointer are read and written with a set of library functions which read/write 1, 2, 3, 4 bytes.
|
|
1437
|
+
|
|
1438
|
+
#### Configuration Bits
|
|
1439
|
+
|
|
1440
|
+
Configuration bits (also known as fuses) can be configured using one of two methods:
|
|
1441
|
+
|
|
1442
|
+
- using #pragma config (see section Pragmas), which is a preferred method for the new code. Example:
|
|
1443
|
+
#pragma config CP0=OFF,OSCS=ON,OSC=LP,BOR=ON,BORV=25,WDT=ON,WDTPS=128,CCP2MUX=ON
|
|
1444
|
+
|
|
1445
|
+
#pragma config STVR=ON
|
|
1446
|
+
|
|
1447
|
+
- using ` __code ' and ` __at ' modifiers. This method is deprecated. Possible options should be ANDed and can be found in your processor header file. Example for PIC18F2550:
|
|
1448
|
+
#include <pic18fregs.h> //Contains config addresses and options
|
|
1449
|
+
|
|
1450
|
+
static __code char __at(__CONFIG1L) configword1l =
|
|
1451
|
+
_USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L &
|
|
1452
|
+
|
|
1453
|
+
_PLLDIV_NO_DIVIDE__4MHZ_INPUT__1L & [...];
|
|
1454
|
+
static __code char __at(__CONFIG1H) configword1h = [...];
|
|
1455
|
+
static __code char __at(__CONFIG2L) configword2l = [...];
|
|
1456
|
+
//More configuration words
|
|
1457
|
+
|
|
1458
|
+
Mixing both methods is not allowed and throws an error message" mixing __CONFIG and CONFIG directives".
|
|
1459
|
+
|
|
1460
|
+
#### PIC16 C Libraries
|
|
1461
|
+
|
|
1462
|
+
##### Standard I/O Streams
|
|
1463
|
+
|
|
1464
|
+
In the *stdio.h* the type FILE is defined as:
|
|
1465
|
+
|
|
1466
|
+
typedef char * FILE;
|
|
1467
|
+
|
|
1468
|
+
This type is the stream type implemented I/O in the PIC18F devices. Also the standard input and output streams are declared in stdio.h:
|
|
1469
|
+
|
|
1470
|
+
extern FILE * stdin;
|
|
1471
|
+
|
|
1472
|
+
extern FILE * stdout;
|
|
1473
|
+
|
|
1474
|
+
The FILE type is actually a generic pointer which defines one more type of generic pointers, the *stream* pointer. This new type has the format:
|
|
1475
|
+
|
|
1476
|
+
| pointer type | | | | | rest of the pointer | descrption |
|
|
1477
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
1478
|
+
| stream | 00 | 1 | 0 | nnnn | uuuuuuuu uuuuuuuu | upper byte high nubble is 0x2n, the rest are zeroes |
|
|
1479
|
+
| stream | 00 | 1 | 0 | nnnn | uuuuuuuu uuuuuuuu | upper byte high nubble is 0x2n, the rest are zeroes |
|
|
1480
|
+
|
|
1481
|
+
Currently implemented there are 3 types of streams defined:
|
|
1482
|
+
|
|
1483
|
+
| stream type | value | module | description |
|
|
1484
|
+
| --- | --- | --- | --- |
|
|
1485
|
+
| STREAM_USART | 0x200000UL | USART | Writes/Reads characters via the USART peripheral |
|
|
1486
|
+
| STREAM_MSSP | 0x210000UL | MSSP | Writes/Reads characters via the MSSP peripheral |
|
|
1487
|
+
| STREAM_USER | 0x2f0000UL | (none) | Writes/Reads characters via used defined functions |
|
|
1488
|
+
| STREAM_USER | 0x2f0000UL | (none) | Writes/Reads characters via used defined functions |
|
|
1489
|
+
|
|
1490
|
+
The stream identifiers are declared as macros in the stdio.h header.
|
|
1491
|
+
|
|
1492
|
+
In the libc library there exist the functions that are used to write to each of the above streams. These are
|
|
1493
|
+
|
|
1494
|
+
_ _stream_usart_putchar writes a character at the USART stream
|
|
1495
|
+
|
|
1496
|
+
_ _stream_mssp_putchar writes a character at the MSSP stream
|
|
1497
|
+
|
|
1498
|
+
putchar dummy function. This writes a character to a user specified manner.
|
|
1499
|
+
|
|
1500
|
+
In order to increase performance *putchar* is declared in stdio.h as having its parameter in WREG (it has the *__wparam* keyword). In stdio.h exists the macro PUTCHAR(arg) that defines the putchar function in a user-friendly way. *arg* is the name of the variable that holds the character to print. An example follows:
|
|
1501
|
+
```c
|
|
1502
|
+
#include <pic18fregs.h>
|
|
1503
|
+
#include <stdio.h>
|
|
1504
|
+
|
|
1505
|
+
PUTCHAR(c)
|
|
1506
|
+
{
|
|
1507
|
+
PORTA = c; /* dump character c to PORTA */
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
void main(void)
|
|
1511
|
+
{
|
|
1512
|
+
stdout = STREAM_USER; /* this is not necessary, since stdout points by default to STREAM_USER */
|
|
1513
|
+
printf (" This is a printf test\ n");
|
|
1514
|
+
}
|
|
1515
|
+
```
|
|
1516
|
+
|
|
1517
|
+
##### Printing functions
|
|
1518
|
+
|
|
1519
|
+
PIC16 contains an implementation of the printf-family range none pageformat default printf()!PIC16 of functions. There exist the following functions:
|
|
1520
|
+
|
|
1521
|
+
extern unsigned int sprintf(char *buf, char *fmt,...);
|
|
1522
|
+
|
|
1523
|
+
extern unsigned int vsprintf(char *buf, char *fmt, va_list ap);
|
|
1524
|
+
|
|
1525
|
+
extern unsigned int printf(char *fmt,...);
|
|
1526
|
+
|
|
1527
|
+
extern unsigned int vprintf(char *fmt, va_lista ap);
|
|
1528
|
+
|
|
1529
|
+
extern unsigned int fprintf(FILE *fp, char *fmt,...);
|
|
1530
|
+
|
|
1531
|
+
extern unsigned int vfprintf(FILE *fp, char *fmt, va_list ap);
|
|
1532
|
+
|
|
1533
|
+
For sprintf and vsprintf *buf* should normally be a data pointer where the resulting string will be placed. No range checking is done so the user should allocate the necessary buffer. For fprintf and vfprintf *fp* should be a stream pointer (i.e. stdout, STREAM_MSSP, etc...).
|
|
1534
|
+
|
|
1535
|
+
##### Signals
|
|
1536
|
+
|
|
1537
|
+
The PIC18F family of microcontrollers supports a number of interrupt sources. A list of these interrupts is shown in the following table:
|
|
1538
|
+
|
|
1539
|
+
| signal name | description | signal name | description |
|
|
1540
|
+
| --- | --- | --- | --- |
|
|
1541
|
+
| SIG_RB | PORTB change interrupt | SIG_EE | EEPROM/FLASH write complete interrupt |
|
|
1542
|
+
| SIG_INT0 | INT0 external interrupt | SIG_BCOL | Bus collision interrupt |
|
|
1543
|
+
| SIG_INT1 | INT1 external interrupt | SIG_LVD | Low voltage detect interrupt |
|
|
1544
|
+
| SIG_INT2 | INT2 external interrupt | SIG_PSP | Parallel slave port interrupt |
|
|
1545
|
+
| SIG_CCP1 | CCP1 module interrupt | SIG_AD | AD convertion complete interrupt |
|
|
1546
|
+
| SIG_CCP2 | CCP2 module interrupt | SIG_RC | USART receive interrupt |
|
|
1547
|
+
| SIG_TMR0 | TMR0 overflow interrupt | SIG_TX | USART transmit interrupt |
|
|
1548
|
+
| SIG_TMR1 | TMR1 overflow interrupt | SIG_MSSP | SSP receive/transmit interrupt |
|
|
1549
|
+
| SIG_TMR2 | TMR2 matches PR2 interrupt | | |
|
|
1550
|
+
| SIG_TMR3 | TMR3 overflow interrupt | | |
|
|
1551
|
+
| SIG_TMR3 | TMR3 overflow interrupt | | |
|
|
1552
|
+
|
|
1553
|
+
The prototypes for these names are defined in the header file *signal.h*.
|
|
1554
|
+
|
|
1555
|
+
In order to simplify signal handling, a number of macros is provided:
|
|
1556
|
+
|
|
1557
|
+
DEF_INTHIGH(name) begin the definition of the interrupt dispatch table for high priority interrupts. *name* is the function name to use.
|
|
1558
|
+
|
|
1559
|
+
DEF_INTLOW(name) begin the definition of the interrupt dispatch table for low priority interrupt. *name* is the function name to use.
|
|
1560
|
+
|
|
1561
|
+
DEF_HANDLER(sig,handler) define a handler for signal *sig.
|
|
1562
|
+
|
|
1563
|
+
END_DEF end the declaration of the dispatch table.
|
|
1564
|
+
|
|
1565
|
+
Additionally there are two more macros to simplify the declaration of the signal handler:
|
|
1566
|
+
|
|
1567
|
+
** SIGHANDLER(handler)** this declares the function prototype for the *handler* function.
|
|
1568
|
+
|
|
1569
|
+
SIGHANDLERNAKED(handler) same as SIGHANDLER() but declares a naked function.
|
|
1570
|
+
|
|
1571
|
+
An example of using the macros above is shown below:
|
|
1572
|
+
|
|
1573
|
+
#include <pic18fregs.h>
|
|
1574
|
+
|
|
1575
|
+
#include <signal.h>
|
|
1576
|
+
|
|
1577
|
+
DEF_INTHIGH(high_int)
|
|
1578
|
+
|
|
1579
|
+
DEF_HANDLER(SIG_TMR0, _tmr0_handler)
|
|
1580
|
+
|
|
1581
|
+
DEF_HANDLER(SIG_BCOL, _bcol_handler)
|
|
1582
|
+
|
|
1583
|
+
END_DEF
|
|
1584
|
+
|
|
1585
|
+
SIGHANDLER(_tmr0_handler)
|
|
1586
|
+
|
|
1587
|
+
{
|
|
1588
|
+
|
|
1589
|
+
/* action to be taken when timer 0 overflows */
|
|
1590
|
+
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
SIGHANDLERNAKED(_bcol_handler)
|
|
1594
|
+
|
|
1595
|
+
{
|
|
1596
|
+
|
|
1597
|
+
__asm
|
|
1598
|
+
|
|
1599
|
+
/* action to be taken when bus collision occurs */
|
|
1600
|
+
|
|
1601
|
+
retfie
|
|
1602
|
+
|
|
1603
|
+
__endasm;
|
|
1604
|
+
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
**NOTES:** Special care should be taken when using the above scheme:
|
|
1608
|
+
|
|
1609
|
+
- do not place a colon (;) at the end of the DEF_* and END_DEF macros.
|
|
1610
|
+
- when declaring SIGHANDLERNAKED handler never forget to use *retfie* for proper returning.
|
|
1611
|
+
|
|
1612
|
+
#### PIC16 Port - Tips
|
|
1613
|
+
|
|
1614
|
+
Here you can find some general tips for compiling programs with SDCC/pic16.
|
|
1615
|
+
|
|
1616
|
+
##### Stack size
|
|
1617
|
+
|
|
1618
|
+
The default stack range none pageformat default PIC16!stack size (that is 64 bytes) probably is enough for many programs. One must take care that when there are many levels of function nesting, or there is excessive usage of stack, its size should be extended. An example of such a case is the printf/sprintf family of functions. If you encounter problems like not being able to print integers, then you need to set the stack size around the maximum (256 for small stack model). The following diagram shows what happens when calling printf to print an integer:
|
|
1619
|
+
|
|
1620
|
+
printf () --> ltoa () --> ultoa () --> divschar ()
|
|
1621
|
+
|
|
1622
|
+
It is should be understood that stack is easily consumed when calling complicated functions. Using command line arguments like --fomit-frame-pointer might reduce stack usage by not creating unnecessary stack frames. Other ways to reduce stack usage may exist.
|
|
1623
|
+
|
|
1624
|
+
#### Known Bugs
|
|
1625
|
+
|
|
1626
|
+
##### Extended Instruction Set
|
|
1627
|
+
|
|
1628
|
+
The PIC16 port emits code which is incompatible with the extended instruction set available with many newer devices. Make sure to always explicitly disable it, usually using:
|
|
1629
|
+
|
|
1630
|
+
- #pragma config XINST=OFF
|
|
1631
|
+
or deprecated:
|
|
1632
|
+
|
|
1633
|
+
- static __code char __at(__CONFIG4L) conf4l = /* more flags & */ _XINST_OFF_4L;
|
|
1634
|
+
Some devices (namely 18f2455, 18f2550, 18f4455, and 18f4550) use _ENHCPU_OFF_4L instead of _XINST_OFF_4L.
|
|
1635
|
+
|
|
1636
|
+
##### Regression Tests
|
|
1637
|
+
|
|
1638
|
+
The PIC16 port currently passes most but not all of the tests in SDCC's regression test range none pageformat default Regression test (PIC16) suite (see section Quality control), thus no automatic regression tests are currently performed for the PIC16 target.
|