CLS para DOS

Si programar VERIFY para DOS en ensamblador fue sencillo, hacer lo propio con CLS lo fue aún más. Aquí partimos nada menos que de CLS.C, el desarrollo de Jim Hall (fundador de FreeDOS y que creó entre 1994 y 1998.

CLS para DOS

La gracia de su CLS en la versión 2.01 es que soportaba redirecciones. Es decir, que si la salida estándar (stdout) estaba redirigida, entonces “borraba” su visualización usando secuencias de escape ANSI. Es un comportamiento bastante extraño, pero que por motivos de compatibilidad se implementa a nivel de COMMAND.COM tanto en MS-DOS 7.10 como en DR DOS 7. DOSBox lo replica, si bien resulta curioso que en una consola de Windows o en 4DOS 8.00 esto no ocurra.

Con todos mis respetos, lo que no me encajaba de esa implementación era de nuevo usar C para algo de tan bajo nivel y tan trivial como esto, pero menos aún, basarse en clrscr() que ni es portable ni está disponible en la mayoría de compiladores. A modo de ejemplo, mientras que en Borland es clrscr y está en conio.h, en Microsoft y Watcom se llama _clearscreen() y está en graph.h. Tal vez programarlo usando int86 para invocar a la BIOS directamente me habría gustado más.

Lo cierto es que ya que me puse, esas 44 líneas originales sin comentarios que se compilaban con Turbo C a un ejecutable CLS.EXE de 9.048 bytes. Mi conversión a ensamblador son unas 80 líneas, pero generan un ejecutable CLS.COM de solamente 380 bytes.

Aunque me lo planteaba mucho más sencillo y rápido que el mencionado VERIFY, en realidad me llevó casi una hora de tiempo hacerlo. El motivo fue programar el borrado de pantalla. La BIOS nos permite borrar la pantalla con el simple truco de hacer scroll de una región de la misma de 0 líneas, no importa si es hacia arriba o hacia abajo; desplazarla 0 filas implica borrar esa región. Sin embargo ello requiere conocer las características del modo actual, la cantidad de filas y columnas que tiene disponible, además de que probablemente no funcionase en los modos gráficos. Adicionalmente habría que mover el cursor a su posición inicial (0,0) etcétera. El “workarround” que conozco desde mis inicios de BASIC es que cuando cambias el modo de pantalla, automáticamente se borra todo su contenido y se resetea el cursor. No había más que obtener el modo actual, y entonces invocar a los servicios 10h de la BIOS para volver a poner el mismo.

Como siempre os pegaré el código fuente de la versión original, y mi conversión con UASM, pero antes, podéis descargar directamente el ejecutable y código fuente (1 KB. en formato ZIP), también disponible en Sourceforge.

/* cls.c */

/* Clears the screen.  No longer will set the colors. */

/*
  Copyright (C) 1994-1998 Jim Hall, jhall1@isd.net

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#include 
#include 				/* for exit() on borland */

#include 				/* for conio on borland */
#include 					/* for isatty on borland */

void usage (const char *progname);


int
main (int argc, char **argv)
{
  int out;
  out = fileno (stdout);

  /* Check command line */

  if (argc > 1)
    {
      usage ("CLS");
      exit (0);
    }

  /* Clear the screen */

  if (isatty (out))
    {
      clrscr();					/* borland */
    }

  else
    {
      printf ("");				/* standard ANSI sequence */
    }

  exit (0);
}


void
usage (const char *progname)
{
  fprintf (stderr, "%s: clear the screen\n", progname);
  fprintf (stderr, "Usage: %s [/?]\n", progname);
}
;--------------------------------------------------------------------------------------------------------------------------------------------------------------
.model tiny
.stack 64
.code
org 100h


;--------------------------------------------------------------------------------------------------------------------------------------------------------------
.startup

;Parse command-line options
mov al, byte ptr ds:[80h]
;We have arguments
.if al > 0
	call ShowHelp
.else
	call DoIt
.endif
.exit



;--------------------------------------------------------------------------------------------------------------------------------------------------------------
;Enable/Disable in AL
DoIt proc
	;Check if stdout is redirected
    mov ax,4400h
    mov bx, 1	;1=Standard output device (Stdout)
    int 21h
	mov ax, dx
    and ax, 80h
	.if (ax != 0)
		;Set videomode to current mode
		mov ah, 0fh
		int 10h
		xor ah, ah
		int 10h
	.else
		;Use ANSI sequence
		mov dx, offset acAnsiCls
		call PrintText
	.endif
	ret
DoIt endp

;--------------------------------------------------------------------------------------------------------------------------------------------------------------
ShowHelp proc
	mov dx, offset acCopyright
	call PrintText
	
	mov dx, offset acCrLf
	call PrintText
	
	;Return
	mov al, -1
	ret
ShowHelp endp


	
;--------------------------------------------------------------------------------------------------------------------------------------------------------------
;Text in DX
PrintText proc uses ax
	mov ah, 9
	int 21h
	ret
PrintText endp

;--------------------------------------------------------------------------------------------------------------------------------------------------------------
.data
acCopyright		db 13, 10
				db "CLS R1.00                          (c) 2022 by Javier Gutierrez Chamorro (Guti)", 13, 10
				db "Clears the screen.", 13, 10, 10
acHelp			db "Syntax is: CLS [-h]", 13, 10, 10
				db "Examples:", 13, 10, 10
				db "	CLS -h", 13, 10
				db "	Shows this help screen.", 13, 10
				db "	CLS", 13, 10
				db "	Clear screen in current video mode.", 13, 10, 10
				db "More information at:", 13, 10
				db "	http://nikkhokkho.sourceforge.net/static.php?page=CLS", 13, 10
acCrLf			db 13, 10, '

acAnsiCls		db "$"
end

20 comentarios en “CLS para DOS”

  1. Me da que los que entendemos lo de llamadas a la interrupción 21h ya peinamos (o lo que quede) canas. Muy compacto el resultado.

  2. Javier Gutiérrez Chamorro (Guti)

    Es realmente interesante, porque las interrupciones, al menos las de BIOS siguen ahí, pese a que tienen tantas capas de software por encima que ya nadie es consciente de ellas Torsan.

  3. Javier Gutiérrez Chamorro (Guti)

    Hola Dr. Daniel. En estos últimos meses te he enviado varios emails. Todos me rebotan diciéndome que tienes el buzón lleno. Lo que ha pasado con ZonaCasio es que ha sido reportado como spam a blogger y ahora lo están intentando recuperar. En el canal de Telegram van publicando las novedades: https://t.me/zonacasio

  4. Lo ocurrido a Zona Casio no me sorprende. A mí me han suspendido un dominio por razones parecidas, por que sí.

    En concreto, a mí se me acusa de utilizarlo para hacer phishing y enviar malware. Acusación falsa y sin pruebas: el dominio estaba aparcado, esto es, no lo estaba utilizando.

    Es algo análogo a que te pongan una multa por exceso de velocidad a pesar de que demuestres, aportando una factura, que ese día tu coche estaba en el aparcamiento del aeropuerto.

    Estos tipos – gigantes como Google o registradores de dominios – primero disparan y luego preguntan. Y en caso de que les demuestres su error, les entra por una oreja y les sale por otra. Por otra parte, de compensaciones por los perjuicios ni hablar; ni aún en el caso de que hayas pagado por el servicio.

  5. Javier Gutiérrez Chamorro (Guti)

    Ciertamente un relojista. Aunque pueda parecer que la tecnología nos ha democratizado, al final estamos siempre a expensas de los proveedores, sean “gratuitos” o de pago.

  6. Dado que Telegram solo es una vía de una única dirección (se pueden enviar mensajes pero no responder), solo comentar a lo dicho por Guti que también la dirección de http://www.zonacasio.com apunta ahora al canal de Telegram (no tenía sentido que siguiera apuntando a blogspot).

    No sé qué ha ocurrido con el blog, o sea, yo soy el primer sorprendido porque como bien comenta Un Relojista, aquí nadie da explicaciones de nada (y por supuesto ni preguntes quién ha reportado el blog). Lo que me sorprende que se puedan cargar de un plumazo un trabajo de más de diez años, pero efectivamente así actúan esas compañías (nos ocurrió con Twitter y con Facebook, por cierto, tras tener grupos de varios miles de personas que en caso de Facebook eran alrededor de 20.000, y tras pedirnos documentos y marearnos, no conseguimos recuperarlo).

    Lo único que os puedo decir es daros las gracias a todos por vuestra preocupación y vuestra ayuda, que han sido muchas las muestras de apoyo que hemos recibido en el correo. Nos gustaría recuperar el blog, no ya para volver o no volver (que eso ya veremos), pero al menos para dejarlo online a disposición de todos los interesados, pero por desgracia eso no está en nuestras manos ahora mismo.

  7. Una verdadera lastima, porque yo he vuelto a la afición Casio este mismo año y ZonaCasio era un filón de información que tenía a golpe de click. Haber si hay alguna forma de recuperar la web y poder mover la info.

  8. Buenas noches Z. Casio, lo lamento muchísimo. De hecho esta tarde lo hablaba con Javier… No entiendo de estas cosas nada… pero me parece una cabronada tipo régimen totalitario. Esos dicen que son adalides de la libertad… tócate las narices con papel de lija del 12.
    No sé como luchar contra estos gigantes pero si hace falta mala leche…. pues a por ellos.
    Una abrazo Z.Casio.

  9. Javier Gutiérrez Chamorro (Guti)

    Muy útil el hacer que el dominio apunte a Telegram ZonaCasio, así podremos estar actualizados de vuestros progresos… Y de nuevo, esperando que al menos el contenido se pueda recuperar.

    La situación es abusiva, tal vez legal según los términos de servicio, pero abusiva. Y me explico, es el trabajo de más de 10 años de ZonaCasio, si Google considera que no debe estar ahí, pues que elimine aquello que no le guste, pero no que cierre todo. Es más, si decide cerrarlo, al menos que mantenga vuestro acceso privado de manera que podáis descargar el material que a fin de cuentas os pertenece.

  10. Javier Gutiérrez Chamorro (Guti)

    Lo comparto contigo Videtti. Zona Casio me ha acompañado en multitud de jornadas de lectura, me ha entretenido y me ha enseñado. Un recurso enormemente valioso para todos los aficionados a la marca. Espero que estos incidentes nos hagan valorar con más motivo el mérito que tiene llevar a cabo una iniciativa como esa.

  11. Javier Gutiérrez Chamorro (Guti)

    A mi me sorprende mucho ese funcionamiento automatizado Sergi. Con las cifras de Zona Casio estoy seguro que no habrá muchos blogs que lo superen en audiencia. Además con una historia intachable que debería ser suficiente para que cualquier operador lo verificase y descartase el reporte de spam.

  12. Una duda
    Quick c (ide) (Microsoft) es compatible con el c compiler 5 de Microsoft ? Y el asm inline debería funcionar en los dos sin masm?

    Saludos

  13. Javier Gutiérrez Chamorro (Guti)

    Bienvenido Ubuntu Peronista. Como dice el artículo depende de la versión. En efecto QuickC 1.0 estaba basando en MSC 5, así que son compatibles. Versiones posteriores basadas en MSC 6, lo serán bastante, pero siempre había alguna historia, en particular con el optimizador.

  14. Tienes un magnífico sitio, te felicito por todo ese esfuerzo, y te agradezco por la valiosa información ofrecida.

    A mí también me gustan todos esos temas de la retroinformática, y los demás, me gustan los programas antiguos, y en mi propio blog he puesto algo de eso, aun cuando no tengo mucho contenido, ni demasiadas habilidades.

    En este tema en particular me propuse crear paso a paso una GUI a mi manera usando QBasic: https://cubansolutions.blogspot.com/2021/11/diseno-e-implementacion-de-una-gui.html

  15. Javier Gutiérrez Chamorro (Guti)

    Bienvenido pcarballosa. No suelo aceptar enlaces en esta página puesto que considero que suelen ser spam. No obstante tras haberme descargado las 8 entregas en formato PDF veo que has hecho un excelente y enorme trabajo que bien merece la pena difundir. Me permito hacerte dos sugerencias. La primera es que hagas un PDF único con todas las partes; la segunda es que quizás valdría la pena que publicaras el código en github o sourceforge, básicamente para que no se pierda. Incluso podrías compilarlo con QuickBASIC o PDS generando un EXE y que sea más fácil de probar.

  16. Hola, Guti.

    Te agradezco la recomendación y trataré de hacerlo como dices más adelante, porque todavía no he publicado una parte del tutorial en mi blog, por eso no está completa ni la primera parte, aunque casi todo eso nada más necesita ser revisado para publicarlo.

    En este otro enlace tengo puesto una demostración de una calculadora simple hecha con la GUI a pesar de no tener todavía en su código todo lo necesario para gestionar los textbox por completo, dado nada más uso uno como pantalla de la calculadora para mostrar texto y no como entrada de datos: https://5minutos.cu/tema/como-hacer-una-calculadora-con-interfaz-grafica-para-dos.11093/

    El artículo anterior también forma parte del tutorial en lo fundamental, no obstante, como te comenté, no lo he publicado todavía en mi sitio para seguir el orden.

    Por cierto, el presente comentario no es obligatorio publicarlo, sólo pongo la url para tu consumo cuando lo revises, pero tal vez también te interese ese foro, incluso cuando no es especializado y la gente habla de muchos temas indistintamente.

    Te doy las gracias una vez más por tus palabras.

Deja un comentario