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)
Diff:
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
Diff:
Fixed in [r13907].
Related
Commit: [r13907]