Usando los 128K desde BASIC compilado - paginación

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

Moderador: Sir Cilve Sinclair

Responder
Avatar de Usuario
radastan
Phantomas
Mensajes: 2232
Registrado: Lun May 07, 2007 5:34 pm
Contactar:

Usando los 128K desde BASIC compilado - paginación

Mensaje por radastan » Mar Mar 11, 2008 9:23 am

A petición popular, no sólo Octocom me ha realizado dicha petición, os expongo en unas líneas una breve reseña sobre como usar la paginación de memoria de los 128K desde BASIC.

ATENCION

El procedimiento aquí reflejado sólo sirve para BASIC compilado con Hisoft BASIC, ya que desde BASIC estándar no es posible su uso porque requiere desactivar las interrupciones.

LA MEMORIA

En BASIC el mapa de memoria, a groso modo, va así:

16K ROM
16K VRAM y variables globales
16K RAM
16K RAM paginable

Bien, cojamos y recortemos lo que nos interesa:

16K RAM paginable

Los últimos 16K de memoria, C000h a FFFFh en hexadecimal y 49152 a 65535 en decimal, son los que vamos a poder cambiar. Eso significa que si vamos a cambiar esa parte de la memoria debemos evitar usarla en el BASIC propiamente dicho y también que la pila de ensamblador no apunte a esa zona. ¿Cómo lo hacemos?:

CLEAR 49151

Es decir, nuestra primera línea de programa debe ser CLEAR 49151, con lo que todo el BASIC no se verá afectado por cambiar la página.

PAGINAS DE MEMORIA

Ahora viene la gran pregunta, qué páginas de memoria podemos intercambiar y cuales son las que podemos usar.

0 - Esta es la que normalmente se usa en BASIC por defecto
1 - libre
2 - RAM del BASIC (es la que contiene el programa) (no usar)
3 - libre
4 - libre
5 - VRAM en BASIC (no usar)
6 - libre
7 - Segunda VRAM, también se usa en +3DOS y cuando editamos BASIC (no usar)

Como podemos ver, las páginas 2 y 5 se corresponden con las que van de 16384 a 49151 inclusive, por lo que no debemos modificarlas porque machacaremos el mapa de pantalla o el programa BASIC, mientras que la número 7 no se debe usar tampoco porque nuestro programa sería incompatible con los +3 (no podríamos cargarlo desde disco) y tampoco podríamos editarlo.

Eso nos deja libres las páginas:

0 - libre (la que tenemos por defecto)
1 - libre
3 - libre
4 - libre
6 - libre

Eso nos da 80K de memoria para nuestros asuntos, 5 páginas de 16 K seleccionables.

OJO, no todas las páginas van igual de rápidas: las 0 a 3 van a tope, pero las 4 a 7 comparten su tiempo con el circuito de vídeo y van más lentas (hasta un 25% según el modelo de ZX Spectrum 128K). Es decir, las páginas 4 y 6 ralentizarán un poco el programa BASIC si las usamos (recomiendo usarlas para gráficos de MENU, intro, final, etc).

PAGINANDO QUE ES GERUNDIO

Y llegamos al momento culminante, ¿qué oscura rutina debemos emplear para usar la paginación de memoria?:

OUT 32765, 16+n

n es el número de página del 0 al 7.

Nada más.
Última edición por radastan el Jue Mar 13, 2008 6:27 pm, editado 6 veces en total.
_________________________________________
Hay otras páginas.... pero no son Bytemaniacos
http://www.bytemaniacos.com
Orgullo de 8 bits
_________________________________________

Avatar de Usuario
Forni
Herbert
Mensajes: 53
Registrado: Mar May 08, 2007 9:03 am
Ubicación: Madrid

Re: Usando los 128K desde BASIC - paginación

Mensaje por Forni » Mar Mar 11, 2008 10:35 am

Antes que nada advierto que nunca he utilizado un 128k ni he jugado con lo de la paginación de la memoria, pero creo que el método que propones para paginar no es correcto (insisto: CREO).

Para paginar hay que hacer OUT en el puerto 32765.
El problema es que dicho puerto de I/O es únicamente de escritura, por lo que no podemos saber que valor tiene almacenado en un principio. Así que los señores que diseñaron el sistema operativo del 128k pensaron que era buena idea utilizar la dirección de memoria 23388 como block de notas para anotar ahí cual era el valor actual de dicho puerto.
Así pues para cambiar la página hay que hacer un PEEK (para saber que hay escrito en el puerto), un OUT (para modificar el valor del LATCH y paginar la memoria) y un POKE (para almacenar lo que hemos escrito en el puerto y ser "polites" con el sistema operativo).

Sólo lo he leido por encima, pero la información está en:

+2 (en castellano, secciones sobre la memoria y las variables del sistema):

http://www.speccy.org/manuales/manual_usuario_plus2/capitulo_8_parte_IV.pdf

+2A/+3 :

http://www.worldofspectrum.org/ZXSpectrum128+3Manual/chapter8pt24.html

The hardware switch normally used to select RAM is at I/O address
7FFDh (32765). The bit field for this address is as follows:

D0...D2 - RAM select
D3 - Screen select
D4 - ROM select
D5 - Disable paging


http://www.worldofspectrum.org/ZXSpectrum128+3Manual/chapter8pt25.html

X1 5B5Ch (23388) BANKM

Copy of last byte output to I/O port
7FFDh (32765). This port is used to
control the RAM paging (bits 0...2),
the 'horizontal' ROM switch (0<->1 and
2<->3 - bit 4), screen selection (bit
3) and added I/O disabling (bit 5).
This byte must be kept up to date with
the last value output to the port if
interrupts are enabled.


Insisto en que nunca lo he utilizado y que puede que me esté equivocando...

Saludos,
Forni

sromero
Nonamed
Mensajes: 1221
Registrado: Mar Abr 17, 2007 12:35 pm
Ubicación: Valencia
Contactar:

Re: Usando los 128K desde BASIC - paginación

Mensaje por sromero » Mar Mar 11, 2008 10:42 am

radastan escribió:OJO, no todas las páginas van igual de rápidas: las 0 a 3 van a tope, pero las 4 a 7 comparten su tiempo con el circuito de vídeo y van un 25% más lentas. Es decir, las páginas 4 y 6 ralentizarán un poco el programa BASIC si las usamos (recomiendo usarlas para gráficos de MENU, intro, final, etc).


Esto no es exactamente así, ya que depende del módelo concreto de Spectrum que estemos usando.

Voy a citar un párrafo de un artículo del curso de ensamblador de MagazineZX (es de una entrega que aún no ha sido publicada):

Contented memory y paginación

¿Cómo afecta la contended-memory al sistema de paginación de los modelos 128K? Al igual que en el 48K existe una “página” (0×4000-0x7FFF) a la que la ULA accede y por tanto afectada por sus lecturas, en el caso de los 128K existen bancos de memoria completos (páginas) de memoria contenida. Como ya hemos visto, estos bancos son:

  • Modelos +2/128K : Bancos 1, 3, 5 y 7.
  • Modelos +2A/+3: Bancos 4, 5, 6 y 7.

La afectación de velocidad de lectura de esta memoria es más importante de lo que parece. Según el manual del +3:

The RAM banks are of two types: RAM pages 4 to 7 which are contended
(meaning that they share time with the video circuitry), and RAM pages
0 to 3 which are uncontended (where the processor has exclusive use).
Any machine code which has critical timing loops (such as music or
communications programs) should keep all such routines in uncontended
banks.

For example, executing NOPs in contended RAM will give an effective
clock frequency of 2.66Mhz as opposed to the normal 3.55MHz in
uncontended RAM.

This is a reduction in speed of about 25%.


Es decir, la velocidad de acceso a memoria (y por tanto, también de ejecución) cae un 25% en un banco con contended-memory con respecto a un banco que no lo sea.

El problema, que para el 128K y +2 las páginas que sufre una penalización son unas, y para el +2A y +3 otras diferentes, por lo que parece que siempre tendremos que primar a uno de los modelos sobre otros: o usamos números de bancos que no penalicen al +2A/+3, o lo hacemos para el 128K/+2.

Lo mejor es no situar en la zona paginada rutinas como las de vídeo o audio, o al menos, no hacerlo si éstas son críticas. En cualquier caso, es probable que para el 90% de las rutinas o datos de un programa no existan problemas derivados de correr o estar alojados en memoria contenida, pero puede ser un detalle a tener muy en cuenta en rutinas que requieran un timming perfecto (efectos con el borde, efectos gráficos complejos, etc).


Un saludo.
NoP / Compiler

Avatar de Usuario
radastan
Phantomas
Mensajes: 2232
Registrado: Lun May 07, 2007 5:34 pm
Contactar:

Re: Usando los 128K desde BASIC - paginación

Mensaje por radastan » Mar Mar 11, 2008 10:48 am

Cierto NOP, según el modelo varía la velocidad, pero de todas formas estamos hablando de BASIC y basta con saber que es algo más lento si usamos esas páginas. He editado el texto para ser más exacto.
Última edición por radastan el Mar Mar 11, 2008 11:00 am, editado 2 veces en total.
_________________________________________
Hay otras páginas.... pero no son Bytemaniacos
http://www.bytemaniacos.com
Orgullo de 8 bits
_________________________________________

Avatar de Usuario
radastan
Phantomas
Mensajes: 2232
Registrado: Lun May 07, 2007 5:34 pm
Contactar:

Re: Usando los 128K desde BASIC - paginación

Mensaje por radastan » Mar Mar 11, 2008 10:55 am

Forni escribió:Para paginar hay que hacer OUT en el puerto 32765.
El problema es que dicho puerto de I/O es únicamente de escritura, por lo que no podemos saber que valor tiene almacenado en un principio. Así que los señores que diseñaron el sistema operativo del 128k pensaron que era buena idea utilizar la dirección de memoria 23388 como block de notas para anotar ahí cual era el valor actual de dicho puerto.


Desde ensamblador esa es la forma correcta, evidentemente, de hecho incluso podemos cambiar la ROM con este puerto. Pero desde BASIC podemos usar el poke y santas pascuas, además de ser mucho más sencillo se puede leer. Evidentemente desde ensamblador no podemos usar la dirección del poke porque no tenemos corriendo el editor BASIC, que es el que lo actualiza, habría que buscar la rutina de la ROM que lo hace y llamarla.
_________________________________________
Hay otras páginas.... pero no son Bytemaniacos
http://www.bytemaniacos.com
Orgullo de 8 bits
_________________________________________

Avatar de Usuario
Forni
Herbert
Mensajes: 53
Registrado: Mar May 08, 2007 9:03 am
Ubicación: Madrid

Re: Usando los 128K desde BASIC - paginación

Mensaje por Forni » Mar Mar 11, 2008 11:31 am

radastan escribió:Pero desde BASIC podemos usar el poke y santas pascuas, además de ser mucho más sencillo se puede leer. Evidentemente desde ensamblador no podemos usar la dirección del poke porque no tenemos corriendo el editor BASIC, que es el que lo actualiza, habría que buscar la rutina de la ROM que lo hace y llamarla.


Ok, no lo sabía. "Nunca te acostarás sin saber un par de cosas más". Y yo me acabo de levantar como quien dice...

Supongo que dado que el editor BASIC está constantemente paginando entre la ROM de 48k y la de 128k y dado que siempre utiliza la dirección de memoria 23388 para no perderse en la siguiente paginación de ROM cogerá el valor correcto de nuestra paginación de RAM y lo pondrá en el LATCH.
Ahora mismo no dispongo de emulador a mano para comprobarlo :D

Lo que si he encontrado (de internet sí que dispongo 8) ) son los artículos de la MicroHobby donde leí todo lo que sé sobre la paginación de los 128k (teoría, todo teoría, nada más que teoría... :roll: ):

Uno que apareció explicando los nuevos modelos de 128k:
http://microhobby.speccy.cz/mhf/111/MH111_26.jpg
http://microhobby.speccy.cz/mhf/111/MH111_27.jpg

Este es realmente bueno (no en vano es de Primitivo de Francisco...):
http://microhobby.speccy.cz/mhf/137/MH137_24.jpg
http://microhobby.speccy.cz/mhf/137/MH137_25.jpg
http://microhobby.speccy.cz/mhf/137/MH137_26.jpg
(...el cual incluso propone modificar la placa para mejorar el diseño original del hardware :shock: ):
http://microhobby.speccy.cz/mhf/138/MH138_28.jpg
http://microhobby.speccy.cz/mhf/138/MH138_29.jpg
http://microhobby.speccy.cz/mhf/138/MH138_30.jpg

Sólo por seguir con el hilo sobre como utilizar toda esa memoria que sobra en los 128k para el BASIC:
En mi opinión paginar está bien para los programas en C/M pero en BASIC estás quitándote de un plumazo los 16k superiores que podrían servirte para almacenar variables o para realizar cálculos complejos con cadenas (el BASIC utiliza mucha memoria de trabajo para concatenar cadenas). 16k son muchos kas si tenemos en cuenta que el BASIC sólo puede disponer de unos 40k como máximo...
La única aplicación práctica que se me ocurre es el tener diversos sets de UDGs y de CHARs en cada página y así cambiar de un plumazo cantidad de gráficos. Pero para almacenar por ejemplo texto o un mapeado o una pantalla, que se vayan a manejar desde BASIC, es preferible tenerlos almacenados en una variable en vez de en memoria, pues con una variable puedes dejar al interprete de BASIC todo el trabajo de trabajar con ellos:

Código: Seleccionar todo

PRINT A$
(alehop !)
mientras que si simplemente están almacenados en memoria tienes que preocuparte tú de gestionarlos y leerlos:

Código: Seleccionar todo

FOR F=1 TO 1000: PRINT PEEK 64000+F:NEXT F
(leeeeeeeentooooooo)

¿No es más efectivo utilizar el DiscoRAM (insisto: estamos hablando de BASIC)?

Avatar de Usuario
radastan
Phantomas
Mensajes: 2232
Registrado: Lun May 07, 2007 5:34 pm
Contactar:

Re: Usando los 128K desde BASIC - paginación

Mensaje por radastan » Mar Mar 11, 2008 11:39 am



Buenos artículos, si señor.

Forni escribió:La única aplicación práctica que se me ocurre es el tener diversos sets de UDGs y de CHARs en cada página y así cambiar de un plumazo cantidad de gráficos. Pero para almacenar por ejemplo texto o un mapeado o una pantalla, que se vayan a manejar desde BASIC, es preferible tenerlos almacenados en una variable en vez de en memoria, pues con una variable puedes dejar al interprete de BASIC todo el trabajo de trabajar con ellos:

Código: Seleccionar todo

PRINT A$
(alehop !)
mientras que si simplemente están almacenados en memoria tienes que preocuparte tú de gestionarlos y leerlos:

Código: Seleccionar todo

FOR F=1 TO 1000: PRINT PEEK 64000+F:NEXT F
(leeeeeeeentooooooo)

¿No es más efectivo utilizar el DiscoRAM (insisto: estamos hablando de BASIC)?


El problema del DiscoRAM es que si tienes que estar cargando continuamente desde él los set gráficos pierdes un segundo, parece una tontería pero en ciertas situaciones es inaceptable. Octocom me mostró un ejemplo, cada vez que pasabas de pantalla en Insert Coin 2 (la demo) la música se paraba mientras la pantalla se actualizaba. Usando paginación y el poke de marrás evitas todo eso.

Ejemplo, metes varios set gráficos en los 16K superiores, incluso la partitura de la música, y con cambiar la RAM cambias de nivel, sin tener que modificar NADA. Es más práctico que tener que usar un cargador.
_________________________________________
Hay otras páginas.... pero no son Bytemaniacos
http://www.bytemaniacos.com
Orgullo de 8 bits
_________________________________________

Avatar de Usuario
Forni
Herbert
Mensajes: 53
Registrado: Mar May 08, 2007 9:03 am
Ubicación: Madrid

Re: Usando los 128K desde BASIC - paginación

Mensaje por Forni » Mar Mar 11, 2008 12:38 pm

radastan escribió:Ejemplo, metes varios set gráficos en los 16K superiores, incluso la partitura de la música, y con cambiar la RAM cambias de nivel, sin tener que modificar NADA. Es más práctico que tener que usar un cargador.


Depende.

Analicemoslo desde el punto de vista del set de gráficos:

Tendríamos (en BASIC, siempre en BASIC):
16 kilobytes x 1024 bytes/kilobyte / 8 bytes/caracter = 2048 caracteres

De los cuales sólo puedes utilizar simultaneamente:
96 CHR$ + 21 UDG = 117 caracteres
Ups! Estamos en 128k!
96 CHR$ + 19 UDG = 115 caracteres

2048 / 115 = 17.8 juegos completos de CHR$ + UDG

Para cambiar de un juego a otro sigues necesitando hacer cuatro POKES para selecionarlo (dos POKEs para cambiar los CHR$ y dos POKEs para los UDGs). Puedes reducirlo a la mitad si haces que estén separados múltiplos de 256 bytes (sólo cambiarias el HiByte del vector de dirección) y seguramente sólo cambiarás de CHR$ o de UDG cada vez, no los dos simultaneamente. Dejémoslo en 1 POKE. Lo mismo que utilizas para paginar, y encima sin trastear con la memoria y sin tener la limitación de tener que utilizar bloques de 16k.

En mi opinión 2048 caracteres dan para muchos gráficos. De hecho la pantalla tiene 32 x 24 = 768 caracteres.
2048 / 768 = 2.7 pantallas podríamos almacenar en un formato RAW (y sin atributos).
Y tipicamente nunca vamos a utilizar tantos caracteres para una pantalla de un nivel de un videojuego (o no deberíamos :D ), pues emplearemos bloques predefinidos y tiles.
Perder un segundo en cargar 2048 caracteres de golpe en memoria no me parece un dispendio teniendo en cuenta que estamos hablando de un ordenador a 3MHz interpretando BASIC. Además yo sólo lo haría si cambiase la fase del juego, no una simple pantalla de un nivel.

Analicémoslo desde el punto de vista de la música:

¿Música simultanea durante un juego en BASIC sólo empleando BASIC?
Es posible, si eres capaz de meter los suficientes BEEPs o OUTs por entre el código para que tenga una fluidez aceptable.
En ese caso cambiar de partitura es igual de sencillo como cambiar de set de gráficos: uno o dos pokes para cambiar el vector de lectura de las notas en memoria. O más rápido en BASIC: cambiar el valor de una variable numérica.
Si se emplean otros métodos para la música (y creo recordar que el "Insert Coins 2" era BASIC compilado) ya no estamos hablando de BASIC únicamente.


En ambos casos dispones de mucha memoria para todos esos datos sin necesidad de hacer paginación ni de andar cargando desde discoRAM durante el desarrollo de uno de los niveles o fases del juego.
Luego sí, para cambiar de nivel o fase sí que emplearía paginación o carga desde discoRAM.
Y yo personalmente emplearía cargar desde el disco porque de esta manera podría hacer las versiones para los hermanos menores (48k) de una manera sencilla, sustituyendo la carga desde disco por la carga desde cinta.



radastan escribió:Octocom me mostró un ejemplo, cada vez que pasabas de pantalla en Insert Coin 2 (la demo) la música se paraba mientras la pantalla se actualizaba.


La música se parará si utilizan BASIC para actualizar la pantalla. Aunque hagan paginación en la zona alta de la memoria, siempre tendrán que dibujar la pantalla en la zona baja de la RAM. Con el discoRAM se puede cargar directamente la pantalla en el fichero de representación visual. El BASIC se encarga de hacer el LDIR por nosotros.
Con el discoRAM tambien podemos cargar una variable que fuese la que pintase la pantalla

Código: Seleccionar todo

LOAD "M:pantalla2" DATA A$
y después la podemos dibujar de un plumazo

Código: Seleccionar todo

PRINT A$
Bueno, instantaneo no es dado que estamos hablando de BASIC, pero es mucho más rápido que andar leyendo con PEEK y dibujando con POKE.
De hecho, si te fijas en el QiZX una vez que te hayas pasado todas las pantallas (¿Cómo?¿Qué no te lo has pasado? Anda, haz BREAK y escribe GOTO 4865) cada pantalla se pinta con un único PRINT, se calculan los atributos (esto tarda más, con unas cuantas operaciones de cadena) y después se aplican éstos con un bucle de cinco PRINTs. Puedes observar que el tiempo de imprimir los 32 x 20 = 640 caracteres (sólo utilizo 20 líneas) es cercano a ese segundo del que hablas.
Ten en cuenta que yo imprimo toda la pantalla del tirón. Para un videojuego típico, sólo se pintarían algunos elementos dispersos por la misma, por lo que el tiempo que tomaría el PRINT y la cantidad de caracteres necesarios sería sensiblemente inferior.

Y vuelvo a insistir: todo lo estoy analizando desde el punto de vista de utilizar únicamente el BASIC, sin C/M.

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

Re: Usando los 128K desde BASIC - paginación

Mensaje por na_th_an » Mar Mar 11, 2008 8:04 pm

Yo le encuentro mucha utilidad a la hora de usar BASIC compilado. Y luego, si programas bien pasando de arrays, cadenas, DATAs y demás cosas lentas y costosas en espacio (o sea, a pelo con PEEK y POKE) esto es la repanocha. Por ejemplo, el próximo juego que publicaré en CEZ (Mariano the Dragon) está hecho en BASIC compilado, ocupa 24K (motor + gráficos + mapeado + variables), tiene 100 pantallas, y cinco misiones diferentes que se pueden ejecutar en cualquier orden.

En 16K cabe un mapa enorme y un porrón de gráficos. Si, además, pensando en una videoaventura, te curras el motor más simple posible a base de triggers de posición y de disparo (pulsando una tecla de acción en un lugar específico) que se codifiquen en un script interpretado (un bytecode), las posibilidades son ilimitadas.

Alrededor de 24K son más que suficientes para un buen motor (si compilas, que ocupa todo mucho menos). Y te puedes hartar de meter datos a mansalva.

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

Re: Usando los 128K desde BASIC - paginación

Mensaje por na_th_an » Mar Mar 11, 2008 8:12 pm

Luego, puntualizando:

1.- En 128K se pueden usar los 21 UDGs con un simple poke :)
2.- Lo mejor es tener una estructura jerárquica: carácter -> tile -> mapeado. Apañándotelas bien puedes meter de todo en poco sitio.
3.- El disco RAM... yo lo evitaría como a la peste. No es lo suficientemente portable (hay que hacer una versión para 128/+2 y otra para +2A/+3 ya que la sintaxis es diferente). Además, lo que dice Radastan: cargar/leer del disco RAM ocupa tiempo y durante ese tiempo no podemos estar tocando música. Sin contar que ningún compilador lo soporta.
4.- POKE/PEEK para usar las cosas es lo más rápido si compilas.
5.- Para hacer un juego de acción casi ni necesitamos usar cadenas. Yo, por ejemplo, sólo las empleo para contener los cachos de gráficos de los "sprites" (añadan mil comillas alrededor de 'sprite').
6.- Es posible usar musica desde BASIC, incluso sin compilar. Casi todos los players se llaman con un RANDOMIZE USR simple y lo que hacen es actualizar "un frame" la partitura, de forma que con

Código: Seleccionar todo

10 RANDOMIZE USR direccion: PAUSE 1: GOTO 10


tienes la música sonando. Con colocar las llamadas en sitios estratégicos tienes solucionado el problema. Fíjate, si no, en los juegos de Beyker que tienen música de fondo.
7.- Su usas POKE/PEEK para gestionar tus datos, puedes usar compresión (Aplib, Pucrunch, etcétera...) y meter incluso más cosas.
8.- Si usas BASIC compilado puedes dividirlo en módulos independientes que se comuniquen mediante una zona común de RAM. Esos bloques pueden ser compilados independientemente y almacenados en diferentes páginas de la RAM.

Avatar de Usuario
Forni
Herbert
Mensajes: 53
Registrado: Mar May 08, 2007 9:03 am
Ubicación: Madrid

Re: Usando los 128K desde BASIC - paginación

Mensaje por Forni » Mar Mar 11, 2008 9:03 pm

De acuerdo en todo (o en casi todo), pero permíteme que te comente y repuntualice tus puntualizaciones.

na_th_an escribió:1.- En 128K se pueden usar los 21 UDGs con un simple poke :)

¿Cómo? Desconozco el método. Por favor: comparte, informa... De verdad que me interesa.

na_th_an escribió:2.- Lo mejor es tener una estructura jerárquica: carácter -> tile -> mapeado. Apañándotelas bien puedes meter de todo en poco sitio.

Exacto. Eso quería decir que con 2048 caracteres en 16k hay caracteres más que de sobra para crear pantallas.
De pequeño yo diseñaba juegos que sólo empleaban los 21 UDGs (más los caracteres normales y los bloques predefinidos) y opino que me quedaban muy chulos :D

na_th_an escribió:3.- El disco RAM... yo lo evitaría como a la peste. No es lo suficientemente portable (hay que hacer una versión para 128/+2 y otra para +2A/+3 ya que la sintaxis es diferente). Además, lo que dice Radastan: cargar/leer del disco RAM ocupa tiempo y durante ese tiempo no podemos estar tocando música. Sin contar que ningún compilador lo soporta.

Ok. La única razón es que no se puede compilar. Yo sólo me estaba refiriendo a BASIC ejecutado en BASIC. Nada de compilaciones. Pensaba más bien en el concurso de Radastan con sus normas y tal.
Lo de la sintaxis distinta bien cierto es que es una jodienda. En que estarían pensando los desarrolladores. Pero también es cierto que algunos juegos comerciales de la época venían con la versión 128k/+2 por una cara y la +2A/+3 por la otra. Y cambiar un par de instrucciones en BASIC para hacer una versión u otra no es tan complicado.

na_th_an escribió:4.- POKE/PEEK para usar las cosas es lo más rápido si compilas.

De nuevo si compilas. También es lo más rápido en BASIC para acceder un único dato en matrices unidimensionales que no varíen mucho. Pero cuando quieres tratar con muchos datos a la vez, en BASIC interpretado lo más rápido es tirar de cadenas de texto y de algebra de cadenas.

na_th_an escribió:5.- Para hacer un juego de acción casi ni necesitamos usar cadenas. Yo, por ejemplo, sólo las empleo para contener los cachos de gráficos de los "sprites" (añadan mil comillas alrededor de 'sprite').

¡Ñeeeec! El QiZX que presenté al concurso puede calificarse de "juego de acción" y hace un uso extensivo de las cadenas.
Si en vez de haberme ceñido a las normas del concurso en su categoría de BASIC puro (que lo hice como reto, de sólo utilizar los recursos del BASIC,... bueno, y también por miedo, porque un qix de toda la vida no podría competir contra un "Insert Pandemia Necesita Vacas") hubiera usado las de BASIC libre hubiera utilizado matrices unidimensionales en vez de bidimensionales, y entonces hubiera accedido a algunos de sus datos mediante PEEK y POKE para ganar algo de velocidad. Es más, hubiera prescindido de un par de esas cadenas y hubiera leido la información directamente desde la pantalla. Y hubiera prescindido de muchas variables y hubiera escrito los valores directamente sobre el código BASIC. Y en vez de haber utilizado pantallas con puntos gordos hubiera utilizado la pantalla de carga del Phantis. Y... y... y...

na_th_an escribió:6.- Es posible usar musica desde BASIC, incluso sin compilar. Casi todos los players se llaman con un RANDOMIZE USR simple y lo que hacen es actualizar "un frame" la partitura, de forma que con

Código: Seleccionar todo

10 RANDOMIZE USR direccion: PAUSE 1: GOTO 10

tienes la música sonando. Con colocar las llamadas en sitios estratégicos tienes solucionado el problema. Fíjate, si no, en los juegos de Beyker que tienen música de fondo.

De nuevo metes el C/M por en medio. Incluso código de terceros, ni siquiera original escrito por ti... :P
Te digo lo mismo: estaba pensando en BASIC interpretado sin nada de C/M.

na_th_an escribió:7.- Su usas POKE/PEEK para gestionar tus datos, puedes usar compresión (Aplib, Pucrunch, etcétera...) y meter incluso más cosas.

C/M, C/M, C/M
No quiero ni pensar en ejecutar un descompresor de esos de a nivel de bits corriendo en BASIC interpretado...

na_th_an escribió:8.- Si usas BASIC compilado puedes dividirlo en módulos independientes que se comuniquen mediante una zona común de RAM. Esos bloques pueden ser compilados independientemente y almacenados en diferentes páginas de la RAM.

Compilado, compilado, compilado


Que sí, que estoy de acuerdo contigo: lo de paginar esta cojonudo siempre que utilices el código máquina, ya sea bien porque tienes un reproductor de música corriendo por interrupciones de fondo, ya sea porque el código máquina lo has obtenido a base de compilar un fuente escrito en BASIC.
Pero el post de titula "Usando los 128K desde BASIC - paginación", por lo que yo he dado mis opiniones para el caso de BASIC lindo y morondo, BASIC Sinclair interpretado en un Spectrum de 128k.
Si ya pasas a utilizar BASIC compilado ¿por qué entonces limitarse a paginar sólo la última página de 16k? ¿Por que no utilizar ya el doble buffer de la pantalla? ¿Por qué no pasar de la ROM y disponer las páginas para tener el espacio de 64k todo disponible en RAM?
Radastan ha explicado como utilizar la paginación desde BASIC en BASIC.
Yo he dado mi opinión sobre lo que me parece utilizar dicha paginación desde BASIC en BASIC.
Tu hablas de lo útil que es la paginación para el código máquina.
Por mi parte estoy de acuerdo en todo (sobre todo con mi opinión :P).

Avatar de Usuario
Forni
Herbert
Mensajes: 53
Registrado: Mar May 08, 2007 9:03 am
Ubicación: Madrid

Re: Usando los 128K desde BASIC - paginación

Mensaje por Forni » Mar Mar 11, 2008 9:35 pm

Perdona, no me he podido resistir...

na_th_an escribió:Y luego, si programas bien pasando de arrays, cadenas, DATAs y demás cosas lentas y costosas en espacio (o sea, a pelo con PEEK y POKE) esto es la repanocha.


En mi opinión programar bien no se reduce a utilizar los recursos a pelo. Programar bien consiste en utilizar los recursos de los que dispones de la manera más eficiente posible.

Yo personalmente opino que en el concurso de Radastan hay ejemplos de juegos que están muy bien programados, no utilizan ni un solo PEEK o POKE y son la repanocha.

Un array o cadena, en BASIC o en C/M es igual de costoso en espacio.

Es cierto que los DATAS son una manera muy lenta de manejar la información. Además crea información redundante, pues cuando lees un data lo sueles meter en una variable o pokearlo en algún sitio: hale, ya tienes los datos duplicados y encima seguro que los datas ocupan más.

Pero si tienes que pintar una pantalla entera (por poner un ejemplo), esto:

Código: Seleccionar todo

10 print a$

es infinitamente más rápido que esto:

Código: Seleccionar todo

10 for f=0 to 740
20 print chr$ peek dir+f
30 next f

Creo que hasta compilado, si el compilador es bueno y está bien programado, la primera opción debería de ser más rápida.

Eso sin contar que con la primera opción puedes utilizar los caracteres de control AT, TAB, INK, PAPER, OVER, FLASH, BRIGHT, CURSOR IZQUIERDA, ENTER... que en la segunda versión te implicarían utilizar más código que los contemplase (ergo, más lentitud).

Todo depende de lo que hagas y de como lo hagas.

Esta claro que un PEEK o un POKE quedan traducidos de manera inmediata a un LD en código máquina. Pero el utilizar cadenas en BASIC, cuando sólo estás utilizando BASIC y sus recursos, te dota de mucha flexibilidad a la hora de tratar con datos. Sobre todo porque el calculador de cadenas que tiene el BASIC de nuestro querido Spectrum es la repanocha (todo, siempre, según mi humilde opinión personal y seguramente intransferible).

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

Re: Usando los 128K desde BASIC - paginación

Mensaje por na_th_an » Mié Mar 12, 2008 9:52 am

No sé, aquí se habla de BASIC, no se especificaba que tuviese que ser PURO.

Avatar de Usuario
radastan
Phantomas
Mensajes: 2232
Registrado: Lun May 07, 2007 5:34 pm
Contactar:

Re: Usando los 128K desde BASIC - paginación

Mensaje por radastan » Mié Mar 12, 2008 10:10 am

Bien, voy a aclarar el porqué de este tutorial:

En primer lugar porque a mi mismo me sirve, mi motor 3D de aventuras está más basado en datos que en cadenas, lo que más necesita es gráficos y este tipo de paginación le viene de perlas y mucho mejor que usando el disco RAM. Lo único que uso con matrices BASIC es el mapa del escenario, ya que se accede un pelín más rápido que usando peek/poke. Hablo de BASIC puro, sin compilar, ojo. Es decir, hay determinadas situaciones en las que es más cómodo y útil hacer tu mismo la paginación desde BASIC que usar el dico RAM.

De igual forma, este sistema de paginar desde BASIC viene perfecto a los que usan BASIC compilado... pero claro, y aquí viene el problema: ¿el basic compilado usa las variables del BASIC o las traslada a ensamblador? porque si no usa las variables del BASIC y la ROM no las actualiza, el poke no sirve de nada.

Haced una prueba los que uséis BASIC compilado, un clear, un poke en la memoria alta, pasad página, leed el contenido y lo poneis en pantalla con print, volved a la primera página, otro print de lectura... debería aparecer 0 cuando leéis en una página que no se ha tocado, y el valor correcto pokeado al volver.
_________________________________________
Hay otras páginas.... pero no son Bytemaniacos
http://www.bytemaniacos.com
Orgullo de 8 bits
_________________________________________

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

Re: Usando los 128K desde BASIC - paginación

Mensaje por na_th_an » Mié Mar 12, 2008 1:44 pm

El BASIC compilado con Hisoft tiene sus propias variables (de hecho hay que definirles el tipo y puedes especificar donde ponerlas). Por defecto se colocan entre RAMTOP y el final del código (Hisoft acomoda el código que genera justo debajo de RAMTOP por defecto).

Responder

¿Quién está conectado?

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