Thanks; I'm getting further. But as I understand (quite probably incorrectly) your comment above, the code in rom will be moved to ram to execute? I can't e.g. put a monitor or a bios written in C in the rom and execute directly from there?
No, no, the copying is only necessary for the data section, i.e. initialized data. Consider e.g.
Code: Select all
int glob = 123;
int main()
{
if(glob == 123) ...
glob++;
...
}
Here, glob has to be located in RAM, but is needs to be initialized to 123 before main() is called. When running from RAM you can simply have the 123 in the image at its target location and glob will be initialized automatically when the image is loaded into RAM. When running from ROM, glob has to be initialized by the startup code. Therefore the init data is put into the ROM image and has to be copied by the startup code to the correct RAM area. The user code will always access the RAM location.
If you do not use initialized data or if your code initializes all its data itself, then you do not need this mechanism. Parts of the C library do depend on it however. On a similar vein, if you want to have programs that sit in RAM and can be restarted there without being loaded into RAM again, you basically need this mechanism as well (because after the program finishes, glob has a new value and must be reset again).
For the actual code, it does not really make a difference if it is running from ROM. It just has to be placed at the correct locations.
Also, I haven't yet found where/how to change the startup code.
The one you found in libsrc is ok. After you made your changes, compile it to object code (vc -c startup.s) and copy the startup.o over the one in your lib directory.
Can I repeat the compliments expressed earlier: in particular, it's hard to see how much more could be chopped of the code generator for
Code: Select all
void cout (char ch)
{
// output single character to serial port
while ((* (volatile char *)ACIASTATUS & 2) == 0)
{ /* wait */ }
* (volatile char *) ACIADATA = ch;
}
which produces
Code: Select all
_cout:
lda sp
bne l8
dec sp+1
l8:
dec sp
l3:
l4:
; volatile barrier
lda 32768
and #2
beq l3
l5:
; volatile barrier
lda r0
sta 32769
l1:
inc sp
bne l9
inc sp+1
l9:
rts
Actually, the stack-pointer handling can be easily eliminated. Just use -O or higher. For the 6502, I would always use at least -O. On the 6502 the difference between optimized and unoptimized code is usually even higher than on many other targets. This is what you get with -O:
Code: Select all
_cout:
; volatile barrier
lda 32768
and #2
bne l7
l6:
; volatile barrier
lda 32768
and #2
beq l6
l7:
; volatile barrier
lda r0
sta 32769
rts