Pers.narod.ru. Алгоритмы. Пишем на Си функции нижнего уровня |
Ниже приводится листинг, содержащий несколько десятков стандартных и нестандартных функций Си. Главная программа только тестирует функции, причем не все. Внимательный анализ листинга и комментариев поможет извлечь немало полезной при изучении языка информации.
#include <stdio.h>
/* нужна только для printf в демо*/
//////////////////////////////////////////////////Прототипы
#define MODE unsigned char
#define YES 0x01
#define NO 0x00
#define UP_DIR 0
#define DOWN_DIR 1
//Форматы даты:
#define MDY 0
#define MDYY 1
#define DMY 2
#define DMYY 3
#define YMD 4
#define YYMD 5
#define YDM 6
#define YYDM 7
//Клавиши
#define ENTER 0x1C0D
#define LEFT 0x4B00
#define RIGHT 0x4D00
#define UP 0x4800
#define DOWN 0x5000
#define ESC 0x011B
#define PAGE_UP 0x4900
#define PAGE_DO 0x5100
#define HOME 0x4700
#define END 0x4F00
#define BUF_LEN 4000 /* Длина буфера для сохранения экрана */
MODE Buffer[BUF_LEN], /* Буфер для сохранения экрана */
String[129], /* Строка для разбора */
Var[129]; /* Строка окружения */
unsigned BufPos=0;
MODE SetString=NO; // Флаг записи в окружение
MODE WEEKDAY,DAY,MON,HOUR,MIN,SEC, //Дата и время
HIGHDOS,LOWDOS; //Версия DOS
int YEAR;
MODE DateFormat=MDY, FullFormat=YES, //
DateDividor='/',TimeDividor=':'; //Разделители даты и времени
MODE ATTR=0x07; //Атрибут экрана
MODE Col=7,Bk=0; //Цвет и фон экрана
MODE Explode=NO, Shadow=NO, Border=0x02,
Filler=' ', Break=YES, ScrollDir=DOWN_DIR;
MODE MaxCol=80, MaxRow=25, //Размеры экрана
Saver=YES; //Флаг сохранения экрана
MODE RowCursor=0,ColCursor=0, //Позиция курсора
LogDrives=3; //Количество дисков
MODE X1=0,Y1=0,X2=24,Y2=39,
UNS=1,
Arg=0,*Args[24],
Return=0,Byte=0;
static MODE **ArgsPtr=&Args[0];
void Exit (MODE);
MODE FULL=0,
ON=1,
SetEnv=0;
#define MONO_VIDEO 3
#define COLOR_VIDEO80 2
#define COLOR_VIDEO40 1
MODE IsSoprocessor, KolFlops, ActiveVideo, KolPrinters; //HardStatus()
unsigned BaseMemorySize; //HardStatus()
union LONG {
int High,Low;
long Long;
} L;
unsigned strlen_(MODE *);
void ClearBox (MODE x1, MODE y1, MODE x2,MODE y2,MODE attr);
void DrawBox (MODE x1, MODE y1, MODE x2, MODE y2, MODE Type, MODE Fill);
void SetCursor (MODE Row, MODE Col);
void WriteString (MODE *s,MODE attr);
void WritePosString (MODE x,MODE y,MODE *Str,MODE attr);
void Save (MODE,MODE,MODE,MODE);
void Restore (MODE,MODE,MODE,MODE);
MODE GetPopup (MODE x1, MODE y1, MODE kol, MODE **Str,MODE Saver);
MODE GetMenu (MODE x1, MODE y1, MODE kol, MODE **Str,MODE Saver);
int Get_Key(void);
//////////////////////////////////////////////////Работа со строками:
unsigned char UpCase (unsigned char c) {
if (c>96 && c<123 || c>159 && c<176) c-=32; // a-z, а-п
else if (c>223 && c<240) c-=80; // р-я
return c;
}
void UpCaseStr (unsigned char *Str) {
unsigned char c; unsigned i;
for (i=0; ; i++) {
c=*(Str+i);
if (c==0) break;
c=UpCase (c);
*(Str+i)=c;
}
return;
}
int StrCmp (unsigned char *s1, unsigned char *s2, unsigned maxlen) {
//Если maxlen=0, сравнивает как stricmp() - до конца строк,
//иначе как strnicmp()
int j=0; unsigned char c1,c2;
while (1) {
c1=UpCase(*(s1+j)); c2=UpCase(*(s2+j));
if(c1=='\0' || c2=='\0' || (maxlen!=0 && j==maxlen)) break;
if (c1==c2) j++;
else break;
}
if (c1<c2) j=c2-c1;
else if (c1>c2) j=c1-c2;
else j=0;
return j;
}
unsigned char *StrChr (unsigned char *s, unsigned char c) {
while (*s) {
if (*s==c) return s;
s++;
}
return 0;
}
unsigned char *StrRChr (unsigned char *s, unsigned char c) {
unsigned char *p=0;
while (*s) {
if (*s==c) p=s;
s++;
}
return p;
}
unsigned char *StrTok (unsigned char *s, unsigned char *c) {
//Указатель на первый символ s, не содержащийся в c
unsigned char *Ptr;
unsigned j;
for (j=0; *(s+j); j++) {
Ptr=StrChr (c,*(s+j));
if (!Ptr) return (s+j);
}
return 0;
}
void StrSet (unsigned char *s, unsigned char c, unsigned kol) {
//Устанавливает в kol байт строки s значение c
unsigned u;
for (u=0; u<kol; u++) *(s+u)=c;
}
unsigned char IsDigit (unsigned char c) {
if (c>47 && c<58 ) return (1);
return (0);
}
unsigned char IsSpace(unsigned char c) {
if ((c>0x08 && c<0x0e) || c==0x20) return 1;
return 0;
}
unsigned char IsUnsigned (unsigned char *ptr) {
// Проверяет, является ли строка записью целого беззнакового числа
// Возвращает 0 или 1
unsigned char Ret=1;
while (*ptr==' ' || *ptr=='\t') ptr++;
if (*ptr=='\0') return 0;
for (; *ptr; ptr++) if (!IsDigit(*ptr)) { Ret=0; break; }
return Ret;
}
unsigned AtoU (unsigned char *s) {
unsigned n;
for (; IsSpace(*s); s++);
for (n=0;IsDigit(*s);s++) n=10*n+*s-'0';
return n;
}
unsigned StrLen (unsigned char *s) {
unsigned l=0;
while (*s!='\0') { l++; s++; }
return l;
}
void StrRev (unsigned char *s) {
int c; unsigned char *t;
for (t=s+StrLen(s)-1; s<t; s++,t--) {
c=*s; *s=*t; *t=c;
}
}
void UtoA (unsigned n, unsigned char *s) {
unsigned char *t=s;
do { *s++=n%10+'0'; } while ((n/=10)!=0);
*s='\0';
StrRev (t);
}
unsigned char *StrCat (unsigned char *d, unsigned char *s) {
unsigned char *ret=d;
while (*d) d++;
while (*s) *d++=*s++;
*d='\0';
return ret;
}
void StrCpy (unsigned char *d, unsigned char *s) {
while (*s) *d++=*s++;
*d='\0';
}
////////////////////////////////// Клавиатура и экран
int Get_Key (void) {
asm mov ax,0;
asm int 16h;
return _AX;
}
void WritePosString (unsigned char x,unsigned char y,unsigned char *Str,unsigned char attr) {
SetCursor (x, y);
WriteString (Str,attr);
}
unsigned char RevAttr (unsigned char Attr) {
return ((Attr&0x70)>>4)|((Attr<<4)&0x7F);
}
unsigned char GetPopup (unsigned char x1, unsigned char y1, unsigned char kol, unsigned char **Str,unsigned char Saver) {
// Падающее меню; возвращает номер выбора (с 1) или 0 по нажатию ESC
int sim;
unsigned char x2,y2,i,maxlen=0,cursor=0,rev=RevAttr (ATTR);
for (i=0; i<kol; i++) {
sim=StrLen(Str[i]);
if (sim>maxlen) maxlen=sim;
}
x2=x1+1+kol; y2=y1+1+maxlen;
if (Saver) Save (x1,y1,x2,y2);
ClearBox (x1,y1,x2,y2,ATTR);
DrawBox (x1,y1,x2,y2,0x02,0);
x1++; y1++;
for (i=0; i<kol; i++) WritePosString (x1+i,y1,Str[i],ATTR);
kol--;
while (1) {
WritePosString (x1+cursor,y1,Str[cursor],rev);
SetCursor (x1+cursor, y1);
sim=Get_Key();
WriteString (Str[cursor],ATTR);
switch (sim) {
case ESC: cursor=0; goto OUT;
case ENTER: cursor++; goto OUT;
case UP:
if (cursor>0) cursor--;
else cursor=kol;
break;
case DOWN:
if (cursor<kol) cursor++;
else cursor=0;
break;
case PAGE_UP: cursor=0; break;
case PAGE_DO: cursor=kol; break;
}
}
OUT:
x1--; y1--;
if (Saver) Restore (x1,y1,x2,y2);
return (cursor);
}
unsigned char GetMenu (unsigned char x1, unsigned char y1, unsigned char kol, unsigned char **Str,unsigned char Saver) {
//Горизонтальное меню; возвращает номер выбора (с 1) или 0 по нажатию ESC
int sim;
unsigned char x2,y2,i,maxlen=0,cursor=0,rev=RevAttr (ATTR);
for (i=0; i<kol; i++) {
sim=StrLen(Str[i]);
maxlen+=(sim+1);
}
y2=y1+maxlen;
if (Saver) Save (x1,y1,x1,y2);
ClearBox (x1,y1,x1,y2,ATTR);
y1++;
for (i=0,maxlen=0; i<kol; i++) {
WritePosString (x1,y1+maxlen,Str[i],ATTR);
maxlen+=(StrLen(Str[i])+1);
}
kol--; y2=y1;
while (1) {
WritePosString (x1,y2,Str[cursor],rev);
SetCursor (x1, y2);
sim=Get_Key();
WriteString (Str[cursor],ATTR);
switch (sim) {
case ESC: cursor=0;
for (i=0; i<=kol; i++) y2+=(StrLen(Str[i])+1);
y1--;
if (Saver) Save (x1,y1,x1,y2);
goto OUT;
case ENTER: cursor++; goto OUT;
case LEFT:
if (cursor>0) cursor--;
else cursor=kol;
break;
case RIGHT:
if (cursor<kol) cursor++;
else cursor=0;
break;
case HOME: cursor=0; break;
case END: cursor=kol; break;
}
y2=y1;
for (i=0; i<cursor; i++) y2+=(StrLen(Str[i])+1);
}
OUT:
for (i=0; i<=kol; i++) y2+=(StrLen(Str[i])+1);
y1--;
if (Saver) Restore (x1,y1,x1,y2);
return (cursor);
}
////////////////////////////////Тестирование оборудования:
unsigned char PrinterIsReady (unsigned Printer) {
// Проверяет готовность принтера и возвращает 0 OK или 1 ERROR
// Printer=0,1,2 - LPT1/2/3
asm mov ah,2;
asm mov dx,Printer;
asm int 17h;
asm cmp ah,090h; //Не занято и выбрано
asm je OK;
asm cmp ah,010h;
asm je OK;
return 0x01;
OK: return 0x00;
}
unsigned char DriveReady (unsigned char Drive) {
// Выдает стандартную ошибку DOS
asm mov ah,36h;
asm mov dl,Drive; //0-текущий,1-A,2-B и т.д.
asm int 21h;
if (_AX==0xffff) return NO;
return YES;
}
void HardStatus (void) {
//Параметры BIOS
unsigned char H,L;
asm int 11h;
H=_AH; L=_AL;
IsSoprocessor=L&0x02 ? YES: NO;
KolFlops=(L&0x01 ? (((L&0xC0)>>6)+1) : 0);
ActiveVideo=(L&0x30)>>4;
KolPrinters=(H&0xC0)>>6;
asm int 12h;
BaseMemorySize=_AX;
return;
}
unsigned char GetDrive (void) {
//0-A,1-B,...
asm mov ah,19h;
asm int 21h;
return _AL;
}
unsigned char SetDrive (unsigned char Disk) {
//Disk=0 -A,1 -B, ...
//Вернет число логических дисков или LASTDRIVE - что больше
asm mov ah,0eh;
asm mov dl,Disk;
asm int 21h;
return _AL;
}
unsigned char GetDirectory (unsigned char Drive) {
//0-OK,1-ERROR, Путь в Buffer
//Путь не начинается с \ и имени диска
//0-текщий,1-A,2-B,3-C,...
asm mov ax,seg Buffer;
asm mov ds,ax;
asm mov si,offset Buffer;
asm mov ah,47h;
asm mov dl,Drive;
asm int 21h;
asm jnc OK;
return 1;
OK: return 0;
}
unsigned long DiskSpace (unsigned char Drive, unsigned char FreeOnly) {
//Если FreeOnly вернет информацию о свободном месте
unsigned long Volume;
unsigned SecPerClast, FreeClast, BytesPerSec, ClastPerDrive;
asm {
mov ah,36h;
mov dl,Drive; //0-текущий,1-A,2-B и т.д.
int 21h;
mov SecPerClast,ax;
mov FreeClast,bx;
mov BytesPerSec,cx;
mov ClastPerDrive,dx;
}
Volume=SecPerClast*BytesPerSec; //Байт на кластер
if (FreeOnly) Volume*=FreeClast; //В байтах
else Volume*=ClastPerDrive;
if (!FULL) Volume/=1024; //In Kbytes
return Volume;
}
void GetDate (void) {
asm {
mov ah,2ah;
int 21h ;
mov DAY,dl;
mov MON,dh;
mov YEAR,cx;
mov WEEKDAY,al;
}
}
void GetTime (void) {
asm {
mov ah,2ch;
int 21h ;
mov HOUR,ch;
mov MIN,cl;
mov SEC,dh;
}
}
long GetTimer (void) {
//Значение таймера BIOS
asm mov ah,0;
asm int 1ah;
L.High=_CX;
L.Low=_DX;
return L.Long;
}
void SetTimer (long Time) {
unsigned Hi,Low;
Low=Time;
Hi=(Time>>16);
asm mov cx,Hi;
asm mov dx,Low;
asm mov ah,01h;
asm int 1ah;
return;
}
void DosVersion (void) {
asm {
mov ah,30h;
int 21h;
mov HIGHDOS,al;
mov LOWDOS,ah;
}
}
unsigned char SetVideoMode (MODE Mode) {
// 0 -OK, 1-ERROR
asm {
mov ah,0;
mov al,Mode;
int 10h;
mov ah,0fh;
int 10h;
cmp al,Mode;
je OK;
}
return 1;
OK:
MaxCol=_AH;
MaxRow=25;
return 0;
}
unsigned char GetVideoMode (void) {
asm mov ah,0fh;
asm int 10h;
return _AL;
}
void ReadCursor(void) {
asm mov ah,3;
asm mov bh,0; //Page
asm int 10h;
RowCursor=_DH;
ColCursor=_DL;
}
void SetCursor (unsigned char Row, unsigned char Col) {
asm mov ah,02h;
asm mov bh,0; //Page
asm mov dh,Row;
asm mov dl,Col;
asm int 10h;
}
void SetSizeOfCursor (unsigned char Low, unsigned char Hi) {
asm mov ah,1;
asm mov ch,Hi; //Верхняя линия на экране | от 0 до 7
asm mov cl,Low; //Нижняя линия |
asm int 10h;
}
unsigned char ReadChar (unsigned char *a) {
unsigned char c;
asm mov ah,8;
asm mov bh,0;
asm int 10h;
c=_AL;
*a=_AH;
return c;
}
void WriteChar (unsigned char c,unsigned char a) {
//Вывод символа с атрибутом в текущую позицию курсора
//Не перемещает курсор !!!
asm mov ah,9;
asm mov al,c;
asm mov bh,0;
asm mov bl,a;
asm mov cx,1;
asm int 10h;
return;
}
void WritePosChar (unsigned char x, unsigned char y, unsigned char c, unsigned char a) {
SetCursor (x,y);
WriteChar (c,a);
}
void Save(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2) {
unsigned char i,j,a,c;
BufPos=0;
for (i=x1; i<=x2; i++)
for (j=y1; j<=y2; j++) {
SetCursor (i,j);
c=ReadChar (&a);
if (BufPos<BUF_LEN-1) {
Buffer[BufPos++]=c;
Buffer[BufPos++]=a;
}
else break;
}
}
void Restore (unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2) {
unsigned char i,j,a,c;
BufPos=0;
for (i=x1; i<=x2; i++)
for (j=y1; j<=y2; j++) {
c=Buffer[BufPos++];
a=Buffer[BufPos++];
WritePosChar (i,j,c,a);
}
}
#define LAST_STYLE 2
void DrawBox (unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char Type, unsigned char Fill) {
// Отрисовка рамки:
// 012 --¬ г=¬
// 3 4 ¦1¦ ¦2¦
// 567 L-- L=-
//Fill используется при Type=0
unsigned char border[LAST_STYLE+1][8]={
{' ',' ',' ',' ',' ',' ',' ',' '},
{'-','-','¬','¦','¦','L','-','-'},
{'г','=','¬','¦','¦','L','=','-'}
}; unsigned char i;
if (!Type) for (i=0; i<8; i++) border[0][i]=Fill; // Задан заполнитель
for(i=x1; i<=x2; i++) { // Вниз
WritePosChar (i,y1,border[Type][3],ATTR);
WritePosChar (i,y2,border[Type][4],ATTR);
}
for (i=y1; i<=y2; i++) { // Вправо
WritePosChar (x1,i,border[Type][1],ATTR);
WritePosChar (x2,i,border[Type][6],ATTR);
}
WritePosChar (x1, y1, border[Type][0],ATTR);
WritePosChar (x1, y2, border[Type][2],ATTR);
WritePosChar (x2, y1, border[Type][5],ATTR);
WritePosChar (x2, y2, border[Type][7],ATTR);
return;
}
void ClearBox (unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char attr) {
unsigned char i,j;
for (i=x1; i<=x2; i++)
for (j=y1; j<=y2; j++)
WritePosChar (i,j,' ',attr);
}
void ScrollWindow (unsigned char x1, unsigned char y1, unsigned char x2,unsigned char y2,unsigned char attr,unsigned char dir,unsigned char lines) {
//Прокручивает окно на lines строк в направлении dir
//Если lines=0, просто очищает окно
unsigned char i;
if (dir==UP_DIR) i=6;
else i=7;
asm {
mov ah,i;
mov al,lines;
mov bh,attr;
mov ch,x1;
mov cl,y1;
mov dh,x2;
mov dl,y2;
int 10h;
}
}
#define DEFAULT_DELAY 6
void MakeDelay (unsigned Tics) {
asm { mov ah,0;
int 1ah;
add dx,Tics;
mov bx,dx; }
CYCLE:
asm { int 1ah;
cmp dx,bx;
jne CYCLE; }
}
void ChangeAttr (unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char Attr) {
unsigned char i,j,c,a;
for (i=x1; i<=x2; i++)
for (j=y1; j<=y2; j++) {
SetCursor (i,j);
c=ReadChar (&a);
WritePosChar (i,j,c,Attr);
}
}
void DrawWindow (unsigned char x_1, unsigned char y_1, unsigned char x_2,unsigned char y_2,unsigned char attr) {
unsigned char x1=x_1, y1=y_1, x2=x_2, y2=y_2, In;
if (Explode) { //explode
x1+=((x_2-x_1)>>1);
x2=x1+1;
y1+=((y_2-y_1)>>1);
y2=y1+1; In=0x0F;
do {
DrawBox (x1,y1,x2,y2,Border,Filler);
MakeDelay (DEFAULT_DELAY);
DrawBox (x1,y1,x2,y2,0,' ');
if (x1>x_1) x1--;
else In&=0xfe;
if (x2<x_2) x2++;
else In&=0xfb;
if (y1>y_1) y1--;
else In&=0xfd;
if (y2<y_2) y2++;
else In&=0xf7;
} while (In);
}
else { // normal
ClearBox (x_1,y_1,x_2,y_2,attr);
}
DrawBox (x_1,y_1,x_2,y_2,Border,Filler);
if (Shadow) { //shadow
In=(y2<MaxCol?(y2<MaxCol-2?y2+2:MaxCol-2):MaxCol-1);
if (y2<MaxCol-1) ChangeAttr (x1+1,y2+1,x2,y2+2,0x08); //Ver
if (x2<MaxRow) ChangeAttr (x2+1,y1+2,x2+1,In,0x08); //Hor
} return;
}
void WriteString (unsigned char *s,unsigned char attr) {
unsigned char r,c;
ReadCursor(); r=RowCursor; c=ColCursor;
for (; *s; s++) {
if (*s=='\n') goto NEXT;
WriteChar (*s,attr);
c++;
if (c>MaxCol) {
NEXT:
c=0; r++;
if (r>MaxRow) break;
}
SetCursor (r,c);
}
}
void WriteToCon (unsigned char *Str) {
unsigned char c;
for (;*Str;Str++) {
c=*Str;
asm mov ah,06h;
asm mov dl,c;
asm int 21h;
}
}
unsigned char IsAnsi (void) {
unsigned char *Test="\033[1D", //ANSI-строка: переместить курсор влево на 1
c,r,Ret;
ReadCursor(); r=RowCursor; c=ColCursor;
Save (0,1,0,4);
SetCursor (0,1);
WriteToCon (Test);
ReadCursor();
if (ColCursor==0) Ret=YES;
else Ret=NO;
Restore (0,1,0,4);
SetCursor (r,c);
return Ret;
}
unsigned char MouseIsReady (void) {
//0-OK,1-ERROR
asm mov ax,0;
asm int 33h;
asm cmp ax,0;
asm je ERROR;
return 0;
ERROR: return 1;
}
void ReadString (unsigned char Maxlen) {
//Введенная строка в Buffer со смещения 2, длина ввода в Buffer[1]
//MaxLen включает символ конца строки
Buffer[0]=Maxlen;
Buffer[1]='\0';
asm mov ah,0ah;
asm lea dx,Buffer;
asm int 21h;
}
void SetColor (unsigned char Color) {
ATTR&=0xF0;
ATTR|=Color|0x0F;
}
void SetBkColor (unsigned char BkColor) {
ATTR&=0x0F;
ATTR|=((BkColor&0x0F)<<4);
}
long GetFileSize (unsigned char *Name) {
// -1 Ошибка, иначе размер файла
int Handle;
asm mov ax,seg Name;
asm mov ds,ax;
asm mov dx,offset Name;
asm mov ax,3d00h;
asm int 21h;
asm jc ERROR;
asm mov Handle,ax;
asm mov ax,4202h;
asm mov bx,Handle;
asm mov cx,0;
asm mov dx,0;
asm int 21h;
asm jc ERROR;
L.High=_DX;
L.Low=_AX;
return L.Long;
ERROR:
return -1L;
}
void Clear_Buf(void) {
asm cli;
asm sub ax,ax;
asm mov es,ax;
asm mov al,es:[41ah];
asm mov es:[41ch],al;
asm sti;
}
int Hit_Key(void) {
asm mov ax,0;
asm mov es,ax;
asm mov al,es:[41ah];
asm mov ah,es:[41ch];
if (_AH==_AL) return (0);
return (1);
}
void SecDelay (unsigned Sec) {
unsigned u; unsigned char Count=0;
for (u=Sec; u>0; u--) {
MakeDelay (18);
if (Break && Hit_Key()) { Clear_Buf(); break; }
Count++;
if (Count==60) { Count=0; MakeDelay (12); }
}
}
unsigned Seconds (unsigned char h, unsigned char m, unsigned char s) {
return (h*3600u+m*60u+s);
}
unsigned KolSeconds (unsigned char h1, unsigned char m1, unsigned char s1,unsigned char h2, unsigned char m2, unsigned char s2) {
unsigned t1,t2;
t1=Seconds (h1,m1,s1);
t2=Seconds (h2,m2,s2);
if (t1<=t2) return (t2-t1);
return (20864-t1+t2);
}
void TimeWait (unsigned char hour, unsigned char min, unsigned char sec) {
unsigned Sec;
GetTime();
Sec= KolSeconds (HOUR,MIN,SEC,hour,min,sec);
SecDelay (Sec);
}
long GetTics (unsigned Sec) {
//Примерное число "тиков" в Sec секундах
long L;
L=Sec*18+ Sec/5+ (Sec%2>2?1:0);
return L;
}
unsigned char AskKey (unsigned char *Keys, unsigned char Delay, unsigned char Case, unsigned char Default, unsigned char Show) {
//Delay=0 - ждать нажатия, иначе через Delay секунд выбрать номер Default
//Case=1 - не различать строчные и прописные
//Show=1 - показать выбор с новой строки
unsigned char c,s,Len,i; long Timer;
Len=StrLen (Keys);
if (Case) UpCaseStr (Keys);
if (Show) {
WriteString ("[",ATTR);
WriteString (Keys,ATTR);
WriteString ("]? ",ATTR);
}
if (Delay) {
Timer=GetTimer()+GetTics(Delay);
if (Timer>1572480L) Timer=1572480L-Timer;
}
Clear_Buf();
while (1) {
if (Delay) while (!Hit_Key()) {
if (GetTimer()>=Timer) {
i=Default-1; c=*(Keys+i); goto OUT;
}
}
c=(unsigned char)Get_Key();
for (i=0; i<Len; i++) {
s=*(Keys+i);
if (s==c || (Case && (UpCase(s)==UpCase(c)) ) ) {
OUT:
if (Show) WriteChar (c,ATTR);
return (i+1);
}
}
}
}
void Sound (unsigned Sec, unsigned Freq) {
long Time=GetTimer();
asm{
PUSH AX //Сохраняем используемые регистры
PUSH BX
PUSH CX
PUSH DX
PUSH DI
CLI //Запрещаем прерывания
MOV DI,Freq //Переносим значения в регистры
MOV BX,Sec
MOV AL,0B6H //Записать в регистр режима таймера
OUT 43H,AL
MOV DX,14H //Длительность времени =
MOV AX,4F38H //1331000 / частота
DIV DI
OUT 42H,AL //Записать младший байт счетчика таймера 2
MOV AL,AH
OUT 42H,AL //Записать старший байт счетчика таймера 2
IN AL,61H //Считать текущую установку порта В
MOV AH,AL //и сохранить ее в регистре AH
OR AL,03H //Включить динамик
OUT 61H,AL
}
WAIT: asm MOV CX,2A00H //Выждать 10 мс
SPKR: asm{
LOOP SPKR
DEC BX //Счетчик длительности исчерпан ?
JNZ WAIT //Нет. Продолжить звучание
MOV AL,AH //Да. Восстаносить исходную установку порта
OUT 61H,AL
POP DI //Востановить регистры
POP DX
POP CX
POP BX
POP AX
STI //Разрешить прерывания
}
SetTimer (Time+Sec);
return;
}
unsigned GetMemory (void) {
unsigned FreeMemorySize;
unsigned Par;
asm mov bx,0ffffh;
asm mov ah,48h;
asm int 21h;
Par=_BX;
FreeMemorySize=(((long)Par)<<4)/1024;
return FreeMemorySize;
}
////////////////////////////////////////////////////////////////////////
void CheckString(void) {
if (SetString) UtoA (Return,String);
}
unsigned char *Months[]={ "января","февраля","марта","апреля","мая","июня",
"июля","августа","сентября","октября","ноября","декабря" };
unsigned char *WeekDays[]={ "понедельник","вторник","среда","четверг","пятница",
"суббота","воскресенье" };
void Day (void) { GetDate(); Return=DAY; CheckString(); }
void WeekDay (void) {
GetDate(); Return=(WEEKDAY==0 ? 7 : WEEKDAY);
if (FullFormat) StrCpy (String, WeekDays[Return-1]);
else CheckString();
}
void Month (void) {
unsigned char Len;
GetDate(); Return=MON;
if (FullFormat) {
StrCpy (String, Months[MON-1]);
Len=StrLen (String);
if (MON==0x08) String[Len-1]='\0';
else String[Len-1]='ь';
}
else CheckString();
}
void Year (void) {
GetDate();
Return=YEAR%100;
CheckString();
}
void GetDateString (unsigned char *Ptr1, unsigned char *Ptr2, unsigned char *Ptr3) {
unsigned char *Str=" \0";
Str[0]=DateDividor;
StrCpy (String,Ptr1);
StrCat (String,Str);
StrCat (String,Ptr2);
StrCat (String,Str);
StrCat (String,Ptr3);
}
void Date (void) {
unsigned char *DayPtr=&String[20],*MonPtr=&String[40],*YearPtr=&String[60];
GetDate();
UtoA (DAY,DayPtr);
if (FullFormat) StrCpy (MonPtr, Months[MON-1]);
else UtoA (MON,MonPtr);
if (DateFormat%2) UtoA (YEAR,YearPtr);
else UtoA (YEAR%100,YearPtr);
if (DateFormat<2) { //MDY[Y]
GetDateString (MonPtr,DayPtr,YearPtr);
}
else if (DateFormat<4) { //DMY[Y]
GetDateString (DayPtr,MonPtr,YearPtr);
}
else if (DateFormat<6) { //Y[Y]MD
GetDateString (YearPtr,MonPtr,DayPtr);
}
else { //Y[Y]DM
GetDateString (YearPtr,DayPtr,MonPtr);
}
}
void Hour (void) { GetTime(); Return=HOUR; CheckString(); }
void Minute (void) { GetTime(); Return=MIN; CheckString(); }
void Second (void) { GetTime(); Return=SEC; CheckString(); }
#define HM 0
#define HMS 1
void Time (void) {
unsigned char Len;
GetTime();
UtoA (HOUR,String);
Len=StrLen(String);
String[Len]=TimeDividor;
UtoA (MIN,&String[Len]);
if (FullFormat) {
Len=StrLen (String);
String[Len]=TimeDividor;
UtoA (SEC,&String[Len]);
}
}
void Exit (unsigned char RetCode) {
asm mov al,RetCode;
asm mov ah,0x4c;
asm int 21h;
}
void main () { //тест функций
ClearBox (0,0,24,79,0x07); SetCursor (1,1);
printf ("\nUpCase: %c", UpCase ('р'));
unsigned char *s="тест Test";
UpCaseStr (s);
printf ("\nUpCaseStr: %s", s);
printf ("\nStrCmp: %d",StrCmp("1001","1000",0));
printf ("\nStrChr: %s",StrChr("1001",'0'));
printf ("\nStrRChr: %s",StrRChr("1001",'0'));
printf ("\nStrTok: %s",StrTok("10020","01"));
s="00000";
StrSet(s,'x',3);
printf ("\nStrSet: %s",s);
printf ("\nIsDigit('0'), IsSpace('\\r'), IsUnsigned (\"-1\"): %d %d %d",
IsDigit('0'), IsSpace('\r'), IsUnsigned ("-1"));
printf ("\nAtoU(\"1000\"): %u",AtoU("1000"));
printf ("\nStrLen(\"abcde\"): %d",StrLen("abcde"));
s="abcde";
StrRev(s);
printf ("\nStrRev(\"abcde\"): %s",s);
s=" ";
UtoA(1234,s);
printf ("\nUtoA(1234,s): %s",s);
unsigned char *d="1234____";
d=StrCat(d,s);
printf ("\nStrCat: %s",d);
StrCpy(d,s);
printf ("\nStrCpy: %s",d);
printf ("\n Free any key:");
printf ("\n Key code: %d",Get_Key());
WritePosString (10,10,"String with attributes - WritePosString ",0x70);
ClearBox (0,0,24,79,0x07);
unsigned char *menu[3] = { "GetPopup menu", "function", "demo" };
GetPopup (1,1,3,menu,1);
StrCpy(menu[0],"GetMenu");
GetMenu (0,0,3,menu,1);
printf ("\nPrinterIsReady(0): %d",PrinterIsReady(0));
printf ("\nDriveReady(current): %d",DriveReady(0));
HardStatus();
printf ("\nHardStatus: IsSoprocessor=%d, KolFlops=%d, ActiveVideo=%d, KolPrinters=%d, BaseMemorySize=%d",
IsSoprocessor, KolFlops, ActiveVideo, KolPrinters, BaseMemorySize);
printf ("\nGetDrive(): %d",GetDrive());
printf ("\nSetDrive(2) returns %d",SetDrive(2));
GetDirectory (3);
printf ("\nGetDirectory (3) sets in Buffer: %s",Buffer);
printf ("\nDiskSpace (3,0)=%ld,DiskSpace (3,1)=%ld",DiskSpace (3,0),DiskSpace (3,1));
printf ("\n Et cetera... press a key to exit");
Get_Key();
}
|
|