Digi has discovered a bug present in Dynamic C 9.30 (but not 9.25) related to code generation for assigning 8-bit values to 16-bit variables via a pointer. The bug has been in all releases of Dynamic C from 9.30 through 9.62A.
Some examples of affected C statements:
pt->int_val = char_val; // impacts pointers to structures
*stack_int_ptr = char_val; // impacts pointers on stack
int_array[7] = char_val; // impacts arrays w/constant index
int_array[int_val] = char_val; // impacts arrays w/variable index
int_ptr[7] = char_val; // impacts array syntax with pointer
*(int_ptr + 7) = char_val; // impacts dereferenced pointer
int_ptr[int_val] = char_val; // impacts pointer w/variable index
The work around is quite simple. Users can either wrap char_val
in parentheses, or explicitly cast it to int:
*int_ptr = char_val; // affected
*int_ptr = (char_val); // workaround
*int_ptr = (int)char_val; // workaround
Dynamic C 9.25 generates the following 11-byte opcode sequence – upon entry, HL holds the address of the integer destination:
1de9 E5 push hl 10
1dea 2A1BB8 ld hl,(0xB81B) 11
1ded 2600 ld h,0x00 4
1def FDE1 pop iy 9
1df1 FDF400 ld (iy+0),hl 13
Note the protection of HL before loading the byte at 0xB81B, and the use of IY to write the 16-bit value to memory.
Starting with Dynamic C 9.30, the compiler generates this 9-byte sequence:
1a88 3A18BA ld a, (0xBA18) 9
1a8b 6F ld l, a 2
1a8c 2600 ld h, 0x00 4
1a8e DDF400 ld (hl + 0), hl 13
Effectively overwriting the destination address with the value to write.
To assess impact, customers can search their binary files for the sequence 6F 26 00 DD F4 00
, which should be unique and unlikely to appear outside of this specific opcode sequence. They can also search the assembly listing (.LST file) for the DDF400
sequence corresponding to ld (hl + 0), hl
which is unlikely to occur outside of this bug.
Users can patch the sequence after the ld a, (0xBA18)
with the following opcodes, making it possible to "fix" existing .bin files containing the 6F 26 00 DD F4 00
sequence in cases where it isn't possible to update and re-compile source code.
77 ld (hl), a
23 inc hl
AF xor a
77 ld (hl), a
2B dec hl ; restore original HL value
00 nop ; keep original byte count
We don’t necessarily have to restore the HL value after the write, but we have two bytes to spare and might as well do it instead of just adding another NOP.
We are adding this as a KNOWN ISSUE and have no plans to update the compiler to fix this bug. This is the first report of the problem since releasing Dynamic C 9.30 over 16 years ago.
Last updated:
Sep 05, 2024