z88dk, uso de memoria

Todo sobre la creación, diseño y programación de nuevo software para
nuestro Spectrum

Moderador: Sir Cilve Sinclair

z88dk, uso de memoria

Notapor saimazoom el Sab Abr 01, 2017 8:11 am

Hola

¿Hay alguna forma de saber lo que ocupa cada función en z88dk con el zcc?. El sdcc te muestra un mapa de memoria donde puedes ver lo que ocupa cada función. Gracias.
saimazoom
rst 0
 
Mensajes: 12
Registrado: Lun Oct 05, 2015 8:42 am

Re: z88dk, uso de memoria

Notapor Alcoholics Anonymous el Lun Abr 03, 2017 9:09 pm

saimazoom escribió:¿Hay alguna forma de saber lo que ocupa cada función en z88dk con el zcc?. El sdcc te muestra un mapa de memoria donde puedes ver lo que ocupa cada función. Gracias.


Agregue "-m" para crear un archivo de mapa.
Alcoholics Anonymous
rst 0
 
Mensajes: 21
Registrado: Lun Feb 04, 2008 7:16 am

Re: z88dk, uso de memoria

Notapor saimazoom el Mar Abr 04, 2017 9:53 pm

¿Cómo se lee el fichero map?. Parece que las funciones vienen precedidas de _, pero aparecen repetidas varias veces en el mapa y parecen estar ordenadas por orden alfabético (?). ¿Cómo calcular lo que ocupa una función en memoria?. Gracias.


Código: Seleccionar todo
_loc_here                       = 7D9F, G: s1lk_1
_localidades_t                  = 9041, G: s1lk_2
_main                           = B2D8, G: s1lk_2
_mensajesSistema_t              = 9244, G: s1lk_2
_mensajes_t                     = 9241, G: s1lk_2
_newLine                        = 8484, G: s1lk_1
_nombres_t                      = 930D, G: s1lk_2
_objectIsAttr                   = 7F8A, G: s1lk_1
saimazoom
rst 0
 
Mensajes: 12
Registrado: Lun Oct 05, 2015 8:42 am

Re: z88dk, uso de memoria

Notapor Alcoholics Anonymous el Mie Abr 05, 2017 1:33 am

saimazoom escribió:¿Cómo se lee el fichero map?. Parece que las funciones vienen precedidas de _, pero aparecen repetidas varias veces en el mapa y parecen estar ordenadas por orden alfabético (?). ¿Cómo calcular lo que ocupa una función en memoria?. Gracias.


¿Está utilizando una versión antigua de z88dk?
Puede encontrar una versión actual aquí: https://github.com/z88dk/z88dk

El archivo de mapa se ordenó alfabéticamente al mismo tiempo, pero actualmente se emite en el orden de direcciones. Puedo mostrarle dos maneras de hacerlo y tal vez uno trabajará con la versión antigua que está utilizando.

Usaré "eliza.c" como ejemplo (https://github.com/z88dk/z88dk/blob/mas ... ES/eliza.c).

Una posible línea de compilación:
zcc +zx -vn -SO3 -startup=8 -clib=sdcc_iy --max-allocs-per-node200000 eliza.c -o eliza -create-app -m --list --c-code-in-asm

-m : Crear un archivo de mapa
--list : Conversión de montaje de salida con bytes montados
--c-code-in-asm : Añadir código c como comentarios en la traducción

Para encontrar el tamaño de "unsigned char * getInput ()" buscar "getInput" en el archivo de mapa:

Código: Seleccionar todo
asm_z80_push_di                 = $9683 ; G asm_z80_push_di
continue                        = $9687 ; L asm_z80_push_di
__code_compiler_head            = $968E ; G
__code_lib_head                 = $968E ; G
__code_lib_tail                 = $968E ; G
__code_z80_tail                 = $968E ; G
;;;;;;;;;********** HERE IT IS
_getInput                       = $968E ; G eliza_c
l_getInput_00102                = $96B7 ; L eliza_c
;;;;;;;;*********** NEXT FUNCTION BELOW
_replace                        = $96C4 ; G eliza_c
l_replace_00113                 = $96F1 ; L eliza_c


"_getInput" comienza en 0x968e y la siguiente función "_replace" comienza en 0x96c4 así que el tamaño es 54 bytes.

En
Código: Seleccionar todo
_getInput                       = $968E ; G eliza_c

"G" significa global así que un símbolo público ("L" significa local a un archivo por lo que será una etiqueta local y no un nombre de función). "Eliza_c" significa que se encuentra en "eliza.c"

Un segundo método del archivo de lista "eliza.c.lis":

Código: Seleccionar todo
677   0000              ;eliza.c:24: unsigned char* getInput()
678   0000              ;   ---------------------------------
679   0000              ; Function getInput
680   0000              ; ---------------------------------
681   0000              _getInput:
682   0000              ;eliza.c:28: putchar('?');
683   0000  21 3F 00       ld   hl,0x003f
684   0003  CD 00 00       call   _putchar_fastcall
685   0006              ;eliza.c:29: putchar(' ');
686   0006  21 20 00       ld   hl,0x0020
687   0009  CD 00 00       call   _putchar_fastcall
688   000C              ;eliza.c:31: if (!fgets(result, sizeof(result), stdin))
689   000C  11 00 00       ld   de,_getInput_result_1_410+0
690   000F  4B             ld   c, e
691   0010  42             ld   b, d
692   0011  2A 00 00       ld   hl,(_stdin)
693   0014  D5             push   de
694   0015  E5             push   hl
695   0016  21 51 00       ld   hl,0x0051
696   0019  E5             push   hl
697   001A  C5             push   bc
698   001B  CD 00 00       call   _fgets_callee
699   001E  D1             pop   de
700   001F  7C             ld   a,h
701   0020  B5             or   a,l
702   0021  20 06          jr   NZ,l_getInput_00102
703   0023              ;eliza.c:32: exit(1);
704   0023  21 01 00       ld   hl,0x0001
705   0026  CD 00 00       call   _exit_fastcall
706   0029              l_getInput_00102:
707   0029              ;eliza.c:34: result[strlen(result) - 1] = '\0';
708   0029  6B             ld   l, e
709   002A  62             ld   h, d
710   002B  CD 00 00       call   _strlen_fastcall
711   002E  2D             dec   l
712   002F  26 00          ld   h,0x00
713   0031  19             add   hl,de
714   0032  36 00          ld   (hl),0x00
715   0034              ;eliza.c:35: return result;
716   0034  EB             ex   de,hl
717   0035  C9             ret


En
"681 0000 _getInput:"
0000 = La dirección de montaje actual

In
"717 0035 C9 ret"
0035 = La última dirección de montaje de la función (0x36 es el siguiente byte disponible)

Así que el tamaño es 0x36-0x00 = 54 bytes


Si su versión de z88dk no está haciendo archivos como este, puede ir a su archivo de mapa y encontrar la dirección de la función de interés y la función que lo sigue directamente en el mismo archivo de origen.

Así que para "getInput ()" encontraría una dirección de 0x968e y la siguiente función es "replace ()" con una dirección de 0x96c4 así que "getInput ()" tendrá tamaño 0x96c4-0x968e = 54 bytes.

O puede ordenar el archivo de mapa de acuerdo a la dirección para obtenerlo en un formulario donde puede ver inmediatamente el tamaño de las funciones.
Alcoholics Anonymous
rst 0
 
Mensajes: 21
Registrado: Lun Feb 04, 2008 7:16 am

Re: z88dk, uso de memoria

Notapor saimazoom el Mie Abr 05, 2017 6:15 am

Muchas gracias por la explicación, me ha resultado muy útil.
saimazoom
rst 0
 
Mensajes: 12
Registrado: Lun Oct 05, 2015 8:42 am

Re: z88dk, uso de memoria

Notapor saimazoom el Lun Abr 17, 2017 10:23 pm

Estoy intentando separar en mi juego el código del motor y de las fases. La intención es paginar en 128Kb las fases pero manteniendo el motor por debajo de la 0xC000. He intentado lo siguente:

1) Primero compilo el motor
Código: Seleccionar todo
zcc +zx ..\libgfx\libgfx.c parser.c juego_compressed.c -o juego.bin -vn -O3 -startup=31 -lfzx -lfzxfonts_utz -m -lzx7


Sin problemas. Obtengo un binario de 23Kb que luego puedo montar en un .TAP con appmake.

2) Luego intento compilar la fase, pero me devuelve el error de que no existe el símbolo de _main y el resto de símbolos de las funciones del motor.

Código: Seleccionar todo
zcc +zx juego_pagina0_compressed.c -o juego_pagina0_.bin -vn -O3


En el código de la pagina0 he añadido todas las funciones del motor como extern. ¿Cómo puedo compilar el código de cada página de modo que se usen los símbolos que ya he generado al compilar el motor?. Lo que pretendo es que el binario de cada página no pase de 16Kb.

Gracias.
saimazoom
rst 0
 
Mensajes: 12
Registrado: Lun Oct 05, 2015 8:42 am

Re: z88dk, uso de memoria

Notapor saimazoom el Lun Abr 17, 2017 11:35 pm

He dado un paso, usando la opción -g obtengo un "global address definition file" o fichero .def para el z80asm. Lo he intentado incluir en el código de la página:

Código: Seleccionar todo
#asm
    include "juego.def"
#endasm


Y he eliminado del código toda referencia extern a las funciones del motor. Ahora obtengo el siguiente error:

Código: Seleccionar todo

zcc +zx juego_pagina0_compressed.c -o juego_pagina0_compressed.bin -vn -O3

Key to filenames:
C:\Users\kmbr\AppData\Local\Temp\s7jc_.o = juego_pagina0_compressed.c
Error at module 's7jc_': symbol 'base_graphics' already defined in module 'zx82_crt0'
Error at module 's7jc_': symbol 'l_dcal' already defined in module 'zx82_crt0'
Error at module 's7jc_': symbol 'cleanup' already defined in module 'zx82_crt0'


Supongo que me falta alguna opción para indicarle que no estoy intentando generar código que necesite un main :-m
saimazoom
rst 0
 
Mensajes: 12
Registrado: Lun Oct 05, 2015 8:42 am

Re: z88dk, uso de memoria

Notapor Alcoholics Anonymous el Mar Abr 18, 2017 6:27 am

Éste puede ser difícil para la traducción automática así que el inglés original aparecerá debajo del español traducido.

saimazoom escribió:Estoy intentando separar en mi juego el código del motor y de las fases. La intención es paginar en 128Kb las fases pero manteniendo el motor por debajo de la 0xC000. He intentado lo siguente:


Hay una manera mucho mejor de hacer esto usando SECTIONs que voy a explicar en el próximo post, pero primero algunos comentarios sobre lo que está haciendo.

1) Primero compilo el motor
Código: Seleccionar todo
zcc +zx ..\libgfx\libgfx.c parser.c juego_compressed.c -o juego.bin -vn -O3 -startup=31 -lfzx -lfzxfonts_utz -m -lzx7



Hay una cierta confusión aquí. "-startup = 31" sólo funciona con la nueva biblioteca C en Z88DK y la nueva biblioteca C sólo se selecciona si aparece "-clib = new", "-clib = sdcc_ix" o "-clib = sdcc_iy" en la línea de compilación. En la nueva librería c, "-startup = 31" elige el código de inicio sin ningún terminal conectado a stdin, stdout, stderr, que es lo que normalmente quieres para juegos.

La nueva biblioteca C y la biblioteca C clásica existen separadamente en z88dk. Cada uno tiene su propio código de puesta en marcha y su propio código de biblioteca. La nueva biblioteca c también contiene FZX, ZX7 y todas las fuentes FZX (incluyendo UTZ) ya, por lo que no es necesario vincularlos o proporcionarlos por separado. Por otro lado, la biblioteca clásica sólo tiene ZX7 y debe ser proporcionado con el resto por separado.

En la compilación anterior está utilizando la clásica biblioteca C y que no define "-startup = 31". No estoy seguro de cómo lo está haciendo funcionar sin errores? La biblioteca C clásica no tiene la opción de desconectar terminales, pero el código de terminal es también muy pequeño cuando no se utilizan.

There is some confusion here. "-startup=31" only works with the new C library in Z88DK and the new C library is only selected if "-clib=new", "-clib=sdcc_ix" or "-clib=sdcc_iy" appears on the compile line. In the new c library, "-startup=31" chooses start up code without any terminals attached to stdin, stdout, stderr which is what you usually want for games.

The new C library and the classic C library exist separately within z88dk. They each have their own start up code and their own library code. The new c library also contains FZX, ZX7 and all the FZX fonts (including UTZ's) already so it's not necessary to link or provide those separately. On the other hand, the classic library only has ZX7 and must be provided with the rest separately.

In the compile above you are using the classic C library and that does not define "-startup=31". I'm not sure how you are getting it to work without errors? The classic C library does not have an option to switch off terminals but the terminal code is also very small when they are not used.


===

Dicho esto, vamos a compilar con la biblioteca clásica. El primer paso es que desea hacer un binario que contiene su motor solamente.

Para hacer eso:
zcc +zx --no-crt ..\libgfx\libgfx.c parser.c juego_compressed.c -o juego.bin -vn -O3 -lfzx -lfzxfonts_utz -lzx7 -gp -m

Necesitará una versión muy reciente de z88dk para usar "-gp" ya que esta característica apareció después de 1.99B. O bien una nightly build o una actualización a través de github. Si ejecuta "zcc -h" debería ver "-g Genera un archivo defc global del ejecutable final (-g, -gp, -gpf nombrearchivo)" en las opciones listadas.

"--no-crt" significa que no habrá c código de inicio en la salida. No habrá llamada a main () pero tampoco inicialización de variables. Puesto que está compilando en ram todas las variables que ha definido deben tener sus valores iniciales correctos. Si usted o la biblioteca necesita ejecutar el código de inicialización, tendrá que escribir una función de inicialización por separado suministrando un CRT o una rutina separada para hacerlo.

"-gp" producirá un archivo especial ".def" con símbolos. Éste define todos los símbolos públicos con las exportaciones ("PUBLIC foo; defc foo = ...") que está listo para su uso en otras compilaciones.

No querrá que se exporten todos esos símbolos. Así que usted querrá especificar cuáles desea mantener. Puede hacerlo suministrando un "archivo de coincidencia" que contiene una lista de expresiones regulares, una por línea. zcc coincidirá con los nombres de los símbolos con ese archivo para determinar cuáles desea en el archivo .def.

Como ejemplo, le mostraré un simple archivo "match.txt" que contiene una expresión regular por línea:

"match.txt"
Código: Seleccionar todo
-_printf_
+_printf
; a comment
+asm_
-[.]*


Las líneas que comienzan con "+" significan aceptar, "-" significan rechazar y ";" Significa ignorar

Las dos primeras líneas aceptarán sólo el símbolo "_printf". La cuarta línea aceptará cualquier símbolo que comience con "asm" y la última línea rechazará todo lo demás.

ZCC pasará por esas reglas para cada símbolo y se detendrá cuando encuentre una coincidencia.

Para utilizar este archivo de reglas:
zcc +zx --no-crt ..\libgfx\libgfx.c parser.c juego_compressed.c -o juego.bin -vn -O3 -lfzx -lfzxfonts_utz -lzx7 -gpf match.txt -m

Ahora verá que el archivo .def se elimina sólo a los símbolos que desea exportar.

That said, let's compile with the classic library. The first step is you want to make a binary containing your engine only.

To do that:
zcc +zx --no-crt ..\libgfx\libgfx.c parser.c juego_compressed.c -o juego.bin -vn -O3 -lfzx -lfzxfonts_utz -lzx7 -gp -m

You will need a very recent version of z88dk to use "-gp" since this feature appeared after 1.99B. Either a nightly build or update via github. If you run "zcc -h" you should see "-g Generate a global defc file of the final executable (-g, -gp, -gpf filename)" in the listed options.

"--no-crt" means there will be no c start up code in the output. There will be no call to main() but also no initialization of variables. Since you are compiling into ram any variables you have defined should have their correct initial values. If you or the library needs to run initialization code, you will have to write a separate initialization function by either supplying a CRT or a separate routine to do so.

"-gp" will produce a special ".def" file with symbols. This one defines all your public symbols with exports ("PUBLIC foo ; defc foo = ...") that is ready for use in other compiles.

You won't want all those symbols exported. So you will want to specify which ones you want to keep. You can do that by supplying a "match file" that contains a list of regular expressions, one per line. zcc will match symbol names to that file to determine which ones you want in the .def file.

As an example, I will show you a simple "match.txt" file containing one regular expression per line:

"match.txt"
Código: Seleccionar todo
-_printf_
+_printf
; a comment
+asm_
-[.]*


Lines beginning with "+" mean accept, "-" mean reject and ";" mean ignore.

The first two lines will accept the "_printf" symbol only. The fourth line will accept any symbols beginning with "asm" and the last line will reject everything else.

ZCC will go through those rules in order for each symbol and stop when it finds a match.

To use this rule file:
zcc +zx --no-crt ..\libgfx\libgfx.c parser.c juego_compressed.c -o juego.bin -vn -O3 -lfzx -lfzxfonts_utz -lzx7 -gpf match.txt -m

Now you will see the .def file is pruned down to only the symbols you want to export.


2) Luego intento compilar la fase, pero me devuelve el error de que no existe el símbolo de _main y el resto de símbolos de las funciones del motor.

Código: Seleccionar todo
zcc +zx juego_pagina0_compressed.c -o juego_pagina0_.bin -vn -O3



Para compilar contra esos símbolos, agregue el archivo .def a la compilación como un archivo asm (debe cambiar el nombre del archivo con la extensión .asm):
zcc +zx juego_pagina0_compressed.c juego.def.asm -o juego_pagina0_.bin -vn -O3

Sin embargo, como he dicho esto no es la mejor manera de hacer esto. Use SECTIONs en su lugar (próxima entrada si tengo tiempo esta noche).
Alcoholics Anonymous
rst 0
 
Mensajes: 21
Registrado: Lun Feb 04, 2008 7:16 am

Re: z88dk, uso de memoria

Notapor Alcoholics Anonymous el Mar Abr 18, 2017 7:03 am

No voy a tener tiempo para describir enteramente SECCIONES esta noche, pero voy a describir brevemente y luego darle un ejemplo de su uso en el juego Pietro Bros.

SECTIONs son contenedores en los que el ensamblador coloca código y datos. Se especifica la SECTION en la que desea que se coloque el código y los datos y, a continuación, en el paso de vinculación, se proporciona un mapa de memoria que indica al vinculador qué direcciones se asignan a dichas SECTIONs.

En un juego de 128k puedes definir SECTIONs para cada banco de memoria de 16k y luego puedes asignar código y datos a esas secciones.

Pietro Bros (source code) está usando la nueva biblioteca C para compilar. Especifica varias opciones para la CRT de la nueva biblioteca C en el archivo zpragma.inc

I will not have time to fully describe SECTIONs tonight but I will briefly describe them and then give you an example of its use in the game Pietro Bros.

SECTIONs are containers into which the assembler places code and data. You specify which SECTION you want your code and data to be placed into and then in the linking step, you provide a memory map that tells the linker to what addresses those SECTIONs are mapped.

In a 128k game you might define SECTIONs for each 16k memory bank and then you can assign code and data to those sections.

Pietro Bros (source code) is using the new C library to compile. It specifies several options to the new C library's CRT in the file zpragma.inc


Código: Seleccionar todo
// DEFINE OWN MEMORY MAP

#pragma output __MMAP                = -1         // memory map is provided in file "mmap.inc"

// COMPILE TIME CRT CONFIGURATION

#pragma output CRT_ORG_CODE          = 23552      // org of compile
#pragma output REGISTER_SP           = -1         // crt will not change stack location; loader sets sp

#pragma output CRT_ENABLE_CLOSE      = 0          // don't bother closing files on exit
#pragma output CRT_ENABLE_EIDI       = 0          // don't di on start or exit; loader does di before start
#pragma output CRT_ON_EXIT           = 0          // jump to address 0 at exit

#pragma output CLIB_MALLOC_HEAP_SIZE = 0          // no malloc heap
#pragma output CLIB_STDIO_HEAP_SIZE  = 0          // no stdio heap (no files)

#pragma output CLIB_FOPEN_MAX        = -1         // no FILE* list
#pragma output CLIB_OPEN_MAX         = -1         // no fd table


En particular "__MMAP = -1" le dice al CRT que proporcionará el mapa de memoria en el archivo mmap.inc. Así es como Pietro Bros controla donde se coloca todo en la memoria.

"Mmap.inc" es una modificación de mapa de memoria estándar de Z88DK. En el archivo "mmap.inc" de Pietro Bro se definen varias secciones nuevas:

* MCLOAD para colocar el código del cargador inicial en la pantalla en la dirección 16384
* LOADER para colocar el código del cargador principal en la dirección 23296
* BANK_06 para definir un banco de memoria de 128 KB en la dirección 0xc000 para almacenar música y datos AY
* NIRVANA_HOLE para colocar cosas en un agujero dejado por el motor nirvana. El mapa de memoria C estándar se modifica para colocar las variables de RAM del programa en ese agujero.
* CODE contiene el código principal del programa en la dirección 23552.

Es muy fácil colocar ASM o código C y datos en una sección específica.

Para ASM un ejemplo:

In particular "__MMAP = -1" tells the CRT that you will provide the memory map in the file mmap.inc. This is how Pietro Bros controls where everything is placed in memory.

"mmap.inc" is a modification of Z88DK's standard memory map. In Pietro Bro's "mmap.inc" file several new sections are defined:

* MCLOAD to place the initial loader code into the screen at address 16384
* LOADER to place the main loader code at address 23296
* BANK_06 to define a 128k memory bank at address 0xc000 to hold AY music and data
* NIRVANA_HOLE to place stuff in a hole left by the nirvana engine. The standard C memory map is modified to place the program's ram variables in that hole.
* CODE contains the program's main code at address 23552.

It's very easy to place ASM or C code and data into a specific section.

For ASM an example:


Código: Seleccionar todo
SECTION BANK_06

PUBLIC _myfunc

myfunc:

   ld hl,10
   ret

some_data:
   defb 0,0,0


Todo lo anterior se agregará a la sección BANK_06.

Para C, hay que saber que el compilador colocará código y datos en diferentes secciones: CODE (código de sólo lectura), RODATA (datos de sólo lectura), DATA (código de modificación automática, variables no inicialmente cero) y BSS ). Normalmente los nombres de sección que utiliza son "code_compiler", "rodata_compiler", "data_compiler" y "bss_compiler". La colocación de estas secciones se define en el mapa de memoria estándar suministrado por Z88DK.

Puede cambiar las secciones en las que el compilador coloca estos elementos en una granularidad de archivo en la línea de compilación usando las opciones "--codeseg CODE_NAME" "--constseg RODATA_NAME" "--dataseg DATA_NAME" "--bssseg BSS_NAME". Por ejemplo, "--codeseg BANK_06 --constseg BANK_06" pondrá el código C y datos constantes en la SECCIÓN BANK_06.

Zsdcc sólo puede hacer --codeseg y --constseg en este momento, pero sccz80 puede hacer todas las secciones.

All of the above will be added to the BANK_06 section.

For C, you have to know that the compiler will place code and data into different sections: CODE (read only code), RODATA (read only data), DATA (self modifying code, variables not initially zero) and BSS (initially zero variables). Normally the section names it uses are "code_compiler", "rodata_compiler", "data_compiler" and "bss_compiler". The placement of these sections is defined in the standard memory map supplied by Z88DK.

You can change the sections that the compiler places those items into on a file granularity on the compile line using options "--codeseg CODE_NAME" "--constseg RODATA_NAME" "--dataseg DATA_NAME" "--bssseg BSS_NAME". For example, "--codeseg BANK_06 --constseg BANK_06" will put the C code and constant data into SECTION BANK_06.

zsdcc can only do the --codeseg and --constseg at this time but sccz80 can do all sections.
Alcoholics Anonymous
rst 0
 
Mensajes: 21
Registrado: Lun Feb 04, 2008 7:16 am

Re: z88dk, uso de memoria

Notapor saimazoom el Mar Abr 18, 2017 5:16 pm

Thanks a lot for the answer. It is really helping me to understand how z88dk works internally. I need to play a bit with the different options, but I think ultimately I would manage to see through.
saimazoom
rst 0
 
Mensajes: 12
Registrado: Lun Oct 05, 2015 8:42 am

Re: z88dk, uso de memoria

Notapor Alcoholics Anonymous el Mie Abr 19, 2017 2:38 am

I will just add how you can use sections to place your engine code in a specific block of memory.

Código: Seleccionar todo
zcc +zx -c ..\libgfx\libgfx.c parser.c juego_compressed.c -o juego -vn -O3 --codeseg=ENGINE --constseg=ENGINE --dataseg=ENGINE --bssseg=ENGINE


This makes a an object file "juego.o" rather than a binary. If you run:

Código: Seleccionar todo
z80nm juego.o | more


you will see everything in the object file, including section placement.

Then add the object file to your compile:

zcc +zx sections.asm juego_pagina0_compressed.c juego.o -o juego_pagina0_.bin -vn -O3

where "sections.asm" is file defining the ENGINE section:

Código: Seleccionar todo
SECTION ENGINE
org 0xc000
defb 0


I have the "defb 0" there because z80asm will ignore the file if it is empty.

After the compile you will have two binaries: the usual "juego_pagina0_.bin" and "juego_pagina0_ENGINE.bin". The "*_ENGINE.bin" is ORGed at 0xc000 and should be loaded separately.

You can also make a library out of your engine code in a similar manner. The difference is the object file will cause all code to be attached to your output binary whereas a library will cause only referenced functions to be added to your output binary.

Usually I'd prefer to have the sections defined in "sections.asm" to be included in the CRT but the classic library has no way to do this aside from you replacing the library's CRT with your own.


There is one major difference between compiling your engine to a binary and compiling to an object file.

The binary, produced by:
zcc +zx --no-crt ..\libgfx\libgfx.c parser.c juego_compressed.c -o juego.bin -vn -O3 -lfzx -lfzxfonts_utz -lzx7 -gpf:match.txt -m

will contain all the code the engine needs. Ie, it will be completely self-contained and will not call anything outside of its own code.

However the object file:
zcc +zx -c ..\libgfx\libgfx.c parser.c juego_compressed.c -o juego -vn -O3 --codeseg=ENGINE --constseg=ENGINE --dataseg=ENGINE --bssseg=ENGINE

will contain only the engine code and data itself and will assigned only that code and data to section ENGINE. If the engine code calls zx7 or fzx functions, for example, those calls are resolved at link time when the binary is built:

zcc +zx sections.asm juego_pagina0_compressed.c juego.o -o juego_pagina0_.bin -vn -O3 -lfzx -lzx7 -lndos

The zx7 and fzx functions will not be in section ENGINE (unless those libraries were built placing them there) and instead the engine code will call outside the ENGINE section to those functions. This can be important if, for example, the ENGINE section is in another memory bank and the zx7/fzx code is not accessible when the ENGINE bank is active. For this reason, commonly accessible functions should be kept below 0xc000 so that they are accessible to code placed in different memory banks.

I hope that helps!
Alcoholics Anonymous
rst 0
 
Mensajes: 21
Registrado: Lun Feb 04, 2008 7:16 am

Re: z88dk, uso de memoria

Notapor saimazoom el Mie Abr 19, 2017 9:02 am

Is working!. Today I was able to load the different pages and execute code from them and make callbacks to the engine. So far I'm using the first approach. I'll delve into sections for the next development :), I think is a better solution. I'll like to give you credit in the game, Shall I use the forum nick?.
saimazoom
rst 0
 
Mensajes: 12
Registrado: Lun Oct 05, 2015 8:42 am

Re: z88dk, uso de memoria

Notapor Alcoholics Anonymous el Mie Abr 19, 2017 7:10 pm

saimazoom escribió:Is working!. Today I was able to load the different pages and execute code from them and make callbacks to the engine. So far I'm using the first approach.


¡Que bueno escuchar eso! Creo que probablemente eres la primera persona en hacerlo de esta manera. Esa función "-gpf" se puso en este sentido, pero la mayoría de los problemas de los bancos se pueden resolver más fácilmente con las secciones.

La cosa "-gpf" es parte de un trampolín para conseguir que la cadena de herramientas genere automáticamente programas con conmutación bancaria. Los otros son las opciones de línea de comandos "--codeseg, --constseg, --dataseg, --bssseg" para que el compilador cambie el nombre de la sección (esto se implementa para sccz80 y parcialmente para sdcc) y para cambiar las secciones dentro de fuente C con Pragmas (no hecho todavía).

Si está interesado en probar una compilación sdcc, para la biblioteca c clásica sólo tiene que agregar "-compiler=sdcc -SO3 --max-allocs-per-node200000 --reserve-regs-iy --fsigned-char"A la línea de compilación. Si está utilizando Windows o OSX, z88dk proporciona el binario zsdcc, pero otros tienen que crear zsdcc por separado. El alto nivel de optimización (-max-allocs-per-node) hará que la compilación sea muy lenta por lo que si tiene un programa grande no se sorprenda si tarda 10-15 minutos. Es posible que desee utilizar "-v" en lugar de "-vn" para que pueda ver lo que está pasando. Sdcc es particularmente bueno si utiliza variables "unsigned char" siempre que sea posible.

Sdcc compilación con la biblioteca clásica es sólo salir de experimental por lo que si lo intentas y funciona, hágamelo saber. Todas estas cosas fueron diseñadas en la nueva biblioteca c desde cero por lo que el clásico ahora se está poniendo al día.

Nice to hear! I think you are probably the first person to actually do it this way. That "-gpf" feature was put in for this purpose but most bankswitching problems can be solved more simply with sections.

The "-gpf" thing is part of a stepping stone toward getting the toolchain to automatically generate bankswitched programs. The others are the command line options "--codeseg, --constseg, --dataseg, --bssseg" to have the compiler change section name (this is implemented for sccz80 and partially for sdcc) and to change sections within C source with pragmas (not done yet).

If you are interested in trying an sdcc compile, for the classic c library just add "-compiler=sdcc -SO3 --max-allocs-per-node200000 --reserve-regs-iy --fsigned-char" to the compile line. If you are using Windows or OSX, z88dk provides the zsdcc binary but others have to build zsdcc separately. The high optimization level (--max-allocs-per-node) will cause the compile to be very slow so if you have a large program don't be surprised if it takes 10-15 minutes. You may want to use "-v" instead of "-vn" so you can see what is going on. sdcc is particularly good if you use "unsigned char" variables where possible.

sdcc compilation with the classic library is just getting out of experimental so if you try it and it works, let me know. All these things were designed into the new c library from scratch so the classic is now catching up.


I'll like to give you credit in the game, Shall I use the forum nick?.


Gracias :) Puedes usar "Alcoholics Anonymous" o "AA" o "aa@z88dk.org" o "@z88dk" o alguna variación de eso, lo que sea mejor.
Alcoholics Anonymous
rst 0
 
Mensajes: 21
Registrado: Lun Feb 04, 2008 7:16 am

Re: z88dk, uso de memoria

Notapor saimazoom el Vie May 05, 2017 9:54 pm

Veamos, tengo un problema en los modelos de +2A y +3 cuando pagino. Básicamente el spectrum se cuelga, esto no me pasa en otros modelos de 128K (e incluso el Pentagon y Scorpion). Me sucede sólo en Spectaculator pero no en ZXSpin. En ZXSpin el juego funciona bien en los modelos +2A y +3. ¿Qué podría ser?. ¿Tiene alguien un modelo real +3/+2A a mano para hacer una prueba?. Gracias.
saimazoom
rst 0
 
Mensajes: 12
Registrado: Lun Oct 05, 2015 8:42 am

Re: z88dk, uso de memoria

Notapor Alcoholics Anonymous el Sab May 06, 2017 5:07 am

¿Tienes el registro "I" apuntando hacia la memoria contended? Algunos modelos de 128 k pueden bloquearse si el "I" registra puntos en un área contended. Esto incluye establecer "I" para apuntar en direcciones mayores que 0xc000 y tener un banco de memoria contended paginado pulg El conjunto de bancos de memoria que se sostienen son diferentes para el + 2A / + 3 y el otro 128k modelos por lo que creo que esto Puede ser su problema.

Es más fácil tener su rutina de interrupción ubicada en 0x8000 -> 0xbffff para evitar estos problemas.
Alcoholics Anonymous
rst 0
 
Mensajes: 21
Registrado: Lun Feb 04, 2008 7:16 am


Volver a Programación y nuevos desarrollos

¿Quién está conectado?

Usuarios navegando este Foro: Ivanzx y 3 invitados