if your ORG address is 0, the crt is responsible for setting up the z80's restart vectors. In the wiki there is a short note about this at the end of the making crt section and a pointer to the embedded target's crt that generates the restarts if the org address is 0.
I understand the issues you've outlined, but I am just debug-hacking around in the code.
What I'm thinking about is your device is generating interrupts (maskable or non-maskable) and is jumping into space to service them. If interrupts are not occurring then this isn't a problem.
I have a full 64k or ram, so wherever the SP is pointing that should be fine (for now).
I want to make sure SP is not pointing into the program. Note that a cpu reset does not load a known value into SP! Maybe a "di; ld sp,0" at the start of the crt could rule these things out?
This also works:
Code: Select all
#include<stdio.h>
void main(void)
{
char buffer[30];
sprintf(buffer, "Hello World!");
__asm
ld a, '@'
out ($20), a
halt
__endasm;
}
But I have no clue how to check the content of buffer. I can read any address in memory. I have tried probing the end of memory ($FFFF) but could see any recognizable text.
Try making 'buffer' a global variable instead so that it is assigned a fixed address. Then you can find its location from the map file. Locals are created on the stack (as you know since you were hunting for it at the end of memory) so it's not known exactly where they are. If you can't find it at the end of memory, it could be SP is not pointing there. sprintf() is going to exercise all the same code as printf() except for the driver.
Just to check, when you compile this test program with:
zcc +zalt -vn -SO3 -clib=sdcc_iy --max-allocs-per-node200000 helloworld.c -o helloworld -m --list
You get the following files generated:
hw (should be zero size, this catches stuff not assigned to sections)
hw.lst (list file contains "hw.c" translated to asm)
hw.map (map file lists all label values)
hw.reloc (should be zero size, this is the relocation data associated with file "hw")
hw_CODE.bin (this is your output binary to be loaded at address 0)
hw_CODE.reloc (this is the relocation data for "hw_CODE.bin")
There should be no other binaries generated. (If your user program deliberately creates new sections or the RAM model is not properly specified in the crt configuration you may get additional binaries generated, separate DATA and BSS binaries in the latter case).
First the TAR__crt_code_org was defined at 32k. Set that to zero and it went a lot better.
Ok well that will make a big difference
The crt configuration should be something like this:
Code: Select all
defc TAR__crt_org_code = 0 ;; org 0
defc TAR__crt_org_data = 0 ;; data section appends to code section
defc TAR__crt_org_bss = 0 ;; bss section appends to data section
defc TAR__crt_model = 0 ;; ram model means no initialization of bss or data
defc TAR__register_sp = 0 ;; specify sp=0 but the crt must do it so it won't happen on its own
defc TAR__crt_stack_size = 256 ;; indicate stack size, only used if heap is automatically sized by c lib
defc TAR__crt_initialize_bss = 0 ;; set to one if you want the bss section to be zeroed by the crt when ram model is active
defc TAR__crt_enable_commandline = 0
defc TAR__crt_enable_restart = 0
defc TAR__crt_enable_close = 1
defc TAR__crt_enable_rst = 0
defc TAR__crt_enable_nmi = 0
; clib defaults
defc TAR__clib_exit_stack_size = 0 ;; set to max number of exit functions you want to be able to register
defc TAR__clib_quickexit_stack_size = 0
defc TAR__clib_malloc_heap_size = 0 ;; 0 = no heap, set to -1 if you want c lib to create heap between end of BSS and bottom of stack
defc TAR__clib_stdio_heap_size = 0 ;; increase if you want to create memstreams
defc TAR__clib_balloc_table_size = 0
defc TAR__clib_fopen_max = 0
defc TAR__clib_open_max = 0
Second thing is that you can run a program only once. I know you said that (somewhere) but I did not think about at the right time.
That's right the ram model will not initialize the bss and data sections before calling main, which means they will only have their correct initial values on the first run. If your program does not depend on initialized data this won't be a problem. Less obvious is the c library may have static data about. For example, if a FILE being written to generates an error, the FILE will still be in an error state at the start of the next run. You may be able to sort out some of these problems by directing the c library to zero the bss section (set TAR__crt_initialize_bss = 1 above).
With these short test programs, there shouldn't be an issue with restarting. Setting the SP to a known value in the crt will ensure SP doesn't creep downward in memory should you hit reset in the middle of program execution.
Thanks for the responses so far. I understand that this is also a burden on you (write out the same stuff over and over again!
)
It's no trouble - I don't mind answering a few questions
Let's see if some of these things improve the result. I think setting SP to zero in the CRT will be one important thing to do.