Capítulo 8. Más sobre el gestor de bancos de memoria

Parte 2: Ficheros en RAM

Contenido:


Ficheros en RAM

Considerado como "RAMdisc", el segundo banco de 64K de RAM se puede organizar en forma de fichero, con cierto número de registros de longitud fija. La longitud de registro puede ser de entre 0 y 255 bytes, si bien 2 bytes es el mínimo recomendable. Una vez establecida la "longitud de registro", cada registro es accesible para operaciones de escritura y lectura por su "número de registro". Es perfectamente posible escribir en un fichero de RAM con una longitud y luego leer con otra distinta.

Nota. El fichero de RAM sólo puede contener datos; no está prevista su utilización para almacenar instrucciones de programa.

Al igual que en los sistemas de ficheros de acceso aleatorio en disco, aquí existe también el concepto de "número de registro actual". Este número se mantiene siempre actualizado, y es útil, por consiguiente, cuando se recorre el fichero avanzando automáticamente de cada registro al siguiente. La orden

|BANKOPEN,<longitud de registro>

establece la longitud de registro e inicializa el "número de registro actual" (a 0), pero no borra memoria.

La orden

|BANKWRITE,@<código generado>,<expresión literal>[,<número de registro>] 

escribe la <expresión literal> en el fichero. El <número de registro> especifica en qué registro se debe escribir. Si se omite este parámetro, se escribe en el número de registro actual. Finalmente, se actualiza este número (sumándole 1).

Si la <expresión literal> no llena el registro, los caracteres antiguos sobre los que no se ha escrito seguirán estando en el registro. Si la <expresión literal> es demasiado larga, se ignoran los caracteres restantes para no "corromper" el registro siguiente.

El <código generado> es una variable entera a través de la cual se puede conocer, al concluir la operación, el número de registro en el que se ha escrito (si la escritura se ha realizado con éxito) o un número de error (negativo) si la escritura ha fracasado:

  • -1 indica que se ha alcanzado el final del fichero (se ha intentado sobrepasar el final de los 64K).
  • -2 indica un error de conmutación de bancos (no debería ocurrir nunca).

Ejemplos:

  |BANKOPEN,10
  |BANKWRITE,@r%,"123 pruebas",0
  |BANKWRITE,@r%,w$

La orden

  |BANKREAD,@<código generado>,@<variable literal>[,<número de registro>]

lee un registro y asigna su contenido a la <variable literal>.

El <número de registro> especifica en qué registro se debe leer. Si se omite este parámetro, se lee en el número de registro actual. Finalmente, se actualiza este número (sumándole 1). Si el contenido del registro no llena completamente la <variable literal>, los caracteres antiguos sobre los que no se ha escrito seguirán estando en la <variable literal>. Si el contenido del registro es más largo que la <variable literal>, se ignoran los caracteres restantes, ya que no es posible aumentar la longitud de la variable mediante una orden externa.

El <código generado> es una variable entera a través de la cual se puede conocer, al concluir la operación, el número de registro en el que se ha leído (si la lectura se ha realizado con éxito) o un número de error (negativo) si la lectura ha fracasado:

  • -1 indica que se ha alcanzado el final del fichero (se ha intentado sobrepasar el final de los 64K).
  • -2 indica un error de conmutación de bancos (no debería ocurrir nunca).

Ejemplo:

|BANKREAD,@r%,i$,0

Búsquedas

Se puede recorrer el fichero en busca de un dato determinado. La orden

|BANKFIND,@<código generado>,<cadena buscada>[,<número de registro inicial>[,<número de registro final>]]

examina los registros especificados. El <número de registro inicial> especifica el registro a partir del cual debe comenzar la búsqueda. Si se omite este parámetro, se toma por defecto el número de registros actual.

La búsqueda continúa, a saltos de <longitud de registro>, hasta que se encuentra la cadena o hasta que se agotan los 64K.

Si se especifica el <número de registro final>, la búsqueda termina cuando se ha examinado ese registro (a menos que se haya encontrado la cadena antes).

Si la búsqueda concluye con éxito, el "número de registro actual" apunta al registro donde se ha encontrado la cadena; si no, sigue teniendo el valor anterior.

El <código generado> es una variable entera que contiene, al terminar la operación, información sobre cómo se ha desarrollado ésta. Si ha concluido con éxito, contiene el número de registro en el que encontró la cadena; si no, contiene un número negativo que es un código de error:

  • -1 Fin del fichero. El <número de registro inicial> sobrepasa el final de los 64K, o bien es mayor que el número de <registro final>.
  • -2 Error de conmutación de bancos (no debería ocurrir nunca).
  • -3 No se ha encontrado la cadena buscada.

La <cadena buscada> puede contener símbolos comodín, que en este caso son caracteres número 0, chr$(0). El número de caracteres que intervienen en las comparaciones es igual a la <longitud de registro> o a la longitud de la <cadena buscada>, el más corto de los dos. Ejemplos:

  |BANKFIND,@r%,"123 pru",0
  |BANKFIND,@r%,f$,100,200

Cuidado con los errores

Los errores obvios, tales como poner demasiados parámetros, son detectados e identificados como Bad Command. Sin embargo, el mecanismo de las órdenes externas no permite detectar errores del tipo Type mismatch, por lo que el usuario debe cerciorarse de que está utilizando parámetros de la forma correcta.

El siguiente programa utiliza las órdenes de RAMdisc para examinar una base de datos que contiene permutaciones de letras formadas con palabras de 7 letras. Busca concordancias y permite utilizar símbolos comodín.

Por ejemplo, las permutaciones de la palabra CENTRAL que concuerdan con ?NACE?? (puede omitir los dos últimos símbolos ?) son TNACERL, TNACELR, RNACETL, RNACELT, LNACETR y LNACERT.

Se tarda bastante en crear la base de datos, pero es que 64K es mucha memoria.

10 ' REVUELTO DE LETRAS, por ROLAND PERRY
20 ' copyright (c) AMSOFT 1985
30 '
49 ' No olvide RUN "BANKMAN" antes de ejecutar este programa
50 ' *************
60 '
70 MODE 2
80 DEFINT a-z
90 r%=0:|BANKOPEN,7
100 INPUT"Que palabra de 7 letras quiere revolver";s$
110 IF LEN(s$)<>7 THEN 100
120 PRINT"Por favor, espere un rato."
130 LOCATE 1,5:PRINT "Sigo trabajando: "
140 FOR c1=1 TO 7
150 FOR c2=1 TO 7
160 IF c2=c1 THEN 370
170 FOR c3=1 TO 7
180 IF c3=c2 OR c3=c1 THEN 360
190 FOR c4=1 TO 7
200 IF c4=c3 OR c4=c2 OR c4=c1 THEN 350
210 FOR c5=1 TO 7
220 IF c5=c4 OR c5=c3 OR c5=c2 OR c5=c1 THEN 340
230 FOR c6=1 TO 7
240 IF c6=c5 OR c6-c4 OR c6=c3 OR c6=C2 OR c6=c1 THEN 330
250 FOR c7=1 TO 7
260 IF c7=c6 OR c7=c5 OR c7=c4 OR c7=c3 OR c7=c2 OR c7=c1 THEN 320
270 o$=MID$(s$,c1,1)+MID$(s$,c2,1)+MID$(s$,c3,1)+MID$(s$,c4,1)+MID$(s$,c5,1)+MID$(s$,c6,1)+MID$(s$,c7,1) 
280 LOCATE 18,5:PRINT x;o$
290 |BANKWRITE,r%,o$
300 IF r%<0 THEN STOP
310 x=x+1
320 NEXT c7
330 NEXT c6
340 NEXT c5
350 NEXT c4
360 NEXT c3
370 NEXT c2
380 NEXT c1
390 ultimoreg=r%
400 REM ahora vamos a buscar
410 r%=0:g$=SPACE$(7)
420 PRINT:INPUT"Que subpalabra quiere buscar (puede escribir ? como simbolo comodin) ",m$
430 m$=LEFT${m$,7)
440 FOR x=1 TO LEN(m$)
450 IF MID$(m$,x,1)="?" THEN MID$(m$,x,1)=CHR$(0)
460 NEXT
470 |BANKFIND,r%,m$,0,ultimoreg
480 IF r%<0 THEN 420
490 |BANKREAD,r%,g$
500 PRINT g$,
510 |BANKFIND,r%,m$,r%+1,ultimoreg
520 GOTO 480