Листинг 7-9. PLAYBACK.C
-------------------------------------------------------------------
/*
Имя: PLAYBACK.C
Назначение: Распечатка образов текстовых экранов, сохра-
ненных в pасшиpенной памяти программой SNAPSHOT, в стан-
дартный выходной файл DOS.
*/
#include
#include
#include
#include
#include
#include "emmconst.h" /*константы менеджеpа pасшиpенной памяти*/
#include "emmtypes.h" /*структуры данных менеджеpа pасшиpенной
памяти*/
#include "emmerr.h" /*коды ошибок менеджеpа pасшиpенной памяти*/
#include "emmfunc.h" /*объявления функций менеджеpа pасшиpенной
памяти*/
#define DisplayError(rc) ShowEMMErr(rc, __LINE__, __FILE__)
#define HANDLE_NAME "SNAPSHOT" /*имя обpаботчика pасшиpенной
памяти/*
#define MAX_SCR 500 /*максимальное кол-во сохра-
няемых экранов*/
#define SCR_COLS 80 /*предполагается 80 колонок,
позже можно корректировать*/
#pragma pack(1) /*структуры данных с байтовым
выравниванием*/
typedef struct scr { /*дескриптор данных экрана*/
unsigned int scr_page; /*страница pасшиpенной памяти для
начального экрана*/
unsigned int scr_offset; /*смещение pасшиpенной памяти для
начального экрана*/
unsigned int scr_width; /*кол-во колонок на экране*/
unsigned int scr_len; /*длина экрана в байтах*/
} SCR;
typedef struct scr_index { /*индексная структура экранов*/
void (interrupt far *scr_int5)(); /*указатель на нашу програм-
му обслуживания прерывания*/
unsigned int scr_count; /*текущее кол-во сохраненных
экранов*/
unsigned int scr_max; /*максимальное кол-во сохра-
ненных экранов*/
SCR scr_idx[MAX_SCR]; /*массив индексов экранов*/
} SCR_INDEX;
/*
Глобальные данные
*/
unsigned int emm_handle, /*обpаботчик pасшиpенной памяти*/
emm_pages; /*кол-во страниц, принадлежащих
обpаботчику*/
char far *page_frame; /*удаленный -> на кадр страниц
спецификации pасшиpенной памяти*/
SCR_INDEX far *ip; /*удаленный -> на индекс экрана*/
SCR far *sp; /*удаленный -> на дескриптор эк-
рана*/
MOVE_XCHG mcb; /*структура "Передвинуть/обменять области*/
main()
{
unsigned int scan_code;
int emm_present, rc, current_screen;
char emm_ver[4];
/*тест наличия pасшиpенной памяти*/
if (rc = emm_exists(&emm_present)) {
/*тест наличия менеджеpа pасшиpенной памяти не прошел*/
printf("replay: EMM presence test failed, rc: %d", rc);
exit(2);
}
if (!emm_present) {
/* pасшиpенной памяти нет */
printf("replay: No expanded memory is present");
exit(1);
}
/*получить версию спецификации pасшиpенной памяти,поддерживае-
мую данным менеджеpом pасшиpенной памяти*/
if (rc = EMSGetVersion(emm_ver)) {
DisplayError(rc);
exit(1);
}
/* убедитесь, что версия не ниже 4.0 */
if (*emm_ver < '4') { /*требуется спецификация pасшиpенной
памяти LIM не ниже 4.0*/
printf("replay: Unsupported EMM version detected: %s,
LIM EMS 4.0 or greater is required", emm_ver);
exit(1);
}
/* получить указатель на кадр страниц спецификации pасшиpен-
ной памяти */
if (rc = EMSGetFrameAddr(&page_frame)) {
DisplayError(rc);
exit(1);
}
/* Поиск обpаботчика, содержащего запомненные экраны */
if (rc = EMSSearchHandleName(HANDLE_NAME, &emm_handle)) {
DisplayError(rc);
exit(1);
}
/* отобразить в страницу, содержащую индекс экрана */
if (rc = EMSMapHandlePage(emm_handle, 0, 0)) {
DisplayError(rc);
exit(1);
}
/* получить адресуемость на структуру данных индексов
экранов */
ip = (SCR_INDEX far *) page_frame;
sp = ip->scr_idx; /*указать на первый запомненный экран*/
if (ip->scr_count == 0)
printf("replay: no screens have been saved");
else
/*
распечатывать каждый запомненный экран на стандартный
вывод
*/
for (current_screen = 0; current_screen < ip->scr_count;
current_screen++) {
rc = print_screen(sp++);
if (rc) { /*произошла ошибка pасшиpенной памяти*/
DisplayError(rc);
exit(1);
}
}
/* перестать отображать страницу индексов экранов */
if (rc = EMSMapHandlePage(emm_handle, -1, 0)) {
DisplayError(rc);
exit(1);
}
}
/*
По данному удаленному указателю на дескриптор экрана, за-
помненный в pасшиpенной памяти, пишите каждый символ за-
помненного образа экрана в стандартный выходной файл DOS
*/
print_screen(sp)
SCR far *sp; /*удаленный -> на дескриптор экрана*/
{
int rc, lpages, line, rows;
char *line_buf[SCR_COLS+1];
int far *bp;
struct SREGS segregs;
/* вычислить, сколько физических страниц нужно отобразить */
lpages = 1; /* по крайней мере, одна страница */
if (sp->scr_offset + sp->scr_len > PAGE_SIZE)
lpages++;
/* отобразить логическую страницу (страницы), которые содержат
образ экрана, в физические страницы, начинающиеся с физической
страницы 1 */
for (i = 0; i < lpages; i++)
if (rc = EMSMapHandlePage(emm_handle, i + sp->scr_page,
i + 1))
return(rc) /* неудача */
/* получить адресуемость на физическую страницу 1 */
bp = (int far *) page_frame; /* базовый адрес кадра
страниц*/
FP_SEG(bp) += (PAGE_SIZE / 16); /*кол-во параграфов в
странице спецификации pасшиpенной памяти*/
FP_OFF(bp) = sp->scr_offset;
rows = sp->scr_len / sp->scr_width / 2; /*вычисление кол-ва
строк на экране*/
putchar('[bs]014'); /*начать новую страницу*/
/* записывать каждый символ на образе экрана в стандартный
выход */
for (line = 0; line < rows; line++) {
i = sp->scr_width;
while (i--)
putchar(*bp++ & 0xFF);
putchar('[bs]n'); /* вывод новой строки после
каждой строки */
}
return(rc);
}
-------------------------------------------------------------------
|