Pascal/Turbo Pascal - Crear el clrscr de cero

 
Vista:

Crear el clrscr de cero

Publicado por Eduardo Lapaz (1 intervención) el 17/08/2008 02:32:44
He estado buscando en la web algo de ayuda, porque tengo entendido que puedo aprovechar que se puede importar código assembler al pascal, y supongo que la funcion clrscr() no debe ser dificil de definir. Me interesa puntualmente no depender de importar otras librerias como crt, sino poder ingeniarmelas para hacer las cosas o por lo menos tener una idea de que hay atras, es por esto que quiero crear esa funcion. intente pasar un codigo que tengo para limpiar la pantalla en assembler pero me da error 216 =/ si alguien tiene idea de como hacer esto sin mucha complicacion agradezco su ayuda
atte Eduardo Lapaz.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Crear el clrscr de cero

Publicado por Miguel (159 intervenciones) el 17/08/2008 03:06:28
Eduardo, estaria bueno que subas el codigo que implementaste, a lo mejor es un error menor.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Crear el clrscr de cero

Publicado por Diego Romero (996 intervenciones) el 17/08/2008 05:37:25
Hay varias formas de hacerlo usando ensamblador (de hecho, hay formas de hacerlo sin usar ensamblador pero supongo que lo que se busca es velocidad).

En primera, no hay un "servicio directo" que haga la tarea.

Una forma es no usando crt sino la unidad dos:
uses dos;
...
procedure cls;
var
regs: registers;
begin
FillChar(regs, sizeof(regs),0);
regs.ah:=$00;
regs.al:=$03;
intr($10,regs);
end;

Lo que se hace es limpiar todos los registros programables, poner $00 en el registro AH y $03 en el AL, y llamar a la interrupción $10, esto quiere decir que se vuelve a poner la pantalla en modo 80x25, que es el estandar en DOS (si se necesita el modo 40x25, mover $01 en AL) con el buffer vacío. Limpio, rápido y facil.

Pero tiene una pega, necesitas la unidad dos.

Lo mismo se puede hacer sin usar la unidad dos ejecutando directamente en ensamblador:

procedure cls2;
begin
asm
mov ah,00h;
mov al,03h;
int 10h;
end;
end;

La pega con este método es que no se asegura que se ejecute con el buffer vacío, en la mayoría de los casos esto no es un problema.

Otra forma de hacerlo es simplemente provocar un scroll de la pantalla completa. Esto se puede hacer usando el servicio 06h de la interrupción 10h. El problema es que hay que establecer la pantalla completa en modo ventana y eso implica pasarle los parámetros adecuados a la interrupción. En el registro CX se le pasa la coordenada de la esquina superior izquierda y en el registro DX la esquina inferior derecha. O sea:

mov cx,0h;
mov dx,184fh; { esto es lo mismo que mov dh,18h y mov dl,4fh, o sea 24,79 }

Lo que convierte toda la pantalla en una ventana.
Luego se establece la cantidad de líneas a mover y llamamos al servicio:

mov al,0h; { cero quiere decir "toda la ventana" }
mov ah,06h; { servicio de "scroll" }
int 10h;

Resumiendo:

procedure cls3;
begin
asm
mov cx,0h;
mov dx,184fh; { esto es lo mismo que mov dh,18h y mov dl,4fh, o sea 24,79 }
mov al,0h; { cero quiere decir "toda la ventana" }
mov ah,06h; { servicio de "scroll" }
int 10h;
end;
end;

La pega con este método es que el cursor no se va a la esquina sino que permanece abajo. La otra es que la pantalla toma el color de fondo que tenía el caracter que estaba en la esquina inferior derecha. Es decir, que si ese caracter estaba con fondo azul, toda la pantalla se pone azul; esto puede ser un problema o no, dependiendo de los gustos de cada uno :P.

Una forma que se me ocurre de solucionar esto es pasando cero (0h) al registro BX antes de llamar al servicio... pero no tengo tiempo para probarlo xD.

Espero haber sido de utilidad.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar