242 FIELD$ (define la estructura de un 'record') FIELD channel,length1 AS field1$,length2 AS field2$.... Este comando te permite definir un 'record' que se usara por un fichero de acceso aleatorio. Este record puede tener hasta 65535 bytes de longitud. Ejemplo: Field 1,15 as APELLIDO$,15 as NOMBRE$,10 as NUMERO$ PUT (incluye un record en un fichero aleatorio) PUT channel,r Este comando traslada un record de memoria hacia el record numero "R" de un fichero de acceso aleatorio. Antes de usarlo, el conte- nido del nuevo record debera primero ser colocado en el campo de cadena definido por FIELD, usando una instruccion como: APELLIDO$="Perez" Pese a que puedes escribir los records existentes en el orden que desees, no esta permitido dispersar los records en el disco de mo do totalmente aleatorio. Esto significa que si tienes que crear un fichero, no podras teclear algo como esto: Put 1,1 Put 1,5 En este caso, la instruccion PUT 1,5 generara un error, puesto que no existen records en el fichero con los numeros entre 2 y 5. El record 2 debe ser el proximo record a incluir en el fichero, luego 3, 4, Ejemplo: Open Random 1,"TELEFONO" Field 1,30 as NOMBRE$,30 as TELEFONO$ Index=1 Do Input "Introduce un nombre";NOMBRE$ Exit if NOMBRE$="" Input "Introduce telefono";TELEFONO$ Put 1,Index:Inc Index Loop Close 1 GET (introduce un record desde un fichero aleatorio) GET channel,r Lee el record numero "R" almacenado en un fichero aleatorio abier to mediante OPEN. Luego se cargara este record en la cadena de campo creado por FIELD. Las cadenas podran manipularse en la for- ma habitual. Ten presente que solo puedes usar GET para recuperar un record que esta actualmente en el disco. Si intentas grabar un numero de record que no existe, entonces se generara un mensaje de error. Ejemplo: 243 Open Random 1,"TELEFONO" Field 1,30 as NOMBRE$,30 as TELEFONO$ Do Input"Introduce numero de record";Index Exit if index=0 Get 1,index: Print NOMBRE$: Print TELEFONO$ Loop Close 1 La impresora ============ LLIST (imprime parte o todo un programa) LLIST Este comando imprime todo el programa por impresora. Prueba a im primir alguno de los programas Basic que se incluyen en el disco de datas AMOS. Ellos te facilitaran una perfecta demostracion de las diferentes tecnicas de programacion necesarias para escribir tus propios programas AMOS Basic. Modifica libremente y experimen ta. LPRINT (imprime una lista de variables) LLPRINT variable list Esto es lo mismo que PRINT pero envia datos a la impresora en vez de a la pantalla. Ejemplo: Lprint "Hola" Vease tambien PRINT, USING, PRINT # LDIR (imprime un directorio en impresora) LDIR ¡path$¿ ¡W/¿ Lista el directorio del disco actual, imprimiendolo. Vease DIR para mas detalles. 244 Dispositivos externos OPEN PORT (abre un canal hacia un puerto I/O o de entrada/salida) OPEN PORT channel,"PAR:" (abre canal para Interface Paralelo) OPEN PORT channel,"SER:" (abre canal para Interface RS-232) OPEN PORT channel,"PRT:" (abre canal para la impresora) Este comando te permite comunicarte con los dispositivos exter nos como es el caso del RS-232. Todos los comandos estandards de fichero pueden ejecutarse normalmente, excepto los comandos LOF o POF, que obviamente solo actuan en las operaciones de disco. Por ejemplo: Open Port 1,"SER:" For X=0 to 10 Print #1,"AMOS Basic" Next X Close 1 Este programa imprime 10 lineas de texto en el dispositivo co- nectado por RS-232. Si tu impresora usa un interface en paralelo, cambia la primera linea por Open Port 1,"PRT:" De forma parecida, puedes obtener informacion de un dispositivo como un modem con una linea como: Input #1,A$: Print A$ Cuando se accede a dispositivos externos todas las instrucciones normales de entrada son disponibles para su uso, esto incluye a INPUT$ o LINE INPUT. = PORT (comprueba si el canal esta esperando) n=PORT(channel) Comprueba si un dispositivo externo esta esperando alguna infor- macion. Si el dispositivo esta esperando para ser leido, un valor de -1 sera devuelto por esta funcion, o 0 en caso contrario. ================================================================ 245 21: C O M P A C T A C I O N D E P A N T A L L A SPACK (compacta una pantalla) SPACK s to n ¡tx,ty,bx,by¿ Este comando compacta la pantalla "S" en la memoria del banco "N" Se grabaran todos los datos de la pantalla, incluyendo su modo, tamaño de pantalla, posicion de visualizacion. Esto te permite re cuperar tu pantalla exactamente en su estado original. "S" es el numero de la pantalla que contiene tu imagen. "N" contiene el numero de un banco de memoria que va de 1 a 16. Si este banco no existiera, sera reservado automaticamente. Tu nue- vo banco se almacenara en la memoria FAST si estuviera disponible y se grabara con tu programa Basic. Despues de que hayas llamado a esta funcion, el tamamño de tu pantalla puede conocerse median- te la funcion LENGTH. Ejemplo: F$=FSEL$("*","","Load a picture") Load IFF F$,0 Spack o to 1 Print "La longitud de tu nuevo banco es";Length(1);"Bytes" Wait key Screen Close 0 Unpack 1 to 0: Rem recupera la pantalla compactada No afectaras toda la pantalla con esta instruccion. Los parame tros opcionales te permiten comprimir cualquier seccion rectangu- lar de la pantalla que desees. "TX,TY" ahora contienen las coordenadas de la esquina superior izquierda de esta region. "BX,BY" establece la posicion de la es- quina infero-derecha. Todas las coordenadas X se redondearan has- ta el pixel multiplo de 8 mas cercano. Ten en cuenta que al objeto de conseguir la maxima reduccion de memoria, SPACK intentara compactar tu imagen utilizando varias estrategias diferentes. Luego comprimira tu imagen usando los dis tintos metodos que consumen la menor memoria posible. Una de las consecuencias de este proceso es el tiempo, ya que se necesitan unos 6 segundos para comprimir cada imagen. Por contra, la descompactacion se realiza en menos de 1 segun- do, por lo que no hay riesgo de interferencia con tus programas. De hecho, esto acelera su velocidad, asi que es logico que desees usar este sistema CBLOCK. Vease para mas detalles Graficos de Fon do. 246 Por otro lado, si comparas el tamaño compactado de tus fiche- ros con su longitud original, puede ser que no te creas la ines- timable reduccion de memoria. Es importante darse cuenta que la gran mayoria de esos ficheros ya han sido COMPRIMIDOS mediante las rutinas estandards de compactacion IFF. Pero aun asi, es muy posible que AMOS pueda reducirlas un 20%. Las pantallas compactadas son ideales para titulos y tablas de records tan necesarias en un juego de arcade, ya que te permiten introducir bonitos efectos de pantalla sin consumir grandes canti dades de memoria. Tambien pueden incluirse en RPG y aventuras. PACK (comprime una pantalla) PACK s TO n ¡tx,ty,bx,by¿ Comprime una pantalla "S" en el banco numero "N". A diferencia del comando previo SPACK, solo se comprimiran los datos de la ima gen. Asi tu pantalla compactada siempre debera ser descompactada directamente a una pantalla existente. Debido al modo en que se descomprimen las imagenes, existira un notable efecto brillante a menos que previamente hayas introdu cido el DOUBLE BUFFER en tus pantallas. Intenta evitarlo usando el comando PACK con pantallas de un solo buffer. Es mucho mas sen sible el sistema SPACK para este proposito. Si las coordenadas opcionales se incluyen, solo una parte de la imagen sera comprimida. Puesto que PACK es completamente compatible con el sistema AU- TOBACK, es facil combinar imagenes con pantallas moviles. Si usas el AUTOBACK modo 2, incluso seras capaz de descompactar tus ima- genes DETRAS de los bobs existentes. Ademas es posible explotar esta instruccion conjuntamente con el comando SCREEN OFFSET para crear fantasticos scrolling de fondo para tus programas. UNPACK (descomprime una pantalla) Descomprime una pantalla que ha sido previamente compactada con las instrucciones PACK o SPACK. Cada rutina de compactacion tiene su propia forma especifica de descompactar: A) Para SPACK: UNPACK b TO s Abre una pantalla y habilita la pantalla compactada del banco "B". Si esta pantalla ya existiera, sera completamente reemplaza- da por la nueva imagen. Una vez la pantalla ha sido descompactada sera claramente vibrante a la vista. 247 B) Para PACK: Las pantallas compactadas mediante PACK pueden ser descompacta das usando dos instrucciones distintas. Dichas instrucciones to- man una imagen de un banco de memoria y la cargan en una pantalla existente. ATENCION!! la pantalla destino DEBE estar en el mismo formato que el dibujo compactado, de otro modo obtendras un mensa je de error "illegal function call". Unpack b Descompacta la pantalla en su posicion original Unpack b,x,y Redibuja tu imagen comenzando en las coordenadas "X,Y". Si la nue va imagen no cabe en la pantalla actual, obtendras un mensaje de error. ================================================================ 248 22: I N S T R U C C I O N E S D E N I V E L Conversion numerica = HEX$ (convierte un numero a hexadecimal) h$=HEX$(v) h$=HEX$(v,n) Esta funcion convierte el entero "V" en una notacion decimal o de base 16 devolviendo una secuencia de "N" caracteres hexadecimales en la cadena "H$". Ejemplo: Print HEX$ (Colour(1),3) = BIN$ (convierte un numero en una cadena binaria) b$=BIN$(v) b$=BIN$(v,n) Convierte un numero en una notacion binaria o de base 2. Manipulacion de memoria ======================= = PEEK (obtiene el byte de una direccion) v=PEEK(address) Devuelve el byte (8-bits) almacenado en la direccion "ADDRESS". POKE (Cambia el byte de una direccion) POKE address,v Copia el numero "V" en la direccion "ADDRESS". V siempre debe es- tar en el rango 0-255. Pero ATENCION: POKE puede ser muy peligro- so. Si 'pokeas' indiscriminadamente, podrias dañar tu ordenador!! = DEEK (obtiene una palabra de una direccion) v=DEEK(address) Lee la palabra de 2 bytes en la direccion "ADDRESS". Dicha direc- cion debe ser PAR, o aparecera un error. 249 DOKE (Cambia una palabra en una direccion) DOKE address,value Este comando carga un numero de dos bytes entre 0 y 65535 en la direccion de memoria "ADDRESS". En manos expertas esta funcion puede ser muy util. Pero como hasta el mejor de todos comete erro res alguna vez, es preferible copiar tus programas a disco antes de usar esta funcion en una rutina. Ejemplo: Doke Phybase(1)+1000,65535 = LEEK (lee una gran palabra en una direccion) v=LEEK(address) Devuelve una gran palabra de 4 bytes almacenada en la direccion "ADDRESS". Como DEEK, la direccion usada con esta funcion debe ser siempre PAR. LOKE (cambia una gran palabra en una direccion) LOKE address,n LOKE copia el numero de 4 bytes en la direccion ADDRESS. Ejemplo: Loke Phybase(1)+10000,$FFFFFFFF El uso indiscriminado de esta funcion puede afectar terriblemente a tu ordenador, ten cuidado!! = VARPTR (obtiene la direccion de una variable) address=VARPTR(variable) Devuelve la direccion en memoria de una variable de Basic. Cada tipo de variable se almacena usando su propio formato: a) Enteras: VARPTR encuentra la direccion de 4 bytes que contiene tu variable b) Coma flotante: VARPTR devuelve la localizacion de los 4 bytes que contienen el valor de la variable en un formato de preci- sion c) Cadena: La direccion VARPTR apunta hacia el primer caracter de la cadena. Una vez AMOS termine su cadena con un CHR$(0), po- dras obtener la longitud de la misma, como sigue: DEEK(VARPTR(A$)-2), en donde A$ es el nombre de la variable. Ademas, tambien podras usar LEN(A$). 250 COPY (copia un bloque de memoria) COPY start,finish TO destination Este comando se usa para mover rapidamente grandes secciones de la memoria del Amiga de un lugar a otro. "START" y "FINISH" son las direcciones de los bytes de comienzo y final respectivamente. "DESTINATION" apunta a un area de memoria que se cargara con los nuevos datos. Todas esas direcciones deben ser PARES, o de lo contrario aparecera un mensaje de error. FILL (rellena un bloque de memoria con un patron) FILL start TO finish, pattern Este comando rellena el area de memoria especificada por "START" y "FINISH" con los 4 bytes contenidos en "PATTERN". Dichas direc ciones deben ser PARES! "PATTERN" es una gran palabra contenida en una patron de relle no de 4 bytes. Esto se copiara en cada grupo de 4 bytes de la me- moria elegida. = HUNT (encuentra una cadena en memoria) f=HUNT(start TO finish,s$) Busca en la memoria del Amiga por la secuencia de caracteres que se encuentra en s$. "START" es la direccion del primer byte de la memoria que se va a investigar, y "FINISH" es el ultimo. El resul tado viene en "F", y sera 0 (si la cadena no aparece) o el numero de posicion de s$. Operaciones con BITS ==================== ROL (rota hacia la izquierda) ROL.B n,v ROL.W n,v ROL.L n,v Esta es una version Basic de la instruccion ROL del lenguaje en- samblador. Su funcion consiste en tomar la representacion binaria de un numero en "V" y rotarlo hacia la izquierda exacatamente "N" lugares. Si "V" es una variable simple, entonces el numero rotado se to mara directamente de V. Pero si "V" fuera una expresion, entonces se tratara como la direccion de tu numero. Ejemplo: A=8 Ror 1,A Print A (resultado: 4) 251 ROR es capaz de dividir cualquier valor positivo por 2. El resul- tado del calculo debera ejecutarse mucho mas rapidamente que la operacion equivalente (/). ROR (rota hacia la derecha) Esta funcion es muy parecida a la anterior, pero rotara el numero en la direccion opuesta. = BTST (comprueba un bit) b=BTST n,v Comprueba un digito binario en la posicion "N" de la variable "V" Si "V" es una expresion, sera usada como la direccion del bit que va a ser chequeado. En este caso, a "N" le sera automaticamente aplicada la funcion AND con 7 antes de continuar. Despues de que BTST haya sido ejecutado, "B" se cargara con -1 si el bit de la posicion N esta puesto a 1, de otro modo sera 0. BSET (pone un bit a 1) BSET n,v Pone el bit de la posicion N a 1, en la variable V BCHG (cambia un bit) BCHG n,v Cambia el bit numero N en la variable V. Si el bit esta a 1 enton ces el nuevo valor sera 0 y viceversa BCLR (limpia un bit) BCLR n,v Limpia del bit numero N en la variable V, poniendolo a 0. Como todas las operaciones con BITs, si V fuera una expresion, se usa ria la localizacion del dato en memoria. Lenguaje ensamblador ==================== AMOS Basic incluye algunas facilidades especiales que te permi tiran combiar rutinas en lenguaje ensamblador con tus programas Basic. Hay que resaltar esto, debido a que la potencia de AMOS hace rara vez util el codigo maquina. Hemos añadido estas carac- teristicas solamente para aquellos programadores que suelan traba jar con codigo maquina que deseen optimizar sus programas con al- gunas rutinas en lenguaje ensamblador. 252 PLOAD (reserva un banco de memoria para codigo maquina) PLOAD "filename",bank Reserva un banco de memoria y lo carga con un programa en codigo maquina desde el disco. "BANK" es el numero del banco de memoria que va a ser reservado para tu programa. Si fuera negativo, en- tonces el banco se calcularia utilizando el valor absoluto del nu mero, y el area de memoria se situaria en memoria CHIP. Una vez que hayas cargado tu programa de este modo, podras sal varlo a disco normalmente como un fichero del tipo ".abk". Creado el banco con esta funcion, este sera permanente y tambien se gra- bara directamente con tu programa AMOS. Tu programa puede consistir en un fichero en codigo maquina en el formato estandard del Amiga. En la practica, puede contener lo que quieras, con las siguientes limitaciones: - El codigo maquina DEBE ser totalmente reposicionable - Solo el codigo empleado por tu programa sera cargado - El programa debe terminar en una instruccion RTS CALL (llama a un programa en codigo maquina) CALL address¡,params¿ CALL bank¡,params¿ Ejecuta un programa en lenguaje ensamblado contenido en la memo- ria del Amiga. "ADDRESS" puede ser tanto una localizacion de memo ria o el numero de un banco de memoria AMOS previamente creado con PLOAD. Al introducir tu programa, los registros D0 a D7 y A0 a A2 se cargaran con los valores contenidos en las matrices DREG y AREG. Tu programa ensamblador podra ahora cambiar cualquier registro si lo desea. Al comienzo de la rutina, el registro A3 apuntara a la opcional lista de parametros y A5 contendra la direccion del area principal de datos de AMOS. Cuando tu programa haya terminado, po dras regresar al Basic con solo una instruccion RTS. "PARAMS" es una lista de parametros que sera colocada en la pila del registro A3 por el comando CALL. Esos parametros necesi- tan salir en orden inverso al de entrada. Asi el ultimo valor en entrar sera el primero de la pila. Dependiendo del tipo de tus parametros, los valores de A3 seran de uno de los siguientes for- matos: a) Enteros: contiene una gran palabra que es un entero AMOS b) Coma flotante: contiene un numero decimal en formato precision IEEE c) Cadena: almacena la direccion de una cadena. Todas las cadenas comienzan con una simple palabra que contiene su longitud. ATENCION: Nunca se debera pokear directamente una cadena! Cuando una cadena se inicializa a una constante, la direccion de cadena apuntara a su punto original dentro del actual listado del progra ma! Asi si tu cambias este valor, afectaras a su fuente original. Esto es poco aconsejable y debera evitarse. Ver ejemplo 21.1. 253 = AREG = (variable usada para transmitir informacion a los registros del procesador 68.000) a=AREG(r) AREG(r)=a AREG es una matriz de 6 seudo-variables que se usan para contener una copia de los primeros 6 registros de direcciones del 68.000. "R" puede oscilar desde 0 a 6, e indica el numero de esos regis- tros de variables que sera afectado. Cuando se ejecuta el comando CALL, el contenido de esta matriz se cargara automaticamente en los registros de direccion A0 a A2. Al final de la funcion, se grabaran con cualquier nueva informa- cion que haya sido ubicada en sus apropiados registros. = DREG = (variable usada para transmitir informacion a los registros de datas del 68.000) d=DREG(r) DREG(r)=d Esta es una matriz de 8 enteros que contienen una copia del conte nido de los registros de datas del procesador 68.000. "R" hace re ferencia al numero de registro y puede oscilar de 0 a 7 para los registros D0-D7 respectivamente. Acceso a las librerias del sistema ================================== AMOS tambien te permite llamar a la mayoria de los sistemas de librerias internas del Amiga directamente desde la ROM. Esto no es particularmente util, si no fuera por AMOS! No uses estas rutinas a menos que sepas lo que estes haciendo. El Amiga es bastante dificil de programar, pero es muy facil de estropear el sistema y generar el infame error GURU. = DOSCALL (DOS libreria) r=DOSCALL(function) Ejecuta una funcion directamente desde una libreria del DOS. Aqui "FUNCTION" es copia de dicha funcion. Vease el manual de la ROM KERNAL del Amiga para mas detalles. Antes de usar esta funcion, necesitaras tener controlados los registros D0-D7 y A0-A2 mediante las funciones AREG y DREG. Con la rutina sales de nuevo al Basic, y el contenido de D0 es devuel to por "R". Ten presente que el valor devuelto no esta cargado en AREG ni en DREG. 254 = EXECALL (EXEC libreria) r=EXECALL(function) Ejecuta una llamada a la libreria EXEC del Amiga. De entrada, D0- D7 y A0-A2 se cargan con las matrices de control AREG y DREG, y "R" devolvera el valor contenido en D0. = GFXCALL (Libreria grafica) r=GFXCALL(function) Llama a una rutina desde la libreria grafica usando los valores de control almacenados en las matrices AREG y DREG = INTCALL (Libreria Intuition) r=INTCALL(function) Ejecuta un comando de la libreria Intuition. Como es habitual los valores de control son cargados de las matrices AREG y DREG, y "R" contiene el resultado de la llamada. Puesto que AMOS no usa la rutina estandard de Intuition, esta funcion es especialmente peligrosa. Debes usarla solo si estas familiarizado con esta libreria. Interior del AMOS Basic ======================= Al objeto de permitirte un completo acceso al funcionamiento interno del sistema AMOS, hemos incluidos varios "huecos" en las diferentes areas de datas. Esto no tendra interes para el progra- mador casual, pero si sera muy util para crear tus propias utili- dades AMOS. = SCREEN BASE (obtiene la tabla de las pantalla) table=SCREEN BASE Devuelve la direccion base de la tabla interna usada para conte- ner el numero y posicion de tus pantallas AMOS. Ver ejemplo 21.2 = SPRITE BASE (obtiene la tabla de sprites) table=SPRITE BASE(n) Te permite la direccion de la lista interna de datos pra el spri- te N. Si este, no existiera, entonces la direccion de la tabla sera 0. 255 Valores negativos para N, devolveran la direccion de una masca ra opcional asociada con este sprite. "TABLE" contendra ahora uno de los 3 siguientes valores posibles, dependiendo del status de esta mascara: *) table <0 Indica que no existe mascara para este sprite *) table =0 El sprite N tiene mascara, pero no ha sido generada *) table >0 Esta es la direccion de la mascara en memoria. La primera palabra de esta area, contiene la longitud de la mascara, y la siguiente se sigue de la actual definicion. Ver ejemplo 21.3. = ICON BASE (obtiene la tabla de iconos) table=ICON BASE(n) Devuelve la direccion del icono N. El formato de esta informacion es exactamente igual al de la funcion anterior.