Jupiter Ace Forth: Utilidades

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 10 Ene 2022 23:00

Último mensaje de la página anterior:

En 1983 se propusieron estos Forth Benchmarks para comparar las distintas versiones de Forth en distintas máquinas de la época

En él se utiliza la palabra SP! para borrar la pila. Su definición en el JA sería:

: SP!
( n1, n2, ····, n - )
HERE 12 + 15419 !
;

Si se desea una versión más rápida en código máquina (aunque no es necesario para los benchmarks, pues se corrige su efecto en ellos). Esta versión alcanza la velocidad de la tabla del final.

Como siempre, pongo el listado para el Assembler and Dis-assembler de Boldfield

Código: Seleccionar todo

code sp!
     \ ld hl,(NN)    \ H 3C37 ))   
     \ ld bc,NN      \ H C ))
     \ add hl,bc     \
     \ ld(NN),hl     \ H 3C3B ))
     \ jp(iy)        \
endc


Aquí subo una tabla en la que el desarrollador del Toddy-Forth-79 para el ZX81 ((Kelly Abrantes Murta)) incluye también el Jupiter Ace (emulado a 1x). Curiosamente el JA es el más lento de todos.
NOTA: Los valores se han de corregir antes. De todos modos, dan una idea general aproximada.
Adjuntos
Forth Benchmarks.png
Forth Benchmarks.png (60.97 KiB) Visto 2257 veces

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 15 Ene 2022 12:53

He hecho un programa que toma de la pila el CFA de una palabra de tu diccionario y te devuelve una lista con todas las palabras de usuario necesarias para poderla definir. Esta lista está ordenada de modo que ninguna palabra necesite para ser definida una palabra anterior a ella en la lista (*)

Lo he llamado "Extractor de Palabras". Es útil si, como es mi caso, programas directamente en el Jupiter Ace (JA) y ya tienes un montón de palabras a las que se van sumando más y más.

Este programa es el que faltaba para cerrar el círculo:

"Extractor Ficheros Fuente" - · · · - "Cargador Ficheros Fuente"

Ahora, además de seguir testeándolo, voy a juntarlo con el "Extractor de Ficheros Fuente" para que, a partir de la lista ordenada me saque un fichero fuente lo más completo posible automáticamente. Casi siempre habrá que hacer cosas a mano, pues ya sabemos que no se pueden descompilar todas las palabras. Pero al final dispondremos del Fuente que se puede guardar y cargar con el "Cargador de Ficheros" y generar un diccionario solo de la palabras necesarias.

(*) Con según qué palabras recursivas se puede dar el caso que aparezca en la lista fuera de sitio. Habría que moverla manualmente (cortar y pegar). El programa ordena correctamente palabras recursivas sencillas (como el FACT del manual), pero otras más complejas no (doble recursión, recursión profunda, etc.). De hecho, con la doble recursión el programa entra en un bucle sin fin hasta que termina dando error.

NOTA: Si el programa contiene doble recursión, lo mejor es cambiar el nombre de una de ellas por otro "dummy" antes de ejecutar la extracción de código fuente y luego se substituye el nombre "dummy" por el real.

Otra opción que me guardo como proyecto futuro es, a partir de la lista ordenada, generar automáticamente un diccionario con solo esas palabras.

A modo de ejemplo sencillo pongo el listado ordenado al "extraer" la palabra TEST. La palabra VALOR1 es una constante generada con 2CONSTANT. La palabra 2@ forma parte de 2CONSTANT. Así se ve que está ordenado: TEST necesita 2LITERAL y VALOR1 para definirla. VALOR1 necesita 2CONSTANT para definirlo y 2CONSTANT necesita a 2@ para definirlo.

TEST es también un ejemplo de una de esas palabras cuyo fichero fuente generado por "Extractor de fuentes" habría que modificarlo a mano. Entre paréntesis va la info que falta para añadir [ 2 1 ] antes del 2LITERAL en el fichero fuente.
Adjuntos
ej1.png
ej1.png (7.3 KiB) Visto 1120 veces

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 16 Ene 2022 13:48

En uno de mis programas necesito una versión de LIST que en vez de teclearle el nombre de la palabra a listar, tome de la pila el CFA de una palabra y la liste. La he llamado LISTA

Está hecha en código máquina y es muy sencilla. Lo único que hace es acceder a la rutina en código máquina de LIST que hay en la ROM pero ignorando el trozo de la misma que busca el nombre de la palabra a listar en el búfer de entrada, saltando directamente al resto de la rutina. Antes pongo el CFA que hay en la pila en el registro DE (tal como haría el trozo de la rutina de LIST que nos hemos saltado).

Así:

FIND nombre LISTA

equivale a

LIST nombre

Versión Assembler Boldfield (hex)

Código: Seleccionar todo

CODE LISTA
      H    DF C3 75 16
ENDC


Versión Assembler Boldfield (mnemónicos)

Código: Seleccionar todo

CODE LISTA
    \ rst24    \
    \ jp NN    \  H 1675 ))
ENDC


Versión Boldfield sin Assembler cargado (genera LISTA como primitiva, tal como haría el assembler de Boldfield)

Código: Seleccionar todo

16 BASE C!
CREATE LISTA
 DF C, C3 C, 75 C, 16 C,
LISTA DUP 2- !


Versión CODE (Jupiter Ace manual)

Código: Seleccionar todo

16 BASE C!
CODE LISTA DF C, C3 C, 75 C, 16 C,

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 17 Ene 2022 11:42

Tengo una palabra que quiero que se ejecute diferente si la ejecuto a mano desde el búfer de entrada o si se ejecuta como parte de la definición de otra palabra. Por más que he mirado, no he sabido encontrar ninguna variable del sistema o lo que sea que me permita discernir ambas situaciones.
Lo único que se me ha ocurrido de momento es determinar el valor del registro SP estando en el búfer de entrada y usar este valor como referencia:

- Si SP = referencia -> está ​en modo "manual"
- Si SP < referencia -> se está ejecutando desde una definición o LINE. (SP como entero unsigned)

Esta es la palabra que uso para el obtener el SP
(Assembler de Boldfield)

Código: Seleccionar todo

CODE R_STACK
    \ ld hl,NN   \ 2 ))
    \ add hl,sp  \
    \ ex de,hl   \
    \ rst16      \
    \ jp(iy)     \
ENDC


En realidad me devuelve el valor de SP cuando se ejecuta R_STACK (2 menos del real) pero como se usa como referencia no hace falta corregirlo.

Si alguien sabe de un modo mejor de discernir ambas situaciones, le agradecería me lo dijera.

Editado (26-04-2022) he cambiado la primera línea de
ld hl,NN \ 0 ))
a
ld hl,NN \ 2 ))

Y así tengo el valor de SP antes que se ejecute R_STACK

El cargador es:

R_STACK primitiva:

Código: Seleccionar todo

BASE C@ DECIMAL 16 BASE C!
CREATE R_STACK
 21 C, 02 C, 00 C, 39 C, EB C,
 D7 C, FD C, E9 C,
BASE C! R_STACK DUP 2- !


R_STACK con CODE (JA manual pág 147):

Código: Seleccionar todo

BASE C@ DECIMAL 16 BASE C!
code R_STACK2
 21 C, 04 C, 00 C, 39 C, EB C,
 D7 C, FD C, E9 C,
BASE C!


en este caso se ha cambiado
ld hl,NN \ 0 ))
a
ld hl,NN \ 4 ))

Pues con CODE hay una llamada más que con "primitiva"

jltursan
Mensajes: 4622
Registrado: 20 Sep 2011 13:59
Ubicación: Madrid
Agradecido : 667 veces
Agradecimiento recibido: 1506 veces
Contactar:

Re: Jupiter Ace Forth: Utilidades

Mensajepor jltursan » 17 Ene 2022 12:29

Y desde la ignorancia, ¿no sería más práctico tener dos palabras, una para cada tipo de uso?. Es que lo de que una palabra haga dos cosas diferentes en función de la situación en la que se ejecute me chirria formalmente un poco...

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 17 Ene 2022 14:59

jltursan escribió:Y desde la ignorancia, ¿no sería más práctico tener dos palabras, una para cada tipo de uso?···


Pues ahora que lo dices.... -banghead

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 17 Ene 2022 23:30

Hoy he intentado hacer con REDEFINE lo que hice con LIST, o sea, tener una versión que en lugar de tomar el nombre de la palabra a redefinir del búfer de entrada, toma su CFA de la pila. Pero la cosa ya no es tan sencilla como con LIST, así que he optado por otro enfoque:

Código: Seleccionar todo

: REDEF
 (CFA - )
 CLS 20 1 AT SHOWNAME
 9856 15396 ! REDEFINE CLS
;


Funcionamiento de REDEF
1 - Limpia la pantalla y coloca el punto de impresión en pantalla: 20 1 AT
2 - SHOWNAME toma un CFA de la pila e imprime en pantalla el nombre de la palabra correspondiente.
3 - Se coloca el principio del búfer de entrada un espacio antes del nombre: 9856 15396 !
4 - REDEFINE usa el nombre del búfer de entrada
5 - Se repone el búfer de entrada: CLS

NOTAS:
15396 es la la variable del sistema L_HALF (contiene la address del inicio del input buffer)
9856 es la dirección de memoria que coincide con la posición 20 0 AT

Este mismo enfoque serviría para LIST, pero con LIST hacerlo en código máquina son solo 4 bytes.
OJO: La palabra que se redefine NO debe estar después de REDEF en el diccionario!!!

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 21 Ene 2022 16:15

He hecho un generador de fuentes semiautomático combinando el Extractor de Fuentes con el Extractor de Palabras. A quién le interese, lo pongo en el hilo del Extractor de ficheros fuente. (Lo haré por partes)

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 22 Ene 2022 12:16

En el manual del JA se propone como medio para introducir rutinas en código máquina usar la palabra definidora CODE. Esto hace que sea necesaria la presencia de CODE para que se puedan ejecutar.

En cambio, si usas el Assembler/Dis-assembler de Boldfied se genera una palabra que no depende de ninguna definidora para ejecutarse. Se ejecuta por sí misma, como una primitiva del JA.

De hecho, cualquier palabra definida con CODE se puede convertir en una tipo Boldfield con una sencilla modificación. Así, por ejemplo, la palabra HALT definida con CODE como se explica en el manual del JA se puede convertir en una primitiva así:

FIND HALT DUP 2+ SWAP !

Ahora HALT ya no necesita la presencia de CODE en el diccionario. Es como si fuera una primitiva de JA. Lo único que hemos hecho es que el CF (Code Field) de HALT, que antes apuntaba a la parte después del DOES> de CODE, ahora apunta al inicio de su propio PF (Parameter Field).

Así, una manera alternativa de definir HALT sin necesidad de CODE sería:

CREATE HALT
118 C, 253 C, 233 C,
HALT DUP 2- !

y de modo similar, cualquier otra que queramos crear.

EDIT: (21-2-2022) dos cosas:
  • Me equivoqué y puse un 2- en vez de un 2+ en el texto. Ya lo he corregido y marcado en amarillo. Era un fallo GARRAFAL!!
  • Si la palabra tipo CODE se convierte a tipo Boldfield con este método la nueva palabra posiblemente fallará si accedía al Return Stack. Pues cuando se usa una palabra definida con CODE, hará una llamada al Run-time de CODE y luego realiza el CALL desde allí, mientras la misma palabra tipo Boldfield solo hace el CALL. Total, que la tipo CODE cuando se ejecuta tiene un valor más cargado en el Return Stack que cuando se ejecuta la tipo Boldfield. Ejemplo: ULOOP en código máquina. Si la programas con CODE y luego la conviertes a Boldfield, fallará totalmente.

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 22 Ene 2022 16:57

Una nueva palabra que me será muy útil: OLVIDA es una versión de FORGET que en lugar de tomar un nombre del búfer de entrada, toma el CFA de la pila de la palabra que quiero borrar. Por suerte es tan sencillo como el caso de LISTA (por LIST):

Assembler Boldfield

Código: Seleccionar todo

CODE OLVIDA
    \ rst24    \
    \ jp NN    \  H 164A ))
ENDC


Programación sin el assembler cargado:

Código: Seleccionar todo

DECIMAL 16 BASE C!
CREATE OLVIDA
  C3DF  ,  164A  ,
OLVIDA DUP 2- !


Voy a estudiar más a fondo el caso de REDEF (por REDEFINE) a ver si puede hacer algo parecido, aunque ya vi que la cosa no es tan sencilla. La ventaja de llamar por CFA frente al enfoque de colocar la palabra en el búfer de entrada es cuando hay palabras con el mismo nombre, pues siempre tomará la primera que se encuentra, mientras que con este sistema puedo escoger directamente la que me interesa. Esto es válido para REDEFINE, FORGET y LIST. Las dos últimas ya puedo hacerlo por CFA, pero REDEF, de momento, aunque usa CFA, acaba trabajando por búsqueda del nombre...

NOTA: Aunque hay maneras de hacerlo, por ejemplo, antes que REDEF ponga el nombre en el búfer usando el CFA, primero cambie la primera letra del nombre de la palabra a redefinir por, por ejemplo el carácter copyright, con lo que buscará la modificada (que será de nombre único). Total, como va a desaparecer...

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 22 Ene 2022 23:44

Ya me puedo ir olvidando del OLVIDA, valga la redundancia... Me acabo de dar cuenta que cuando se ejecuta FORGET/OLVIDA se detiene cualquier programa en curso y se vuelve al intérprete. Así no me sirve de nada. Tendré que hacer un proceso equivalente por programa.

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 24 Ene 2022 00:42

Programa Fantasma

Ahora estoy con el proyecto de, partiendo de un diccionario, dar el CFA de una palabra y dejar solo un diccionario compuesto por dicha palabra y las que necesita para funcionar. Las demás se eliminarán automáticamente. Pare ello usaré le extractor de palabras para determinar las palabras que han de sobrevivir (sin ordenar) y las palabras REDEF y OLVIDA para ir redefiniendo y borrando por programa.

Como un programa no debe moverse mientras se ejecuta, pues se puede descontrolar todo, un enfoque posible es que esté fuera del diccionario. Para ello se carga en memoria encima del diccionario a convertir y a continuación, al ejecutarlo, lo primero que hace es borrarse a sí mismo (solo el programa, no el diccionario a convertir). Al borrarse sigue estando en memoria pero desvinculado del diccionario, por lo que los movimientos que causen las sucesivas Redefiniciones y Borrados de palabras no lo moverán. El programa ya tendrá un palabra COLCHON del tamaño adecuado para que haya una separación suficiente entre el diccionario que queda y el programa borrado, por el tema de la pila, que así queda entre los dos y no sobre-escribe al borrado.

A ver que tal va, pues la solución normal para que no se mueva al funcionar, es que el programa esté el primero en el diccionario y cargar todo los demás encima. Luego, al terminar habría que ir redefiniendo "a mano" para eliminar el programa y dejar solo el diccionario convertido, que es lo que pretendo evitar con este método del programa fantasma.

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 25 Ene 2022 12:00

He tenido que modificar algo REDEF, pues cierto tipo de palabras solo se pueden redefinir con otra palabra del mismo tipo, concretamente las palabras hechas con DEFINER y las hechas con COMPILER. En caso contrario se genera ERROR 11 (REDEFINE or FORGET error)

Como durante el uso para el que se pensó REDEF se puede dar dicha situación, la he modificado: Detecta si la palabra que se va a redefinir es del tipo COMPILER/DEFINER en cuyo caso le cambia su Code Field por otro valor antes de redefinirla, concretamente les pongo el de las palabras tipo CREATE (#FEC). Para este uso de REDEF, se podría hacer por defecto, o sea, convertir cualquier palabra objeto de REDEF, sin comprobar, total tanto ella como las por ella generadas van a desaparecer....

dancresp
Mensajes: 5740
Registrado: 13 Nov 2010 02:08
Agradecido : 390 veces
Agradecimiento recibido: 508 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor dancresp » 25 Ene 2022 21:15

Elurdio escribió:HAunque ya sé que es como escribir en saco roto, pues esto del Ace Forth está bastante muerto :( (y digo "bastante" por ser optimista...) , voy a ir publicando aquí, en este tema, diversas palabras (o grupos de palabras) que voy haciendo y también copiando de otras fuentes. De éstas últimas intentaré en la medida de lo posible dar crédito de su autoría. Bienvenida será cualquier contribución.

Pues aunque solo sea por mi, sigue publicando cosillas de estas, que son la mar de interesantes.

El Forth siempre ha sido un lenguaje de programación que me ha fascinado, aunque por desgracia, no hice nada relevante hasta que programé una versión del "Nuclear Invaders" que anteriormente ya había hecho para el Dragon, MSX, Oric, Spectrum, Amstrad, CP/M-86 e incluso el Camputers Lynx.

He estado un par de años bastante desaparecido por temas profesionales y de reciclaje que no me permitían "distraerme" como suelo hacer por aquí, pero poco a poco voy a ir recuperando mi actividad, que ganas no me faltan.

Respecto al Jupiter Ace, tengo hecho a medias un juego que espero publicar en breve, y dos más en proyecto bastante interesantes. No soltaré más info, por ahora.

Con todo, si a parte de escribir palabras de utilidades te decides a hacer algo más sofisticado (un juego), no tengas ninguna duda en poder contar conmigo.

Y viendo lo visto, y asumiendo que en Forth estás más formado que yo, en breve te iré haciendo consultas varias, para mejorar mi nivel a base de programar juegos.

Para terminar el ladrillete, tengo la famosa placa de jepalza, que nunca ha funcionado y se limita a sacar basura en la pantalla. Espero algún día hacerla funcionar y meterla en mi teclado DK'troniks. Mientras, emulación o FPGA.

Encantado de saber que existes !!! -drinks
Buscando la IP de la W.O.P.R. he encontrado mi índice

jltursan
Mensajes: 4622
Registrado: 20 Sep 2011 13:59
Ubicación: Madrid
Agradecido : 667 veces
Agradecimiento recibido: 1506 veces
Contactar:

Re: Jupiter Ace Forth: Utilidades

Mensajepor jltursan » 25 Ene 2022 21:27

Para terminar el ladrillete, tengo la famosa placa de jepalza, que nunca ha funcionado y se limita a sacar basura en la pantalla. Espero algún día hacerla funcionar y meterla en mi teclado DK'troniks. Mientras, emulación o FPGA.


Pues esa la tengo funcionando; así que podría llegar a resolverte alguna duda al respecto. De hecho tengo pensado desenpolvarlo ya que estuve mirando hace poco la posibilidad de realizarle el overclock que en teoría parece que se podía hacer sobre el Jupiter original.

dancresp
Mensajes: 5740
Registrado: 13 Nov 2010 02:08
Agradecido : 390 veces
Agradecimiento recibido: 508 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor dancresp » 25 Ene 2022 21:31

jltursan escribió:[Pues esa la tengo funcionando; así que podría llegar a resolverte alguna duda al respecto. De hecho tengo pensado desenpolvarlo ya que estuve mirando hace poco la posibilidad de realizarle el overclock que en teoría parece que se podía hacer sobre el Jupiter original.

Pues a la que pueda saco unas fotos de la placa y la pantalla y las subo.
Yo y el hardware no nos llevamos bien... se lo digan a wilco2008, entre otros...
Buscando la IP de la W.O.P.R. he encontrado mi índice

Elurdio
Mensajes: 410
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona
Agradecido : 90 veces
Agradecimiento recibido: 84 veces

Re: Jupiter Ace Forth: Utilidades

Mensajepor Elurdio » 25 Ene 2022 22:34

dancresp escribió:Y viendo lo visto, y asumiendo que en Forth estás más formado que yo, en breve te iré haciendo consultas varias, para mejorar mi nivel a base de programar juegos.


Dudo mucho que esté más puesto que tú en Forth. Lo que estoy algo puesto es en el funcionamiento interno del Jupiter Ace Forth. A modo de comparación, si el Forth fuera el ajedrez, estoy puesto en sus reglas y movimientos de las fichas, pero de lo importante, saber jugar al ajedrez, poco.


Volver a “Jupiter Ace”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado