Menu

#2187 IF statement only works in linux

closed-works-for-me
None
other
5
2014-10-22
2013-06-15
slenk
No

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

Discussion

  • Philipp Klaus Krause

    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

     
  • slenk

    slenk - 2013-06-17

    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
  • Brian Ruthven

    Brian Ruthven - 2013-07-15

    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:

    • You assume malloc() returns non-zero.
    • Without a crt0, you don't pull in a call to _sdcc_heap_init (which is in the _GSINIT section of _malloc.rel)
    • You don't mention whether you used "CLEAR 25999" or equivalent, so we don't know where the stack is.

    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:

    sdcc -mz80 --code-loc 26000 --opt-code-size --no-std-crt0 -Wl "-b _HEAP_END=0xFF00" spec.c
    

    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
  • Philipp Klaus Krause

    • status: open --> closed-works-for-me
    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    Most likely, this issue is not an sdcc bug.

    Philipp

     

Log in to post a comment.