Historia de DZX-Forth en 2014
Descripción del contenido de la página
Historia del desarrollo en 2014 de DZX-Forth, un Forth para ZX Spectrum +3e.
2014-11-03
Idea: Proyecto DZX-Forth, una adaptación de DX-Forth a ZX Spectrum...
DX-Forth es un Forth moderno para CP/M. Bastaría adaptar el código relacionado con el sistema operativo...
Primeros cambios en las fuentes de Z80 para poder ensamblarlas con Pasmo. Inicio de la versión A-00.
2014-12-15
Reviso el proyecto y hago algunos cambios.
Descubrimiento: Pasmo hace los include
antes de los if
.
La adaptación de las fuentes será muy difícil sin la documentación del ensamblador original.
2014-12-16
Logro compilar todas las fuentes con Pasmo. Tuve que hacer varios cambios automáticos con Vim, y otros manuales. Necesité consultar un manual de MASM para confirmar algunas instrucciones específicas de la plataforma.
La adaptación de CP/M a ZX Spectrum será larga.
2014-12-17
Para facilitar el trabajo, junto en un solo fichero, <dzx-forth.z80s>, todas las fuentes originales salvo, de momento, <float.z80s>.
Tras hacer los cambios necesarios en el módulo de coma flotante, el ensamblado tuvo éxito.
Tamaño del fichero TAP resultante:
- Sin el módulo de coma flotante: 16864
- Con el módulo de coma flotante: 20665
2014-12-18T04-08
La macro header
está terminada: adaptada, mejorada y comprobada:
previous_nfa defl 0 ; initial link pointer (end of chain)
_ header macro enabled,name,immediate,fl,alias_xt
; enabled = enable the header? (0=disable)
; name = name string
; immediate = immediate
; fl = application/system flag ; XXX OLD not used anymore
; XXX TODO remove 'fl' from the macro header calls
; alias_xt = alias xt
if enabled
; the name field
last_nfa defl $ ; link address for next word
bits defl 0
if not nul immediate
bits defl bits+0x40 ; set immediate bit
endif
if not nul alias_xt
bits defl bits+0x80 ; set alias bit
endif
local _first ; address of the first char of the name
local _next ; address after the last char of the name
db _next-_first+bits ; count and flags byte
_first db name
_next
; the link field
dw previous_nfa
; the code field
if nul alias_xt
last_xt defl $+2
else
last_xt defl alias_xt
endif
dw last_xt
previous_nfa defl last_nfa
endif
endm
2014-12-18T04:37
Ya están corregidas las palabras cuyo código continuaba en el de la palabra siguiente. Esto funcionaba en DX-Forth porque las cabeceras estaban en otra zona de memoria.
2014-12-18T20:50
Tras incorporar los cambios de DX-Forth 4.09, la última versión disponible, y rehacer los cambios perdidos en la operación, el código puede ser compilado de nuevo.
2014-12-19T00:18
Nuevas palabras toupper
, lower
y tolower
para completar upper
, que ya existe. Todas van al módulo de cadenas.
También la rutina cls
es convertida en una palabra de Forth.
2014-12-19T03:34
Más cambios. Más palabras nuevas. Primera purga de código original anulado desde hace tiempo porque es específico de CP/M e inútil para ZX Spectrum.
Primera prueba de ejecución con una versión de cold
que solo cambia el borde y queda en un bucle sin fin. Hasta ahí parece que el intérprete funciona. Pero si añado a cold
la palabra decimal
, el sistema estalla...
2014-12-20
El problema es que la zona de variables de usuario no está creada. Por eso decimal
no funciona: base
es una variable de usuario.
Ajustes masivos en el formato del código. Más cambios de nombre de etiquetas. Todo para hacer el código más legible.
Completada la palabra border
, que sirve para las pruebas de ejecución.
_header _public,'BORDER'
border_:
; Code based on Lennart Benschop's Spectrum Forth-83 System:
; : BORDER ( n -- )
; DUP DUP 4 < 7 AND SWAP 8 * + 23624 C! 254 P! ;
; This is my translation to Z80:
pop hl
border_.l:
if 0
; XXX OLD -- the screen will be used as a whole, not like Sinclair BASIC,
; so this is not needed.
; Set the paper of the bottom screen
ld a,l
cp 4 ; dark color?
jp nc,border_.a
; dark color
sla a
sla a
sla a ; *8 (converted to paper_)
add a,7 ; white ink
ld (sys_bordcr),a
endif
ld a,l
border_.a:
out (254),a
jp next
2014-12-22
Completadas las palabras bye
, return
, key?
y key
.
2014-12-23
Corregido error grave que arruinaba el intérprete: (next)
continuaba su ejecución en la palabra definida a continuación, execute
. Esto en DX-Forth era posible, porque las cabeceras estaban separadas.
Completadas las palabras type
y bootmessage
.
2014-12-25
La mayoría de las etiquetas ya tiene nombres significativos. Esto hace el código más legible.
Siguen los trabajos con el mapa de memoria, las variables de usuario y el proceso de arranque en frío.
up
(user area pointer) pasa a ser udp
(user data pointer), más estándar y claro.
Eliminado el antiguo parámetro fl
de las llamadas a la macro hdr
.
2014-12-26
Comienza la tarea de adaptar quit
, lo que supone reescribir (accept)
.
2014-12-27
(accept)
es reescrito desde cero, con varias palabras pequeñas para facilitar su ampliación posterior con más teclas de control.
cf0
es renombrada como cs0
, por coherencia con las demás palabras de pila.
Nueva palabra 0<>branch
y nuevas etiquetas con sinónimos para las direcciones de ejecución tanto de ella como de ?branch
.
Primer borrador de .s
, útil durante el desarrollo; después irá en un fichero fuente opcional.
Corregido un error oscuro en 2dup
, provocado por un despiste durante la adaptación: todas las conversiones del original dpush
están mal: debe meterse en pila también el registro HL. Corrijo la rutina, que ahora llamo push_de_hl
. Después busco los puntos en que en la fuente original de DX-Forth se salta a dpush
y los corrijo en la fuente de DZX-Forth.
Corregido un error en (of)
, que continuaba la ejecución en branch
suponiendo, como pasaba en DX-Forth, que no había cabecera entre medias.
2014-12-28
Nueva palabra alias
, tomada de Gforth; usa el código final de aka
. Sería más lógico al revés: Mover ese código a alias
y llamarlo desde aka
.
; ALIAS ( xt "newname" -- )
; XXX NEW -- after Gforth; alias doesn't copy the precedence bit of the xt
; XXX TODO -- test
hdr _public,'ALIAS'
alias:
call do_colon
dw lit,-1 ; flag for a not immediate word
dw branch,aka.alias
; AKA ( "oldname" "newname" -- )
; defined tuck ?defined (header)
; $80 xnfa 0> if immediate then
hdr _public,'AKA'
aka:
call do_colon
dw defined_ ; ( ca|xt -1|0|1 )
dw tuck ; save for later
dw question_defined ; abort if not defined
aka.alias:
; ( -1|1 xt "newname" )
dw header ; ( -1|1 )
dw c_lit
db alias_mask
dw xnfa ; set the alias mask of the header
dw zero_greater ; is the old word immediate?
dw branch_if_false,aka.end
dw immediate ; make the new word immediate
aka.end:
dw exit
La corrección de push_de_hl
en todo el programa, hecha ayer, permite que funcione la palabra .
(el punto), y presumiblemente muchas otras palabras.
2014-12-30
Eliminado el código que quedaba del puntero de diccionario de sistema (dph
), así como la palabra ?protected
, que está relacionada. Esta separación en dos diccionarios no se hará en DZX-Forth.
Corregido un error en (loop)
, que continuaba su ejecución en unloop
sin tener en cuenta la cabecera, que en DX-Forth no estaba en medio.
Despiste en el original: el salto a inte3 puede ser directo a inte14:
dw bran,inte3
inte2: dw exec
inte3: dw bran,inte14
inte4: dw count
dw base,at,tor
Palabras que cambian de nombre:
En <dzx-forth.z80s>:
getfilename
->parse-filename
loadfile
->current-block-file
fload
->load-file
setfcb
->set-fcb
En <tools.fs>:
fname
->current-stream-file
loadfile
->current-block-file
Cambio las extensiones predeterminadas de ficheros fuente (.FB y .FS en lugar de .SCR y .F).