Issues when migrating back to Classic from newlib

Requests for features
User avatar
jorgegv
Well known member
Posts: 305
Joined: Wed Nov 18, 2020 5:08 pm

Re: Issues when migrating back to Classic from newlib

Post by jorgegv »

Hi again. 2 years later, I'm reviving my migration from Newlib to Classic. Context: compiling with SDCC for Classic lib.

I have a couple of doubts. First is: why is the function __sdcc_enter_ix called at the beginning of some functions? E.g.:

Code: Select all

   929                          ;engine/lowmem/memory.c:39: void memory_call_banked_function_a16( uint8_t function_id, uint16_t arg ) {
   930                          ;       ---------------------------------
   931                          ; Function memory_call_banked_function_a16
   932                          ; ---------------------------------
   933                          _memory_call_banked_function_a16:
   934  0023  cd0000                    call    ___sdcc_enter_ix
   935                          ;engine/lowmem/memory.c:47: previous_memory_bank = memory_switch_bank( ENGINE_CODE_MEMORY_BANK );
   936  0026  2e04                      ld      l,0x04
   937  0028  cd0000                    call    _memory_switch_bank
   938                          ;engine/lowmem/memory.c:50: run_function[ function_id ]( arg );
   939  002b  dd5e04                    ld      e,(ix+4)
   940  002e  4d                        ld      c,l
   941  002f  1600                      ld      d,0x00
   942  0031  eb                        ex      de, hl
   943  0032  29                        add     hl, hl
I have read the source, and besides pushing IY to the stack (_NOT_ IX!) I can't imagine its purpose.

My second doubt is related to the same code snippet above: I'm having trouble with this function, and debugging it I can see that when entering, IX = C862, which kind of makes it blow up. The correct value that should be loaded in E is 0, but instead a 50 is loaded because (of course), _memory_switch_bank switches to another bank at C000.

According to the function signature, the function_id parameter should come from the stack, which is safely at around 0x81xx. But instead it's loading it from IX+4, which has just been paged out, and explodes.

The strange thing is that according to the MAP, Nothing is stored above C85D:

Code: Select all

asm_sp1_UpdateNow               = $C824 ; addr, public, , asm_sp1_UpdateNow, code_temp_sp1, /home/jorgegv/src/spectrum/z88dk-original-2.3/libsrc/_DEVELOPMENT/temp/sp1/zx/updater/asm_sp1_UpdateNow.asm:21
skipthischar                    = $C834 ; addr, local, , asm_sp1_UpdateNow, code_temp_sp1, /home/jorgegv/src/spectrum/z88dk-original-2.3/libsrc/_DEVELOPMENT/temp/sp1/zx/updater/asm_sp1_UpdateNow.asm:35
updatelp                        = $C83F ; addr, local, , asm_sp1_UpdateNow, code_temp_sp1, /home/jorgegv/src/spectrum/z88dk-original-2.3/libsrc/_DEVELOPMENT/temp/sp1/zx/updater/asm_sp1_UpdateNow.asm:46
doneupdate                      = $C853 ; addr, local, , asm_sp1_UpdateNow, code_temp_sp1, /home/jorgegv/src/spectrum/z88dk-original-2.3/libsrc/_DEVELOPMENT/temp/sp1/zx/updater/asm_sp1_UpdateNow.asm:71
all_return                      = $C85D ; addr, local, , asm_sp1_UpdateNow, code_temp_sp1, /home/jorgegv/src/spectrum/z88dk-original-2.3/libsrc/_DEVELOPMENT/temp/sp1/zx/updater/asm_sp1_UpdateNow.asm:78
The only symbols in the map with value C862 are all the unused sections ..._head and ..._size symbols, which all resolve to the same C862, and the associated ..._size values are set to 0 (expected):

Code: Select all

 jorgegv@endor  rage1   migrate_back_to_classic ⇡1  🐧  grep C862 main.map
__code_temp_sp1_tail            = $C862 ; const, public, def, , ,
__code_splib2_head              = $C862 ; const, public, def, , ,
__code_splib2_tail              = $C862 ; const, public, def, , ,
__code_sound_bit_head           = $C862 ; const, public, def, , ,
__code_sound_bit_tail           = $C862 ; const, public, def, , ,
__code_graphics_head            = $C862 ; const, public, def, , ,
__code_graphics_tail            = $C862 ; const, public, def, , ,
__code_user_head                = $C862 ; const, public, def, , ,
__code_user_tail                = $C862 ; const, public, def, , ,
__CODE_END_head                 = $C862 ; const, public, def, , ,
__CODE_END_tail                 = $C862 ; const, public, def, , ,
__RODATA_head                   = $C862 ; const, public, def, , ,
__RODATA_tail                   = $C862 ; const, public, def, , ,
__rodata_fp_head                = $C862 ; const, public, def, , ,
__rodata_fp_tail                = $C862 ; const, public, def, , ,
__rodata_fp_math48_head         = $C862 ; const, public, def, , ,
__rodata_fp_math48_tail         = $C862 ; const, public, def, , ,
__rodata_fp_math32_head         = $C862 ; const, public, def, , ,
__rodata_fp_math32_tail         = $C862 ; const, public, def, , ,
__rodata_fp_math16_head         = $C862 ; const, public, def, , ,
__rodata_fp_math16_tail         = $C862 ; const, public, def, , ,
__rodata_fp_mbf32_head          = $C862 ; const, public, def, , ,
__rodata_fp_mbf32_tail          = $C862 ; const, public, def, , ,
__rodata_fp_mbf64_head          = $C862 ; const, public, def, , ,
__rodata_fp_mbf64_tail          = $C862 ; const, public, def, , ,
__rodata_fp_am9511_head         = $C862 ; const, public, def, , ,
__rodata_fp_am9511_tail         = $C862 ; const, public, def, , ,
__rodata_fp_dai32_head          = $C862 ; const, public, def, , ,
__rodata_fp_dai32_tail          = $C862 ; const, public, def, , ,
__rodata_arch_head              = $C862 ; const, public, def, , ,
__rodata_arch_tail              = $C862 ; const, public, def, , ,
__rodata_psg_head               = $C862 ; const, public, def, , ,
__rodata_psg_tail               = $C862 ; const, public, def, , ,
__rodata_sound_ay_head          = $C862 ; const, public, def, , ,
__rodata_sound_ay_tail          = $C862 ; const, public, def, , ,
__rodata_graphics_head          = $C862 ; const, public, def, , ,
__rodata_graphics_tail          = $C862 ; const, public, def, , ,
__rodata_user_head              = $C862 ; const, public, def, , ,
__rodata_user_tail              = $C862 ; const, public, def, , ,
__rodata_font_head              = $C862 ; const, public, def, , ,
__rodata_font_tail              = $C862 ; const, public, def, , ,
__rodata_font_fzx_head          = $C862 ; const, public, def, , ,
__rodata_font_fzx_tail          = $C862 ; const, public, def, , ,
__rodata_font_6x8_head          = $C862 ; const, public, def, , ,
__rodata_font_6x8_tail          = $C862 ; const, public, def, , ,
__rodata_font_8x8_head          = $C862 ; const, public, def, , ,
__rodata_font_8x8_tail          = $C862 ; const, public, def, , ,
__rodata_font_8x10_head         = $C862 ; const, public, def, , ,
__rodata_font_8x10_tail         = $C862 ; const, public, def, , ,
__rodata_font_ansi_head         = $C862 ; const, public, def, , ,
__rodata_font_ansi_tail         = $C862 ; const, public, def, , ,
__rodata_splib2_head            = $C862 ; const, public, def, , ,
__rodata_splib2_tail            = $C862 ; const, public, def, , ,
__rodata_appdor_head            = $C862 ; const, public, def, , ,
__rodata_appdor_tail            = $C862 ; const, public, def, , ,
__RODATA_END_head               = $C862 ; const, public, def, , ,
__RODATA_END_tail               = $C862 ; const, public, def, , ,
__ROMABLE_END_head              = $C862 ; const, public, def, , ,
__ROMABLE_END_tail              = $C862 ; const, public, def, , ,
__DATA_head                     = $C862 ; const, public, def, , ,
__DATA_tail                     = $C862 ; const, public, def, , ,
__smc_clib_head                 = $C862 ; const, public, def, , ,
__smc_clib_tail                 = $C862 ; const, public, def, , ,
__smc_fp_head                   = $C862 ; const, public, def, , ,
__smc_fp_tail                   = $C862 ; const, public, def, , ,
__smc_compress_head             = $C862 ; const, public, def, , ,
__smc_compress_tail             = $C862 ; const, public, def, , ,
__smc_user_head                 = $C862 ; const, public, def, , ,
__smc_user_tail                 = $C862 ; const, public, def, , ,
__data_driver_head              = $C862 ; const, public, def, , ,
__data_driver_tail              = $C862 ; const, public, def, , ,
__data_psg_head                 = $C862 ; const, public, def, , ,
__data_psg_tail                 = $C862 ; const, public, def, , ,
__data_sound_ay_head            = $C862 ; const, public, def, , ,
__data_sound_ay_tail            = $C862 ; const, public, def, , ,
__data_PSGlib_head              = $C862 ; const, public, def, , ,
__data_PSGlib_tail              = $C862 ; const, public, def, , ,
__data_graphics_head            = $C862 ; const, public, def, , ,
__data_graphics_tail            = $C862 ; const, public, def, , ,
__data_crt_head                 = $C862 ; const, public, def, , ,
__data_crt_tail                 = $C862 ; const, public, def, , ,
__data_fp_mbf32_head            = $C862 ; const, public, def, , ,
__data_fp_mbf32_tail            = $C862 ; const, public, def, , ,
__data_splib2_head              = $C862 ; const, public, def, , ,
__data_splib2_tail              = $C862 ; const, public, def, , ,
__data_user_head                = $C862 ; const, public, def, , ,
__data_user_tail                = $C862 ; const, public, def, , ,
__data_alloc_balloc_head        = $C862 ; const, public, def, , ,
__data_alloc_balloc_tail        = $C862 ; const, public, def, , ,
__DATA_END_head                 = $C862 ; const, public, def, , ,
__DATA_END_tail                 = $C862 ; const, public, def, , ,
__BSS_head                      = $C862 ; const, public, def, , ,
__BSS_tail                      = $C862 ; const, public, def, , ,
__bss_fp_head                   = $C862 ; const, public, def, , ,
__bss_fp_tail                   = $C862 ; const, public, def, , ,
__bss_fp_math32_head            = $C862 ; const, public, def, , ,
__bss_fp_math32_tail            = $C862 ; const, public, def, , ,
__bss_fp_math16_head            = $C862 ; const, public, def, , ,
__bss_fp_math16_tail            = $C862 ; const, public, def, , ,
__bss_fp_mbf32_head             = $C862 ; const, public, def, , ,
__bss_fp_mbf32_tail             = $C862 ; const, public, def, , ,
__bss_fp_mbf64_head             = $C862 ; const, public, def, , ,
__bss_fp_mbf64_tail             = $C862 ; const, public, def, , ,
__bss_fp_am9511_head            = $C862 ; const, public, def, , ,
__bss_fp_am9511_tail            = $C862 ; const, public, def, , ,
__bss_fp_dai32_head             = $C862 ; const, public, def, , ,
__bss_fp_dai32_tail             = $C862 ; const, public, def, , ,
__bss_compress_aplib_head       = $C862 ; const, public, def, , ,
__bss_compress_aplib_tail       = $C862 ; const, public, def, , ,
__bss_fardata_head              = $C862 ; const, public, def, , ,
__bss_fardata_tail              = $C862 ; const, public, def, , ,
__bss_arch_head                 = $C862 ; const, public, def, , ,
__bss_arch_tail                 = $C862 ; const, public, def, , ,
__bss_string_head               = $C862 ; const, public, def, , ,
__bss_string_tail               = $C862 ; const, public, def, , ,
__bss_alloc_balloc_head         = $C862 ; const, public, def, , ,
__bss_alloc_balloc_tail         = $C862 ; const, public, def, , ,
__bss_graphics_head             = $C862 ; const, public, def, , ,
__bss_graphics_tail             = $C862 ; const, public, def, , ,
__bss_psg_head                  = $C862 ; const, public, def, , ,
__bss_psg_tail                  = $C862 ; const, public, def, , ,
__bss_sound_ay_head             = $C862 ; const, public, def, , ,
__bss_sound_ay_tail             = $C862 ; const, public, def, , ,
__bss_PSGlib_head               = $C862 ; const, public, def, , ,
__bss_PSGlib_tail               = $C862 ; const, public, def, , ,
__bss_splib2_head               = $C862 ; const, public, def, , ,
__bss_splib2_tail               = $C862 ; const, public, def, , ,
__bss_user_head                 = $C862 ; const, public, def, , ,
__bss_user_tail                 = $C862 ; const, public, def, , ,
__BSS_END_head                  = $C862 ; const, public, def, , ,
__BSS_END_tail                  = $C862 ; const, public, def, , ,
So I really don't understand what's going on here, and why IX has a high value outside of the program.

Any help or pointers would be greatly appreciated.
TIA
User avatar
dom
Well known member
Posts: 2194
Joined: Sun Jul 15, 2007 10:01 pm

Re: Issues when migrating back to Classic from newlib

Post by dom »

jorgegv wrote: Sat Apr 20, 2024 6:27 pmI have read the source, and besides pushing IY to the stack (_NOT_ IX!) I can't imagine its purpose.
It saves the callers framepointer and sets up the new frame pointer for the function - classic should use the __SDCC_IX path. However I can't see being defined in the build except for IXIY builds...

Normally I see this code as the prologue:

Code: Select all

push ix
ld ix,0
add ix,sp
But, supplying --opt-code-size results in the helper function being used instead. Which neatly explains why I've never seen it.

I'm deep in __far at the moment, but if you go into libsrc/ then edit z80_crt0s/Makefile and add -D__SDCC_IX to the appropriate lines. rm -fr z80_crt0s/obj and then make z80_crt0.lib && cp z80_crt0.lib ../lib/clibs/ then hopefully that'll fix it.

[edited a few times]
User avatar
jorgegv
Well known member
Posts: 305
Joined: Wed Nov 18, 2020 5:08 pm

Re: Issues when migrating back to Classic from newlib

Post by jorgegv »

I'm adding it to the z80 target, what about the rest? Should they be added to? At least not GB, right? I believe the gbz80 does not have index registers...?

I'll pass you the PR and you can comment on that.
Post Reply