FP50 FORTH ---------- FP50 es por SPECTRUM FLOATING-POINT FORTH está basado en el FORTH-79 con añadidos para manejar aritmetica de COMA FLOTANTE. Copyright original de Mike Hampson,el mismo autor del ZX Forth de CP software y el HL ZX Forth. LOAD "" para cargar. Una vez hcho eso aparece el sigte mensaje: "© MIKE HAMPSON (May 1983)." "Still loading - please wait." "SPECTRUM""FLOATING-POINT" "FORTH" Comandos directos: Son solamente 4 y todas de un solo caracter: ":" (definir procedimiento), "s" (salvar), "d" (definir udg) y "f" (eliminar) que deben ser tipeadas en minusculas. todas las opciones y mensajes son similares a los del HL ZX-Forth. Palabras reservadas del FP50: STKSWP, number, SPtoCS, ., 2toCS, CStoD, +, -, *, /, ^, OR, AND, NOT, NEGATE, SINR, SIND, COSR, COSD, TANR, TAND, ASNR, ACSR, ATNR, ASND, ACSD, ATND, LN, EXP, INT, SQR, SGN, ABS, RND, DROP, DUP, SWAP, OVER, flgtst, >, <, =, CR, FIELD, EMIT, INK, PAPER, FLASH, BRIGHT, INVERS, PROVERB, DO, +LOOP, I, LOOP, AT, TAB, CLS, prstrg, CIRCLE, PLOT, DRAW, POINT, A, B, C, D, E, F, G, H, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, !, @, ?, +!, ATTR, BEEP, >=, <=, <>, ?DUP, LEAVE, EXIT, EXITLP, SPACE, wrdsch, SPACES, BORDER, BLEEP, MAX, MIN, WAIT, PICK, ROT, INKEY, KEY, VLIST, %FIELDT, %+, %-, %*, %/MOD, %MOD, %/, %AND, %OR, %XOR, %=, %<, %>, ROLL, >R, R>, R@, %DO, %LOOP, %I, %+LOOP, %., %LEAVE, EXIT%L, %MAX, %MIN, %@, C@, %!, C!, C?, %?, P@, P!, FILL, ERASE, DELETE, CMOVE, %MOVE, MOVE, TYPE, CDUMP, %DUMP, DUMP, ', -LOOP, %+!, %1+, EXPECT, QUERY, WORD, >IN, PAD, COUNT, DEPTH, FIND, EXECUT, QUIT, ABORT, %1-, -TRAIL, 0<, 0>, 0=, %0=, %NOT, 1+, 1-, 2+, 2-, %2+, %2-, %<>, %>=, %<=, J, K, 79-STA, IF, ELSE, THEN, BEGIN, UNTIL, WHILE, REPEAT ---- Funciones aritmeticas y logicas: + (suma) sintaxis: x y + - (resta) sintaxis: x y - * (multiplica) sintaxis: x y * / (divide) sintaxis: x y / %+, %-, %*, %/ Estos equivalentes hacen lo mismo pero con valores enteros sin punto decimal. 1+, 1- suma o resta 1 al valor presente en la pila 2+, 2- suma o resta 2 al valor presente en la pila %1+, %1-, %2+, %2- hacen lo mismo pero con valores enteros ^ (potencia) sintaxis: x y ^ - eleva x a la potencia y = (igual) sintaxis: x y = <> (distinto) sintaxis: x y < > - nota: no deben separarse los dos signos con uno o más espacios < (menor) sintaxis: x y < > (mayor) sintaxis: x y > %=, %<, %> Igual para comparaciones con valores enteros %<>, %>=, %<= sirven para distinto, mayor igual y menor igual respectivamente 0=, 0<, 0> Evaluan si un valor es igual a cero, menor que cero (negativos) o mayor a cero (positivo) NOT sintaxis: x NOT %0=, %NOT igual pero con valores enteros MAX, %MAX sintaxis: x y MAX deja en la pila el mayor de 2 numeros MIN, %MIN sintaxis: x y MIN deja en la pila el menor de 2 numeros SINR, COSR, TANR, ASNR, ACSR, ATNR sintaxis: x ...R dejan en la pila, el seno, coseno, tangente, arcoseno, arcocoseno y arcotangente de un valor. 'R' es por real. SIND, COSD, TAND, ASND, ACSD, ATND Igual que los anteriores, la 'D' parece ser por doble precisión LN - devuelve el logaritmo natural de un numero EXP - deja el exponente de un numero INT - deja el el valor entero de un numero con punto decimal sin redondearlo SQR - deja la raiz cuadrada de un valor dado SGN - deja 1 si el valor es positivo, -1 si es negativo o 0 si es cero ABS - devuelve el valor absoluto de un número AND, %AND sintaxis: y x AND Función lógica bit a bit entre los dos números x e y OR, %OR sintaxis: y x OR Función lógica binaria OR de dos números XOR, %XOR como OR, pero exclusiva. NEGATE vuelve negativo un numero positivo y viceversa. MOD, %MOD guarda en la pila el resto de la división %/MOD devuelve dos valores, deja el resto y también el resultado de la división en la pila RND devuelve un valor entero positivo al azar. ---- Manipuladores de datos en la pila: . Extrae el valor de la pila y lo imprime en pantalla, vaciando a su vez la pila CR da un retorno de carro SPACE imprime 1 espacio en la línea en curso. ." sintaxis: ."texto" imprime en pantalla el texto contenido entre las comillas SPACES sintaxis: n SPACES imprime n espacios en la línea en curso. Ejemplo: 5 SPACES ."Hola" -TRAIL elimina los espacios en una cadena dada DUP duplica el valor contenido en el stack para evitar generalmente que se pierda al usar "." ?DUP hace DUP sólo si el valor no es cero DROP borra el valor en el stack sin mostrarlo en pantalla swap sintaxis: x y SWAP intercambia los dos valores que estan en la pila over sintaxis: x y OVER copia el segundo valor (x) y lo pone sobre la pila ROT sintaxis: x y z ROT Como SWAP pero intercambiando los valores primero y tercero de la pila. PICK sintaxis: n PICK copia el enesimo numero en la pila. Sean por ejemplo los números ingresados: 10 20 30 40 3 PICK - añadirá 20 que es el tercero desde el último valor ingresado 2 PICK - es equivalente a OVER Nota: pick debe tener un argumento o alterará el último valor ingresado en la pila ROLL sintaxis: n ROLL pone el enesimo numero en la pila moviendolo de su sitio en vez de copiarlo. Ejemplo: 3 ROLL - en el ejemplo anterior dejará la lista como: 10 30 40 20 Nota: sin parametros roll puede generar efectos imprevistos. DEPTH Cuenta el número de elementos que hay en la pila KEY Espera indefinidamente a que se pulse una tecla y la guarda en la pila INKEY Como KEY pero espera por un breve momento a que se pulse una tecla. EMIT extrae de la pila el valor ingresado ya sea del teclado, posición de memoria, variable o constante. key e inkey dan el codigo ascii, emit muestra en pantalla su caracter correspondiente Ejemplo: : espera KEY EMIT ; !, %! sintaxis: y x ! Almacena el valor y en la dirección de memoria x (como doble POKE en Basic) ó Da el valor 'y' a la variable 'x' previamente definida, sino se generará un error. Ejemplo: 444 60000 %! @, %@ sintaxis: x @ busca el valor contenido como 2 bytes en la dirección x (doble PEEK) o en la variable 'x'. Ejemplo: 60000 %@ . - devolverá 444 o el valor que sea que contenga C! por 'character', es como ! pero guarda el byte menos significativo (POKE simple) C@ como @ para el byte almacenado con C! (PEEK simple) C? equivale a "C@ ." .En Basic sería como hacer "PRINT PEEK". Ejemplo: 150 60000 ! 60000 C? - devolverá el valor almacenado en esa dirección ?, %? equivale a hacer 'Print Double Peek' en Basic. Ejemplo: 60000 ? +!, %+! como ! pero sumando y al valor previamente almacenado en x antes que reemplazarlo. Ejemplo: 100 60000 +! - añadirá 100 más al valor del ejemplo anterior 60000 ? - devolverá 544 en vez de 444 o solo 100 MOVE, %MOVE sintaxis: d1 d2 n MOVE copia n caracteres como texto o numero, desde la dirección d1 a la d2. CMOVE sintaxis: d1 d2 n CMOVE copia n bytes de la dirección d1 a la d2. Ejemplo: 16396 40000 64 CMOVE - moverá 64 bytes desde la posición 16396 a la 40000 ---- Estructura condicional if: sintaxis: c IF lp1 {ELSE {lp2}} THEN {lp3} if inicia la condicion y ejecuta 'lp1' si se cumple 'c' else sino ejecuta siguiente opción 'lp2' then cierra la condición y se prosigue con 'lp3' Ejemplo: : test 2 > IF ."TOO BIG" ELSE THEN ; - para ejecutar hacer por ejemplo: '1 test' Nota: un defecto del programa hace que el uso de THEN produzca un error que devuelve el control al Basic. Para evitarlo hay que hacer 'ELSE THEN' como se muestra en el ejemplo. Esto ocurre solo cuando se carga el Forth por primera vez, lo que obliga que la primera definición contenga un 'ELSE THEN', en cambio las proximas definiciones ya pueden tener 'THEN' sin el 'ELSE'. Bucle do - loop: sintaxis: f c DO {I} lp {s +}LOOP donde: f = valor final o el numero de veces que correrá el bucle + 1 c = valor inicial lp = la serie de palabras que se ejecutarán dentro del bucle do inicia el bucle y equivale en Forth al bucle FOR del Basic loop cierra el bucle (como NEXT) +loop sintaxis: s +LOOP equivale a 'STEP s' del Basic -LOOP Como +LOOP pero decrementando el valor del indice. >R, R>, R@: además de la pila con la que trabaja normalmente el usuario, existe una segunda pila, en la que se almacenan otros valores para uso generalmente interno como el caso de DO-LOOP, pero es posible manipular estos datos mediante las sigtes ordenes: >R transfiere n de la pila de datos a la pila de retorno R> hace la inversa de >R R@ copia el valor de la pila de retorno en la pila de datos I guarda el índice del bucle do loop. I es equivalente a: 'R> DUP >R'. Ejemplo: : ft 11 1 DO I . CR LOOP ; - imprimirá 10 numeros J y K reservados para capturar los indices de sub-bucles internos con respecto de I %DO, %LOOP, %I, %+LOOP versiones para manejar bucles con valores enteros bucles begin: sintaxis1: BEGIN lp c UNTIL {...} begin inicia el bucle indefinido o condicional until hasta que se cumple 'c'. Si 'c' = 0 o se omite, el bucle se repite indefinidamente Ejemplo: : tt BEGIN KEY EMIT UNTIL ; - una vez ejecutado no hay modo de interrumpirlo : tt BEGIN KEY DUP EMIT 13 = UNTIL ; - termina al pulsar sintaxis2: BEGIN {lp} c WHILE lp2 REPEAT {...} while mientras se cumpla 'c' repeat se repite el bucle - nota: si falta REPEAT o WHILE, genera error y retorna al Basic Ejemplo: : tt BEGIN INKEY DUP 13 < > WHILE EMIT REPEAT ; LEAVE, %LEAVE fuerza la salida prematura de un bucle DO LOOP haciendo que el límite 'f' sea igual al í ndice. Ejemplo: : ft 11 1 %DO %I DUP 6 = IF %LEAVE ELSE THEN . CR %LOOP ; se detendrá tras imprimir 6 numeros, en cambio: : ft DO I DUP 6 = IF LEAVE ELSE . CR THEN LOOP ; - se detiene tras mostrar 5 numeros EXIT termina a la fuerza la ejecución de una definición como ';'. No puede usarse dentro de DO LOOP pero si con bucles BEGIN. Ejemplo: : tt BEGIN KEY DUP 13 = IF EXIT ELSE EMIT THEN 0 UNTIL ; termina al pulsar pero dejará el valor 13 en la pila : tt BEGIN KEY DUP 13 = IF DROP EXIT ELSE EMIT THEN 0 UNTIL ; saldrá sin dejar ningun valor en la pila al terminar EXITLP, EXIT%L permite salirse de un bucle DO LOOP antes de su cierre normal como LEAVE. Ejemplo: : ft %DO %I DUP 6 = IF EXIT%L ELSE . CR THEN %LOOP ; ABORT sale de un programa y borra la pila de datos Ejemplo: : tt BEGIN KEY DUP 13 = IF ABORT ELSE EMIT THEN 0 UNTIL ; - el mismo ejemplo de EXIT QUIT como ABORT pero sin borrar la pila. Tanto ABORT como QUIT pueden usarse dentro de bucles DO LOOP y BEGIN indistintamente, incluso en lugar de LEAVE, EXIT o EXITLP. WAIT espera indefinidamente interrumpiendo el programa hasta que el usuario pulse "Y". VLIST Muestra todas las palabras reservadas del FORTH, incluidas las que añade el usuario. A medida que imprime una linea de la lista espera a que se pulse "Y" para continuar hasta terminr de mostrar todo el diccionario. ( sintaxis: (comentarios) permite añadir notas a las definiciones que serán ignorados en tiempo de compliación. FIND sintaxis: FIND np devuelve la dirección de compilación de una palabra Forth, o error si no existiese. ---- Spectrum equivalentes: son ordenes exclusivas del Forth para ZX Spectrum, inexistentes en Forth estandar. CLS limpia la pantalla y pone el cursor de texto en la esquina superior izquierda. BORDER sintaxis: n BORDER permite elegir el color del borde como en Basic. INK sintaxis: n INK idem para el color de la tinta. PAPER sintaxis: n PAPER idem para el color del papel. FLASH, BRIGHT, INVERS admiten 1 para activar y 0 para desactivar como en Basic. AT sintaxis: y x AT posiciona el cursor de texto para usar con ., U., ó ." Ejemplo: 5 5 AT ." Hola Mundo" PLOT sintaxis: y x PLOT dibuja un punto en el color por defecto en alta resolución. UNPLOT sintaxis: y x UNPLOT borra el punto en coordenadas absolutas. OVRPLT sintaxis: y x OVRPLT sobreimprime los puntos a diferencia de UNPLOT. DRAW sintaxis: y x DRAW dibuja una línea en coordenadas relativas como el DRAW del Basic. CIRCLE sintaxis: y x r CIRCLE Dibuja un círculo con centro en y x con radio r. POINT sintaxis: y x POINT devuelve 0 si no hay ningun punto dibujado en las coord. y x, 1 si lo hay. BEEP sintaxis: y x BEEP toca una nota Y por un tiempo X, sin parametros o con valores negativos, el sistema se cuelga. Y puede llegar a ser desde 0 hasta 65535, X debe ser un valor nada exagerado. BLEEP esta versión es más equivalente al BEEP del Basic en los valores de sus parámetros. ---- Manejo de variables y constantes Otras versiones Forth poseen dos palabras reservadas que son CONSTANT y VARIABLE, inexistentes en HL-zX Forth y FP50, donde se aplica un metodo bastante irregular. Para crear constantes numéricas hay que definirlas con ":". Ejemplo: :alfa 120; - crea una constante numerica de valor 120 Para ver los contenidos basta hacer "alfa ." No importa qué, una constante no puede ser modificada más que por ':'. En el caso de textos es posible hacer lo sigte: : cadena ."texto" ; - bastará con tipear 'cadena' para mostrar el 'texto' En el caso de las variables numericas son de una sola letra y están ya predefinidas: A B C D E F G H L M N O P Q R S T U V W X Y Z La I está reservada exclusivamente para leer el indice de un bucle DO LOOP. Igual J y K. Ejemplo: 23 B ! - da a la variable B predefinida el valor 23 B ? - muestra el contenido de la variable. Equivale a "B @ ." Una variable numerica siempre puede ser modificada con ! y examinada con ? o @. QUERY almacena textos en la dirección 32883 hasta pulsar ENTER (incluido como valor 13 al final) WORD lee el texto almacenado con QUERY un caracter a la vez y los pone en la pila de datos >IN Devuelve con '.' la dirección 23681 TYPE sintaxis: d s TYPE extrae cadenas de texto de la posición de memoria 'd' con longitud 's'. COUNT En otras versiones de Forth devuelve el largo de una cadena de n caracteres. PAD area tampón donde se almacena texto (dirección 32883) con QUERY pero sin el ENTER EXPECT sintaxis: y x EXPECT lee x caracteres desde el teclado y los almacena en la dirección Y. Ejemplo: PAD 5 EXPECT - quedará a la espera de que uno tipee un texto de 5 caracteres PAD 5 TYPE - lee el texto almacenado con EXPECT Z 5 EXPECT - salvará un texto en Z que podrá ser leido con TYPE Para ver el contenido del PAD sin preocuparse por el largo máximo de la cadena, definir por ejemplo: : READ PAD 160 + PAD DO WORD DUP 13 = IF DROP LEAVE ELSE EMIT THEN LOOP ; Para probarlo basta hacer: QUERY - tipeamos por ejemplo "ALICIA" READ - mostrará en pantalla el texto "ALICIA" Para contar cuantos caracteres tiene la cadena habría que definir por ejemplo: : LEN PAD 160 + PAD DO WORD DUP 13 = IF DROP I PAD - LEAVE ELSE DROP THEN LOOP ; LEN . ; - devolverá 6 Nota: WORD solo lee por cada QUERY que se usa, debido a eso, READ y LEN no funcionan mas que una vez por cada QUERY, en cualquier otro caso dará otro valor menos la ;omgitud. Para que las nuevas definiciones funcionen correctamente hay que modificarlas así: : READ PAD 160 + PAD DO I C@ DUP 13 = IF DROP LEAVE ELSE EMIT THEN LOOP ; : LEN PAD 160 + PAD DO I C@ DUP 13 = IF DROP I PAD - LEAVE ELSE DROP THEN LOOP ; ---- Miscelaneas: Otras palabras propias del HL-ZX FORTH y Spectrum Forth ' sintaxis: ' np da la dirección de memoria de una palabra definida 'np' o error si no existiese. Ejemplo: ' alfa . ; - mostrará en pantalla su posición en la RAM en caso de existir alfa DUMP, %DUMP sintaxis: d n DUMP muestra en pantalla un volcado del contenido de la memoria a partir de 'd', n valores de 2 bytes. Ejemplo: 32000 7 DUMP ; - mostrará en pantalla: 32,000 0 - o el valor que se haya depositado en esa posición y un cuadrado parpadeante 32,002 0 - DUMP espera que se pulse 'Y' para continuar línea a línea 32,004 0 - y así sucesivamente hasta dar los 7 numeros Nota: debido a que DUMP toma dos valores de la pila, es mejo tipearlo así: '0 32000 7 DUMP' CDUMP sintaxis: d n CDUMP Igual que DUMP pero un byte a la vez como PEEK. Ejemplo: 32000 7 CDUMP ; - mostrará en pantalla: 32,000 0 32,001 0 - y así sucesivamente hasta completar la lista Nota: sin parámetros, empieza a mostrar toda la memoria sin parar. FIELD, %FIELDT tabula la impresión en pantalla primero en 9 espacios y luego cada 8. Ejemplo: FIELD ."A" FIELD ."B" FIELD ."C" FIELD ."D" ; - imprimirá en pantalla: A B C D P! sintaxis: n m P! envía un valor n al puerto numero m. Equivale a OUT m,n del Basic. P@ sintaxis: n P@ lee datos del puerto n al igual que 'IN n'. Ejemplo: : IN BEGIN 31 P@ 5 5 AT DUP . 16 = UNTIL ; - lee de un joystick Kempston EXECUT sintaxis: n EXECUT fuerza la ejecución de una dirección de diccionario en la dirección de compilado en la pila. HIRES Admite dos argumentos numericos y devuelve un valor. ATTR sintaxis: {y} x ATTR da un valor si se dan los dos argumentos, ninguno si se omite uno de los parametros. STKSWP parece aludir a Stack Swap (intercambio de valores de la pila) admite valores numericos dependiendo de lo cual puede dar error e interrumpirse, provocar un reset total del sistema en Basic del mismo modo que PRINT USR 0, o colgarse. SPtoCS - ¿? 2toCS - mueve 2 valores CStoD - deja un valor en la pila 79-STA muestra el sigte mensaje en pantalla: SPECTRUM FLOATING-POINT FORTH is based on FORTH-79 with additions for FLOATING-POINT arithmetic. © Copyright May 1983 M Hampson. PROVERB admite un parametro 0 ó 1. FILL sintaxis: d n b FILL Llena con n bytes de valor b, una area de memoria a partir de la posición d ERASE sintaxis: d n ERASE Elimina n bytes a partir de la dirección d llenandola con puro ceros. DELETE sintaxis: d n DELETE como ERASE pero llenandola con espacios. Ejemplo: 60000 100 DELETE - equivale a hacer 60000 100 32 FILL Las siguientes palabras reservadas están en minúsculas y deben ser tipeadas así. number no debe ser usado con la pila vacía ya que copia todos los valores que esta contenga. Ejemplo: 123 40 50 ; - si se ingresa esto el sistema respondera con "Stack: 3" number ; - dará el mensaje "Stack: 6" dejando: 123 40 50 123 40 50 en la pila Nota: number . ; - da "Stack: 4" sin repetir la serie ni imprimir nada en pantalla, dejando en la pila un valor, generalmente -25139 tras hacer un nuevo '. ;', 0 con '? ;' number . . ; - muestra el valor y deja "Stack: 3" number ? . ; - es similar a hacer number @ . ; flgtst quita el último valor ingresado en la pila de modo similar a DROP, con la diferencia de que number puede recuperarlo. Ejemplo: 10 20 30 40 ; - si se ingresa esto el sistema respondera con "Stack: 4" flgtst ; - dará "Stack: 3" y dejará la pila solo 10 20 y 30 number ; - dará "Stack: 7" y la pila queda 10 20 30 10 20 30 40 flgtst . ; - elimina 2 valores e imprime un resultado prstrg A diferencia de VLIST no espera que se pulse ninguna tecla ni se detiene hasta que acaba solo. wrdsch ¿?