z80 Development Kit
You are not logged in.
On Sun, 6 May 2007, alvin albrecht wrote:
(on printf)
the "-preserve" flag to all the zcc compiles.
Oops, missed that - it works with '-preserve'.
Now onto the next problem: getting malloc and friends to work. I've
finally gotten around to poking around with this. To cut to the chase, the
problem I have now is if I do this:
#include <stdio.h>
int foo;
main()
{
printf("Foo is at address %x", &foo);
}
...it shows that the address of foo is 0x0000 - which isn't much use
because that's in ROM. Looking around other crt0.asm files, I've not seen
anything that causes this sort of thing to be initialized and pointed
somewhere else. (Predictably, if I use the HEAPSIZE() macro in malloc.h,
this ends up in ROM).
Any pointers (forgive the pun) would be appreciated :-)
--
Dylan Smith, Port St Mary, Isle of Man | Code fast, crash young and
Flying: http://www.dylansmith.net | leave a beautiful core.
FFE/Elite Universe: http://www.alioth.net | -- JK (#afe)
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
Oops, missed that - it works with '-preserve'.
Ah, good. I should have mentioned maybe the
first (or last?) zcc should be without the -preserve
so that you start with a fresh zcc.opt file with each
new compile.
> Now onto the next problem: getting malloc and friends to work. I've> finally gotten around to poking around with this. To cut to the chase, the> problem I have now is if I do this:> > #include <stdio.h>> > int foo;> > main()> {> printf("Foo is at address %x", &foo);> }> > ...it shows that the address of foo is 0x0000 - which isn't much use> because that's in ROM. Looking around other crt0.asm files, I've not seen> anything that causes this sort of thing to be initialized and pointed> somewhere else. (Predictably, if I use the HEAPSIZE() macro in malloc.h,> this ends up in ROM).> > Any pointers (forgive the pun) would be appreciated :-)
Ahem, yes :-)
There is a new version of malloc in cvs; 1.6 still uses the old version.
The main difference is that the old version of malloc could only allocate
out of a single monolithic block of memory whereas the new version is
able to allocate out of many scattered blocks of available memory.
Anyway I'll describe the requirements of both here:
1. Old Malloc (1.6 and earlier)
Requires two 16-bit variables called "heaplast" and "heapblocks"
and a block of free memory whose address is named "_heap".
Before using the malloc function the free block of memory and
these two variables must be initialized with a call to heapinit(size).
You can place the location of the two 16-bit variables in RAM
in your crt0 file by doing something like:
XDEF heaplast, heapblocks
defc heaplast = 0x8000
defc heapblocks = 0x8002
This way these variables are declared in RAM in your "system
variables area".
You could do the same with the heap, reserving a location
(and possibly fixed size of memory) for the heap by declaring
its location in your crt0 file:
XDEF _heap
defc _heap = 0x8004
But most applications will have different heap size needs and
memory map so you may prefer to have the user program
declare the heap.
In the user's C program the heap declaration can be done
like so:
extern unsigned char heap(32772);
which will place the heap at address 32772 in memory.
Information on the size of the heap is communicated when
heapinit is called:
heapinit(size of heap in bytes);
The documentation (there is some if you hunt for it!) suggests
using the following macro to declare the heap:
HEAPSIZE(size of heap in bytes)
which should be declared globally (ie in the same place you
declare global variables). The macro actually generates
an array declaration:
unsigned char heap[size of heap in bytes];
which will place the heap in the global/static variables
area. The extern syntax I gave above to declare "heap"
is an alternative that can place the heap at a fixed address
in RAM.
2. New Malloc (cvs -- in 1.7 and later)
A single four-byte variable "_heap" is needed. I'd place this
in your crt0:
XDEF _heap
defc _heap = 0x8000
(the four-byte variable is located in your system variables
area at address 32768).
The heap must be initialized to empty; you can do this
with a call to mallinit:
LIB mallinit
call mallinit
or you can zero the heap variable yourself in the crt0:
ld hl,0
ld (_heap),hl
ld (_heap+2),hl
That's what I'd put in the crt0 (your specific app may have
different requirements).
With the heap empty, you must then add available memory
blocks to the heap with calls to sbrk(). This is something
that may be best left to the user C program as each application
will have different memory needs and memory map.
Make one or more calls to:
sbrk(address of RAM block, size in bytes);
or the asm equivalent to add memory to malloc. With that
done, the malloc lib is all set up.
=== Regarding global and static variable locations (int foo, etc)
this is something to ask Dom about. The compiler separates
the global and statics already but leaves it in the asm file as lump
that gets mixed up with the binary (ie your ROM) by the linker.
Since the variables are already separated by the compiler, it
should be possible to specify an alternate ORG address for them
without trouble. Dom will have to comment on this.
In my own (largeish) project I have a separate globals.h file
that declares the location of all global variables in RAM with the
extern syntax (as seen above to declare the heap). But should
not be necessary -- the compiler should do this automatically.
z88dk will be moving to the next version of the z80asm assembler
(mpm) and it is then that we should be introducing multiple sections,
etc that will do these things properly. In the meantime I think it
shouldn't be too hard to create a separate global/static section
that can be located at a different ORG address than the current
monolithic binary section. Dom / Stef?
Alvin
_________________________________________________________________
Discover the new Windows Vista
http://search.msn.com/results.aspx?q=wi … ;form=QBRE
Offline
One thing I forgot to mention: it was a little weird
that foo was at address 0, as that should be the
location of your crt0 (I assume?). There should be
an ORG in there for address 0.
Alvin
_________________________________________________________________
Connect to the next generation of MSN Messenger
http://imagine-msn.com/messenger/launch … ailtagline
Offline
On Mon, 7 May 2007, alvin albrecht wrote:
=== Regarding global and static variable locations (int foo, etc)
this is something to ask Dom about. The compiler separates
the global and statics already but leaves it in the asm file as lump
that gets mixed up with the binary (ie your ROM) by the linker.
Since the variables are already separated by the compiler, it
should be possible to specify an alternate ORG address for them
without trouble. Dom will have to comment on this.
I'm not sure it could turn out to be 0, I'd suggest a bug in the %x
format converter, try %d!
Regarding globals, there's two ways to do this:
1. Default behaviour, globals are intermingled with the code.
2. ROMable code.
In this model, all globals (non-initialised) are placed together in a
contigious area of memory. This is quite fiddly to sort out, but the z88
port uses this technique, some notes on this:
a) The crt0 should define a DEFVARS clause at a RAM address
b) Object files can't be linked - you should use the assembler outputs as
the intermediate file (otherwise the DEFVARS information in the modules is
lost and variables end up overwriting each other etc).
Here's the ZSock makefile that's an example as to how to compile large
projects which use the ROM information and use the zcc_opt.def file to
transfer information from compilation to linking stage.
TARGET = +z88
#TARGET = +cpm
CC = zcc
CFLAGS = -vn -DNETSTAT -DINACTIVETO=1200 -make-app -O3 -preserve
INCLUDES = -I. -I../include
LIBS = -lnetdev -lmalloc
LDFLAGS =
SOURCES := setup.c icmp.c ip.c udp.c tcp.c udp_dom.c \
handler_call.c net_utils.c loopback.c pbuf.c socket.c socket_int.c
\
pppset.c slip_dev.c z80.c time.c tcp_int.c ping.c lowlevel2.c
device.c
ifeq (+z88,$(TARGET))
SOURCES += config_read.c main.c app.c
LDFLAGS = -create-app -nt
LIBS += -lz88
endif
ifeq (+cpm,$(TARGET))
SOURCES += unixmain.c
endif
ASMS := $(SOURCES:.c=.opt)
all: $(ASMS)
$(CC) $(TARGET) $(LDFLAGS) -o zsock $(CFLAGS) $(ASMS) $(LIBS)
%.opt: %.c zsock.h
$(CC) $(TARGET) $(CFLAGS) -a $(INCLUDES) $<
clean:
rm -f *.opt *~ zsock zsock.62 zsock.63 zcc_opt.def
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
Offline