RE:Crear el clrscr de cero
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.