1   2   3   4   5   6   7   8
Ім'я файлу: ЗВІТ КУРСАЧА - РЕЗИДЕНТНИЙ КАЛЬКУЛЯТОР.docx
Розширення: docx
Розмір: 511кб.
Дата: 05.11.2021
скачати

5.5. Вимоги до апаратного і програмного забезпечення


Вимоги до програмого забеспеченні: Windows XP і вище, необхідні бібліотеки, драйвера для підтримки клавіатури.

Вимоги до апаратного забеспечення: ОЗУ 1ГБ (для Windows XP), 2ГБ (для Windows 7) , 3+ГБ (для Winsows 10).

ВИСНОВОКИ

Під час виконання курсової роботи я дізнався, що таке резидентні програми, для чого їх використовують, де вони використовуються, дізнався про процес створення таких програм та за допомогою отриманих знань, в тому числі протягом усього курсу «Системне програмування та операційні системи в комп'ютерній поліграфії» мені вдалося створити програму «Резидентний калькулятор» на основі мов С та Асемблер. Також для виконання цієї курсової роботи мені довелося ознайомитися з такою мовою як Асемблер, частково її розібрати та вивчити. Звісно треба ще дуже багато старань та зусиль для повного вивчення цієї мови, але на рівні чайника я вже розібрався.

СПИСОК ВИКОРИСТАНОХ ДЖЕРЕЛ


  1. MS-DOS для программиста [Електронний ресурс] – Режим доступу: http://www.frolov-lib.ru/books/bsp.old/v18/ch5.html#b5.6

  2. C для профессиональных программистов [Електронний ресурс] – Режим доступу: http://aiut.tugab.bg/Library/Software/Doc/C/c_za_progr.pdf

  3. Stack Overflow [Електронний ресурс] – Режим доступу: https://stackoverflow.com/

  4. Резидентные программы [Електронний ресурс] – Режим доступу: http://www.realcoding.net/articles/chast-iii-rezidentnye-programmy.html


ДОДАТКИ


ТЕКСТ ПРОГРАМИ

Розділ ініціалізації програми резидентного калькулятора дуже невеликий і цілком поміщається в наступній функції:

void interrupt test(bp, di, si, ds, es, dx, cx, bx,

ax, ip, cs, flags)

unsigned bp, di, si, ds, es, dx, cx, bx, ax, ip, cs, flags;

main ()

void interrupt tsr_ap (); / * Вхід в прикладну програму * /

main (){

struct address {

char far * p;}; / * Адреса переривання друку екрану * /

struct address far * addr = (struct address far *) 20;

addr-> p = (char far *) tsr_ap;

set_vid_mem ();

tsr (2000);}

Функція tsr_ap () є точкою входу в прикладну частину TSR-програми. Вона використовує покажчик на вміст таблиці векторів, відповідне переривання 5. Значення глобального покажчика vid_mem встановлюється за допомогою функції set_vid_mem, що приводиться нижче.

set_vid_mem (){

int vmode;

vmode = video_mode ();

if ((vmode! = 2) && (vmode! = 3) && (vmode! = 7)) {

printf ( "video must be in 80 column text mode");

exit (1);}

/ * Встановити відповідну адресу відеопам'яті * /

if (vmode == 7) vid_mem = (char far *) 0xB0000000;

else vid_mem = (char far *) 0xB8000000;}

Вихід з функції main () здійснюється шляхом звернення до функції tsr (), наведеної нижче.

/ * Завершити виконання, але залишити резидентною * /

tsr (size)

unsigned size;{

union REGS r;

rhah = 49; / * Завершити і залишити резидентною * /

rhal = 0; / * Код повернення * /

rxdx = size;

int86 (0x21, & r, & r);}

Параметр size, який визначається в регістрі DX, використовується для того, щоб повідомити DOS, скільки пам'яті потрібно для розміщення ТSR-програми. Розмір пам'яті визначається в 16-байтних параграфах. Після завершення виконання функції маin () програма залишається в пам'яті, і ніяка інша програма не може бути завантажена на її місце. Це означає, що прикладна частина програми в будь-який момент часу готова бути запущеною натисканням клавіші PrtSc.

Точкою входу в прикладну частину TSR-програми повинна бути функція типу interrupt. Запуск прикладної частини виконується шляхом виклику функції window_main().

/ * Точка входу в прикладну частину TSR-програми * /

void interrupt tsr_ap (){

if (! busy) {

busy =! busy;

window_main ();

busy =! busy;}}

Глобальна змінна busy спочатку встановлюється в 0. Прикладна частина TSR-програми не є повторно входимою, отже, вона не повинна запускатися двічі за час одного використання. Змінна busy використовується як раз для того, щоб запобігти цьому.

/ * TSR-програма, яка використовує переривання друку екрану * /

#include "dos.h"

#include "stdlib.h"

#define BORDER 1

#define ESC 27

#define MAX_FRAME 1

#define REV_VID 0x70

#define NORM_VID 7

#define BKSP 8

void interrupt tsr_ap ();

void save_video (), restore_video ();

void write_string (), write_char ();

void display_header (), draw_border ();

void window_gets ();

void window_cleol (), window ();

void calc ();

char far * vid_mem;

struct window_frame {

int startx, endx, starty, endy;

int curx, cury; / * Поточний стан курсору у вікні * /

unsigned char * p; / * Покажчик буфера * /

char * header; / * Повідомлення у верхній частині вікна * /

int border; / * Включення / відключення бордюру * /

int active; / * Активація / деактивація вікна * /

} Frame [MAX_FRAME];

char wp [4000]; / * Буфер для зберігання поточного вмісту екрана
/ * Busy встановлена ​​в 1, якщо програма активна, інакше - в 0 * /

char busy = 0;
main ()

{

struct address {

char far * p;

};

/ * Адреса переривання друку екрану * /

struct address far * addr = (struct address far *) 20;

addr-> p = (char far *) tsr_ap;

set_vid_mem ();

tsr (2000);

}

set_vid_mem ()

{

int vmode;

vmode = video_mode ();

if ((vmode! = 2) && (vmode! = 3) && (vmode! = 7)) {

printf ( "video must be in & 0 column text mode");

exit (1);

}

/ * Встановити відповідну адресу відеопам'яті * /

if (vmode == 7) vid_mem = (char far *) 0xB0000000;

else vid_mem = (char far *) 0xB8000000;

}

/ * Точка входу в прикладну частину TSR-програми * /

void interrupt tsr_ap ()

{

if (! busy) {

busy =! busy;

window_main ();

busy =! busy;

}

}

/ * Завершити, але залишити резидентною * /

tsr (size)

unsigned size;

{

union REGS r;

rhah = 49; / * Завершити, але залишити резидентною * /

rhal = 0; / * Код повернення * /

rxax = size;

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

}

window_main ()

{

/ * Насамперед, створити структуру вікна * /

make_window (0, "Calculator", 8, 20, 12, 60, BORDER);

/ * Для активації описаного вікна використати window () * /

calc ();

}

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

/ * Функції управління вікнами * /

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

/ * Вивести на екран спускається меню * /

void window (num)

int num; / * Номер вікна * /

{

int vmode, choice;

int x, y;

/ * Зробити вікно активним * /

if (! frame [num] .active) {/ * використовується не постійно * /

save_video (num); / * Зберегти поточний екран * /

frame [num] .active = 1; / * Встановити прапор активності * /

}

if (frame [num] .border) draw_border (num);

display_header (num); / * Вивести вікно * /

}

/ * Створити вікно якщо вікно може бути створено, повертається 1; інакше повертається 0.* /

make_window (num, header, startx, starty, endx, endy, border)

int num; / * Номер вікна * /

char * header; / * Текст заголовка * /

int startx, starty; / * Координати X, Y лівого верхнього кута * /

int endx, endy; / * Координати X, Y правого нижнього кута * /

int border; / * Без бордюру якщо 0 * /

{

register int i;

int choice, vmode;

unsigned char * p;

if (num> MAX_FRAME) {

window_puts (0, "Too many windows \ n");

return 0;

}

if ((startx> 24) || (starty> 78) || (starty <0)) {

window_puts (0, "range error");

return 0;

}

if ((endx> 24) || (endy> 79)) {

window_puts (0, "window will not fit");

return 0;

}

/ * Створити структуру вікна * /

frame [num] .startx = startx; frame [num] .endx = endx;

frame [num] .starty = starty; frame [num] .endy = endy;

frame [num] .p = wp;

frame [num] .header = header;

frame [num] .border = border;

frame [num] .active = 0;

frame [num] .curx = 0; frame [num] .cury = 0;

return 1;

}

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

deactivate (num)

int num;

{

/ * Встановити курсор в лівий верхній кут * /

frame [num] .curx = 0;

frame [num] .cury = 0;

restore_video (num);

}

/ * Вивести заголовок вікна в відповідне поле * /

void display_header (num)

int num;

{

register int i, y, len;

y = frame [num] .starty;

/ * Обчислити точне значення центральної позиції заголовка

якщо негативне - заголовок не може бути виведений* /

len = strlen (frame [num] .header);

len = (frame [num] .endy - y - len) / 2;

if (len <0) return; / * Do not display it * /

y = y + len;

write_string (frame [num] .startx, y,

frame [num] .header, NORM_VID);

}

void draw_border (num)

int num;

{

register int i;

char far * v, far * t;

v = vid_mem;

t = v;

for (i = frame [num] .startx + 1; i= Frame [num] .endy) {

return 1;

}

if (x> = frame [num] .endx) {

return 1;

}

if (ch == '\ n') {/ * символ переходу на новий рядок * /

x ++;

y = frame [num] .startx + 1;

v = vid_mem;

v + = (x + 160) + y * 2; / * Обчислити адресу * /

frame [num] .curx ++;

frame [num] .cury = 0; / * Скинути Y * /

}

else {

frame [num] .cury ++;

* V ++ = ch; / * Вивести символ * /

* V ++ = NORM_VID; / * Нормальні атрибути символу * /

}

window_xy (num, frame [num] .curx, frame [num] .cury);

return 1;

}

/ * Установка курсора в задану позицію вікна, повертає 0 при виході за кордон; НЕ нуль в іншому випадку.* /

window_xy (num, x, y)

int num, x, y;

{

if (x <0 || x + frame [num] .startx> = frame [num] .endx-1)

return 0;

if (y <0 || y + frame [num] .starty> = frame [num] .endy-1)

return 0;

frame [num] .curx = x;

frame [num] .cury = y;

return 1;

}

/ * Вважати рядок з вікна. * /

void window_gets (num, s)

int num;

char * s;

{

char ch, * temp;

temp = s;

for (;;) {

ch = window_getche (num);

switch (ch) {

case '\ r': / * натиснута клавіша ENTER * /

* S = '\ 0';

return;

case BKSP: / * повернення * /

if (s> temp) {

s--;

frame [num] .cury--;

if (frame [num] .cury <0) frame [num] .cury = 0;

window_xy (num, frame [num] .curx, frame [num] .cury);

write_char (frame [num] .startx + frame [num] .curx + 1,

frame [num] .starty + frame [num] .cury + 1, '', NORM_VID);

}

break;

default: * s = ch;

s ++;

}

}

}

/ * Введення символу з клавіатури у вікно.

Повертає повний 16-розрядний скан-код.

/ *

window_getche (num)

int num;

{

union inkey {

char ch [2];

int i;

} C;

if (! frame [num] .active) return 0; / * Window not active * /

window_xy (num, frame [num] .curx, frame [num] .cury);

ci = bioskey (0); / * Обробити натискання клавіші * /

if (c.ch [0]) {

switch (c.ch [0]) {

case '\ r': / * натиснута клавіша ENTER * /

break;

case BKSP: / * повернення * /

break;

default:

if (frame [num] .cury + frame [num] .starty
write char (frame [num] .startx + frame [num] .curx + 1,

frame [num] .curx--;

window_xy (num, frame [num] .curx, frame [num] .cury);

}

return ci;

}

/ * Очистити до кінця рядка * /

void window_cleol (num)

int num;

{

register int i, x, y;

x = frame [num] .curx;

y = frame [num] .cury;

window_xy (num, frame [num] .curx, frame [num] .cury);

for (i = frame [num] .cury; i0) {

frame [num] .curx--;

window_xy (num, frame [num] .curx, frame [num] .cury);

return 1;

}

return 0;

}

/ * Перемістити курсор на один рядок вниз. При успішному завершенні повернути нульове значення; в іншому випадку - 0.* /

window_downline (num)

int num;

{

if (frame [num] .curx0) {

frame [num] .cury--;

window_xy (num, frame [num] .curx, frame [num] .cury);

window_putchar (num, '');

frame [num] .cury--;

window_xy (num, frame {num} .curx, frame [num] .cury);

}

}

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

/* Додаткові функції */

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

/ * Вивести рядок з встановленими атрибутами * /

void write_string (x, y, p, attrib)

int x, y;

char * p;

int attrib;

{

register int i;

char far * v;

v = vid_mem;

v + = (x * 160) + y * 2; / * Обчислити адресу * /

for (i + y; * p; i ++) {

* V ++ = * p ++; / * Вивести символ * /

* V ++ = attrib; / * Вивести атрибути * /

}

}

/ * Вивести символ з утановленнимі атрибутами * /

void write_char (x, y, ch, attrib)

int x, y;

char ch;

int attrib;

{

register int i;

char far * v;

v = vid_mem;

v + = (x * 160) + y * 2;

* V ++ = ch; / * Вивести символ * /

* V = attrib; / * Вивести атрибути * /

}

/ * Зберегти вміст області екрану * /

void save_video (num)

int num;

{

register int i, j;

char far * v, far * t;

char * but_ptr;

but_ptr = frame [num] .p;

v = vid_mem;

t = v;

for (i = frame [num] .starty; ibos) return 0;

* P = i;

p ++;

return 1;

}

/ * Видобути верхній елемент стека Повернути 0, якщо стек порожній.

* /

pop ()

{

p--;

if (pp == (int9 + 1) -> p) {

int9-> p = addr-> p;

addr-> p = (char far *) tsr_ap;

printf ( "F3 for calculator");

} Else {

printf ( "tsr application already initialized \ n");

exit (1);

}}

set_vid_mem ();

tsr (2000);

}

Слід зазначити, що дана версія програми не допускає, щоб її запускали більше одного разу протягом одного сеансу роботи. Це пов'язано з тим, що повторний запуск програми приведе до запису адреси точки входу в TSR-програму в таблицю векторів за адресою 60-го переривання, а утримувався там адреса програми реакції на натискання клавіші буде пошкоджений. Під час роботи функції перевіряється, чи збігається вміст таблиці векторів, відповідне перериванням 60 і 61. (Переривання 61 також не використовується DOS). DOS обробляє всі невикористовувані нею переривання однієї і тієї ж програмою обробки неприпустимого переривання. Отже, перед запуском TSR-програми ці адреси будуть збігатися, а після запуску вони будуть різні.



1   2   3   4   5   6   7   8

скачати

© Усі права захищені
написати до нас