Un método sencillo para anular la tecla BREAK

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

Moderador: Sir Cilve Sinclair

Responder
Avatar de Usuario
NeilParsons
Dizzy
Mensajes: 1094
Registrado: Mar Oct 02, 2007 5:13 pm

Un método sencillo para anular la tecla BREAK

Mensaje por NeilParsons » Dom Feb 24, 2013 10:04 pm

Buscaba en el foro alguna información sobre cómo anular la tecla BREAK o la combinación Caps + Space fácilmente desde BASIC, bien mediante pokes o bien usando alguna rutina de CM para poderla implementar en mis programas, sobre todo en uno que ya tengo casi terminado y a punto de lanzarlo en breve para su libre descarga.

En la revista Microhobby se llegaron a publicar algunos trucos que hicieran eso mismo, pero no estoy muy convencido de su funcionalidad o más bien no me fio de que funcionen de la manera que prometen.

Varios trucos que he visto:

- POKE 23613,PEEK 23630-5 (Visto en MH 34)
- POKE 23613,82 (Visto en MH 56)
- o el programita incluido en el MH 177

En cualquier caso, los que conocen mejor cómo bloquear el ordenador pueden indicarme alguna solución eficiente y sencilla a la vez.

Sobre todo, me interesa que funcione en modo 128k, ya que el programa que estoy en vías de publicar sirve para estos modelos.

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Un método sencillo para anular la tecla BREAK

Mensaje por zup » Dom Feb 24, 2013 11:05 pm

Exactamente... ¿qué quieres que pase cuando pulsas Break?

Los dos primeros POKEs modifican la dirección de retorno cuando hay errores (cualquier error, incluso los de cinta). El primer ejemplo causa un cuelgue y el segundo no funciona en 128k (deja retornar al BASIC, curiosamente en 48k sigue ejecutando el programa como si nada pasara).

La tercera opción es algo más elaborada, pero imagino que si quieres usar interrupciones para algo esta opción no te sirve.

Me da en la nariz que si quieres que no retorne al BASIC pero continúe la ejecución, la cosa es algo más complicada. A lo mejor solo te basta con colgar el equipo para que no hurguen en tu código.

El único problema es que nada de esto te va a detener si tienes ganas de ver el código. Se me ocurren varias formas de espiar el código usando únicamente un Spectrum, y no te digo cómo se quedan las cosas si además echas mano de ZX Spin (tiene de lejos el depurador que más me gusta de todos).

Otro asuntillo: ¿piensas venderlo o regalarlo? Si vas a regalarlo, sería todo un detalle una versión "limpia" (sin protecciones ni cosas raras) por si alguien quiere aprender o hacer alguna cosa rara con él (por ejemplo, pasarlo a disco). Todavía estoy dándome de leches con el cargador personalizado de "Phantomasa 1", y no parece que la cosa avance mucho...
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

Avatar de Usuario
NeilParsons
Dizzy
Mensajes: 1094
Registrado: Mar Oct 02, 2007 5:13 pm

Re: Un método sencillo para anular la tecla BREAK

Mensaje por NeilParsons » Lun Feb 25, 2013 2:05 am

zup escribió:Exactamente... ¿qué quieres que pase cuando pulsas Break?


Simplemente, que si se pulsa BREAK por cualquier motivo, que no se interrumpa la ejecución del programa en curso, pero tampoco quiero provocar su cuelgue. Es decir, que no tiene por qué coscarse nada y el programa va a lo suyo.

De todas maneras, es con vistas a la futurible edición física del programa, no para la versión que se colgará digitalmente en internet de manera gratuita.

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Un método sencillo para anular la tecla BREAK

Mensaje por zup » Lun Feb 25, 2013 8:22 am

Bueee... pues no sé qué decirte.

Hay otras maneras de boquear el Spectrum, como jugar con el área de canales, pero no se me ocurre nada sencillo para que siga ejecutándose.

Imagino que una manera sería (ojo, nunca lo he hecho):
- Aprovechar la dirección de retorno de error para colocar nuestra rutina de "captura" de errores (vamos a hacer una especie de ON ERROR GOTO)
- Comprobar si el error es un BREAK.
- Usar las variables del sistema para indicar cuál debe ser la siguiente instrucción a ejecutar. Hay dos errores BREAK, L y D (si mal no recuerdo). El comportamiento por defecto de CONTINUE es ejecutar la siguiente instrucción en el caso de L, y repetir la instrucción en curso en caso de D.
- Volver a saltar al BASIC.

Habría que controlar que la pila esté en buenas condiciones antes de saltar a BASIC otra vez, y empollarse cómo funcionan ERRSP, ERR NR, NEWPPC, NSPPC, PPC, SUBPPC y alguna otra cosilla (como cómo saltar al BASIC para que procese la siguiente instrucción), pero me imagino que alguien ya lo habrá estudiado. Hay unos cuantos juegos que cargan con LOAD "" CODE (sin USR), sobreescribiendo BASIC y área de variables. Cuando el Spectrum acaba de ejecutar el LOAD, se encuentra que las variables están apuntando a otra instrucción BASIC (que esta vez sí que lanza el código).

En cuanto a lo de las protecciones, creo que me has entendido mal. Está muy bien que quieras poner protección al juego, por nostalgia (creo que había alguien en WOS que quería meterle un Speedlock a un juego nuevo) o porque quieras venderlo (aquí estoy hablando de venderlo en exclusiva; si vas a vender cintas además de compartirlo, estaría bien tener una cara A con el juego protegido y una cara B con el juego "limpio"). Y de cara a una versión gratuita, tampoco está mal que impidas que funcione BREAK. Lo que quiero decir es que, si vas a compartirlo, quizás haya gente que quiera ver el código o depurarlo de alguna manera; a esta gente le puede interesar (además del código fuente) una versión "limpia" para verlo en su emulador (pregunta tontísima... ¿hay depuradores de Spectrum a nivel de BASIC?).
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

Avatar de Usuario
jevilon
Manic Miner
Mensajes: 288
Registrado: Mié Jul 23, 2008 1:15 pm
Ubicación: La Rioja

Re: Un método sencillo para anular la tecla BREAK

Mensaje por jevilon » Lun Feb 25, 2013 8:33 am

¿¿Lo que buscas es para el cargador o para el juego en sí?? Si es para el juego que este en BASIC... ¿Por que no basic compilado? Con eso ya te evitas que se pueda hacer BREAK (salvo que le digas al compilador que te deje hacerlo)

Avatar de Usuario
na_th_an
Nonamed
Mensajes: 1889
Registrado: Lun May 07, 2007 10:16 am
Ubicación: Andalucía

Re: Un método sencillo para anular la tecla BREAK

Mensaje por na_th_an » Lun Feb 25, 2013 10:57 am

Porque está usando PLAY y, que yo sepa, ningún compilador lo soporta.

Me temo que no hay solución buena. La que hay que liar es tan gorda que creo que no merece la pena. Si alguien pulsa BREAK, que se joda. Si es para proteger el programa, tampoco tiene sentido, porque hay MIL formas de ver ese código fuente por muy protegido que esté.

Avatar de Usuario
NeilParsons
Dizzy
Mensajes: 1094
Registrado: Mar Oct 02, 2007 5:13 pm

Re: Un método sencillo para anular la tecla BREAK

Mensaje por NeilParsons » Lun Feb 25, 2013 1:37 pm

Vale. Ya me ha quedado más claro en cuanto a lo que se refiere a mis ulteriores intenciones. En ese caso, no me merece la pena para lo que pensaba añadir a mi proyecto, que saldrá por fin en esta semana. :wink:

Dejo este hilo abierto porque es un tema muy interesante y aquí cualquiera puede exponer casos sobre cómo proteger sus juegos o aplicaciones escritos en BASIC o en otro tipo de código.

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Un método sencillo para anular la tecla BREAK

Mensaje por zup » Mié Feb 27, 2013 8:51 am

Vale, tenemos básicamente tres casos:

- Si sólo te importa proteger un cargador puedes jugar con ERRSP para hacer un reset del Spectrum o con el área de canales. En este caso no te importa que el programa se rompa (si has pulsado BREAK, vas a tener que rebobinar la cinta de todas maneras). Ya de paso le metes trucos como llenar la memoria (estilo al Ant Attack) y tienes una protección más o menos eficiente y sencilla (optativo: turbos y cargadores custom).

- Si es el programa en sí lo que te importa (y obligatoriamente tiene que ser en BASIC interpretado), entonces estamos de acuerdo en que romper el programa o resetear/bloquear el equipo es inaceptable. Aquí te convendría meter una rutina del estilo ON ERROR GOTO, como he dicho antes. De hecho, debería ser imprescindible para capturar cualquier otro error que se produzca en el programa, aunque decidir que haces si te sale un OUT OF DATA es otra cuestión.

- Por último, por lo que dicen (no tengo experiencia con ellos) los compiladores de BASIC permiten anular BREAK lo que los hace una muy buena solución. na_th_an dice que PLAY no está soportado, pero ¿qué tal echar mano de alguna rutina de música simultánea (Microhobby tiene una)? ¿Se podría mezclar junto con BASIC compilado para tener protección antiBREAK y música a la vez?
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

Avatar de Usuario
na_th_an
Nonamed
Mensajes: 1889
Registrado: Lun May 07, 2007 10:16 am
Ubicación: Andalucía

Re: Un método sencillo para anular la tecla BREAK

Mensaje por na_th_an » Mié Feb 27, 2013 9:08 am

Esa rutina, según veo, está diseñada para funcionar desde el mismo intérprete, ya que necesita el PLAY después del RANDOMIZE USR, por lo que no podría usarse.

La verdad, estaría bien diseñar alguna implementación de PLAY para ZX Basic y no debería ser difícil... Pero ah, el tiempo.

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Un método sencillo para anular la tecla BREAK

Mensaje por zup » Mié Feb 27, 2013 10:16 am

Acabo de encontrar una rutina en alemán para hacer un ON ERROR GOTO. La rutina viene a ser algo así:

- Para activarse, lee el valor de ERRSP. Después, coloca la dirección donde va a estar nuestra rutina de manejo de errores. ERRSP no es una dirección fija, sino un puntero a "alguna parte" en la pila; si ERRSP es 30000, deberíamos meter la dirección de nuestra rutina en (30000).

- Para desactivarse, carga en ERRSP su valor "normal" (4099?)

La rutina de manejo de errores viene a ser algo así:

Código: Seleccionar todo

ld hl,4867
push hl
; hemos metido en la pila la dirección de MAIN_4 (para tener un retorno al BASIC)
ld bc, (23670)
ld hl,9999
and a
sbc hl,bc
jr nc, onerror
; Aquí leemos el valor de SEED. En SEED está el número de línea donde saltará nuestra rutina, si es mayor de 9999 retornamos con error, si no se sigue para alante.
; Obviamente, quien dice SEED puede decir cualquier dirección de memoria o incluso meterla a pelo en BC y pasar de la comprobación.
rst 8
sub d
; "We have cagated"
:onerror
ld hl, (23621)
ld (23662),hl
; Cargamos PPC (la línea actual) en OLDPPC (la línea a la que se saltará tras un CONTINUE)
ld a,(23623)
ld (23664),a
; Lo mismo con la sentencia (NSPPC y OSPPC)
; Cuidado porque el BASIC NO continua normalmente. En caso de error, el programa se desvía a una línea concreta, pero volver a donde estábamos es cosa nuestra. Nuestra rutina debería analizar qué es lo que ha pasado, OLDPPC y OSPPC son informativos en este caso (no se usan para nada).
call 7786
; Saltamos dentro de la rutina de GOTO. Creo que en este punto bc apunta a la línea que queremos saltar.
jp 7070
; Se salta a la rutina LINE-NEW.


Hay algún detalle más, como que ERR NR se actualiza (es decir, contiene el último código de error) para permitir deducir qué ha pasado. Una vez decidamos qué hacemos, podemos usar esta minirutina para saltar otra vez a la instrucción que ha cascado:

Código: Seleccionar todo

ld hl,(23662)
ld (23618),hl
ld a,(23664)
ld (23620),a
ret


Todo esto es bastante experimental y probablemente casque un montón de veces en el mundo real, pero al menos es un comienzo.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 8 invitados