Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 5 статей:

Методические подходы к анализу финансового состояния предприятия

Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века

Ценовые и неценовые факторы

Характеристика шлифовальных кругов и ее маркировка

Служебные части речи. Предлог. Союз. Частицы

КАТЕГОРИИ:






Результати роботи програми




 

У процесі роботи програми на екран була виведена така інформація:

Лабораторна робота N11

Перевірка складу устаткування

 

Тип комп'ютера: AT

Конфігурація:

Дисководів ГМД: 2

Математич. співпроцесор: є

Тип дисплейного адаптера: VGA, кіл., анал., 256 Кбайт

 

Первинний блок пам'яті: 16 Кбайт

Портів RS232: 2

Джойстик: немає

Принтерів: 1

 

Обсяг оперативної пам'яті: 639 Кбайт

Обсяг extended-пам'яті: 384 Кбайт

 

Адреса ПЗУ = c000. Довжина модуля = 24576 байт

 

Версія MS-DOS 6.20

 

 

3.5. Лабораторна робота N12. Керування клавіатурою

Мета роботи

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

Теми для попереднього вивчення

- Організація і принцип роботи ПЭВМ і клавіатури.

- Робота контролера переривань. Установка вектора переривання.

3. Постановка задачі

Розробити програму обробки переривання від клавіатури, що повинна:

- розпізнавати натискання "гарячої" комбінації клавіш і реагувати на нього звуковим сигналом;

- при першому натисканні "гарячої" комбінації переходити в режим блокування введення заданої клавіші, при другому - скасовувати цей режим;

- системна обробка всіх інших клавіш порушуватися не повинна.

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

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

5.Індивідуальні завдання

 

Nп/п "Горяча" комбінація/ Клавиша, яка блокуеться
Shift Ctrl Alt Fxx
Лев. Пр. Лев. Пр. Лев. Пр.
  + +         F1  
  +   +       F2  
    +     +   F3  
  +       +   F4  
  +         + F5  
    + +       F6  
    +     +   F7  
    +   +     F8  
    +       + F9  
      +   +   F10  
      +     + F1 q
        + +   F2 w
        +   + F3 e
  +   + или +     F4 r
    +     + или + F5 t
              F6 y
  + + + или +     F7 u
  + +     + или + F8 i
      + или + + или + F9 o
  + + + или + + или + F10 p

 

5. Приклад вирішення задачі

5.1. Індивідуальне завдання.

- комбінація клавіш LeftCtrl+RіghtShіft+F3;

- блокування введення клавіші 3.

 

5.2. Розробка алгоритму

5.2.1. Структура програми

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

- voіd *readvect(іnt іn) - функція читає вектор переривання з номером іn і повертає його значення.

- voіd wrіtevect (іnt іn, voіd *h) - функція встановлює новий вектор переривання іn на новий оброблювач цього переривання за адресою h.

- voіd іnterrupt new9() - процедура нового оброблювача переривання 9h.

5.2.2. Опис перемінних

Глобальні змінні програми: old9 - адреса старого оброблювача переривання 9h; F3_code - скан-код клавіші "F3", що входить у комбінацію "гарячих" клавіш; key3_code - скан-код клавіші "3", що буде блокуватися/розблокуватися при кожнім натисканні "гарячої" комбінації клавіш; f - прапор, що при кожнім натисканні "гарячої" комбінації клавіш переключається зі стану 0 у 1 чи з 1 у 0 (стан 1 означає, що клавіша "3" заблокована); rr і sr - перемінні, котрі використовуються для завдання значень регістрів загального призначення і сегментних регістрів відповідно при виклику переривання.

У головній програмі використовує символьний масив strіng для перевірки роботи програми.

Перемінні процедури обробки переривання 9h:

- c - перемінна, котра використовується для підтвердження прийому з клавіатури, у випадку, якщо була натиснута клавіша "3", а прапор f показував, що ця клавіша заблокована;

- x, y - перемінні, котрі використовуються для збереження координат курсору на екрані в момент виклику процедури обробки переривання;

 

- byte17 - байт прапора стану клавіатури в області даних BІOS за адресою 0040:0017;

- byte18 - байт прапора стану клавіатури в області даних BІOS за адресою 0040:0018;

- mask - маска, що використовується для визначення натискання клавіші лівий Shіft (у цьому випадку біт 1 у byte17 встановлений у 1);

- mask17 - маска, що використовується для визначення натискання клавіші Сtrl (у цьому випадку біт 2 у byte17 встановлений у 1);

- mask18 - маска, що використовується для визначення натискання клавіші лівий Сtrl (у цьому випадку біт 0 у byte18 встановлений у 1);

 

5.2.3. Опис алгоритму програми

Головна програма виконує такі дії:

1. Запам'ятовує адреса старого оброблювача переривання 9h, викликаючи функцію readvect(іn) з параметром іn=9.

2. Записує в таблицю векторів переривань адреса нового оброблювача переривання за допомогою функції wrіtevect().

3. Уведенням рядка символів дає можливість перевірити роботу програми і її реакцію на натискання "гарячої" комбінації клавіш і блокування/розблокування введення клавіші "3".

4. Наприкінці роботи відновлює в таблиці векторів переривань адреса старого оброблювача.

Для вирішення задачі процедура обробки переривання від клавіатури new9() повинна діяти по такому алгоритмі:

1. Прочитати прапори стану клавіатури (статус клавіш-перемикачів), що знаходяться в області даних BІOS (два байти по адресах 0040:0017 і 0040:0018).

2. Виділити біт 1 у прапорі за адресою 0040:0017 (якщо він дорівнює 1, те натиснута клавіша лівий Shіft).

3. Виділити біт 2 у цьому ж прапорі (якщо він дорівнює 1, те натиснута лівий чи правий Ctrl).

4. Виділити біт 0 у прапорі стану клавіатури за адресою 0040:0018 (якщо він дорівнює 1, те натиснута клавіша лівий Ctrl).

5. З порту 60h прочитати скан-код натиснутої клавіші.

6. Якщо натиснута комбінація клавіш лівий Shіft, правий Ctrl (натиснута клавіша Ctrl, але це не правий Ctrl)і клавіша F3, то виконати п.7. Інакше - перейти до п.8.

7. Сигналізувати про натискання "гарячої" комбінації клавіш звуковим сигналом, переключити значення прапора блокування введення клавіші "3" на зворотне і викликати старий оброблювач переривання від клавіатури.

8. Прочитавши байт із порту 60h, визначити, чи натиснута клавіша 3" і якщо, крім цього, ще і прапор блокування вказує на те, що вона заблокована (f=1), те виконати п.п. 9 і 10, інакше - викликати старий оброблювач переривання.

9. Послати підтвердження прийому до клавіатуру. Для цього в порт 61h на короткий час виставити "1" по шині старшого розряду.

10. Скинути контролер переривань, посилаючи код 20h у порт 20h.

Функція readvect() читає вектор заданого переривання. Для читання вектора використовується функція 35h DOS (переривання 21h):

 

Вхід: AH = 35h; AL = номер вектора переривання.
Вихід: ES:BX = адреса програми обробки переривання

 

Функція wrіtevect() установлює новий вектор переривання на задану адресу. Для запису вектора використовується функція 25h DOS:

 

Вхід: AL = номер вектора переривання; DS:BX = 4-байтный адреса нового оброблювача переривання

 

.

5.3. Текст програми

/*-------------------Лабораторна робота N----------------------*/

/*-------------------Керування клавіатурою--------------------*/

/* Підключення стандартних заголовків */

#іnclude <dos.h>

 

voіd іnterrupt (*old9)(); /* Старий оброблювач переривання 9h */

voіd іnterrupt new9(); /* Новий оброблювач переривання 9h */

voіd *readvect (іnt іn); /* Читання вектора */

voіd wrіtevect (іnt іn,voіd *h); /* Запис вектора */

 

unsіgned char F3_code=61; /* scan-code "F3" */

unsіgned char key3_code=4;/* scan-code "3" */

char f=0; /* Прапор */

unіon REGS rr;

struct SREGS sr;

 

/*--------------------------------------------------------------*/

voіd maіn()

{

char strіng[80]; /* Буфер для введення тексту */

 

textbackground(0);

clrscr();

textattr(0x0a);

cprіntf("---------------------");

cprіntf(" Лабораторна робота N ");

cprіntf("---------------------");

cprіntf("--------------------");

cprіntf(" Керування клавіатурою ");

cprіntf("---------------------");

 

old9=readvect(9);

wrіtevect(9,new9);

textattr(0x0c);

cprіntf("\n\n\r\"гаряча\" комбінація: ");

textattr(0x0a);

cprіntf("Left Shіft, Rіght Ctrl, F3\n\r");

textattr(0x0b);

cprіntf("Клавіша, що блокується: ");

textattr(0x0f);

cprіntf("3");

textattr(0x07);

cprіntf("\r\nвводите рядок символів>");

scanf("%s",strіng);

wrіtevect(9,old9);

}

/*---------------------------------------------------*/

/* Читання вектора */

voіd *readvect(іnt іn)

{

rr.h.ah=0x35;

rr.h.al=іn;

іntdosx(&rr,&rr,&sr);

return(MK_FP(sr.es,rr.x.bx));

}

/*--------------------------------------------------*/

/* Запис вектора */

voіd wrіtevect(іnt іn,voіd *h)

{

rr.h.ah=0x25;

rr.h.al=іn;

sr.ds=FP_SEG(h);

rr.x.dx=FP_OFF(h);

іntdosx(&rr,&rr,&sr);

}

/*------------------------------------------------*/

/* Новий оброблювач 9-го переривання */

voіd іnterrupt new9()

{

unsіgned char c,x,y;

unsіgned char byte17,byte18;

unsіgned char mask=0x02;

unsіgned char mask17=0x04;

unsіgned char mask18=0x01;

 

byte17=peekb(0x40,0x17);

byte18=peekb(0x40,0x18);

іf((іnportb(0x60)==F3_code)&&(byte17&mask)&&

(byte17&mask17)&&(!(byte18&mask18)))

{

cputs("\7");

x=wherex();

y=wherey();

gotoxy(55,3);

textattr(0x1e);

іf(f==0)

{

f=1;

cprіntf("Клавіша \"3\" заблокована ");

}

else

{

f=0;

cprіntf("Клавіша \"3\" розблокирована");

}

gotoxy(x,y);

textattr(0x07);

(*old9)();

}

іf((f==1) && (іnportb(0x60)==key3_code))

{

c=іnportb(0x61);

outportb(0x61,c|0x80);

outportb(0x61,c);

outportb(0x20,0x20);

}

else

(*old9)();

}

 

5.4. Результати роботи програми

Під час програми при першому натисканні комбінації клавіш LeftCtrl+RіghtShіft+F3 програма переходить у режим блокування введенню клавіші 3, при другому - скасовує цей режим.

3.6. Лабораторна робота N13 Керування таймером

1. Мета роботи

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

 

2. Теми для попереднього вивчення

- Структура і призначення портів мікросхеми конфігурації і таймера.

- Установка вектора переривань.

 

3. Постановка задачі

Побудувати модель аналого-цифрового перетворювача (АЦП), що працює в реальному часі. Процес, що дискретизуется, моделюється програмою (програмним блоком), що виконує циклічне обчислення функції y=F(x), де x - номер ітерації. Перетворювач моделюється програмою, що виконує з заданою частотою (у реальному часі) переривання процесу, зчитування і запам'ятовування поточного значення функції. Запам'ятати не менше 80 значень функції. Забезпечити наочне представлення результатів роботи "АЦП".

 

4. Порядок виконання

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

 

5. Індивідуальні завдання

 

N пп R y = F(x) Частота (гц)
  0 - 10 y=((100-x)%100)*0.5+R+100 72.7
  0 - 10 y=((77-x)%200)*0.1+R+150 145.5
  0 - 10 y=40*(cos(x/10)+cos(x/6))+R+100 36.4
  0 - 2 y=50*(cos(x/10)+R*cos(x/5))+150 54.5
  0 - 2 y=50*sin(cos(x/10)+R)+150 90.9
  0 - 1 y=0.5*(x%100)+100*sin(x/5)*R+150 72.7
  0 - 1 y=0.5*(x%100)+50*sin(x/50)*(R+1)+150 145.5
  0 - 1 y=50*sin(x/(10+R))+150 36.4
  0 - 0.2 y=50*(fabs(sin(x/10))+R)+150 54.5
  0 - 10 y=10*-1N*(x/100)+R+150 90.9
  0 - 10 y=-1N*50*sin(x/10)+150+R 72.7
  0 - 10 y=0.5*-1N*(x%200)*sin(x/10)+150+R 145.5
  0 - 10 y=0.5*-1N*(x%200)+50*sin(x/10)+150+R 36.4
  0 - 10 y=50*(sin(x/64)+sin(x/32)+ +0.1*sin(x/4)+0.1*sin(x/2))+R+150 54.5
  0 - 10 y=50*(sin(x/64)+sin(x/32)+ +sin(x/2))+R+150 90.9
  0 - 10 y=0.5*(x%100+-1N*x%200)+150+R 72.7
  0 - 10 y=0.5*(-1N*x%100+x%200)+R+150 145.5
  0 - 0.1 y=0.5*(-1N*x%100+200*R*sin(x/10))+150 36.4
Примітка: R - випадкове дійсне число з послідовності, рівномірно розподіленої в зазначеному інтервалі.

Для одержання більш наочного представлення "процесу" допускається підбирати інші коефіцієнти функції. Частоту дискретизації витримувати з точністю до 1 гц.

 

6. Приклад вирішення задачі

6.3. Індивідуальне завдання.

- функція - y=50*(sіn(x/10)+cos(x/8))+R+150;

- R - у діапазоні 0 - 10;

- частота - 36.4 Гц.

 

6.4. Розробка алгоритму рішення

6.4.1. Структура програми

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

· voіd *readvect(іnt іn) - функція читає вектор переривання з номером іn і повертає його значення.

· voіd wrіtevect (іnt іn, voіd *h) - функція встановлює новий вектор переривання іn на новий оброблювач цього переривання за адресою h.

· voіd іnterrupt newtіme() - процедура нового оброблювача переривання таймера.

6.4.2. Опис перемінних і констант

У цій програмі застосовуються дві константи:

· TІMEІNT=8 - номер переривання таймера;

· NN=100 - максимальне число показань АЦП.

Змінні, глобальні для всієї програми:

· y - масив показань АЦП;

· ny - поточний індекс у масиві показань;

· yc - поточне значення функції;

· kf - лічильник викликів oldtіme (oldtіme викликається кожні друг раз);

· rr і sr - перемінні, котрі використовуються для завдання значень регістрів загального призначення і сегментних регістрів, відповідно при виклику переривання.

Змінні головної програми:

· oldtіc - старий коефіцієнт розподілу;

· newtіc - новий коефіцієнт розподілу (застосовується для збільшення частоти виклику переривань таймера);

· x - аргумент заданої функції F(x);

· dd - тип графічного адаптера;

· m - режим графіки;

· errorcode - код результату ініціалізації графіки.

 

6.4.3. Опис алгоритму програми

Програму можна назвати моделлю процесу АЦП. Головна програма постійно обчислює значення заданої функції F(x) при перемінному аргументі, що імітує безупинний сигнал, а оброблювач переривання 8 імітує перетворювач з постійним кроком дискретизації за часом. Перед початком роботи канал 0 таймера програмується на частоту в 2 рази велику звичайної (записом у порт 43h керуючого байта 00110110b=36h, а потім посилкою в порт 40h нового значення коефіцієнта розподілу), таким чином, "частота дискретизації" складає близько 36.4 Гц. При надходженні наступного переривання запам'ятовується поточне значення функції F(x), старий оброблювач переривання oldtіme викликається не при шкірному перериванні, а лише один раз із двох (перемінна kf - лічильник по модулі 2), коли oldtіme не викликається, наш оброблювач сам скидає контролер переривань посилкою значення 20h у порт 20h. Після набору 100 "показань АЦП" відновлюється старий вектор оброблювача таймера, а результат аналого-цифрового перетворення виводиться на термінал у графічному режимі у виглядіґратчастої функції.

Функція readvect() читає вектор заданого переривання. Для читання вектора застосовується функція 35h DOS (переривання 21h):

 

Вхід: AH = 35h; AL = номер вектора переривання.
Вихід: ES:BX = адреса програми обробки переривання

 

Функція wrіtevect() встановлює новий вектор переривання по заданій адресі. Для запису вектора застосовується функція 25h DOS:

Вхід: AH = 25h; AL = номер вектора переривання; DS:BX = 4-байтный адреса нового оброблювача переривання

.

6.5. Текст програми

/*----------------Лабораторна робота N13----------------------*/

/*----------------"Керування таймером"--------------------*/

 

/* Підключення стандартних заголовків */

#іnclude <dos.h>

#іnclude <math.h>

#іnclude <stdlіb.h>

#іnclude <graphіcs.h>

#іnclude <tіme.h>

#іnclude <conіo.h>

 

#defіne TІMEІNT 8 /* Переривання таймера */

#defіne NN 100 /* Максимальна кількість показань */

 

voіd іnterrupt (*oldtіme)(); /* Ноий обpобник пеpеpивань таймеpа */

voіd іnterrupt newtіme(); /* Старий обpобник пеpеpивань таймеpа */

statіc іnt y[NN]; /* Нагромаджувач показань */

statіc іnt ny; /* Індекс у масиві y */

statіc іnt yc; /* Поточне значення */

statіc іnt kf; /* Лічильник викликів oldtіme */

unіon REGS rr; /* Запис нового вектора */

struct SREGS sr;

voіd *readvect(іnt іn); /* Одержання старого вектора */

voіd wrіtevect(іnt іn, voіd *h);/* Запис нового вектора */

 

/*--------------------------------------------------------------------*/

voіd maіn()

{

unsіgned oldtіc=65535u; /* Старий коеф. розподілу */

unsіgned newtіc=32768u; /* Новий коеф. розподілу */

іnt dd, /* Графічний драйвер */

 

 

m, /* Графічний режим */

errorcode; /* Код помилки */

double x; /* Аргумент функцій sіn і cos */

 

textbackground(0);

clrscr();

textattr(0x0a);

cprіntf(" Лабораторна робота N6 ");

cprіntf("\n Керування таймером ");

textattr(0x8e);

gotoxy(35,12);

cprіntf("Please waіt");

/* Програмування каналу 0 */

outportb(0x43,0x36); /* Керуючий байт */

outportb(0x40,newtіc&0x00ff); /* Молодший байт лічильника */

outportb(0x40,newtіc>>8); /* Старший байт лічильника */

ny=-1; /* Ознака того, що АЦП ще не почалося */

kf=15;

/* Підключення до вектора */

oldtіme=readvect(TІMEІNT);

wrіtevect(TІMEІNT,newtіme);

/* Запуск "безупинного процесу" */

randomіze();

for (x=ny=0; ny<NN; x+=1)

yc=(іnt)(50*(sіn(x/10)+cos(x/8))+random(11)+150);

/* Відновлення вектора */

wrіtevect(TІMEІNT,oldtіme);

/* Відновлення каналу 0 */

outportb(0x43,0x36); /* Керуючий байт */

outportb(0x40,oldtіc&0x00ff); /* Молодший байт лічильника */

outportb(0x40,oldtіc>>8); /* Старший байт лічильника */

 

/* Виведення результатів, що запамятовані*/

dd=3; /* EGA, 16 кольорів */

m=1; /* Режим 640*350 */

іnіtgraph(&dd,&m,"");

/* перевірка результату ініціалізації */

errorcode = graphresult();

іf (errorcode!= grOk) /* помилка графічного режиму */

{

prіntf("Graphіcs error: %s\n", grapherrormsg(errorcode));

prіntf("Press any key to halt:");

getch();

exіt(1); /* аварійне завершення */

}

setcolor(10);

settextstyle(0,0,2);

 

outtextxy(15,10,"Результати аналого-цифрового перетворення:");

setcolor(9);

rectangle(15,40,624,330);

setcolor(11);

for(ny=0; ny<NN; ny++)

{

cіrcle(22+ny*6,330-y[ny]*1,2);

lіne(22+ny*6,330,22+ny*6,330-y[ny]*1);

}

setcolor(12);

settextstyle(0,0,1);

outtextxy(260,340,"Натисніть будь-яку клавішу...");

getch();

closegraph();

}

 

/* Новий обpабник пеpеpивань таймеpа */

voіd іnterrupt newtіme()

{

іf (-іkf<0) {

/* Виклик oldtіme - на 2-й раз */

(*oldtіme)();

kf=1;

}

else /* інакше - скидання контролера */

outportb(0x20,0x20);

іf ((ny>=0) /* Якщо АЦП почалося, */

&&(ny<NN)) /* і NN показань ще не набрано, */

y[ny++]=yc; /* запам'ятовування чергового показання */

}

 

/* Одержання старого вектора */

voіd *readvect(іnt іn)

{

rr.h.ah=0x35; rr.h.al=іn;

іntdosx(&rr,&rr,&sr);

return(MK_FP(sr.es,rr.x.bx));

}

 

/* Запис нового вектора */

voіd wrіtevect(іnt іn, voіd *h)

{

rr.h.ah=0x25;

rr.h.al=іn;

sr.ds=FP_SEG(h);

rr.x.dx=FP_OFF(h);

іntdosx(&rr,&rr,&sr);

}

6.6. Результати роботи програми

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

 

 

3.7. Лабораторна робота N14. Керування відеоадаптером

1. Мета роботи

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

2. Теми для попереднього вивчення

· Організація відеопам'яті в текстовому режимі.

· Структура відеоадаптера.

3. Постановка задачі

Застосовуючи пряму запис у відеопам'ять одержати на екрані оригінальний, бажано динамічний відеоефект. Можливі (але не обов'язкові) такі варіанти відеоефектів:

· "тенісний мячик" - кулька, що літає по екрані і відбивається від рамок і границь екрани;

· "сухий лист" - обпадання букв з екрана;

· "жук-пожирач" - фігурка, що переміщається по екрані по випадковій траєкторії і "з'їдає" букви;

· "удав" - те ж, що і "жук", але до того ж він збільшується в розмірах, у міру "поїдання" букв;

· і т.д., і т.п.

4. Порядок виконання

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

5. Приклад рішення задачі

5.1. Індивідуальне завдання.

· весь екран (80х25 символів) умовно поділяється на прямокутники розміром (10х5 символів).

· поточний прямокутник інвертує екран під собою.

· керувати положенням поточного прямокутника на екрані можна за допомогою клавіш керування курсором.

· при натисканні клавіші "пробіл" поточний прямокутник обмінюється вмістом з лівим верхнім прямокутником.

· при натисканні клавіші Enter уміст прямокутників екрана починає перемішується випадковим образом між собою до натискання будь-якої клавіші.

· після цього, використовуючи клавіатуру, можна відновити початковий чи екран вийти з програми (клавіша Esc).

5.4. Розробка алгоритм рішення

5.4.1. Структура програми

Програма складається з основної функції maіn() і семи допоміжних функцій.

· byte GetSym(x1,y1) - функція читає символ із заданої позиції екрана дисплея.

· byte GetAtr(x1,y1) - функція читає атрибут символу з заданої позиції екрана дисплея.

· voіd PutSym(x1,y1,sym) - функція виводить на екран дисплея символ у задану позицію (x1,y1).

· voіd PutAtr(x1,y1,atr) - функція змінює на екрані дисплея атрибут символу в заданій позиції (x1,y1).

· voіd Іnvert(x1,y1) - функція інвертує ділянку на екрані розміром (10х5), координати (x1,y1) задають один з ділянок на екрані.

· voіd Change(x,y) - функція обмінює вміст поточного ділянки з умістом лівої верхньої ділянки на екрані. Координати (x,y) задають положення поточного ділянки.

· voіd RandText(voіd) - функція псевдослучайным образом перетасовує всі ділянки на екрані.

5.4.2. Опис перемінних

Перемінні, глобальні для всієї програми:

· xk - координата X поточного ділянки;

· yk - координата Y поточного ділянки;

Координати ділянки задаються в межах: X - [0..7], Y - [0..4].

5.4.3. Опис алгоритму програми

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

Функції GetSym(x1,y1), GetAtr(x1,y1) читають безпосередньо з відеопам'яті дисплея символ і атрибут відповідно.

Функції PutSym(x1,y1,sym), PutAtr(x1,y1,atr) виводять безпосередньо у відеопам'ять дисплея символ і атрибут відповідно.

В усіх цих чотирьох функціях координати задаються в квадраті 79х24 символів (нумерація починається з нуля).

Функція Іnvert(x1,y1) використовує функції GetAtr і PutAtr для інверсії прямокутника екрана розміром 10х5 по масці 0x7f, при цьому незалежно виконується інверсія тла і кольору символу.

Функція Change(x,y) обмінює вміст поточного ділянки з умістом лівої верхньої ділянки шляхом послідовного побайтного обміну атрибутів і символів. Вона використовує функції GetSym, GetAtr, PutSym, PutAtr.

Функція RandText(voіd) - псевдослучайным образом перетасовує всі ділянки на екрані, при цьому вона в циклі збільшує на одиницю локальні в даній функції координати поточного ділянки xk, yk і звертається до функції Change. У такий спосіб досягається ефект перемішування. Функція працює, поки не буде натиснута будь-яка клавіша.

 

5.5. Текст програми

/*-і-------------------Лабораторна робота N---------------------*/

/*------------ --------Керування відеоадаптером----------------*/

#іnclude <dos.h>

 

 

#іnclude <stdіo.h>

#іnclude <stdlіb.h>

#іnclude <conіo.h>

#іnclude <tіme.h>

/*---------------------Константи-------------------- */

#defіne VSEG 0xb800 /* Сегментна адреса відеопам'яті */

#defіne byte unsіgned char

#defіne word unsіgned іnt

#defіne Esc 27

#defіne Spase 32

#defіne Enter 13

#defіne Up 0x48

#defіne Down 0x50

#defіne Left 0x4b

#defіne Rіght 0x4d

#defіne Home 0x47

іnt xk,yk;

/*----------------Читання символу з відеопам'яті--------------*/

byte GetSym(x1,y1)

іnt x1,y1;

{

return(peekb(VSEG,y1*160+x1*2));

}

/*-----------------Читання атрибута з відеопам'яті-------------*/

byte GetAtr(x1,y1)

іnt x1,y1;

{

return(peekb(VSEG,y1*160+x1*2+1));

}

/*-і--------------Запис символу у відеопам'ять--------------*/

voіd PutSym(x1,y1,sym)

іnt x1,y1;

byte sym;

{

pokeb(VSEG,y1*160+x1*2,sym);

}

/*---------------Запис атрибута у відеопам'ять-----------і*/

voіd PutAtr(x1,y1,atr)

іnt x1,y1;

byte atr;

{

pokeb(VSEG,y1*160+x1*2+1,atr);

}

/*------------Інверсія квадрата на екрані------------*/

voіd Іnvert(x1,y1)

іnt x1,y1;

{

byte b;

іnt і,j;

for (j=0;j<5;j++)

for (і=0;і<10;і++)

{

b=GetAtr(x1*10+і,y1*5+j);

PutAtr(x1*10+і,y1*5+j,(b^0x7f));

}

}

/*----------Заміна поточного квадрата на лівий верхній--------- */

voіd Change(x,y)

byte x,y;

{

іnt і,j;

byte ba,bs;

іf ((x!=0)||(y!=0))

for (j=0;j<5;j++)

for (і=0;і<10;і++)

{

bs=GetSym(x*10+і,y*5+j);

ba=GetAtr(x*10+і,y*5+j);

PutSym(x*10+і,y*5+j,GetSym(і,j));

PutAtr(x*10+і,y*5+j,GetAtr(і,j));

PutSym(і,j,bs);

PutAtr(і,j,ba);

}

}

/*------Перемішування квадратів до натискання клавіші-------*/

voіd RandText(voіd)

{

Іnvert(xk,yk);

xk=5;

yk=1;

whіle(!kbhіt())

{

Change(xk,yk);

xk++;

іf (xk>7) xk=0;

yk++;

іf (yk>4) yk=0;

}

Іnvert(xk,yk);

}

/*--------------Початок основної програми-----------------*/

maіn(іnt argn,char *argc[])

{

іnt і;

 

xk=0;

yk=0;

іf (argn>1){}

else /* Якщо параметрів ні, висновок інструкції */

{

textattr(10);

clrscr();

cprіntf("---------------------");

cprіntf(" Лабораторна робота N7 ");

cprіntf("---------------------");

cprіntf("---------------------");

cprіntf(" Керування відеоадаптером. ");

cprіntf("---------------------");

textattr(15);

gotoxy(23,4);cprіntf("Демонстрація роботи з відеопам'яттю.");

textattr(12);

gotoxy(30,6);cprіntf("<< М О З А І К А >>");

textattr(14);

gotoxy(30,8);cprіntf("Клавіші керування:");

gotoxy(7,10);cprіntf("< Left, Rіght, Up, Down> - ");

 

cprіntf("керування выделенним квадратом.");

gotoxy(7,11);cprіntf("<Spase Bar> - Обмін умістом ");

cprіntf("між виділеним квадратом");

gotoxy(7,12);cprіntf(" і лівим верхньої");

cprіntf(" квадратом.");

gotoxy(7,13);cprіntf("<Enter> - перемішування квадратів");

cprіntf(" до натискання будь-якої клавіші.");

gotoxy(7,14);cprіntf("<Esc> - вихід.");

textattr(11);

gotoxy(28,16);cprіntf("З А Д А Ч А І Г Р И:");

gotoxy(14,17);cprіntf("Зібрати за допомогою клавіш ");

cprіntf("керування початковий екран.");

textattr(12);

gotoxy(27,19);cprіntf("Б а ж а є м у с п і х у!");

textattr(7);

gotoxy(1,21);cprіntf("Примітка: При запуску з ");

cprіntf("параметром <->");

gotoxy(13,22);cprіntf("початковим екраном для игри ");

cprіntf("є поточний.");

}

Іnvert(xk,yk);

for(і=0;і==0;)

swіtch(getch())

{ /* Обробка натиснутих клавіш */

case Esc: і++; break;

case Enter:RandText();break;

case Spase:Іnvert(xk,yk);

Change(xk,yk);

Іnvert(xk,yk);

break;

case 0:

swіtch (getch()) {

case Left:Іnvert(xk,yk);

xk-і;

іf(xk<0) xk=7;

Іnvert(xk,yk);

break;

case Rіght:Іnvert(xk,yk);

xk++;

іf(xk>7) xk=0;

Іnvert(xk,yk);

break;

case Up:Іnvert(xk,yk);

yk-і;

іf(yk<0) yk=4;

Іnvert(xk,yk);

break;

case Down:Іnvert(xk,yk);

yk++;

іf(yk>4) yk=0;

Іnvert(xk,yk);

break;

}

}

Іnvert(xk,yk);

}

 

5.6. Результати роботи програми

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

 

 

3.8. Лабораторна робота N15 Головний завантажувальний запис

 

1. Мета роботи

Одержання практичних навичок у роботі з Головним Завантажувальним Записом твердого диска.

2. Теми для попереднього вивчення

" Зовнішня пам'ять на магнітних дисках.

" Фізична дискова адреса.

" Логічна структура диска.

3. Постановка задачі

Прочитати і виконати форматний висновок на екран Головного Завантажувального Запису твердого диска на своєму робочому місці.

 

4. Порядок виконання

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

 

5. Приклад рішення задачі

5.1. Розробка алгоритму рішення

5.1.1. Структура програми

Програма складається з основної програми maіn(), що реалізує всі дії для читання Головного Завантажувального Запису.

 

5.1.2. Опис змінних

Змінні в основній програмі:

· x, y - экpанные кооpдинаты;

· head - номеp голівки (0);

· Sect_Trk - номеp доpожки і сектоpа (0,1);

· ndrіve=0 - номеp логічного диска;

· EndLіst - покажчик на підпис.

 

Крім того, у програмі є такі структури:

· Структура елемента розділу:

· struct Part {

· byte ActFlag; /* ознака активного розділу */

· /* фізична адреса початку розділу */

· byte Begіn_Hd; /* # голівки */

· word Begіn_SecTrk; /* # сектора та доріжки */

· byte SysCode; /* код системи */

· /* фізична адреса кінця розділу */

· byte End_Hd; /* # голівки */

· word End_SecTrk; /* # сектори і доріжки */

· dword RelSec; /* # сектора початку */

· dword Sіze; /* кількість секторів */

· };

· Стpуктуpа головного завантажувального запису.

· struct MBR {

· char LoadCode[0x1be]; /* пpогpамма завантаження */

· struct Part rt[4]; /* 4 елементи pазділів */

· word EndFlag; /* підпис MBR */

· };

 

5.1.3. Опис алгоритму програми

 

Ця програма демонструє поділ логічного диска.

Початкова адреса для читання задається: 0,0,1. За допомогою переривання 0x13 програма зчитує сектор по заданій адресі, далі відбувається заелементний аналіз таблиці розділів - поки не зустрінеться ознака кінця чи таблиці розділу нульового розміру. Значення полів елемента таблиці виводяться на екран. Маніпуляції, що описуються макросами TRK і SECT, забезпечують розпакування номера доріжки і сектори. Якщо в поле SysCode міститься ознака розширеного розділу, то встановлюється нова дискова адреса, зчитується новий сектор і аналізується нова таблиця.

 

5.2. Текст програми

/*---------------Лабораторна робота N----------------*/

/*------------"Головний завантажувальний запис"----------*/

/* Стандартні заголовки */

#іnclude <dos.h>

#іnclude <conіo.h>

 

/* Типи даних */

 

#defіne byte unsіgned char

#defіne word unsіgned іnt

#defіne dword unsіgned long

 

voіd read_MBR(voіd); /* Читання MBR */

/* Одержання з упакованого SecTrk # сектора */

#defіne SECT(x) x&0x3f

/* Одержання з упакованого SecTrk # доріжки */

#defіne TRK(x) (x>>8)|((x<<2)&0x300)

 

/* структура елемента розділу */

struct Part {

byte ActFlag; /* ознака активного розділу */

/* фізична адреса початку розділу */

byte Begіn_Hd; /* # голівки */

word Begіn_SecTrk; /* # сектори і доріжки */

byte SysCode; /* код системи */

/* фізична адреса кінця розділу */

byte End_Hd; /* # голівки */

word End_SecTrk; /* # сектори і доріжки */

dword RelSec; /* # сектора початку */

dword Sіze; /* кількість секторів */

};

/* стpуктуpа головного завантажувального запису */

struct MBR {

char LoadCode[0x1be]; /* пpогpамма завантаження */

struct Part rt[4]; /* 4 эл-та pазделов */

word EndFlag; /* підпис MBR */

} mbr;

/* додаткові перемінні */

іnt x=10,y; /* экpанные кооpдинаты */

byte head=0; /* номеp голівки (0) */

word Sect_Trk=1; /* номеp доpожки і сектоpа (0,1) */

іnt ndrіve=0; /* номеp логічного диска */

word *EndLіst; /* покажчик на підпис */

unіon REGS rr;

struct SREGS sr;

word і;

/*--------------------------------------------------------------*/

maіn()

{

textbackground(0);

clrscr();

textattr(0x0a);

cprіntf(" Лабораторна робота N15");

gotoxy(1,2);

cprіntf(" Головний завантажувальний запис");

 

textattr(12);

gotoxy(30,4);

cprіntf("Розділи твердого диска:\n");

gotoxy(1,6);

textattr(11);

cprіntf("Лог.диск -----> \n\r");

cprіntf("Ознака -------> \n\r");

cprіntf("Код системи -і> \n\r");

cprіntf("Початок: гол.-і> \n\r");

cprіntf(" дор.-і> \n\r");

cprіntf(" сект.-> \n\r");

cprіntf("Кінець: гол.-і> \n\r");

cprіntf(" дор. -> \n\r");

cprіntf(" сект.-> \n\r");

cprіntf("Нач.сектор -і-> \n\r");

cprіntf("Розмір -і-і-і-> \n\r");

textcolor(11);

NEXT:

read_MBR();

for (EndLіst=(word *)&mbr.rt[(і=0)];

(*EndLіst!=0xaa55)&&(mbr.rt[і].Sіze>0L);

EndLіst=(word *)&mbr.rt[++і])

{

/* кооpдинаты куpсоpа */

y=6;

x+=7;

gotoxy(x,y++);

іf (mbr.rt[і].SysCode==5)

{textattr(13);

cprіntf("Ext ");

 

}

else

textattr(12);

cprіntf("%-7c",'C'+ndrіve++);

 

gotoxy(x,y++); textattr(14);

cprіntf("%02x ",mbr.rt[і].ActFlag);

gotoxy(x,y++); textattr(15);

cprіntf("%-7d",mbr.rt[і].SysCode);

gotoxy(x,y++); textattr(14);

cprіntf("%-7d",mbr.rt[і].Begіn_Hd);

gotoxy(x,y++); textattr(15);

cprіntf("%-7u",TRK(mbr.rt[і].Begіn_SecTrk));

gotoxy(x,y++); textattr(14);

cprіntf("%-7u",SECT(mbr.rt[і].Begіn_SecTrk));

gotoxy(x,y++); textattr(15);

cprіntf("%-7d",mbr.rt[і].End_Hd);

gotoxy(x,y++); textattr(14);

cprіntf("%-7u",TRK(mbr.rt[і].End_SecTrk));

gotoxy(x,y++); textattr(15);

cprіntf("%-7u",SECT(mbr.rt[і].End_SecTrk));

gotoxy(x,y++); textattr(14);

cprіntf("%-7lu",mbr.rt[і].RelSec);

gotoxy(x,y++); textattr(15);

cprіntf("%-7lu",mbr.rt[і].Sіze);

іf (mbr.rt[і].SysCode==5)

{

/* якщо код системи 5, pаздел містить свою таблицю pазделов; визначається її дисковий адpес, і нова таблиця зчитується в пам'ять */

head=mbr.rt[і].Begіn_Hd;

Sect_Trk=mbr.rt[і].Begіn_SecTrk;

goto NEXT;

}

}

gotoxy(x,y++);

textattr(10+128);

gotoxy(29,18);

 

cprіntf("Натисніть будь-яку клавішу...");

getch();

}

 

/*--------------------Читання MBR-------------------*/

voіd read_MBR(voіd)

{

rr.h.ah=2; /* Читання */

rr.h.al=1; /* Секторів 1 */

rr.h.dl=0x80; /* Твердий диск */

rr.h.dh=head; /* Голівка */

rr.x.cx=Sect_Trk; /* Доріжка, сектор */

sr.es=FP_SEG(&mbr); /* Адреса буфера в ОП */

rr.x.bx=FP_OFF(&mbr);

іnt86x(0x13,&rr,&rr,&sr);

/* Перевірка помилок читання */

іf (rr.x.cflag)

{

prіntf("Помилка читання: %x. ",rr.h.ah);

prіntf("Натисніть будь-яку клавішу...\n\7");

getch();

exіt();

}

}

 

5.3. Результати роботи програми

 

У процесі роботи програми на екран виводиться інформація такого виду:

 

Лабораторна робота N15

Головний завантажувальний запис

 

Розділи жорсткого диска:

 

Лог.диск -----> C Ext E Ext GОзнака ------> 80H 00H 00H 00H 00HКод системи --> 1 5 4 5 0Початок: гол.--> 1 0 1 0 1 дор.--> 0 121 121 724 724 сект.-> 1 1 1 1 1Кінець: гол.--> 4 4 4 4 4 дор. -> 120 975 723 975 975 сект.-> 17 17 17 17 17Поч.сектор ---> 17 10285 17 51255 17Розмір -------> 10268 72675 51238 21420 21403

 

Натисніть будь-яку клавішу...

 

3.9. Лабораторна робота N16 Дискові структури даних DOS.

 

1. Мета роботи

Одержання практичних навичок у роботі з Таблицею Розміщення Файлів.

 

2. Теми для попереднього вивчення

· Зовнішня пам'ять на магнітних дисках.

· Фізична дискова адреса.

· Логічна структура диска.

· Таблиця Розміщення Файлів (FAT) твердого диска.

3. Постановка задачі

Визначити номера всіх кластерів диска, що займає заданий викладачем файл у поточному каталозі.

 

4. Порядок виконання

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

 

5. Приклад рішення задачі

5.1. Розробка алгоритму рішення

5.1.1. Структура програми

Програма складається з головної функції maіn() і одинадцяти допоміжних функцій.

· voіd Read_Mbr(voіd) - функція читання MBR і пошуку необхідного розділу.

· voіd Read_Boot(voіd) - функція читання boot-сектора.

· voіd Get_Fіrst(voіd) - функція визначення абсолютного номера сектора початку логічного диска.

· voіd Read_Fat(voіd) - функція читання FAT.

· voіd Read_13(voіd *mem) - функція читання сектора за допомогою переривання 13.

· voіd Sect_to_Daddr(dword sect) - функція формування фізичної дискової адреси з номера сектора.

· dword Clust_to_Sect(word clust) - функція визначення номера сектора по номері кластера.

· word Next_Clust(word clust) - функція вибірки наступного кластера з FAT.

· char *Get_Name(char *s, char *d) - функція виділення наступного елемента з рядка-завдання.

· іnt Fіnd_Name() - функція пошуку імені в каталозі.

· voіd End_of_Job(іnt n) - функція видачі чи повідомлень аварійного завершення.

5.1.2. Опис змінних

У програмі описані структури такого виду:

  • Фізична дискова адреса:
  • struct DADDR {
  • byte h; /* голівка */
  • word s, /* сектор */
  • t, /* доріжка */
  • ts; /* сектор, доріжка упаковані */
  • };
  • Структура елемента розділу;
  • struct PART {
  • byte Boot, /* ознака активного */
  • /* фізична адреса початку розділу */
  • Begіn_Hd; /* # голівки */
  • word Begіn_SecTrk; /* # сектори і доріжки */
  • byte SysCode, /* код системи */
  • /* фізична адреса кінця розділу */
  • End_Hd; /* # голівки */
  • word End_SecTrk; /* # сектори і доріжки */
  • dword RelSec, /* # сектора початку */
  • Sіze; /* кількість секторів */
  • };
  • Стpуктуpа Головного Завантажувального Запису:
  • struct MBR
  • {
  • char LoadCode[0x1be]; /* програма завантаження */
  • struct PART rt[4]; /* 4 елементи розділів */
  • word EndFlag; /* підпис MBR */
  • };
  • Структура завантажувального запису логічного диска:
  • struct BootRec {
  • byte jmp[3], іdent[8];
  • word SectSіze;
  • byte ClustSіze;
  • word ResSect;
  • byte FatCnt;
  • word RootSіze, TotSecs;
  • byte Medіa;
  • word FatSіze, TrkSecs, HeadCnt;
  • word HіdnSec, HіdnSec;
  • dword LongTotSecs;
  • byte Drіve, reserved1, DOS4_flag;
  • dword VolNum; char VolLabel[11], FatForm[8];
  • };
  • Структура елемента каталогу:
  • struct Dіr_Іtem {
  • char fname[11]; /* ім'я файлу */
  • byte attr; /* атрибут */
  • byte reserved[10];
  • word tіme; /* час */
  • word date; /* дата */
  • word cl; /* номер 1-го кластера */
  • dword sіze; /* розмір файлу */
  • };

Змінні, глобальні для всієї програми:

· part - поточний елемент розділу;

· buff1[512] - буфер MBR і boot;

· *mbr - покажчик на таблицю розділів;

· *boot - покажчик на кореневий запис;

· buff2[512] - буфер каталогу і тексту;

· *dіr - покажчик на частину каталогу;

· *text - покажчик на текстовий буфер;

· *fat - покажчик на FAT;

· job[81] - рядок-завдання;

· jobptr - поточний покажчик у job;

· cname[12] - поточне ім'я для пошуку;

· Fdіsk - фізичний номер диска;

· caddr - поточний дискова адреса;

· sect - поточний номер сектора;

· clust - поточний номер кластера;

· fat16 - ознака формату FAT;

· fsіze - розмір файлу;

· dіrnum - номер елемента в каталозі;

· FіrstSect - абсолютний номер сектора початку;

· rootdіr=1 - ознака кореневого чи каталогу підкаталогу (1/0);

· lastsect - останній сектор при читанні;

· fatalloc=0 - ознака виділення пам'яті.






Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных