SPECTRUM FORTH de CP Software De Mike Hampson y publicado por CP Software, este paquete de lenguaje de programación Forth, venía en dos versiones, una para Spectrum de 16k y otra para el modelo de 48k. Incluía además otra versión del mismo Forth llamada Spectrum Forth Game, solo para el 48k. La versión de 16k lleva el nombre de "sforthv16" y al cargarse muestra el siguiente mensaje: "****************" *SPECTRUM FORTH *" "****************" "© January 1983 M Hampson" "From CP Software 17 Orchard Lane, Prestwood, Gt.Missenden, Bucks." "Please wait still loading" (Espere por favor, aun cargando) Hecho esto empieza a cargar los sigtes archivos en CM: 'dict'ry', 'routines' y 'characters'. La versión Game muestra una pantalla similar a la de 16k (ambas son de la misma fecha): *********************** * SPECTRUM FORTH GAME * *********************** January 1983 M Hampson Esta versión carga en cambio solo dos archivos en CM: 'dict&chrs' y 'routines'. La de 48k se llama "sforthv48" y su pantalla de presentación muestra lo sigte: "****************" "*SPECTRUM FORTH* "****************" "V2.0 © March 83 M Hampson" Al igual que la versión GAME, carga solo dos archivos en CM: 'dict&chrs' y 'routines'. Una vez se ha terminado de cargar correctamente todo, aparece el sigte. mensaje: "You are now in Command Mode." (Usted está ahora en modo comando) "***>" y el sistema queda en espera de que uno ingrese algun dato. Cada vez que se ingrese un dato o serie de datos, hay que cerrar siempre con el signo ';'. Una pulsado ENTER, aparece el sigte mensaje: "Compiling - please wait." (Compilando - espere por favor) En seguida se imprimen todos los datos ingresados uno por uno, y si se detecta un error ya sea sintactico o de otro tipo aparece: "Typing error.Continue." (Error en el tipeado. Continue) y espera que uno prosiga. Si uno no ha terminado con ";" entonces pide que uno prosiga con: "Continue definition:" (Continue la definición) Si todo ha salido bien, dará el resultado final con el sigte. mensaje: "Stack:" {aquí el numero de datos existentes en la pila} y "---OK" y queda a la espera de nuevos datos. Ejemplo: ***> 30 20 + . ; - el sistema repetirá la orden una a una y dará el resultado Nota: a menos que uno finalice con ';', Forth seguirá a la espera de más datos a ingresar Spectrum Forth requiere que todas las palabras reservadas sean tipeadas en mayusculas, de este modo 'CR' es valido pero 'cr' dará error de tipeo y quedará a la espera de que uno ingrese una orden valida. ---- Comandos directos: Las tres versiones admiten en comun como ordenes directas las tres sigtes ":", "s" y "d", para definir, salvar y diseño de udgs respectivamente. "sforthv16" y GAME admiten un cuarto comando que es "cp" por copia, mientras "sforthv48" reemplaza esta opción por "f" (forget) para borrar una definición creada con ":". : Permite acceder al editor de definición de palabras. Apenas hecho eso pregunta: "Name Word:" (Nombre de la palabra que el usuario debe ahora ingresar) Si la palabra ya existiese da el sigte mensaje: "Word already used." (esa palabra ya está siendo utilizada) Si no hay problemas, seguirá solicitando que uno continue con la definición hasta que uno ingrese ';' para terminar. Nota: la definición debe tipearse con cuidado, ya que no hay modo de corregirlo una vez pulsado ENTER, ni existen comandos para eliminarlo de la librería o editarlo. s Permite crear una copia de seguridad de todo el programa, o salvar una nueva versión con todos las palabras nuevas que el usuario ha añadido. Una vez se da esta orden, el sistema solicita: "File Name:" (espera que se le ingrese un nombre de archivo a salvar) Una vez dado el nombre, muestra el sigte mensaje: "© Copying of this program is illegal except for storage of the purchacer's own FORTH words exclusively for his own use." Literalmente: "copiar el programa es ilegal excepto para salvar las palabras Forth de uso exclusivo del comprador" Una vez salvados los respectivos archivos, da el sigte mensaje: "Please play back to verify." (Por favor retroceda la cinta para su verificación) Y si todo ha salido bien, contestará con un: "Tape OK." Nota: Para que opere correctamente debe salvarse con las variables r=32433 y d=54952 que no están definidas dentro del listado, de lo contrario dará error tras cargar la nueva versión del programa. d Esta opción permite acceder al editor de UDGs. Una vez hecho esto muestra y pide lo sigte: ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ ABCDEFGHIJKLMNOPQRSTU ABCDEFGHIJKLMNOPQRSTU - (esta es la fila de UDGs) ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ "Name UDG:" (deme nombre de UDG) tras lo cual pedirá que uno ingreso las 8 líneas del 0 al 7, en binario que darán la nueva forma del UDG. Una vez completado todo exitosamente volverá al prompt esperando una nueva orden. La versión GAME empieza en cambio pidiendo de frente: "Give UDG number:" (deme número de UDG)tras lo cual muestra la sigte pantalla: ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ Redefinition of character {aquí el valor que uno diera antes} Y como en la versión de 16k esperará que uno ingrese las líneas del 0 a 7 en binario una por una, con la unica diferencia de que aquí no se limita a 21 UDGs sino que es posible redefinir 256 caracteres. De este modo, si el usuario eligió el gráfico 1 no será el primer UDG 'A', sino cHR$ 1, y bastará hacer 1 EMIT para confirmarlo. Orden exclusiva de "sforthv16" y "Game": cp permite sacar una copia de la pantalla a la impresora Orden exclusiva de "sforthv48": f Permite eliminar las palabras definidas por el usuario del diccionario de Forth. Nota: Las versiones "sforthv16" y GAME carecen de la orden 'f' por lo que no parece ser posible eliminar una palabra una vez ha sido definida. ---- Palabras reservadas del Forth: STKSWP, number, SPACE, EMIT, ., FIELD, CR, +, -, *, /, AND, OR, XOR, =, <, >, DROP, DUP, OVER, PICK, SWAP, ROT, ROLL, >R, R>, R@, I, MOD, NEGATE, ABS, NOT, flgtst, DO, LOOP, +LOOP, LEAVE, EXIT, EXITLP, WAIT, MAX, MIN, prstrg, SPACES, CLS, AT, ATTR, FLASH, BRIGHT, PAPER, INK, BORDER, HIRES, PLOT, UNPLOT, POINT, OVRPLT, @, C@, !, C!, P@, P!, FILL, ERASE, DELETE, CMOVE, MOVE, TYPE, CDUMP, DUMP, C?, ?, ', INKEY, KEY, RND, VLIST, IF, ELSE, THEN, BEGIN, UNTIL, WHILE, REPEAT, (, ." Exclusivas del Forth Game Posee una librería identica a la del Forth de 16k sin ningún comando extra de la versión de 48k y añade: SCREEN, TURN9, INP3, RAND, SKILL, FINI?, GAME Añadidos en la versión de 48k Posee toda la librería del Forth de 16k, nada del Forth Game pero incluye en cambio: wrdsch, A, B, C, D, E, F, G, H, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, +!, /MOD, QUERY, WORD, >IN, ?DUP, ABORT, COUNT, DEPTH, EXECUT, EXPECT, FIND, PAD, QUIT, INVERS, BEEP A continuación la librería de palabras Forth de la version 16k y GAME. + (suma) sintaxis: x y + - (resta) sintaxis: x y - * (multiplica) sintaxis: x y * / (divide) sintaxis: x y / = (igual) sintaxis: x y = < > (distinto) sintaxis: x y < > - nota: tener separados los dos signos con un espacio < (menor) sintaxis: x y < > (mayor) sintaxis: x y > NOT sintaxis: x NOT MAX sintaxis: x y MAX deja en la pila el mayor de 2 numeros MIN sintaxis: x y MIN deja en la pila el menor de 2 numeros ABS devuelve el valor absoluto de un número AND sintaxis: y x AND Función lógica bit a bit entre los dos números x e y OR sintaxis: y x OR Función lógica binaria OR de dos números XOR como OR, pero exclusiva. NEGATE vuelve negativo un numero positivo y viceversa. MOD guarda en la pila el resto de la división RND devuelve un valor entero positivo al azar. . 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" DUP duplica el valor contenido en el stack para evitar generalmente que se pierda al usar "." 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. 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 usando el área de edición. 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 ; TYPE sintaxis: d s TYPE extrae cadenas de texto de la posición de memoria 'd' con longitud 's'. ! 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 ? MOVE sintaxis: d1 d2 n MOVE copia n caracteres como texto, de 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 >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 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 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 permite salirse de un bucle DO LOOP antes de su cierre normal como LEAVE. Ejemplo: : ft DO I DUP 6 = IF EXITLP ELSE . CR THEN LOOP ; 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 terminar de mostrar todo el diccionario. ( sintaxis: (comentarios) permite añadir notas a las definiciones que serán ignorados en tiempo de compliación. ---- 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 y BRIGHT 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. POINT sintaxis: y x POINT devuelve 0 si no hay ningun punto dibujado en las coord. y x, 1 si lo hay. ---- Ampliando la librería Otras versiones de Forth poseen una palabra exclusiva para leer testos del teclado, la cual es inexistente en Spectrum Forth versión 16k, pero que es posible definir del modo sigte: : EXPECT OVER + SWAP DO KEY I ! LOOP ; Para usarlo debemos hacer por ejemplo: 50000 5 EXPECT - quedará a la espera de que uno tipee un texto de 5 caracteres 50000 5 TYPE - mostrará lo almacenado con EXPECT No hay variables, en cuanto a las constantes solo pueden ser definidas así: : alfa 120 ; - crea una constante numerica de valor 120 Miscelaneas: Otras palabras existentes en 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 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 que indica pausa 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 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 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. Sin el manual original no hay modo de saber qué hacen exactamente los siguientes comandos: ATTR sintaxis: {y} x ATTR da un valor si se dan los dos argumentos, ninguno si se omite uno de los parametros. HIRES Admite dos argumentos numericos y devuelve un valor o ninguno si se omite un parámetro. 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. FILL, ERASE y DELETE No parecen hacer nada en esta version, cuelgan el sistema sin importar qué argumento se les de.