На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 7 / Листинг 7-9. PLAYBACK.C Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Листинг 7-9. PLAYBACK.C

                             Листинг 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);
        }
        -------------------------------------------------------------------

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz