Recuperar gráfico de pantalla tras la carga

Moderador: Fundadores

Avatar de Usuario
Fermars
Demonio segundo orden
Demonio segundo orden
Mensajes: 1195
Registrado: 20 Feb 2014, 16:58
Ubicación: El Escorial
Been thanked: 3 times

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por Fermars »

elfoscuro escribió:Sobre el que no se pare:

http://microhobby.speccy.cz/mhf/136/MH136_07.jpg

Parece ser que era algo habitual en la época ;-)

Ahora, no te pares aquí. Investiga más, y mejora el sistema. Mhoogle es una gran herramienta de aprendizaje.

Un saludo.
Pues te va a parecer curioso, pero para parar el microdrive una vez que está en marcha y no deja de dar vueltas hago exactamente lo que dice en ese artículo, un reset y un CAT. Después un Break lo para siempre. El problema realmente no es ese, porque lo del microdrive puede pasar de forma aleatoria de vez en cuando por 1000 razones, pero en este caso sucede siempre, es decir, da la impresión que no puede volcar en memoria el contenido que previamente había grabado, incluso apagando y encendiendo.

Pasando página, lo que realmente me gustaría saber de los listados anteriores son varias cosas, ya a nivel de programación en BASIC. La verdad es que en listado del salvapantallas a mi entender y dado los ínfimos conocimientos que tengo, me las ingenié bastante bien, manual del Spectrum en mano, para usar el GOSUB y el RETURN, así como terminar el bucle con el valor de "q". No se si habrá otra forma de hacerlo más fácil, pero a mi me sorprendió que funcionara la idea. :|

Por otro lado no tengo claro lo siguiente:

1. En la línea 100 ¿porqué el bucle FOR va de 0 a 11? Según eso, el POKE iría del 25000 al 25011 ¿por qué?. Entiendo que el valor "a" son los DATA de la línea 110, ¿es así?

2. ¿Cómo sabemos qué DATA son los que hacen falta para hacer lo que deseamos?

3. ¿Por qué en la línea 300 usamos las direcciones del POKE 25004 y 25005? y lo que me deja ya fuera de juego totalmente, ¿por qué la ejecución del programa únicamente la hacemos en la dirección 25000 (línea 310)?
Fernando
Avatar de Usuario
Bubu
Demonio segundo orden
Demonio segundo orden
Mensajes: 1125
Registrado: 02 May 2013, 20:35

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por Bubu »

Fermars escribió: 1. En la línea 100 ¿porqué el bucle FOR va de 0 a 11? Según eso, el POKE iría del 25000 al 25011 ¿por qué?. Entiendo que el valor "a" son los DATA de la línea 110, ¿es así?
Va de 0 a 11 porque hay 12 bytes (lo que ocupa el pograma en ensamblador) en la línea 110. Con el bucle se van leyendo uno a uno esos 12 bytes en la variable 'a' y metiéndolos en memoria, en la dirección 25000+n, uséase, desde la 25000 a la 25011. Así que sí, es lo que tu dices.

Fermars escribió: 2. ¿Cómo sabemos qué DATA son los que hacen falta para hacer lo que deseamos?
Esto es ya algo casi mágico. Yo sé pogramar en ensamblador, y el pograma que recupera de memoria una pantalla eséste:

Código: Seleccionar todo

 LD DE, 16384  ; Indica la dirección de la pantalla
 LD HL, 0        ; Indica la dirección de la memoria donde hay una pantalla
 LD BC, 6912   ; Indica el tamaño de la pantalla en bytes
 LDIR             ; Hace la transferencia
 RET             ; Retorna al BASIC
También sé que la instrucción "LD DE, nnnn" se traduce en el byte: 17. Y el 16384 se traduce en los bytes 0 y 64 (0 + 256*64 = 16384), por lo que la instrucción LD DE, 16384 se traduce en estos 3 bytes:

17, 0, 64

que son precisamente los 3 primeros bytes que hay en el DATA. Y así con el resto de bytes.

Fermars escribió: 3. ¿Por qué en la línea 300 usamos las direcciones del POKE 25004 y 25005? y lo que me deja ya fuera de juego totalmente, ¿por qué la ejecución del programa únicamente la hacemos en la dirección 25000 (línea 310)?
Lo que se hace con este pograma es ir variando el valor de HL en función de la tecla pulsada, es decir, esta línea:

Código: Seleccionar todo

LD HL, 0
En lugar del 0 tenemos que poner la dirección de donde tengas la pantalla almacenada. Si te fijas, el pograma empieza en la dirección 25000:

Código: Seleccionar todo

LD DE, 16384
lo cual ocupa 3 bytes. Por tanto la siguiente instrucción:

Código: Seleccionar todo

LD HL, 0
empieza en la dirección 25003. En concreto, el 0 está en la dirección 25004 y 25005 (es un 0 de 16 bits, uséase, de 2 bytes). Por tanto, al pulsar la tecla 1, cogemos la dirección 25856, la descomponemos en 2 bytes: 0 y 101, y esos 2 números son los que tenemos que meter en las direcciones 25004 y 25005 respestívaménete para que el pograma se convierta en:

Código: Seleccionar todo

 LD DE, 16384  ; Indica la dirección de la pantalla
 LD HL, 25856   ; Indica la dirección de la memoria donde hay una pantalla
 LD BC, 6912   ; Indica el tamaño de la pantalla en bytes
 LDIR             ; Hace la transferencia
 RET             ; Retorna al BASIC
Si algo funciona... no lo toques. ¡¡Pero ni de coña!!
Avatar de Usuario
elfoscuro
Demonio segundo orden
Demonio segundo orden
Mensajes: 1825
Registrado: 01 Abr 2013, 22:00
Been thanked: 25 times

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por elfoscuro »

Fermars escribió:
elfoscuro escribió:Sobre el que no se pare:

http://microhobby.speccy.cz/mhf/136/MH136_07.jpg

Parece ser que era algo habitual en la época ;-)

Ahora, no te pares aquí. Investiga más, y mejora el sistema. Mhoogle es una gran herramienta de aprendizaje.

Un saludo.
Pues te va a parecer curioso, pero para parar el microdrive una vez que está en marcha y no deja de dar vueltas hago exactamente lo que dice en ese artículo, un reset y un CAT. Después un Break lo para siempre. El problema realmente no es ese, porque lo del microdrive puede pasar de forma aleatoria de vez en cuando por 1000 razones, pero en este caso sucede siempre, es decir, da la impresión que no puede volcar en memoria el contenido que previamente había grabado, incluso apagando y encendiendo.

Pasando página, lo que realmente me gustaría saber de los listados anteriores son varias cosas, ya a nivel de programación en BASIC. La verdad es que en listado del salvapantallas a mi entender y dado los ínfimos conocimientos que tengo, me las ingenié bastante bien, manual del Spectrum en mano, para usar el GOSUB y el RETURN, así como terminar el bucle con el valor de "q". No se si habrá otra forma de hacerlo más fácil, pero a mi me sorprendió que funcionara la idea. :|
Mírate este programa a ver si lo entiendes:

Código: Seleccionar todo

10 CLEAR 24999: DIM N$(5):DIM p(5)
20 LET N$(1)="flight":LET N$(2)="pssst":LET N$(3)="flag":LET N$(4)="jetpac":LET N$(5)="raiders"
20 LET p(1)=25856:LET p(1)=32768:LET p(1)=39680:LET p(1)=46592:LET p(1)=53504

30 FOR f=1 TO 5
40 PRINT "Pantalla ";f;": ";N$(f)
50 PAUSE 0
60 CLS
70 LOAD *"m";1;N$(f) CODE p(f),6912
80 NEXT f: REM bucle que carga las pantallas una a una según se pulse una tecla


90 RESTORE 100: FOR f=0 TO 11:READ a:POKE 25000+f,a:NEXT f
100 DATA 17,0,64,33,0,0,1,0,27,237,176,201: REM bucle que mete el código máquina

100 IF INKEY$<>"" THEN STOP: REM sale si se pulsa una tecla

110 FOR f=1 TO 5
120 LET b=INT(p(f)/256)
130 LET a=p(f)-256*b
140 POKE 25004,a
150 POKE 25005,b
160 RANDOMIZE USE 25000
170 PAUSE 100
180 NEXT f: REM bucle que muestra las pantallas una a una, con 2 segundos de retardo.

200 GO TO 100
Lo primero, te habías dejado el CLEAR, por lo que imagino que al cargar las pantallas estabas machacando algo de los mapas del microdrive y quizá por eso no se paraba el motor. A ver si poniendo el CLEAR se soluciona. SIEMPRE que trabajes con código máquina, o datos en memoria (PEEK y POKE), debes hacer el CLEAR para crear esa parte de memoria protegida dónde el sistema no mete nada. Te evitarás problemas.

Te he puesto instrucciones como DIM para que investigues. He quitado la rutina de GO SUB porque realmente no es necesaria, y te he puesto bucles, y lo que odian los profes de informática, salidas "a lo bruto" con el INKEY$. Pero, en Spectrum, se hacía así XD XD
Fermars escribió: Por otro lado no tengo claro lo siguiente:

1. En la línea 100 ¿porqué el bucle FOR va de 0 a 11? Según eso, el POKE iría del 25000 al 25011 ¿por qué?. Entiendo que el valor "a" son los DATA de la línea 110, ¿es así?
Realmente da igual. El código máquina que te han puesto es totalmente reubicable, por lo que es lo mismo dónde se ubique. Podrías haber puesto el bucle 1 TO ..., pero habrías tenido que cambiar el RANDOMIZE USR a 25001 en lugar de 25000. Por cierto, RANDOMIZE no forma parte de la llamada a código máquina. Es la función USR la que lo hace. RANDOMIZE es un iniciador de números aletorios, y se podría haber usado LET z=USR 25000, PRINT USR 25000... en su lugar, es decir cualquier instrucción que use una función. Te lo explico, porque si ves otros listados, igual lo ves así en lugar de RAND. USR devuelve un número, que le puedes dar desde el código máquina. Si, por ejemplo, te creas tus propias rutinas de cálculo, podrías aprovechar ese número como resultado.
Fermars escribió: 2. ¿Cómo sabemos qué DATA son los que hacen falta para hacer lo que deseamos?
Lo marca el RESTORE. Esta instrucción pone el puntero de READ en la línea que quieras. Lo puedes usar para definir un UDG según un valor, por ejemplo. Teniendo varias líneas DATA, si haces un INPUT al usuario para su idioma por ejemplo, podrías definir los UDG "N" como Ñ, o dibujar la libra o el dolar, según el país, etc. Cada pais estaría en una DATA, y haciendo el restores a esa línea, podrías dibujar directamente el caracter que fuera, sin tener que hacer varios bloques FOR.

Aunque ahora releyendo, no se si te refieres a esto, o a porqué tenemos estos números y no otros... Si es eso, te diré que esos números son los necesarios para meter en memoria el miniprogramita en código máquina (assembler) que mueve las pantallas. Para hacer otras cosas, habrá otras DATA diferentes. Quizá esto, junto con mi respuesta siguiente, te aclare más cosas.
Fermars escribió: 3. ¿Por qué en la línea 300 usamos las direcciones del POKE 25004 y 25005? y lo que me deja ya fuera de juego totalmente, ¿por qué la ejecución del programa únicamente la hacemos en la dirección 25000 (línea 310)?
Si revisas el código máquina, verás el porqué. A grosso modo, lo que hace el programa es:

Código: Seleccionar todo

10 LET destino=16384: REM DATA 17,0,64 (64*256=16384)
20 LET inicio=30000: REM 33,0,0 --- ponemos 0,0 porque estos son los valores que cambiaremos siempre, da igual lo que valgan al principio
30 LET longitud=6912: REM 1,0,27 (27*256=6912)
40 FOR f=0 TO longitud-1: POKE destino+f, PEEK inicio+f:NEXT f: REM esto sería el LDIR --- 237,176
50 RETURN: REM esto sería el RET --- ,201
Lo que hacemos es cambiar el valor de inicio, que está en 25004 y 25005 por el que necesitemos según la pantalla. Destino y longitud siempre serán el mismo valor, la dirección de la pantalla y el tamaño, y no los tocamos. Pero, si lo que hicíeramos fuera de la pantalla a la dirección 30000, no tocaríamos 25004 y 25005, si no 25001 y 25002.

Mientras que el código máquina lo hace en un suspiro, el BASIC es lento de narices. Si cambias el RANDOMIZE USR 25000 por este código, podrás comprobar la diferencia. Es brutal.

Creo que te puse unos enlaces a unas páginas de MicroHobby dónde se veía todo esto en detalle. Revisa el hilo, porque creo que eran dos páginas que explicaban el tema bastante bien (antes de lo de comprimir pantallas me suena).

Un saludo.
Fin de impresión
Avatar de Usuario
elfoscuro
Demonio segundo orden
Demonio segundo orden
Mensajes: 1825
Registrado: 01 Abr 2013, 22:00
Been thanked: 25 times

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por elfoscuro »

Añadir a lo que ha dicho bubu que tanto HL, DE, como BC son registros del procesador. Hay otros, como A, IX, IY, IX', IY' y no recuerdo si las HL', etc., existían.

En ensamblador no puedes definir variables, y existen unas fijas (los registros), que se usan para todas las instrucciones de código máquina. En el curso de código máquina de MicroHobby existía una relación de cada instrucción del Z80, con los valores necesarios, y los valores después de la instrucción. LDIR usa HL (high-low), DE (destino), y BC (contador). USR devuelve al BASIC el valor del registro A, que es de un byte (HL,DE y BC son de dos bytes). Es decir, que puedes devolver un valor de 0 a 255 como retorno de USR (habitualmente para devolver códigos de error propios de tu programa).

Quizá ya te estemos liando con el código máquina, y debamos dejarte en el BASIC... Lo mejor es que hagas copy-paste de las rutinas que te den o que encuentres en la microhobby, y las intentes entender, pero imaginalas como un GOSUB en el que no ves el código ;-)

Como te ha dicho bubu, el assembler es algo mágico, pero jodio de programar.

Un saludo.
Fin de impresión
Avatar de Usuario
Fermars
Demonio segundo orden
Demonio segundo orden
Mensajes: 1195
Registrado: 20 Feb 2014, 16:58
Ubicación: El Escorial
Been thanked: 3 times

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por Fermars »

Joder chicos, sois increíbles. Qué envidia sana poder saber, entender y dominar algo así, me quito el sombrero. Desde luego que hay que tener muchos conceptos claros tanto de hardware como de software para llegar a imaginar algo y metérselo al Z80 por intravenosa para que lo entienda de un plumazo. Impresionante de verdad pero...¡me habéis dejado hundido! :? :? :~( :~( :~(

Es broma ;) , pero cierto es que leyendo vuestras explicaciones me aclaran unas cosas pero me surgen mil dudas más. He llegado a un callejón cuya única salida es estudiar, leer y aprender, cosa que a día de hoy me es imposible tanta dedicación. Aunque si os soy sincero, hace unos 10 años que tengo un manual de ensamblador que siempre que me he puesto no he pasado de la segunda o tercera página.
Este año me he hecho con algún libro de código máquina de la época para el Spectrum y también el de Microhobby, pero no se cuando voy a darle. Mientras tanto intentaré pasarlo bien con lo que se y voy aprendiendo con vosotros.

Prometo eso sí mirar el nuevo código de elfoscuro e intentar aprender algún comando más del BASIC como el que has sugerido de "DIM". No obstante, como ya dije antes, el poder editar y manipular el código inicial del post para lograr el objetivo, para mi ha sido un logro, aunque haya tenido que tirar de herramientas como GOSUB para conseguirlo. Lástima no haber tenido algo de ayuda como esta a finales de los 80...

¡Gracias! :)
Fernando
Avatar de Usuario
elfoscuro
Demonio segundo orden
Demonio segundo orden
Mensajes: 1825
Registrado: 01 Abr 2013, 22:00
Been thanked: 25 times

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por elfoscuro »

Hombre, la ayuda la tenías... MicroHobby!!!!

En serio, creo que muchos de los programadores españoles de hoy día, no habrían existido sin ella. La existencia de gente como Primitivo de Francisco, Pedro José Rodriguez Larrañaga, etc., hacía que siempre quisieras más. Era una revista técnica para todos los públicos ;-)

Otra vez te dirijo a ella... Para aprender BASIC, que mejor que el MicroBasic que se publicó en sus páginas centrales:

ftp://ftp.worldofspectrum.org/pub/sincl ... icroBasic/

Y ya si quieres código máquina, el curso de las páginas centrales que vino después:

ftp://ftp.worldofspectrum.org/pub/sincl ... goMaquina/

Al estar las páginas sueltas en JPG, te recomiendo que uses algo como flashgot en el firefox, o directamente filezilla, el cliente de FTP gratuito. Bájatelo, lee y disfruta ;-)

También puedes visitar Microhobby forever. Te pongo el enlace a la sección de PDF:

http://www.microhobby.org/especial_pdf.htm

Dónde podrás encontrar entre otras cosas los dos cursos y las microfichas.

Y el manual original del gomas que te puse más atrás también te vendrá bien.

Un saludo.
Fin de impresión
Avatar de Usuario
Fermars
Demonio segundo orden
Demonio segundo orden
Mensajes: 1195
Registrado: 20 Feb 2014, 16:58
Ubicación: El Escorial
Been thanked: 3 times

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por Fermars »

elfoscuro escribió:Hombre, la ayuda la tenías... MicroHobby!!!!

En serio, creo que muchos de los programadores españoles de hoy día, no habrían existido sin ella. La existencia de gente como Primitivo de Francisco, Pedro José Rodriguez Larrañaga, etc., hacía que siempre quisieras más. Era una revista técnica para todos los públicos ;-)

Otra vez te dirijo a ella... Para aprender BASIC, que mejor que el MicroBasic que se publicó en sus páginas centrales:

ftp://ftp.worldofspectrum.org/pub/sincl ... icroBasic/

Y ya si quieres código máquina, el curso de las páginas centrales que vino después:

ftp://ftp.worldofspectrum.org/pub/sincl ... goMaquina/

Al estar las páginas sueltas en JPG, te recomiendo que uses algo como flashgot en el firefox, o directamente filezilla, el cliente de FTP gratuito. Bájatelo, lee y disfruta ;-)

También puedes visitar Microhobby forever. Te pongo el enlace a la sección de PDF:

http://www.microhobby.org/especial_pdf.htm

Dónde podrás encontrar entre otras cosas los dos cursos y las microfichas.

Y el manual original del gomas que te puse más atrás también te vendrá bien.

Un saludo.
Gracias. Los enlaces ya los tengo en favoritos desde ¡hace años!, pero es lo de siempre, uno no encuentra tiempo para dedicarse en pleno a esa tarea, que por otro lado no es nada fácil.
Yo siempre he tirado de Microhobby y en su época compré muchos números que tengo perfectamente guardados con sus cintas clasificadas en archivos, me encantaba ver los listados, novedades de juegos y sus mapas, la sección de trucos "tokes y pokes" donde muchos listados sencillos ponían a prueba el Spectrum con fractales imposibles, probé decenas de juegos, copié pacientemente listados BASIC y de CM de esos interminables y pasé horas buscando errores (¿quien no?)... ¡hasta me hice una enciclopedia temática en BASIC que casi termino las 9999 líneas de listado! (inacabada). Desde luego que fue una época que no se olvidará fácilmente. Sin embargo, a lo que yo me refería, es que cuando entré en el mundillo ciertamente muy tarde, finales de los 80, yo era un chaval de 12 o 13 años y en poco tiempo el PC entró a saco. Además, no tenía ni un solo amigo/conocido que le gustara esto y era difícil compartir conocimientos e inquietudes, desde luego hubiera estado genial trabajar en equipo. Pero bueno, para eso están estos foros hoy en día ¿no? :)
Fernando
Avatar de Usuario
Bubu
Demonio segundo orden
Demonio segundo orden
Mensajes: 1125
Registrado: 02 May 2013, 20:35

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por Bubu »

Fermars escribió: Pero bueno, para eso están estos foros hoy en día ¿no? :)
Efestívaménete. Yo cuando estoy en un foro, pregunto algo tésnico y me dirigen al google o ande sea, direstamente me voy del foro.

:-D

Es que pa eso están. Si preguntaras sobre cómo freir espárragos, pues te mandaba al ídem, pero ¿algo tésnico del Spectrum? Este es tu sitio ;-)
Si algo funciona... no lo toques. ¡¡Pero ni de coña!!
Avatar de Usuario
elfoscuro
Demonio segundo orden
Demonio segundo orden
Mensajes: 1825
Registrado: 01 Abr 2013, 22:00
Been thanked: 25 times

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por elfoscuro »

Si, la década de los 90 se cargó todo el mundo 8 bits, y casi el 16 bits... El PC empezó a convivir en serio con las consolas (aunque para mi, enseguida se hizo con el trono), y los viejos roqueros desaparecieron... Yo aguanté gracias al emulador de Pedro Gimeno, seguido por el Z80 (sparrow claro), y luego el R128 y el realspectrum.

He visto como los emuladores eran cada vez mejores, y como actualmente no hay máquina sin emulador de spectrum ;-)

Pero sigo teniendo la espinita de hacer algún juego. Pasar de copiar listados a generar listados. Siempre quise publicar algo en MH (en los programas de lectores, claro), y ahora se puede, gracias a internet, difundir cualquier obra con facilidad...

Tengo pendiente la churrera. En cuanto pueda, me pongo a crear gráficos y hacer algo con ella. He visto que se hacen juegos como el de Brunilda, que es muy Zelda (como me gusta, no sólo de plataformas vive el hombre), y que no debe ser complicado de hacer con la herramienta. Todo es ponerse, y lo haré algún día ;-)

Un saludo.
Fin de impresión
Piccolojunior !Sinclair 1
Siervo de Satán
Siervo de Satán
Mensajes: 1
Registrado: 16 Feb 2023, 17:54

Re: Recuperar gráfico de pantalla tras la carga

Mensaje por Piccolojunior »

Buenas tardes, han pasado unos cuantos años del tema en cuestión pero nunca es tarde para aprender, al lío.
Resulta que estoy haciendo un juego en basic para Spectrum (espinita clavada de mi juventud) y para ahorrar unos UGD de la pantalla del juego que son fijos quería ubicar la pantalla en el último bloque de memoria disponible (65535 - 6912), parece que lo consigo, pero debo fallar con los poke, porque cuando llamo a la pantalla con randomize usr se me machaca de la parte de abajo.
El juego por ahora ocupa 31k y todavía no está acabado, por eso quiero ubicar la pantalla en el último bloque de memoria disponible, hay alguien que me pueda ayudar. HELP!
Responder

Volver a “Sinclair”