Cómo restaurar el firmware (y no morir en el intento)
Reglas del Foro
Debido a que hay varios temas pidiendo ayuda para programar en ensamblador máquinas distintas al Amstrad CPC, con micro distinto al Z80 y que incluso dependen del sistema operativo, nos vemos en la necesidad de poner por escrito que estos posts son bienvenidos pero que no es el lugar adecuado ya que por estos lares nos dedicamos más al ensamblador del Z80, un microprocesador de 8 bits que tuvo su gran auge en ordenadores y consolas de los años 80.
De todas formas, esto no quita que alguien que sepa del asunto pueda postear alguna respuesta pero es más fácil encontrar foros dedicados a programar en ensamblador en Windows o MS-DOS que ayudarán más que nosotros:
http://www.lawebdelprogramador.com/news ... nsamblador
Debido a que hay varios temas pidiendo ayuda para programar en ensamblador máquinas distintas al Amstrad CPC, con micro distinto al Z80 y que incluso dependen del sistema operativo, nos vemos en la necesidad de poner por escrito que estos posts son bienvenidos pero que no es el lugar adecuado ya que por estos lares nos dedicamos más al ensamblador del Z80, un microprocesador de 8 bits que tuvo su gran auge en ordenadores y consolas de los años 80.
De todas formas, esto no quita que alguien que sepa del asunto pueda postear alguna respuesta pero es más fácil encontrar foros dedicados a programar en ensamblador en Windows o MS-DOS que ayudarán más que nosotros:
http://www.lawebdelprogramador.com/news ... nsamblador
Cómo restaurar el firmware (y no morir en el intento)
Pongo esto aquí porque me parece interesante y porque no lo he visto en ningún otro sitio.
Cuando se programa cualquier cosa de cierta envergadura para el Amstrad lo habitual es "cargarse" el firmware y usar funciones dedicadas para escribir en pantalla, leer el teclado, manejar las interrupciones (o simplemente ignorarlas), etc. Estas funciones son menos versátiles que las del firmware, pero normalmente mucho más rápidas.
El problema viene cuando queremos hacer un juego "multicarga", o un programa que acceda a disco para cargar datos de vez en cuando. Las funciones de acceso a disco son más complejas que las habituales de escritura en pantalla y lectura de teclado. Se puede hacer y de hecho grandes juegos como el ORION Prime lo hacen (y de paso usan formatos de disco personalizados que aprovechan más el espacio del mismo).
Pero no siempre vamos a tener el tiempo y las ganas de hacer esto con nuestros juegos. Lo más cómodo en estos casos es "tirar de firmware" para cargar archivos "normales" en memoria, pero... ¿Es posible hacer esto si nos lo hemos "cargado" previamente?
Bueno, pues la respuesta es que sí, se puede, es algo "complejo", pero no mucho, y lo más importante, ahorra bastante espacio en RAM puesto que no tenemos que reservar espacio para rutinas de lectura de disco. A continuación adjunto un código muy comentado (hay mucho más texto que código), de un programa que simplemente se "carga" el firmware de la forma habitual, para a continuación restaurarlo y usarlo para cargar una imagen en la memoria de video. Se puede tomar como plantilla de referencia para usar en cualquier desarollo.
Espero que sea de vuestro interés.
Edito: Lo resubo con algunos cambios y correcciones en los comentarios
Cuando se programa cualquier cosa de cierta envergadura para el Amstrad lo habitual es "cargarse" el firmware y usar funciones dedicadas para escribir en pantalla, leer el teclado, manejar las interrupciones (o simplemente ignorarlas), etc. Estas funciones son menos versátiles que las del firmware, pero normalmente mucho más rápidas.
El problema viene cuando queremos hacer un juego "multicarga", o un programa que acceda a disco para cargar datos de vez en cuando. Las funciones de acceso a disco son más complejas que las habituales de escritura en pantalla y lectura de teclado. Se puede hacer y de hecho grandes juegos como el ORION Prime lo hacen (y de paso usan formatos de disco personalizados que aprovechan más el espacio del mismo).
Pero no siempre vamos a tener el tiempo y las ganas de hacer esto con nuestros juegos. Lo más cómodo en estos casos es "tirar de firmware" para cargar archivos "normales" en memoria, pero... ¿Es posible hacer esto si nos lo hemos "cargado" previamente?
Bueno, pues la respuesta es que sí, se puede, es algo "complejo", pero no mucho, y lo más importante, ahorra bastante espacio en RAM puesto que no tenemos que reservar espacio para rutinas de lectura de disco. A continuación adjunto un código muy comentado (hay mucho más texto que código), de un programa que simplemente se "carga" el firmware de la forma habitual, para a continuación restaurarlo y usarlo para cargar una imagen en la memoria de video. Se puede tomar como plantilla de referencia para usar en cualquier desarollo.
Espero que sea de vuestro interés.
Edito: Lo resubo con algunos cambios y correcciones en los comentarios
- Adjuntos
-
- restorefirmware.zip
- (15.58 KiB) Descargado 140 veces
Última edición por opqa el Vie 10 Oct , 2014 10:53 pm, editado 2 veces en total.
Re: Cómo restaurar el firmware (y no morir en el intento)
Yo solo he hecho uso de lo que comentas una vez y debo admitir que intenté repetirlo años después y ya no me acordaba.
Saludos,
gg.
gg.
Re: Cómo restaurar el firmware (y no morir en el intento)
Ahora, al verlo todo tan bien explicadito y en español, diría que la segunda vez me salté pasos. Me lo apunto y ya lo probaré.
Saludos,
gg.
gg.
Re: Cómo restaurar el firmware (y no morir en el intento)
¿y donde esta explicado esto en inglés? Porque mira que lo he buscado, y lo único que he visto es cómo hacer para restaurar el AMSDOS nada más empezar el programa. Pero claro, no es lo mismo, porque en esos ejemplos todo el jumpblock sigue en su sitio, no es necesario empezar de 0.
Re: Cómo restaurar el firmware (y no morir en el intento)
No me hagas mucho caso porque fue hace tiempo, pero creo que fue en cpcwiki. De todas formas, creo que no estaba tan completo o, al menos, yo no lo veía así de claro.
Saludos,
gg.
gg.
Re: Cómo restaurar el firmware (y no morir en el intento)
En realidad aun no lo he probado en funcionamiento real, me acabo de dar cuenta de que es muy posible que me haya dejado algo importante. Antes de activar las interrupciones del firmware tiene pinta de que sea necesario invocar la función KL CHOKE OFF (&BCC8), que borra cierta área de memoria que usan las interrupciones para ejecutar eventos programados por el usuario.
En el ejemplo adjuntado no sería necesario porque previamente he borrado todo ese banco de memoria, pero en un caso real en el que tengamos datos obsoletos en esa zona de memoria podría llevar a un cuelgue activar las interrupciones sin haberla borrado previamente.
Los cambios en el código serían de esto:
a esto:
Lo probaré en "acción" y si veo que funciona actualizaré el .zip
En el ejemplo adjuntado no sería necesario porque previamente he borrado todo ese banco de memoria, pero en un caso real en el que tengamos datos obsoletos en esa zona de memoria podría llevar a un cuelgue activar las interrupciones sin haberla borrado previamente.
Los cambios en el código serían de esto:
Código: Seleccionar todo
; Ahora que ya esta copiada la invocamos, pero antes
; hay que desactivar las interrupciones, puesto que tambien
; restaura la rutina de interrupciones del firmware
di
call &4000 ; JUMP_RESTORE
; Antes de volver a activar las interrupciones del fimware
; hay que tener una precaucion, hay que fijar la pareja de
; registros BC del set de registros alterno para que coincida
; con el estado actual del modo grafico (0,1 o 2) y las ROMS
; (desactivadas ambas)
exx
ld bc, &7f8c OR MODE
exx
; Activamos las interrupciones, ahora el firmware vuelve a tener
; el control de la maquina
ei
; Ahora hay que restarurar el KERNEL jumpblock, para ello usamos
; una funcion del propio firmware cuya direccion hemos guardado
; al principio, esta ya se puede ejecutar desde cualquier sitio
; porque ahora seran las funciones del HIGH jumpblock las que se
; encargaran de activar/desactivar la LOWER ROM cuando sea necesario
call firmware_JUMP_RESTORE
...
Código: Seleccionar todo
; Ahora que ya esta copiada la invocamos, pero antes
; hay que desactivar las interrupciones, puesto que tambien
; restaura la rutina de interrupciones del firmware
di
call &4000 ; JUMP_RESTORE
; Antes de volver a activar las interrupciones del fimware
; hay que tener una precaucion, hay que fijar la pareja de
; registros BC del set de registros alterno para que coincida
; con el estado actual del modo grafico (0,1 o 2) y las ROMS
; (desactivadas ambas)
exx
ld bc, &7f8c OR MODE
exx
; Ahora hay que restarurar el KERNEL jumpblock, para ello usamos
; una funcion del propio firmware cuya direccion hemos guardado
; al principio, esta ya se puede ejecutar desde cualquier sitio
; porque ahora seran las funciones del HIGH jumpblock las que se
; encargaran de activar/desactivar la LOWER ROM cuando sea necesario
call firmware_JUMP_RESTORE
; Borramos la cola de eventos y lista de temporizadores del firmware
call &bcc8 ; KL CHOKE OFF
; Activamos las interrupciones, ahora el firmware vuelve a tener
; el control de la maquina
ei
Re: Cómo restaurar el firmware (y no morir en el intento)
Mmmm, pues me acabo de dar cuenta de que la "solución" (todavía no se si es realmente un problema) tampoco es buena, la llamada a JUMP RESTORE vuelve con las interrupciones activadas y antes no podemos llamar a KL CHOKE OFF. Creo que lo mejor para curarse en salud es borrar antes de empezar esa zona de memoria "a mano" (son sólo 2KBs), quedaría así:
Código: Seleccionar todo
; Borramos la zona de memoria que contiene (entre otras cosas)
; la cola de eventos y lista de temporizadores del firmware,
; por si acaso hay algo que pueda colgar la maquina cuando activemos
; sus interrupciones
ld hl,&b100
ld de,&b101
ld bc,&07ff
ld (hl),a
ldir
; Ahora que ya esta copiada la invocamos, pero antes
; hay que desactivar las interrupciones, puesto que tambien
; restaura la rutina de interrupciones del firmware
di
call &4000 ; JUMP_RESTORE
; Antes de volver a activar las interrupciones del fimware
; hay que tener una precaucion, hay que fijar la pareja de
; registros BC del set de registros alterno para que coincida
; con el estado actual del modo grafico (0,1 o 2) y las ROMS
; (desactivadas ambas)
exx
ld bc, &7f8c OR MODE
exx
; Activamos las interrupciones, ahora el firmware vuelve a tener
; el control de la maquina
ei
; Ahora hay que restarurar el KERNEL jumpblock, para ello usamos
; una funcion del propio firmware cuya direccion hemos guardado
; al principio, esta ya se puede ejecutar desde cualquier sitio
; porque ahora seran las funciones del HIGH jumpblock las que se
; encargaran de activar/desactivar la LOWER ROM cuando sea necesario
call firmware_JUMP_RESTORE
-
- Keeper of The Forum
- Mensajes: 712
- Registrado: Vie 27 Feb , 2009 12:21 pm
Re: Cómo restaurar el firmware (y no morir en el intento)
Una puntualizacion que igual os ayuda un poco, de mi experiencia usando AMSDOS en Marron en la Euskal, ya que la intro, juego y final se cargan con llamada a Amsdos.
Como decis, al deshabilitar el firmware no tenemos ni firmware base ni Amsdos, pero al restaurar la tabla de interrupciones recuperamos el firmware y el Amsdos. La historia esta en cargar el codigo con un LOAD" y CALL desde un basic, o en hacer un RUN" al binario.
Si haces LOAD"" y CALL, desactivas el firmware parcheando el vector de interrupcion, y al restaurarlo sigues con AMSDOS, bien...
Si haces RUN"" a pelo, se carga el codigo, y antes de llamar a la direccion de ejecucion de la cabecera amsdos, se pega una limpia de las ROM extendidas (Incluida AMSDOS) y cualquier llamada a las funciones de fichero deriba a un intento de carga desde CASSETTE ya que solo el firmware base esta disponible.
Aun asi, el firmware base del CPC dispone de llamadas con las que poder re-inicializar el Amsdos o lo que querramos necesitar.
El problema es que en el RUN" corremos el riesgo casi seguro de que se pierda el valor de AMSDOS de si estamos en B: o A: asi que es un tema a controlar antes de inicializar las ROM extendidas...
Creo que era por esto que muchos cracks como los de XOR solo van en la unidad A:, y habria que reescribirlos para que sean mas amistosos conservando el valor de la unidad en uso, llamandolos desde un BASIC y agregando al codigo original un chequeo de la variable antes de reinicializar AMSDOS...
No se si os valdra de algo, es lo que me encontre yo en su momento
Como decis, al deshabilitar el firmware no tenemos ni firmware base ni Amsdos, pero al restaurar la tabla de interrupciones recuperamos el firmware y el Amsdos. La historia esta en cargar el codigo con un LOAD" y CALL desde un basic, o en hacer un RUN" al binario.
Si haces LOAD"" y CALL, desactivas el firmware parcheando el vector de interrupcion, y al restaurarlo sigues con AMSDOS, bien...
Si haces RUN"" a pelo, se carga el codigo, y antes de llamar a la direccion de ejecucion de la cabecera amsdos, se pega una limpia de las ROM extendidas (Incluida AMSDOS) y cualquier llamada a las funciones de fichero deriba a un intento de carga desde CASSETTE ya que solo el firmware base esta disponible.
Aun asi, el firmware base del CPC dispone de llamadas con las que poder re-inicializar el Amsdos o lo que querramos necesitar.
El problema es que en el RUN" corremos el riesgo casi seguro de que se pierda el valor de AMSDOS de si estamos en B: o A: asi que es un tema a controlar antes de inicializar las ROM extendidas...
Creo que era por esto que muchos cracks como los de XOR solo van en la unidad A:, y habria que reescribirlos para que sean mas amistosos conservando el valor de la unidad en uso, llamandolos desde un BASIC y agregando al codigo original un chequeo de la variable antes de reinicializar AMSDOS...
No se si os valdra de algo, es lo que me encontre yo en su momento
--------
Carpeta publica [url=https://mega.nz/#F!W5IyhbLa!51JpgZqvyx6j__v12Pr9QA]MEGA Amstrad[/url]
Carpeta proyecto [url=https://github.com/KaosOverride]GitHub[/url]
Carpeta publica [url=https://mega.nz/#F!W5IyhbLa!51JpgZqvyx6j__v12Pr9QA]MEGA Amstrad[/url]
Carpeta proyecto [url=https://github.com/KaosOverride]GitHub[/url]
- Mode 2
- I am The Forum
- Mensajes: 2058
- Registrado: Lun 10 Oct , 2005 8:01 pm
- Ubicación: Sevilla, años 80.
- Contactar:
Re: Cómo restaurar el firmware (y no morir en el intento)
Muy interesante este hilo y posiblemente necesario para uno de los juegos en los que estoy. Gracias.
BUSCO: VideoPac+, Jaguar Saturn, Micromanía 1, Amstrad Semanal, MicroHobby, juegos especialmente CPC y Vectrex, Aquarius, Sam Copé, 520 ST, manual +3, manual CPC664.
Re: Cómo restaurar el firmware (y no morir en el intento)
Muy interesante este hilo y posiblemente necesario para uno de los juegos en los que estoy. Gracias.
Salu2,
Arta
Arta
-
- Keeper of The Forum
- Mensajes: 712
- Registrado: Vie 27 Feb , 2009 12:21 pm
Re: Cómo restaurar el firmware (y no morir en el intento)
De todas formas, a ver si lo subo al hilo de Basic y otros lenguajes, o lo tenia ya subido..., un crt0 para sdcc que permite cargar muy bajito (0x140 o 0x200) mediante RUN"", no reinicializar AMSDOS y volver al basic. Realmente es un minibasic+bin, al estilo de los compactados de cngsoft, que con el Run"" carga el bin y el minibasic, que es solo un call al inicio de ejecucion del codigo bin. Seguro lo adaptais facil de asm de sdcc a vuestros proyectos puramente en asm.
Lo unico te obliga a ubicar el codigo desde 0x140 (o 0x200, no recuerdo bien) pero no destroza a AMSDOS, puedes controlar en las variables del firmware la unidad activa, y guarrear con AMSDOS sin perder la unidad actual.
Ahh, otra cosa, las Rom inicializalas a tintas todas a cero, que Parados, Maxam etc muestran texto...
Edit: aqui esta www.amstrad.es/forum/viewtopic.php?p=46916#p46916
Lo unico te obliga a ubicar el codigo desde 0x140 (o 0x200, no recuerdo bien) pero no destroza a AMSDOS, puedes controlar en las variables del firmware la unidad activa, y guarrear con AMSDOS sin perder la unidad actual.
Ahh, otra cosa, las Rom inicializalas a tintas todas a cero, que Parados, Maxam etc muestran texto...
Edit: aqui esta www.amstrad.es/forum/viewtopic.php?p=46916#p46916
--------
Carpeta publica [url=https://mega.nz/#F!W5IyhbLa!51JpgZqvyx6j__v12Pr9QA]MEGA Amstrad[/url]
Carpeta proyecto [url=https://github.com/KaosOverride]GitHub[/url]
Carpeta publica [url=https://mega.nz/#F!W5IyhbLa!51JpgZqvyx6j__v12Pr9QA]MEGA Amstrad[/url]
Carpeta proyecto [url=https://github.com/KaosOverride]GitHub[/url]
Re: Cómo restaurar el firmware (y no morir en el intento)
Una preguntilla... ¿cuál es la razón de regresar al basic o reponer el firmware? ¿usar el acceso a disco? Si es así hay una rutina que ocupa creo que unos 512 bytes (o 300 y pico si no recuerdo mal) que carga ficheros con cabeceras amsdos.
-
- Keeper of The Forum
- Mensajes: 712
- Registrado: Vie 27 Feb , 2009 12:21 pm
Re: Cómo restaurar el firmware (y no morir en el intento)
Yo entiendo que lo interesante de mantener el firmware + Roms auxiliares en uso, es el poder acceder a ficheros no solo en la unidad A: o B:, sino en futuros roms que soporten unidades C:, D:, hasta d3 red, etc... Y soportar otros sistemas de archivos como Fat, etc. Sino estamos cayendo en el problema de solo cargar de data, system, ibm y de A y B, y ahi quedarse...
--------
Carpeta publica [url=https://mega.nz/#F!W5IyhbLa!51JpgZqvyx6j__v12Pr9QA]MEGA Amstrad[/url]
Carpeta proyecto [url=https://github.com/KaosOverride]GitHub[/url]
Carpeta publica [url=https://mega.nz/#F!W5IyhbLa!51JpgZqvyx6j__v12Pr9QA]MEGA Amstrad[/url]
Carpeta proyecto [url=https://github.com/KaosOverride]GitHub[/url]
Re: Cómo restaurar el firmware (y no morir en el intento)
Pues yo sí muero en el intento. Supongamos que tienes un juego petado desde 0000 hasta cfff.
¿Que zonas de memoria ram hay que salvar antes de que el firmware las sobreescriba.?.
¿Que zonas de memoria ram hay que salvar antes de que el firmware las sobreescriba.?.
Esa subrutina donde está?.Una preguntilla... ¿cuál es la razón de regresar al basic o reponer el firmware? ¿usar el acceso a disco? Si es así hay una rutina que ocupa creo que unos 512 bytes (o 300 y pico si no recuerdo mal) que carga ficheros con cabeceras amsdos.
Re: Cómo restaurar el firmware (y no morir en el intento)
Lo acabo de mirar. Ocupa 797 bytes y requiere un buffer de 384 bytes (en pantalla mismo si es entre cargas). La tengo adaptada para que se compile como una funci'on de C y ser compilada con el SDCC. Si te interesa te la paso.Pues yo sí muero en el intento. Supongamos que tienes un juego petado desde 0000 hasta cfff.
¿Que zonas de memoria ram hay que salvar antes de que el firmware las sobreescriba.?.
Esa subrutina donde está?.Una preguntilla... ¿cuál es la razón de regresar al basic o reponer el firmware? ¿usar el acceso a disco? Si es así hay una rutina que ocupa creo que unos 512 bytes (o 300 y pico si no recuerdo mal) que carga ficheros con cabeceras amsdos.
¿Quién está conectado?
Usuarios navegando por este Foro: Ahrefs [Bot]
La Comunidad Española |