Historia de Afera
Descripción del contenido de la página
Historia del desarrollo de Afera, una biblioteca para Abersoft Forth.
2015-03-11
Comienzo a recopilar el código escrito por mí para Abersoft Forth, para reutilizarlo para crear una biblioteca.
2015-03-13
Recupero de mi archivo un fichero MGT (una imagen de disquete de DISCiPLE), que contiene una copia de Abersoft Forth adaptado a DISCiPLE, con la fuente de la extensión, y el fichero del juego Tron.
2015-03-16
El módulo de G+DOS está muy avanzado, más que el de +3DOS.
Las cadenas también están muy avanzadas. Ya hay definiciones de S"
, S'
y otras.
2015-03-21
Hay un extraño problema con el ensamblador (adaptado del escrito por Coos Haak, usado por Lennart Benschop en su Spectrum Forth-83), que me impide compilar las extensiones para G+DOS. Es algo relacionado con el enlazado de vocabularios en fig-Forth. No lo entiendo bien aún. Podría ser un fallo de Abersoft Forth.
Añado al fichero <extend.fbs>, con algunos cambios, las palabras que había recopilado en el artículo Palabras para ampliar Abersoft Forth, salvo las de gráficos de estilo Logo.
2015-03-28
Entre otros muchos avances, ya funcionan las extensiones para cargar y salvar en cinta cualquier zona de memoria.
La biblioteca ya tiene nombre: «Afera». Comienzo a unificar las cabeceras.
2015-03-30
Uso RUNT
en todos los módulos, para que al ser usados como parte de otro programa se carguen en cadena. Sin embargo esto no siempre es deseable. Hace falta un método que permita elegir, por ejemplo una misma palabra definida de dos formas, cada una en su fichero. Así, al incluir el fichero con la definición que no hace nada, cada módulo se detendría al final de su carga. Sin embargo esto obliga a cargar siempre uno de los dos ficheros, antes de usar la biblioteca. La solución más sencilla parece dejar sin definir la palabra que carga en cadena, que hasta ahora es RUNT
. Así, al cargar manualmente los módulos, se produciría un error al final de la compilación. Esto no es un problema.
2015-04-01
Creo los parches que permiten usar también la zona inferior de la pantalla, aunque aún hay que solucionar un problema al imprimir en la última línea. Hay que terminar de adaptar el código de Spectrum Forth-83.
2015-04-14
Divido los ficheros en los directorios <src/> y <tap/> y actualizo <Makefile>.
Varias novedades y mejoras en <src/extend.fsb>, <src/strings.fsb> y <src/gdos.fsb>.
2015-04-15
Prescindo de RUNT
para enlazar los ficheros, pues ello hacía prácticamente imposible que la biblioteca fuera utilizable tanto en cinta como en disco. No hay una solución buena para usar una palabra similar que solo encadene los ficheros al cargar desde cinta y no actúe cuando se use el disco, aparte del problema de necesitar algún medio de poder anular su función, para poder cargar módulos sueltos (lo que a falta de otra opción mejor se hace usando DEPTH
).
La solución es usar un cargador a medida para cada programa, que no necesite palabras de Afera, y que cargue todas las fuentes de la biblioteca y del programa. La prueba la he hecho con Tron 0xF:
( Tron: loader )
." Tron: loader "
: LOADER ( -- )
\ Get and compile every source file RAM-disc from tape;
\ the last source will load the graphics from tape
\ and run the program.
19 0 DO FLUSH INIT-DISC LOADT 1 LOAD LOOP ;
LOADER
No obstante, conservo RUNT
y ?RUNT
en un fichero propio, pues aún pueden ser útiles.
2015-04-17
Nuevo cargador usado en Tron 0xF, igualmente independiente de la biblioteca:
\ ## LOADED? ## is set in the last source file,
\ meaning all source files have been loaded.
0 VARIABLE LOADED?
: LOADER ( -- )
\ Get and compile every source file RAM-disc from tape,
\ and then execute the latest word defined.
BEGIN LOADED? @ 0= WHILE
255 23692 C! ( no scroll message)
FLUSH INIT-DISC LOADT 1 LOAD
REPEAT
\ LATEST PFA CFA EXECUTE
\ XXX OLD
\ Simple version of ## 1 LOAD ## :
\ 0 IN ! B/SCR BLK ! INTERPRET
;
LOADER
2015-04-18
Nuevo: <decode.fsb>.
Nuevo: <color.fsb>, con versiones seguras y más rápidas de INK
y PAPER
.
2015-04-23
Nuevo: UPPERC
, escrito en Z80, en <upperc.fsb>.
2015-05-01
Nuevo: <point.fsb>, versión más rápida de POINT
.
2015-05-03
Gran mejora: Un parche para hacer utilizable la primera pantalla del disco RAM. Adapto los THRU
y LOAD
usados en algunos módulos, y modifico aquellos módulos en que se puede usar el primer bloque.
2015-05-04
La versión rápida de PLOT
está terminada.
Nuevo: :NONAME
.
2015-05-05
Módulo <color.fsb> terminado: versiones de INK
y PAPER
mucho más rápidas que las anteriores. El resto de palabras de coloreado han sido reescritas en Z80 también, y aún no están cronometradas.
2015-05-06
1+
y 2+
han sido modificadas para parchear las definiciones originales, más lentas, sin usar memoria. Por eso las muevo al fichero <extend.fsb>.
Nuevos módulos <uppers.fsb> y <lowers.fsb> para convertir cadenas.
Gran mejora: Nuevo módulo <caseins.fsb> para convertir el sistema en insensible a «úsculas».
Mejora: POINT
es un poco más rápido, y sobreescribe el código original.
Medición:
La compilación de Tron 0xF tarda 20522 cuadros de sistema.
Tras parchear CFA
para usar el código de 2+
, tarda 20480 (06:49)
Tras parchear además provisionalmente LFA
para usar código en Z80, tarda 20501.
Quito el parche de LFA
.
Tras activar el modo de insensibilidad a «úsculas», tarda 21383 (07:07), 18 segundos adicionales y 104% del tiempo.
Añadiendo el parcheado de TRAVERSE
, tarda 21429, lo que es extraño porque el nuevo código de TRAVERSE
tiene un tiempo de ejecución de entre el 20% y el 4% del código original. Su impacto no es significativo durante la compilación porque se usa solo una vez, durante la compilación de cada palabra, y durante la búsqueda en el diccionario se usan los campos de enlace ya compilados.
2015-05-07
El módulo <lowermem.fsb> permite bajar el sistema por debajo de 0xC000. Solo queda un problema por solucionar para bajar también los búferes de disco, lo que permitirá usar +3DOS.
2015-05-08
Gracias a que se puede bajar el sistema por debajo de 0xC000, ya es posible usar la memoria paginada en 128K.
He adaptado el cargador de Tron 0xF para usarlo con cualquier combinación de ficheros fuente. He actualizado Makefile para usar este método con los ficheros de pruebas. Ahora cualquier fichero creado con el Forth y una recopilación de módulos puede compilarse con un solo LOADT 1 LOAD
sin necesidad de saber cuántos ficheros fuente hay en el fichero TAP. La palabra provisional RUNTS
, definida en <extend.fsb>, ya no es necesaria.
2015-05-12
El módulo <16screens.fsb> (nombre provisional) ya funciona: 16 pantallas en el banco 1 de la memoria paginada. Siguiente paso: segundo disco RAM, usando DR1
y DR0
.
Segundo disco RAM. Siguiente paso: unificar las palabras base para que sirvan también con el disco RAM normal en 48K.
2015-05-13
Confirmo que este método no desperdicia espacio en el diccionario tras borrar la palabra:
: X
\ Make this word to forget itself:
[ LATEST ] LITERAL DUP DP ! PFA LFA @ CURRENT @ !
;
Nuevo: GREETING
.
Nuevo: 2NIP
, copiado de DZX-Forth.
2015-05-14
El fichero principal se llama ahora <afera.fsb> en lugar de <extend.fsb>.
Primera prueba de 48K?
en <afera.fsb>, en Z80. Aún no funciona bien.
Nuevo: EXTEND
completado con el código extraído de SYSTEM
, que he movido a <afera.fsb>.
Memoria libre: 18919 octetos en Abersoft Forth 1.1A; 17911 octetos tras cargar <afera.fsb>.
La compilación condicional ya funciona. Está en <bracket-if.fsb>.
2015-05-15
- Nuevo: módulo <hi-to.fsb>, útil para usar con el modelo de 48K, pues permite recuperar 1 KiB de memoria que Abersoft Forth desperdicia al final de la memoria física.
2015-05-17
Progreso hacia un módulo para G+DOS. Varias mejoras y novedades.
Sistema base para ficheros, común a cinta y disco. Gestión de requisitos con NEEDS
, aún no para disco.
2015-05-18
La versión de NEEDS
para disco ya está terminada. Permite anidamiento de ficheros.
2015-05-20
Por fin CAT
ya está terminada, tras mucho investigar el desensamblado de G+DOS y hacer muchas pruebas.
CODE (CAT) ( n -- )
AF POP
BC PUSH IX PUSH \ save the Forth registers
AF PUSH PATCH HOOK
\ Copy Forth UFIA to G+DOS UFIA1.
UFIA HL LDP# UFIA1 DE LDP# /UFIA BC LDP# LDIR
HL POP L A LD \ CAT type: 2=compact;4=detailed
24B5 CALL \ CAT_RUN
168E CALL \ BORD_REST = restore the border
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
NEXT JP END-CODE
\ CAT ( ca len -- )
\
\ Show a disk catologue using the given wild-card filename.
\ See the +D manual for wild-card syntax.
\
\ The catalogue can be printed out on a printer by storing
\ the number 3 into SSTR1 (a field of UFIA that holds the
\ stream number to use) before doing `CAT`. The default value
\ is 2 (screen) and should be restored. Example:
\
\ 3 SSTR1 C! S" FORTH?.*" CAT 2 SSTR C!
: CAT ( ca len -- ) FILENAME>UFIA 4 (CAT) ;
\ SCAT ( ca len -- )
\
\ A variant of `CAT` that shows an abbreviated catalogue.
: ACAT ( ca len -- ) FILENAME>UFIA 2 (CAT) ;
DECIMAL
2015-06-17
Corrijo un error: Tras definir, RDROP
, NEXT
era parcheado para ejecutar el código de RDROP
, más rápido. Pero no era correcto porque NEXT
es una palabra de alto nivel, que por tanto al ser ejecutada creaba un nivel adicional en la pila de retorno, que es lo que borraba la propia palabra. RDROP
es primitiva, y por tanto no crea esa anidación. Aunque las dos palabras borran el elemento superior de la pila de retorno, no hacen lo mismo.
El caso de UNLOOP
y 2RDROP
es diferente, sí pueden compartir el mismo código.
2015-07-05
Corrijo un error en el código de POINT
, introducido con los últimos cambios en el módulo.
Corrijo el código que aplica el parche de (R/W)
en <afera.fsb>: la dirección del parche quedaba en la pila.
2015-07-06
Hago COLORS0
configurable.
Corrijo un error en :NONAME
, que al usar SMUDGE
para anular el efecto del siguiente SMUDGE
, hecho por ;
, impedía usar en la palabra definida con :NONAME
la última palabra creada. La solución ha sido que :NONAME
parchee ;
para desactivar su SMUDGE
y que el parche se elimine por sí solo con la ejecución de ;
, como se ve en el código:
: ;SMUDGE ( -- )
\ Called by `;` to do `SMUDGE`.
[ HERE ] \ Save the address of `SMUDGE`.
SMUDGE \ When patched by `:NONAME`, this is `NOOP`.
\ Unpatch a possible patch done by `:NONAME`,
\ using the saved address where `SMUDGE` was compiled:
[ ' SMUDGE CFA ] LITERAL LITERAL ! ;
\ Substitute the `SMUDGE` in `;` with `;SMUDGE`:
' ;SMUDGE CFA 25378 !
: :NONAME ( -- cfa )
?EXEC CURRENT @ CONTEXT !
\ Deactivate the `SMUDGE` in `;SMUDGE`:
[ ' NOOP CFA ] LITERAL ' ;SMUDGE !
\ Create a code field of a colon definition:
HERE !CSP 25350 ,
] ;
2015-07-07
Reviso, corrijo y simplifico las dos implementaciones de DEFER
, gracias a un problema detectado al usar IS
con :NONAME
durante el desarrollo de Tron 0xF. La implementación predeterminada es ahora la que espera en la pila una dirección de campo de código (cfa).
Reviso y simplifico las implementaciones de VALUE
y TO
. La predeterminada sigue siendo la compatible con ANS Forth.
2015-07-13
Varios errores relacionados con el color, detectados durante el desarrollo de Tron 0xF. El primero es que INVERSE
no surte efecto si es seguido por INK
o PAPER
:
1 INVERSE 2 INK ." No inverse mode!"
1 INVERSE 2 PAPER ." No inverse mode!"
Esto no ocurre en Abersoft Forth, aunque el código de INVERSE
en Afera hace lo mismo que el original, solo que en Z80. El problema está en las versiones mejoradas de INK
y PAPER
, que llaman a la rutina en la dirección 0x1CAD de la ROM para copiar los colores temporales como permanentes; pero INVERSE
fija precisamente el estado de vídeo inverso permanente, por lo que INK
o PAPER
lo sobreescriben con el valor temporal, que es cero. La solución fue modificar INVERSE
para que cambiara ambos bitios del modo de impresión inverso: permanente y temporal. En el mismo caso está GOVER
. El nuevo código es:
( GOVER )
\ Convert `GOVER` to a code word.
HERE ' GOVER DUP CFA ! ( f -- )
HEX
E1 C, \ pop hl
78 04 + C, \ ld a,h
B0 05 + C, \ or l
21 C, 5C91 , \ ld hl,23697
CA C, ' GOVER 10 + , \ jp z,turn_off
\ ; turn on
CB C, C6 8 0 * + C, \ set 0,(hl) ; temporary
CB C, C6 8 1 * + C, \ set 1,(hl) ; permanent
C3 C, NEXT , \ jp next
\ turn_off:
CB C, 86 8 0 * + C, \ res 0,(hl) ; temporary
CB C, 86 8 1 * + C, \ res 1,(hl) ; permanent
C3 C, NEXT , \ jp next
DUP ' GOVER OVER HERE SWAP - CMOVE
DP ! DECIMAL -->
( INVERSE )
\ Convert `INVERSE` to a code word.
HERE ' INVERSE DUP CFA ! ( f -- )
HEX
E1 C, \ pop hl
78 04 + C, \ ld a,h
B0 05 + C, \ or l
21 C, 5C91 , \ ld hl,23697
CA C, ' INVERSE 10 + , \ jp z,turn_off
\ ; turn on
CB C, C6 8 2 * + C, \ set 2,(hl) ; temporary
CB C, C6 8 3 * + C, \ set 3,(hl) ; permanent
C3 C, NEXT , \ jp next
\ turn_off:
CB C, 86 8 2 * + C, \ res 2,(hl) ; temporary
CB C, 86 8 3 * + C, \ res 3,(hl) ; permanent
C3 C, NEXT , \ jp next
DUP ' INVERSE OVER HERE SWAP - CMOVE
DP ! DECIMAL
Aprovecho para corregir un fallo pendiente desde hace tiempo: INVERSE
, BRIGHT
, FLASH
y GOVER
solo comprobaban si los 8 bitios bajos de la bandera en la pila eran cero. Ahora comprueban el valor completo (como se ve en el ejemplo de arriba).
El segundo fallo es que INK
no surte efecto con PLOT
a menos que se imprima algo entre medias:
2 ink 10 10 plot \ plots but...
10 10 point . 1 \ ...with black ink! why?
\
3 ink cr 10 10 plot \ it works with `cr` between
\
3 ink
10 10 plot \ it works also in two commands
Por algún motivo, la variable del sistema ATTR T (dirección 23695) no cambia, a pesar de que INK
usa el método de imprimir el carácter de control correspondiente para hacer el cambio de color:
6 ink 23695 c@ 100 100 plot \ black ink, black paper plot!
. 0 \ content of ATTR T
La definición de INK
es correcta:
HEX HERE ' INK DUP CFA !
\ ( b -- ) \ 28%
\ b = color value
3E C, 10 C, D7 C, \ ld a,16 / rst 0x10
E1 C, 7D C, D7 C, \ pop hl / ld a,l / rst 0x10
CD C, 1CAD , \ call set-permanent-colors
C3 C, NEXT , \ jp next
DUP ' INK OVER HERE SWAP - CMOVE DP !
Este mismo problema ocurre en Abersoft Forth, a pesar de que su definición de INK
es muy diferente. Sigo sin entender cuál es el motivo del fallo, pero esta nueva definición, que manipula las variables del sistema directamente, sin usar la ROM, funciona bien y es más rápida:
HEX HERE
' INK DUP CFA ! \ convert `INK` to a code word
\ ( b -- )
\ b = color value
D1 C, \ pop de
3A C, 5C8F , \ ld a,(23695) ; ATTR_T
E6 C, F8 C, \ and %11111000 ; remove the current ink
50 07 + C, \ ld d,a ; save the result
78 03 + C, \ ld a,e ; new ink
E6 C, 07 C, \ and %00000111 ; only the ink
B0 02 + C, \ or d ; combine with the current attr
32 C, 5C8F , \ ld (23695),a ; update ATTR_T
32 C, 5C8D , \ ld (23693),a ; update ATTR_P
C3 C, NEXT , \ jp next
DUP ' INK OVER HERE SWAP - CMOVE DP !
Reescribo PAPER
de forma análoga. El único inconveniente es que con este método los colores 8 (contraste) y 9 (transparente) son ignorados. Para gestionarlos harán falta nuevas palabras.
2015-07-14
Escribo POSTPONE
, de ANS Forth:
: POSTPONE ( "name" -- )
-FIND 0= 0 ?ERROR ( pfa b ) \ error if not found
64 AND 0= \ non-immediate word?
IF COMPILE COMPILE THEN \ if so, compile `compile`
CFA , \ compile the cfa
; IMMEDIATE
Corrección: las nuevas versiones de INK
y PAPER
dejaban sin efecto a BRIGHT
y FLASH
, que solo actualizaban ATTR_P. Para evitarlo, estas últimas han sido reescritas para modificar también ATTR_T:
( FLASH )
HERE
' FLASH DUP CFA ! \ convert `FLASH` to a code word
\ ( f -- )
HEX
E1 C, \ pop hl
78 04 + C, \ ld a,h
B0 05 + C, \ or l
CA C, ' FLASH 11 + , \ jp z,turn_off
\ ; turn on
FD C, CB C, 53 C, C6 08 7 * + C, \ set 7,(iy+0x53) \ ATTR_P
FD C, CB C, 55 C, C6 08 7 * + C, \ set 7,(iy+0x55) \ ATTR_T
C3 C, NEXT , \ jp next
\ turn_off:
FD C, CB C, 53 C, 86 08 7 * + C, \ res 7,(iy+0x53) \ ATTR_P
FD C, CB C, 55 C, 86 08 7 * + C, \ res 7,(iy+0x55) \ ATTR_T
C3 C, NEXT , \ jp next
DUP ' FLASH OVER HERE SWAP - CMOVE DP ! DECIMAL -->
2015-07-16
Muevo MS
y S=
a ficheros propios. El motivo es no desperdiciar la escasa memoria que queda libre en Tron 0xF, que está llegando al final de su desarrollo. Así se reduce el número de palabras que no se usan pero que están incluidas en módulos necesarios.
Creo una nueva definición para MS
, con código adaptado de DZX-Forth:
CREATE MS ( u -- ) HEX
D1 C, \ pop de
HERE \ ms1:
78 03 + C, B0 02 + C,
\ ld a,e
\ or d
CA C, NEXT , \ jp z,next
21 C, 0004 , \ ld hl,4 ; MHz
29 C, 29 C, 29 C,
\ add hl,hl
\ add hl,hl
\ add hl,hl
HERE \ ms2:
E3 C, E3 C, E3 C, E3 C,
\ ex (sp),hl ; 19T
\ ex (sp),hl ; 19T
\ ex (sp),hl ; 19T
\ ex (sp),hl ; 19T
E5 C, E1 C, 2B C,
\ push hl ; 11T
\ pop hl ; 10T
\ dec hl ; 6T
3E C, 00 C, 78 05 + C, B0 04 + C,
\ ld a,0 ; 7T
\ ld a,l ; 4T
\ or h ; 4T
C2 C, , \ jp nz,ms2 ; 10T
1B C, \ dec de
C3 C, , \ jp ms1
SMUDGE DECIMAL
La versión provisional usada hasta ahora dependía de la variable del sistema FRAMES (y por tanto del estado de las interrupciones) y, por ello, tenía una precisión de 20 milisegundos:
[DEFINED] SYS-FRAMES ?\ 23672 CONSTANT SYS-FRAMES
: MS ( u -- )
\ Wait u ms (miliseconds), with 20 ms precision.
20 / SYS-FRAMES @ +
BEGIN DUP SYS-FRAMES @ U< UNTIL DROP ;
2015-07-18
Durante el desarrollo de Tron 0xF descubro un fallo en Afera: Abersoft Forth usa en varios lugares el valor literal devuelto por LO
, es decir, la dirección del disco RAM de Forth, en lugar de usar el valor en curso mediante una llamada a esta palabra. Esto hace que tras ejecutar el módulo <hi-to.fsb>, que mueve el disco RAM hacia la parte superior de la memoria para ganar 1 KiB de memoria adicional para el diccionario, LOADT
cargue los discos RAM en la dirección antigua.
Por una parte, INIT-DISC
debe ser parcheado para usar LO
, (aunque no tiene que ver con el fallo de LOADT
); esto puede hacerse el el módulo principal de la biblioteca:
\ In `INIT-DISC`, change the literal 0xD000 to `LO`:
' INIT-DISC ' NOOP CFA OVER ! ' LO CFA SWAP 2+ !
También (TAPE)
y las cabeceras de lectura y grabación de cintas deben ser parcheadas, pero solo es posible hacerlo en el módulo <hi-to.fsb>, tras haber cambiado el valor de LO
:
: HI>TOP ( -- )
\ Update `HI` and `LO`:
LO FREED + ' LO ! NEW-HI ' HI !
\ Patch `(TAPE)` and the tape headers
\ with the new value of `LO`:
LO [ ' (TAPE) 6 + ] LITERAL ! LO 75F3 ! LO 7604 ! ;
El parcheado de COLD
(para que use FIRST
en lugar de su valor predeterminado) era engorroso:
: ', ( "name" -- ) [COMPILE] ' CFA , ; HERE
\ Compile the patched version of `COLD`.
', EMPTY-BUFFERS ', FIRST ', USE ', ! ', FIRST ', PREV ', !
', DR0 ', LIT 5E52 , ', LIT 5E66 , ', @ ', LIT 6 , ', +
', LIT 10 , ', CMOVE ', LIT 5E4C , ', @ ', LIT 6CF8 , ', !
', ABORT
\ XXX Space freed: 4 bytes at 0x6E06
\ Patch `COLD` and free the used space.
DUP ' COLD OVER HERE SWAP - CMOVE DP ! FORGET ',
El primer método usado en su día era más sencillo, pero dejaba dos NOOP
en el código, en lugar de dejar ese espacio inútil al final:
' NOOP CFA ' COLD 02 + ! ' FIRST CFA ' COLD 04 + !
' NOOP CFA ' COLD 0A + ! ' FIRST CFA ' COLD 0C + !
El nuevo método es el siguiente:
\ Compile the patched version of `COLD`.
HERE ] EMPTY-BUFFERS FIRST USE ! FIRST PREV ! DR0
5E52 5E66 @ 6 + 10 CMOVE 5E4C @ 6CF8 ! ABORT [
\ XXX Space freed: 4 bytes at 0x6E06
\ Patch `COLD` and free the used space.
DUP ' COLD OVER HERE SWAP - CMOVE DP !
Corrijo un fallo escondido: en el módulo principal, la actualización de la versión de usuario se hacía con números en decimal mientras la base era hexadecimal. Esto hacía que se corrompiera el primer octeto del valor de inicio del puntero de las variables de usuario, situado en HEX 10 +ORIGIN
, aunque en la práctica no causaba problemas porque Abersoft Forth, al contrario que la implementación original de fig-Forth, no usa este valor para inicializar el sistema en el arranque en COLD
. La versión corregida es:
43 0A +ORIGIN C! \ 0x43 = ASCII "C"
2015-07-19
Nueva palabra BASCALL
para llamar a líneas del programa en BASIC y reentrar mediante el punto de entrada warm habitual. El código está adaptado del de Spectrum Forth-83 de Lennart Benschop, y mejorado para que funcione tanto si el modo de pantalla completa, proporcionado por el módulo <plusscreen.fsb>, está activo o no (en Spectrum Forth-83 siempre está activo, no es opcional).
2015-08-12
Sustituyo la versión de 2/
usada hasta ahora:
.( 2/ )
\ Code adapted from the `2/` written on 1985-05-07 by Edmund
\ Ramm for the Z80 fig-Forth implementation written by Dennis
\ L. Wilson (1980-09-07).
CREATE 2/ ( n1 -- n2 )
HEX
E1 C, \ pop hl
CB C, 7C C, \ bit 7,h ; negative?
18 C, 01 C, \ jr z,twosl1 ; no
23 C, \ inc hl ; yes, add 1
\ twosl1:
CB C, 2C C, \ sra h
CB C, 1D C, \ rr l ; asr hl
C3 C, PUSHHL , \ jp PUSHHL
SMUDGE DECIMAL
En su lugar uso el código adaptado de Spectrum Forth-83, pues no entiendo qué utilidad tiene la comprobación que hace la versión anterior, que no supone diferencia en los resultados:
.( 2/ )
\ Code adapted from Lennart Benschop's Spectrum Forth-83 (1988).
CREATE 2/ ( n1 -- n2 )
HEX
E1 C, \ pop hl
CB C, 2C C, \ sra h
CB C, 1D C, \ rr l ; asr hl
C3 C, PUSHHL , \ jp PUSHHL
SMUDGE DECIMAL
2015-08-28
Módulos de G+DOS: Confirmo que DRIVE@
funciona con CAT
.
2015-10-26
Reviso todas las fuentes para unificar las cabeceras, y actualizar o corregir algunos comentarios.
Borro el fichero _sequals.fsb_, versión antigua de _s-equals.fsb_.
2015-10-30
Añado algunas dependencias que faltaban en algunos ficheros fuente del directorio benchmarks/. De todas formas estos ficheros fueron escritos solo para ser utilizados durante el desarrollo.
2016-03-02
Elimino la directiva #vim
que convertía la cadena "\*" en el carácter 127 (el signo de copyright en ZX Spectrum), porque solo funciona en fsb: actualmente para construir la biblioteca se usa fsb2, que no reconoce directivas. En lugar del símbolo de copyright uso la cadena «(C)».
Actualizo el formato del número de versión y el mensaje de bienvenida.