Opus Discovery 1 Manual del sistema operativo Discovery (Opus Dos). Sintaxis: comando #flujo,"canal",drive,"nombre" Comandos: Format, Cat, Load*, Save*, Merge*, Verify*, Move, Erase, Open#, Close#, Run, Lprint, Llist, Clear#, Cls#, Point#, Usr. Drives: Los drives admitidos por defecto son 1 y 2. Para usos de copiado admite 3 y 4(*). El disco Ram es 5(**). El número de drive puede ser un número, una variable numérica o alfanumérica con Val. (*) según el manual original el drive 4 no fue implementado en aquel entonces. (**) el drive 6 permitía acceder al disco Ram propio del 128k y solo con esta máquina. Nota: Se llama Discovery 1 al sistema con una sola unidad, el Opus con dos unidades era el Discovery 2. Para convertir un Discovery 1 en 2 había que comprar entonces un pack de expansión llamado Discovery +. Nombre: El nombre es de hasta 10 caracteres. EL DOS diferencia los nombres con mayúsculas de aquellos en minúsculas. Por ejemplo: "QUOTE" es distinto de "quote" y "QuotE" o "qUOTe". No existen extensiones ni atributos, pero añadiendo Chr$ 0 al comienzo del nombre, el archivo queda oculto. Así ya no aparecerá al hacer CAT, el único dilema es que si uno olvida el nombre ya no podrá cargarlo otra vez. Para ver los archivos escondidos es forsozo tener una utilidad que los muestre. Flujos: El Spectrum envía datos desde una fuente a un destino por medio de flujos, los cuales están numerados del 0 15. En un Spectrum sin expandir solo hay 4 flujos (0-3) con sus respectivos canales (k,s,p) en uso. Canales: Todos los datos son manejados por el Discovery 1 mediante los siguientes dispositivos o canales: "b" - entrada / salida al puerto paralelo, los caracteres son enviados y recibidos como 8 bits sin modificación. "CAT" - este canal da acceso al archivo del catalogo del disco. La especificación completa del canal es "CAT";. "CODE" - este canal escribe o lee directamente en la memoria. "d" - trata al disco como un todo y es usado por la instrucción MOVE. Su especificación plena es "d";. "j" - activa / desactiva el puerto del joystick y es usado solo por el comando FORMAT. "K" - lee el teclado y envía a la parte baja de la pantalla. "m" - para archivos de disco. "P" - la impresora. "S" - la parte alta de la pantalla. "t" - entrada / salida al puerto paralelo. Su especificación plena es "t", estado. "#" - este canal de flujo permite abrir un flujo hacia otro. La especificación plena es "#"; ó # . K, t, y b son considerados canales lentos. Las letras de canales pueden ser tanto minúsculas como mayúsculas. Nota: "CAT" y "CODE" son las palabras reservadas, no pueden escribirse letra a letra. Format sintaxis completa: FORMAT ["m";];"volumen" donde: ["m";] es opcional y sirve para mantener la compatibilidad con el IF1 microdrive. "m" es de hecho el canal por defecto. drive es el número de la unidad elegida: 1 o 2. volumen es el nombre que se le dará al disco. Ejemplo: Format 1, "sd1" Format avisa cuando se pone un disco que ya ha sido formateado antes y pregunta si se quiere proseguir o no con la acción de formateado. Nota: Opusdos formatea a 178k en 40 tracks, para formatear a 380k, 720k o 860k es necesario usar rutinas especiales de formateo. Disco RAM: Para crear un disco Ram reservar primero una zona de RAM con Clear y usar entonces Format. Clear 32767: Format 5;"Ram-disc". Es más rápido para cualquier operación, pero su uso reduce la memoria disponible. El disco Ram siempre desaparece con New o al reiniciar la máquina, así que hay que crearlo cada vez que se quiera usar. Nota: En el 128k, basta hacer: Format 6;"ramd6" sin un Clear previo. Joystick: el Discovery 1 tiene una interfase de joystick incorporada, basta iniciarla con Format para usarla en un programa basic. Format "j", donde: "J","j" - es el canal del joystick kempston compatible. es el estado del joystick. n = 1 activa el puerto de joystick para su uso. n = 0 desactiva el uso del joystick. El joystick una vez accesible puede ser leído solo con la función IN 31. Nota: también es posible abrirlo con Open# y leerlo con Inkey$#. Cat sintaxis: Cat [#flujo;] Muestra el contenido del disco en el drive n (un número del 1 al 4 o 5 si se crea el disco RAM). La lista generada por Cat, no está en orden alfabético. Cat requiere que se le de un número de drive, de lo contrario da mensaje de error. Cat puede enviar la información mediante un flujo dado previamente abierto con Open#. Cat #3;1 envía la información de Cat a la impresora en vez de a la pantalla. Cat 3 solicita inserción de disco y opera igual que Cat 1. Cat 4 hace lo mismo pero con la unidad 2 si esta estuviese habilitada de lo contrario dará mensaje de error. Cat [#flujo;]"m", actúa igual que Cat (*). (*) Esta última variante es la única aceptada por el Betabasic estandar. Cualquier otra letra distinta de "m" devuelve error. Nota: Hay una variante extraña no mencionada en el manual y aparentemente sin utilidad alguna y es: Cat 1,"". Esta curiosa variante solo admite una cadena vacía, de lo contrario devuelve error. Save* Sintaxis: Save *<;/,>"nombre" [Line/Code/Data/Screen$] También admite la sintaxis del IF1 microdrive: Save *"m",número,"nombre"... Ejemplos: Save *1,"nombre" Code x,y Save *2;"datos" Data a$() Save *Val x$,"prob" Line 2 Save *1,Chr$ 0+"nombre" - salva archivo escondido A diferencia del microdrive, si el nombre ya existe, Opus simplemente lo reemplaza o regraba sin dar reportes u error. De hecho, el Opus DOS nunca pregunta tampoco si se quiere sobre escribir o no el archivo a salvar. Nota: La desventaja es que si hay un archivo distinto, este desaparecerá si se usara erroneamente su nombre en un nuevo Save. Load* sintaxis: Load *["m",]<;/,>"nombre" [Code/Data/Screen$] Ejemplos: Load *1,"beta" Load *1,Chr$ 0+"nombre" - carga archivo escondido Load *Val x$,a$ Screen$ Load *2,"bytes"Code x,y. Tanto x como y son opcionales pero de usarse deben ser los valores correctos sino dará error. Merge* sintaxis: Merge *["m",]<;/,>"nombre" Solo permite cargar y mezclar archivos de programas Basic. A diferencia del IF1 microdrive permite mezclar archivos Basic salvados con "Save ... Line". Verify* sintaxis: Verify *["m",]<,/;>"nombre"[Data/Screen$/Code[num1[,num2]] Da OK si la verificación es correcta o un mensaje en caso de que no lo sea, o si el nombre no existe en el directorio. Move (Disc Copy) Permite la copia de discos previamente formateados. sintaxis: MOVE "d"; TO "d"; donde: "D","d" = el canal del disco como un todo. drive_1 = la unidad fuente a ser copiada. drive_2 = la unidad destino ejemplos: MOVE "d"';1 TO "d";3 - es la única forma de copiar discos con una sola unidad. Move pide cambiar el disco fuente por el destino en el mismo drive y procede entonces a hacer el copiado. MOVE "d"';1 TO "d";2 - si hay dos drives, copia discos directamente de una unidad a otra. Move (Compacting Disc) Permite reagrupar y usar todos los espacios intermedios que se generan al crear, copiar, anular o modificar archivos y que con el tiempo llenan innecesariamente el disco impidiendo añadir nuevos datos. sintaxis: MOVE "d"; TO "d"; donde: disco = ha de ser el mismo valor, ya que no se trata de pasar datos de una fuente a un destino. Ejemplo: MOVE "d";1 TO "d";1 compacta disco en la unidad 1. Nota: Se recomienda hacer copias del disco antes de compactarlo, pues un cuelgue del Spectrum o la falla de energía intempestiva hará que los datos se pierdan irremediablemente. Move (channels) Transfiere los datos de un canal a otro. Sintaxis: Move to donde: can_1 = el canal fuente o de lectura can_2 = el canal de destino o de escritura Ejemplos: MOVE "K" TO "S" - envía directamente lo que uno teclea directamente a la pantalla. MOVE "K" TO "K" - hace lo mismo pero hacia la parte inferior de la pantalla. Para salir de este modo, pulsar CAPS S. + ENTER. Move (Open# type files) Lee datos de un archivo del tipo Open#, un sector a la vez y los transfiere ya sea por un canal o a otro archivo. sintaxis: Move ["m",],"file-name" TO "" Ejemplos: MOVE "m";1;"telephone" TO "S" - muestra en pantalla el contenido del fichero "telephone" MOVE 1;"teleph" TO "t" - envía a la impresora todo cuanto contenga el fichero "teleph" Move (File Copy) El comando MOVE permite copiar cualquier clase de archivo, ya sea programas Basic, CODE, DATA, SCREEN$ o ficheros. sintaxis: Move ["m",],"nomb_f" TO ["m",],"nomb_d" Ejemplos: MOVE "m";1;"telephone" TO "m";2;"telephone" - copia fichero en disco 1 al disco 2. MOVE "m",1,"tel1" TO "m",3,"tel1" - copia archivo en otro disco dsitinto usando una sola unidad. MOVE 2;"tel_1" TO 2;"tel_2" - crea una copia en el mismo disco dándole un nombre distinto al de la fuente. Move (file's position on the disc) Permite cambiar la posición de un archivo en el disco. sintaxis: MOVE ["m";]disco;"file" TO ["m";]disco;"file" donde: disco = el mismo valor pues no se trata de ningun copiado de datos. file = el mismo nombre de archivo a mover. Es muy util en casos de que se obtenga error por espacio insuficiente al querer "EXPandir" un fichero existente. Ejemplo: MOVE "m";1;"ficha1" TO "m";1;"ficha1" Erase sintaxis: Erase ["m",]<,/;>"nombre" ["m";] es opcional y sirve para mantener la compatibilidad con el IF1 microdrive. Remueve cualquier tipo de archivo del directorio y deja su espacio disponible para su futuro uso. A diferencia de Save*, Load*, Merge* o Verify*, Erase no necesita especificadores como [Line/Code/Data/Screen$]. Ejemplo: Erase 1;"prg", Erase 2,a$ Da mensaje de error en caso de que el archivo a borrar no exista en disco. Nota: El uso de "m" en Erase, no da mensaje de error si el archivo no fuese hallado. Open# Open# flujo,"canal" Permite asociar un canal a cualquier flujo diferente del que usa por defecto. Ejemplos: Open #4,"s". Open #5, "t" Open# flujo,"canal" [In / Out] Asocia un canal a un flujo especificado y lo fija ya sea para solo lectura (In) o solo escritura (Out). Los canales dispositivos están asociados de la siguiente forma: "K","k" - IN y OUT "S","s" - OUT "P","p" - OUT "B","b" - IN y OUT "CAT" - IN "CODE" - IN y OUT "T","t" - IN y OUT "#" - IN y OUT "M","m" - es el canal por defecto y es omitible en su mayoría de casos. Ejemplos: OPEN # 7;"b" IN - abre el canal "b" usando flujo 7 para solo lectura. OPEN # 4;"#";1 - asocia la corriente 4 con el flujo 1 Open# flujo,["m",]número,"nombre" [In / Out / Exp] Permite manejar ficheros secuenciales. donde: flujo = un número de 4 a 15 número = un valor de 1 a 5 In = especifica que el archivo se abre secuencialmente para solo lectura. Out = especifica un archivo de solo escritura. Este es creado si no existiese. Exp = abre archivo ya creado y permite añadir más datos a partir del último dato ingresado. En caso de omitirse In y Out, entonces Open obrará por defecto igual que el Open# del IF1. Open devuelve una cadena nula ("") como fin de fichero (EOF) Ejemplos: Open# 4,"m",1,"file1" In - Abre el fichero existente "file1" para solo lectura. Open# 4,x,"alfa" Out - Crea el archivo "alfa" de no existir y pasa a modo de escritura (*). Open# 5;"m";2;"ficha5" Exp - Abre fichero "ficha5" en drive 2 para añadir más datos (**). (*) De existir el archivo todos los datos se perderían, pues Out "resetearía" dicho fichero. (**) A diferencia de Out, Exp no crea ficheros, solo los abre. De no existir el fichero, Exp dará error de lectura. Open# flujo,["m",]número,"nombre" [long] donde: long = marca la longitud máxima del archivo a crear o a expandir. Si se omite, adopta su valor por defecto: -1 Ejemplos: OPEN # 6;"m";1;"Carol" OUT 1000 - crea o reinicia un fichero limitándolo a un máximo de mil caracteres (bytes) OPEN # 11;2;"Laurie" EXP 256 - abre el archivo y lo fija para que no puedan añadírsele más de 256 caracteres. Si no hubiera suficiente espacio en el disco para Exp, se generaría un error por espacio insuficiente. Al omitirse la longitud máxima, o poner -1, Exp incrementará al doble o lo que permita el espacio disponible en disco. OPEN# flujo;["m";]número;"nombre" RND long[,reg] donde: Rnd = permite crear, abrir y leer ficheros de acceso directo o aleatorio. long = la longitud de caracteres por registro en el fichero. reg = fija el número máximo de registros para el fichero. Es necesario fijar el número de registros cuando se crea el fichero, pero no para leer o escribir en él después. reg = -1 crea ficheros directos usando la mitad del mayor espacio disponible en el disco para el máximo de registros. Ejemplos: OPEN # 10;"m";1;"Paul" RND 20,10 (*) Crea un fichero de acceso directo de nombre "Paul", con solo 10 registros y 20 caracteres máximo por registro. OPEN # 8;1;"Dave" RND 128 permite abrir el fichero directo ya existente para su lectura / escritura fijando el máximo de datos a 128. (*) si se volviera a usar esta opción nuevamente, todos los datos desaparecerían pues el fichero sería "reseteado". OPEN # ;"t";[estado] [RND anchura] En este caso, Rnd asociado a "t" permite elegir el número de caracteres a imprimir por línea a 80. El valor por defecto es 0. No puede ser usado para entrada (IN) solo para salida (OUT). Ejemplo: OPEN # 4;"t";0 RND 80 Para leer (input) el bit alto está a cero, dando los códigos entre 0 y 127. Para salida (output) los codigos menores de 32 son ignorados excepto CR o el par CR/LF). Los códigos mayores de 127 son expandidos si son tokens Basic, e impresos como "?" si son caracteres gráficos. Si el estado es 0 entonces se envía un par CR/LF. si es 2 solo se envía un CR. Si está a 1 entopnces se emula la impresora ZX. Si el estado se omite entonces se toma su valor por defecto que es 0. OPEN # ;"CAT" [RND /EXP ] donde: long ha de ser siempre un múltiplo de 16 bytes. El catálogo es de 110 nombres por directorio. Puede haber aun espacio en disco pero no para crear más archivos. Es posible incrementar entonces el directorio accediendo al archivo del catálogo mediante el canal "CAT". Ejemplo: OPEN # 4;"CAT" - permite leer las diversas entradas que son de 16 bytes por fichero, más tres punteros y el nombre. OPEN # 4;"CAT" EXP x: Clear #4 - permite crear más sitio para más nombres de archivos a salvar o crear. OPEN # 4;"CAT" RND 16 - permite usar Point# para leer y escribir los contenidos del catálogo. Nota: Es aconsejable trabajar con una copia del catálogo en caso de manipularlo, pues un error dañaría el disco irreparablemente. OPEN # ;"CODE" [RND] Mediante Point# puede accederse a las posiciones de memoria que uno desea leer o escribir. Permite leer la ROM sombra y acceder así al hardware del sistema de disco. Open# permite el uso de: Input# n;([Line] a$/var.;...[#n;...]) para leer datos numéricos y alfanuméricos. Inkey$# para leer datos alfanuméricos caracter a caracter o incluso bytes como caracteres ascii. Print# n;(a$/var.;...'...,....) para la escritura de los datos. Permite usar los separadores entre datos: , ; ' List# n[,linea] también puede ser usado en un Open#/close#. Tanto Print # como Input # permiten usar más de un flujo en la misma línea. Ejemplos: INPUT #5;A; #7;b$;c - lee datos por las corrientes 5 y 7 a la vez. PRINT #5;"SPECTRUM"; #8;"disc"' #2;"system" En caso de ficheros aleatorios, la variable alfanumérica a salvar debe ser dimensionada antes. El valor de DIM debe ser siempre menor al dado en RND. Por ejemplo, si "Open ... Rnd x,y" entonces Dim ... (x-1). Todos los valores numéricos deben ser convertidos previamente a cadena. Point# sintaxis: Point #, Permite leer o escribir en ficheros de acceso directo mediante un puntero de número de registro. Ejemplo: POINT # 4;13 - fija el puntero en el registro #13 del fichero por medio de la corriente #4. Close# Sintaxis: Close# Close# cierra solamente el flujo especificado con su canal correspondiente si está abierto y permite su uso futuro. Es muy importante cerrar los archivos abiertos, de lo contrario, los datos se perderían. Nota: Puede usarse con los flujos 0 - 3, los cierra, pero estos se reabren automaticamente hacia sus canales por defecto. Clear# sintaxis: Clear# [] Clear# sin parametro alguno, cierra los flujos abiertos y los deja disponibles para su futuro uso. Clear # hace lo mismo pero solo con el flujo especificado. Cls# Borra la pantalla y resetea todos los atributos definidos por Border, Paper, Ink, Bright, Inverse, Flash y Over. Run Ejecuta archivo de Autoload llamado "run", solo si este existiese en el disco y hubiese sido creado con "Save... Line". Llist Llist manda los listados a la impresora que haya sido previamente conectada a la interface usando el flujo #3. La impresora por defecto es la ZX (canal "p"). Para usar una impresora conectada al Discovery usar: Open #3,"t": Llist. Si se desea puede cerrarse el canal con Close #3. Lprint Sintaxis: Lprint [#],<"datos"> Imprime "datos" por la impresora o a cualquier otro dispositivo a traves de un flujo. Lprint siempre usará el flujo #3 por defecto. TAB n; y AT n,n: <"datos"> también son admitidos por Lprint. Al igual que Llist, Lprint también está asociado al canal "p" por defecto. Open #3,"t": Lprint "texto": Close #3 enviará el "texto" hacia la impresora conectada al Discovery. Conectando Spectrums con Opus. Es posible conectar dos Spectrum mediante el puerto paralelo del Discovery 1 y transferir datos por medio del canal "b". Ejemplo: MOVE "m";1;"sfile" TO "b" - envía el archivo "sfile" desde la fuente a través de "b" MOVE "b" TO "m";1;"rfile" - recibe los datos por "b" y los copia a archivo "rfile" como destino. Esto es lo más cercano a una conección en red con el Opus Discovery 1. Los demás comandos también son permitidos. Ejemplo: Paso 1: el receptor escribe LOAD *"b" y espera el envío Paso 2: el transmisor da SAVE *"b" Paso 3: el receptor puede tipear VERIFY *"b" para confirmar que los datos se enviaron correctamente Paso 4: entonces el transmisor vuelve a hacer un Save *"b" final. El programa está ya en la memoria del receptor y puede ser confirmado entonces por Verify. Este último método es mejor que Move, pues permite la verificación y no necesita que se le envíe un EOF por el teclado. Usr (rutinas útiles): USR 0 - se resetea el Spectrum, pero no el sistema de disco. USR 14070 - resetea el sistema de disco. USR 8 - devuelve el número de la versión del sistema operativo de disco. USR 432 - devuelve el número de bytes que quedan en el flujo en curso. Da -1 si el flujo tiene longitud desconocida. Para saber la longitud de un dato hacer: PRINT #4;: LET lenght= USR 432:PRINT lenght Para saber si se llegó al final de fichero, usar antes de Input#: 'PRINT #4;: IF USR 432 = 0 THEN ... "EOF"'. Ejemplo: 10 OPEN # 4,"m";1;"telephone" IN 100 PRINT #4; 110 IF USR 432=0 THEN CLOSE # 4:STOP 120 INPUT #4;n$;t$ 130 PRINT n$,t$ 140 GOTO 100 Nota: esta instrucción debe usarse solamente en modo lectura. Print #; - deja fijado el flujo elegido a diferencia de Inkey$ #. QuickDos: El Quickdos (sistema operativo de discos rápido) fue una modificación de la rom para el Opus D1. Mediante Format "q", (dónde número = 0 - 3) permitía dar un CAT de 3 columnas. Aparte eso, su fin principal era acelerar los procesos de carga y otros desempeños considerados lentos en el Opus estandar. También permitía leer discos formateados en 80 tracks a doble cara (normalmente Opus trabaja con 40 tracks simple cara). Print Usr 8 da 2.31 si está instalado el Quickdos. Excom: Otra mejora al Opusdos fue el EX-COM, que como su nombre indica, añadía comandos extras al Discovery. Subdirectorios: El Opusdos no fue diseñado originalmente pensando en el uso de subdirectorios. Pero con ciertas utilidades es posible crear particiones y darles nombres para manejarlos como autenticos subdirectorios. Mensajes de error: a- Invalid device name - identificador de canal incorrecto. Nombre de dispositivo no permitido. b- stream already open - el flujo o corriente especificado está actualmente en uso (abierto) c- invalid drive number - número de unidad incorrecto. Los valores admitidos son: 1, 2, 3, 4 o 5. e- write protected - el disco en uso está protegido contra escritura. f- disc full - el espacio en el disco es insuficiente (disco lleno). Hay que probar a compactar el disco. g- disc I/0 error - problemas al leer o escribir en el disco. Posibilidades: 1 - no hay disco alguno en la unidad, 2 - la unidad especificada no está conectada o... 3 - se corrompió la información que hay en el disco. h- file not found - el nombre de archivo dado no se encuentra en el disco dentro de la unidad especificada. i- hook code error - una rutina en código máquina usando códigos de enganche (hooks) del microdrive hook codes. Este mensaje (error en el codigo de enganche) nunca se obtiene desde el BASIC. j- file size error - error en el tamaño del fichero. Sucede si uno trata de verificar o escribir más allá del fin de fichero. Cuando un fichero es abierto, una longitud es siempre fijada aun si es solo la mitad del disco. l- verification failed - la verificación falló m- wrong file type - el archivo especificado en el comando no es del tipo correcto (tipo de archivo erroneo). - ram corrupt - la RAM se ha corrompido. Hay inconsistencia interna. Ejemplo: un canal contiene la longitud erronea. ?- no message - significa que no hay mensaje definido para el codigo de error que se está dando.