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(); }
гостевая; E-mail |