Ввід інформації з клавіатури. Обмін інформації з файлами засобами мови Turbo C

Можливості організації вводу з клавіатури в комп'ютерах сімейства ІВМ РС. Обмін інформацією між файлами засобами бібліотечних функцій Turbo C. Основні принципи функціонування маніпулятора "миша", отримання демонстраційної програми, яка читає її стан.

Рубрика Программирование, компьютеры и кибернетика
Вид методичка
Язык украинский
Дата добавления 27.05.2016
Размер файла 40,1 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru//

Размещено на http://www.allbest.ru//

Міністерство освіти та науки України

Національний університет ”Львівська політехніка”

Інститут післядипломної освіти

Кафедра СКС

Звіти з лабораторних робіт

з дисципліни «Системне програмне забезпечення»

Виконав: ст. гр.КІі - 21з

Паук І. І.

Прийняв: доц.

Вельгош С.Р.

Львів - 2015

Лабораторна робота №1

Назва роботи: Ввід інформації з клавіатури

Мета роботи: Ознайомитись з можливостями організації вводу з клавіатури в комп`ютерах сімейства ІВМ РС.

Загльні положення

Ввід інформації в комп`ютер може бути виконаний на трьох рівнях:

зверненням до функцій операційної системи (МS DOS);

зверненням до функцій BIOS;

фізичним безпосереднім доступом до апаратних засобів.

Перший рівень дозволяє пропускати клавіатурний ввід через через інста- льованні драйвери,забезпечує контроль за клавішами Crtl-C ( Crtl-Break) та стандартну для операційної системи обробку помилок.

Другий рівень дозволяє програмі слідкувати за натиском усіх, а не тільки символьних клавіш, виконувати керування апаратурою клавіатури і інш. Третій рівень - ( безпосередній доступ до буферу клавіатури )значно підвищує продуктивність програми. В деяких випадках необхідна імітація натиску клавіш клавіатури з записом кодів безпосередньо у буфер. При цьому фізично натиск клавіш не відбивається. Так будуються,наприклад, демонстрційні програми.

Коротко зупинимось на апаратних засобах персонального комп`ютера для вводу з клавіатури. Клавіатура вміщує вбудований мікропроцесор. Він при кожному натисканні клавіші визначає її порядковий номер ( скенд-код ) і розміщує його в порт спеціальної електронної схеми - програмованого переферійного інтерфейсу (ППІ). Скенд-код у перших 7 бітах вміщує порядковий номер натиснутої клавіши, а восьмий біт дорівнє “о”, якщо клавіша була натиснута (прямий скенд-код), та дорівнює “1”,якщо клавіша

була відпущена (зворотній скенд-код). Коли скенд-код записаний у порт 60h, схема ППІ видає сигнал “підтвердження” повідомляючи мікропроце- сор клавіатури про те, що код прийнято.

Якщо клавіша натиснута довше деякого часу затримки ( delay value ), мікропроцесор клавіатури починає генерувати з заданою частотою (typenic) прямий скенд-код натиснутої клавіші.Коли скенд-код прийнятий схемою ППІ,аппаратура комп`ютера генерує переривання 9.Стандартний обробник переривання 9 - це програма,що входить до BIOS ISR аналізує скенд-код, та по спеціальним правилам перетворює його ( ISR - Interrupt Servise Routine - програма обслуговування переривання ).

Буфер BIOS для запису кодів клавіш займає 32 байта пам`яті з адреси 40:1ЕН (1086 в 10 с/г). Запис йнформації до буферу виконує ISR BIOS переривання 9, читаня - функції ISR BIOS переривання 16Н. Буфер клавіатури розрахований на 15 натискань клавш, що генерують двохбайтні коди, і тому має 30 байт для кодів клавіш та два додаткових байта, які резервуються під двохбайтовий код для клавіші ENTER.

Буфер організовується як кільцева черга, доступ до якої виконується за допомогою покажчика “голови” (head-pointer),адреса якого 40:1АН ( 1050 в с/г), та покажчика “хвоста” (tail pointer) адреса якого 40:1СН(1052 в с/г). Значення, що записані у покажчиках дорівнюють зміщення до слова, де буде записаний обробником переривання 9 код клавіші,що буферизується, т.т. перше вільне слово буфера.

Покажчик “годови” задає зміщення слова, яке буде повернуте запиту буферизованого вводу з клавіатури, зробленого операційного системою або BIOS.

Буфер для клавіатури - це класичний приклад використання кільцевого кільцевого буферу для органіції асихронної взаємодії програм за схемою “виробник-споживач”. Одна з програм (ISR BIOS переривання 9)“виробляє” інформацію, тобто, вона є процесом-виробником. Програма, що виконується, через функцію АН=00Н переривання 16Н BIOS “споживає” інформацію,тобто є процесом-споживачем.Асинхронність взаємодії означає що запис до буферу нової їнформації та читання з нього відбувається у випадкові,не зв`язані моменти часу. Тому що “виробник” постійно аналізує наявність переповнення буферу,не відбувється перевизначення не прочитаних ще “споживачем” кодів клавіатури. Тобто при переповненні буферу “виробник” блокується до того часу, доки “споживач” не прочитає одне або декілька слів з буферу.Якщо ж буфер пустий і виконується спроба читання інформації, функція АН=00Н переривання 16Н BIOS переходить до безконечного циклу, умовою якого є нерівність між собою покажчиків “голови” і “хвоста”. Фактично, біжуча програма, що виконує ввід з клавіатури, блокується, не даючи “споживати” неіснуючу ще інформацію.

Перший рівень вводу з клавіатури

Послідовність дій системи при вводі з клавіатури така:

функція MS-DOS викликає драйвер клавіатури,передаючи йому запит

на ввід одного символу з буферу клавіатури;

драйвер,виконуючи запит, звертається до потрібної функції перерива-

ння 16Н BIOS;

ISR BIOS переривання 16Н читає з буферу клавіатури потрібне слово

та передає його в драйвер;

драйвер повертає байт (звичайно молодший) в MS-DOS.

Таким чином, функції MS-DOS та функції бібліотеки Turbo C, що спираються на них,слабо залежать від особливостей апаратури, оскільки система ізольована від неї двома шарами програмного забезпечення -

драйверами та BIOS.

Для вводу з клавіатури використовується такі функції MS-DOS:

АН = 01Н - ввід з очікуванням з стандартного пристрою вводу (клавіатури);

АН = 06Н - ввід-вивід з консолі;

АН = 07Н - ввід з консолі з очікуванням без “відлуння” на екран;

АН = 08Н - подібна до попередньої, крім реакції на натискання Crtl-Break (викликається переривання 23Н);

АН = ОАН - буферизований ввід рядка з консолі;

АН = ОВН - перевірка стану стандартного вводу;

АН = ОСН - ввід з клавіатури з чисткою буфера;

АН = 3FH - функція префіксного читання з файлу або пристрою.

Бібліотечні функції Turbo C для роботи з файлами можна поділити на дві

групи: потокові та префіксні. Потокові функції виконують додаткову буферизацію інформації, що приводить до подвійної буферизації інфор-

мації: на рівні бібліотечної функції та на рівні MS-DOS. Префіксні

функції не виконують додаткову буферизацію, а одразу звертаються до

префіксних функцій MS-DOS. Початкові функції більш ефективні при

перенесенні інформації між файлом та Сі-програмою по символам та рядкам. Префіксні функції - блок-орієнтовані функції і їх використа ння дає виграш в продуктивності при перенесені одразу цілої групи байтів за одне звертання до функції. Розглянуті функції MS-DOS для вводу з клавіатури можна викликати одразу з Сі-програми через такі функції Тurbo C, як geninterrupt(), int86(), intr(), та інші,або нявно функціями вводу Turbo C. Bелика група функцій Turbo C для вводу з клавіатури - це функції потокового та префіксного вводу. Використовуючи функції вводу, прототипи яких розміщені у файлі stdio.h, неможливо виконати, наприклад, не відображення символів і т.ін. Для виконання таких дій використовуються функції Turbo C,прототипи яких розміщені у файлі conio.h.Вони,як правило розраховані на побудову найпростішого віконного інтерфейсу.

Приклад використання функцій cgets()*L7-1.C*,функцій gets() та getsh() *L7-2.C*, getpass() - *L7-3.C*, ungetch() - *L7-4.C*

Другий рівень вводу з клавіатури

Інтерфейсом програм у персональному комп`ютері з клавіатурою є переривання 16Н BIOS.

Його функції такі:

АН=00Н- читання з очікуванням двохбайтового коду з буферу клавіатури

АН=01Н- читання без очікування двох байтового коду з буферу клавіа…;

АН=02Н- визначення стану шифра тригерних клавіш;

АН=03Н- установка затримки та частоти повторення ;

АН=04Н - запис до буферу клавіатури двохбайтового коду клавіші ( ця

функція не має аналогів у бібліотеці Turbo C ).

Функції Аh=00-02H є аналогами функції 00-02Н, але для клавіатур з 102/102 клавішами. Приклади використання функції enter-kb-BIOS ( ) - *L7-5.C*,

*L7-6.C*.

Функція АН=00-02Н переривання 16Н BIOS покладенні в основу функції bioskey( ) бібліотеки Turbo C. Приклади її використання - *L7-7.C*

Третій рівень вводу з клавіатури.

Для багатьох професійних програм необхідним є безпосереднім доступ до буферу клавіатури. Для функції цього типу існує власний заголовочний

файл kb.р. Це такі функції:

Clear-kb ( ) - очищення буферу клавіатури;

Gets-kb ( ) - очищення буферу клавіатури та ввід з очікуванням двохбайтового коду натискання клавіші;

Key-kb ( ) - читання двохбайтового коду натискання клавіші;

Gets-kb ( ) - розширене визначення стану шифт - та тригерних клавіш

на момент виклику функції;

Sets-kb ( ) - розширена установка стану шифт - та тригерних клавіш;

Enter-kb ( )- запис безпосередньо до буферу клавіатури коду натискання клавіш.

Приклади використання функцій - *L7-8.C*, *L7-9.C*, *L7-10C*, *L7-11.C*,

*L7-12.C*,*L7-13.C*

Порядок виконання роботи

1.В середовищі MS-DOS ініціалізувати одну з систем програмування Turbo C, Turbo C++, Boorland C++.

2.Відкомпілювати та виконати один або декілька вказаних вказаних викладачем прикладів (Всі приклади з ВООК/2).

3.Модифікувати вказаний приклад (або приклад ) певний чином. Виконати модифікований приклад.

4.Зробити висновки з особливостей функціонування тих або інших програмних засобів вводу інформації з клавіатури.

Результат виконання роботи:

#include <stdio.h>

#include <conio.h>

#include <ctype.h>

void main(){

char string[80];

char * str, ch, * password;

int c, i, extended;

//cgets()

string[0] = 81;

printf("\n1. Function cgets()\n\n");

printf("Input some chars:");

str = cgets(string);

printf("\ncgets read %d characters: \"%s\"\n", string[1], str);

printf("The returned pointer is %p, string[0] is at %p\n", str, &string);

//gets()

printf("\n2. Function gets()\n\n");

printf("Input a string:");

gets(string);

printf("The string input was: %s\n", string);

//getch()

extended = 0;

printf("\n3. Function getch()\n\n");

printf("Enter any character: ");

c = getch();

if (!c){

extended = getch();

printf("\nSpecial key. Extended scan-cod %#u\n", ch);

}

else {

printf("\nSymbol key %c (ASCII-cod %#u)\n", ch, ch);

}

//getpass()

printf("\n4. Function getpass()\n\n");

password = "\x04\x0E\x1C\x0E\x1B\x04\x06";

str = getpass("Enter password (8 symbols):");

while(*password)

if(*str++ != (*password++ ^ 0x4f)){

puts("\aWrong password.\n");

cprintf("The password is: %s\r\n", password);

}

puts("Correct password.\n");

//ungetch()

i = 0;

printf("\n5. Function ungetch()\n\n");

puts("Input an integer followed by a char:");

while((ch = getche()) != EOF && isdigit(ch))

i = 10 * i + ch - 48;

if (ch != EOF) ungetch(ch);

printf("\n\ni = %d, next char in buffer = %c\n", i, getch());

}

#include <dos.h>

#include <bios.h>

#include <stdio.h>

#include <conio.h>

int enter_kb_BIOS(unsigned key_code){

struct REGPACK r;

r.r_cx = key_code;

r.r_ax = 0x0500;

intr (0x16, &r);

return r.r_ax & 0x00ff;

}

void main(){

char BIOS_key_cur, BIOS_key_old, BIOS_key;

char * icons[] =

{

"Right Shift:", "Left Shift :", "Ctrl :",

"Alt :", "ScrollLock :", "NumLock :",

"CapsLock :", "Ins :", 0,

};

int index = 0, x, y;

//enter_kb_BIOS()

if (!enter_kb_BIOS('a')) printf("Successfuly loaded into keyboard buffer\n");

else printf("Keyboard buffer is full\n");

printf("\n\n\n\nRead from buffer: %c\n",getche());

printf("Press any key to continue...\n");getche();

//bioskey()

clrscr();

while(icons[index]) puts(icons[index++]);

BIOS_key_old = bioskey(2);

BIOS_key_old = ~BIOS_key_old;

while(!((bioskey(1) & 0xff00) == 0x1000)){

y = 1;

BIOS_key_cur = BIOS_key = bioskey(2);

for(index = 0; index < 8; index++){

x = 14;

gotoxy(x, y);

if((BIOS_key & 0x01) != (BIOS_key_old & 0x01))

if(BIOS_key & 0x01){

textattr(BLACK | (LIGHTGRAY << 4));

cputs("on ");

}

else{

textattr(LIGHTGRAY | (BLACK << 4));

cputs("off");

}

BIOS_key >>= 1;

BIOS_key_old >>= 1;

y++;

}

BIOS_key_old = BIOS_key_cur;

}

bioskey(0);

}

#include <stdio.h>

#include <dos.h>

#include "kb.h"

int enter_kb_BIOS(unsigned key_code){

struct REGPACK r;

r.r_cx = key_code;

r.r_ax = 0x0500;

intr (0x16, &r);

return r.r_ax & 0x00ff;

}

void clear_kb(void){

char register _es * tail = (char _es *) TAIL_PTR, _es * head = (char _es *) HEAD_PTR;

disable();

_ES = 0x40;

* tail = * head;

enable();

}

unsigned int getc_kb(void){

register ret_ax = 0;

_AX = 0x0C01;

geninterrupt(0x21);

ret_ax = _AL;

if(!ret_ax){

_AH = 0x01;

geninterrupt(0x21);

ret_ax = _AL;

return ret_ax << 8;

}

return ret_ax;

}

unsigned key_kb(void){

register char _es * tail = (char _es *) TAIL_PTR;

register char _es * head = (char _es *) HEAD_PTR;

_ES = 0x40;

if(* head == * tail) return 0;

disable();

tail = (char _es *) (* head);

enable();

return * (unsigned _es *) tail;

}

void getsh_kb(unsigned * old_status){

unsigned _es * shift_address = (unsigned _es *) 0x17;

disable();

_ES = 0x40;

* old_status = * shift_address;

enable();

}

void setsh_kb(unsigned * new_status){

unsigned _es * shift_address = (unsigned _es *) 0x17;

disable();

_ES = 0x40;

* shift_address =* new_status;

enable();

}

enter_kb(int where, unsigned key_code){

unsigned register _es * tail = (unsigned _es *) TAIL_PTR, _es * head = (unsigned _es *) HEAD_PTR, _es * tmp, ret;

_ES = 0x40;

disable();

switch(where){

case KB_HEAD:

tmp = (unsigned _es *) * head;

tmp--;

if(tmp < (unsigned _es *) KB_BUFFER_START)

tmp = (unsigned _es *) (KB_BUFFER_END - 2);

if(tmp == (unsigned _es *) * tail){

ret = FULL;

break;

}

else{

* (unsigned _es *) tmp = key_code;

* head = (unsigned) tmp;

ret = OK;

break;

}

case KB_TAIL:

tmp = (unsigned _es *) * tail;

if(tmp == (unsigned _es *) KB_BUFFER_END)

tmp = (unsigned _es *) KB_BUFFER_START;

if(tmp + 1 == (unsigned _es *) * head){

ret = FULL;

break;

}

else{

* (unsigned _es *) tmp = key_code;

tmp ++;

* tail = (unsigned) tmp;

ret = OK;

break;

}

default:

ret = ERROR;

}

enable();

return ret;

}

void main(){

unsigned stat, errorlevel;

//clear_kb()

printf("\n\nFunction clear_kb()\n");

printf("Clearing keyboard buffer...");

clear_kb();

printf("done\n");

//getc_kb()

printf("\nFunction getc_kb()\n");

printf("Enter any key: ");

printf("\nScan code: %X\n",getc_kb());

//key_kb()

printf("\nFunction key_kb()\n");

printf("Writing in key buffer char 'Z'..."); enter_kb_BIOS('Z');printf("done\n");

printf("Reading: %c\n",key_kb());

printf("Reading again: %c\n",key_kb());

//getsh_kb

printf("\nFunction getsh_kb(old_status)");

getsh_kb(&stat);

printf("\nShift-Trigger Byte: %X\n",stat);

//setsh_kb

printf("\nFunction setsh_kb(new_status)");

printf("\nSetting new Shift-Trigger Byte\n");

setsh_kb(&stat);

//enter_kb

printf("\nFunction enter_kb(where, key_code);");

errorlevel=enter_kb(KB_HEAD, 'A');

printf("\nWriting to key buffer char 'A' with left shifting of key head\nErrorlevel=%x - ",errorlevel);

if (errorlevel==0) {printf("( OK )"); }

if (errorlevel==1) {printf("( FULL )"); }

if (errorlevel==2) {printf("( ERROR )");}

}

Лабораторна робота №2

Назва роботи: Обмін інформації з файлами засобами мови Turbo C

Мета роботи: Ознайомитись з можливостями організації обміну інформацією між файлами засобами бібліотечних функцій Turbo C.

Загальні положення

Бібліотечні функції Turbo C для роботи з файлами можна розділити на дві групи: потокові та префіксні. Як ті так і інші звертаються, в принципі, до одних і тих самих функціональних викликів MS DOS. Але потокові функції виконують додаткову буферизацію, що викликає подвійну буферизацію на рівні бібліотечних функцій і на рівні MS DOS. Префіксні функції одразу звертаються до префіксних функцій MS-DOS: це блок орієнтованих функцій і їх використання дає виграш у продуктивності при перенесенні одразу цілої групи байтів за одне звернення до функцій. Максимальний виграш досягається тоді, коли розмір блоку, що переноситься із програми кратний розміру сектора диску (512 байт). Обмін інформацією між файлом і Сі-програмою по символам і по рядкам більш ефективній при використанні потокового файлового вводу-виводу.

Як для потокових так і для префіксних функцій файлового вводу-виводу можливі два різних режими доступу до файла: текстовий і двійковий. В текстовому режимі відбувається трансляція символів СR (0DH,0AH)(ознака кінця регулярного файлу).При читананні інформації з файла в цьому режимі пара символів СR LF перетворюється в один символ нового рядка `\n`,а при записі символ нового рядка перетворюється в пару символів СR LF. Крім того як тільки з файла зчитується символ Crtl-Z,(ASCII 1AH - символ EOF регулярного файла ),рахується, що кінець файла вже досягнуто(умова EOF).

Таким чином у текстовому файлі не можна прочитати інформацію після символа Crtl-Z. При виконанні файлового вводу-виводу у двійковому режимі ніякого перертворення символів не відбувається,а всі вони розглядаються як такі,що не мають якогось особливого значення.

Режим доступу дофайлу задається під час відкриття файлу через бібліотечну функцію відкриття або спеціальною зовнішньою змінною, яка описана в заголовочних файлах fcntl.h або stdlib.h і може приймати два значення:

0-BINARY - доступ до файла виконуються у двійковому режимі;

0-ТЕХТ - доступ до файла виконується в текстовому режимі;

По замовченню fmode встановлюється в значення 0-ТЕХТ.

Це значення може бути перевизначене при відкритті файла або оператором присвоєння.

Доступ до файлів через потік вводу-виводу.

Відриття файла вводу-виводу через потік виконує функція fopen( ), закриття fclose( ).Приклад,що демонструє використання функцій стандартної бібліотеки для відкриття та закриття файлів *L3-1.C*.Ім`я та режим відкриття задаються в командному рядку при запуску програми. Після успішного відкриття файла програма може виконувати файловий ввід-вивід. Функція потокового вводу-виводу можна розділити на чотири групи:

функції символьного вводу-виводу, за одне звертання до яких переноситься один символ;

функції порядкового вводу-виводу, за одне звертання до яких переноситься ASCIIZ-рядок символів( рядок у форматі ASCIIZ- це масив

елементів типу char, в кінці якого символ`\0`нуль-термінатор);

функції блокового вводу-виводу, за одне звертання до яких переноситься цілий блок (або запис) інформації;

функції форматованого вводу-виводу, при виконанні яких виконується присвоєння значень змінних (ввід) або вивід представлення змінних змінних у потік.

Приклад посимвольного вводу-виводу інформації у файли, що відкриті як потоки - *L3-2.C*.Програма *L3-3.C* виконує посимвольне копіювання файла джерела у файл призначення.

Приклад порядкового вводу-виводу - *L3-4.C*, *L3-5.C*. Функції dfread( )та fwrite( ) дозволяють виконувати виконувати перенос між файлом і програмою блока байтів або записів (records).Блок (запис)- це група поруч

розташованих байтів, що немають ніяких спеціальних розділювачів.

Приклад блокового вводу-виводу - *L3-6.C*.Функції форматованого вводу-виводу наведені у прикладі *L3-7.C*.

Регулярний та спеціальні символьні файли не логічному рівні представляються стрічкою байтів, що має початок і кінець.Місце у файлі куди записується інформація, або звідки вона зчитується, визначається значенням покажчика запису-читання файла. Стандартна Сі -бібліотека включає функції, що дозволяють встановлювати на потрібному місці у файлі покажчик запису-читання,або,інакше кажучи,виконувати доступ до довільного байту файла.При виконанні послідовного доступу покажчик позиціонується автоматично на довільній операції читання чи запису. Але “пересуновши” покажчик на довільне місце,можна читати інформацію з файла або записувати її в файл у довільному порядку. Дві потокові функції, що найчастіше використовуєтьсядля явного керування положенням покажчика записучитання це rewind( ) та fseek( ).

Приклад довільного доступу до файлів - *L3-8.C*.

Префіксний доступ до файлів

Turbo C вміщує певну групу функцій префіксного доступут до файлів, або так званих “системних викликів” або “процедур нижнього рівня” ( LOW LEVEL FILE I/O Routines ).

Префіксне відкриття файла здійснюють дві функції: open( ), _open( ).

Наступні функції створюють файли : creat( ), _creat( ), createnew( ),

createtemp( ).Закриття файлів відкритих префіксним доступом, виконується функціями close( ), _close( ).Hеявне закриття файлів, відкритих програмою, виконує операційна система при завершенні програми.

Приклад використання цього класу функцій - *L3-12.C*, *L3-13.C*, *L3-14.C*.

Перенесення інформації між прикладною програмою і файлом для префіксного доступу, виконують дві пари функцій: read ( )/_read( ) та

write( )/_write( ). Приклад використання *L3-15.C*.

Порядок виконання роботи

В середовищі MS DOS ініціалізувати одну з систем програмування:

Turbo C, Turbo C++, Borland C++.

2. Відкомпілювати та виконати один або декілька прикладів, вказаних

викладачем,виконючи модифікації,потрібні для функціонування тих чи інших функцій. Всі приклади з ВООК2.

3. Зробити висновки щодо особливостей функціонування засобів обміну інформацію між файлами.

Результат виконання роботи:

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <string.h>

#include <io.h>

#define NAME 32

#define TITLE 64

typedef struct {

char name[32];

char title[64];

int year;

float price;

} BOOKS;

int file_input_book(FILE * fp, BOOKS * ptr){

return(fread(ptr, sizeof(BOOKS), 1, fp));

}

int file_output_book(FILE * fp, BOOKS * ptr){

return(fwrite(ptr, sizeof(BOOKS), 1, fp));

}

void main(void){

int ch;

clrscr();

// by chars

printf("1. Copying by chars from stdin to stdout... (Ctlr+Z to finish)\n");

while((ch = getchar()) != EOF)

putchar(ch);

// by lines

char string[256];

int line_number = 0;

FILE * fptr;

printf("\n\n\n2. Copying by lines from <testread.txt> to stdout...\n\n");

if((fptr = fopen("testread.txt", "r")) != NULL){

for(; fgets(string,255,fptr) != NULL; line_number++)

fputs(string, stdout);

printf("\nRead %d lines of file <testread.txt>\n", line_number);

fclose(fptr);

}

else

printf("\nFile not open!\n");

// by block

FILE *b_in, *b_out;

BOOKS *b_ptr;

printf("\n\n\n3. Copying by blocks from <books.txt> to <books2.txt> \n (1 block = 104 bytes)\n\n");

if ((b_in = fopen("books.txt","r"))!= NULL){

b_out = fopen("books2.txt","w");

file_input_book(b_in,b_ptr);

file_output_book(b_out,b_ptr);

fclose(b_in);

fclose(b_out);

}

else

printf("\nFile 'books.txt' not open!\n");

//formated

FILE * fp;

int i, num;

printf("\n\n\n4. Formated read & write.\n\n");

if((fp = fopen("square.txt", "wb")) == NULL){

printf("\nFile 'square.txt' not open!\n"); exit(1);

}

for(i=1; i < 10; i++) if(fprintf(fp,"%d\n",i*i) == 0)

printf("File write error");

freopen("square.txt", "r", fp);

for(i = 1; i < 10; i++){

fscanf(fp,"%d",&num);

printf("%d * %d = %u\n", i,i, num);

}

fclose(fp);

}

#define STOP_STRING ""

#define BUFFER_SIZE 128

#define KEY_SIZE 16

#include <stdio.h>

#include <string.h>

#include <errno.h>

struct file_record {

long offset;

char indicator;

unsigned key_length;

unsigned length;

} work;

main(){

char *argv="database.dat";

FILE * fptr;

int in_lines;

int file_lines;

char key[KEY_SIZE];

char buffer[BUFFER_SIZE];

fpos_t f_ptr;

if((fptr = fopen(argv, "a+b")) == NULL){

perror("ЋиЁЎЄ ®вЄалвЁп д ©« ");

return(2);

}

fseek(fptr, 0L, SEEK_END);

if(!ftell(fptr)){

file_lines = 0;

if(!fwrite(&file_lines, 2, 1, fptr)) return(3);

}

else{

fseek(fptr, 0L, SEEK_SET);

if(!fread(&file_lines, 2, 1, fptr)) return(3);

fseek(fptr, 0L, SEEK_END);

}

printf("\n‚ д ©«Ґ § ЇЁб ­® %d бва®Є. "\

"Џ®¦ «г©бв, ўў®¤ЁвҐ ­®ўлҐ бва®ЄЁ\n"\

"„«п § ўҐа襭Ёп ўў®¤ ўўҐ¤ЁвҐ Їгбвго бва®Єг.\n",

file_lines);

fflush(stdin);

for(in_lines=0; strcmp(gets(buffer),STOP_STRING);){

strcpy(key, " ");

printf("‚ўҐ¤ЁвҐ Є«оз § ЇЁбЁ (15 бЁ¬ў®«®ў): ");

fflush(stdin);

fgets(key, 15, stdin);

work.length = strlen(buffer);

work.key_length = strlen(key);

if(*(key + work.key_length -1) == '\n')

work.key_length--;

work.offset = ftell(fptr) + work.length +

work.key_length +

sizeof(struct file_record);

work.indicator = 'B';

if(!fwrite(&work, sizeof(struct file_record), 1, fptr))

break;

if(!fwrite(key, work.key_length, 1, fptr))

break;

if(!fwrite(buffer, work.length, 1, fptr))

break;

in_lines++;

fflush(stdin);

}

if(in_lines){

file_lines += in_lines;

f_ptr = ftell(fptr);

fclose(fptr);

fopen(argv, "r+b");

fseek(fptr, 0, SEEK_SET);

if(!fwrite(&file_lines, 2, 1, fptr)) in_lines = 0;

fsetpos(fptr, &f_ptr);

}

printf("ЏpЁҐ¬ бвp®Є § ўҐp襭\n");

printf("ЏpЁ­пв® %d бвp®Є:\n‚ᥣ® ў д ©«Ґ бв «® %d бва®Є\n",

in_lines, file_lines);

fclose(fptr);

return(0);

}

#include <io.h>

#include <stdio.h>

#include <dos.h>

#include <fcntl.h>

#include <sys\stat.h>

int main(void){

int handle;

unsigned segment;

char string [512] = "'Ґбв®ў п бвp®Є ¤«п § ЇЁбЁ ў д ©«";

// read file

if((handle = _creat("rd-wr.txt",FA_ARCH|FA_SYSTEM|FA_HIDDEN)) == -1){

printf("ЋиЁЎЄ ®вЄpлвЁп д ©« 'rd-wr.txt'\n");

perror("ЏpЁзЁ­ ®иЁЎЄЁ");

return (2);

}

write(handle, string, sizeof(string));

read(handle, string, 512);

write(1, string, 512);

close(handle);

// open file

if ((handle = open("dumpmem.dat", O_TRUNC|O_CREAT|O_WRONLY|O_TEXT,S_IWRITE)) ==-1){

printf("ЋиЁЎЄ ®вЄpлвЁп д ©« 'dumpmem.dat'\n");

return(1);

}

// write to file

for(segment = 0; segment < 0x8000; segment += 0x1000){

if(_write(handle, (char far *)MK_FP(segment, 0), 0xffff) == 0){

perror("\aЋиЁЎЄ § ЇЁбЁ ў® ўаҐ¬Ґ­­л© д ©«");

return(2);

}

if(_write(handle, (char far *)MK_FP(segment, 0xffff), 1) == 0){

perror("\aЋиЁЎЄ § ЇЁбЁ ў® ўаҐ¬Ґ­­л© д ©«");

return(2);

}

}

printf("\n‚лЇ®«­Ґ­ ¤ ¬Ї 512Љ Ў ©в Ї ¬пвЁ ў д ©« 'dumpmem.dat'\n");

}

Лабораторна робота № 3

Назва роботи: Вивід інформації на екран ПК

Мета роботи: Ознайомитись з можливостями організації виводу інформації на екран ПК.

Загальні положення.

Вивід інформації на екран ПК може виконуватись на рівні:

МS DOS з використанням функцій переривання 21Н;

безпосереднім доступом до апаратних засобів;

Перший рівень - мобільний,але повільніший. Функції MS DOS для виклику іінформації на екран викликають драйвер консолі ( виконують вивід в спеціальний символьний файл CON ). Якщо в системі інстальований спеціальний драйвер ( наприклад ANSY.SYS ),то можуть використовуватись

додаткові засоби по керуванні екраном.Суть розширеного керування полягає в передачі драйверу консолі спеціальних керуючих рядків.Драйвер розпізнає початок керуючого рядка по символу 27Н (1ВН).Символи, що передаються за ним на екран розглядаються як параметри команди, яку виконує драйвер. Інші додатні сторони функцій MS DOS:

автоматичне позиціювання курсора та скролінг (прокрутка) екрану;

реакція на натискання клавіш Crtl-Break.

Недоліки - неможливість безпосереднього керування курсором та атрибутом символів. На рівні MS DOS працюють функції стандартного виводу Turbo C, їх прототипи розміщені у файлі stdiо.h

Другий рівень - вивід на рівні BIOS дає більш широкі можливості по

керруванню екраном. Саме ці функції використовуються драйверами MS DOS для виводу інформації на екран. Недоліком функції BIOS є невелика швидкість виводу, що особливо відчувається при роботі в графічних режимах. На рівні BIOS працюють функції консольного виводу Turbo C, їх прототипи розміщені у файлі conio.h.

Третій рівень - використовується у випадках, критичних за швидкістю

виводу, коли треба виконувати вивід, використовуючи безпосередній доступ до портів відео-пам`яті адаптера. Це дає можливість досягти максимально можливої швидкості виводу, але вимагає максимальних зусиль програмістів. Функції консольного виводу Turbo С можуть за вибором користувача працювати і на самому нижньому рівні, виконуючи доступ до відео-буфера при роботі у текстовому режимі. Вивід на екран засобами BIOS:

Переривання 10Н має в своєму складі декілька функцій для виводу на екран :

АН=09Н- вивід символа із заданим атрибутом в біжучій позицій курсора;

АН=0АН- вивід символа без атрибута в біжучій позиції курсора;

АН=0ЕН- вивід символа без атрибута в біжучій позиції курсора в режимі “телетайп”;

АН=13Н - вивід рядка символів з різними додатковими опціями:

із зсувом курсора та без нього;

із визначенням атрибута для всього рядка, для кожного символа, а також без визначення атрибута.

Як приклад використання функції АН=09Н можна розглянути функцію

wert-prn( ) (приклад *L9-2.C*).Корисною для виведення рамок,заповнення областей екрану є функція printche( ) (приклад *L9-3.C*,*L9-4.C*). Ці функції дають майже максимально можливу при використанні BIOS швидкість.

Скролінг.Очищення вікна всього екрану.

Функції АН=06 та 07 переривання 10Н BIOS виконують так званий скролінг (прокрутку) вікна екрану. При виконанні скролінгу на один рядок догори вся інформація у вікні переміщується на рядок догори. Знизу з`являється чистий рядок догори. Знизу з`являється чистий рядок.

Сі-функція scroll( ) виконує вертикальний скролінг вікна екрану, що задається рядком і стовпчиком лівого верхнього, та рядком і стовпчиком правого нижнього кутів вікна. Якщо змінна direction дорівнює UP, то відбувається скролінг на один рядок догори, якщо вона дорівнює DOWN, скролінг на один рядок донизу, якщо ENTIRE - відбувається очищення екрану (приклад *L9-5.C*). Функція expl_win виводить виводить вибухаюче вікно на екран ( приклад *L9-6.C*). Вивід інформації на екран засобами Turbo C.

Turbo C вміщує великий набір функцій вводу-виволу інформації у вікно екрану. Прототипи цих функцій знаходяться безпосередньо в заголовочному файлі соnio.h. На відміну від функцій стандартного вводу-виводу вони дозволяють керувати кольором виводимих символів.

Вони не виходять за межі активного в біжучий момент вікна. При досягненні правої вертикальної межі курсор автоматично переходить на початок наступного рядка у вікні, а при досягненні нижньої вертикальної межі виконується скролінг вікна догори.

Приклад функції горизонтального скролінга текстового вікна на одну позицію вліво або вправо в програмі *L9-10.C*. Використовується функція movetext( ).

Функція файла соnio.h в принципі дозволяють побувати віконний інтерфейс довільної складності, різноманітні системи меню, т.ін. Програма *L9-11.C* працює в графічному режимі 10Н ЕGA та VGA адаптерів. Ця демонстраційна прогама створює на екркані вікно вводу-виводу. Програма приймає з клавіатури ціле число та рядок символів, потім виводить їх на екран. Вікно вводу-виводу займає 25 стовбчиків та 10 рядків у лівому верхньому куті екрану. Попередній вміст екрану зберігається, а перед звертанням програми відновлюється.

Читання інформації з екрану

В практиці програмування необхідність читання вмісту екрана виникає, як правило, в таких випадках:

при організації віконного інтерфесу ;

при побудові програм переносу резидентною програмою тексту в довільний текстовий редактор;

при побудові різноманітних резидентних HELP систем, які видають “підказку” по слову у біжучій позиції курсора (контекстно-чутлива підказка).

Розглянемо приклад Сі-функцій, яка “читає” слово інформації в біжучій позиції курсора. Словом називається довільна послідовність ASCII-символів, що не включає символи-розділювачі. Всі символи-розділювачі розміщають в ACIIZ-рядок, покажчик на початок якого є параметром функції separators. ASCIIZ-рядок - це масив елементів типу char, в кінці якого розміщенний символ `\0`-нуль-термінатор. Слово з екрана “копіюється” в статичний буфер функції і доповнюється в кінці нуль-термінатором, утворюючи звичайний ASCIIZ-рядок. Покажчик на початок повертається в точку виклику. В змінних на які вказує str та stlob (нумерується від 0 ), значення передаються в рядок та стовбчик на початку слова на екрані. Якщо слово не знайдено, str та stlob зберігають біжучу позицію курсора. Значення покажчика, що повертається функцією, NULL, свідчить про відсутність в біжучій позиції курсора слова. В такому випадку значення рядка та стовпчика з змінних, на які посилаються str та stlob, будуть дорівнювати біжучий позиції курсора.

Алгоритм роботи функції read-str( ) такий. Визначається біжуча позиція курсора. З відеопам`яті зчитується весь рядок символів, в якому розташовується курсор. Потім починається цикл виділення та аналізу слів в рядку. Для “розбору” рядка на слова використовується функція Turbo C виділення лексем strtok ( ).

Якщо біжуче положення курсора попадає на слово, робота функції завершується і в точку виклику передається покажчик на виділене слово. Якщо у біжучій позиції курсора записаний символ розділювач, повертається слово, що знаходиться зліва від позиції курсора. Якщо ж зліва знаходиться ще один символ розділювач, то повертається NULL. Приклад використання функції у файлі *L9-14.C*. Максимально ефективний варіант функції lh-light( ).(“перефарбування” рядка або вертикально, або горизонтально) в програмі *L9-15.C*.

Порядок виконання роботи :

В середовищі MS DOS ініціалізувати одну з систем програмування: Turbo

C, Turbo C++, Boorland C++.

Розглянути можливості виводу на екран засобами BIOS,відкомпілювавши та виконавши приклади (Всі приклади з ВООК2).

Розглянути приклади для виконання скролінгу та очищення.

Розглянути засоби Turbo C виводу на екран та читання інформації з екрану.

Результат виконання проекту:

#include <dos.h>

#include <string.h>

#include <conio.h>

#include "screen.h"

//*********************************************************************

goto_xy(int stroka, int stolb, int page)

{

unsigned old_ds;

register max_colons, max_string, cur_pos, ret;

old_ds = _DS;

_DS = 0x40;

max_colons = * (char near *) 0x4a;

max_string = * (char near *) 0x84;

if(stroka <= max_string && stolb <= max_colons)

{

cur_pos = (stroka << 8) | stolb;

* (unsigned near *)(0x50 + (page << 1)) = cur_pos;

ret = OK;

}

else

ret = BAD_PARAM;

_DS = old_ds; return ret;

}

void save_cur(struct cursor_pos * work)

{

register base_adr;

register offs

work -> cur_page = *(char far *)MK_FP(0x40,0x62);

offs = 0x50 + (work -> cur_page << 1);

work -> row_col= *(unsigned far *)MK_FP(0x40,offs);

base_adr = *(unsigned far *)MK_FP(0x40,0x63);

outportb(base_adr++, 14);

work -> reg_14 = inportb(base_adr--);

outportb(base_adr++, 15);

work -> reg_15 = inportb(base_adr);

}

void rest_cur(struct cursor_pos * work)

{

register base_adr;

register offs;

offs = 0x50 + (work -> cur_page << 1);

*(unsigned far *)MK_FP(0x40, offs) = work -> row_col;

base_adr = *(unsigned far *)MK_FP(0x40, 0x63);

outportb(base_adr++, 14);

outportb(base_adr--, work -> reg_14);

outportb(base_adr++, 15);

outportb(base_adr, work -> reg_15);

}

void cursor(int mode)

{

static unsigned shape;

if(mode == ON)

{

if(shape)

{

_CX = shape;

shape = 0;

}

else

return;

}

else

{

shape = *(unsigned far *)MK_FP(0x40, 0x60);

_CX = 0x2000;

}

_AH = 0x01;

geninterrupt(0x10);

}

//*********************************************************************

vert_prn(int stroka, int stolb, char * str, char attr)

{

register char cur_page;

union REGS r;

cur_page = * (char far *) MK_FP(0x40, 0x62);

/*

if(goto_xy(stroka, stolb, cur_page) == BAD_PARAM)

return BAD_PARAM;

while(*str)

{

/*

*/

r.h.bh = cur_page;

r.h.bl = attr;

r.x.cx = 1;

r.h.ah = 0x09;

r.h.al = *str ++;

int86(0x10, &r, &r);

stroka++;

if(goto_xy(stroka, stolb, cur_page) == BAD_PARAM)

return END_OF_SCREEN;

}

return OK;

}

hor_prn(int stroka, int stolb, char * str, char attr)

{

register char cur_page;

union REGS r;

cur_page = * (char far *) MK_FP(0x40, 0x62);

if(goto_xy(stroka, stolb, cur_page) == BAD_PARAM)

return BAD_PARAM;

while(*str)

{

r.h.bh = cur_page;

r.h.bl = attr;

r.x.cx = 1;

r.h.ah = 0x09;

r.h.al = *str ++;

int86(0x10, &r, &r);

stolb++;

if(goto_xy(stroka, stolb, cur_page) == BAD_PARAM)

return END_OF_SCREEN;

}

return OK;

}

//*********************************************************************

printche(int str, int stolb, char symb, char atr, int n)

{

register cur_page;

register max_stolb;

union REGS r;

cur_page = * (char far *) MK_FP(0x40, 0x62);

max_stolb = * (unsigned far *) MK_FP(0x40, 0x4a);

if(goto_xy(str, stolb, cur_page) == BAD_PARAM)

return BAD_PARAM;

if(max_stolb < (stolb + n - 1))

return BAD_PARAM;

r.h.ah = 0x09;

r.h.al = symb;

r.h.bh = cur_page;

r.h.bl = atr;

r.x.cx = n;

int86(0x10, &r, &r);

return OK;

}

//*********************************************************************

border(int s0, int c0, int s1, int c1, char * title,

char atr_title, char style[], char atr)

{

register max_stolb, max_string, s;

max_stolb = * (char far *) MK_FP(0x40, 0x4a);

max_string = * (char far *) MK_FP(0x40, 0x84);

if(s0 >= 0 && s0 < s1 && c0 >= 0 && c0 < c1 &&

s1 <= max_string && c1 < max_stolb &&

((title != NULL && (c1 - c0) >= strlen(title)) ||

title == NULL))

{

printche(s0,c0,style[0],atr,1);

printche(s0,c0+1,style[1],atr,c1-c0-1);

printche(s0,c1,style[2],atr,1);

for(s = s0 + 1; s < s1; s++)

{

printche(s,c0,style[3],atr,1);

printche(s,c1,style[4],atr,1);

}

printche(s1,c0,style[5],atr,1);

printche(s1,c0+1,style[6],atr,c1-c0-1);

printche(s1,c1,style[7],atr,1);

if(title != NULL)

hor_prn(s0, c0+(c1-c0-strlen(title))/2+1, title, atr_title);

return OK;

}

else

return BAD_PARAM;

}

//*********************************************************************

void scroll(int direction, char l_row, char l_col, char r_row,

char r_col, char attr)

{

union REGS r;

if(direction)

{

r.h.al = 1;

r.h.ah = direction;

}

else

{

r.h.al = 0;

r.h.ah = 6;

}

r.h.ch = l_row; r.h.cl = l_col;

r.h.dh = r_row; r.h.dl = r_col;

r.h.bh=attr;

int86(0x10,&r,&r);

}

//*********************************************************************

#define HOR_STEP 2

#define VERT_STEP 1

#define TIME 150

int expl_win(char s0, char c0, char s1, char c1, char color,

char style[], char atr)

{

int hor_step, vert_step;

register char max_stolb, max_string;

register int cur_s0, cur_c0, cur_s1, cur_c1;

max_stolb = * (char far *) MK_FP(0x40, 0x4a);

max_string = * (char far *) MK_FP(0x40, 0x84);

if(s0 >= 0 && s0 < s1 && c0 >= 0 && c0 < c1 &&

s1 <= max_string && c1 < max_stolb)

{

hor_step = HOR_STEP;

vert_step = VERT_STEP;

cur_s0 = (s1 + s0) >> 1;

cur_c0 = (c0 + c1) >> 1;

cur_s1 = cur_s0;

cur_c1 = cur_c0;

while(cur_c0>c0 || cur_s0>s0 || cur_c1<c1 || cur_s1<s1)

{

scroll(ENTIRE, cur_s0, cur_c0, cur_s1, cur_c1, color);

if(style != NULL)

border(cur_s0, cur_c0, cur_s1, cur_c1, NULL, atr, style, atr);

cur_c0 -= hor_step;

cur_c1 += hor_step;

cur_s0 -= vert_step;

cur_s1 += vert_step;

cur_c0 = (cur_c0 < c0)? c0 : cur_c0;

cur_c1 = (cur_c1 > c1)? c1 : cur_c1;

cur_s0 = (cur_s0 < s0)? s0 : cur_s0;

cur_s1 = (cur_s1 > s1)? s1 : cur_s1;

delay(TIME);

}

scroll(ENTIRE, cur_s0, cur_c0, cur_s1, cur_c1, color);

if(style != NULL)

border(cur_s0, cur_c0, cur_s1, cur_c1, NULL, atr, style, atr);

return OK;

}

else

return BAD_PARAM;

}

//*********************************************************************

h_scroll(int direction, int l_row, int l_col, int r_row,

int r_col, char *blank_str, char attr)

{

int ret, position;

l_col ++; l_row ++; r_col ++; r_row ++;

switch(direction) {

case LEFT:

if(!(ret=movetext(l_col + 1, l_row, r_col, r_row, l_col, l_row)))

return ret;

position = r_col;

break;

case RIGHT:

if(!(ret=movetext(l_col, l_row, r_col-1, r_row, l_col+1, l_row)))

return ret;

position = l_col;

break;

}

vert_prn(--l_row, --position, blank_str, attr);

return 1;

}

//*********************************************************************

int hv_light(int s0, int c0, int n, char atr, int mode)

{

struct cursor_pos old_cursor;

register char str, col, max_stolb, max_string, cur_page;

register cur_pos;

_ES = 0x40;

max_stolb = *(char _es *) 0x4a;

cur_page = *(char _es *) 0x62;

max_string = *(char _es *) 0x84;

if(s0 >=0 && c0 >=0 &&

s0 <= max_string && c0 <= max_stolb &&

((mode == HORIZONTAL && (c0 + n -1) <= max_stolb) |

(mode == VERTICAL && (s0 + n -1) <= max_string)))

{

save_cur(&old_cursor);

cursor(OFF);

str = s0;

col = c0;

while(n--)

{

cur_pos = (str << 8) | col;

* (unsigned _es *)(0x50 + (cur_page << 1)) = cur_pos;

_AH = 0x08;

geninterrupt(0x10);

_BH = cur_page;

_BL = atr;

_CX = 1;

_AH = 9;

geninterrupt(0x10);

if(mode == HORIZONTAL)

col ++;

else

if(mode == VERTICAL)

str ++;

else

return BAD_PARAM;

}

rest_cur(&old_cursor);

cursor(ON);

return OK;

}

else

return BAD_PARAM;

}

//*********************************************************************

//*********************************************************************

void main(){

clrscr();

vert_prn(2,2,"Vertical",15);

hor_prn(3,5,"Horisontal",15);

printche(3, 20, 'x', 14, 5);

border(2, 27, 15, 38, "Tilte",15, "ЪДїііАДЩ", 7);

scroll(UP, 1, 2, 3, 3, 1);

expl_win(10, 5, 15, 20, 1, "ЪДїііАДЩ", 7);

h_scroll(LEFT, 1, 1, 3, 3,"", 4);

//hv_light(3, 22, 2, 4, 0);

getch();

char buffer[2048];

gettext(1, 1, 40, 25, buffer);

puttext(41, 1, 80, 25, buffer);

movetext(3, 4,15, 4, 36, 20);

Лабораторна робота № 4

Назва роботи : Організація функціонування маніпулятора “миша”

Мета роботи: Ознайомитись з принципами функціонуваня маніпулятора “миша”. Засобами Turbo C організувати функціонування маніпулятора “миша”.

Загальні положення

Апаратно маніпулятор являє собою периферійні пристрій, що підключається до одного з адапторів послідовного зв`язку комп`ютера. До складу маніпулятора входять датчики преміщення “миші” в горизонтальному та вертикальному напрямках, індикатор натиску кнопок та блок зв`язку з інтерфейсом. Блок зв`язку з інтерфейсом передає в адаптер послідовного зв`язку байти даних при довільному натисканні кнопок та переміщенні “миші” в горизонтальному та вертикальному напрямках на певну величину, так звану “міккі”. Один “міккі” звичайно дорівнює 1/200 частині дюйма.

Значення зміщення, що передаються в адаптер, мають “знак”. Наприклад, при переміщенні маніпулятора знизу догори на один “міккі” передається байт 01Н, а при переміщенні зверху донизу - байт FFH. Обробник переривань від послідовного адаптера сумує отримані значення з врахуванням знаку. Таким чином, завжди є можливість визначити “біжучу” позицію маніпулятора відносо моменту початку спостереження. Звичайно спостереження за “мишею” починаються після завантаження драйвера “миші” або виконання операції ініціалізації “миші” з програми користувача.

Основними частинами драйвера миші є :

Секція інсталяції драйвера.

Обробник апаратних переривань від адаптера послідовного зв`язку (в ІВМ РС АТ адптерам СОМ1 та СОМ2 відповідають переривання - 0СН та 0СВ).

Обробник програмного переривання інтерфейса прикладної програми з “мишею” (переривання 33Н).

Обробник програмного переривання 10Н керування екраном.

Кожна програма, що використовує для вводу інформації маніпулятор

“миша”, повинна виконати такі підготовчі операції:

Визначити, чи інстальований драйвер “миші”.

Задати вид і форму курсора маніпулятора.

Описати межі переміщення курсора “миші” по екрану.

Описати “чутливість” курсора, яка дорівнює числу “міккі”,що приходяться на один піксель екрана по горизонталі та вертикалі.

Встановити поріг “подвоєної” швидкості курсора “миші”.

“Включити” курсор маніпулятора( зробити видимим на екрані).

Встановити курсор в початкову позицію на екрані у відповідності з потребами програм.

Багато з цих дій допомагає виконати функція ініціалізації та визначення біжучого стану маніпулятора стає в стан по замовченню:

Курсор маніпулятора встановлений в центрі екрана та виключений.

Чутливість маніпулятора по вертикалі дорівнює 2 “міккі” на піксел, по горизонталі - 1 “міккі” на піксел.

Поріг “подвійної” швидкості встановлюється рівним 64 “міккі”/сек.

Встановлюється форма курсора по змовченню.

Координати лівого верхнього кута області переміщення курсора маніпулятора відповідають координатам (00), а координати ніжнього правого кута області перемщення маніпулятора - максимальним координатам біжучого відеорежиму мінус 1.

Якщо треба встановити значення, відмінні від значень по замовченню, використовуються функції установки форми курсора,меж його переміщення, завдання значень чутливості та порогу подвійної швидкості.

Сі-функція завдання параметрів курсора маніпулятора “миша” для текстового режиму роботи адаптера в програмі *L4-1.C*.

В графічному режимі роботи відеоадаптора може бути описана довільна власна форма курсора в межах прямокутника 16x16 пікселів курсорів в графічному режимі описується двома масками розміром 16x16 біт кожна. XOR-маска (маска курсора ). При переміщенні курсора попередній вміст екрану відновлюється драйвером “миші “. Маски, комбінують, визначають спосіб обробки біжучого коду кольору пікселя на екрані (pixel-Picture Element - телевізійна точка на екрані).

Біт AND-маски

Біт XOR- маски

Колір піксела на екрані

0

0

Колір фону

0

1

Білий колір

1

0

Біжучий колір пікселя

1

1

Побітова інверсія біжучого кольору пікселя

В графічні режимах задається так звана “гаряча пляма” ( Hot spot) у відносних координатах, за точку відліку яких приймається верхній лівий кут прямокутника 16x16 пікселів. “Гаряча пляма” - це той піксел, на який вказує в біжучий момент графічний курсор. Сі-функція установки графічного “миші” в програмі *L4-2.C*.Для отримання графічнрго курсора,

Якого видно на довільному фоні, поступають наступним чином.AND-маскою задають із слів FFFFH,a XOR-маску описують таким чином, щоб в нійстояли одиниці в тих бітах, які утворюють контури кукрсора, а нулі - в усіх решта бітах маски.В прикладі викликається функція для завдання графічного курсору у вигляді стрілки (функція set-graph-cursor ( ) ).

Одразу після ініціалізації екрану, за область допустимих переміщень курсора по замовченню приймається весь екран. Але завжди є можливість обмежити переміщення курсору окремо по горизонталі та по вертикалі. Сі-фуекції для установки меж переміщення курсору по вертикалі та по горизонталі в програмах *L4-3.C*, *L4-4.C*. Після того, як виконані всі необхідні підготовчі операції, програма може використовувати маніпулятор для вводу інформації. Інформація, що вводиться, - це біжуча позиція курсора та стан кнопок маніпулятора. Періодичний ввід інформації з “миші” та попадання курсору в ті або інші області екрану дозволяють виконувати потрібні дії - “відкрити2 підменю і т.ін. визначення стану кнопки (натиснута двічі) використовується як команда на виконання програмою додаткових дій.

Сі-функція визначення біжучих координат курсора та стану кнопок “миші” в прикладі *L4-5.C* та прикладі *L4-6.C* (фіксація одноразового або дворазового натиску на кнопку “миші”).

При переміщенні маніпулятоорапостолу, драйвер пересуває “мишу” по екрану без участі програми. Але і прикладна програма має можливість керувати позицією курсора “миші”. Сі-функція позиціонування курсору “миші” в точку екрана з координатами int hor-position та int ver-position в прикладі *L4-7.C*.

Для отримання демонстраційної програми, яка читає стан “миші” та фіксує всі переміщення курсора “миші” в межах екрану у верхньому рядку треба, використовуючи файл проекту, виконати сумісну компіляцію файлів : ВООК3 - L3-13.C, L4-1.C,L4-3.C,L4-5.C - L4-8.C та ВООК2 - L8-11.C,L9-5.C,L9-8.C,L9-9.C.

Для отримання демонстраційної програми, що демонструє можливість використання вводу з “миші” для “малювати”, треба,використовуючи файл проекту, виконати сумісну компіляцію файлів ВООК3 - L4-1.C-L4-5.C, L4-7.C - L4-9.C та ВООК2 - L8-11.C, L9-2.C, L9-5.C. В ції програмі адаптер встаноалювається в графічний режим 12Н. Далі описується графічний курсор. В верхній частині екрану виводяться номера рядка та стовпчика курсора маніпулятора. Окрім того, відображається код кольора пікселя, що використовується для “малювання”.Для виводу текста в графічномуу режимі використовується варіанти функція scroll( ), hor-pm( ) та printche ( ), що працюють через BIOS (ВООК2 - L9-5.C, L9-2.C, L9-3.C. Позиціонування курсора виконує функція goto-xy ( ) (L8-11.C). При натисканні лівої кнопки маніпулятора він “малює” піксел в біжучий позиції. При кожому натисканні правої кнопки код кольору малюємого піксела збільшується на 1. При одночастному натисканні лівої та правої кнопок “миші” демонстраційна програма заверщує свою роботу для виводу пікселя на екран використовуються функція plot( )(BOOK2-L10-5.C).

Порядок виконаня роботи:

1. В середовищі MS DOS ініціалізувати одну з систем програмування :

Turbo C, Turbo C++,Borland C++.

2. Компілювати та виконуючі відповідні приклади,розглянути особливості функціонування функцій керування маніпулятором “миша”.

3. Зкомпілювати та виконати програми, що демонструють різні режими

використання “миші”. інформація файла клавіатура маніпулятор миша

4. Зробити висновки відносно можливостей маніпулятора “миші”.

Результат виконання програми.

#include <dos.h>

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#define CURSOR_ON() _AX=1; geninterrupt(0x33);

#define CURSOR_OFF() _AX=2; geninterrupt(0x33);

static unsigned screen_and_cursor_masks[] =

{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,

0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,

0x8000, 0xC000, 0xA000, 0x9000, 0xA800, 0xB400, 0xBA00, 0xBD00,

0xBE80, 0xBF40, 0xBFA0, 0xBFD0, 0xBFE0, 0xAE00, 0xA300, 0xE300,

};

struct MOUSE_STATE {

char buttons;

int hor_position;

int ver_position;

};

void set_text_cursor(int mode, unsigned int AND_mask, unsigned int XOR_mask){

struct REGPACK r;

r.r_ax = 0x0a;

r.r_bx = mode;

r.r_cx = AND_mask;

r.r_dx = XOR_mask;

intr(0x33, &r);

}

void set_graph_cursor(int hot_spot_column, int hot_spot_row, unsigned int far * screen_and_cursor_masks){

struct REGPACK r;

r.r_ax = 9;

r.r_bx = hot_spot_column;

r.r_cx = hot_spot_row;

r.r_es = FP_SEG(screen_and_cursor_masks);

r.r_dx = FP_OFF(screen_and_cursor_masks);

intr(0x33, &r);

}

void hor_movement(int start_hor_movement, int end_hor_movement){

_AX = 7;

_CX = start_hor_movement;

_DX = end_hor_movement;

geninterrupt(0x33);

}

void vert_movement(int start_vert_movement, int end_vert_movement){

_AX = 8;

_CX = start_vert_movement;

_DX = end_vert_movement;

geninterrupt(0x33);

}

void ms_state(struct MOUSE_STATE * current_state){

struct REGPACK r;

r.r_ax = 3;

intr(0x33, &r);

current_state -> buttons = r.r_bx;

current_state -> hor_position = r.r_cx;

current_state -> ver_position = r.r_dx;

}

int ms_release(struct MOUSE_STATE * current_state){

struct REGPACK r;

r.r_ax = 6;

r.r_bx = current_state -> buttons;

intr(0x33, &r);

current_state -> hor_position = r.r_cx;

current_state -> ver_position = r.r_dx;

return r.r_bx;

}

void ms_move(int hor_position, int ver_position){

_AX = 4;

_CX = hor_position;

_DX = ver_position;

geninterrupt(0x33);

}

void main(){

struct MOUSE_STATE cur_state;

_AX=0;

geninterrupt(0x33);

if(_AX==0){

puts("No mouse !!!");

exit(-1);

}

set_text_cursor(1, 0x000e, 0x000f);

hor_movement(0, 639);

vert_movement(16, 199);

ms_move(0, 160);

CURSOR_ON();

while (cur_state.buttons != 0x03){

ms_state(&cur_state);

gotoxy(1,1);

printf("x=%i\n",cur_state.hor_position);

printf("y=%i\n",cur_state.ver_position);

if (cur_state.buttons == 0x01) printf("left ");

if (cur_state.buttons == 0x02) printf("right ");

if (cur_state.buttons == 0x03) printf("both ");

}

CURSOR_OFF();

_AX = 0x0012;

geninterrupt(0x10);

_AX=0;

geninterrupt(0x33);

if(_AX==0){

puts("no mouse !");

exit(-1);

}

set_graph_cursor(0, 0, screen_and_cursor_masks);

hor_movement(0, 639);

vert_movement(16, 199);

ms_move(160, 160);

ms_state(&cur_state);

CURSOR_ON();

while (cur_state.buttons != 0x01){


Подобные документы

  • Клавіатури та маніпулятори, принципи їх дії, основні характеристики та застосування. Графічні планшети та сенсорні екрани. Автоматичні засоби вводу графічної інформації. Програма Fine Reader 4. Сканування та автоматичне розпізнавання документів.

    курсовая работа [3,8 M], добавлен 30.03.2017

  • Характеристика клавіатурних шпигунів та захист від них. Засоби для стеження введення з клавіатури. Програми моніторинг введенням клавіатури. Стеження за клавіатурним введенням за допомогою пасток та опитування клавіатури. Апаратні клавіатурні шпигуни.

    курсовая работа [494,5 K], добавлен 09.01.2013

  • Клавіатура як один з найважливіших пристроїв комп’ютера, її призначення та конфігурація. Основні види клавіатури, їх характеристика та відмінні риси, порядок і правила діагностування. Методика пошуку несправностей і ремонту. Побудова миші та трекболів.

    курсовая работа [182,2 K], добавлен 24.05.2009

  • Користування стандартним та форматованим вводом-виводом. Використання вводу та виводу аргументу. Розробка лінійних програм. Програми з розгалуженням, циклічні програми з регулярною змінною аргументу. Використання вказівників для роботи з масивами даних.

    курсовая работа [4,6 M], добавлен 27.02.2014

  • Мережне адміністрування. Програми для віддаленого адміністрування. Віддалене управління засобами Telnet. Можливості програми Remote Administrator 2.2. Безпека Radmin. Режим обміну файлами. Запит логіна і пароля перед початком роботи з File Manager.

    курсовая работа [1,5 M], добавлен 24.03.2009

  • Структурна схема та принцип дії ємнісної та фотоелектричної клавіатури. Функції герконових, мембранних клавіш та безконтактних перемикачів. Схема та скен-коди стандартної клавіатури. Структурна схема перетворювача Хола. Структура контролера клавіатури.

    реферат [562,6 K], добавлен 14.04.2010

  • Базові типи змінних. Елементарний ввід-вивід. Умовні оператори та оператори множинного вибору. Основні функції вводу даних із клавіатури scanf, gets, getchar. Визначення основних (базових) типів даних. Вивід повідомлення при невірно заданому ключі.

    контрольная работа [74,6 K], добавлен 03.10.2010

  • Створення довідкової системи по зменшенню витрат часу на здобуття інформації по кримінальному праву. Розробка алгоритму основної програми на мові програмування Turbo Pascal з підключенням модуля СRT, якій відповідає за графіку і DOS та працює з файлами.

    курсовая работа [20,8 K], добавлен 07.10.2010

  • Широке використання інформаційних технологій у всіх сферах життя суспільства. Інформація як об’єкт захисту. Основні види загроз безпеки інформації в комп’ютерних мережах. Несанкційований доступ до інформації і його мета. Порушники безпеки інформації.

    реферат [253,2 K], добавлен 19.12.2010

  • Арифметичні основи, на яких ґрунтується функціонування комп'ютерної техніки. Основні поняття дискретної обробки інформації. Системи числення, форми подання чисел у комп'ютерах. Арифметичні операції, що виконуються над числами, подані у двійковому коді.

    учебное пособие [903,6 K], добавлен 18.12.2010

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.