/*
 *  CLS.C - clear screen internal command
 *
 *  Comments:
 *
 *  07/27/1998 (John P. Price)
 *    started.
 *
 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 * - added config.h include
 *
 * 30-Nov-1998 (John P Price <linux-guru@gcfl.net>)
 * - CLS now sets the text colors to lightgray on black before clearing the
 *   screen.
 *
 * 06-Jun-2006 (Jacob Persico <JacobPersico@gmail.com>)
 * bugfix: CLS only cleared first 25 lines.
 * + Added optional attribute setting.
 * bugfix: Caret (text cursor) didn't reset on some pages.
 * + added dos.h include.
 *
 * 19-Jun-2006 (Jacob Persico <JacobPersico@gmail.com>)
 * Changed char to BYTE and moved varible definitions up.
 *
 * You can use this program to change the screen color
 * by providng a two digit hex code as an argument.
 */

#include "../config.h"

#include <conio.h>
#include <dos.h>

#include "../include/command.h"

typedef unsigned char	BYTE;
typedef unsigned short	WORD;
typedef unsigned long	DWORD;

#define TRUE 0x01
#define FALSE 0x00

#pragma argsused
int cmd_cls(BYTE *param)
{

 	// Default Lightgray on black (attribute 0x07)
	BYTE *BIOS=MK_FP(0x0040,0x0000);
	BYTE rows=BIOS[0x0084]+1; // rows (EGA/MCGA/VGA)
	BYTE cols=BIOS[0x004A]; // columns
	BYTE pageNo=BIOS[0x0062]; // current video page number
	BYTE temp;
	BYTE y;
	union REGS r;
	BYTE attrib;
	BYTE attribFlag=FALSE;

	// Skip spaces
	while (*param == 0x20)
	{
		if (*param == 0x00) break;
		param++;
	}
	
	// Set hi 4 bits of attrib
	if (*param > 0x2F && *param < 0x3A)
	{
		attrib=*param<<4;
		attribFlag=TRUE;
	}
	else
	{
		temp=*param & 0xDF;
		if (temp > 0x40 && temp < 0x47)
		{
			attrib=(temp+9)<<4;
			attribFlag=TRUE;
		}
	}

	// Set lo 4 bits of attrib
	if (attribFlag==TRUE)
	{
		attribFlag=FALSE;
		param++;
		if (*param > 0x2F && *param < 0x3A)
		{
			temp=*param & 0x0F;
			attrib=attrib | temp;
			attribFlag=TRUE;
		}
		else
		{
			temp=*param & 0xDF;
			if (temp > 0x40 && temp < 0x47)
			{
				temp=(temp+9) & 0x0F;
				attrib=attrib | temp;
				attribFlag=TRUE;
			}
		}
		param--;
	}

	if (attribFlag==FALSE)
	{
		attrib=0x07;
	}

	// clrscr:
	for (y=0; y<=rows; y++)	// check this
	{
		r.x.ax=0x0920;	// Write space
		r.h.bh=pageNo;
		r.h.bl=attrib;
		r.h.ch=0x00;
		r.h.cl=cols;
		int86(0x10,&r,&r);

		// move caret
		r.h.ah=0x02;
		r.h.bh=pageNo;
		r.h.dh=y;	// Next row
		r.h.dl=0x00;	// Left column
		int86(0x10,&r,&r);
	}
	
	// reset caret (text cursor)
	r.h.ah=0x02;
	r.h.bh=pageNo;
	r.h.dh=0x00;	// Secound row
	r.h.dl=0x00;	// Left column
	int86(0x10,&r,&r);

	return 0;
}
