Autor Tema: Cosas interesantes...  (Leído 197114 veces)

SingletonJohn

  • Commodore Master
  • *****
  • Mensajes: 259
  • Poke 35136,0
    • Ver Perfil
Re:Cosas interesantes...
« Respuesta #480 en: Hoy a las 03:30:50 »
Hola a todos!

Ahí va una buena aportación del uso de una rutina de copia rápida de bloques de memoria del ROM del BASIC. Se trata de la rutina BLTUC ($A3BF-41919), y que mueve el bloque apuntado por $5F-$60(95-96) y que termina en la dirección $5A-$5B(90-91) -1 al bloque que termina en la dirección apuntada por $58-$59(88-89) -1. El principal problema que nos ocurre al pokear los datos es que la propia instrucción POKE de BASIC machaca los datos de la dirección $5F-$60. Podéis probar a hacer un POKE95,1:POKE96,2:PRINT PEEK(95):PRINT PEEK(96) y veréis que, indefectiblemente, obtendréis dos preciosos ceros en pantalla.

Como las primeras instrucciones de la rutina lo que hacen es calcular el número total de bytes a mover,  restando los punteros $5A y $5F, el resultado será un desastre total
« última modificación: Hoy a las 04:37:09 por SingletonJohn »
"Ya al final de mi vida de pecador, mientras espero el momento de perderme en el abismo..." pues me lío y me pongo a hacer lo que no pude de pequeño! ;)

SingletonJohn

  • Commodore Master
  • *****
  • Mensajes: 259
  • Poke 35136,0
    • Ver Perfil
Re:Cosas interesantes...
« Respuesta #481 en: Hoy a las 03:31:28 »
Pues bien: tengo la solución!

Después de analizar el código de la rutina y estar peleando un buen rato, hay una manera sencilla de usarla desde BASIC.

Como comentaba antes, las primeras instrucciones restan los punteros que marcan el principio y el final del bloque a mover y guarda los datos en Y( Byte menos significativo del tamaño del bloque) y X (Byte más significativo).
Lo que hay que hacer es poner el tamaño del  bloque que queremos mover en SXREG ($30D-781) y SYREG($30E-782), poner la dirección de memoria siguiente a la final del bloque de origen en $5A-$5B (90-91), poner la dirección de memoria siguiente a la final del bloque de destino en $58-$59 (88-89) y hacer un SYS a $A3CC (41932) en vez de a $A3BF (41919). De esta manera nos saltamos la resta de punteros y entramos con X e Y asignados

Como puede resultar algo lioso lo vemos con un ejemplo: el clásico de copiar el charset de $D000-$D7FF (el charset Gráfico) a $A000-$A7FF (para modificar algunos caracteres para tiles gráficos, por ejemplo, y conservar el resto). $A000 es la posición 4 del charset en el banco 2 (el banco 2 es un buen sitio para hacer estas cosas en BASIC)

20015 POKE 56333,127:POKE 1,51
20020 POKE781,8:POKE782,0:POKE90,0:POKE91,216:POKE88,0:POKE89,168:SYS41932
20025 POKE 1,55:POKE 56333,129


las líneas 20015 y 20025 son para activar/desactivar las interrupciones por tiempo y exponer/esconder el charset). Nada nuevo, esto lo encontráis en cualquier manual de BASIC en el capítulo de CUSTOM CHARSET.

El meollo está en la línea 20020. Como queremos mover el bloque $D000-$D7FF a $A000-$A7FF (esto es $800 bytes= 2048 bytes), ponemos 8 en SXREG(781) y 0 en SYREG(782):como decíamos, el byte más significativo a Registro X y el menos significativo a Registro Y. Ponemos en 90-91 la dirección de memoria siguiente a la del final del bloque de origen ($D7FF+1=$D800 -> 0 a 90 y 216 ($D8) a 91) y en 88-89 el byte siguiente al último byte del bloque de destino ($A7FF+1=$A800 -> 0 a 88 y 168 ($A8) a 89). hacemos el SYS y......tachán! podremos comprobar que el charset se ha copiado correctamente (usando un monitor de charset, por ejemplo) y tan sólo ha tardado algo menos de un segundo, en lugar del minuto de rigor si hacemos esto con el MÉTODO CLÁSICO (blucle FOR y POKES...)

Saludos y espero que os sirva para mover bytes a toda velocidad en BASIC!!!

« última modificación: Hoy a las 04:39:12 por SingletonJohn »
"Ya al final de mi vida de pecador, mientras espero el momento de perderme en el abismo..." pues me lío y me pongo a hacer lo que no pude de pequeño! ;)