Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


Tema 10 - Manejo de ficheros, discos y cintas

Por simplicidad, comenzaremos suponiendo que manejamos un CPC 664 o un CPC 6128, equipados con una unidad de disco. Después comentaremos algunas diferencias en el manejo de cintas de cassette.

 

10.1 Guardando programas: SAVE

Hasta ahora sabíamos teclear programas y ponerlos en funcionamiento, pero como la memoria (RAM) de un CPC es volátil, cuando apagamos el ordenador, el programa se pierde. Si en un momento posterior queremos volver a utilizar el programa, deberíamos volver a teclearlo... a no ser que lo guardemos.

Guardar en disco el programa que tenemos en memoria es sencillo: usamos la orden SAVE, a continuación de la cual indicamos el nombre del programa entre comillas (un nombre de hasta 8 letras, sin espacios en blanco, y para el que tampoco se permite casi ningún símbolo de puntuación):

SAVE "PRUEBA01"

A este nombre se le añadirá automáticamente la extensión ".BAS" (por tratarse de un programa en Basic), de modo que el programa anterior aparecería en el disco como "PRUEBA01.BAS".

Dos opciones habituales de la orden SAVE nos permiten:

  • Proteger el programa, para que quien use nuestro disco no tenga fácil descubrir qué ordenes habíamos tecleado. Para eso se usa la opción P: SAVE "PRUEBA01", P
  • Guardar el programa como ASCII puro (texto puro, formado sólo por caracteres legibles), en vez de permitir que se "abrevie" a cambio de hacerlo menos legible para nosotros. Puede ser interesante si vamos a editar o imprimir nuestro fuente desde alguna otra utilidad u otro sistema operativo (como CP/M en un CPC "real" o Windows, Linux o cualquier otro si usamos un emulador dentro de un PC. La opción correspondiente es la A: SAVE "PRUEBA01", A

Y hay más: podemos crear ficheros "binarios", a partir de información contenida en cualquier punto de la memoria del CPC, pero eso todavía es demasiado avanzado para nosotros...

 

10.2 Cargando un programa: LOAD

De acuerdo, ya hemos guardado el programa. Apagamos el equipo y nos vamos a cenar. Al día siguiente pretendemos recuperar el trabajo que dejamos a medias...

Sin problema: la orden LOAD, y entre comillas le detallamos el nombre el programa:

LOAD "PRUEBA01"

 

10.3 El contenido de un disco: CAT

Sabemos cargar un programa... cuyo nombre recordemos. Pero eso no siempre ocurre. Si no sabemos seguro qué hay en un disco, no todo está perdido, la orden CAT, que nos muestra el nombre de cada fichero, junto con su tamaño (en Kilobytes). Se usa sin parámetros:

CAT

 

10.4 Guardando datos desde un programa: OPENOUT, WRITE, CLOSEOUT

Si lo que queremos guardar con datos que esté manipulando nuestro programa, deberemos abrir un fichero para escritura. Esto lo hace la orden "OPENOUT", a la que le indicamos el nombre del fichero

OPENOUT "agenda.dat"

Para guardar datos, podemos usar la misma orden PRINT que usaríamos para mostrarlos en pantalla, con una pequeña diferencia: debemos añadir #9 después de PRINT, para indicar al CPC que queremos mandarlo hacia un lugar especial, hacia un cierto "canal". Existen varios de estos canales. Por ahora sólo nos interesa el canal 9, que es el que se utilizar para enviar a un fichero (o leer de él). Un poco más adelante hablaremos de algún otro...

PRINT #9, "Hola"

Otra alternativa es usar la orden WRITE, que escribirá las cadenas entre comillas, y si indicamos varios datos, los separará por comas, algo que puede resultar muy cómodo para leer después esos datos desde el disco:

WRITE #9, nombre$, direccion$

Cuando terminemos de guardar datos, deberemos cerrar el fichero con CLOSEOUT:

CLOSEOUT

 

10.5 Los números de canal. La impresora.

El canal 9 no es el único. Otros dos son especialmente importantes:

  • El canal 0 se refiere a la pantalla, pero la mayoría de las veces no será necesario indicarlo: PRINT #0, "Hola" es lo mismo que PRINT "Hola" (aun así, ya veremos que en algún caso sí hara falta utilizar ese #0.
  • El canal 8 es el de impresora. Así, PRINT #8, "Hola" escribe la palabra Hola en impresora, y LIST #8 envía el listado del programa a impresora. Podemos ajustar la anchura de cada línea que se muestre en impresora con la orden WIDTH: WIDTH 80

¿Qué pasa con los canales con números entre el 1 y el 7? Es cierto, existen otros números de canal intermedios... pero los usaremos más adelante... cuando hablemos de las ventanas en modo de texto.

 

10.6 Cargando datos guardados previamente: OPENIN, CLOSEIN

Cargar datos es sencillo: abriremos un fichero para lectura con OPENIN, leemos datos con INPUT #9, y cerramos con CLOSEIN.

OPENIN "agenda.dat"
INPUT #9, nombre$
CLOSEIN

 

10.7 Un primer ejemplo casi completo

Vamos a ver lo que sería la estructura básica para una agenda: Reservaremos espacio para varios datos (sólo 5, por abreviar), pediremos los valores al usuario, los guardaremos en un fichero, los borraremos, los volveremos a leer desde fichero y los mostraremos en pantalla (en orden contrario, por marear un poco...):

10 dim nombre$(5), direccion$(5)
20 ' Primero pedimos datos
30 for i = 1 to 5
40   print "Dime el nombre ";i;": ";
50   input nombre$(i)
60   print "Dime su direccion: ";
70   input direccion$(i)
80 next i
90 ' Ahora guardamos los datos
100 openout "agenda.dat"
110 for i = 1 to 5
120   write #9,nombre$(i)
130   write #9,direccion$(i)
140 next i
150 closeout
160 ' Vaciamos los datos
170 for i = 1 to 5
180   nombre$(i) = ""
190   direccion$(i) = ""
200 next i
210 ' Volvemos a leer los datos
220 openin "agenda.dat"
230 for i = 1 to 5
240   input #9,nombre$(i)
250   input #9,direccion$(i)
260 next i
270 closein
280 ' Y los escribimos al reves
290 for i = 5 to 1 step -1
300   print nombre$(i); ": ";
310   print direccion$(i)
320 next i

 

10.8 Cargando datos guardados (2): LINE INPUT, EOF

Es muy frecuente que leamos de un fichero en el que no sabemos cuántos datos hay guardados, y nos interese procesarlo "hasta que se acabe", todo entero. Para eso tenemos "EOF", que es "verdadero" cuando el fichero se ha terminado (End Of File). Así, la forma habitual de analizar todo un fichero es:

WHILE NOT EOF
  ...
WEND

Por otra parte, LINE INPUT es similar a INPUT, pero lee toda una línea de golpe (mientras que INPUT puede "desglosarla" en varias partes) y la guarda en una variable de cadena:

LINE INPUT #9, linea$

10.9 ¿Y en cinta? TAPE

Si utilizamos un CPC4xx, sin unidad de disco, las órdenes anteriores funcionarán casi sin cambios, pero la información se guardará en cinta.

Si utilizamos un CPC6xxx, con unidad de disco, aun así podemos conectarle un lector/grabador de cintas de cassette externo. En ese caso, podremos elegir si queremos guardar datos y leerlos de cinta o de disco.

Por ejemplo:

Si tecleamos |TAPE pasamos a guardar y leer desde cinta, en vez de utilizar el disco.

Si usamos |DISC volvemos a guardar y leer desde disco.

Pero podemos afinar más: podemos emplear |DISC.OUT para guardar en disco y |TAPE.IN para leer desde cinta (es una forma de hacer copia de seguridad en disco de programas sencillos que tengamos en cinta).

De forma similar, usaríamos |DISC.IN y |TAPE.OUT para leer de disco y guardar en cinta.

10.10 Otras órdenes de AMSDOS

Estas órdenes que comienzan por una barra vertical son "órdenes externas", no se trata de órdenes originales del Locomotive Basic, sino de órdenes adicionales, creadas por alguna utilidad.

En nuestro caso, se trata de órdenes extendidas para manejo de disco, creadas por AmsDos (el sistema operativo de disco incluido en los CPC664 y CPC6128). Pero además de TAPE y DISC, tenemos alguna otra que puede ser útil:

  • En un sistema con dos unidades de disco, |A indica que queremos utilizar la primera unidad de disco, y |B indica que ahora queremos trabajar con la segunda.
  • |ERA borra un fichero de disco (es la abreviatura de ERASE). El formato habitual en los CPC6xxx es indicar el nombre de fichero entre comillas y precedido por una coma: |ERA, "ejemplo.txt". En los 464 con unidad de disco externa, era ligeramente más complejo, había que hacerlo en dos pasos, usando una variable auxiliar: a$="*.BAS" : |DIR,@a$
  • |REN cambia el nombre de un fichero (RENAME). El formato es parecido al de ERA: |REN, "antes.txt", "despues.txt"
  • |USER permite cambiar el usuario activo: existen 16 "áreas de usuario" disponibles en el disco. La habitual (si no indicamos otra cosa) es la 0. Tecleando |USER,1 pasamos a otra zona de disco distinta, de forma que al hacer CAT sólo veremos nuestros ficheros. Se puede mover ficheros de un área de usuario a otra con REN si indicamos las áreas de usuario al principio del nombre del fichero: |REN, "0:inicial.txt", "1:final.text"
  • |DIR es menos útil porque hace casi lo mismo que CAT: muestra la lista de ficheros, pero en un formato ligeramente distinto (al estilo usado por CP/M). Además, permite listar sólo los ficheros que contengan ciertas letras. Por ejemplo, se podría buscar los ficheros TXT con |DIR, "*.TXT"
  • |CPM lee el sistema operativo desde el disco. Es la forma habitual de entrar al sistema operativo CP/M que se incluía como extra en los CPC equipados con unidad de disco, pero también era una forma de cargar ciertos juegos.

 

10.11 Ejercicio propuesto

Crear una agenda que guarde nombre, dirección, teléfono y e-mail de hasta 50 personas. Debe permitir añadir datos, modificarlos y borrarlos.

10.12 Guardar el contenido de la pantalla

Cuando hemos creado una imagen en la pantalla de nuestro CPC, podemos guardar lo que se ve en pantalla gráfica, y luego volverlo a cargar, como ocurre habitualmente con la pantalla de presentación de los juegos.

Para guardarla, debemos usar la orden SAVE, pero en modo binario (opción B), comenzando en la dirección de memoria 49152 (&C000 en hexadecimal) y con una longitud de 16 K (&4000 en hexadecimal):

SAVE "pantalla.bin",b,&C000,&4000

Para cargarla, basta con usar la orden LOAD, y se leerá directamente en la posición de memoria de la que se grabó:

LOAD "pantalla.bin"

Un ejemplo completo, basado en uno de los fuentes del tema 5 (el del apartado 5.2), podría ser así: (asegúrate de tener introducido un disco -o una imagen de disco si usas un emulador- que no esté protegido y que tenga libres al menos 17 K)

10 MODE 1 
20 FOR i = 1 TO 640 STEP 2
30   MOVE 0,0: DRAW i,400,1,1
40 NEXT
50 FOR i = 1 TO 400 STEP 2
60   MOVE 0,0: DRAW 640,i,1,1
70 NEXT
80 SAVE "pantalla.bin",b,&C000,&4000
90 CLS
100 PRINT "Pulsa una tecla para cargar la pantalla..."
110 WHILE INKEY$="": WEND
120 LOAD "pantalla.bin"

En este ejemplo, se tarda cerca de 45 segundos en dibujar la imagen en pantalla, pero apenas 3 segundos en leerla de disco.