BBimport

Descripción del contenido de la página

Programa para importar en el intérprete de Beta BASIC un código fuente creado en el sistema anfitrión del emulador de ZX Spectrum.

Etiquetas:

BBimport es el último eslabón de la utilería BBim. Es un programa en Beta BASIC que importa en la ZX Spectrum el código en formato BBim, preparado por BBim2BB.

Hay seis versiones del programa, cuyas características se detallan a continuación. La última versión es la recomendada.

Comandos y errores durante la importación

El programa BBim2BB elimina los números de línea de aquellas líneas que comiencen por el signo de dos puntos («:»). Esto permite incluir en el código fuente comandos de Beta BASIC que se ejecutarán durante la importación.

Esto por ejemplo permite ejecutar, al final del código, una línea para borrar las líneas de BBimport y grabar en disco el programa recién importado. Como cabe esperar, tras ejecutar esos comandos Beta BASIC provoca un error porque la línea de BBimport que estaba siendo ejecutado ha sido borrada. Pero eso no quiere decir que la importación haya fallado. Un ejemplo puede verse a continuación en los pantallazos.

Cuando durante la importación se produce un error debido a una línea con sintaxis errónea que KEYIN no puede interpretar, el programa se detendrá con el mensaje correspondiente. La línea causante de un error de sintaxis estará en la variable l$.

Otro tipo de errores detectados durante el proceso provocaran que el programa se detenga con un simple STOP.

Pantallazos

Hasta la versión BBimport 4, el método para mostrar el código fuente que está siendo leído es el siguiente: Las líneas interpretadas se sobreescriben en la misma posición de pantalla, bajo la zona de almacenamiento de los sectores del disco, y a continuación se borra el equivalente a dos saltos de tabulación para facilitar la lectura. Pero a pesar de usar un juego de caracteres de 4x8 puntos, las líneas muy largas pueden llegar al final de la pantalla y provocar el mensaje de confirmación de desplazamiento, desplazamiento que evidentemente corrompe el almacén de sectores.

La siguiente imagen muestra este fallo, que fue corregido en BBimport 4a:

BBimport 4

La siguiente imagen muestra BBimport 5 durante el proceso de importación. Como siempre, la parte superior de la pantalla se usa como almacén del contenido de los sectores del disquete, pero las líneas importadas se muestran en una ventana independiente:

BBimport 5

La siguiente imagen muestra el final exitoso del proceso de importación, con un mensaje de error causado por el comando que ha borrado las líneas del propio BBimport 5 (la línea que comienza por delete 59 to:

BBimport 5

Código fuente

BBimport 1

BBimport 1 importa el código desde una falsa imagen de disquete MGT. Es una traducción del programa análogo MBimport 2 de MBim.

BBimport 1 no resultó útil porque el comando LOAD@ de Beta DOS hace inestable el sistema cuando se ejecuta en procedimientos, bucles o subrutinas en Beta BASIC. Para soslayar este inconveniente se escribió BBimport 3.

   1 REM BBimport 1
     (C) 2011 Marcos Cruz (programandala.net)
   2 DEF PROC import drive
   3   DEFAULT drive=2
   4   LOCAL buffer,sectorLen,bufferLen,l$,buffer,bufferEnd,c$,endOfSource,side,track,sector,sliceStart,CRPos,lastTrack
   5   LET c$=CHR$ VAL "13",endOfSource=NOT PI,buffer=VAL "22528",sectorLen=VAL "512",bufferLen=sectorLen+SGN PI,bufferEnd=buffer+sectorLen-SGN PI,side=NOT PI,track=NOT PI,sector=SGN PI,CRPos=NOT PI,lastTrack=CODE " CAT "
   6   loadSector
   7   DO
   8     diskTo l$
   9   EXIT IF endOfSource
  10     PRINT AT 0,0;lineN
  11     PRINT l$
         PAUSE NOT PI
  12   LOOP
  13 END PROC
  14 DEF PROC diskTo REF l$
  15   LET l$=""
  16   IF NOT PEEK sliceStart THEN LET endOfSource=SGN PI
         GO TO 21
  17   DO
  18     LET crPos=INSTRING(1,MEMORY$()(sliceStart TO bufferEnd),c$)
  19     IF crPos
           LET l$=l$+MEMORY$()(sliceStart TO crPos-1)
           IF crPos=bufferEnd THEN feedBuffer
           ELSE LET sliceStart=crPos+1
           ELSE LET l$=l$+MEMORY$()(sliceStart TO bufferEnd)
             feedBuffer
  20   LOOP UNTIL crPos
  21 END PROC
  22 DEF PROC feedBuffer
       nextSector
       loadSector
     END PROC
  23 DEF PROC loadsector d,t,s
  24   DEFAULT d=drive,t=track,s=sector
  25   PRINT t,s
       REM LOAD @d,t,s,buffer,1
  26   LET sliceStart=buffer
  27 END PROC
  28 DEF PROC nextSector
  29   IF 10>sector THEN LET sector=sector+1
       ELSE nextTrack
  30 END PROC
  31 DEF PROC nextTrack
  32   IF track=lastTrack THEN wipeBuffer
         LET endOfSource=SGN PI
         GO TO 35
  33   IF 80>track THEN doSide1 track
       ELSE doSide0 track
         LET track=track+1
  34   LET sector=1
  35 END PROC
  36 DEF PROC doSide1 REF track
       LET track=track+128
     END PROC
  37 DEF PROC doSide0 REF track
       LET track=track-128
     END PROC
  38 DEF PROC r
       RENUM LINE SGN PI STEP SGN PI
     END PROC
  39 DEF PROC s
       ERASE d*"BBimport1!"
       ERASE d*"BBimport1" TO "BBimport1!"
        SAVE d*"BBimport1"
     END PROC

BBimport 2

BBimport 2 emplea un método diferente de importación: lee el código fuente como un fichero secuencial desde un disquete MGT, fichero previamente creado con la extensión .bb por BBim2BB y que debe ser después introducido en el disquete con ayuda de una herramienta como SAM Diskimage Manager. Sin embargo, ciertos problemas (descritos en el historial de desarrollo) hicieron impracticable este método.

   1 REM BBimport 2
     (C) 2011 Marcos Cruz (programandala.net)
   2 INPUT "Drive: ";d,"File:"; LINE f$
     CLOSE #*
     OPEN #VAL "4",dd;f$RND
     FOR n=SGN PI TO VAL "9"
       LET l$=INKEY$#VAL "4"
     NEXT n
   3 INPUT #VAL "4"; LINE l$
     PRINT AT NOT PI,NOT PI;l$,,
     KEYIN l$
     GO TO 3
   4 DEF PROC s
       ERASE d*"BBimport2!"
       ERASE d*"BBimport2" TO "BBimport2!"
       RENUM LINE SGN PI STEP SGN PI
        SAVE d*"BBimport2"
     END PROC

BBimport 3

BBimport 3 es una versión de BBimport 1 en que el bucle principal está fuera de un procedimiento y en lugar de bucles se usan saltos de línea. Esto evita los problema que crean ciertos comandos de Beta DOS cuando se ejecutan en procedimientos, bucles o subrutinas de Beta BASIC.

9990 REM BBimport 3
     (C) 2011 Marcos Cruz (programandala.net)
9991 LET buffer=VAL "16384",drive=VAL "2",bufferEnd=buffer+VAL "511",track=NOT PI,sector=SGN PI,l$=""
9992 LOAD @drive,track,sector,buffer
     LET chunk=buffer
     IF NOT PEEK chunk THEN STOP
9993 LET crPos=INSTRING(SGN PI,MEMORY$()(chunk TO bufferEnd),CHR$ VAL "13")
     IF crPos THEN LET l$=l$+MEMORY$()(chunk TO chunk+crPos-VAL "2")
       IF crPos=bufferEnd THEN nextSector
         LOAD @drive,track,sector,buffer
         LET chunk=buffer
       ELSE LET chunk=chunk+crPos
       ELSE LET l$=l$+MEMORY$()(chunk TO bufferEnd)
         nextSector
         GO TO 9992
9994 PRINT AT VAL "9",NOT PI;l$,,
     KEYIN l$
     LET l$=""
     GO TO 9993
9995 DEF PROC nextSector
       IF VAL "10">sector THEN LET sector=sector+SGN PI
       ELSE LET sector=SGN PI
         IF track=VAL "207" THEN STOP
         ELSE IF VAL "80">track THEN LET track=track+VAL "128"
         ELSE LET track=track-VAL "127"
9996 END PROC
9997 DEF PROC s
        SAVE d*"BBimport3"
     END PROC

BBimport 4

BBimport 4 es una versión más rápida de BBimport 3, pues no lee los sectores del disco de uno en uno sino en grupos de cinco. Esta fue la versión utilizada en el desarrollo de La legionela del pisto hasta que se produjo un oscuro error en la importación de uno de los módulos, para cuya investigación se creó la versión BBimport 5.

9990 REM BBimport 4
     (C) 2011 Marcos Cruz (programandala.net)
9991 LET buffer=VAL "16384",drive=VAL "2",bufferEnd=buffer+VAL "2559",track=NOT PI,sector=SGN PI,l$=""
9992 LOAD @drive,track,sector,buffer,VAL "5"
     LET chunk=buffer
     IF NOT PEEK chunk THEN STOP
9993 LET crPos=INSTRING(SGN PI,MEMORY$()(chunk TO bufferEnd),CHR$ VAL "13")
     IF crPos THEN LET l$=l$+MEMORY$()(chunk TO chunk+crPos-VAL "2")
       IF crPos=bufferEnd THEN next5sectors
         LOAD @drive,track,sector,buffer,VAL "5"
         LET chunk=buffer
       ELSE LET chunk=chunk+crPos
       ELSE LET l$=l$+MEMORY$()(chunk TO bufferEnd)
         next5sectors
         GO TO 9992
9994 PRINT CSIZE VAL "4",VAL "8";AT VAL "16",NOT PI;l$,,
     KEYIN l$
     LET l$=""
     GO TO 9993
9995 DEF PROC next5sectors
       IF sector=SGN PI THEN LET sector=VAL "6"
       ELSE LET sector=SGN PI
         IF track=VAL "207" THEN STOP
         ELSE IF VAL "80">track THEN LET track=track+VAL "128"
         ELSE LET track=track-VAL "127"
9996 END PROC
9997 DEF PROC s
        SAVE d*"BBimport4"
     END PROC

BBimport 4a

BBimport 4a es una modificación de BBimport 4, que fue necesaria para poder importar BBimport 5: imprime las líneas en una ventana. Sin este cambio las líneas muy largas provocaban un desplazamiento de pantalla que corrompía la informacíon leída del disco.

9990 REM BBimport 4a
     (C) 2011,2012 Marcos Cruz (programandala.net)
9991 WINDOW SGN PI,NOT PI,CODE "/",VAL "256",CODE "0"
     WINDOW SGN PI
     LET buffer=VAL "16384",drive=VAL "2",bufferEnd=buffer+VAL "2559",track=NOT PI,sector=SGN PI,l$=""
9992 LOAD @drive,track,sector,buffer,VAL "5"
     LET chunk=buffer
     IF NOT PEEK chunk THEN STOP
9993 LET crPos=INSTRING(SGN PI,MEMORY$()(chunk TO bufferEnd),CHR$ VAL "13")
     IF crPos THEN LET l$=l$+MEMORY$()(chunk TO chunk+crPos-VAL "2")
       IF crPos=bufferEnd THEN next5sectors
         LOAD @drive,track,sector,buffer,VAL "5"
         LET chunk=buffer
       ELSE LET chunk=chunk+crPos
       ELSE LET l$=l$+MEMORY$()(chunk TO bufferEnd)
         next5sectors
         GO TO 9992
9994 POKE VAL "23692",CODE " COPY "
     PRINT l$
     KEYIN l$
     LET l$=""
     GO TO 9993
9995 DEF PROC next5sectors
       IF sector=SGN PI THEN LET sector=VAL "6"
       ELSE LET sector=SGN PI
         IF track=VAL "207" THEN STOP
         ELSE IF VAL "80">track THEN LET track=track+VAL "128"
         ELSE LET track=track-VAL "127"
9996 END PROC
9997 DEF PROC s
        SAVE d1"BBimport4a"
     END PROC

BBimport 5

BBimport 5 empezó como una traducción de BBimport 4 al formato BBim, con el objetivo de manejar mejor el código y encontrar la oscura causa de un error que se producía durante la importación de un módulo de La legionela del pisto. Sorprendentemente, usando esta versión el problema desapareció, sin hacer ningún cambio, al menos conscientemente.

Esta es pues la versión recomendada.

/*

BBimport 5

Copyright (C) 2012 Marcos Cruz (programandala.net)

Licence:
http://programandala.net/license

This file is part of BBim:
http://programandala.net/es.programa.bbim

2011-03-07 First version (BBimport 4 converted to BBim).
2012-03-09 Added WINDOW ERASE at the end.

*/

rem BBimport 5 (C) 2012 programandala.net

// *****************************
// Metacommands 

// Convert long variable and procedure names to short ones.
// It saves memory and execution time.

#vim %substitute/\<bufferEnd\>/be/gI
#vim %substitute/\<bufferPointer\>/bp/gI
#vim %substitute/\<buffer\>/b/gI
#vim %substitute/\<commandLenght\>/l/gI
#vim %substitute/\<command\$/c$/gI
#vim %substitute/\<crPosition\>/p/gI
#vim %substitute/\<drive\>/d/gI
#vim %substitute/\<line\$/l$/gI
#vim %substitute/\<pointToNext5sectors\>/n5/gI
#vim %substitute/\<sector\>/s/gI
#vim %substitute/\<track\>/t/gI

// *****************************
// Init

let \
  buffer=val "16384",\ // The screen is used as buffer.
  bufferEnd=buffer+val "2559",\  // Space for 5 disk sectors.
  drive=val "2",\  // The source must be in the second drive.
  track=not pi,\  // Tracks are 0-79.
  sector=sgn pi,\  // Sectors are 1-10.
  line$="":\  // Source line to be interpreted.

// Output window 
// (below the screen region used as buffer)

window erase:\
window sgn pi,\
  not pi,code"/",\ // Top left corner: x=0 and y=47.
  val"256",code"0":\ // Size: width=256 and height=48.
window sgn pi

// *****************************
// Main loop

label @load5sectors:\
load @drive,track,sector,buffer,val "5":\
let bufferPointer=buffer:\
if not peek bufferPointer then \
  // The sectors are empty. There is no more source code.
  window erase:stop

label @searchForEndOfLine:\
let crPosition=instring(sgn pi,memory$()(bufferPointer to bufferEnd),chr$ val "13"):\

if crPosition then \
  // The end of the line was found.
  let line$=line$+memory$()(bufferPointer to bufferPointer+crPosition-val "2"):\
  if crPosition=bufferEnd then \
    // The end of line is the last byte of the buffer.
    pointToNext5sectors:\
    load @drive,track,sector,buffer,val "5":\
    let bufferPointer=buffer:\
  else \
    let bufferPointer=bufferPointer+crPosition:\
else \
  // The end of the line was not found yet.
  let line$=line$+memory$()(bufferPointer to bufferEnd):\
  pointToNext5sectors:\
  goto @load5sectors

// The source line is ready.

// Force endless scrolling,
// poking the ZX Spectrum variable SCR_CT with 255: 
poke val "23692",code "\#255":\
//
print line$:\
keyin line$:\
let line$="":\
goto @searchForEndOfLine

// *****************************
// Disk sector position

defproc pointToNext5sectors:\
  /*
    Update the sector and track numbers
    in order to load the next five sectors.
  */
  if sector=sgn pi then \
    // Point to the second half of the current track.
    let sector=val "6":\
  else \
    // Point to the first half of the next track.
    let sector=sgn pi:\
    if track=code "\#207" then \ // track=207?
      // No more tracks. The source code is too big.
      stop:\
    else \
      // Next track (and change the disk side).
      if track < code "\#80" then \ // track<80?
        let track=track + code "\#128":\ // Add 128.
      else \
        let track=track - code "\#127" // Substract 127.
endproc

// *****************************
// Import-time commands:

// This version doesn't work fine:
#:\
# delete 9990 to:\  // Remove the import program used.
# renum line 9990 step 1:\  // Occupy its position.
# save over d1"BBimport5"

// Manual alternative:
:\
  cls:print \
  "Type in the following commands:"'\
  "DELETE 9990 TO"'\
  "RENUM LINE 9990 STEP 1"'\
  "SAVE OVER D1""BBIMPORT5"""

Descargas

Imágenes de disquete de Plus D:

Las imágenes de disquete contienen, además de todas las versiones de BBimport:

Todos los componentes de BBim pueden descargarse en la sección de descargas de BBim.

Páginas relacionadas

MBimport
Programa escrito en MasterBASIC para importar en el emulador SimCoupe código fuente en MasterBASIC escrito en ficheros de texto creados en el sistema operativo anfitrión.