[vc_row][vc_column][vc_column_text]
NestorBASIC versión 1.10
Por Néstor Soriano (Konami Man), Junio 2.004
1. ¿QUE ES NESTORBASIC?
NestorBASIC es un paquete de rutinas en código máquina, integrado en un único fichero, pensado para ser usado en programas BASIC. NestorBASIC proporciona, sin perder la compatibilidad con el Turbo-BASIC, la siguiente funcionalidad:
– Acceso a toda la memoria mapeada del ordenador (a toda la memoria libre en caso de tener DOS 2), hasta 4 Mb.
– Acceso a toda la VRAM, con intercambio de bloques de datos entre ésta y RAM.
– Almacenamiento de diversos programas BASIC en la memoria mapeada, con posibilidad de pasar de uno a otro sin perder las variables.
– Acceso a ficheros de disco y acceso directo a sectores, con lectura/escritura directamente a/de la memoria mapeada y VRAM. Búsqueda de ficheros, gestión de directorios.
– Compresión/descompresión de gráficos.
– Reproducción de música MoonBlaster. Carga de samplekits.
– Reproducción de efectos de sonido PSG.
– Ejecución de rutinas en código máquina situadas en la BIOS, en la SUB-BIOS, en la memoria normal del BASIC, en la zona de trabajo del sistema, o en un segmento de RAM mapeada.
– Ejecución de funciones de NestorMan y rutinas de InterNestor Suite e InterNestor Lite.
Todas estas funciones son accesibles a través de un único USR y una matriz entera de parámetros, por lo que pueden usarse sin problemas desde dentro de turbo bloques. De hecho, el propio TurboBASIC está incluido en el fichero de NestorBASIC, y se carga automáticamente al instalar éste.
NestorBASIC se instala en un segmento de RAM oculto al BASIC, y sólo requiere un espacio de unos 500 bytes en la memoria principal del BASIC para una rutina de salto. El resto de la memoria principal queda libre para el programa BASIC.
2. REQUERIMIENTOS Y CARGA
NestorBASIC funciona en cualquier MSX2/2+/TR con al menos 128K de RAM mapeada. En el caso del DOS 2 ha de haber al menos un segmento libre en el mapeador primario (dos si se van a usar los reproductores musicales. Ver sección 8 para más detalles).
Cargar NestorBASIC es tan fácil como hacer BLOAD»NBASIC.BIN»,R, sin necesidad de ningún CLEAR ni ningún DEFUSR ni antes ni después de la carga. Si no ha habido ningún error ha ocurrido lo siguiente:
– NestorBASIC y el Turbo-BASIC se han instalado en sendos segmentos de RAM, quedando ambos listos para su uso.
– La memoria disponible para el BASIC se ha reducido en unos 500 bytes, que han sido ocupados por una rutina de salto al segmento del NestorBASIC.
– El primer USR [USR0(parámetro) o simplemente USR(parámetro)] apunta a la rutina de salto. Será el gancho de llamada a las funciones de NestorBASIC.
– Se ha creado la matriz entera P, de 15 elementos. Esta matriz se usará para pasar parámetros a y devolver los resultados de las funciones de NestorBASIC, excepto los códigos de error, que serán devueltos a través del comando USR (las funciones de acceso a ficheros y las de tratamiento de cadenas también usan una matriz de cadenas, que hay que definir por separado; más detalles en la sección 4). Los cinco primeros elementos de P han sido inicializados como sigue:
P(0) | Número de segmentos de RAM disponibles, o código de error |
P(1) | Versión principal de NestorBASIC |
P(2) | Versión secundaria de NestorBASIC, en formato BCD (visualizar en formato hexadecimal) P(3) = Versión principal de MSX-DOS |
P(4) | Versión secundaria de MSX-DOS, en formato BCD (visualizar en formato hexadecimal) |
El número de segmentos de RAM disponibles siempre será 5 como mínimo. Un número inferior indica un error que ha impedido la instalación:
0 | El ordenador no tiene memoria mapeada, o sólo tiene 64K de memoria mapeada. |
1 | Error de disco al intentar leer NestorBASIC o el Turbo-BASIC del fichero. |
2 | No hay ningún segmento libre en el mapeador primario. Este error sólo puede aparecer bajo DOS 2. |
3 | NestorBASIC ya estaba instalado. Las variables han sido inicializadas. |
4 | Futuras aplicaciones (dedicado a mis fans). |
Tras la instalación de NestorBASIC es posible reservar memoria para otras rutinas residentes mediante el procedimiento habitual, es decir, el uso de la instrucción CLEAR para especificar el inicio de la zona reservada. Sin embargo, debido a que NestorBASIC realiza cambios de slot/segmento en la página 2 y el intérprete BASIC sitúa la pila en una zona anterior a la zona de cadenas y a la zona reservada por el usuario, existe un límite inferior para la dirección a especificar en el comando CLEAR. En concreto, no se puede reservar memoria por debajo de la dirección indicada por la siguiente fórmula:
&HC000 + (MAXFILES+1)*267 + FRE("") + 100
También hay que tener tener en cuenta que la instrucción CLEAR, así como la carga de otro programa BASIC, borran las variables. En ese caso habrá que volver a definir la matriz de parámetros (DEFINT P:DIM P(15), esto ha de hacerse fuera de turbo-bloques) y, si es necesario, la matriz F (justo después del inicio del turbo-bloque en caso de usar turbo-BASIC) para poder seguir usando las funciones de NestorBASIC:
10 'save"autoexec.bas"
20 BLOAD"nbasic.bin",R:IF P(0)<5 THEN PRINT "Error!":END
30 CLEAR 100:DEFINT P:DIM P(15)
40 _TURBO ON(P())
50 DIM F$(1) 'Para las funciones de acceso a ficheros. Ver sección 4.
...
65000 _TURBO OFF
65010 RUN"next.bas"
10 'save"next.bas"
20 DEFINT P:DIM P(15)
30 _TURBO ON(P())
40 DIM F$(0) 'Si no se va a usar F$(1). Ver sección 4.1.
...
65000 _TURBO OFF
También hay que tener en cuenta que NestorBASIC siempre utiliza el primer USR como gancho de llamada, por lo que no debe modificarse. USR1 a USR9 quedan libres.
3. SEGMENTOS LOGICOS
3.1. QUE ES UN SEGMENTO LOGICO?
La memoria RAM mapeada de los MSX se estructura en segmentos de 16K. Cada slot de RAM contiene un número S de segmentos (0 a S-1), accesibles mediante su conexión al espacio de direccionamiento por medio de los puertos &HFC a &HFF, previo establecimiento del slot correspondiente.
Al instalarse, NestorBASIC busca toda la RAM mapeada utilizable (toda la existente en el caso del DOS 1, sólo la libre en el caso del DOS 2) y construye una tabla en la que constan todos los segmentos encontrados y el slot en el que se encuentran (bajo DOS 2, los segmentos son reservados antes). Cada pareja slot-segmento se identifica con su número de orden en la tabla. Este número se denomina número de segmento lógico, y permite al usuario manejar toda la RAM disponible de forma ordenada y sin preocuparse del slot o slots en que se encuentra.
Por ejemplo, supongamos un MSX con 128K de memoria interna (8 segmentos), y 1024K (64 segmentos) en un slot externo. Una vez instalado NestorBASIC en este ordenador, y suponiendo DOS 1, el usuario dispone de 72 segmentos lógicos numerados de 0 a 71, y no tiene más que indicar este número en las funciones correspondientes de NestorBASIC cuando quiera usarlos. En ningún momento se manejan números de slot o segmento «físico».
El rango de direcciones de un segmento lógico (simplemente «segmento» a partir de ahora) es &H0000 a &H3FFF. Si se especifican direcciones superiores serán transformadas al rango adecuado al ejecutarse la función, es decir, las direcciones &H4000-&H7FFF, &H8000-&HBFFF y &HC000-&HFFFF equivalen a &H0000-&H3FFF.
Todos los segmentos pueden ser leídos y escritos, pero existen importantes restricciones con respecto a los seis primeros:
– El segmento 0 contiene el propio NestorBASIC, y sólo queda libre para el usuario una pequeña zona al final del mismo. La dirección inicial de dicha zona puede averiguarse con la función 1 (ver listado de funciones).
– El segmento 1 contiene el Turbo-BASIC. Sólo puede ser modificado si no se va a usar el compilador.
– El segmento 2 está conectado a la página 2 (direcciones &H8000 a &HBFFF), siendo por tanto el que alberga el programa BASIC en ejecución y parte de las variables del mismo.
– El segmento 3 está permanentemente conectado a la página 3 (direcciones &HC000 a &HFFFF), y contiene la zona de trabajo del sistema y algunas de las variables del programa BASIC. Peligrosísimo escribir aquí sin estar seguro de lo que se hace.
– El segmento 4 es usado como buffer interno por algunas funciones de NestorBASIC. Puedes usarlo para almacenar tus propios datos siempre que no uses tales funciones. Consulta la sección 10 o el apéndice 1 para saber qué funciones usan este segmento.
– Si existe, el segmento 5 está inicialmente libre, y no es usado por NestorBASIC. Pero si se inicializan los reproductores musicales, éstos quedan cargados en este segmento. Ver sección 8 para más detalles.
El resto de segmentos quedan totalmente a disposición del programador.
ATENCIÓN: Los papeles de los segmentos lógicos 2 y 4 se han intercambiado con el paso de la versión 0.07 a la 1.00 de NestorBASIC. En la versión 0.07 y anteriores, el segmento 2 correspondía al buffer interno de NestorBASIC, y el 4 correspondía a la memoria para el BASIC en página 2.
Al usar las funciones de intercambio de bloques hay que tener cuidado de no sobrepasar la dirección &H3FFF al sumar la dirección de destino y la longitud del bloque a transferir (por ejemplo, no hacer una transferencia de longitud &H2000 usando como dirección de destino &H3000), ya que en estos casos se
invade el segmento 0 o el 3 y los resultados son impredecibles.
Nota: mediante la función 80 es posible hacer que NestorBASIC reserve menos segmentos de memoria de los que hay disponibles, lo cual es útil bajo DOS 2 cuando se usan simultáneamente otros programas residentes que también necesitan reservar memoria (por ejemplo el RAM disk o NestorMan). Ver la sección 10 para la descripción de las funciones.
3.2. USO DE LA VRAM COMO SEGMENTOS LOGICOS
Para facilitar el uso de la VRAM como almacén de datos, ésta también es accesible mediante el uso de segmentos lógicos: si NestorBASIC indica que hay S segmentos disponibles, los segmentos 0 a S-1 son RAM mapeada, y los numerados como S a S+7 o S a S+3 se refieren a la VRAM (según la capacidad del ordenador, 128K o 64K).
Volviendo al ordenador del ejemplo anterior, tras instalar NestorBASIC o tras usar la función 1 (ver listado de funciones) se obtiene P(0)=72. Entonces, suponiendo 128K de VRAM, los segmentos 72 a 79 se refieren a la VRAM.
La correspondencia entre segmentos y direcciones VRAM es tal que los segmentos con número más alto se refieren a las direcciones VRAM más bajas, de forma que los últimos segmentos corresponden a la zona de visualización en pantalla cuando se trabaja en modo texto o con sólo una página en modo gráfico. Esto evita al programador tener que estar atento para saltarse el segmento correspondiente a la zona de visualización.
Siguiendo con el ejemplo anterior, si el programa funciona en SCREEN 0 (sólo se usan las primeras 16K de VRAM), los segmentos disponibles para guardar datos son del 4 al 78. En cambio, usando SCREEN 7 y sólo la página 0 (las primeras 64K de VRAM usadas), el rango de segmentos utilizables es 4 a 75.
Por supuesto, también hay funciones específicas para acceder a la VRAM e intercambiar datos entre ésta y cualquier segmento, o un fichero.
ATENCIÓN: Los segmentos VRAM pueden usarse igual que los segmentos normales para almacenar datos y programas BASIC, y para realizar transferencias entre segmentos o entre un segmento y un fichero/sectores, pero NO para los siguentes propósitos:
– Compresión/descompresión de gráficos
– Ejecución de una rutina de usuario
– Ejecución de una interrupción de usuario
– Reproducción de una efecto de sonido PSG
– Reproducción de una música
Cualquier intento de usar los segmentos VRAM para estos fines hará que las funciones correspondientes devuelvan un error de segmento inexistente.
3.3. EL SEGMENTO 255
El número de segmento lógico 255 tiene una función especial. No se refiere a ningún segmento de RAM o VRAM en particular, sino a la memoria normal del BASIC, es decir, las direcciones &H8000 a &HFFFF (sin que se aplique aquí la restricción ni la conversión de direcciones de los segmentos normales), que contienen el programa BASIC, las variables y la zona de trabajo del sistema.
Esto es útil por ejemplo para intercambiar datos entre un segmento y una matriz:
1 'Traspaso de 10 bytes del segmento 7, dirección inicial &H1000,
2 'a la matriz de enteros D.
3 '(Ver descripción de las funciones)
4 '
10 DEFINT D:DIM D(4) '5 datos enteros = 10 bytes
20 P(0)=7 'Segmento de origen
30 P(1)=&H1000 'Dirección inicial de origen
40 P(2)=255 'Segmento de destino=memoria principal
50 P(3)=VARPTR(D(0)) 'Dirección inicial de destino=matriz D
60 P(4)=10 'Longitud
70 J=USR(10) 'Llamada a la función 10 (transferencia entre segmentos)
3.4. MAPA DE SEGMENTOS
Como resumen de esta sección, he aquí la lista de segmentos disponibles y su descripción. S es el número de segmentos devuelto en P(0) al instalar NestorBASIC o al usar la función 1.
0 | Segmento de NestorBASIC |
1 | Segmento del Turbo-BASIC |
2 | Memoria del BASIC, página 2 (&H8000-&HBFFF) |
3 | Memoria del BASIC, página 3 (&HC000-&HFFFF) |
4 | Segmento buffer interno 5 a S-1: RAM Disponible para el programador (si S>5) Si se inicializan los reproductores musicales, éstos quedan cargados en el segmento 5 |
S | VRAM, direcciones &H1C000-&H1FFFF (64K VRAM: &HC000-&HFFFF) |
S+1 | VRAM, direcciones &H18000-&H1BFFF (64K VRAM: &H8000-&HBFFF) |
S+2 | VRAM, direcciones &H14000-&H17FFF (64K VRAM: &H4000-&H7FFF) |
S+3 | VRAM, direcciones &H10000-&H13FFF (64K VRAM: &H0000-&H3FFF) |
S+4 | VRAM, direcciones &H0C000-&H0FFFF (no disponible con 64K VRAM) |
S+5 | VRAM, direcciones &H08000-&H0BFFF (no disponible con 64K VRAM) |
S+6 | VRAM, direcciones &H04000-&H07FFF (no disponible con 64K VRAM) |
S+7 | VRAM, direcciones &H00000-&H03FFF (no disponible con 64K VRAM) |
S+8 a 254 | No disponibles (si S+8<255) |
S255 | Memoria del BASIC (&H8000-&HFFFF) |
3.5. ERRORES
Todas las funciones de acceso a segmentos y/o VRAM devuelven el error -1 si se especifica un segmento inexistente, si se intenta acceder a una dirección VRAM superior a &HFFFF en un ordenador con únicamente 64K de VRAM, o si se especifica un segmento de VRAM o el segmento 255 en funciones que sólo soportan segmentos normales.
4. ACCESO A DISCO
NestorBASIC incorpora funciones para el manejo de ficheros y el acceso a otras funciones de MSX-DOS, concretamente:
* Creación/borrado/renombrado/Búsqueda de ficheros.
* Lectura/escritura de ficheros a/desde cualquier segmento o zona de VRAM.
* Bajo DOS 2, movimiento y obtención/establecimiento de atributos para un fichero.
* Lectura/escritura de sectores a/desde cualquier segmento o zona de VRAM.
* Obtención/establecimiento de la unidad/directorio (bajo DOS 2) por defecto.
* Obtención de la capacidad y espacio libre de un disco.
* Bajo DOS 2, obtención de la capacidad/establecimiento del RAM disk.
4.1. LA MATRIZ F$
Para el paso de nombres de fichero y de directorio, estas funciones emplean una matriz de cadenas, F$. Cuatro de ellas (Búsqueda, renombrado y movimiento de ficheros, y tratamiento de una ruta de acceso) emplean dos cadenas, por lo que necesitan que F$ se haya definido con dos elementos [DIM F$(1)]. Las demás funciones sólo necesitan una cadena, por lo que si no se va a usar ninguna de esas cuatro funciones se puede definir F$ con un sólo elemento [DIM F$(0)]. Esto es especialmente recomendable en caso de usar Turbo-BASIC, pues dentro de los turbo-bloques cada cadena emplea 256 bytes de memoria, sea cual sea su longitud. también hay que tener en cuenta que la matriz F$ se ha de definir inmediatamente después del comienzo del turbo bloque:
1000 _TURBO ON(P())
1010 DIM F$(1) o DIM F$(0)
...
65000 _TURBO OFF
IMPORTANTE: Las variables de cadena definidas fuera de un turbobloque, al igual que el resto de variables, no son traspasadas al mismo, y se recuperan a su finalización. Por ejemplo:
10 A$="Fuera"
20 _TURBO ON
30 A$="Dentro":PRINT A$
40 _TURBO OFF
50 PRINT A$
run
Dentro
Fuera
NestorBASIC mantiene esta propiedad, pero las cadenas F$() requieren una precaución adicional. Si se ha usado la matriz F$ fuera del turbobloque y va a definirse dentro del mismo, hay que insertar la siguiente línea antes del CALL TURBO ON:
F$(0)=F$(0)+"":F$(1)=F$(1)+""
Esta precaución no es necesaria si no se tiene interés en conservar el contenido de F$ anterior al turbo-bloque, o si no se va a definir F$ dentro del mismo.
Otra limitación de F$(0) y F$(1) es que su longitud máxima es de 80 carácteres; los carácteres sobrantes serán ignorados por las funciones de NestorBASIC que tengan estas cadenas como parámetros de entrada. Todas estas limitaciones no se presentan para índices superiores a 1 si se define F$ con más elementos (es decir, es posible definir F$ con más de dos elementos y usar F$(2), F$(3)… normalmente).
4.2. ERRORES
Además del error -1, explicado en 3.5, las funciones de acceso a ficheros tienen también sus propios códigos de error.
Los siguientes errores sólo aparecen bajo DOS 1:
1: Error general del MSX-DOS 1. Puede deberse a varias causas:
– Fichero no encontrado.
– Nombre de fichero incorrecto.
– El fichero ya existe (al intentar renombrar un fichero).
– Unidad inexistente (formando parte de un nombre de fichero).
– Final de fichero encontrado al hacer una lectura del mismo.
– Disco lleno.
– Directorio raíz completo.
– Función no disponible bajo DOS 1.
Hay que tener en cuenta que bajo DOS 2 cada uno de los errores mencionados tiene un código de error específico, que en ningún caso es el 1.
2 | Número de fichero incorrecto (no se ha asignado ese número a ningún fichero abierto). |
3 | Hay demasiados ficheros abiertos. El número máximo de ficheros que pueden abrirse simultáneamente bajo DOS 1 puede consultarse mediante la función 1. |
Los siguientes errores son comunes al DOS 1 y al DOS 2, y tienen el mismo código que sus equivalentes BASIC:
60 | FAT incorrecta. |
62 | Unidad inexistente (al intentar cambiar la unidad por defecto). |
68 | Disco protegido contra escritura. |
69 | Error físico en el disco. |
70 | No hay disco. |
Los errores propios del DOS 2 son:
222 | No hay memoria libre para crear el RAM disk o para abrir el fichero. |
219 | Unidad inexistente (formando parte de una ruta/nombre de fichero) |
218 | Nombre de fichero incorrecto. |
217 | Ruta incorrecta. |
215 | Fichero no encontrado. |
214 | Directorio no encontrado. |
213 | Directorio raíz lleno. |
212 | Disco lleno. |
211 | El fichero ya existe (al intentar renombrar o mover un fichero). |
210 | Movimiento de directorio incorrecto (se ha intentado mover un directorio a uno de sus descendientes). |
209 | Fichero de sólo lectura (al intentar escribir). |
208 | El directorio no está vacío (al intentar borrarlo). |
207 | Atributos inválidos (al intentar cambiarlos). |
206 | Operación incorrecta sobre las entradas «.» o «..» |
205 | Existe un fichero de sistema con ese nombre (al crear un fichero o directorio se borra el preexistente, excepto si es de sistema). |
204 | Existe un directorio con ese nombre (lo mismo que con los ficheros de sistema). |
203 | Existe un fichero con ese nombre (al intentar crear un directorio). |
202 | El fichero está abierto (al intentar borrarlo, renombrarlo, moverlo, o cambiar sus atributos especificando directamente el nombre del fichero). |
199 | Se ha llegado al final del fichero (al leer del mismo). |
196 | Demasiados ficheros abiertos (al intentar abrir uno). |
195 | Número de fichero incorrecto (mayor de 63). |
194 | Número de fichero incorrecto (no se ha asignado ese número a ningún fichero abierto). |
188 | El RAM disk ya existe (al intentar crearlo). |
187 | El RAM disk no existe (al intentar borrarlo). |
5. COMPRESION Y DESCOMPRESION DE GRAFICOS
NestorBASIC incorpora funciones para la compresión de gráficos de VRAM a RAM, y su descompresión de RAM a VRAM. El formato de compresión es el que utiliza Sunrise (o al menos utilizaba) en la rutina de aparición de su logotipo, trabaja por bytes y es el siguiente:
– Bytes sin repetir (hasta 63):
&B00nnnnnn &Hdd .. &Hdd
&Bnnnnnn es el número de bytes, &Hdd son los bytes
– Byte repetido hasta 63 veces:
&B01nnnnnn &Hdd
&Bnnnnnn es el número de repeticiones, &Hdd es el byte
– Byte repetido hasta 16383 veces:
&B10nnnnnn &Bnnnnnnnn &Hdd
&Bnnnnnnnnnnnnnn es el número de repeticiones, &Hdd es el byte
– Marca de final de los datos:
&B11000000 = &HC0
La (des)compresión se realiza a través de segmentos consecutivos; es decir, tras (des)comprimir de/a la posición &H3FFF del segmento S, se continúa con la posición &H0000 del segmento S+1.
5.1 ERRORES
Los errores que pueden devolver las rutinas de compresión y descompresión de gráficos son:
-1 | Error al comprimir o descomprimir. No existe el segmento o la dirección VRAM especificadas en los parámetros de entrada, o bien el segmento especificado corresponde a VRAM o es el 255 (segmentos no utilizables por estas funciones). |
5 | Error al comprimir. No hay segmentos suficientes para comprimir toda la imagen. |
6 | Error al descomprimir. Se ha encontrado un dato incorrecto, o se han acabado los segmentos. |
6. ALMACENAMIENTO DE PROGRAMAS BASIC EN RAM
NestorBASIC incorpora funciones que permiten el almacenamiento de programas BASIC en cualquier segmento de RAM o VRAM, y la activación o la ejecución de los mismos manteniendo intactas las variables del programa original (el que realiza el salto al nuevo).
MUY IMPORTANTE: Para poder usar estas funciones hay que cambiar la dirección de comienzo de los programas BASIC, originalmente &H8000, a &H8003; esto ha de hacerse sólo una vez, ANTES de cargar NestorBASIC. Hay dos formas de realizar este cambio:
– En modo directo, teclear lo siguiente:
POKE &HF676,4
POKE &H8003,0
NEW
– Desde un programa BASIC. Esta es la mejor opción, ya que puede ser el mismo programa que cargue NestorBASIC. La primera línea del programa ha de ser como sigue:
1 'programa.bas
10 IF PEEK(&HF676)<>4 THEN POKE &HF676,4:POKE &H8003,0:RUN"programa.bas"
20 'A partir de aquí ya se puede cargar NestorBASIC
Cuando un programa almacenado en un segmento va a ser activado o ejecutado, NestorBASIC guarda las variables y las matrices en el segmento 4; posteriormente copia el programa del segmento deseado a la memoria normal del BASIC, y coloca las variables antes guardadas al final del mismo, tras lo cual actualiza los punteros apropiados de la zona de trabajo. El último paso es la ejecución del programa desde la primera línea o bien el salto al modo directo, según la función usada (ejecución o activación).
Para que un programa BASIC pueda ser almacenado en un segmento y posteriormente activado o ejecutado, debe ser almacenado con una cabecera especial con información sobre su longitud, imprescindible para poder concatenarle las variables ya existentes. Existe una función que permite grabar el programa BASIC activo en un fichero con esa cabecera; posteriormente, basta cargar dicho archivo en cualquier segmento con las funciones de acceso a disco, y el programa ya estará listo para ser activado o ejecutado en cualquier momento.
6.1 ERRORES
Evidentemente, si se ejecuta la instrucción o línea siguiente al USR que ordena la activación o ejecución de otro programa BASIC, nos encontramos ante una situación de error. Hay dos posibles errores:
Error -1 | si no se existe el segmento especificado. Estas funciones soportan segmentos VRAm, pero no el segmento 255. |
Error -2 | si la memoria del BASIC es insuficiente para albergar el nuevo programa y las variables. Puede ocurrir si el programa activado o ejecutado es más largo que el original. |
7. FUNCIONES VARIAS
En este grupo se engloban funciones para:
– Ejecución de rutinas en código máquina de la BIOS, la SUB-BIOS, la memoria del BASIC, la zona de trabajo del sistema, o bien rutinas almacenadas en segmentos (denominadas aquí «rutinas de usuario»).
– Almacenamiento y posterior recuperación de cadenas en segmentos.
– Impresión de una cadena en modo gráfico.
– Tratamiento de bloques parpadantes (modo «blink») en SCREEN 0.
– Definición de una interrupción de usuario (una rutina en código máquina contenida en un segmento, que será ejecutada en cada interrupción del reloj).
– Ejecución de efectos de sonido PSG creados con SEE versión 3.xx
Algunas de estas funciones usan una matriz de cadenas, F$, para el paso de parámetros, además de la matriz P. Ver sección 4 para más detalles acerca de F$.
Algunas de las rutinas internas de NestorBASIC pueden ser usadas por las rutinas de usuario y por la interrupción de usuario. En el apéndice 2 se detalla la ubicación y el funcionamiento de dichas rutinas.
El editor de efectos de sonido SEE ha sido creado por Fuzzy Logic y el uso de los efectos así creados en programas comerciales implica el pago de una pequeña cantidad de dinero a los autores. Más detalles en el apéndice 4.
8. REPRODUCCION DE MUSICAS
8.1. INICIALIZACION DEL REPRODUCTOR
NestorBASIC incorpora un reproductor de músicas Moonblaster 1.4 y uno de Moonblaster para MoonSound, versión Wave 1.05.
Dichos reproductores no son cargados automáticamente cuando NestorBASIC es cargado, dado que por su gran longitud no caben en el segmento de NestorBASIC y ha residir en un segmento aparte. Por tanto, para poder usar un reproductor hay que cargarlo explícitamente. sólo se puede tener cargado uno a la vez.
La función 71 se encarga de cargar e inicializar el reproductor deseado, dejándolo listo para su uso. Dicha función comprueba si el segmento 5 existe y pertenece al mapeador primario, en cuyo caso carga el reproductor en dicho segmento, que deja de estar disponible para el usuario. Si el segmento 5 no existe, o si existe pero no pertenece al mapeador primario, el reproductor no será cargado y la función devolverá un error.
El fichero NBASIC.BIN contiene dos versiones del reproductor de Moonblaster Wave: una es para ordenadores MSX2/2+ y para el Turbo-R en modo Z80, y la otra es para el Turbo-R en modo R800. En el caso del Turbo-R, NestorBASIC decide qué versión cargar en función del procesador que está activo en el momento de ejecutar la función 71. Hay que tener en cuenta que si se realiza un cambio de procesador es necesario volver a ejecutar esta función, ya que la versión Z80 no funciona en modo R800 y la versión R800 introduce en modo Z80 un ralentizamiento innecesario del sistema.
Cuando el reproductor es cargado también se realiza una búsqueda de chips musicales, y todos los encontrados quedan activos. Ver descripción de la función 73 para más detalles sobre la activación y desactivación de chips musicales.
8.2. FUNCIONALIDADES DEL REPRODUCTOR
Una vez que el reproductor está cargado, pueden usarse las funciones que NestorBASIC incorpora para:
– Comenzar la reproducción de una música previamente cargada en un segmento (que NO puede ser un segmento VRAM).
– Detener la reproducción de la música que está sonando.
– Pausar/continuar la música que está sonando.
– Desvanecer la música que está sonando, con elección de la velocidad de desvanecimiento.
– Obtener información sobre la música que está sonando (segmento y dirección inicial, título y samplekit o wavekit, posición y paso actuales).
– Obtener información sobre los chips musicales detectados.
– Desactivar los chips musicales, de forma que no sean usados aunque hayan sido detectados, y volver a activarlos.
– Cargar un samplekit de Music Module o un wavekit de MoonSound desde un fichero.
Mientras una música está sonando pueden usarse todas las funciones de NestorBASIC, incluyendo la reproducción de efectos de sonido y el uso de interrupciones de usuario. Si se desinstala NestorBASIC, la música que está sonando quedará automáticamente interrumpida.
El reproductor de Moonblaster 1.4 ocupa sólo 4.5K, por lo que el espacio entre las direcciones &H1200 y &H3FFF del segmento 5 queda libre y puede usarse, por ejemplo, para almacenar la música que va a ser reproducida. Esto no ocurre con el reproductor de Moonblaster Wave, que ocupa la totalidad del segmento 5.
En el caso de músicas Moonblaster 1.4, la música ha de estar almacenada en un único segmento, por lo que no puede ser mayor de 16K. Las músicas Moonblaster Wave pueden estar almacenadas a través de segmentos consecutivos, como máximo tres: si al leer datos de una música para su reproducción NestorBASIC llega a la dirección &H3FFF de un segmento, continuará en la dirección 0 del segmento siguiente.
Para cargar una música a través de segmentos consecutivos se puede usar por ejemplo un listado como este:
1000 'Carga de una musica a traves de segmentos consecutivos,
1010 'empezando en el segmento S, direccion D
1020 F$(0)="musica.mwm":P(2)=S:P(3)=D
1030 E=USR(31):IF E<>0 THEN 10000
1040 P(4)=&H4000:E=USR(33)
1050 IF (E<>0 AND E<>1 AND E<>199) THEN 10000
1060 IF E=0 THEN P(2)=P(2)+1:P(3)=0:GOTO 1040
1070 E=USR(32):IF E<>0 THEN 10000
...
10000 'Rutina de tratamiento del error de disco E
...
ATENCIÓN: Una música Moonblaster Wave puede comenzar en cualquier dirección de un segmento, siempre que continúe en el principio del segmento siguiente. Sin embargo al menos los primeros 800 bytes de la música, que contienen la tabla de patrones y diversos punteros, han de estar íntegros en el primer segmento.
8.3 ERRORES
Los errores devueltos por las funciones de reproducción musical son:
Error 7 | devuelto por las funciones de establecimiento de chips, de pausa y de desvanecimiento de la música si uno de los parámetros de entrada es incorrecto. |
Error 12 | devuelto por las funciones de inicio de una música y activación/desactivación de chips si el reproductor no ha sido cargado. El resto de funciones no devueven error en este caso, simplemente no hacen nada. |
Los siguientes errores son devueltos por la función de inicio de una música:
-1 | El segmento lógico especificado no existe, corresponde a VRAM o es el 255. |
12 | El reproductor no ha sido cargado. |
13 | La música ha sido grabada en modo EDIT y no puede ser reproducida (reproductor Moonblaster 1.4). En la dirección especificada no hay una música Moonblaster Wave, o bien hay una música Moonblaster Wave grabada en modo EDIT (reproductor Moonblaster Wave). |
14 | Ya hay una música en reproducción. |
La función de carga de un wavekit de Moonsound puede devolver el siguiente error, además de los errores de las funciones de acceso a disco:
15: En la posición actual del fichero especificado no hay un wavekit Moonblaster, o bien hay un wavekit que no ha sido grabado en modo USER.
NOTA: El reproductor de Moonblaster 1.4 no puede detectar si en la dirección especificada hay realmente una música Moonblaster, y se fía únicamente del byte inicial para decidir si en dicha dirección comienza una música en modo EDIT. El reproductor de Moonblaster Wave no tiene estas limitaciones.
La función de carga del reproductor devuelve los mismos errores que las funciones de acceso a disco, y el error -1 si el segmento 5 no existe o no pertenece al mapeador primario.
9. INTERACCION CON NESTORMAN E INTERNESTOR SUITE/LITE
NestorBASIC dispone de funciones especiales para la interacción con NestorMan (gestor residente de memoria dinámica para MSX-DOS 2), InterNestor Suite (pila TCP/IP para MSX-DOS 2) e InterNestor Lite (pila TCP/IP para MSX-DOS 1/2), si estos programas están instalados. De esta forma es posible desarrollar en BASIC aplicaciones que hagan uso de bloques de memoria dinámica y listas encadenadas, así como aplicaciones basadas en Internet. Para saber si NestorMan e InterNestor Suite están instalados se puede usar la función 81; el procedimiento para detectar si InterNestor Lite está instalado se detalla en la sección 9.4.
Nota: NestorMan e InterNestor Suite/Lite tienen sus propios manuales, donde se describen las funciones y rutinas que proporciona cada uno. Estos programas están disponibles en http://msx.konamiman.com.
9.1. SEGMENTOS DE NESTORBASIC Y SEGMENTOS DE NESTORMAN
NestorMan usa un sistema de segmentos lógicos muy similar al usado por NestorBASIC. Ambos espacios de segmentos, el de NestorBASIC y el de NestorMan, son independientes entre sí, con las siguientes excepciones:
– Los segmentos 0, 1, 2 y 3 son comunes a NestorBASIC y a NestorMan (en el manual de NestorMan, estos segmentos se denominan «segmentos de TPA»).
– Si NestorMan está presente cuando NestorBASIC es instalado, el segmento lógico 4 de NestorBASIC no se reserva usando las rutinas de soporte del mapeador del DOS 2, como el resto de los segmentos. En vez de eso, se reserva usando la función 7 de NestorMan; de esta forma, el segmento 4 de NestorBASIC tiene asignado a su vez un número de segmento en NestorMan (dicho número puede consultarse mediante la función 81 de NestorBASIC). El segmento es reservado con el atributo «exclusivo», por lo que no es usado por NestorMan para realizar reservas de bloques de memoria.
Si se va a usar NestorMan (y/o InterNestor Suite) junto con NestorBASIC, es recomendable limitar la cantidad de segmentos de RAM que usará NestorBASIC mediante la función 80. De lo contrario, NestorBASIC reservará para sí mismo todos los segmentos disponibles, y NestorMan no podrá realizar reservas de segmentos de RAM (necesarias para realizar reservas de bloques de memoria, crear listas encadenadas y enviar/recibir datos a/desde Internet).
Para ejecutar las funciones de NestorMan se puede usar la función 82; o bien se puede usar la función 58 especificando el gancho de la BIOS extendida (&HFFCA) como dirección a llamar, &H2202 en el par de registros DE, y el número de función en el registro C. Ver la sección 10 para la descripción de las funciones.
9.2. INTERCAMBIO DE DATOS ENTRE NESTORBASIC Y NESTORMAN
Al usar NestorMan a través de NestorBASIC, normalmente se necesitará hacer traspasos de datos entre un segmento de NestorBASIC y uno de NestorMan. Hay tres formas de hacer esto:
1) Si el segmento de origen o el de destino es de TPA (número de segmento 0 a 3), basta usar la función adecuada de NestorMan para el traspaso de un bloque de datos, dado que NestorMan ya ve estos segmentos.
2) Se puede usar el segmento 4 de NestorBASIC como buffer intermedio para el traspaso. Por ejemplo, supongamos un traspaso de NestorBASIC a NestorMan. S1 es el segmento de origen de NestorBASIC, S2 es el segmento de destino de NestorMan, y S3 es el número del segmento 4 desde el punto de vista de NestorMan. Entonces, primero se haráa una transferencia S1->4 usando la función de transferencia de bloques de NestorBASIC (función 10), y después se hará una transferencia S3->S2 usando la función de transferencia de bloques de NestorMan (función 14).
3) Las funciones de NestorBASIC 83 y 84 realizan una transferencia de un bloque de datos de un segmento de NestorMan a un segmento de NestorBASIC y viceversa.
Para leer o escribir únicamente un byte de datos de un segmento de NestorMan, lo más fácil es usar las funciones que el mismo proporciona para este propósito (funciones 12 y 13, respectivamente).
Recuerda que algunas funciones de NestorBASIC usan el segmento 4 como buffer para el almacenamiento temporal de datos. Para saber qué funciones usan el segmento 4, consulta la sección 10 o el apéndice 1.
9.3. USO DE INTERNESTOR SUITE
Las técnicas para usar InterNestor Suite desde NestorBASIC son similares a las técnicas descritas anteriormente para usar NestorMan. Únicamente hay que tener en cuenta lo siguiente:
– La función 85 permite ejecutar las rutinas de InterNestor Suite.
– Para leer y escribir datos de los segmentos de InterNestor Suite (constantes de configuración y variables), primero hay que averiguar mediante la función 81 los números de segmento de los módulos de InterNestor Suite (cada módulo reside en un segmento de NestorMan), y a partir de ahí usar las técnicas de intercambio de datos explicadas en la sección anterior.
– Las rutinas de InterNestor Suite para leer/escribir datos TCP o datagramas UDP sólo admiten segmentos TPA como orígen/destino para los datos o datagramas. Para este propósito se puede usar la porción final del segmento de NestorBASIC (segmento 0) como zona intermedia de almacenamiento. Esta zona siempre tendrá una longitud mínima de 600 bytes, sea cual sea la versión de NestorBASIC usada; esto es suficiente para almacenar datagramas estándar de hasta 576 bytes de longitud (o para almacenar un bloque de datos TCP de hasta 600 bytes).
El programa de ejemplo TCPCON-S.BAS, suministrado con NestorBASIC, ilustra el uso conjunto de NestorBASIC e InterNestor Suite.
9.4. USO DE INTERNESTOR LITE
InterNestor Lite es un programa mucho más sencillo que InterNestor Suite, por tanto su uso desde NestorBASIC también es más sencillo. Se proporciona una única función, la 86, que permite ejecutar cualquier rutina del segmento de código de InterNestor Lite. Para leer o escribir en su segmento de datos, es necesario usar las rutinas GET_VAR, SET_VAR y COPY_DATA del segmento de código.
Para saber si InterNestor Lite está instalado, se debe usar la función 58 para hacer una llamada al gancho de la BIOS extendida (dirección &HFFCA), pasando A=0 y DE=&H2203. Si la llamada devuelve A<>0, entonces InterNestor Lite está instalado. Ver la descripción de la función 86 para más detalles.
Muchas de las rutinas de InterNestor Lite usan direcciones de TPA como origen o destino para el intercambio de datos con las aplicaciones. Para estas rutinas se pueden especificar direcciones superiores a &H8000, que harán referencia a la memoria principal del BASIC y a la zona de trabajo del sistema; o bien direcciones inferiores a &H4000, que harán referencia al segmento de NestorBASIC.
Al final del segmento de NestorBASIC hay una zona libre, cuyo tamaño varía entre versiones de NestorBASIC pero que siempre será de al menos 600 bytes, que puede usarse como zona de almacenamiento temporal para intercambiar datos con InterNestor Lite. En otras palabras, puede usarse el espacio entre &H3DA8 y &H3FFF como origen o destino TPA para una transferencia de datos entre NestorBASIC e InterNestor Lite.
El programa de ejemplo TCPCON-L.BAS, suministrado con NestorBASIC, ilustra el uso conjunto de NestorBASIC e InterNestor Lite.
9.5. ERRORES
La función 86 (llamada a una función de InterNestor Lite) devolverá el error -1 si InterNestor Lite no está instalado.
La función 85 (llamada a una función de InterNestor Suite) devolverá el error -1 si InterNestor Suite no está instalado, o si se especifica un número de módulo inválido (los números de módulo válidos son del 1 al 4).
Las funciones 83 y 84 (transferencia de un bloque de datos entre un segmento de NestorMan y un segmento de NestorBASIC) devuelven el error -1 si se especifica un número de segmento (de NestorMan o de NestorBASIC) de origen o de destino inexistente. Pueden usarse los segmentos VRAM y el segmento 255 con estas funciones.
Las funciones 80, 81 y 82 nunca devuelven error.
10. LAS FUNCIONES DE NESTORBASIC
10.1. DESCRIPCION GENERAL
Las funciones que componen NestorBASIC se identifican con un número que se pasa como parámetro a través de la instrucción USR. Así, para usar la función F basta hacer USR(F), teniendo en cuenta que en caso de usar una variable para especificar la función, dicha variable ha de ser de tipo entero. Los parámetros para las funciones han de ser establecidos en la matriz P (y, dado el caso, en la matriz F) antes de la llamada a la función. Análogamente, los resultados devueltos por la función se encontrarán en P y/o en F.
Los elementos de P y F que no se mencionan explícitamente en la lista de resultados de cada función no resultan modificados, excepto las direcciones de segmento, que son convertidas al rango &H0000-&H3FFF si lo sobrepasaban (las direcciones del segmento 255 nunca son convertidas). Salvo que se especifique lo contrario, los parámetros de salida no son válidos en condiciones de error (P y F no resultan modificadas).
El «bloque VRAM» se refiere a las 64K inferiores (bloque 0) o a las 64K superiores (bloque 1). Las direcciones VRAM van de &H0000 a &HFFFF; si la dirección VRAM pasa de &HFFFF a &H0000 tras un autoincremento, el bloque VRAM también se actualiza (si era 0 pasa a 1, si era 1 pasa a 0).
La función USR devolverá un código de error, o 0 si no hay error. Los errores específicos para cada grupo de funciones están explicados en las secciones correspondientes.
El apéndice 1 contiene una lista de todas las funciones, que puede ser útil como referencia rápida.
Las funciones que usan el segmento 4 tienen una marca «(S4)» tras su nombre. Dichas funciones son las siguientes: 0, 26-28, 30, 33-41, 55-57, 71, 78, y 79.
10.2. FUNCIONES GENERALES
Función 1 | Obtención de información general sobre NestorBASIC y sobre un segmento lógico |
Entrada | P(10)= Segmento lógico a investigar |
Salida | P(0) = Número de segmentos de RAM disponibles P(1) = Versión principal de NestorBASIC P(2) = Versión secundaria de NestorBASIC, en formato BCD (visualizar en formato hexadecimal) P(3) = Versión principal de MSX-DOS P(4) = Versión secundaria de MSX-DOS, en formato BCD (visualizar en formato hexadecimal) P(5) = Cantidad de memoria ocupada por la rutina de salto P(6) = Tamaño de la VRAM en K P(7) = Dirección inicial de la zona libre en el segmento 0 (como máximo &H3DA8) P(8) = Número de la última función llamada P(9) = Número de ficheros abiertos P(10)= Número máximo de ficheros abiertos simultaneamente (aplicable sólo bajo DOS 1) P(11)= Slot en el que se encuentra el segmento P(0) (255 si ese segmento no existe o corresponde a VRAM) P(12)= Segmento físico correspondiente al segmento lógico P(0) F$(0)= Ruta completa del fichero NBASIC.BIN |
El número máximo de ficheros abiertos bajo DOS 2 depende del estado de la memoria interna del DOS, pero nunca será mayor de 63. Esta función devuelve el error -1 si el segmento especificado en P(0) no existe, corresponde a VRAM o es el 255. Los parámetros devueltos en P(0) a P(10) serán válidos aún en caso de error. El número devuelto en P(0) por esta función es igual al número devuelto en P(0) por la función 80; es decir, es el número de segmentos reservados para NestorBASIC. Por defecto (si tras instalar NestorBASIC no se ha ejecutado nunca la función 81), NestorBASIC reserva todos los segmentos libres en el momento de su instalación, hasta un máximo de 247. Bajo DOS 1, F$(0) contendrá simplemente una unidad y dos puntos, por ejemplo «A:». Bajo DOS 2 contendrá una unidad y un directorio, acabado en «\»; por ejemplo «C:\UTILS\GENIALES\». La dirección devuelta en P(7) depende de la versión de NestorBASIC, pero siempre será inferior o igual a &H3DA8; es decir, siempre habrá al menos 600 bytes libres al final del segmento de NestorBASIC. Esta zona puede usarse, por ejemplo, para albergar temporalmente datos TCP o un datagrama UDP en caso de que se use InterNestor Suite con NestorBASIC. P(8) devuelve el número de la última función llamada, pero la propia función 1 no cuenta. Así, si se llaman en secuencia, por ejemplo, las funciones 64, 3, 10, 1, 1, 1, lo que se obtendrá al final es P(8)=10. Un valor de cero indica que no se ha ejecutado ninguna función aparte de la 1 desde que se ha instalado NestorBASIC. |
10.3. FUNCIONES DE ACCESO A SEGMENTOS LOGICOS
Función 3 | Lectura de un byte de un segmento con autoincremento de la dirección |
Entrada | P(0) = Segmento P(1) = Dirección |
Salida | P(2) = Byte leído P(1) = P(1) + 1 |
Función 6 | Escritura de un byte en un segmento |
Entrada | P(0) = Segmento P(1) = Dirección P(2) = Byte a escribir |
Salida | – |
Función 7 | Escritura de un byte en un segmento con autoincremento de la dirección |
Entrada | P(0) = Segmento P(1) = Dirección P(2) = Byte a escribir |
Salida | P(1) = P(1) + 1 |
10.4. FUNCIONES DE ACCESO A LA VRAM
Función 13 | Lectura de un byte de la VRAM |
Entrada | P(0) = Bloque VRAM P(1) = Dirección |
Salida | P(2) = Byte leído |
Función 14 | Lectura de un byte de la VRAM con autoincremento de la dirección |
Entrada | P(0) = Bloque VRAM P(1) = Dirección |
Salida | P(2) = Byte leído P(0):P(1) = P(0):P(1) + 1 |
Función 17 | Escritura de un byte en la VRAM |
Entrada | P(0) = Bloque VRAM P(1) = Dirección P(2) = Byte a escribir |
Salida | – |
Función 18 | Escritura de un byte en la VRAM con autoincremento de la dirección |
Entrada | P(0) = Bloque VRAM P(1) = Dirección P(2) = Byte a escribir |
Salida | P(0):P(1) = P(0):P(1) + 1 |
Función 24 | Llenado de una zona de la VRAM con un byte |
Entrada | P(0) = Bloque VRAM P(1) = Dirección inicial P(2) = Byte P(3) = Longitud de la zona (máximo 16K) |
Salida | – |
Para establecer una longitud mayor de 16K se ha de emplear el truco explicado en la función 23. |
Función 25 | Llenado de una zona de la VRAM con un byte con autoincremento de la dirección |
Entrada | P(0) = Bloque VRAM P(1) = Dirección inicial P(2) = Byte P(3) = Longitud de la zona (máximo 16K) |
Salida | P(0):P(1) = P(0):P(1) + P(3) |
Para establecer una longitud mayor de 16K se ha de emplear el truco explicado en la función 23. |
10.5. FUNCIONES DE ACCESO A FICHEROS
Función 30 | Creación de un fichero o directorio |
Entrada | F$(0) = Nombre del fichero o subdirectorio P(0) = Atributos de creación (ignorado bajo DOS 1): R + 2*H + 4*S para crear un fichero; 2*H + 16 para crear un directorio. R = 1 -> sólo lectura H = 1 -> Oculto S = 1 -> Sistema |
Salida | – |
F$(0) puede incluir una unidad y una ruta de acceso. El fichero será creado con una longitud de 0 bytes, y no quedará abierto: para acceder a él, primero hay que abrirlo explícitamente (función 31). Bajo DOS 1 sólo es posible crear ficheros, y P(0) es ignorado. Bajo DOS 2 los ficheros siempre son creados con el atributo de «Archivo», además de los especificados en P(0). |
Función 31 | Apertura de un fichero |
Entrada | F$(0) = Fichero |
Salida | P(0) = Número asociado al fichero |
F$(0) puede incluir una unidad y, en el caso del DOS 2, una ruta de acceso. El número devuelto en P(0) identifica al fichero y hay que especificarlo posteriormente en las funciones empleadas para acceder al mismo. El valor concreto de este número depende de la versión del DOS y del número de ficheros que ya han sido abiertos y cerrados: nunca debe tomarse como referencia del número de ficheros abiertos (para ello hay que usar la función 1). Bajo DOS 1 se generará un error 3 si ya hay demasiados ficheros abiertos. El número máximo de ficheros que pueden ser abiertos bajo DOS 1 puede consultarse mediante la función 1. |
Función 33 | Lectura de un fichero (S4) |
Entrada | P(0) = Número de fichero P(2) = Segmento de destino P(3) = Dirección de destino P(4) = Número de bytes a leer P(6) = Incrementar P(3) si <>0 |
Salida | P(7) = Número de bytes leídos P(3) = P(3)+P(4) si P(6)<>0 P(3)+P(4) debe ser menor de &H4000, de lo contrario el resultado es impredecible. |
El fichero es leído a partir de la posición que indique su puntero en ese momento; dicho puntero es incrementado automáticamente tras la lectura. Para consultar o modificar el puntero de un fichero hay que usar la función 42. Para leer hasta el final del fichero, o para leer el fichero entero si es menor de 16K, lo mejor es intentar leer 16K (establecer P(4)=&H4000) e ignorar el error devuelto si éste es el 1 o el 199: para esta función, estos errores simplemente indican que se ha leido hasta llegar al final del fichero. Si se llega al final del fichero antes de haber leído P(4) bytes se producirá un error; para averiguar cuántos bytes han podido ser leídos basta consultar P(7). Si no hay error, P(7) será igual a P(4); si hay un error físico (FAT incorrecta, error físico general o ausencia de disco) P(7) siempre será 0. |
Función 34 | Lectura de un fichero a VRAM (S4) |
Entrada | P(0) = Número de fichero P(2) = Bloque VRAM de destino P(3) = Dirección de destino P(4) = Número de bytes a leer (máximo &H4000) P(6) = Incrementar P(3) si <>0 |
Salida | P(7) = Número de bytes leídos P(2):P(3) = P(2):P(3)+P(4) si P(6)<>0 |
Si P(4) es mayor de &H4000 sólo se leerán &H4000 bytes, y el incremento de la dirección se limitará también a &H4000, pero P(4) no se modificará. Por tanto, para leer bloques mayores (hasta 64K) se puede emplear el truco explicado en la función 23. Para esta función también son válidas las consideraciones sobre el puntero del fichero y el valor de P(7) hechas en la descripción de la función 33. |
Función 36 | Lectura de sectores de disco a VRAM (S4) |
Entrada | P(0) = Unidad (0=A:,…,7=H:) P(1) = Sector inicial P(2) = Bloque VRAM de destino P(3) = Dirección de destino P(4) = Número de sectores a leer (máximo 32) P(6) = Incrementar P(3) si <>0 |
Salida | P(7) = P(4)*512 (0 en condiciones de error) P(3) = P(3)+P(4)*512 si P(6)<>0 |
Si P(4) es mayor de 32 sólo se leerán 32 sectores (&4000 bytes), y el incremento de la dirección se limitará también a &4000, pero P(4) no se modificará. Por tanto, para leer bloques mayores (hasta 64K) se puede emplear el truco explicado en la función 23. Para esta función también son válidas las consideraciones sobre P(7) hechas en la descripción de la función 35. |
Función 37 | Escritura en un fichero (S4) |
Entrada | P(0) = Número de fichero P(2) = Segmento de origen P(3) = Dirección de origen P(4) = Número de bytes a leer P(6) = Incrementar P(3) si <>0 |
Salida | P(7) = Número de bytes escritos P(3) = P(3)+P(4) si P(6)<>0 P(3)+P(4) debe ser menor de &H4000, de lo contrario el los datos escritos en el fichero son impredecibles. |
El fichero es escrito a partir de la posición que indique su puntero en ese momento; dicho puntero es incrementado automáticamente tras la escritura. Para consultar o modificar el puntero de un fichero hay que usar la función 42. En caso de error físico (FAT incorrecta, error físico general, ausencia de disco o disco protegido contra escritura), P(7) será 0. |
Función 38 | Escritura en un fichero desde VRAM (S4) |
Entrada | P(0) = Número de fichero P(2) = Bloque VRAM de origen P(3) = Dirección de origeno P(4) = Número de bytes a escribir (máximo &H4000) P(6) = Incrementar P(3) si <>0 |
Salida | P(7) = Número de bytes escritos P(2):P(3) = P(2):P(3)+P(4) si P(6)<>0 |
Si P(4) es mayor de &4000 sólo se escribirán &4000 bytes, y el incremento de la dirección se limitará también a &4000, pero P(4) no se modificará. Por tanto, para escribir bloques mayores (hasta 64K) se puede emplear el truco explicado en la función 23. Para esta función también son válidas las consideraciones sobre el puntero del fichero hechas en la descripción de la función 37. |
Función 40 | Escritura de sectores de disco desde VRAM (S4) |
Entrada | P(0) = Unidad (0=A:,…,7=H:) P(1) = Sector inicial P(2) = Bloque VRAM de origen P(3) = Dirección de origen P(4) = Número de sectores a escribir (máximo 32) P(6) = Incrementar P(3) si <>0 |
Salida | P(7) = P(4)*512 (0 en condiciones de error) P(3) = P(3)+P(4)*512 si P(6)<>0 |
Si P(4) es mayor de 32 sólo se escribirán 32 sectores (&H4000 bytes), y el incremento de la dirección se limitará también a &H4000, pero P(4) no se modificará. Por tanto, para escribir bloques mayores (hasta 64K) se puede emplear el truco explicado en la función 23. Para esta función también son válidas las consideraciones sobre P(7) hechas en la descripción de la función 39. |
Función 41 | Relleno de un fichero con un dato (S4) |
Entrada | P(0) = Número de fichero P(1) = Dato (un byte) P(4) = Longitud (máximo &H4000) |
Salida | P(7) = Número de bytes escritos |
Esta función simplemente escribe P(4) bytes iguales a P(1) a partir de la dirección 0 en el segmento 4, y hace una llamada a la función 37 con P(2)=4 y P(3)=0. Por tanto, son válidas todas las consideraciones hechas en la explicación de la función 37. |
Función 47 | Establecimiento del directorio actual (DOS 2) |
Entrada | F$(0) = Unidad (opcional) + directorio |
Salida | – |
Esta función sólo está disponible bajo DOS 2. Bajo DOS 1 siempre devolverá el error 1. Esta función no cambia la unidad establecida por defecto, para ello hay que usar la función 44. |
Función 49 | Creación del RAM disk (DOS 2) |
Entrada | P(0) = Tamaño deseado en segmentos de 16K |
Salida | P(0) = Tamaño del RAM disk creado en segmentos de 16K |
Esta función sólo está disponible bajo DOS 2. Bajo DOS 1 siempre devolverá el error 1. Dado que por defecto NestorBASIC reserva todos los segmentos de RAM disponibles al instalarse, antes de llamar a esta función es necesario usar la función 80 para reducir la cantidad de segmentos usados por NestorBASIC; de lo contrario no habrá segmentos libres con los que crear el RAM disk (a no ser que el ordenador disponga de más de 4M de RAM). Si no hay P(0) segmentos libres pero es posible crear un RAM disk menor, la función lo creará y no devolverá error; en P(0) se devolverá el tamaño del RAM disk que ha podido crearse. En cambio, si no hay ningún segmento libre y no puede crearse el RAM disk, sí devolverá error. |
10.6. FUNCIONES DE COMPRESION Y DESCOMPRESION DE GRAFICOS
10.7. FUNCIONES PARA LA EJECUCION DE PROGRAMAS BASIC
Función 55 | Ejecución de un programa BASIC almacenado en un segmento (S4) |
Entrada | P(0) = Segmento P(1) = Dirección inicial |
Salida | – |
MUY IMPORTANTE: Para poder usar esta función hay que cambiar la dirección de comienzo de los programas BASIC. Ver sección 6 para más detalles. Esta función ejecuta el programa BASIC almacenado en el segmento indicado. El programa ha de estar almacenado a partir de la dirección indicada en P(1) del segmento especificado en P(0), con el siguiente formato: +&H0000: No usado por NestorBASIC. Puede ser útil, por ejemplo, para insertar un byte identificador. Todas las variables numéricas del programa original Serán traspasadas al programa ejecutado. Es posible ejecutar esta función desde dentro de un turbo-bloque; en este caso sólo se transferirán las variables enteras creadas fuera del mismo que hayan sido especificadas al principio con CALL TURBO ON (variable, …, matriz(), …). Las variables de cadena que hayan sido guardadas en la zona de cadenas también serán transferidas; no así aquellas que hayan sido asignadas directamente desde el programa BASIC: éstas residen dentro del mismo, y se perderán. Para asegurarse de que una cadena es almacenada en la zona de cadenas hay que realizar la siguiente operación: C$=C$+»». Evidentemente, la opción más práctica es centralizar todas las cadenas en una matriz (por ejemplo F$), y realizar esta operación con un simple bucle. Esta función devolverá el error -1 si se especifica un segmento inexistente (el segmento 255 no es soportado), y el -2 si la memoria del BASIC es insuficiente para albergar el nuevo programa y las variables. Esto puede ocurrir si el programa ejecutado es más largo que el original, pero no es probable si la diferencia de longitudes entre ambos programas no es exagerada y el número de variables es razonablemente bajo. |
Función 56 | Activación de un programa BASIC almacenado en un segmento (S4) |
Entrada | P(0) = Segmento P(1) = Dirección inicial |
Salida | – |
MUY IMPORTANTE: Para poder usar esta función hay que cambiar la dirección de comienzo de los programas BASIC. Ver sección 6 para más detalles. Esta función actúa como la función 55, con la siguiente diferencia: una vez que el nuevo programa y las variables están en la memoria del BASIC, el programa no es ejecutado y el BASIC vuelve al modo directo. Por lo demás, el funcionamiento es idéntico, así como los posibles errores. |
Función 57 | Grabación de un programa BASIC con cabecera en un fichero (S4) |
Entrada | P(0) = Byte a grabar en la primera posición (no usado por NestorBASIC) F$(0) = Ruta + nombre del fichero |
Salida | P(1) = -1 -> No hay error <> -1 -> Ha habido un error de disco, y el fichero ha quedado abierto con ese número; el código de error es devuelto entonces por el USR, como siempre. |
MUY IMPORTANTE: Para poder usar esta función hay que cambiar la dirección de comienzo de los programas BASIC. Ver sección 6 para más detalles. Esta función graba el programa BASIC activo en el fichero especificado, con la cabecera adecuada para ser ejecutado o activado con las funciones 55 o 56 (ver descripción de la función 55 para detalles sobre el formato). El uso de esta función simplifica la conversión de programas BASIC normales a programas ejecutables con la función 55, proceso que se reduce a:
Una vez grabado de esta forma, la carga y ejecución del programa es sencilla:
Usando la función 56 en lugar de la 55 es posible cargar programas grabados con cabecera de los cuales no se tenga copia en formato normal (LOADable). Por supuesto, también pueden usarse las funciones normales de acceso a disco para grabar el programa, pero entonces habrá que crear la cabecera a mano:
Los posibles errores devueltos por esta función son los mismos que los de las funciones de acceso a disco (ver sección 4.2). En el caso de que una finalización con error provoque que el fichero quede abierto, P(1) contendrá el número asociado al fichero; en caso contrario valdrá -1. |
10.8. FUNCIONES VARIAS
Función 59 | Ejecución de una rutina de usuario (rutina en código máquina contenida en un segmento) |
Entrada | P(0) = Segmento en el que reside la rutina P(1) = Dirección de inicio de la rutina P(2) a P(11) = Registros de entrada a la rutina: P(2) = AF P(8) = AF’ P(3) = BC P(9) = BC’ P(4) = DE P(10)= DE’ P(5) = HL P(11)= HL’ P(6) = IX P(7) = IY |
Salida | P(2) a P(12) = Registros de salida de la rutina, con la misma asignación que a la entrada, más los siguientes: P(12) = A P(13) = Bandera Cy (-1 si establecida, 0 si no) P(14) = Bandera Z (-1 si establecida, 0 si no) |
Esta función permite ejecutar rutinas en código máquina residente en un segmento, con posibilidad de establecer los registros del Z80 antes de la llamada usando la matriz de parámetros; el estado de los registros tras la llamada también puede ser consultado de la misma forma. El segmento indicado será conectado en la página 2 para la ejecución de la rutina, por lo que ésta debe estar ensamblada entre las direcciones &H8000 y &HBFFF. La BIOS estará conectada y disponible en la página 0, y el segmento de NestorBASIC en la página 1 antes de la llamda a la rutina. Al final de la misma este estado ha de ser reestablecido si se realizan cambios de slot o segmento. Algunas de las rutinas y variables internas de NestorBASIC (rutinas para la manipulación de RAM y VRAM, y para obtener información sobre las interrupciones, entre otras) pueden ser usadas por las rutinas de usuario. En el apéndice 2 se detalla la ubicación y el funcionamiento de dichas rutinas y variables. Para esta rutina también sín válidas las consideraciones sobre los valores de salida P(12) a P(14) hechas en la explicación de la función 58. Esta función no soporta segmentos VRAM ni el segmento 255, y devolverá el error -1 si se indica un segmento inexistente en P(0). |
Función 64 | Construcción o borrado de un bloque de carácteres parpadeantes en SCREEN 0 |
Entrada | P(0) = 0 para borrar bloque <> 0 para crear bloque P(1) = Coordenada X (columna) inicial (0 a 79) P(2) = Coordenada Y (fila) inicial (0 a 27) P(3) = Longitud en X (columnas) P(4) = Longitud en Y (filas) P(5) = Actualizar P(1) si <>0 P(6) = Actualizar P(2) si <>0 |
Salida | P(1) = P(1) + P(3) si P(5)<>0 P(2) = P(2) + P(4) si P(6)<>0 |
Esta función crea o borra el bloque de carácteres parpadeantes de las dimensiones especificadas, en las coordenadas especificadas. Es conveniente haber ejecutado la función 63 antes de usar esta. Esta función sólo puede ejecutarse en modo SCREEN 0 con al menos 41 columnas; en caso contrario no hará nada, y no devolverá error. Si P(1)>79 y/o P(2)>27 a la entrada, devolverá el error -1. La función no comprueba si el bloque sobrepasa los límites de la pantalla. Si un bloque sobrepasa la columna 79, continuará en la columna 0 de la línea siguiente. Por el contrario, aquella parte del bloque que sobrepase la línea 27 no se visualizará. |
Función 65 | Obtención de información sobre las interrupciones |
Entrada | – |
Salida | P(0) = -1 si hay alguna interrupción en marcha (interrupción de usario, efecto de sonido o reproducción de música) P(1) = -1 si hay una interrupción de usuario en marcha P(2) = Segmento de la interrupción de usuario P(3) = Dirección de la interrupción de usuario P(4) = -1 si hay un efecto de sonido en marcha P(5) = -1 si hay una música en reproducción |
P(2) y P(3) devuelven la definición de la interrupción de usuario, aunque está suspendida. Si no se ha definido ninguna, ambos parámetros valdrán cero. Para obtener más información sobre el efecto de sonido en marcha hay que usar la función 67. En cuanto a la música, la función a utilizar para obtener más información es la 72. |
Función 66 | Definición o suspensión de una interrupción de usuario |
Entrada | P(0) = 0 para suspender la interrupción en curso 1 para definir y establecer una interrupción -1 para invertir el estado de la interrupción (establecida <–> suspendida) P(1) = Segmento de la interrupción (ignorado si P(0)<>1) P(2) = Dirección de la interrupción (ignorado si P(0)<>1) |
Salida | – |
Esta función define o suspende una interrupción de usuario, es decir, una rutina en código máquina que será ejecutada en cada interrupción del reloj, 50 o 60 veces por segundo. Si P(0)=1, la interrupción queda definida mediante P(1) y P(2), y establecida (se ejecuta a 50 o 60 Hz). Si P(0)=0, la interrupción queda suspendida (no se ejecuta), pero su definición no cambia. Si P(0)=-1 se invierte el estado de la interrupción (de establecimiento a suspensión y viceversa), pero tampoco cambia la definición de la misma. El segmento de la interrupción será conectado en la página 2 para la ejecución de la misma, por lo que ésta debe estar ensamblada entre las direcciones &H8000 y &HBFFF. La BIOS estará conectada en la página 0 y el segmento de NestorBASIC en la página 1; este estado ha de ser reestablecido al final de la interrupción en caso de que ésta realice cambios de slot o segmento. Las interrupciones estarán inhibidas y así han de permanecer durante la ejecución de la interrupción. No es necesario preservar ningún registro, NestorBASIC ya se encarga de ello. Algunas de las rutinas y variables internas de NestorBASIC (rutinas para la manipulación de RAM y VRAM, y para obtener información sobre las interrupciones, entre otras) pueden ser usadas por la interrupción de usuario. En el apéndice 2 se detalla la ubicación y el funcionamiento de dichas rutinas y variables. No es posible definir una interrupción en un segmento VRAM, ni en el 255. Esta función devolverá el error -1 si se indica un segmento inexistente en P(1). Si se especifica un valor distinto de 0, 1 o -1 en P(0), la función devolverá el error 7. |
10.9. EFECTOS DE SONIDO PSG
Función 67 | Obtención de información sobre los efectos de sonido PSG |
Entrada | P(0) = Nuevo volumen máximo (0 a 15, -1 para no cambiarlo) |
Salida | P(1) = -1 si hay un efecto sonando P(2) = Número de efecto que suena, o del último que ha sonado P(3) = Prioridad del efecto que suena, o del último que ha sonado P(4) = Segmento del juego de efectos P(5) = Dirección del juego de efectos P(6) = Número más alto de efecto definido P(7) = Volumen máximo |
La información devuelta por esta función sólo será válida si el juego de efectos ha sido inicializado con la función 68. El juego de efectos ha de haber sido creado con el editor SEE versión 3.xx, desarrollado por Fuzzy Logic. Esta función nunca devuelve error. Si se especifica un valor mayor que 15 en P(0), será interpretado como 15. |
Función 68 | Inicialización de un juego de efectos de sonido PSG |
Entrada | P(0) = Segmento P(1) = Dirección |
Salida | – |
Esta función inicializa el juego de efectos de sonido almacenado en el segmento y dirección especificados, dejándolo listo para su uso mediante la función 69. El juego de efectos ha de haber sido creado con el editor SEE versión 3.xx, de Fuzzy Logic; si el formato del juego es incorrecto la función devolverá el error 8. No es posible usar un juego de efectos almacenado en segmentos VRAM ni en el segmento 255. Esta función devolverá el error -1 si se indica un segmento inexistente en P(0). |
Función 69 | Reproducción de un efecto de sonido PSG |
Entrada | P(0) = Número de efecto P(1) = Prioridad (0: baja, <>0: alta) |
Salida | – |
Esta función reproduce el efecto de sonido especificado del juego de efectos inicializado con la función 68. El juego de efectos ha de haber sido creado con el editor SEE versión 3.xx, de Fuzzy Logic. No se ha de ejecutar esta función si no se ha inicializado antes el juego de efectos: el resultado en este caso es impredecible. P(1) regula la prioridad en caso de intentar reproducir un efecto cuando ya está sonando otro. Funciona de la siguiente manera: – Si el efecto que está sonando y el nuevo tienen la misma prioridad, el efecto en curso se interrumpe y comienza la reproducción del nuevo. Si el efecto especificado en P(0) no está definido (la pista inicial se ha dejado en «OFF» en el editor), la función devolverá el error 9. Si el efecto no existe (el número de efecto es mayor que el número de efecto más alto), se devolverá el error 10. |
Función 70 | Interrupción del efecto de sonido PSG en curso |
Entrada | – |
Salida | – |
Esta función interrumpe la reproducción del efecto de sonido en curso si lo hay, y silencia el PSG. Nunca devuelve error. |
10.10. FUNCIONES PARA LA REPRODUCCION DE MUSICA MOONBLASTER
Función 71 | Carga e inicialización, o desinstalación, del reproductor Moonblaster (S4) |
Entrada | P(0) = Reproductor a cargar: 0: Moonblaster 1.4 1: Moonblaster para Moonsound, versión Wave 1.05 3: Detección automática: Cargar reproductor Moonblaster Wave si hay MoonSound; si no, cargar reproductor Moonblaster 1.4. -1: Desinstalar el reproductor cargado actualmente |
Salida | P(0) = Reproductor cargado (0, 1 o -1, igual que a la entrada) P(1) = -1 -> No hay error <> -1 -> Ha habido un error de disco, y NBASIC.BIN ha quedado abierto con ese número; el código de error es devuelto entonces por el USR, como siempre. |
Esta función carga el reproductor de músicas seleccionado por P(0) en el segmento 5, dejándolo listo para su uso. también realiza una Búsqueda de todos los chips musicales existentes, y los deja todos activos (ver función 73 para más detalles sobre la activación y desactivación de chips). Para que el reproductor pueda ser cargado, el segmento 5 ha de existir y pertenecer al mapeador primario; en caso contrario la función devolverá el error -1. En caso de error de disco al leer el fichero, la función devolverá el código de error correspondiente (ver sección 4.2). Si a causa de un error de disco NBASIC.BIN queda abierto, su número de fichero asociado será devuelto en P(1); en caso contrario P(1) valdrá -1. El fichero NBASIC.BIN contiene dos versiones del reproductor de Moonblaster Wave: una es para ordenadores MSX2/2+ y para el Turbo-R en modo Z80, y la otra es para el Turbo-R en modo R800. En el caso del Turbo-R, NestorBASIC decide qué versión cargar en función del procesador conectado en el momento de ejecutar la función 71. Hay que tener en cuenta que si se realiza un cambio de procesador es necesario volver a ejecutar esta función, ya que la versión Z80 no funciona en modo R800 y la versión R800 introduce en modo Z80 un ralentizamiento innecesario del sistema. Para desinstalar el reproductor se puede usar esta misma función con P(0)=-1 a la entrada; no es necesario detener antes la música que está sonando, la función ya se encarga de eso. Tras la desinstalación (consistente simplemente en el borrado de la cadena «NestorPlayer» situada al principio del segmento 5), el segmento 5 vuelve a estar disponible como un segmento más. Si se intenta desinstalar el reproductor cuando no hay ningún reproductor instalado, la función no hará nada, y no devolverá error. Se pueden cargar, desinstalar y volver a cargar los reproductores Moonblaster tantas veces como sea necesario a lo largo de un programa. Si hay un reproductor cargado y se desea cargar otro, es conveniente desinstalar primero el que hay cargado. |
Función 72 | Obtención de información sobre la música en reproducción |
Entrada | – |
Salida | P(0) = -1 si hay una música sonando o pausada P(1) = -1 si hay una música Moonblaster 1.4 sonando o pausada P(2) = -1 si hay una música Moonblaster Wave sonando o pausada P(3) = 0 P(4) = -1 si hay una música pausada P(5) = Segmento de la música que suena, o de la última que ha sonado P(6) = Dirección inicial de la música que suena, o de la última que ha sonado P(7) = Posición actual P(8) = Paso actual en la posición (0 a 15) P(9) = -1 si hay un MSX-MUSIC detectado P(10)= -1 si hay un MSX-AUDIO detectado P(11)= -1 si hay un OPL4 detectado P(12)= -1 si el reproductor está cargado P(13)= Reproductor cargado (válido sólo si P(12)=-1): 0: Moonblaster 1.4 1: Moonblaster Wave 1.05 F$(0)= Título de la musica (cadena vacía si no suena ninguna) F$(1)= Samplekit o wavekit (cadena vacía si no suena ninguna música) |
Si no hay ningún reproductor cargado, P(12) valdrá 0 y el resto de parámetros de salida no Serán establecidos (excepto P(9) a P(11)); la función no devolverá ningún error. Para cargar el reproductor hay que usar la función 71. Si no hay ninguna música sonando, P(5) y P(6) devolverán la posición y el paso en que se detuvo la última música reproducida, y F$(0) y F$(1) estarán vacías. En caso contrario, F$(0) devolverá el título de la música (siempre 40 carácteres en el caso de una música Moonblaster 1.4, 50 para una música Moonblaster Wave) y F$(1) el samplekit o wavekit que había sido cargado en el Moonblaster cuando la música se grabó, en mayúsculas y sin extensión («NONE» si no había ninguno). P(9) a P(11) devuelven información sobre los chips detectados, aún en el caso de que no haya ningún reproductor cargado. Para obtener información sobre los chips activos hay que usar la función 73. |
Función 73 | Activación y desactivación de los chips musicales |
Entrada | P(0) = 0 -> sólo consultar chips activos 1 -> Activar o desactivar chips según P(1) a P(3) 2 -> Activar todos los chips presentes P(1) = 0 -> No modificar estado del MSX-MUSIC 1 -> Desactivar MSX-MUSIC 2 -> Activar MSX-MUSIC -1 -> Invertir estado del MSX-MUSIC P(2) = 0 -> No modificar estado del MSX-AUDIO 1 -> Desactivar MSX-AUDIO 2 -> Activar MSX-AUDIO -1 -> Invertir estado del MSX-AUDIO P(3) = 0 -> No modificar estado del OPL4 1 -> Desactivar OPL4 2 -> Activar OPL4 -1 -> Invertir estado del OPL4 |
Salida | P(4) = 0 -> MSX-MUSIC no presente 1 -> MSX-MUSIC presente pero inactivo 2 -> MSX-MUSIC presente y activo P(5) = 0 -> MSX-AUDIO no presente 1 -> MSX-AUDIO presente pero inactivo 2 -> MSX-AUDIO activo P(6) = 0 -> OPL4 no presente 1 -> OPL4 presente pero inactivo 2 -> OPL4 presente y activo |
Esta función permite desactivar el MSX-MUSIC, el MSX-AUDIO y el OPL4, de forma que no sonarán aunque están presentes, y volverlos a activar. Puede ser útil, por ejeplo, para oir sólo la parte MSX-AUDIO de una música en un ordenador con el MSX-MUSIC interno. Si P(0)=0 a la entrada, la función sólo devolverá información sobre los chips activos en P(4) a P(5), y no cambiará el estado de ningún chip. Si P(0)=2, todos los chips presentes Serán activados (este es el estado establecido por defecto al cargar el reproductor musical). Para obtener información sobre los chips presentes hay que usar la función 72. Si P(0)=1, los chips Serán activados o desactivados según P(1) a P(3); cualquier intento de activar un chip no presente será ignorado. Si tanto el MSX-MUSIC como el MSX-AUDIO (reproductor Moonblaster 1.4) o el OPL4 (reproductor Moonblaster Wave) son desactivados, la función 74 (inicio de la reproducción de una música) no hará nada pero no devolverá error. Para que los cambios en el estado de los chips surtan efecto, la música que está sonando debe ser detenida (función 75 o 77) y recomenzada (función 74). Si no había ninguna música sonando basta iniciarla normalmente (función 74). Esta función devolverá el error 7 si alguno de los parámetros de entrada es incorrecto (aunque si P(0)<>1 no es necesario establecer P(1) a P(3)), y el error 12 si el reproductor no ha sido cargado. |
Función 74 | Inicio de la reproducción de una música Moonblaster |
Entrada | P(0) = Segmento de la música P(1) = Dirección inicial de la música |
Salida | – |
Esta función comienza la reproducción de la música Moonblaster especificada. Si el segmento especificado no existe, corresponde a VRAM o es el 255, la función devolverá el error -1. Si el reproductor adecuado a la música no está cargado, devolverá el error 12 (para cargar el reproductor hay que usar la función 71). Si la música es Moonblaster Wave puede estar almacenada a través de segmentos consecutivos; ver sección 8.2 para más detalles. En el caso del reproductor Moonblaster 1.4, la función examina el primer byte de la música en la dirección indicada; si es &HFF significa que el fichero de la música ha sido grabado en formato EDIT y no puede ser reproducida, en cuyo caso devuelve el error 13. En caso contrario asume que en la dirección indicada comienza una música en formato USER y comienza la reproducción sin más comprobaciones. Si se especifica una dirección en la que no hay una música Moonblaster 1.4 almacenada los resultados son impredecibles. El reproductor de Moonblaster Wave no tiene esta limitación: es capaz de detectar si en la dirección especificada realmente hay una música Moonblaster Wave, y si está grabada en modo USER; en caso contrario devuelve el error 13. Si tanto el MSX-MUSIC como el MSX-AUDIO (reproductor Moonblaster 1.4) o el OPL4 (reproductor Moonblaster Wave) han sido desactivados con la función 73, esta función no hará nada, y no devolverá error. Si ya hay una música sonando o pausada, devolverá el error 14. |
Función 77 | Desvanecimiento de una música |
Entrada | P(0) = 0 -> sólo consultar si hay un desvanecimiento en marcha -1 -> Congelar desvanecimiento 1..254 -> Iniciar/descongelar desvanecimiento con el retardo indicado |
Salida | P(1) = -1 si hay un desvanecimiento en marcha P(2) = Retardo del desvanecimiento en curso (-1 si está congelado) |
Esta función inicia el desvanecimiento de la música Moonblaster en curso. El retardo indica los ciclos de reloj (de 1/50 o 1/60 segundos) que pasarán entre cada paso del desvanecimiento, por lo que un retardo más bajo implicará un desvanecimiento más rápido. Una vez que el desvanecimiento se haya completado (el volumen de la música alcance cero), la música será detenida automáticamente: no es necesario detenerla manualmente con la función 75. Si P(0)=-1 el desvanecimiento queda congelado, es decir, la música queda sonando normalmente con el nivel de volúmen alcanzado. Para continuar con el desvanecimiento hay que volver a ejecutar esta función especificando un nuevo retardo en P(0). Si P(0)=0 lo único que hará la función será establecer P(1) y P(2) a la salida. Si no hay ninguna música sonando o pausada, o si el reproductor no ha sido cargado, la función no hará nada. Nunca devuelve error. |
10.11. FUNCIONES PARA EL CONTROL DEL USO DE SEGMENTOS
Función 80 | Consulta y establecimiento del número de segmentos reservados para NestorBASIC |
Entrada | P(0) = Nuevo número de segmentos reservados para NestorBASIC (0: no modificar, sólo obtener el número de segmentos reservados actualmente) Este número incluye los segmentos de NestorBASIC, el TurboBASIC y la memoria normal del BASIC |
Salida | P(0) = Número de segmentos reservados para NestorBASIC tras la llamada P(1) = Máximo número de segmentos reservables para NestorBASIC |
Esta función puede ejecutarse tanto en DOS 1 como en DOS 2, pero está pensada para ser usada en DOS 2. Bajo DOS 2, cuando NestorBASIC es instalado reserva para sí mismo todos los segmentos de RAM libres que encuentra, hasta 247. Esto implica que no quedan segmentos libres para otros programas residentes que también hagan reservas de segmentos de RAM, como el RAM disk del DOS 2, NestorMan o InterNestor Suite. La solución a este problema es usar esta función para indicarle a NestorBASIC cuántos segmentos necesitamos realmente, de forma que el resto de los segmentos sean liberados y queden disponibles para otros programas. Por ejemplo, si vamos a usar un reproductor musical (que se cargará en el segmento 5) y sólo necesitamos un segmento extra para datos, es conveniente llamar a esta función con P(0)=7; el segmento extra será el número 6. Si se indica un número de segmentos inferior a 6 en P(0), NestorBASIC reservará 5 segmentos (ver sección 2), o 6 si hay algún reproductor musical instalado. Si se indica un número de segmentos superior al total disponible, se reservarán tantos segmentos como sea posible (hasta 247) y se devolverá en P(0) el número de segmentos que realmente han podido ser reservados. En cualquier caso, la función nunca devuelve error. Bajo DOS 1, lo único que hace esta función es modificar variables internas de NestorBASIC; el valor devuelto en P(1) es fijo y se calcula cuando NestorBASIC es instalado. Bajo DOS 2, en cambio, esta función realmente realiza reservas o liberaciones de segmentos usando las rutinas de soporte l mapeador del DOS 2; en este caso el valor devuelto en P(1) es recalculado en cada ejecución de la función, y depende de la cantidad de segmentos que hayan sido reservados por otros programas residentes. |
10.12. FUNCIONES PARA LA INTERACCION CON NESTORMAN E INTERNESTOR SUITE/LITE
Función 81 | Consulta de la disponibilidad de NestorMan e InterNestor Suite |
Entrada | – |
Salida | P(0) = 0 si NestorMan no está instalado 1 si NestorMan está instalado 3 si NestorMan e InterNestor Suite están instalados P(1) = Segmento NestorMan del módulo de nivel 1 de InterNestor Suite P(2) = Segmento NestorMan del módulo de nivel 2 de InterNestor Suite P(3) = Segmento NestorMan del módulo de nivel 3 de InterNestor Suite P(4) = Segmento NestorMan del módulo de nivel 4 de InterNestor Suite P(5) = Número de segmento NestorMan del segmento 4 de NestorBASIC |
El valor devuelto en P(5) sólo será válido si P(0) vale 1 o 3 a la salida. Este valor es necesario si se quiere hacer un traspaso de datos entre un segmento de NestorMan y un segmento de NestorBASIC usando como buffer intermedio el segmento 4 (que es común a ambos programas) como se explica en la sección 9.2. Los valores devueltos en P(1) a P(4) sólo Serán válidos si P(0) vale 3 a la salida. No es necesario conocer la ubicación de los módulos de InterNestor Suite para ejecutar sus rutinas (mediante la función 85), pero sí para leer y escribir las constantes de configuración y las variables de los módulos, como se detalla en la sección 9.3. |
Función 82 | Ejecución de una función de NestorMan |
Entrada | P(0) = Función a ejecutar P(2) a P(11) = Registros de entrada a la función: P(2) = AF P(8) = AF’ P(3) = BC P(9) = BC’ P(4) = DE P(10)= DE’ P(5) = HL P(11)= HL’ P(6) = IX P(7) = IY |
Salida | P(2) a P(12) = Registros de salida de la función, con la misma asignación que a la entrada, más los siguientes: P(12) = A P(13) = Bandera Cy (-1 si establecida, 0 si no) P(14) = Bandera Z (-1 si establecida, 0 si no) |
Esta función ejecuta la función de NestorMan especificada en P(0) mediante el método indirecto, es decir, por medio de una llamada al gancho de la BIOS extendida. Es equivalente por tanto a la ejecución de la función 58 previo establecimiento de P(1)=&HFFCA, P(3)=Función+256*B, y P(4)=&H2202. Para esta rutina también sín válidas las consideraciones sobre los valores de salida P(12) a P(14) hechas en la explicación de la función 58. Se devolverá un error -1 si NestorMan no está instalado. Sin embargo, no se comprueba si la función especificada existe realmente en NestorMan. La sección 9 describe técnicas para el intercambio de datos entre NestorMan y NestorBASIC. |
Función 83 | Transferencia de un bloque de bytes de un segmento de NestorMan a un segmento de NestorBASIC |
Entrada | P(0) = Segmento NestorMan de origen P(1) = Dirección inicial de origen P(2) = Segmento NestorBASIC de destino P(3) = Dirección inicial de destino P(4) = Longitud del bloque P(5)<> 0 -> Autoincremento de P(1) P(6)<> 0 -> Autoincremento de P(3) |
Salida | P(1) = P(1) + P(4) si P(5)<>0 P(3) = P(3) + P(4) si P(6)<>0 |
Esta función es idéntica a la función 10, excepto que el valor pasado en P(0) hace referencia a un segmento de NestorMan. Como en la función 10, P(3)+P(4) debe ser menor de &H4000, se puede especificar un segmento VRAM o el segmento 255 en P(2), y se devuelve el error -1 si alguno de los segmentos especificados no existe. Esta función tiene una única limitación: no es posible usarla especificando el segmento 1 como segmento NestorBASIC de destino. Normalmente esto no supondrá un problema, ya que el segmento 1 contiene el TurboBASIC y no se querrá modificar su contenido. Si a pesar de todo se necesita hacer una |
Función 84 | Transferencia de un bloque de bytes de un segmento de NestorBASIC a un segmento de NestorMan |
Entrada | P(0) = Segmento NestorBASIC de origen P(1) = Dirección inicial de origen P(2) = Segmento NestorMan de destino P(3) = Dirección inicial de destino P(4) = Longitud del bloque P(5)<> 0 -> Autoincremento de P(1) P(6)<> 0 -> Autoincremento de P(3) |
Salida | P(1) = P(1) + P(4) si P(5)<>0 P(3) = P(3) + P(4) si P(6)<>0 |
Esta función es idéntica a la función 10, excepto que el parámetro pasado en P(2) hace referencia a un segmento de NestorMan. Como en la función 10, P(3)+P(4) debe ser menor de &H4000, se puede especificar un segmento VRAM o el segmento 255 en P(0), y se devuelve el error -1 si alguno de los segmentos especificados no existe. Esta función tiene una única limitación: no es posible usarla especificando el segmento 1 como segmento NestorBASIC de origen. Normalmente esto no supondrá un problema, ya que el segmento 1 contiene el TurboBASIC y no se querrá leer su contenido. Si a pesar de todo se necesita hacer una transferencia desde el segmento 1, primero se deberá hacer una copia a otro segmento de NestorBASIC como paso intermedio, por ejemplo el segmento 4. |
Función 85 | Ejecución de una rutina de InterNestor Suite |
Entrada | P(0) = Módulo de la rutina a ejecutar, 1 a 4 P(1) = Dirección de la rutina a ejecutar P(2) a P(11) = Registros de entrada a la rutina: P(2) = AF P(8) = AF’ P(3) = BC P(9) = BC’ P(4) = DE P(10)= DE’ P(5) = HL P(11)= HL’ P(6) = IX P(7) = IY |
Salida | P(2) a P(12) = Registros de salida de la rutina, con la misma asignación que a la entrada, más los siguientes: P(12) = A P(13) = Bandera Cy (-1 si establecida, 0 si no) P(14) = Bandera Z (-1 si establecida, 0 si no) |
Mediante esta función es posible ejecutar una rutina de cualquiera de los módulos de InterNestor Suite. Para leer o escribir las constantes de configuración y las variables de los módulos es necesario obtener los números de segmento de NestorMan de los mismos mediante la función 81, y usar entonces alguna de las técnicas descritas en la sección 9.2 para el intercambio de datos entre NestorBASIC y NestorMan. Para esta rutina también sín válidas las consideraciones sobre los valores de salida P(12) a P(14) hechas en la explicación de la función 58. Esta función devolverá el error -1 si InterNestor Suite no está instalado, o si el número de módulo pasado en P(0) es inválido. La sección 9.3 menciona algunas consideraciones sobre el uso conjunto de NestorBASIC e InterNestor Suite. |
Función 86 | Ejecución de una rutina de InterNestor Lite |
Entrada | P(1) = Dirección de la rutina a ejecutar P(2) a P(11) = Registros de entrada a la rutina: P(2) = AF P(8) = AF’ P(3) = BC P(9) = BC’ P(4) = DE P(10)= DE’ P(5) = HL P(11)= HL’ P(6) = IX P(7) = IY |
Salida | P(2) a P(12) = Registros de salida de la rutina, con la misma asignación que a la entrada, más los siguientes: P(12) = A P(13) = Bandera Cy (-1 si establecida, 0 si no) P(14) = Bandera Z (-1 si establecida, 0 si no) |
Mediante esta función es posible ejecutar cualquier rutina de InterNestor Lite. P(1) debe contener la dirección de alguna de las rutinas de InterNestor Lite listadas en su manual del programador, de lo contrario el resultado de ejecutar esta función es impredecible. Esta función devuelve el error -1 si InterNestor Lite no está instalado. Para saber por adelantado si InterNestor Lite está instalado, usa el siguiente código, que implementa el método de detección descrito en la sección 9.4: P(0)=0: P(1)=&HFFCA: P(2)=0: P(4)=&H2203: E=USR(58):IF P(12)=0 THEN … (not installed) Para esta rutina también sín válidas las consideraciones sobre los valores de salida P(12) a P(14) hechas en la explicación de la función 58. En la sección 9.4 se comenta el uso de las rutinas de InterNestor Lite que realizan intercambios de datos con TPA desde NestorBASIC. Para esta rutina también sín válidas las consideraciones sobre los valores de salida P(12) a P(14) hechas en la explicación de la función 58. El siguiente programa de ejemplo muestra la versión de InterNestor Lite que está instalada.
El programa TCPCON-L.BAS, suministrado con NestorBASIC, es un ejemplo más complejo que ilustra el uso conjunto de NestorBASIC e InterNestor Lite. |
APENDICE 1 – LISTADO DE FUNCIONES DE NESTORBASIC
En este apéndice se listan todas las funciones de NestorBASIC ordenadas por número. Las funciones que usan el segmento 4 tienen una marca «(S4)» tras su nombre. Dichas funciones son las siguientes: 0, 26-28, 30, 33-41, 55-57, 71, 78, y 79.
Funciones generales | |
Función 0 | Desinstalación de NestorBASIC (S4) |
Función 1 | Obtención de información general sobre NestorBASIC y sobre un segmento lógico |
Acceso a RAM | |
Función 2 | Lectura de un byte de un segmento |
Función 3 | Lectura de un byte de un segmento con autoincremento de la dirección |
Función 4 | Lectura de un entero (2 bytes) de un segmento |
Función 5 | Lectura de un entero (2 bytes) de un segmento con autoincremento de la dirección |
Función 6 | Escritura de un byte en un segmento |
Función 7 | Escritura de un byte en un segmento con autoincremento de la dirección |
Función 8 | Escritura de un entero (2 bytes) en un segmento |
Función 9 | Escritura de un entero (2 bytes) en un segmento con autoincremento de la dirección |
Función 10 | Transferencia de un bloque de bytes de un segmento a otro |
Función 11 | Llenado de una zona de memoria con un byte |
Función 12 | Llenado de una zona de memoria con un byte con autoincremento de la dirección |
Acceso a VRAM | |
Función 13 | Lectura de un byte de la VRAM |
Función 14 | Lectura de un byte de la VRAM con autoincremento de la dirección |
Función 15 | Lectura de un entero (2 bytes) de la VRAM |
Función 16 | Lectura de un entero (2 bytes) de la VRAM con autoincremento de la dirección |
Función 17 | Escritura de un byte en la VRAM |
Función 18 | Escritura de un byte en la VRAM con autoincremento de la dirección |
Función 19 | Escritura de un entero (2 bytes) en la VRAM |
Función 20 | Escritura de un entero (2 bytes) en la VRAM con autoincremento de la dirección |
Función 21 | Transferencia de un bloque de bytes de VRAM a RAM |
Función 22 | Transferencia de un bloque de bytes de RAM a VRAM |
Función 23 | Transferencia de un bloque de bytes de VRAM a VRAM |
Función 24 | Llenado de una zona de la VRAM con un byte |
Función 25 | Llenado de una zona de la VRAM con un byte con autoincremento de la dirección |
Acceso a disco | |
Función 26 | Búsqueda de ficheros (S4) |
Función 27 | Renombrado de un fichero (S4) |
Función 28 | Borrado de un fichero (S4) |
Función 29 | Desplazamiento de un fichero (DOS 2) |
Función 30 | Creación de un fichero o directorio (S4) |
Función 31 | Apertura de un fichero |
Función 32 | Cierre de un fichero |
Función 33 | Lectura de un fichero (S4) |
Función 34 | Lectura de un fichero a VRAM (S4) |
Función 35 | Lectura de sectores de disco (S4) |
Función 36 | Lectura de sectores de disco a VRAM (S4) |
Función 37 | Escritura en un fichero (S4) |
Función 38 | Escritura en un fichero desde VRAM (S4) |
Función 39 | Escritura de sectores de disco (S4) |
Función 40 | Escritura de sectores de disco desde VRAM (S4) |
Función 41 | Relleno de un fichero con un dato (S4) |
Función 42 | Movimiento del puntero de un fichero |
Función 43 | Obtención de la unidad establecida por defecto y el vector de unidades disponibles |
Función 44 | Establecimiento de la unidad por defecto |
Función 45 | Obtención de información sobre el espacio de un disco |
Función 46 | Obtención del directorio actual (DOS 2) |
Función 47 | Establecimiento del directorio actual (DOS 2) |
Función 48 | Obtención del tamaño del RAM disk (DOS 2) |
Función 49 | Establecimiento del RAM disk (DOS 2) |
Función 50 | Obtención del byte de atributos de un fichero (DOS 2) |
Función 51 | Establecimiento del byte de atributos de un fichero |
Función 52 | Tratamiento de una cadena de ruta de acceso (DOS 2) |
Compresión de gráficos | |
Función 53 | Compresión de datos gráficos |
Función 54 | descompresión de datos gráficos |
Ejecución de programas BASIC | |
Función 55 | Ejecución de un programa BASIC almacenado en un segmento (S4) |
Función 56 | Activación de un programa BASIC almacenado en un segmento (S4) |
Función 57 | Grabación de un programa BASIC con cabecera en un fichero (S4) |
Funciones varias | |
Función 58 | Ejecución de una rutina de la BIOS, de la SUB-BIOS, de la memoria BASIC o de la zona de trabajo del sistema |
Función 59 | Ejecución de una rutina de usuario (rutina en código máquina contenida en un segmento) |
Función 60 | Impresión de una cadena en modo gráfico |
Función 61 | Almacenamiento de una cadena en un segmento |
Función 62 | Recuperación de una cadena almacenada en un segmento |
Función 63 | Inicialización del modo de parpadeo en SCREEN 0 |
Función 64 | Construcción o borrado de un bloque de carácteres parpadeantes en SCREEN 0 |
Función 65 | Obtención de información sobre las interrupciones |
Función 66 | Definición o suspensión de una interrupción de usuario |
Efectos de sonido PSG | |
Función 67 | Obtención de información sobre los efectos de sonido PSG |
Función 68 | Inicialización de un juego de efectos de sonido PSG |
Función 69 | Reproducción de un efecto de sonido PSG |
Función 70 | Interrupción del efecto de sonido PSG en curso |
Reproducción de música Moonblaster | |
Función 71 | Carga e inicialización, o desinstalación, del reproductor Moonblaster (S4) |
Función 72 | Obtención de información sobre la música en reproducción |
Función 73 | Activación y desactivación de los chips musicales |
Función 74 | Inicio de la reproducción de una música Moonblaster 1.4 |
Función 75 | Detención de la reproducción de una música |
Función 76 | Pausa y continuación de una música |
Función 77 | Desvanecimiento de una música |
Función 78 | Carga de un samplekit de Music Module (S4) |
Función 79 | Carga de un wavekit de MoonSound (S4) |
Control del uso de segmentos | |
Función 80 | Consulta y establecimiento del número de segmentos reservados para NestorBASIC |
Interacción con NestorMan e InterNestor Suite/Lite | |
Función 81 | Consulta de la disponibilidad de NestorMan e InterNestor Suite |
Función 82 | Ejecución de una función de NestorMan |
Función 83 | Transferencia de un bloque de bytes de un segmento de NestorMan a un segmento de NestorBASIC |
Función 84 | Transferencia de un bloque de bytes de un segmento de NestorBASIC a un segmento de NestorMan |
Función 85 | Ejecución de una rutina de InterNestor Suite |
Función 86 | Ejecución de una rutina de InterNestor Lite |
APENDICE 2 – RUTINAS Y VARIABLES DE NESTORBASIC ACCESIBLES AL USUARIO
Cuando se ejecuta una rutina de usuario o una interrupción de usuario, el segmento de NestorBASIC queda conectado en le página 1. Al principio del mismo hay una tabla que contiene saltos a algunas de las rutinas internas de NestorBASIC, así como algunas variables internas del mismo, que pueden resultar útiles para las rutinas de usuario. En esta sección se detalla la ubicación y el funcionamiento de dichas rutinas y variables.
Todas estas rutinas mantienen el estado de las interrupciones, excepto PUTSLOT 0 que vuelve con las interrupciones inhibidas.
ATENCIÓN: El segmento lógico 255 se refiere siempre a la memoria conectada en las páginas 2 y 3 en el momento en que se hace referncia a dicho segmento. Mientras se está ejecutando una rutina o una interrupción de usuario la página 2 NO contiene el segmento del BASIC, sino el de la rutina o la interrupción. Para convertir realmente el segmento 255 a una dirección+segmento del BASIC hay que hacer lo siguiente:
ld hl,dirección
call CHKSLFF
cp 3
jr z,OKFF
ld a,2
OKFF: ;
Nota: Las variables y zonas de datos mencionadas en esta sección son de sólo lectura. Modificarlas puede dar lugar a resultados impredecibles.
El contenido de la tabla es el siguiente:
&H4100: Cadena identificadora «NestorBASIC x.xx»
&H4110: TABSEGS
Puntero a la tabla de segmentos lógicos de NestorBASIC. El formato de dicha tabla es el siguiente:
-2: Máximo número de segmentos reservables para NestorBASIC (siempre válido bajo DOS 1; bajo DOS 2 este valor es válido inmediatamente después de la instalación de NestorBASIC, pero puede variar después)
-1: Número de segmentos disponibles (como P(0) devuelto por las funciones 1 y 80)
+0: Slot del segmento lógico 0
+1: Segmento fisico del segmento lógico 0
+2: Slot del segmento lógico 1
+3: Segmento fisico del segmento lógico 1
…
+492: Slot del segmento lógico 246
+493: Segmento fisico del segmento lógico 246
&H4112: INT_DATA
Contiene información sobre las interrupciones de NestorBASIC:
bit 0 = 1: Interrupción de usuario en marcha
bit 1 = 1: Efecto de sonido en marcha
bit 2 = 1: música Moonblaster 1.4 en reproducción
bit 3 = 1: música Moonblaster Wave en reproducción
&H4113: PUTSLOT0
Conecta un slot en la pagina 0 sin usar ENASLT. Vuelve con las interrupciones inhibidas.
Entrada: A = Slot a conectar
Salida: –
Registros: AF
&H4116: CHKSLE
Comprueba si un segmento lógico existe. NO reconoce como validos los segmentos correspondientes a VRAM ni el 255.
Entrada: A = Segmento lógico
Salida: Cy= 1 -> El segmento lógico existe
Cy= 0 -> El segmento lógico no existe
Registros: F
&H4119: CHKSLFF
Comprueba si un segmento lógico es el 255, en ese caso lo convierte al segmento adecuado (segmento de la pagina 2 si HL<&HC000, segmento 3 si HL>=&HC000)
Entrada: A = Segmento lógico
HL = Dirección
Salida: A = Segmento convertido si era el 255, si no, inalterado
Registros: F
&H411C: CHKSLV
Comprueba si un segmento lógico corresponde a VRAM, en ese caso lo convierte a la dirección VRAM adecuada.
Entrada: A = Segmento lógico
HL = Dirección
Salida: Si es VRAM:
A = Bloque VRAM
HL = dirección VRAM
Cy = 1
Si no es VRAM:
A, HL inalterados
Cy = 0
Registros: –
&H411F: VTOSL
Convierte una dirección VRAM en su segmento lógico equivalente.
Entrada: A = Bloque VRAM
HL = Dirección VRAM
Salida: A = Segmento lógico equivalente
HL = Dirección RAM equivalente
Cy = 1 -> A=1 pero solo hay 64K VRAM
Registros: F
&H4122: GET_SF
Obtiene el segmento físico y el slot correspondientes a un segmento lógico.
Entrada: A = Segmento lógico
Salida: A = Segmento físico
B = Slot (255 -> Segmento lógico inexistente)
Registros: –
&H4125: GET_SLT
Obtiene el slot conectado a la pagina 1 o 2.
Entrada: A = Pagina (1 o 2)
Salida: B = Slot
Registros: F, C
&H4128: READ_SL
Lee un byte de un segmento lógico.
Entrada: A = Segmento lógico
HL = Dirección (0-&H3FFF)
Salida: A = Dato
Registros: F, AF’
&H412B: WRITE_SL
Escribe un dato en un segmento lógico.
Entrada: A = Segmento lógico
E = Dato
HL = Dirección (0-&H3FFF)
Salida: –
Registros: F, AF’
&H412E: LDIRSS
Realiza una transferencia de un segmento lógico a otro. Reconoce el segmento lógico 255 y los segmentos VRAM. Vuelve con la BIOS conectada en la pagina 0. NO comprueba si BC > &H4000.
Entrada: IXh = Segmento lógico fuente
IXl = Segmento lógico destino
HL = Dirección origen (0..&HFFF)
DE = Dirección destino (0..&HFFF)
BC = Longitud (0..&H3FFF)
Salida: A = 0 -> Transferencia realizada
A <> 0 -> Uno de los segmentos lógicos no existe
Registros: Todos
&H4131: CHKBV
Comprueba si una dirección VRAM existe.
Entrada: A = Bloque VRAM (0 o 1, 64K inferiores o superiores)
Salida: Cy = 1 -> No existe esa dirección
(A = 1 pero el ordenador sólo tiene 64K VRAM)
Registros: –
&H4134: SET_RD
Prepara el VDP para lectura de VRAM.
Entrada: HL = Dirección VRAM, 16 bits bajos
CY = Dirección VRAM, bit 17
Salida: –
Registros: AF, HL
&H4137: SET_WR
Prepara el VDP para escritura en VRAM.
Entrada: HL = Dirección VRAM, 16 bits bajos
CY = Dirección VRAM, bit 17
Salida: –
Registros: AF, HL
&H413A: LDIRVR
Copia de un bloque de bytes de VRAM a RAM.
Entrada: Dirección VRAM establecida con SET_RD
DE = Destino RAM
BC = Longitud
Salida: DE = dirección siguiente al final del bloque
Registros: AF
&H413D: LDIRRV
Copia de un bloque de datos de RAM a VRAM.
Entrada: Dirección VRAM establecida con SET_WR
HL = Origen RAM
BC = Longitud
Salida: HL = dirección siguiente al final del bloque
Registros: AF
&H4140: LDIRVV
Copia de un bloque de datos de VRAM a VRAM a traves de un buffer en RAM.
Entrada: HL = Origen, 16 bits bajos
DE = Destino, 16 bits bajos
BC = Longitud
A = %000000 D O, bit 17 de Origen y Destino
IX = Buffer RAM de BC bytes
Salida: –
Registros: AF, HL, DE
&H4143: FILLVR
Llena una zona de VRAM con un byte.
Entrada: Dirección inicial establecida con SET_WR
BC = Longitud
A = Dato
Salida: –
Registros: –
&H4146: BLK_CLS
Borra la zona de VRAM destinada al modo de parpadeo (modo «blink» de SCREEN 0).
Entrada: –
Salida: –
Registros: AF
&H4149: BLK_COL
Establecimiento del color del modo de parpadeo.
Entrada: A = Color texto + 16* color fondo
Salida: –
Registros: A
&H414C: BLK_TIM
Establecimiento de los tiempos del modo de parpadeo.
Entrada: A = Tiempo ON + 16* tiempo OFF
Salida: –
Registros: A
&H414F: BLK_ON
Construcción de un bloque parpadeante.
Entrada: HL = XXYY
B = Longitud X
C = Longitud Y
Salida: L = YY siguiente a la última línea
H = XX original
Registros: AF
&H4152: BLK_OF
Borrado de un bloque parpadeante.
Entrada: HL = XXYY
B = Longitud X
C = Longitud Y
Salida: L = YY siguiente a la última línea
H = XX original
Registros: AF
&H4155: C_BLKAD
Cálculo de la dirección VRAM correspondiente a una coordenada concreta para el modo de parpadeo.
Entrada: HL = XXYY
Salida: HL = Dirección VRAM
Registros: AF
&H4158: C_STBT
Cálculo del bit correspondiente a una coordenada concreta del modo de parpadeo.
Entrada: A = Coordenada X
Salida: A = Bit puesto a 1
Registros: F
&H415B: GINFOUS
Devuelve información sobre la interrupción de usuario.
Entrada: –
Salida: A = Segmento
HL = Dirección
&H415E: GINFOSFX
Devuelve información sobre los efectos de sonido PSG
Entrada: A = Nuevo volumen máximo (-1 para no cambiarlo)
Salida: A = Segmento del juego de efectos
HL = Dirección del juego de efectos
B = Número del efecto que suena, o del último que ha sonado
C = Prioridad del efecto que suena, o del último que ha sonado
D = Número de efecto más alto existente
E = Volumen máximo
&H4161: GINFOMUS
Devuelve información sobre la música que está sonando y la presencia del reproductor Moonblaster.
Entrada: –
Salida: Cy = 1 -> No hay ningún reproductor cargado,
el resto de resultados no son válidos.
Cy = 0 -> Hay un reproductor cargado.
El resto de resultados son válidos
si hay una música sonando (consultar INT_DATA).
A = Segmento lógico de la música que suena
HL = Dirección inicial de la música que suena
B = Chips presentes:
bit 0 = 1 -> MSX-MUSIC presente
bit 1 = 1 -> MSX-AUDIO presente
bit 2 = 2 -> OPL4 presente
C = Chips activos:
bit 0 = 1 -> MSX-MUSIC activo
bit 1 = 1 -> MSX-AUDIO activo
bit 2 = 2 -> OPL4 activo
D = Posición
E = Paso actual en la posición (0 a 15)
IXl= 255 si la música está pausada
&H4164: REPTYPE
Byte de información que contiene el tipo de reproductor musical cargado:
0: Reproductor MoonBlaster 1.4
1: Reproductor MoonBlaster Wave
Atención: antes de consultar esta información hay que comprobar que efectivamente hay algún reproductor cargado. Esto se puede hacer con la función GINFOMUS (&H4161).
&H4165: GETF01
Entrada: –
Salida: –
Esta rutina copia los contenidos de las cadenas F$(0) y F$(1) a dos buffers de NestorBASIC situados en la página 3; las direcciones de dichos buffers están indicadas en las variables F0BUFADD y F1BUFADD, mencionadas más adelante.
sólo se copian los 80 primeros carácteres de las cadenas. Al final de las mismas se inserta un carácter 0.
&H4168: SETF0
&H416B: SETF1
Entrada: –
Salida: –
Estas rutinas establecen las cadenas F$(0) y F$(1), respectivamente, con el contenido de dos buffers internos de NestorBASIC situados en la página 3; las direcciones de dichos buffers están indicadas en las variables F0BUFADD y F1BUFADD, mencionadas más adelante.
Las cadenas deben estar finalizadas con un carácter 0 en los buffers, y su longitud máxima es de 80 carácteres; si son más largas, sólo se establecerán los primeros 80 carácteres.
&H416E: F0BUFADD
&H4170: F1BUFADD
Estas variables almacenan las direcciones de los buffers en página 3 que son usados como destino por la rutina GETF01 y como origen por las rutinas SETF0 y SETF1, respectivamente. Estos buferes tienen un tamaño de 80 bytes cada
uno.
&H4172: SL_2
Número de segmento lógico conectado en la página 2 (es decir, número de segmento lógico en el que reside la rutina que lee esta variable).
&H4173: NMAN_SL4
Número de segmento NestorMan del segmento 4 de NestorBASIC.
&H4174: INS_SL1
&H4175: INS_SL2
&H4176: INS_SL3
&H4177: INS_SL4
Números de segmento NestorMan de los módulos 1 a 4, respectivamente, de InterNestor Suite.
APENDICE 3 – INTERRUPCIONES BAJO MSX TURBO-R
NestorBASIC funciona perfectamente en cualquier MSX 2/2+/Turbo-R, pero puede dar problemas con las interrupciones si se ejecuta en un Turbo-R en modo DOS 1, sobre todo si se usa una amplicación de memoria externa. Esto es debido a que antes de ejecutar una interrupción, NestorBASIC ha de averiguar qué segmento hay conectado en la página 1, y en modo DOS 1 esto sólo se puede hacer con la instrucción IN A,(&HFD), que en los Turbo-R no funciona exactamente igual que en los MSX2/2+.
Por tanto, si se van a usar interrupciones de usuario o efectos de sonido en un programa que use NestorBASIC, lo mejor es detectar si el ordenador es un Turbo-R (si PEEK(&H2D)=3) y se trabaja en modo DOS 1 (se puede averiguar con la función 1), y en ese caso avisar de que se ha de arrancar en modo DOS 2.
APENDICE 4 – CONDICIONES DE USO
NestorBASIC es software gratuito, o como dicen los expertos, freeware. Sin embargo hay un par de condiciones para usarlo en tus progamas:
– En algún lugar del programa (al cargar, en una opción «acerca de», en el «staff», etc) ha de aparecer una mención al uso de NestorBASIC, así como la versión del mismo (para averiguar la versión de NestorBASIC que usas, utiliza la función 1).
– Si el programa no es para uso personal del autor (es decir, si va a ser distribuido, de forma gratuita o no) has de cederme una copia del mismo.
Para cualquier sugerencia, consulta o comentario acerca de NestorBASIC, me encontrarás en <konamiman@konamiman.com>.
El uso de los efectos de sonido creados con el editor SEE tiene sus propias condiciones de uso. Si vas a vender tu programa por más de 15 NLG has de pagar una pequeña cantidad a los autores, como máximo 25 NLG. Para más detalles o para comentarios acerca de SEE contacta con Fuzzy Logic:
R. v/d Meulen A. v/d Wal
Lijsterstraat 25 Tormentil 15
8917 CX Leeuwarden 8445 RR Heerenveen
Holland. Holland.
[/vc_column_text][/vc_column][/vc_row]