Ver el código de Turbo-Basic XL

{{toc numerate=1}}

===Introducción===

Fue escrito para el computador ATARI en 1985 por Frank Ostrowski (quien más tarde desarrolló el GFA Basic para el computador ATARI ST).

El Turbo Basic fue publicado originalmente como un programa de "mecanografía" en la revista alemana ((https://archive.org/details/happycomputer?&sort=-downloads&page=2 Happy Computer Magazine)) y más tarde estuvo disponible en muchas fuentes de dominio público.

Hay muchas versiones conocidas : 

  * La versión 1.4 que puede funcionar en el ATARI 400/800 con 48k de RAM.
  * La versión 1.5 que funciona en el ordenador 600/800/XL/XE con 64k de RAM.
  * Las versiones 2.0/2.1 que son similares a la v1.5 pero con la adición de rutinas de cinta Turbo para unidades de cinta modificadas.
  * La versión 3.2 que es compatible con SpartaDOS.

El Turbo BASIC, además de ofrecer 42 comandos y 22 funciones más que el ((/Apuntes/InstruccionesdelBasic Atari BASIC)), le da al usuario 1603 bytes más de espacio de programa al "esconder" parte de sí mismo bajo el sistema operativo del XL/XE. También funciona 3 veces más rápido que el Atari BASIC, incluye la mayoría de los comandos del DOS, tiene funciones gráficas y de programación avanzadas y es insensible a los caracteres en minúsculas o inversos para la mayoría de los comandos.

A continuación haremos una lista rápida de las nuevas instrucciones y las mejoradas :

===Comandos del DOS===

#|
*|Comando|Formato o ejemplo|Comentario|*
||BLOAD|BLOAD "D:nombre"
BLOAD "D:TEST.OBJ" |Cargar archivo binario (Opción L del DOS con /N).||
||BRUN|BRUN  "D:nombre"
BRUN "D:COMPILER.COM"
|Cargar y ejecutar archivo binario (Opción L del DOS).||
||DELETE |DELETE "D:nombre"
DELETE "D:TEST.BAS" |Eliminar archivo(s) (Opción D del DOS).||
||DIR|DIR
DIR "D2:*.BAS" |Listar el directorio del disco (Opción A del DOS).||
||LOCK |LOCK "D:nombre"
LOCK "D:AUTORUN.SYS" |Proteger archivo(s) (Opción F del DOS).||
||RENAME|RENAME "D:nombres actual,nuevo"
RENAME "D:TEST1.BAS,TEST2.BAS" |Renombrar archivo actual y nuevo (Opción E del DOS).||
||UNLOCK |UNLOCK "D:nombre"
UNLOCK "D:AUTORUN.SYS" |Desproteger archivo(s) (Opción G del DOS).||
|#

===Gráficos===

#|
*|Comando|Formato o ejemplo|Comentario|*
||CIRCLE|CIRCLE x,y,r
CIRCLE x,y,r,r2
CIRCLE 160,96,20
|Traza un círculo con centro en x e y con el radio r.
r2 es un "radio vertical" opcional para círculos o elipses.||
||CLS|CLS
CLS #6|Limpia la pantalla.  
Limpia la pantalla grafica.||
||FCOLOR|FCOLOR n
FCOLOR 3|Determina el color de relleno.||
||FILLTO|FILLTO x,y
FILLTO 80,93|Un comando de relleno igual a los comandos en BASIC (POSITION x,y:XIO 18,#6,0,0,"S:").||
||PAINT|PAINT x,y
PAINT 80,48|Rellena una figura cerrada con el color elegido mediante COLOR.||
||TEXT|TEXT x,y,a$
TEXT 3,8,"HOLA"|Escribe texto en un modo grafico en las coordenadas x e y.||
|#

===Memoria===

#|
*|Comando|Formato o ejemplo|Comentario|*
||DPOKE|DPOKE m,v
DPOKE 88,32750|Este comando coloca 2 bytes de datos en 2 ubicaciones de memoria consecutivas. En el ejemplo anterior en POKE 88 y POKE 89 se almacena el entero 32750.||
||DPEEK|DPEEK(m)
? DPEEK(88)|Esto es lo contrario de DPOKE. Recupera un entero de 2 bytes de 2 ubicaciones consecutivas. En el ejemplo anterior en PEEK (88) y PEEK (89).||
||MOVE|MOVE m,m1,m2
MOVE 53248,32768,1024|Transferencia en bloque, mueve m2 (número de bytes) desde la posición inicial m hasta la nueva posición inicial m1.||
||-MOVE|-MOVE m,m1,m2
-MOVE 53248,32768,1024|Igual que MOVE, pero las copias comienzan con el último byte del bloque.||
||BPUT|BPUT #n,adr,len
BPUT #3,ADR(B$),LEN(B$)|Bloque Put, es igual a FOR I=0 TO LEN-1:PUT #N,PEEK(ADR+I):NEXT I.||
||BGET|BGET #n,adr,len
BGET #3,ADR(B$),LEN(B$)|Bloque Get, es ifual a FOR I=0 TO LEN-1:GET #N,A:POKE ADR+I,A:NEXT I.||
||%PUT|%PUT #n,a
%PUT #1,A|Hasta ahora, no había una forma conveniente de poner valores numéricos en archivos de disco o casete que no fuera usando PRINT, que los convertía primero en cadenas, un proceso lento y engorroso. %PUT coloca el número en el dispositivo "tal cual", en formato FP de 6 bytes.||
||%GET|%GET #N,A
%GET #1,A|Obtenga un número almacenado con %PUT del dispositivo y guárdelo en la variable A. Nuevamente, esto es mucho más rápido que usar INPUT #N,A.||
|#

===Programación estructurada===

#|
*|Comando|Formato o ejemplo|Comentario|*
||REPEAT|REPEAT|Inicie un ciclo REPEAT hasta UNTIL.||
||UNTIL|UNTIL <c>
REPEAT:A=A+1
? A
UNTIL A=6|Terminar cuando se cumpla la condición <c>.||
||WHILE|WHILE <c>
A=10:WHILE A
? A
A=A-1:WEND|Inicie un ciclo WHILE-WEND para finalizar cuando se cumpla la condición <c>.||
||WEND|WEND|Termina un bucle WHILE-END.||
||ELSE|ELSE
IF X>3:? "LARGO":ELSE:? "OK":ENDIF
|Extensión opcional para IF. La condición SI no debe ir seguida de un "IF", sino que debe terminar con un final de línea o dos puntos.||
||ENDIF|ENDIF|Finaliza una condición IF-ELSE-ENDIF o IF-ELSE. Tenga en cuenta que esto permite que una condición IF abarque más de una línea BASIC, siempre que la declaración "IF" esté estructurada como se muestra en la Nota 4.||
||DO|DO|Inicia un bucle DO "infinito".||
||LOOP|LOOP|Vuelve al inicio de un ciclo DO.||
||EXIT|EXIT
DO:A=A+1
IF A=150 THEN EXIT
LOOP|Salir de un bucle DO-LOOP.||
||PROC|PROC nombre
PROC INICIO|Iniciar definición de procedimiento.||
||ENDPROC|ENDPROC|Fin de la definición de procedimiento.||
||EXEC|EXEC nombre
EXEC INICIO|Ejecute el nombre del procedimiento.||
|#

===Programación en general===

#|
*|Comando|Formato o ejemplo|Comentario|*
||PAUSE|PAUSE n
PAUSE 50|Pausar el procesamiento durante n / 50 segundos.||
||RENUM|RENUM n,i,j
RENUM 10,100,10|Vuelva a numerar el programa comenzando en la línea n, el primer número es i, el incremento es j. Esta función manejará GOTO, TRAP y todas las demás referencias de línea, excepto aquellas que involucran variables o valores calculados.||
||DEL|DEL n,i
DEL 60,100|Elimina las líneas del n al i.||
||DUMP|DUMP



----
DUMP unidad
DUMP "P:"
|Muestra todas las variables y valores. Para matrices numéricas, los números son los valores DIMed más uno. Para las cadenas, el primer número es su LONGITUD actual y el segundo número es su tamaño DIM. DUMP también enumera los nombres de los procedimientos y las etiquetas con sus valores de línea.
----
DUMP al nombre del dispositivo, como "P:" o "D:DUMP.DAT.||
||TRACE|TRACE
----
TRACE - |Seguimiento del programa durante la ejecución.
----
Desactiva el modo de seguimiento (predeterminado).||
||DSOUND|DSOUND n,f,d,v
----
DSOUND
|Forma de SONIDO que activa el emparejamiento de canales para aumentar el rango de frecuencia.

----
Apaga todos los sonidos.||
||GO TO|GO TO n
GO TO 20|Forma alternativa de GOTO.||
||*L|*L
----
*L - |Active la sangría de línea (predeterminado).
----
Desactiva la sangría de línea.||
||*F|*F (o *F +)



----
 *F - |Modo especial para bucles FOR..NEXT que corrige un error en Atari BASIC. Parece que en Atari BASIC, un bucle inverso "ilegal" como "FOR X = 2 TO 1: PRINT X: NEXT X" se ejecutará una vez aunque la condición se cumpla inicialmente (X ya es mayor que 1). Turbo BASIC corrige este error, pero lo deja disponible para los programas Atari BASIC que pueden aprovecharlo.
----
Desactiva el modo especial FOR..NEXT para que Turbo BASIC actúe como Atari BASIC.||
||*B|*B (o *B +)

----
*B -
|Comando que permite atrapar la llave de interrupción mediante el comando TRAP dentro de un programa.
----
Desactiva el modo de tecla especial BREAK.||
||--|--|Forma especial de REM que pone 30 guiones en una lista de programas.||
|#

===Etiquetas de línea===

#|
*|Comando|Formato o ejemplo|Comentario|*
|| # | # nombre
# ELFIN|Asigna el número de línea actual a la etiqueta nombre. Ésta es una forma conveniente de solucionar el problema de volver a numerar cuando se utilizan variables como números de línea. Las etiquetas se pueden considerar como una forma especial de variable, ya que ocupan la tabla de nombres de variables junto con las variables "regulares". También creemos que el número de variables permitidas se ha incrementado de 128 a 256 para permitir la adición de estas etiquetas.||             
||GO#|GO# nombre
GO# SETCHAT|Análoga al comando GOTO.||
|#

===Lógica y aritmética===

#|
*|Comando|Formato o ejemplo|Comentario|*
||HEX$|HEX$(n)
? HEX$(32)|Convierte n en cadena hexadecimal.||
||DEC|DEC(a$)
? DEC("FF")|Convertir cadena hexadecimal a$ a decimal.||
||DIV|n DIV i
? 9 DIV 4|División entre n e i, sin resto.||
||MOD|n MOD i
? 9 MOD 4|División entre n e i, con resto.||
||FRAC|FRAC(a)
? FRAC(22/2)
|Parte fraccionaria de a.||
||TRUNC|TRUNC(a)
? TRUNC(22/2)
|Trunca la parte fraccionaria de a.||
||RND|RND(n)
? RND
|Genera un número aleatorio 0 al n.||
||$|$nnnn
X=$10|Permite la entrada de números hexadecimales, pero se convierten a decimales. 
Ejemplo: FOR I=$0600 to $067F es igual a FOR I=1536 to 1663||
||&|n & i
? 1 & 1|Y binario.||
||!|n ! i
? 1 ! 0|O binario.||
||EXOR|n EXOR i
? 1 EXOR 1|Exclusive O binario.||
|#

===Cadenas y errores===

#|
*|Comando|Formato o ejemplo|Comentario|*
||TIME|TIME
? TIME/60|Hora del día (numérico).||
||{{anchor href="linktime"}}TIME$|TIME$
? TIME$|Cadena de hora del día, HHMMSS. Desafortunadamente, los comandos de tiempo no funcionan correctamente porque fueron escritos para Ataris europeos que operan a 50 Hz, en lugar de 60 Hz como los estadounidenses, el resultado neto es que ganan 12 minutos cada hora.||
||INKEY$|INKEY$
? INKEY$|Devuelve el último carácter escrito.||
||INSTR|INSTR(x$,a$)


----
INSTR(x$,a$,i)
|Devuelve la ubicación relativa del inicio de la cadena A $ dentro de X $ (devuelve 0 si no se encuentra). La coincidencia debe ser exacta; No se encontrarán cadenas con las mismas letras pero diferencias entre mayúsculas y minúsculas o tipo (normal o inverso).
----
i especifica el punto de inicio de la búsqueda.
||
||UINSTR|UINSTR(x$,a$)

----
UINSTR(x$,a$,i)
|Igual que INSTR, no distingue entre mayúsculas y minúsculas o caracteres inversos. 
Ejemplo: UINSTR ("HeLlO", "hola") devuelve 1.
----
Especifica un punto de partida opcional.||
||ERR|ERR
? ERR|Valor del último número de error.||
||ERL|ERL
? ERL|El último error de línea ocurrió en.||
|#

===Instrucciones actualizadas===

#|
*|Comando|Formato o ejemplo|Comentario|*
||CLOSE|CLOSE|Cierre los canales del 1 a 7.||
||DIM|DIM a(n)
DIM A(6)|Asignará automáticamente un valor de cero a todos los elementos de la matriz numérica que se está dimensionando y caracteres nulos a todos los elementos de una cadena (sin embargo, el LEN sigue siendo variable e inicialmente cero).||
||GET|GET nombre
GET A|Espere a que se presione una tecla, asigne el valor al nombre. Igual que OPEN #7,4,0,"K:":GET #7,NOMBRE:CLOSE #7.||
||INPUT|INPUT "texto";a,b...
INPUT "Numeros ";A
|Imprime texto como un mensaje antes de pedir variables, igual que Microsoft-BASIC.||
||LIST|LIST n,
LIST 90,|Enumere el programa desde la línea n hasta el final.||
||ON|ON a EXEC n1,n2,...
ON X EXEC INICIO,JUEGO,FINAL
----
ON a GO# n1,n2,...
ON X GO# NIVEL1,NIVEL2
|Variación de ON ... GOSUB para procedimientos. n1, n2, etc. son nombres de procedimientos que se ejecutarán.

----
Similar a ON ... GOTO excepto que se utilizan etiquetas de línea en lugar de números de línea.||
||POP|POP|Este comando ahora muestra la pila de tiempo de ejecución para los cuatro tipos de bucles.||
||PUT|PUT n
PUT 90|Igual que PRINT CHR$(n);||
||RESTORE|RESTORE #nombre
RESTORE #DATOS|Restaura la línea de datos indicada por el nombre de la etiqueta.||
||RAND|RAND(n)
? RAND(10)|En este comando, los números aleatorios se imprimen como enteros. Comienzan con 0 y terminan con el número 1 entre paréntesis.||
||SOUND|SOUND|Apaga todos los sonidos.||
||TRAP|TRAP #nombre
TRAP #ERROR|TRAPs a la línea a la que hace referencia el nombre de la etiqueta.||
|#

===Constantes===

#|
*|Comando|Formato o ejemplo|Comentario|*
||%0 
%1 
%2 
%3|X=%1|Estas cuatro constantes simplemente representan los números 0-3, respectivamente. La diferencia con utilizarlos en un programa es que X=1 requiere 10 bytes, mientras que X=%1 solo necesita 4 (los números requieren 7 bytes, 6 para el número más un identificador que lo precede. Siempre es una buena practica para hacer variables para números que se utilizan más de tres veces en un programa).||
|#

%%(info type="note" title="NOTA IMPORTANTE")
  1. Los nombres de variables, procedimientos y etiquetas pueden contener el carácter de subrayado (_).
  1. Para imprimir comillas dobles (") en una cadena de texto, use dos de ellos juntos, en lugar del método Atari BASIC de usar CHR$(34). Ejemplo: "TEST";CHR$(34);"TEXT" se convierte en "TEST" "TEXT" en Turbo-BASIC, los cuales producen la salida => TEST"TEXT.
  1. Tras el arranque inicial, TURBO-BASIC busca un archivo BASIC llamado AUTORUN.BAS. Si encuentra un archivo AUTORUN.BAS, lo cargará y ejecutará automáticamente.
  1. Turbo-BASIC también imprime descripciones en inglés de todos los errores, incluidos varios nuevos para errores relacionados con los nuevos comandos. Pero ((/Apuntes/CodigosdeErrores#h27-2 acá)) los encontrara traducidos. 
%%

===Compilación===

El compilador aumentará la velocidad de sus programas Turbo Basic 3 a 5 veces y los programas regulares de Atari BASIC pueden acelerarse hasta 10 a 15 veces más rápido. Desafortunadamente el compilador solo se ejecutará en la serie de computadores XL/XE. Además, los programas compilados también se ejecutarán solo en la serie XL/XE. 

El compilador es muy fácil de operar. Se puede utilizar con más de una unidad de disco, incluso la unidad D8 "disco RAM del 130XE". En el disco del compilador Turbo-BASIC XL, encontrará varios archivos. Los importantes para el funcionamiento del compilador son **COMPILER.EXE** y **RUNTIME.EXE**. Antes de comenzar, debe preparar dos discos.

  * El primero debe ser un disco formateado en blanco con DOS.SYS y DUP.SYS escritos en él. 
  * Su segundo disco debe contener su programa BASIC (TURBO o ATARI BASIC). 

Para comenzar, inserte el disco compilador en su unidad y encienda su computadora. Cuando haya terminado de cargar estarás en Turbo-BASIC XL. Escriba DOS para acceder al menú DOS 2.5. Elija la opción DOS 'L', cargue el archivo binario y cargue el archivo **COMPILER.EXE**. Después de un rato, verá una pantalla :

%%(wacko wrapper=text wrapper_align=center)((https://www.atariware.cl/archivos/tbxl/tbxlcomp.png))%%
En cualquier momento que esté en esta pantalla, puede reiniciar su sistema presionando **Control-R** o puede regresar a DOS presionando **Control-D**. Se le preguntará si realmente desea hacer esto. Presione 'Y' para si o 'N' para no.
 
Para compilar sus programas, quite el disco compilador de la unidad e inserte el disco con el programa que desea compilar. (Si tiene dos unidades, inserte su disco con el programa a compilar en la Unidad 2 y el disco DOS en blanco en la Unidad 1.) Presione la tecla número 1 (Número 2 si tiene dos unidades). Una lista completa de todos los archivos en esa unidad aparecerá en la pantalla con uno resaltado en video inverso. Usando las teclas de flecha, resalte el archivo que desea compilar y presione **ENTER**. ¡Eso es todo! 

%%(wacko wrapper=text wrapper_align=center)((https://www.atariware.cl/archivos/tbxl/tbxlcomp1.png))%%
En la parte superior de la pantalla, verá los números de línea volar mientras se compila el programa. Cuando haya terminado, se le pedirá un nombre de archivo para guardar su programa compilado. Tiene que tener un extensión de CTB (Compiled Turbo Basic).

%%(wacko wrapper=text wrapper_align=center)((https://www.atariware.cl/archivos/tbxl/tbxlcomp2.png))%%
El programa no le permitirá utilizar ningún otra extención. En este momento, si tiene una unidad, debe quitar el disco con su programa original y reemplazarlo con su disco DOS en blanco. Si desea que su programa compilado sea un archivo AUTORUN, debe nombrarlo **AUTORUN.CTB**. Luego, el archivo se cargará y ejecutará automáticamente en el momento del arranque. 

Hay un paso más que debe realizar para obtener un programa compilado completamente ejecutable. Regrese a DOS y copie el archivo RUNTIME.EXE del disco del compilador al disco con su programa compilado. Cambie el nombre del archivo RUNTIME.EXE por el nombre AUTORUN.SYS. Su disco ahora está listo para funcionar. El compilador no se compila en código ejecutable, debe ejecutar el archivo RUNTIME.EXE para ejecutar su programa compilado.

===Linker===

La idea es unir RUNTIME con el programa previamente compilado (CTB) para generar solo un archivo binario y guardarlo en disco.

Para ello cargamos desde Turbo Basic **RUN "D:LINKER.TUR"**

%%(wacko wrapper=text wrapper_align=center)((https://www.atariware.cl/archivos/tbxl/tbxllink.png))%%
Te preguntara el nombre de tu programa "ya compilado" y después como quieres que se llame. Empezara el proceso de unión y finalizara avisándote. 

===Versión NTSC===

La versión publicada aquí es la NTSC, ya que originalmente es PAL por que fue programado en Europa.

Cambios: 

  * Se cambió la palabra **READY** por **Turbo** y se mantuvo el color estándar de fondo.
  * Lo más importante se ajusto el reloj a 60hz para las funciones TIME y ((#linktime TIME$)) para no tener problemas en la hora.
  
===Descarga===

((https://www.atariware.cl/archivos/tbxl/TurboBasicXL.atr Turbo Basic XL 1.5)) para NTSC, este ATR incluye Turbo Basic, compilador, runtime y linker.