I have that the page that never is going to change is the one where the program ends, so I'd be interested in all the auxiliary functions (those beginning with l_, the math ones, etc.) would be allocated at the end, so they could be called from any part of the code.
Can that be achieved? I even don't care if they have to be duplicated adding them again at the end with another decoration compiling within the code in that last page as isolated .o file to be linked.
It should be linker related but can't find the way, also there is a pragma-redirect but probably has another purpose.
If required, can even put the required section in corresponding sources so the linker put them at the end, if I am not mistaken maybe in the DATA area or somewhere.
Some way to put the l_gint and etc. at the end of the code?
-
- Member
- Posts: 71
- Joined: Sun Apr 01, 2018 4:02 pm
-
- Member
- Posts: 71
- Joined: Sun Apr 01, 2018 4:02 pm
Re: Some way to put the l_gint and etc. at the end of the code?
Or maybe something less dramatic would be setting for them the section code_compiler and adding them manually at the end? Not sure what sources are involved.
-
- Member
- Posts: 71
- Joined: Sun Apr 01, 2018 4:02 pm
Re: Some way to put the l_gint and etc. at the end of the code?
Well after a bit research found i.e. the source for l_gint:
Them seems something about reallocating the clib.
Could change all those sections to another placed at the end, but if the clib could be reallocated (i.e. with a compiler option) much better, and would survive to z88dk SDK updates (that would overwrite the files).
Code: Select all
SECTION code_clib
SECTION code_l_sccz80
PUBLIC l_gint, l_gint1, l_gint2, l_gint3
l_gint3:
inc hl
l_gint2:
inc hl
l_gint1:
inc hl
l_gint:
ld a,(hl+)
ld h,(hl)
ld l,a
ret
Could change all those sections to another placed at the end, but if the clib could be reallocated (i.e. with a compiler option) much better, and would survive to z88dk SDK updates (that would overwrite the files).
-
- Member
- Posts: 71
- Joined: Sun Apr 01, 2018 4:02 pm
Re: Some way to put the l_gint and etc. at the end of the code?
More research. I found the file ./lib/crt/classic/crt_section_code.inc which defines the order, then moving the required ones to the end does the trick.
But again if it could be done by command instead modifying the z88dk own files would be better.
But again if it could be done by command instead modifying the z88dk own files would be better.
Re: Some way to put the l_gint and etc. at the end of the code?
It's interesting that you have that memory layout. When I was adding banking to various targets I tweaked things that the compiler support routines (and library in general) should end up in low memory so they weren't paged out - with your model you've gone the other way so I'm curious as to why.
To get the support routines at the end of memory, as you found out you need to rearrange the memory map. Classic has a feature that I copied from newlb but I've never used, so it's not documented outside of the newlib side.
Looking at this post from jorgev: https://z88dk.org/forum/viewtopic.php?p=19933#p19933 it looks like the steps are:
1. Compile with -pragma-define:__MMAP=-1
2. Create a local file called mmap.inc
Into this file, let's put the relevant bits of lib/crt/classic/crt_section_standard.asm (I don't know if you're producing ROM or RAM executables, so you could trim accordingly)
Now, if you want to rearrange the sections you'll need to copy the contents of the included files into mmap.inc and put them in the order you want.
To get the support routines at the end of memory, as you found out you need to rearrange the memory map. Classic has a feature that I copied from newlb but I've never used, so it's not documented outside of the newlib side.
Looking at this post from jorgev: https://z88dk.org/forum/viewtopic.php?p=19933#p19933 it looks like the steps are:
1. Compile with -pragma-define:__MMAP=-1
2. Create a local file called mmap.inc
Into this file, let's put the relevant bits of lib/crt/classic/crt_section_standard.asm (I don't know if you're producing ROM or RAM executables, so you could trim accordingly)
Code: Select all
INCLUDE "crt/classic/crt_section_code.inc"
INCLUDE "crt/classic/crt_section_rodata.inc"
SECTION ROMABLE_END
IF !__crt_model
INCLUDE "crt/classic/crt_section_data.inc"
ENDIF
INCLUDE "crt/classic/crt_section_bss.inc"
IF __crt_model > 0
SECTION DATA
org -1
defb 0 ; control name of data binary
INCLUDE "crt/classic/crt_section_data.inc"
ENDIF
SECTION BSS_END
-
- Member
- Posts: 71
- Joined: Sun Apr 01, 2018 4:02 pm
Re: Some way to put the l_gint and etc. at the end of the code?
OK I'll have to try. Currently was modifying the lib/crt/classic/ files but if can be done with that project local mmap.inc better.
My memory layout is peculiar. Usually is done as you say, distribute the code and data within the segments then they are swapped as required.
In my case what I have is:
- page 0: Functional code | scripts.
- page 1: engine loop + its required functions + data.
- page 2: data
- page 3: data + stack + system area.
Looking at page 0, the scripts means that the idea is not filling the full memory at program load, but loading as self-contained generated binary that will be loaded per scene, this is, each scene can have its own 16KB of binary code.
So on page 1 we have the loop and required functions, as we are going to swap the page 0 to the script binary loaded, overlapping code that we don't need at that moment (the load functions, drawing, etc.). The code is small, I think it would take about 4-6KB, so that give us the max amount of contiguous data on the heap for allocating assets and other loaded data. As we need a fixed heap size for allocating resources, this is optimal, if I'd change the page 1 then I could not use below the address 0x8000 as the _tail would change depending the binary loaded (that can be up to full 16KB).
Also this minimizes the number of segment swaps, that on MSX is not too fast to do it on each object script call.
https://msx.org/forum/msx-talk/developm ... gment-call
We swap page 0, execute the loop, then restore page 0, draw, and repeat. Only 2 swaps.
To be able to swap page 0 on MSX-DOS2 we have the trick of copying the 256 bytes header of the original RAM segment into the segment we are going to put on page 0, so the system runs nicely and don't crash when we swap (well so we really have 16KB - 256bytes for binary).
My memory layout is peculiar. Usually is done as you say, distribute the code and data within the segments then they are swapped as required.
In my case what I have is:
- page 0: Functional code | scripts.
- page 1: engine loop + its required functions + data.
- page 2: data
- page 3: data + stack + system area.
Looking at page 0, the scripts means that the idea is not filling the full memory at program load, but loading as self-contained generated binary that will be loaded per scene, this is, each scene can have its own 16KB of binary code.
So on page 1 we have the loop and required functions, as we are going to swap the page 0 to the script binary loaded, overlapping code that we don't need at that moment (the load functions, drawing, etc.). The code is small, I think it would take about 4-6KB, so that give us the max amount of contiguous data on the heap for allocating assets and other loaded data. As we need a fixed heap size for allocating resources, this is optimal, if I'd change the page 1 then I could not use below the address 0x8000 as the _tail would change depending the binary loaded (that can be up to full 16KB).
Also this minimizes the number of segment swaps, that on MSX is not too fast to do it on each object script call.
https://msx.org/forum/msx-talk/developm ... gment-call
We swap page 0, execute the loop, then restore page 0, draw, and repeat. Only 2 swaps.
To be able to swap page 0 on MSX-DOS2 we have the trick of copying the 256 bytes header of the original RAM segment into the segment we are going to put on page 0, so the system runs nicely and don't crash when we swap (well so we really have 16KB - 256bytes for binary).
-
- Member
- Posts: 71
- Joined: Sun Apr 01, 2018 4:02 pm
Re: Some way to put the l_gint and etc. at the end of the code?
In the list, data = heap area, not compiled data.
-
- Member
- Posts: 71
- Joined: Sun Apr 01, 2018 4:02 pm
Re: Some way to put the l_gint and etc. at the end of the code?
Well tested the MMAP method and works, but has changed:
1) Create a local mmap.inc, and other files you want to modify.
2) Now instead __MMAP has to define MMAP (more intuitive). So compile with -pragma-define:MMAP=-1.
In my case, I have this files:
mmap.inc, notice that changes the order and the code file is a custom one:
local crt_section_code.inc:
1) Create a local mmap.inc, and other files you want to modify.
2) Now instead __MMAP has to define MMAP (more intuitive). So compile with -pragma-define:MMAP=-1.
In my case, I have this files:
mmap.inc, notice that changes the order and the code file is a custom one:
Code: Select all
INCLUDE "crt/classic/crt_section_rodata.inc"
INCLUDE "crt/classic/crt_section_data.inc"
ENDIF
INCLUDE "crt/classic/crt_section_bss.inc"
INCLUDE "./crt_section_code.inc"
IF __crt_org_graphics
SECTION HIMEM
org __crt_org_graphics
SECTION smc_clib
SECTION code_graphics
SECTION code_himem
SECTION rodata_graphics
SECTION rodata_himem
SECTION data_himem
SECTION data_graphics
SECTION bss_graphics
SECTION bss_himem
SECTION HIMEM_END
ENDIF
Code: Select all
; CODE sections defined by the classic library
SECTION CODE
SECTION code_crt_init
SECTION code_crt_init_exit
SECTION code_crt_exit
SECTION code_crt_exit_exit
SECTION code_driver
SECTION code_l ;Keep these in "low" memory
; SECTION code_l_sdcc
; SECTION code_l_sccz80
SECTION code_z80
SECTION rodata_driver ;Keep it in low memoey
SECTION code_compiler
; SECTION code_clib
SECTION code_compress_zx7
SECTION code_compress_zx0
SECTION code_compress_zx1
SECTION code_compress_zx2
SECTION code_compress_aplib
SECTION code_ctype
SECTION code_esxdos
SECTION code_fp
SECTION code_fp_math48
SECTION code_fp_math32
SECTION code_fp_math16
SECTION code_fp_mbf32
SECTION code_fp_mbf64
SECTION code_fp_am9511
SECTION code_fp_dai32
SECTION code_math
SECTION code_error
SECTION code_stdlib
SECTION code_string
SECTION code_adt_b_array
SECTION code_adt_b_vector
SECTION code_adt_ba_priority_queue
SECTION code_adt_ba_stack
SECTION code_adt_bv_priority_queue
SECTION code_adt_bv_stack
SECTION code_adt_p_forward_list
SECTION code_adt_p_forward_list_alt
SECTION code_adt_p_list
SECTION code_adt_p_queue
SECTION code_adt_p_stack
SECTION code_adt_w_array
SECTION code_adt_w_vector
SECTION code_adt_wa_priority_queue
SECTION code_adt_wa_stack
SECTION code_adt_wv_priority_queue
SECTION code_adt_wv_stack
SECTION code_alloc_balloc
SECTION code_alloc_obstack
SECTION code_arch
SECTION code_font
SECTION code_font_fzx
SECTION code_psg
SECTION code_sound_ay
SECTION code_PSGlib
SECTION code_time
SECTION code_sprite_sp1
SECTION code_temp_sp1
SECTION code_splib2
SECTION code_sound_bit
IF !__crt_org_graphics
SECTION code_graphics
ENDIF
SECTION code_video_vdp
SECTION code_user
SECTION code_l_sdcc
SECTION code_l_sccz80
SECTION code_clib
SECTION CODE_END