if you compile this in linux it will work
but if you compile for z80 it doesnt
#include <string.h> #include <stdlib.h> #ifdef __linux__ #include <stdio.h> #endif const squareclosed=1; const squareopen=2; const pathfound=1; const pathnotfound=2; const TargetSquareIsStartSquare=3; int pathtowalkx[20]; int pathtowalky[20]; int numberofopenlistitems; char pathresult; int iter1; int iter2; void drawdot(); void drawdot2(); char findpath(char startx,char starty,char targetx,char targety); void clearpath(); struct maptile { char hcost; char parentX; char parentY; char state; char occupied; }; struct maptile * maptiles[32][24]; void main(void) { for (iter1=0;iter1<32;iter1++) { for(iter2=0;iter2<24;iter2++) { maptiles[iter1][iter2]=malloc(sizeof(struct maptile)); } } // maptiles[1][10]->occupied=1; pathresult=findpath(1,1,1,10); #ifdef __linux__ printf("end"); #else while(1) {} #endif } char findpath(char startx,char starty,char targetx,char targety) { struct maptile * targetsquare; clearpath(); if ((startx==targetx)&&(starty==targety)) { return pathnotfound; } targetsquare=maptiles[targetx][targety]; if (targetsquare->occupied==1) { drawdot2(); return TargetSquareIsStartSquare; } //HCost(startx,starty)=GetHCost(startx,starty,targetx,targety) //AddToOpenList(startx,starty,startx,starty) //LowestFCostSquareX=startx //LowestFCostSquareY=starty return pathnotfound; } void clearpath() { #ifdef __linux__ printf("clear path"); #else drawdot(); #endif } void drawdot() { #ifdef __linux__ printf("drawdot"); #else __asm LD A,#0xFF LD HL,#0x4000 LD (HL),A __endasm; #endif } void drawdot2() { #ifdef __linux__ printf("drawdot2"); #else __asm LD A,#0xF LD HL,#0x4000 LD (HL),A __endasm; #endif }
drawdot2 is never called on the zx spectrum
I know drawdot2 works because I tested it ,
drawdot1 works in the spectrum
the line that doesnt work seems to be
if (targetsquare->occupied==1)
SDCC version-SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.3.1 #8687 (May 29 2013) (Linux)
cmdline used:
Bin/sdcc/bin/sdcc -mz80 --code-loc 26000 --opt-code-size --no-std-crt0 spec.c
I tried to reproduce this bug using the attached code (slightly modified version of your code)). But the if apparently works for me. Also the generated asm code for the if looks correct to me, even for your original code.
Could it be that the problem is elsewhere? Are you sure your memory allocation is ok? You're allocating a lot of memory in tiny chunks.
Philipp
In the SDCC command line I put the code at 26000,
Is there anything that would push the main function away from 26000?
I use a hex2bin program and then a bin2tap to get it into a spectrum tape.
I notice that if I have a lot of C code the program doesnt run, as if the first code is not really at 26000
Last edit: slenk 2013-06-17
Sorry for sticking my nose in, but it tickled my interest as I write for the Spectrum too. I tested this code on the fuse emulator running a +3 in 48K mode, and noted a few things:
If you run the test case as provided, malloc() returns two allocations before returning NULL. Thus maptiles[1][10] is NULL, and we instead lookup offsetof(maptile, occupied) which is at address 0x4 in the ROM. As this contains 0xff, it will never be == 1, and we don't branch to drawdot2().
If you include an explicit call to _sdcc_heap_init() from the start of main, we get a bit further (91 allocations) before NULL. I believe this is hitting the default 1Kb heap size. I'm not sure if this is the preferred way of increasing the heap, but adding the _sdcc_heap_init call and compiling using:
allows the test case to run to completion, calling drawdot2() as expected. However, this isn't a substitute for checking malloc() actually did what you wanted!
Last edit: Brian Ruthven 2013-07-15
Most likely, this issue is not an sdcc bug.
Philipp