¿qué está mal en este código?

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

¿qué está mal en este código?

Mensaje por Uto » 29 Abr 2017, 01:50

La idea es tener un codigo que pueda ejecutarse al arrancar el ZX1 antes que el firmware, pensando en meter algun cambio que luego el firmware no toca (ni las ROM al arrancar). Cosas como enviar algo al PS/2 arduino del UnoGomas y cosas así. Además la idea es poder poner este "prefirmware" facilmente a cualquier firmware que salga, sin tener que recompilar, solo con el fichero firmware.ZX1. Concatenaríamos el output de este programa y el firmware.ZX1 y luego recortamos el fichero a 16K.

En el código lo que pretendo hacer es que al arrancar el ZX-Uno, coja toda la ROM y la copie en $8000. Luego pagino con mastermapper la System ROM 0 en $C000 y copio en $C000 el trozo de ese firmware que es el original, quitando el "preparche" de modo que en $0000 pase a estar el firmware original y en $c000 también, y luego hago un RST 0 para ejecutar el firmware original.

En este código el preparche no hace nada, la zona de hacer cosas está vacía, pero no me va en ZesarUX y no he conseguido nunca que haga debug ZesarUX de la ROM BIOS por lo que ando un poco a ciegas y no sé que puede ser:

Código: Seleccionar todo

            output  prefirmware.bin

            define  zona_alta $8000     ; 32768
            define  zxuno_port $FC3B 
            define  MASTERMAPPER 1
            

            ; ********* Copiamos la ROM en RAM *****************
start       ld hl,  0
            ld de,  zona_alta                
            ld bc,  $4000                ; 16K
            ldir 
            jp zona_alta + highStart    ; salta a la siguiente instrucción pero en la copia en RAM

            ; ********* Copiamos la ROM BIOS original sin el preparche en la ROM *****************
highStart   
            ld  bc, zxuno_port          ; Mapea System ROM en $C000
            ld a, MASTERMAPPER
            out (c), a           
            inc b
            ld  a, 9                    ; RAM slot 9, System ROM 1
            out (c), a

            ld hl, $8000 + endpf        ; Copia toda la ROM restante (todo menos la pre-firmware) que tengo en $8000 en $C000 (que es donde está mapeada la ROM)
            ld de, $C000                
            ld bc, $4000 - endpf
            ldir

            ld  bc, zxuno_port          ; MAP again bank 0 at $C000
            ld a, MASTERMAPPER
            out (c), a           
            inc b
            xor  a                       ; Slot 0                    
            out (c), a
            ; ******************** Aquí es donde realmente van las rutinas del prefirmware ****************
            ; ******************** Este prefirmware podría  usar las rutinas RST de la ROM de Antonio porque este ya está en su sitio ****************
preFirmware 
            



restart      rst 0
endpf  ; Aqui empezaría el firmware orginal
Última edición por Uto el 29 Abr 2017, 09:41, editado 1 vez en total.

Avatar de Usuario
mcleod_ideafix
Mensajes: 831
Registrado: 27 Sep 2015, 00:14
Ubicación: Jerez de la Frontera
Contactar:

Re: ¿qué está mal en este código?

Mensaje por mcleod_ideafix » 29 Abr 2017, 02:01

Para poder usar MASTERMAPPER, el bit BOOTM debe valer 1. Cuando ese bit está a 1 el espacio de memoria de la CPU es el siguiente:
0000-3FFF : ROM interna del core (no la BIOS, sino la pequeña ROM que a su vez carga la BIOS)
4000-7FFF : pagina 2 de la SRAM
8000-BFFF : pagina 0 de la SRAM
C000-FFFF : pagina seleccionada por MASTERMAPPER

Cuando la BIOS de Antonio arranca, lo hace con BOOTM=0, pero LOCK también vale 0, así que se puede cambiar desde software el bit BOOTM de nuevo a 1 y así acceder a MASTERMAPPER.

Pero ojo! porque en el momento en que se pone BOOTM a 1, lo que se pagina en el área $0000-$3FFF es de nuevo la ROM interna del core, así que la BIOS deja de estar visible. Cuando Antonio necesita acceder a MASTERMAPPER, debe hacerlo en código en RAM: copia la rutina que sea desde BIOS hasta RAM, la ejecuta en RAM, y desde la misma RAM vuelve a poner BOOTM a 0 para volver a poder saltar a la BIOS.

Por lo que leo, tú empiezas bien, copiando ROM en RAM, pero creo que te ha faltado, una vez que estás en RAM, activar el bit BOOTM para ponerlo a 1 y así poder usar MASTERMAPPER.
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: ¿qué está mal en este código?

Mensaje por Uto » 29 Abr 2017, 08:52

Cierto, no sé por qué he pensado que MASTERMAPPER ya era utilizable de serie. Lo que está pasando es que no reescribo la BIOS por lo cual entro en bucle sin fin. A ver si puedo probarlo más tarde.

Lo que no tengo tan claro es dónde está la página 2 de la SRAM cuando MSTERMAPPER está inhabilitado. Parece ser la única página que tengo para hacer el cambio y que es accesible tanto con MASTERMAPPER habilitado como inhabilitado. ¿Está también en $4000 o en $8000?

¡gracias!

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: ¿qué está mal en este código?

Mensaje por Uto » 29 Abr 2017, 12:37

Quizá lo esté haciendo muy complicado usando mastermapper. ¿en modo Boot puedo escribir en $0000-$3999? Si es así la cosa es simple, se copia toda la ROM en RAM, se salta a seguir ejecutando en RAM y luego se copia la RAM en ROM quintando el preparche y RST 0.

Voy a probar.

Avatar de Usuario
mcleod_ideafix
Mensajes: 831
Registrado: 27 Sep 2015, 00:14
Ubicación: Jerez de la Frontera
Contactar:

Re: ¿qué está mal en este código?

Mensaje por mcleod_ideafix » 29 Abr 2017, 16:17

Uto escribió:¿en modo Boot puedo escribir en $0000-$3999?
No. Con BOOTM=1, el espacio entre 0000 y 3FFF es la ROM interna del core. No hay RAM "por debajo" de ella. Para eso está MASTERMAPPER: para paginar cualquier bloque de 16KB de la SRAM en el espacio C000-FFFF
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: ¿qué está mal en este código?

Mensaje por Uto » 30 Abr 2017, 02:08

Vuelvo a poner el código modificado, que me sigue sin funcionar, al menos en ZesarUX. En este mismo emulador veo que no consigo sobreescribir la ROM BIOS.


Recuerdo lo que quiero hacer:
0) Tengo una BIOS grabada en flash que es una concatenación de mi código (unos 50 bytes) y una BIOS normal (la 0.61 por ejemplo), truncado a 16K (que no pasa nada porque a la BIOS le sobran más de los ~50 bytes que le pongo por delante).
1) Nada mas empezar copio la ROM en RAM (de $0000 a $4000, 16K, esto funciona a juzgar por lo que se ve en la pantalla)
2) Salto la ejecución a esa copia en la RAM para seguir
3) Ya ejecutándome en RAM activo BOOTM y pagino la pagina 8 de la SRAM (System ROM 0) en $C000
4) Copio desde $4000 + la longitud de mi codigo a $C000, con una longitud de 16K menos los ~50 bytes de mi rutina. Esto debería copiar en el banco de la ROM lo que es el firmware original sin mi "preparche".
5) Desactivo BOOTM con lo que volvemos a la paginación normal.
6) Hago un RST 0 para forzar que se ejecute de nuevo la ROM desde el principio

En teoría como se ha copiado la BIOS normal a la ROM, debería arrancar con la BIOS habitual, pero no pasa, aparentemente sigue la misma BIOS ahí con mi preparche, y por tanto vuelvo a ejecutar mi preparche en bucle sin fin. Esto se ven el el debugger de ZesarUX (salta todo el rato de $0000 a $4000 y vuelta) y se ve si pongo unos out 254 para el borde, que cambia todo el rato.

He aquí el código, que intencionadamente no tiene ninguna optimización para que se vea muy claro. Cuando me funcione, ya optimizaré :-D

Código: Seleccionar todo

            output  prefirmware.bin

            define  zona_alta $4000     
            define  zxuno_port $FC3B 
            define  MASTERCONF 1
            define  MASTERMAPPER 1
            

            ; ********* Copiamos la ROM en RAM *****************
start       ld hl, 0
            ld de,  zona_alta                
            ld bc,  $4000                ; 16K
            ldir 
            jp zona_alta + highStart    ; salta a la siguiente instrucción pero en la copia en RAM

            
highStart   


            ; ********* Activamos BOOTM y con ello MASTERMAPPER *****************


            ld  bc, zxuno_port
            ld a, MASTERCONF
            out (c), a           
            inc b
            ld  a, 1                    
            out (c), a

            ; ********* Mapea System ROM 0 en $C000 *****************

            ld  bc, zxuno_port
            ld a, MASTERMAPPER
            out (c), a   
            inc b
            ld  a, 8
            out (c), a

            ; ********* Copiamos el código original de la BIOS en $C0000 *****************            

            ld hl, $8000 + endpf      
            ld de, $C000
            ld bc, $4000 - endpf
            ldir

            ; ********* Mapea Bank RAM 0 en $C000 ***************** ESTO PROBABLEMENTE NO HACE FALTA

            ld  bc, zxuno_port
            ld a, MASTERMAPPER
            out (c), a   
            inc b
            xor a
            out (c), a


            ; ********* Deshabilitamos master mapper y todo queda igual *****************            

            ld  bc, zxuno_port          
            ld a, MASTERCONF
            out (c), a           
            inc b
            xor  a
            out (c), a


            ; ******************** Aquí es donde realmente van las rutinas del prefirmware ****************
            ; ******************** Este prefirmware podría  usar las rutinas RST de la ROM de Antonio porque este ya está en su sitio ****************
preFirmware 
            



restart    rst 0
endpf  ; Aqui empezaría el firmware orginal

Avatar de Usuario
mcleod_ideafix
Mensajes: 831
Registrado: 27 Sep 2015, 00:14
Ubicación: Jerez de la Frontera
Contactar:

Re: ¿qué está mal en este código?

Mensaje por mcleod_ideafix » 01 May 2017, 01:17

Uto escribió:

Código: Seleccionar todo

            output  prefirmware.bin

            define  zona_alta $4000     
            define  zxuno_port $FC3B 
            define  MASTERCONF 1
            define  MASTERMAPPER 1
El registro MASTERCONF es el 0, no el 1.
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: ¿qué está mal en este código?

Mensaje por Uto » 01 May 2017, 01:28

mcleod_ideafix escribió:
Uto escribió:

Código: Seleccionar todo

            output  prefirmware.bin

            define  zona_alta $4000     
            define  zxuno_port $FC3B 
            define  MASTERCONF 1
            define  MASTERMAPPER 1
El registro MASTERCONF es el 0, no el 1.
Joder menuda cagada jajaja, maldito copy paste.

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: ¿qué está mal en este código?

Mensaje por Uto » 01 May 2017, 01:55

Ya me funciona, gracias por los comentarios. Había otro pequeño bug aparte del define MASTERCONF, pero una vez pasado ese punto la cosa ha ido bien.

Dejo aquí el código final junto con una explicación de por qué esto:

Imaginad que tenéis una cosa que queréis que haga vuestro ZX-Uno al arrancar, parece que un punto ideal para hacerlo es la BIOS. Por supuesto podéis coger el código de la BIOS y modificarlo, pero eso obliga a hacerlo a cada versión nueva de la BIOS que salga, lo cual es un poco rollo.

Con este invento generáis el código que queréis ejecutar (poniendolo entre la etiqueta preFirmware y el RST 0 que hay al final) y compilais, lo cual os dará el prefirmware.bin. Ahora concatenais prefirmware.bin y cualquier FIRMWARE.ZX1, el que sea, y luego lo recortáis a 16384 bytes (yo lo hago con truncate en linux, pero podéis usar el fcut.exe que hay en el repo desde windows). Al resultado lo volvéis a llamar FIRMWARE.ZX1 y ya está, ya tenéis el último firmware parcheado con los mismos cambios. Si sale otro firmware, solo volveis a concatenar y cortar y ya está.

¿Y para qué? Pues probablemente para poca cosa, porque aunque molaría poder usarlo para configurar alguna cosa en el ZX-Uno me temo que la BIOS que se ejecuta después machacaría casi todos vuestros cambios, así que poco se puede hacer.

Mi idea es algo que me vale para el proyecto del ZX-Uno dentro de teclado de gomas con arduino, que pasa por enviar algún scan code especial al arduino, pero aun tengo que probarlo. Quien sabe, lo mismo algún día os vale a alguno, aquí queda.

¡Ah! El código tiene 0 optimización, y muuucho que optimizar, pero prefiero ponerlo en esta versión que es más legible.

Código: Seleccionar todo

            output  prefirmware.bin

            define  zona_alta $8000     
            define  zxuno_port $FC3B 
            define  MASTERCONF 0
            define  MASTERMAPPER 1
            

            ; ********* Copiamos la ROM en RAM *****************
start       ld hl, 0
            ld de,  zona_alta                
            ld bc,  $4000                ; 16K
            ldir 
            jp zona_alta + highStart    ; salta a la siguiente instrucción pero en la copia en RAM
            
highStart   
            ; ********* Activamos BOOTM y con ello MASTERMAPPER *****************

            ld  bc, zxuno_port
            ld a, MASTERCONF
            out (c), a           
            inc b
            ld  a, 1                    
            out (c), a

            ; ********* Mapea System ROM 0 en $C000 *****************

            ld  bc, zxuno_port
            ld a, MASTERMAPPER
            out (c), a   
            inc b
            ld  a, 8
            out (c), a

            ; ********* Copiamos el código original de la BIOS en $C0000 *****************            

            ld hl, zona_alta + endpf     ; Desde detrás de este código 
            ld de, $C000                 ; a $C000
            ld bc, $4000 - endpf         ; Y una longitud de 16K menos la longitud de este código
            ldir


            ; ********* Deshabilitamos master mapper y todo queda igual *****************            

            ld  bc, zxuno_port          
            ld a, MASTERCONF
            out (c), a           
            inc b
            xor  a
            out (c), a

            ; ******************** Aquí es donde realmente van las rutinas del prefirmware ****************
            ; ******************** Este prefirmware podría  usar las rutinas RST de la ROM de Antonio porque este ya está en su sitio ****************
preFirmware 
            


restart    rst 0
endpf       ; ********************* Aqui empezaría el firmware original *************************

Avatar de Usuario
Uto
Mensajes: 1394
Registrado: 17 Dic 2015, 16:39

Re: ¿qué está mal en este código?

Mensaje por Uto » 02 May 2017, 20:53

Hmmm... estoy mirando un fichero FIRMWARE.ZX1 y aunque le sobra mucho espacio no parece que le sobre al final, al final parece que hay algo. Mirando el fuente veo varios pseudonemonicos BLOCK que colocan cosas en sitios específicos.

Esto hace que simplemente concatenar el prefirmware con el firmware y cortar a 16K probablemente no funcione. Imagino que algo parecido se podría hacer comprimiendo el firmware antes de concatenarlo, y luego descomprimiendolo en lugar de simplemente copiarlo en la ROM. No es que sea mucho más complicado, pero se puede hacer.

Ya por mera curiosidad ¿por qué? :-?

Responder