microcontroladores
Reconocer y generar una orden
Este primer acercamiento reconocerá sólo la orden CLS, encargada de borrar la pantalla. La orden en lenguaje ensamblador de un Amstrad CPC equivalente es CALL &BB6C, que en código máquina sería la secuencia de bytes CD, 6C, BB (expresados en hexadecimal).
Para simplificar la prueba de los programas destino creados, el compilador no generaráensamblador. Ni siquiera creará un fichero ".BIN" de código máquina, sino un fuente en Basic capaz de "generar ese código máquina". Así, para una única orden CLS, se obtendría el siguiente programa, que lee los bytes en hexadecimal, los coloca a partir de la dirección 40.000 de la memoria y finalmente llama a esa dirección para poner el programa en marcha:
10 DATA CD,6C,BB: ' CALL &BB6C
20 DATA C9: 'RET
30 longitud = 3
40 MEMORY 39999
50 FOR n=40000 TO 40000+longitud
60 READ a$:POKE n,VAL("&"+a$)
70 NEXT
80 CALL 40000
Con todas estas consideraciones, el primer acercamiento al compilador es muy sencillo:
Un procedimiento que obtiene una orden (sólo una) del usuario, desde el teclado.
Un procedimiento que analiza la orden, y da un mensaje de error si no es CLS.
Unprocedimiento que genera el código de destino (que por ahora es fijo).
El fuente sería así:
program cpcPaChi;
(* Un compilador de Pascal chiquitito para CPC
Version 0.01, preliminar
Versiones hasta la fecha:
Num. Fecha Cambios
---------------------------------------------------
0.01 21-Mar-2008 Preliminar: solo acepta CLS por teclado
y genera el codigo correspondiente
*)
var
ficheroDestino: text;
orden: string;
(* Obtiene una orden del programa fuente. En esta version, solo
es una unica orden, y solo se admite "CLS" *)
procedure obtenerOrden;
begin
write('Introduzca la orden a traducir: ');
readln(orden);
end;
(* Analiza la orden que el usuario ha dado, y sale con un mensaje
de error si esincorrecta *)
procedure analizarOrden;
begin
if upcase(orden) 'CLS' then
begin
writeln('Error: orden no reconocida. Se esperaba: CLS');
halt;
end;
end;
(* Genera el codigo de destino: codigo maquina de Amstrad CPC
dentro de un cargador en Basic *)
procedure generarCodigo;
begin
assign( ficheroDestino, 'salida.bas' );
rewrite( ficheroDestino );
writeln(ficheroDestino, '10 DATA CD,6C,BB: '' CALL &BB6C' );
writeln( ficheroDestino, '20 DATA C9: '' RET' );
writeln( ficheroDestino, '30 longitud = 3' );
writeln( ficheroDestino, '40 MEMORY 39999' );
writeln( ficheroDestino, '50 FOR n=40000 TO 40000+longitud' );
writeln( ficheroDestino, '60 READ a$:POKE n,VAL("&"+a$)' );
writeln( ficheroDestino, '70 NEXT' );
writeln( ficheroDestino, '80CALL 40000' );
close(ficheroDestino);
end;
(* Cuerpo del programa *)
begin
obtenerOrden;
analizarOrden;
generarCodigo;
end.
(2 - Varias órdenes, con parámetros y desde fichero)
Este segundo acercamiento va a reconocer dos órdenes más: WRITECHAR, que escribirá una única letra en pantalla, y LOCATE, que moverá el cursor a otras coordenadas de pantalla. Además, envez de aceptar una única orden por teclado, leerá varias desde disco.
Así, aceptará programas como éste:
cls
locate(10,5)
writeChar('a')
locate(1,10)
writeChar('b')
El hecho de que el usuario indique el nombre del fichero no es mucha complicación: vemos con "paramcount" si realmente lo ha detallado, avisamos si no lo ha hecho, y leemos el nombre con "paramstr(1)" en caso contrario:
ifparamcount >= 1 then
nombreOrigen := paramstr(1)
else
begin
writeln('No se ha indicado el nombre del fichero');
halt;
end;
assign( ficheroOrigen, nombreOrigen );
reset( ficheroOrigen );
En cuanto a la traducción de writeChar('a'), se convertiría en dos órdenes de ensamblador: LD A, &61; CALL &BB5A. El primer problema es que tenemos que crear un código que no será siempre el...
Regístrate para leer el documento completo.