Wafadrive. WOS: Sistema Operativo del Rotronics Wafadrive. El Wafadrive es un sistema de micro cintas, ofrecido como alternativa al Interfase 1 / Microdrive. Tiene solamanete dos unidades de cartucho y dos puertos para impresora, uno serial y otro paralelo. Sus cartuchos son más anchos que los del M/drive, y se les conoce como wafers, traducible como obleas o tabletas. Sintaxis: comando *"[drive:] nombre" Comandos: Format*, Cat*, Load*, Save*, Merge*, Verify*, Move*, Erase*, Open#*, Close#*, New*, Clear*, Cls* Dos drives admitidos: a y b. El nombre es de hasta 10 caracteres máximo. Todas las minúsculas en el nombre son automáticamente cambiadas a mayusculas al displayarse en pantalla mediante CAT*. El WOS cataloga automáticamente cada nombre dándole una extensión indicando el tipo de archivo: .PRG - para archivos Basic .BYT - para código máquina y pantallas salvadas .DAT - para ficheros tipo Open# Se admite "*" como único wildcard (comodín) específicado. Pero "*" no reconoce ninguna letra(s) que se tipee(n) después. "*alfa" por ejemplo es igual a tipear solo "*". Format* sintaxis_1: Format *"[drive:]volumen" Formatea y da el nombre al wafer en el drive especificado. Ejemplo: Format *"a:disk1" Nota: si se quiere cancelar un Format* dado por error, basta con hacer un Break inmediatamente. sintaxis_2: Format *"R";baudios donde: baudios = solo puede ser: 110, 150, 300, 600, 1200, 2400, 4800, 9600 0 19200. Configura el protocolo para la transmisión/recepción por medio del puerto serial. El valor por defecto es de 1200 baudios. Cualquier otro número dará error. Cat* sintaxis: Cat <*/#>["drive:"] Cat* - carga y displaya el directorio de la unidad por defecto. Cat *"b:" muestra el contenido dela unidad B. Cat# - permite seleccionar / cambiar la unidad por defecto sin displayar nada. Cat #"b:" cambia al drive B como unidad por defecto. Otro método para seleccionar el drive es usando Poke: Poke 23767, . (donde unidad = 0 para el drive A y 1 para el drive B) Peek 23767 revela cuál es la unidad en uso. Save* Sintaxis_1: Save <*/#>"[drive:]nombre" [Line / Screen$] sintaxis_2: Save <*/#>"[drive:]nombre", dir, long, [run] Cuando el nombre ya existe el Wos informa del hecho y se detiene sin grabar nada. La opción Save# sobregraba sin dar mensajes o hacer preguntas al respecto. Ejemplos: Save #"opera.bas" Line 1 - sobregraba archivo ya existente. Save *"image.scr",16384,6912 - salva la posición de pantalla como .BYT. Save *"img.scr" Screen$ - hace lo mismo que el ejemplo anterior. Save *"form/code",32000,1000,32000 - salva 1000 bytes, con autoarranque en la dirección 32000 como .BYT. Load* sintaxis: Load* ["[drive:][nombre]"[,dir[,long]]] Ejemplos: Load* - sin parámetro alguno, carga el primer archivo salvado en la unidad usada por defecto. Load* "b:" - carga el primer programa salvado en el drive B. Load* "form/code",32000 - carga archivo tipo .BYT a la posición 32000. Load* "nombre" - carga cualquier archivo de tipo .PRG o .BYT (pantallas inclusive). Devuelve error si es un .DAT. Load* "" - es igual a Load* sin parámetro alguno. Merge* sintaxis: Merge* ["[drive:]nombre"] como Load*. Verify* sintaxis: Verify* ["[drive:][nombre]"] como Load*. Move* Admite wildcards. Sintaxis: Move* "[drive1:]nombre origen" To "[drive2:][nombre destino]" Permite copiar cualquier tipo de archivo. Ejemplos: Move *"amigo.bas" To "amici.bas" - copia el archivo en la misma unidad y con otro nombre. Move *"prb.dat" To "b:" - copia el archivo de la unidad en curso A pasándolo a B. Move *"a:*" To "b:" - copia todos los archivos de A a B. Erase* Admite wildcards. sintaxis: Erase* "[drive:]nombre" Ejemplos: Erase* "a:prg.bas" Erase* "Alf*" - borra todos los archivos que cumplan la condición especificada. New* sintaxis: New [*/#] New - cumple su función habitual, pero también resetea tanto al Spectrum como al WOS. New* - debe usarse tras cada NEW, inicializa el WOS para su uso. Estando el WOS activo, New* devuelve error. New# - limpia la zona del Basic sin afectar al WOS. Nota: Estas instrucciones New no pueden ser usadas dentro de programas Basic, solamente como comandos directos. Open#* Trabaja solamente con ficheros secuenciales, en el Wafadrive es el único modo de salvar datos, pues no existe Save... Data. Sintaxis_1: Open# ;"letra" Letra solamente puede ser: "k","s" o "p". Es el modo por defecto del Basic Sinclair sin extensiones. sintaxis_2: Open#* ;"letra" Letra solo puede ser un puerto: "r" o "c". Permite enviar hacia la impresora por un puerto mediante un canal. sintaxis_3: Open# *;"[drive:]nombre" Permite usar ficheros para almacenar cadenas y datos numéricos. El canal debe ser un número del 0 al 15 El nombre puede ser cualquier expresión de cadena, también una sola letra (incluso k, s ó p) pero no: "R","r" - interfase serial RS-232 "C","c" - interfase paralelo Centronics Nota: "r" y "c" solo pueden ser usados por Open#*, no son reconocidos por la sintaxis básica Open #. Ejemplos: Open#* 4,"file1" - si el fichero existe se abre para solo lectura. Permite el uso de Input# y Inkey$# . Open#* 4,"b:alfa" - crea el fichero "alfa" en B sino existiera y pasa a modo de escritura. Permite el uso de Print#. List#, Llist# y Lprint# también son admitidos. Nota: No hay modo "append" (añadir). Si se abre un fichero existente para tratar de añadir más datos, se obtendrá un error. Es decir que una vez cerrado un fichero de escritura, este solo puede ser leído pero ya no más reescrito. Si se desea sobreescribir el fichero, habrá que eliminarlo antes con Erase* y volver a crearlo con Open#*. Close#* Sintaxis: Close# [*] Cierra solamente el canal abierto especificado. Close#* es preferible a Close#. Print# Sintaxis: Print #; char$' num'... Admite el uso de separadores como Chr$13 ó "'" por cada elemento a salvar. Ejemplos: Print #2;""Hello"" - salva el dato entre comillas. Print #1; a$+Chr$ 13+b$ - salva dos datos que podrán leerse individualmente. Print #3; a$'b$'valor - salva tres valores para leerlos individualmente. Print #4; n$;b$+p$;c$ - salvará todo como una sola línea y será leída como tal. Input# Sintaxis: Input #; [Line ]var$; num;... Solo admite ";" como separador de variables de lectura de datos. Ejemplos: Input #1; a$;b$;valor Input# 2; Line v$ Clear* Cierra todos los canales y ficheros de datos que estén abiertos, y "resetea" los canales de 0 a 3. Clear* puede ser usado incluso en lugar de Close#*. Cls* Borra la pantalla y resetea todos los atributos definidos por Border, Paper, Ink, Bright, Inverse, Flash y Over. Break No es una sentencia, es el habitual "Break/Space" usado como comando directo. Cualquier operación del Wafadrive puede ser cancelada con Break, menos la carga de archivos protegidos. Algunas operaciones requieren que Break se mantenga pulsada hasta que haya mensaje de cancelación. Notas: Es posible imprimir el contenido de un directorio mediante: 10 OPEN #*4,"c" 20 PRINT #4; 30 CAT *"a: " 40 CLOSE #*4 El interfase serial puede ser usado no solo para conectar la impresora, sino también para terminales y modems. En el caso de recibir información por este medio es más aconsejable usar: 10 FORMAT *"r";2400 (o el valor más adecuado) 20 OPEN #*4,"r" 30 PRINT INKEY$ #4; 40 GO TO 30 El directorio de cada drive se almacena en la RAM, ocupando cada uno 582 bytes, a partir del área 23734. Para leer el contenido, basta una rutina Basic como la siguiente: 9600 REM rutina para leer el Directorio 9610 DIM w(4): DIM s(32): DIM d$(32,14) 9620 GO SUB 9900 9630 LET w$=a$: LET a=a+13 9640 FOR n=1 TO 4: LET w(n)=PEEK a: LET a=a+1: NEXT n 9650 LET a=a+21 9660 FOR e=1TO 32 9670 GO SUB 9800 9700 IF CODE a$=0 THEN RETURN 9710 LET d$(e)=a$ 9720 NEXT e 9730 RETURN 9800 REM tomando la entrada 9810 GO SUB 9900 9820 LET c=PEEK a-4*INT ((PEEK a)/4) 9830 IF c=0 THEN LET a$=a$+".PRG" 9840 IF c=1 THEN LET a$=a$+".BYT" 9850 IF c=2 THEN LET a$=a$+".DAT" 9860 LET a=a+1: LET z=PEEK a: LET s(e)=z 9870 FOR n=1 TO z+1: LET a=a+1: NEXT n 9880 RETURN 9900 REM tomando el nombre 9910 LET a$="" 9920 FOR n=1 TO 10 9930 LET a$=a$+CHR$(PEEK a): LET a=a+1 9940 NEXT n 9950 RETURN La variable a=24862 para el directorio A y a=25444 para el directorio B. Usar CAT # antes para cargar los directorios. La cadena a$ contiene el nombre del wafer (WAFER_NAME). La matriz w() contiene información sobre el wafer del modo siguiente: w(1) = La capacidad máxima del wafer (WAFERSIZE) w(2) = Número de sectores buenos en el wafer (GOOD_SECT) w(3) = Número de sectores que quedan disponibles (FREE_SECT) w(4) = Número de archivos almacenados (FILES) La matriz s() contiene las dimensiones de archivos individuales y la matriz d$(), los nombres. Para ver lo antes expuesto añadir: 10 REM muestra directorio 20 LET a=24862 30 INPUT "Unidad A o B?", LINE a$ 40 IF a$="B" OR a$="b" THEN LET a=25444 50 GO SUB 9600 100 PRINT "Nombre del Wafer:",w$ 110 PRINT "'Tamaño:";w(2);"K disponible: ";w(3);"'K 120 PRINT "Archivos:";w(4): PRINT 130 FOR e=1 TO w(4) 140 PRINT d$(e);": ";s(e);"K" 150 NEXT e 160 STOP Mensajes de error: El Wafadrive añade nuevos mensajes de error al Spectrum, algunos de los cuales están aquí listados. Algunos reportes no se dan normalmente cuando se opera desde el BASIC, pero algunos programas especiales pueden usarlos. El código del error está entre paréntesis, de hecho estos números nunca se visualizan en pantalla. Directory full (22) Se ha llegado al número máximo de archivos posibles en el wafer que es de 32. Directory locked (24) Se intentó acceder al wafer estando un archivo aun abierto. Cerrar todos los archivos antes de salvar, borrar, etc. Drive write-protected (8) Se intentó salvar, borrar o copiar en un wafer con el tab de protección puesto. Faulty Wafer (15) Hubo cuatro intentos inexitosos de cargar un archivo, o falló la verificación de un número significativo de sectores durante el formateado. File exists (18) Se intentó salvar un programa y el nombre ya existía en el directorio. Basta usar SAVE# en vez de SAVE* para evitar este mensaje. File opened for write (16) Este error no se obtiene normalmente. File name missing (4) No se obtiene normalmente. File not found (11) El archivo solicitado no aparece en el directorio del wafer. File read only (23) Se intentó copiar un archivo protegido. File write-protected (21) Se intentó borrar o sobregrabar un archivo protegido. Invalid Baud rate (17) El valor especificado en el comando FORMAT para el RS232 no es ninguno de los 9 disponibles. Invalid drive (3) Se usó una letra de unidad que no es "A:", "a:", "B:" o "b:". Sucede tambien si se trata de copiar muchos archivos en el mismo wafer. Invalid hook code (19) No se obtiene normalmente. Invalid name (2) Nombre de archivo no válido. Más de dies caracteres, por ejemplo. O si se quiere copiar un archivo en el mismo wafer sin renombrarlo. Invalid stream number (1) Número de canal fuera del rango permitido entre 0 y 15. Merging error (12) El comando MERGE no tuvo exito en su ejecución. Nonsense in BASIC (0) El contenido de una cadena no era una expresión válida del Basic extendido. Out of range (20) Argumento de funcción fuera del rango permitido. Program finished (255) No había programa en memoria al hacer RUN, o hubo RUN, GOTO, GOSUB con números que excedieron el último número de líneas del programa. Reading from a write file (7) INPUT o INKEY$ han sido usados en conjunto con un fichero abierto solo para escritura. Stream already opened (5) El canal elegido para un OPEN# ya estaba abierto. Los canales deben ser cerrados antes de su reasignación. Verification failed (13) El comando VERIFY no halló equivalencia entre el programa en memoria y el salvado en el wafer. Wafer full (9) Espacio insuficiente en el wafer para guardar el archivo especificado. Wafer not inserted (10) No hay wafer presente en el drive especificado. Writing to a read file (6) Se ha usado PRINT, LIST, o un INPUT con separadores no válidos, para manejar ficheros de solo lectura. Wrong file type (14) Se ha intentado cargar un archivo .DAT, mezclar un archivo .BYT o .DAT, abrir con Open# un archivo .BAS, etc...