I encountered a strange behavior with z88dk and I am not sure if it is a bug. I will prepare a bug report on GitHub if you think it is the case.
I develop text adventure games that run on multiple platforms and I noticed a case where my games (based on a C source that is automatically generated and is almost identical for each platform) could not run correctly on the Spectrum.
I try to show here the problematic code, tested with z88dk 23469-0b7d9f00a9-20250517
This is a code that yields a problematic asm on z88dk:
Code: Select all
object *odummy;
/* many lines of code */
boolean drop(unsigned int o) __z88dk_fastcall
{
odummy=search_object_p(o);\
if(odummy->position==CARRIED){\
odummy->position=current_position;\
} else {\
show_message(message1007);\
return true;\
}\
return false;\
}
The object struct is defined as follows:
Code: Select all
typedef struct object_d {
obj_code code;
const char *desc;
unsigned int position; // Always int, as carried =1500, worn=1600
unsigned char attributes;
} object;
Code: Select all
object *search_object_p(unsigned int o) __z88dk_fastcall
{
/* some code*/
}
Code: Select all
; Function drop flags 0x00000208 __smallc __z88dk_fastcall
; unsigned char booleandrop(unsigned int o)
; parameter 'unsigned int o' at sp+2 size(2)
C_LINE 1476,"silkdust2_no_UTF8.c::drop::0::32"
._drop
push hl
call _search_object_p
ld (_odummy),hl
inc hl
inc hl
inc hl
call l_gint ;
ld de,1500
and a
sbc hl,de
jp nz,i_290 ;
ld hl,(_odummy)
inc hl
inc hl
inc hl
ex de,hl
ld a,(_current_position)
ld (de),a
jp i_291 ;EOS
.i_290
ld hl,_message1007
call _show_message
ld hl,1 ;const
pop bc
ret
.i_291
ld hl,0 ;const
pop bc
ret
I noticed that the behavior is corrected if I read odummy->position, immediately after having updated its value. For instance, this code seems to work:
Code: Select all
object *odummy;
unsigned int dummy;
/* many lines of code */
boolean drop(unsigned int o) __z88dk_fastcall
{
odummy=search_object_p(o);\
if(odummy->position==CARRIED){\
odummy->position=current_position;\
dummy=odummy->position;\
} else {\
show_message(message1007);\
return true;\
}\
return false;\
}
Code: Select all
; Function drop flags 0x00000208 __smallc __z88dk_fastcall
; unsigned char booleandrop(unsigned int o)
; parameter 'unsigned int o' at sp+2 size(2)
C_LINE 1476,"silkdust2_no_UTF8.c::drop::0::32"
._drop
push hl
call _search_object_p
ld (_odummy),hl
call l_gint3 ;
ld de,1500
and a
sbc hl,de
jp nz,i_290 ;
ld hl,(_odummy)
inc hl
inc hl
inc hl
ex de,hl
ld hl,(_current_position)
ld h,0
call l_pint
ld hl,(_odummy)
call l_gint3 ;
ld (_dummy),hl
jp i_291 ;EOS
.i_290
ld hl,_message1007
call _show_message
ld hl,1 ;const
pop bc
ret
.i_291
ld hl,0 ;const
pop bc
ret
The program (called Silk Dust) is quite long, I can of course publish the complete C source but if it is necessary, I can try to see if I can obtain a minimal reproducible program that shows the problem.