Menu

#3567 loop overflow

closed-fixed
None
Z80
5
2023-03-19
2023-03-18
Under4Mhz
No

In the below code, the size loop iterates too often. Changing the variable "size" to static removes the problem.

/// GPL 2.0 or later
#include <stdio.h>
#include <stdint.h>

#ifdef linux
static volatile uint8_t VDPControlPort;
static volatile uint8_t VDPControlPortIn;
static volatile uint8_t VDPDataPortIn;
static volatile uint8_t VDPDataPortOut;
#else
// define VDPControlPort(SDCC z80 syntax)
static volatile __sfr __at 0x7f VDPControlPort;
static volatile __sfr __at 0x7f VDPControlPortIn;

// define VDPDataPort
static volatile __sfr __at 0x7e VDPDataPortIn;
static volatile __sfr __at 0x7e VDPDataPortOut;
#endif

#define BYTE_HI(x) ((x)>>8)
#define VDU_ADDRESS_SET_MASK 0x4000

void vdu_stop() {}

#define vdu_next_set_fast(value) VDPDataPortOut = value
#define vdu_address_set_unsafe(address) { VDPControlPort=address; VDPControlPort=BYTE_HI((address) | VDU_ADDRESS_SET_MASK ); }

#define for8( var, size ) for ( unsigned char var = 0; var < size; var++ )
typedef uint8_t u8;
typedef uint16_t u16;

#define MAX_TILES 24

typedef struct {

    u16 address;
    u8 size;
    u8 tile[2];

} GameTile;

typedef struct {

    GameTile tiles[MAX_TILES];
    u8 size;

} GameTileState;

GameTileState gameTiles = { .size = 2, .tiles = { { 1, 2, { 2, 3 } }, { 6, 2, { 7, 8 } } } };

void GameTileCallback() {

    vdu_stop();

    GameTile *gameTile = gameTiles.tiles;

    for8( id, gameTiles.size ) {

        vdu_address_set_unsafe( gameTile->address );

        u8 *ptr = gameTile->tile;
        /*static*/ u8 size; size = gameTile->size;
        do {
            vdu_next_set_fast( *ptr++ );

        } while ( --size );

        printf("wrote %d\n", (int)(ptr - gameTile->tile));

        gameTile++;
    }

    gameTiles.size = 0;
}


void main() {

    printf( "Start\n" );

    GameTileCallback();

    printf( "End\n" );

}

#ifdef __SDCC
__sfr __at 0xff sif;
int putchar( int c ) {

    sif = 'p';
    sif = c;

    return c;
}
#endif

// sdcc -mz80 --fverbose-asm ./stack.c  -o stack.ihx && ucsim_z80 -I if=outputs[0xff] stack.ihx
$ sdcc -mz80 --fverbose-asm ./stack.c  -o stack.ihx && ucsim_z80 -I if=outputs[0xff] stack.ihx
./stack.c:23: warning 283: function declarator with no prototype
./stack.c:51: warning 283: function declarator with no prototype
./stack.c:77: warning 283: function declarator with no prototype
uCsim 0.7.9, Copyright (C) 1997 Daniel Drotos.
0> Loading from stack.ihx
3380 words read from stack.ihx
r
Simulation started, PC=0x000000
Start
wrote 32765
wrote 32678
End

$ gcc stack.c  && ./a.out 
Start
wrote 2
wrote 2
End
$ sdcc -v
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502 TD- 4.2.14 #13906 (Linux)

Related

Wiki: NGI0-Entrust-SDCC

Discussion

  • Philipp Klaus Krause

    • Attachments has changed:

    Diff:

    --- old
    +++ new
    @@ -0,0 +1 @@
    +bug-3567.c (1.5 kB; text/x-csrc)
    
    • Category: other --> Z80
     
  • Philipp Klaus Krause

    I can reproduce the issue using the attached test case using current SDCC on Debian GNU/Linux testing on amd64.
    Apparently, only the z80 port and some of the closely related ones are is affected (the test passes for me for test-stm8, test-pdk and test-ucgbz80, but fails for test-ucz80 and test-ucr3ka).

     

    Last edit: Philipp Klaus Krause 2023-03-19
  • Philipp Klaus Krause

    • Attachments has changed:

    Diff:

    --- old
    +++ new
    @@ -1 +0,0 @@
    -bug-3567.c (1.5 kB; text/x-csrc)
    
     
  • Philipp Klaus Krause

    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
     
  • Philipp Klaus Krause

    Fixed in [r13907].

     

    Related

    Commit: [r13907]


Log in to post a comment.

MongoDB Logo MongoDB