]> git.sur5r.net Git - cc65/blob - doc/internal.doc
This commit was generated by cvs2svn to compensate for changes in r2,
[cc65] / doc / internal.doc
1
2
3                             Internals doc for CC65
4
5
6
7 Stacks:
8 -------
9
10 The program stack used by programs compiled with CC65 is located in high
11 memory.  The stack starts there and grows down.  Arguments to functions, local
12 data etc are allocated on this stack, and deallocated when functions exit.
13
14 The program code and data is located in low memory. The heap is located
15 between the program code and the stack. The default size for the parameter
16 stack is 2K, you may change this by declaring an externally visible variable
17 named named _stksize that holds the new stack size:
18
19     unsigned _stksize = 4*1024;         /* Use 4K stack */
20
21 Note: The size of the stack is only needed if you use the heap, or if you
22 call the stack checking routine (_stkcheck) from somewhere in your program.
23
24 When calling other functions, the return address goes on the normal 6502
25 stack, *not* on the parameter stack.
26
27
28
29 Registers:
30 ----------
31
32 Since CC65 is a member of the Small-C family of compilers, it uses the notion
33 of a 'primary register'.  In the CC65 implementation, I used the AX register
34 pair as the primary register.  Just about everything interesting that the
35 library code does is done by somehow getting a value into AX, and then calling
36 some routine or other.  In places where Small-C would use a secondary
37 register, top-of-stack is used, so for instance two argument function like
38 integer-multiply work by loading AX, pushing it on the stack, loading the
39 second value, and calling the internal function.  The stack is popped, and the
40 result comes back in AX.
41
42
43
44 Calling sequences:
45 ------------------
46
47 C functions are called by pushing their args on the stack, and JSR'ing to the
48 entry point.  (See ex 1, below) If the function returns a value, it comes back
49 in AX.  NOTE!!!  A potentially significant difference between the CC65
50 environment and other C environments is that the CALLEE pops arguments, not
51 the CALLER.  (This is done so as to generate more compact code) In normal use,
52 this doesn't cause any problems, as the normal function entry/exit conventions
53 take care of popping the right number of things off the stack, but you may
54 have to worry about it when doing things like writing hand-coded assembly
55 language routines that take variable numbers of arguments.  More about that
56 later.
57
58 Ex 1:  Function call:  Assuming 'i' declared int and 'c' declared
59        char, the following C code
60
61         i = baz(i, c);
62
63        in absence of a prototype generates this assembler code.  I've added
64        the comments.
65
66         lda     _i              ; get 'i', low byte
67         ldx     _i+1            ; get 'i', hi byte
68         jsr     pushax          ; push it
69         lda     _c              ; get 'c'
70         ldx     #0              ; fill hi byte with 0
71         jsr     pushax          ; push it
72         ldy     #4              ; arg size
73         jsr     _baz            ; call the function
74         sta     _i              ; store the result
75         stx     _i+1
76
77        In presence of a prototype, the picture changes slightly, since the
78        compiler is able to do some optimizations:
79
80         lda     _i              ; get 'i', low byte
81         ldx     _i+1            ; get 'i', hi byte
82         jsr     pushax          ; push it
83         lda     _c              ; get 'c'
84         jsr     pusha           ; push it
85         jsr     _baz            ; call the function
86         sta     _i              ; store the result
87         stx     _i+1
88
89
90 Note that the two words of arguments to baz were popped before it exitted.
91 The way baz could tell how much to pop was by the argument count in Y at call
92 time.  Thus, even if baz had been called with 3 args instead of the 2 it was
93 expecting, that would not cause stack corruption.
94
95 There's another tricky part about all this, though.  Note that the args to baz
96 are pushed in FORWARD order, ie the order they appear in the C statement.
97 That means that if you call a function with a different number of args than it
98 was expecting, they wont end up in the right places, ie if you call baz, as
99 above, with 3 args, it'll operate on the LAST two, not the first two.
100
101
102
103 Symbols:
104 --------
105
106 CC65 does the usual trick of prepending an underbar ('_') to symbol names when
107 compiling them into assembler.  Therefore if you have a C function named
108 'bar', CC65 will define and refer to it as '_bar'.
109
110
111
112 Systems:
113 --------
114
115 Supported systems at this time are: C64, C128, Plus/4, CBM 600/700, the newer 
116 PET machines (not 2001), and the Apple ][ (thanks to Kevin Ruland, who did the
117 port).
118
119 C64:    The program runs in a memory configuration, where only the kernal ROM
120         is enabled. The text screen is expected at the usual place ($400), so
121         54K of memory are available to the program.
122
123 C128:   The startup code will reprogram the MMU, so that only the kernal ROM
124         is enabled. This means, there are 41K of memory available to the
125         program.
126
127 Plus/4: Unfortunately, the Plus/4 is not able to disable only part of it's
128         ROM, it's an all or nothing approach. So, on the Plus/4, the program
129         has only 28K available (16K machines are detected and the amount of
130         free memory is reduced to 12K).
131
132 CBM 600/700:
133         The C program runs in a separate segment and has almost full 64K of
134         memory available.
135
136 PET:    The startup code will adjust the upper memory limit to the installed
137         memory. However, only linear memory is used, this limits the top to
138         $8000, so on a 8032 or similar machine, 31K of memory are available to
139         the program.
140
141 APPLE2: The program starts at $800, and of RAM is $8E00, so 33.5K of memory
142         (including stack) are available.
143
144 Note: The above numbers do not mean that the remaining memory is unusable.
145 However, it is not linear memory and must be accessed by other, nonportable
146 methods. I'm thinking about a library extension that allows access to the
147 additional memory as a far heap, but these routines do not exist until now.
148
149
150
151 Inline Assembly:
152 ----------------
153
154 CC65 allows inline assembly by a special keyword named "asm". Inline assembly
155 looks like a function call. The string in parenthesis is output in the
156 assembler file.
157
158 Example, insert a break instruction into the code:
159
160         asm ("\t.byte\t$00")
161
162 Note: The \t in the string is replaced by the tab character, as in all other
163 strings.
164
165
166
167 Pseudo variables:
168 -----------------
169
170 There are two special variables available named __AX__ and __EAX__. These
171 variables must never be declared (this gives an error), but may be used as any
172 other variable. However, accessing these variables will access the primary
173 register that is used by the compiler to evaluate expressions, return
174 functions results and pass parameters.
175
176 This feature is useful with inline assembly and macros. For example, a macro
177 that reads a CRTC register may be written like this:
178
179 #define wr(idx) (__AX__=(idx),asm("\tsta\t$2000\n\tlda\t$2000\n\tldx\t#$00"),__AX__)
180
181 An obvious problem here is that macro definitions may not use more than one
182 line.
183
184
185