Guía
Para empezar
¿Qué tipo de maquina tienes?
- Si tienes el gomas, Spectrum+, Spectrum 128K con disipador o el Spectrum +2 gris, quita el jumper J3 (el jumper más cerca del puerto JTAG).
- Si tienes el +3 o +2 negro, necesitas instalar el jumper J3.
Para las máquinas de 128K, necesitas usar el modo "USR 0" para usar las extensiones de BASIC (los +3 lo hace de forma automática. Se va a arreglar esto para los otros modelos de 128K en una actualización del firmware).
Configuración
La configuración por defecto es usar DHCP para configurar la dirección IP y DNS. Si no tienes un servidor de DHCP, desde ZX BASIC teclea:
%ifconfig
También puedes tocar el NMI para entrar en el menú de configuración.
Configuración de sistemas de ficheros
Se necesita un servidor de ficheros (el tnfsd; es una tarea pendiente hacer un paquete de instalación para este programa). Hay un servidor de ficheros público disponible en vexed4.alioth.net. Para montarlo desde BASIC:
%mount 0,"vexed4.alioth.net"
Es probable que quieras montar un sistema de ficheros de forma automática. Puedes configurar el "automounter" usando este comando:
%fsconfig
Aparecerá este menú:
Pulsa la tecla "A" para añadir un nuevo sistema de ficheros. Por ejemplo, para usar "tnfs://vexed4.alioth.net" como sistema de ficheros por defecto:
- Pulsa "A", "Set a filesystem"
- Teclea "0" (y Enter) para seleccionar FS 0
- Teclea tnfs://vexed4.alioth.net
- Pulsa "D" para guardar los cambios.
Cuando se resetea el Spectrum, se va a montar el servidor "vexed4.alioth.net".
Si hay problemas en montar el sistema de ficheros (por ejemplo, si el servidor "vexed4.alioth.net" ha dejado de funcionar), puedes pulsar BREAK mientras el Spectrum está tratando de montarlo para abortar la operación.
Guía breve a los comandos de BASIC
%mount
%mount <fsnum>,"<url>" - Montar un sistema de ficheros. Ejemplos:
%mount 0,"vexed4.alioth.net" %mount 0,"192.168.0.1" %mount 1,"tnfs://192.168.0.1" %mount 3,"tnfs://example.com/games"
El URL funciona como los de la Web. Si hubiera un modulo de sistemas de ficheros para el DivIDE, se podría teclear %mount 0,"ide://0" (o algo muy parecido).
%umount
%umount <fsnum> - Desconectar de un sistema de ficheros. Ejemplo:
%umount 0
%cat
%cat "<fsp>" - Mostrar los contenidos de un directorio. Ejemplos:
%cat %cat "foobar" %cat "0:/foo/bar/baz"
El "path" funciona como Unix. El separador entre los directorios es el "/". ".." significa un directorio por arriba, "." significa el directorio corriente.
%cd
%cd "<fsp>" - Cambiar el directorio. Ejemplos:
%cd "/" %cd "juegos" %cd "/programs/basic" %cd ".."
%fs
%fs <fsnum> - Cambiar el sistema de ficheros. Ejemplo:
%fs 1
El sistema de ficheros por defecto es 0.
Leyendo y guardando ficheros
%load
%load "<fsp>" [CODE dirección] - Cargar un fichero. Ejemplos:
%load "manic" %load "imagen" CODE 16384 %load "/foo/bar/baz.zx" %load ""
El comando %load "" cargará el programa BASIC "boot.zx". (Si has seleccionado la opción "Autoboot" en el menú de %fsconfig, el Spectrum cargará "0:/boot.zx" cuando se resetea).
%save
%save "<fsp>" [CODE dirección,tamaño] - Guardar un fichero. Ejemplos:
%save "programa" %save "imagen" CODE 16384,6912 %save "programa" LINE 1
%aload
%aload "<fsp>" CODE dirección - Cargar datos arbitrarios. Ejemplo:
%aload "codigomaquina" CODE 32768
La diferencia entre %load y %aload es que "%aload" efectivamente carga un fichero "sin cabeceras". Los ficheros "normales" son del formato tap (es decir, tienen los mismos cabeceras que un fichero guardado en una cinta, contienen la dirección en que se necesita cargar los datos, el tipo de datos, por ejemplo "Program" o "Bytes"). El comando %aload puede cargar cualquier fichero. Por eso, siempre tienes que poner la dirección en que los datos debe cargarse porque no hay cabecera que especifica esta información.
Entonces %aload es algo imprendiscible cuando quieres cargar un fichero que ha creado un ensemblador en un PC.
%tapein
%tapein "<fsp>" - Cargar un fichero del tipo .TAP. Ejemplo:
%tapein "jsw.tap" LOAD ""
Efectivamente, %tapein es para emular la cinta. Para cargar lo que contiene el fichero, debes teclear LOAD "".
%loadsnap
%loadsnap "<fsp>" - Cargar un snapshot del tipo .SNA. Ejemplo:
%loadsnap "matchday.sna"
Se puede cargar .SNA de 48K o 128K.
Abrir y cerrar ficheros
Hay un secuencia de comandos que se usa con el sistema de streams de ZX BASIC. Funciona con ficheros, directorios y sockets de la red. Aquí tienes un ejemplo y una explicación breve (escribiré más en las semanas que vienen...)
10 %open #4,"file","r" 20 %oneof 100 30 INPUT #4,a$ 40 PRINT a$ 50 GO TO 30 100 %close #4
Este programa abre el fichero "file" y lee los contenidos, poniendolos en la pantalla. La primera linea:
10 %open #4,"file","r"
...abrirá el fichero que se llama "file" para leer. Linea 20 es para coger el fin del fichero. Se dice que vamos a saltar a la línea 100 cuando acabe el fichero. Líneas 30, 40 y 50 son comandos estandares del Spectrum para leer el "stream" y poner los resultados en la pantalla. Entonces llegamos a la línea 100 donde cerramos el fichero. (¡Es muy importante cerrar el stream!)
Abrir y cerrar sockets
Es muy fácil hacer cosas similares con una conexión de la red. Por ejemplo:
10 %connect #4,"spectrum.alioth.net",80 20 %oneof 100 30 PRINT #4;"GET HTTP/1.0" 40 PRINT #4 50 INPUT #4;a$ 60 PRINT a$ 70 GO TO 50 100 %close #4
Así que -con código muy similar- podemos conectar a una máquina en la red con un socket de TCP. La sintaxis de %connect es:
%connect #<streamno>,"dirección",puerto
Aqui tienes un ejemplo de un servidor muy sencillo:
10%listen #4,2000 20%accept #5,4 30 INPUT #5;a$ 40 PRINT #5;"Me has enviado: ";a$ 60%close #5 70%close #4
Puedes probarlo desde un PC con telnet:
telnet <ip-del-spectrum> 2000
Por ejemplo:
serendipity:~ winston$ telnet 172.16.0.41 2000 Trying 172.16.0.41... Connected to 172.16.0.41. Escape character is '^]'. hello Me has enviado: hello Connection closed by foreign host.
Un ejemplo un poco más complicado, un servidor que puede acceptar hasta 3 conexiones al mismo tiempo a través de tcp puerto 2000:
1 DIM c(4) 10%listen #4,2000 20%control #5 30 PRINT #5;"p" 40 PRINT "Esperando..." 45 INPUT #5;a;a$ 50 IF a<>0 THEN GO TO 200 60 LET a$=INKEY$ 70 IF a$="x" THEN GO TO 700 80 GO TO 45 200 IF a=4 THEN GO TO 400 210 IF a$="disconn" THEN GO TO 600 220 INPUT #a;c$ 230 PRINT "Strm ";a;": ";c$ 240 IF c$="rnd" THEN PRINT #a;RND: GO TO 40 250 IF c$="foo" THEN PRINT a;"Foo bar baz": GO TO 40 260 IF c$="quit" THEN PRINT #a;"Adios":GO TO 600 300 PRINT #a;"No te puedo entender" 310 GO TO 40 400 FOR i=1 TO 4 410 IF c(i)=0 THEN LET chan=i+5: GO TO 500 420 NEXT i 430 PRINT "No hay canales" 440 STOP 500 PRINT "Conexion aceptado en canal ";chan 510%accept #chan,4 520 LET c(i)=1 530 GO TO 40 600 PRINT "Cerrando #";a 605%close #a 610 LET c(a-5)=0 620 GO TO 40 700 PRINT "Se acaba el programa" 710%close #5 715 PRINT "Cerrando socket" 720%close #4 730 PRINT "Cerrando conexiones" 740 FOR i=1 TO 4 750 IF c(i)=1 THEN %close #i+5 760 NEXT i
Para probarlo desde un PC, teclea "telnet <ip-de-spectrum> 2000". Puedes escribir "rnd", "quit" o "foo".
Destaco estas partes de este programa:
10%listen #4,2000
Cuando ejecuta esta línea, el Spectrum empieza a escuchar al puerto 2000 (tcp). Pero necesitamos hacer un poco más para aceptar conexiones: tenemos que usar el comando "%accept". Pero %accept va a esperar para una conexion, y va a parar la ejecución de nuestro programa. Por eso hay un canal de control. Se abre así:
20%control #5
Ahora el canal de control está conectado a stream #5 de BASIC. Así que podemos escribirlo y leerlo. Los siguentes:
30 PRINT #5;"p" 50 INPUT #5;a;a$
le dice al canal de control "dime si hay datos pendientes" (el comando "p"). En línea 50, llegan dos cosas: el número del stream en que hay datos, y información sobre los datos. El canal llega en el variable "a", la información en "a$". Si el stream es 4 (es decir, stream #4) sabemos que debe ser una conexión nueva porque #4 es el "socket de escuchar". Si el variable "a" contiene 0, entonces no hay datos pendientes.
510 %accept #chan,4
En esta línea, aceptamos conexiones nuevas. La sintaxis de este comando es:
%accept #stream,stream-de-escuchar
El stream #4 es nuestro stream-de-escuchar. El variable "chan" contiene el número del stream nuevo que queremos abrir.
Código máquina
Si quieres escribir programas en asm o C, hay un guía (en inglés) con ejemplos. Se usa los sockets en la misma manera de los de UNIX o Windows, si ya sabes cómo escribir programas de la red para sistemas operativos modernos, no tendrás ningún problema. Si nunca has usado la librería de BSD sockets, hay tutoriales en esta página.