lunes, 9 de mayo de 2016

Cómo escribir juegos para el ZX Spectrum. Capítulo 17

Índice de entradas

Esta serie de artículos han sido traducidos a partir del documento "How to Write ZX Spectrum Games" con permiso de su autor, Jonathan Cauldwell, un gran desarrollador de juegos para el Spectrum, os recomiendo visitar su Web donde está el texto original. El documento original, y por tanto esta traducción, tiene © Jonathan Cauldwell y solo puede duplicarse con permiso expreso por escrito de su autor.

Interrupciones

La creación de tus propias interrupciones puede ser una pesadilla la primera vez que lo intentes, ya que es un asunto complicado. Con práctica se convierte en un poco más fácil. Para hacer que el Spectrum ejecute nuestra propia rutina de interrupción hay que decirle en que ubicación está nuestra rutina, poner la máquina en modo 2 de interrupción, y garantizar que las interrupciones están habilitadas. ¿Suena bastante simple? La parte difícil es decirle al Spectrum, donde se encuentra nuestra rutina.

Con la máquina en modo 2, el Z80 utiliza el registro i para determinar el byte alto de la dirección del puntero a la dirección de la rutina de servicio de interrupción. El byte bajo es suministrado por el hardware. En la práctica, nunca se sabe lo que va a contener el byte bajo, ¿ves el problema? El byte bajo igual podría ser 0, que podría ser 255, o que podría estar en cualquier posición intermedia. Esto significa que necesitamos todo un bloque de 257 bytes de punteros a la dirección de inicio de nuestra rutina de servicio. Como el byte bajo suministrado por el hardware puede ser par o impar, tenemos que asegurarnos de que el byte bajo y el byte alto de la dirección de nuestra rutina de servicio son idénticos. Esto limita seriamente donde podemos localizar nuestra rutina. También debemos localizar nuestra tabla de punteros y nuestra rutina sólo en la memoria RAM no contenida. No lo coloques por debajo de la dirección 32768. Incluso ubicándolo en la memoria RAM no contenida, como por ejemplo en el banco 1, producirá problemas en ciertos modelos del Spectrum. Personalmente, encuentro el banco 0 un lugar tan bueno como cualquier otro.

Digamos que elegimos la dirección 51400 como la ubicación de nuestra rutina de interrupción. Esto es válido ya que tanto el byte alto como el byte bajo son 200, ya 200*256+200=51400. A continuación, necesitamos una tabla de 129 punteros que apunten todos a esta dirección, o 257 veces DEFB 200, situada en el inicio de un límite de página de 256 bytes. Suponiendo que lo ponemos en lo alto del camino, podríamos empezar por 254*256=65024.

Debemos hacer esto

       org 51400

int    ; rutina de servicio de interrupción.


       org 65024

       ; punteros a rutina de interrupción.

       defb 200,200,200,200
       defb 200,200,200,200
       .
       .
       defb 200,200,200,200
       defb 200

¡Uf! Aún así, ahora llegamos a nuestra rutina de interrupción. Las interrupciones pueden ocurrir durante cualquier período, por lo que tenemos que conservar los registros que es probable que se utilicen, ejecutar nuestro código, llamar opcionalmente a  la rutina de servicio de la ROM, restaurar los registros, volver a habilitar las interrupciones y por último regresar de la interrupción con un reti. Nuestra rutina podría asemejarse a esta:

int    push af             ; preservar registros.
       push bc
       push hl
       push de
       push ix
       call 49158          ; hacer sonar la música.
       rst 56              ; rutina ROM, leer teclas y actualizar el reloj.
       pop ix              ; restaurar registros.
       pop de
       pop hl
       pop bc
       pop af
       ei                  ; Volver a habilitar interrupciones antes de regresar.
       reti                ; echo.
       ret

Si no estás leyendo el teclado a través de las variables del sistema, puedes desear prescindir del rst 56. Si lo haces, vas a liberar los registros iy. Sin embargo, si el temporizador de tu juego cuenta los cuadros usando el método descrito en el capitulo de temporización, tendrás que incrementar el contador de cuadros por ti mismo:

       ld hl,23672         ; contador de cuadros.
       inc (hl)            ; aumentarlo.

Con todo esto en su lugar, estamos listos para deshabilitar las interrupciones. Hay que apuntar al registro i en la tabla de punteros y seleccionar el modo 2 de interrupción. Este código va a hacer el trabajo por nosotros:

       di                  ; deshabilitar las interrupciones por precaución.
       ld a,200            ; byte alto del puntero a la tabla de ubicaciones.
       ld i,a              ; establecer el byte alto.
       im2                 ; seleccionar el modo2 de interrupción.
       ei                  ; habilitar las interrupciones.

No hay comentarios:

Publicar un comentario