Basito: Basic compatible CPC por NotFound A MODO DE INTRODUCCIÓN No pensaba escribir nada aun respecto al CPC de Amstrad, hasta que entré al foro de Speccy.org y me di con la existencia de algo totalmente inesperado. Pero ahí estaba Not Found, el mismo del BLASSIC ahora ofreciendo una versión de Locomotive Basic para el +3. Así que heblemos algo al respecto... Y no se me ha ocurrido mejor modo de empezar estas notas que volviendo a publicar lo que el autor ya posteó en el foro de SPECCY.ORG respecto a su programa para +3: "Hola a todos. He estado poniendo un poco a punto mi viejo proyecto Basito: un Basic compatible con el Locomotive Basic de los Amstrad CPC. En primicia mundial para speccy.org he subido una imagen dsk para Spectrum +3 en: https://notfound.tecnawebs.com/bin/basitop3.tgz Funciona la mayor parte del Basic, con la gran excepción de que solo admite enteros (asume DEFINT A-Z), aunque como caso especial admite números hasta 65535 y los convierte. Las cosas que dependen del hardware, como los colores, funcionan mas o menos. WINDOW y familia no funciona, los canales 0 a 7 se dirigen todos a la consola. Las funciones e instrucciones no implementadas generan un error 255, o en algunos casos error de syntaxis. Puede cargar y guardar programas del CPC, tanto en binario como texto. Pues eso, toda extraña persona que conozca tanto el Spectrum como el CPC y quiera probar este Frankestein puede contar sus impresiones." "Ah, olvidaba mencionar que aún no tiene arrays ni def fn." "Puede usar el ramdisc, usando |M o "M:..." en los nombre fichero." "El ramdisc no se borra al iniciar, y la orden |exit (y también la instrucción no-CPC system, pero esto no he decidido aún si lo mantendré) vuelve al menú del Spectrum sin perder el ramdisc. Los ficheros abiertos con OPENIN admiten finales de línea con CRLF como es habitual, y también con solo LF. Esto último no es muy fiel al CPC, pero facilita las cosas al usar ficheros copiados de linux. SYMBOL permite definir los caracteres del rango de los UDG del Spectrum (incluyendo los del modo 48K) y también los mapea al rango 235-255 para poder usar sin modificar los ejemplos típicos del CPC (salvo que SYMBOL AFTER por ahora no funciona). O sea, que SYMBOL 144, .... y SYMBOL 235, ... redefinen el mismo caracter, PRINT CHR$ (144) y PRINT CHR$(235) imprimen el mismo caracter. Y otra, para teclear caracteres de control ^A a ^Z se usa modo extendido y la tecla correspondiente sin ningún shift, y break hace de ESC. Creo que esto no impide el tecleo de ningún caracter normal ni gráfico, avisadme si me equivoco. ...Por ahora las instrucciones de gráficos no están implementadas, así que no se acerca nada en absoluto. Aparte de mi total desconocimiento de la ULA Plus. Pero cuando la cosas esté un poco mas pulida y publique los fuentes todo será posible. Por otra parte he publicado solo la versión Plus3 como especial para speccy.org, pero es multiplataforma (siempre que sea Z80). Además de +3 lo estoy probando en el propio CPC y en CP/M. Así que la parte gráfica necesariamente deberá tener varias versiones (o no funcionar en absoluto, en caso de CP/M genérico)." NotFound Y con esa información en mente, ya paso a... PARTE I ------- LOS COMANDOS DEL BASIC DE AMTRAD CPC Resumidamente los comandos y funciones del Basic 1.1 de Locomotive para CPC-6128. PREFIJOS: --------- &, &H = constante hexadecimal &X = constante binaria # = indicador de canal o flujo | = comando de disco SUFIJOS: -------- % = valor entero (entre -32768 a +32767) ! = valor real (de 9 digitos de precisión) $ = cadenas SENTENCIAS: ----------- AFTER d,t GOSUB n - va a subroutina en n tras demora de 1/50vo de segundo según t. AUTO {n{,i}} - Genera lineas automaticamente empezando por n con incremento i Starting at linenumber and incrementing by increment. BORDER c1,c2 - Changes border colour. If two colours are specified alternates at the rate determined by the SPEED INK command CALL dir{,lista de parametros} - llama a subrutina en C.M. desde el Basic CAT - lee dispositivo (cinta o disco) y lista todos los archivos encontrados. $ - programa BASIC % - Programa protegido de BASIC * - archivo de texto en ASCII & - archivo de tipo binario ' - binario protegido CHAIN n${,linea} - carga un programa reemplazando al que está en memoria. CHAIN MERGE n$ - Mezcla un programa del dispo con el que está en la memoria su sintaxis completa es: CHAIN [{MERGE}] n${,linea}[{,DELETE líneas}] CLEAR - borra todas las variables y ficheros CLG {c} - borra la pantalla gráfica y la coloreará con c CLOSEIN - cierra fichero de solo lectura CLOSEOUT - cierra fichero de solo escritura CLS {#x} - borra una pantalla de texto en la ventana x CONT - continua un programa que se detuvo tras BREAK, STOP o END DATA - contiene una lista de datos constantes DEF FN nombre(parametros)=expresion - define función, debe estar fuera de cualquier bucle dentro del programa principal y no puede ser usado como comando directo. DEFINT, DEFSTR, DEFREAL - define el rango de tipos de variables por defecto DEG - hace que las funciones radiales devuelvan grados en vez de radianes DELETE [x{-}]{-y} - borra números de línea según el rango dado o todo el listado DI - deshabilita las interrupciones que no sean BREAK o un EI o retorno de GOSUB DIM - reserva espacio para las matrices, ejemplo: DIM b$(5) DRAW x,y [,i{,modo de tinta}] - dibuja desde el cursor hasta x,y con color i DRAWR x,y{,i...} - lo mismo pero usando coordenadas relativas EDIT n - edita una línea n EI - habilita las interrupciones desactivadas por DI END - termina el programa ENT envelopenumber, envelopesections - varia el tono de un sonido ENV envelopenumber, envelopesections - varia el volumen de un sonido ERASE array - libera la memoria utilizada por una matriz ERROR i - genera una acción de error dependiendo del código de error i. EVERY t1,t2, GOSUB n - va a subrutina en el intervalo t1, con t2 de 0 a 3 FILL n - rellena una región de la pantalla gráfica con el color n FOR var=start TO end STEP size - bucle FOR de tipo estandar FRAME - hace que el movimiento de figuras sea más suave sin parpadeos en pantalla GRAPHICS PAPER n - especifica el color de fondo de la pantalla gráfica GRAPHICS PEN n{,modo} - elige el color de tinta con modo opaco 0 o transparente 1 GOSUB n - salta a una subrutina en la línea n RETURN - fin de la subrutina y vuelve adonde se la invocó GOTO n - salta a una linea n IF e1 THEN e2 ELSE e3 - también existe la variante IF e1 GOTO n ELSE e3 INK n,c - Cambia tinta n al color c. Depende del modo gráfico en curso. INPUT - recibe datos de un canal por medio de una variable y genera un mensaje su sintaxis completa: INPUT {#s;}{"mensaje"}{;}{,}var{$}{,variable2{$}...} KEY k,s$ - asocia una tecla d función a una definición de cadena s$. K= 128-159. KEY DEF - Define lo que una tecla particular devuelve. siendo su sintaxis completa: KEY DEF tecla n, repite[,normal{,con shift}{,control}] {LET }variable=expresion - Asocia una variable con un valor dado en la expresion. LINE INPUT {#s,} {"txt",} var$ - como INPUT, pero acepta una línea completa LIST [rango{,#s] - Lista el programa en el canal s según un rango: n-m, -m o n-. LOAD "name"{,dir} - carga un programa BASIC. Si se añade dir es un archivo binario. LOCATE {#s,}x,y - Mueve el cursor de texto a la posicion x,y {en ventana #s} MEMORY &dir - fija el más alto byte disponible en RAM para el BASIC MERGE "name" - Mezcla un programa BASIC con el que existe en memoria. MODE n - Cambia el modo de pantalla tanto texto como resolución gráfica sea 0, 1 o 2. MOVE x,y - mueve el cursor gráfico hasta x,y sin dibujar o trazar MOVER x,y - como MOVE pero con coordenadas x,y relativas. NEW - borra todo el programa junto con las variables. ON ie {GOSUB / GOTO} lista - evalua ie y salta a una línea de la lista ON BREAK GOSUB n - salta a subrutina en n cuando un programa es detenido. ON BREAK STOP - deshabilita ON BREAK GOSUB. ON ERROR GOTO n - si un error ocurre entonces salta a la linea n. ON SQ(ch) GOSUB n - captura vacíos en la cola de sonido, 1 canal A, 2 es B y 3 es C OPENIN "filename" - abre archivo para su lectura. OPENOUT "filename" - abre archivo para escritura. ORIGIN x,y{,izq,der,ar,ab} - fija el inicio del cursor gráfico. Usando 'izq,der,ar,ab' fija una nueva ventana con el origen dentro de esa ventana. OUT &p,i - envia un dato entero i a un puerto especificado &p. PAPER {#x,}p - fija el color del fondo. PEN {#x,}p - fija el color de tinta del lapiz. PLOT x,y{,c} - mueves el cursor gráfico hasta x,y dibujando un punto de color c PLOTR x,y{,c} - como PLOT pero con coordenadas relativas POKE &dir,v - inserta un valor v en la dirección de memoria dir. PRINT - su sintaxis completa es: PRINT [#,][][][] RAD - fija modo en radianes RANDOMIZE {n} - fija el valor inicial {n} para el generador de numeros aleatorios. READ - lee los datos contenidos en una sentencia DATA. RELEASE sc - libera un sonido cuando es retenido en la cola del canal sc dado REM - comentario RENUM [nueva{,original}{,incremento}] - Renumera el programa BASIC. RESTORE {n} - hace que READ relea una DATA en {n}, por defecto va al primer dato RESUME [{linea}/{NEXT}]- hace que el programa continue tras un evento ON ERROR GOTO. RUN {/} - ejecuta programa s$ ó el programa en curso desde la linea n. SAVE "name"{,t}{,bin} - Salva el programa. donde: t = A (ASCII), P (protegido), B (salva archivo binario) bin = ", inicio, largo, punto de autoejecución". SOUND estado canal, periodo del tono, duracion, volumen, envoltura del volumen, envoltura del tono, periodo del ruido SPEED INK t1, t2 - alterna entre INK y BORDER los cuales permiten que dos colores sean asociados mutuamente. SPEED KEY d, r - velocidad de las teclas, donde d= demora y r= repetición SPEED WRITE i - Cambia los i baudios del interfaz del cassette. 1=2000 baud, 0=1000 baud STOP - detiene la ejecución de un programa con el mensaje "Break" SYMBOL c,lista- Redefine la representación de un caracter c. SYMBOL AFTER x - fija el número de caracteres definibles por el usuario. Por defecto x es 240 dejando 16 caracteres disponibles. TAG #s - Redirige el texto enviado a un canal s al cursor gráfico. TAGOFF #s - Cancela TAG TRON - ejecuta el rastreo de un programa TROFF - Cancela TRON WAIT p, m, i - Suspende todo hasta que el puerto p de E/S retorne un dato particular. El dato leido es XOR con inversion i, luego AND con mascara m hasta ser no-cero. WHILE ... WEND - mientras condicion ... expresiones ... fin del mientras WIDTH w - especifica el ancho w de la impresora WINDOW #stream, left,right,top,bottom - Sets a text window for a given stream. WINDOW SWAP s1, s2 - intercambia las ventanas de texto. WRITE {#s,} list - Como PRINT pero añadiendo comillas o comas a los datos. ZONE i - Cambia el ancho i de la zona de impresión. FUNCIONES: ---------- ABS(x) - retorna el valor absoluto de x ASC(x$) - returna el valor ASCII de x$ ATN(x) - retorna la arcotangente de x BIN$(n, d) - retorna una cadena con largo d para la representación binaria de n CHR$(x) - retorna un caracter equivalente a x CINT(x) - convierte x a un entero redondeado. COS(x) - retorna el coseno de x en radianes CREAL(n) - convierte n a número real COPYCHR$(#s) - lee cara caracter en la posición real del cursor en pantalla #s DERR - devuelve error de disco EOF - si se llegó al final de un archivo en cinta o disco devuelve -1 o 0 si no. ERR - Variable reservada para el manejo de errores. ERL - Variable reservada para capturar la línea del error. EXP(n) - calcula el exponente de n FIX(n) - deja la expresión entera, redondea la fracción a cero FRE(...) - 0 da la memoria libre, FRE("") fuerza una 'limpieza de memoria' además. HEX$(n{,x}) - Convierte un decimal n en hexadecimal de anchura x opcional HIMEM - devuelve el byte más alto de la memoria. INKEY(n) - escanea el teclado, y su resultado es su código numerico. INKEY$ - lee una tecla y su resultado es un caracter ASCII o la cadena vacía. INP(p) - lee de un puerto p de E/S. INSTR({i,} s1$, s2$) - busca s1$ en s2$ a partir de i, el cual es opcional. INT(n) - Redondea al entero más bajo posible. JOY(jn) - lee del joystick jn (0 o 1) y su resultado es el bit más significativo. LEFT$(s$, n) - Retorna los n caracteres a la izquierda de s$ LEN(s$) - Retorna el largo de la cadena s$ LOG(n) - Retorna el logaritmo natural de n LOG10(n) - Retorna el logaritmo en base 10 de n LOWER$(s$) - convierte todos los caracteres de s$ a minúsculas. MAX (a,b,c,d,e) - Retorna el maximo valor dentro de una lista especifica. MIN(a,b,c,d,e,f etc) - Retorna el dato de menos valor en la lista. MID$(s$, s{, n}) - Retorna los {n} caracteres de s$ a partir de s PEEK(&addr) - Retorna el contenido de una dirección. PI - 3.14159265 POS(#s) - Retorna coordenada horizontal del canal s de la pantalla, da la posicion del acarreo de impresora donde 1 es el margen izquierdo. REMAIN(t) - Desabilita el tiempo de demora especificado por t. RIGHT$(s$, n) - Retorna los n caracteres a la derecha de s$. RND{(x)} - número aleatorio, parámetro opcional. ROUND(n {,p}) - Redondea un numero n con p decimales. SGN(n) - Retorna el signo de un numero n. SIN(a) - Seno del angulo a. SQ(ch) - Chequea el numero de entradas libres en cola de un canal ch dado SQR(n) - raiz cuadrada de n. SPC(n) - genera n espacios en una línea de PRINT SPACE$(n) - Crea una cadena conteniendo n espacios. STR$(n) - Convierte n en una cadena. STRING$(i, c$) - Retorna cadena de largo i consistente en el caracter c$. TAN(a) - Tangente de un ángulo a. TEST(x,y) - Retorna el color en x,y TESTR(x,y) - Retorna el color de tinta en las coordenadas relativas TIME - Reporta el tiempo transcurrido desde que se inició el sistema. UNT(&addr) - Convierte entero sin signo de 16bits a un valor de -32768 a +32767 UPPER$(s$) - Convierte s$ en mayúsculas. VAL(s$) - Retorna el valor numerico de s$. VPOS(#s) - Retorna la posicion vertical del cursor de texto en el canal s. XPOS - da la posición x del cursor gráfico. YPOS - da la posición y. OPERADORES LOGICOS Y MATEMATICOS: --------------------------------- ^ MOD - * y / \ + y - AND OR NOT XOR MENSAJES DE ERROR: ------------------ 1 Unexpected NEXT - NEXT sin su FOR correspondiente 2 Syntax Error - error de sintaxis al tipear una instrucción dada 3 Unexpected RETURN - sentencia RETURN sin su GOSUB correspondiente 4 DATA exhausted - se trató de leer más allá de la lista de DATAs 5 Improper argument - parámetro no válido 6 Overftow - se excedió el valor permitido por una operación aritmetica o no se pudo cambiar un valor de coma flotante a entero de 16 bits 7 Memory full - el programa o sus variables exceden la memoria libre 8 Line does not exist - se referenció una línea que no existe 9 Subscript out of range - indice de matriz fuera del rango 10 Array already dimensioned - la matriz ya fue dimensionada 11 Division by zero - se intentó una división por cero 12 Invalid direct command - comando directo no válido 13 Type mismatch - valor no válido, numero en vez de cadena con READ o INPUT 14 String space full - no hay más espacio disponible para las cadenas 15 String too Long - la cadena excede los 255 caracteres. 16 String expression too complex - la expresión de cadena es demasiado compleja 17 Cannot CONTinue - algo impide a CONT proseguir tras un STOP o ESC 18 Unknown user function - función de usuario desconocida. FN sin DEFinir 19 RESUME missing - se llegó al final del programa habiendo hecho ON ERROR GOTO. 20 Unexpected RESUME - se encontró RESUME sin su respectivo ON ERROR 21 Direct command found - se encontró un comando directo en el listado tras cargarlo 22 Operand missing - falta un operando: el BASIC encontró una expresión incompleta. 23 Line too Long - al convertir una línea del BASIC internamente resultó muy larga. 24 EOF met - se intentó leer un fichero más allá de su final 25 File type error - tipo de archivo erroneo, al usar OPENIN o LOAD y RUN 26 NEXT missing - se encontró un FOR sin su NEXT correspondiente 27 File already open - archivo ya abierto, se hizo OPENIN u OPENOUT antes de cerrarlo 28 Unknown command - comando externo no reconocido 29 WEND missing - se encontró un WHILE sin su WEND correspondiente 30 Unexpected WEND - Se encontró un WEND pero no WHILE 31 File not open - archivo no abierto (ver ‘errores de Disco’.) 32 Broken in - dañado... (ver ‘errores de Disco’.) Errores de disco de AMSDOS: Si hay problemas de hardware surge el mensaje: Retry, Ignore or Cancel? - reintentar, ignorar o cancelar? R causa que la operacion se repita, posiblemente una vez el usuario tomó medidas preventativas. I causa que la computadora continue como si el problema no hubiese ocurrido C causa que la accion se cancele, lo cual suele llevar a otros mensajes de error Unknown command - el comando (desconocido) no fue tipeado correctamente. Bad command - el comando (malo) no puede ejecutarse por sintaxis o configuracion de hardware already exists - se ha intentado renombrar con un nombre ya existente. not found - no encontrado... el archivo no existe. Drive : directory full - No espacio en el directorio para más entradas. Drive : disc full - No hay espacio en el disco para nuevos archivos Drive : disc changed, closing - cambió disco con archivos aun abiertos is read only - el fichero no puede ser modificado ya que es solo lectura (CP/M) Drive : disc missing - No hay disco o ha sido mal puesto Drive : disc is write protected - disco protegido contra escritura Drive : read fail - error de hardware al leer un disco. Drive : write fail - error de hardware al escribir en un disco. Failed to toad CP/M - error al cargar CP/M tras |CPM, o no hay un disco de sistema valido PARTE II -------- DEL CPC AL SPECTRUM A modo de repaso: Sentencias BASIC comunes a Amstrad, Spectrum y Microsoft: PRINT, INPUT, CLS, RUN, POKE, DIM, GOTO, GOSUB, LIST, FOR, TO, STEP, NEXT, RETURN, IF, THEN, REM, POKE, NEW, SAVE, LOAD, MERGE, CLEAR, LET, SIN, COS, TAN, INT, STR$, CHR$, PEEK, TAB, ATN, ABS, SQR, VAL, LEN, EXP, INKEY$, RANDOMIZE, DATA, RESTORE, READ, RND, LINE, DEF FN, FN, OUT, AND, OR, NOT y USR. Sentencias comunes entre Amstrad y Spectrum: BORDER, CAT, INK, PAPER, PLOT, DRAW y PI Sentencias exclusivas de Amstrad (inexistentes en el Spectrum): AFTER, CLG, DEG, DI, EI, EVERY, INKEY, LOWER$, MAX, MEMORY, MIN, MODE, ORIGIN, PEN, RAD, RELEASE, REMAIN, ROUND, SPEED, SQ, SYMBOL, TAG, TAGOFF, UNT, UPPER$, ZONE, KEY, KEYDEF, CREAL, JOY, ENT, ENV, TEST, TESTR, LOG10, FRAME, VPOS, FRAME y HIMEM. Sentencias de Amstrad (con equivalente posible en el Spectrum): &X, DRAWR, PLOTR, MOVE, MOVER, XPOS, YPOS, DERR, OPENIN y OPENOUT Sentencias comunes entre Amstrad y Microsoft: CALL, CHAIN {MERGE}, CONT, END, LOCATE, LOG, LEFT$, MID$, RIGHT$, RESUME, SPACE$, SPC, ASC, FIX, INP, SOUND, WAIT, WEND, WRITE, WIDTH, POS, CINT, ERASE, ERR, ERL y ERROR. Sentencias comunes entre Amstrad, Beta Basic y Microsoft: AUTO, DELETE, EDIT, RENUM, ELSE, HEX$, ON, ON ERROR, STRING$, INSTR, WHILE, TIME, EOF, XOR, TRON y TROFF. Sentencias comunes entre Amstrad y Beta Basic: BIN$, FILL y WINDOW. EL TECLADO Posee las sigtes. teclas especiales: AMSTRAD CPC SPECTRUM +3 -------------------------------------------------------- RETURN - RETORNO - ENTER INTRO - ENTER - (no existe) <- BORR - BORRA RETROCEDIENDO - DELETE (C.Shift + 0) MAYS - CAPS MAYUSCULAS - CAP SHIFT FIJA MAYS - CAPS LOCK - (C.Shift + 2) CONTROL - MODO EXTENDIDO (C.Shift + Symbol S.) CLR - CLEAR BORRA AVANZANDO - (extendido + symbol + k) ESC - ESCAPE - BREAK (C.Shift + espacio) - modo Gráficos (C.shift + 9) Características del Basic de Amstrad: A diferencia de otros BASICs, el Basic de Locomotive, no permite omitir los espacios etre las sentencias y sus parámetros. Por ejemplo, print1 devolvería 1, incluso en Basic 128k del mismo modo que pasaría en Basic de Commoodore o cualquier compatible Microsoft. En un CPC devuelve error de sintaxis. Usa -1 para cierto y 0 para falso. Al sistema le es indiferente si se tipea ya sea en minúscuas o en mayúsculas, tanto las palabras reservadas del Basic como las variables. Acepta nombres de variables largos tanto de cadenas como numéricos. Tiene una gran cantidad de comandos gráficos y modos, pero carece curiosamente de la sentencia CIRCLE. Las únicas sentencias comunes con las del Spectrum difieren en lo que a sintaxis se refiere. Posee CHAIN MERGE pero sin COMMON. El AMSDOS (sistema operativo de discos de Amstrad) es bastante parco en cuanto al número de sentencias de disco. No hay VERIFY ni instrucciones para copiar archivos del disco. Hay que acceder al CP/M para poder formatear o copiar discos y archivos. Con |ren,"new","old" se renombran ficheros y con !era,"name" se eliminan. Los nombre de archivos usan la norma CP/M de 8 caracteres más el punto y la extensión opcional de 3 caracteres. Las únicas extensiones válidas y que tienen sentido para el BASIC son BAS y BIN. BAK es creada por defecto por el sistema cuando se vuelve a salvar un programa. Mientras COM y SUB son exclusivas del CP/M. Solamente parece trabajar con ficheros secuenciales, el manual no menciona nada respecto a ficheros directos o indexados. Hay en cambio instrucciones para manejar el disco RAM pero solo para ficheros de datos, no programas. COLORES: Los números de color estan diapuestos de manera que en pantallas monocromaticas, cuanto mas alto sea el numero, mas brillo aparezca. Los numeros de color y los colores producidos (en una pantalla adecuada) son: 0 - NEGRO 1 - AZUL 2 - AZUL BRILLANTE 3 - ROJO 4 - MAGENTA 5 - MALVA 6 - ROJO BRILLANTE 7 - PURPURA 8 - MAGENGA BRILLANTE 9 - VERDE 10 - CIANO 11 - AZUL CIELO 12 - AMARILLO 13 - BLANCO 14 - AZUL PASTEL 15 - NARANJA 16 - ROSA 17 - MAGENTA PASTEL 18 - VERDE BRILLANTE 19 - VERDE MAR 20 - CIANO BRILLANTE 21 - LIMA 22 - VERDE PASTEL 23 - CIANO PASTEL 24 - AMARILLO BRILLANTE 25 - AMARILLO PASTEL 26 - BLANCO BRILLANTE Características del Basito Tal como afirma su autor, esta versión carece de todos los comandos referentes a gráficos de alta resolución y sonido. Intentar usarlos devuelve el mensaje de que no está implementado ("UNPLIMENTED"). Otras sentencias y funciones como PI, devuelven en cambio error sintáctico ("SYNTAX ERROR"). También están los que dan comando desconocido ("UNKNOWN COMMAND"). Por el contrario algunas sentencias aceptadas como MODE o ZONE simplemente no hacen nada. El CPC permite mover el cursor por toda la pantalla. BASITO no permite eso, a medida que avanza el cursor hacia abajo, ahí queda el cursor. Actúa más como el Apple ][. Otros efectos del teclado son: Ext + C.Shift + 3 = Break + 9 = va al inicio de la línea Algunas teclas en modo EXT + Shift generan un caracter o dígito en modo inverso. Debido a que CONTROL + tecla genera un gráfico en la CPC, aquí da generalmente espacios, en cambio las teclas I,J,K,L y M cumplen su función como en CP/M. Las flechas de izquierda y derecha cumplen su función. Las de arriba y abajo, en cambio hacen salto al comienzo y fin de la línea respectivamente. Los códigos del 0 al 15 generan un ? en pantalla. Los del 16 al 22 provocan ya sea un cuelgue o un reset. El 23 genera un raro efecto pero no cuelga. Del 24 al 31 también da el signo ?. Del 128 al 164 estan los gráficos y UDGs del Spectrum. Del 165 al 234, se repite el juego de caracteres pero en inversa, siendo las últimas 5 de la 'a' a la 'e' en minúsculas, faltando todo lo demás, ya que del 235 al 255 son los mismos UDGs, ni siquiera un segundo set. En un CPC real, a partir del código 128 están todos los símbolos gráficos de Amstrad. EN SUMA Volviendo al comienzo, el archivo descargado está en formato TGZ, ni siquiera en ZIP o RAR. Encima dentro contiene un TAR. Una vez "desTARreado" ya tenemos el archivo "basitop3.dsk". Elijo REALSPECTRUM y lo cargo en modo +3. Veo el CATalogo del disco y encuentro dos archivos: disk y basito.p3d. Este último es un binario. Una vez ejecutado aparece en pantalla en fondo azul con letras amarillas: basito-(C)2008-2021 Julian Albo 20567 free bytes Ready Y la máquina está ahora esperando a que uno tipee algo válido para el sistema. Lo primero que noto es que solamente me deja 20k libres contra los 42 y pico de RAM libre que el CPC real le deja al usuario. Esto me deja con varias limitaciones, la primera es la cantidad de RAM disponible, la otra es la ausencia de sentencias gráficas, matrices tanto numéricas como de cadena. Y por último no hay DEF FN. Si VAL operase como el del Spectrum, entonces podría definir cadenas como se hace con el ZX81. Pero no, no tengo ni eso. Paso a probar las sentencias una a una y los resultados son: - DEFSTR funciona como se espera. - BORDER, PAPER, INK y PEN operan con los colores básicos del Spectrum. - No hay información sobre qué posiciones de RAM tengo accesibles, hay que hacer prueba y error para ver donde alojar alguna rutina en C.M. - CHAIN MERGE puede ayudar a paliar el problema de la poca memoria dividiendo un programa grande en varias partes. - En cuanto a los comandos de disco, aparte de CAT, SAVE, LOAD y MERGE, tengo la posibilidad de crear ficheros OPEN/CLOSE. - Otros comandos válidos del AMSDOS aceptados por BASITO, son: |dir{,"letra:nombre.ext"} - hace lo mismo que CAT pero con más opciones |user,n - donde n = un valor de 1 a 15, selecciona el usuario n |drive,"letra" - donde letra = A, B o M, selecciona la unidad a usar por defecto. - !ERA y !REN son rechazados, así que no hay modo de renombrar o eliminar ficheros. Tampoco son aceptados |disc o |tape para cambiar de cinta a disco y viceversa. - en modo G se pueden tipear los gráficos y UDGs del Spectrum, pero las teclas V y W generan espacios, X parece provocar un ENTER, Y y Z dan # y $ en inverso. Con 9 o EXT se sale del modo G. - mientras ESC detiene la ejecución de un bucle FOR, BREAK no hace lo mismo en BASITO. El bucle ignora la pulsación de Break y sigue hasta completarse. - algunos signos y letras en inversa parecen generar comandos. Por ejemplo, EXT + Symbol + 1 da I en inversa, si pulso ENTER da Break igual que tipear STOP. - se pueden salvar pantallas mediante SAVE "nombre.bin",B,16384,6912 como lo haría SAVE CODE o SAVE SCREEN$, pero cargarlo solo con tipear LOAD "nombre". Tras todo esto, ya creo tener una idea de como sacarle el máximo provecho a esta versión de Basic. No queda otra que limitarnos a juegos que usen SYMBOL y PRINT para crear y mover figuras en pantalla de modo texto. Ahora a falta de un DIM numérico, la única solución es almacenar los números en una variable de cadena, la cual tendría que ser troceada mediante MID$, o con LEFT$ y RIGHT$ y convertida luego con VAL. En cuanto a las matrices de cadena, se tendría que hacer algo similar. La única limitación es que el máximo de caracteres de una variable alfanumérica es de 255. Eso nos da 25 numeros de 10 dígitos o 25 palabras de 10 caracteres c/u. Y 51 números de 5 digitos. A continuación un programa ejemplo: 5 DIM h(20) 10 FOR i=1 TO 20 20 READ h(i) 40 NEXT 50 DATA 4,5,6,7,8,9,10,11,12,13 60 DATA 1,2,3,14,15,16,17,18,19,20 Sin DIM, ese listado se convierte en: 5 a$="" 10 FOR i=1 TO 20 20 READ h 30 b$=STR$(h) 32 IF LEN(b$)=2 THEN b$="0"+RIGHT$(b$,2) 33 IF LEN(b$)=3 THEN b$=RIGHT$(b$,2) 34 a$=a$+b$ 40 NEXT 50 DATA 4,5,6,7,8,9,10,11,12,13 60 DATA 1,2,3,14,15,16,17,18,19,20 Para salvar la información al disco: 100 OPENOUT"nums.dat" 110 WRITE #9,a$ 120 CLOSEOUT Y para leer los datos: 150 OPENIN"nums.dat" 160 INPUT #9,b$ 170 CLOSEIN 210 FOR i=1 TO 20*2 STEP 2 220 h=VAL(MID$(b$,i,2)) 230 PRINT h 240 NEXT Ya que no puedo usar sentencias Basic para dibujar supongo que habrá que recurrir a rutinas en C.M. y ver qué pasa. Ahora ya solo me queda ver si llega a salir alguna versión nueva del BASITO. Ya que sería muy tedioso convertir un programa de CPC con todas las limitaciones existentes. En cambio crear un programa desde cero tal vez no tanto. No importa que no le añada las sentencias gráficas, ya que de hacerlo éstas estarían limitadas a la única más alta resolución del Spectrum con todo y color clash. En cambio, implementar DIM, PI y DEF FN o DEFREAL sería más atractivo. Claro que una versión del Basic CPC de tipo entero no esta mal si aparte se usase un compilador del código fuente. Es decir tipeas el programa en BASITO, y lo pruebas a ver que tal corre. Salvas el fichero .BAS, sales del programa y luego cargas la utilidad que lo compile y listo. Tampoco interesa que carezca de los comandos del "banco de datos" con los que el CPC maneja el disco RAM. Ya que esta versión permite usar ficheros OPEN con la unidad "m:" del +3. Tras comparar el AMSDOS con el +3Dos, se puede concluir que con el +3, AMSTRAD sí se lució, pues ofrece más sentencias para el manejo de disco como formatear, copiar, renombrar o eliminar todo desde el BASIC a diferencia del CPC que debe de recurrir al CP/M para todo esto último. Y ni hablar del manejo del disco RAM. He intentado leer otras imágenes de disco formateadas con el +3, pero BASITO no parece reconocerlas. He elegido copiar el DSK que lo contiene ya que con ese DSK, CAT si funciona como se espera. Ahi he salvado y leido correctamente. Pero para renombrar y borrar datos tendré que recurrir al +3Dos. Mi otro dilema es acostumbrarme a separar las sentencias mediante espacios. A cada rato me da error cuando tipeo "edit10" por ejemplo en vez de "edit 10" o "goto5" en vez de "goto 5". En otros BASICs eso no pasa. NOT FOUND llama a su programa un Basic Frankenstein, pero en mi opinión ese titulo se lo ganó hace mucho el Basic de Locomotive ya que algunas sentencias como las de color son parecidas a las del Spectrum, mientras la mayoría de instrucciones y funciones son tipicamente Microsoft, salvo en lo que a comandos gráficos, sonido y manejo de ficheros se refiere. En cuanto a portar los programas en BASIC del CPC al Spectrum, solamente lo que es más estandar o Microsoft es facil de convertir. Los gráficos y sonido hay que buscar sus equivalentes. Ni qué decir de sus comandos de manejo de fichero, el Microdrive y la IF1 ofrecen más sentencias en comparación y todas las sentencias de disco y de cinta tienen su equivalente en el Spectrum. (c)2021 zx_if1@hotmail.com