home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / misc_programming / AGUL / WINDOWZ.ADB / WINDOWZ.ADB
Encoding:
Text File  |  1991-06-09  |  38.5 KB  |  1,037 lines

  1. --        ╔═════════════════════════════════════════════════════════════╗
  2. --        ║█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█║
  3. --        ║█                                                           █║
  4. --        ║█                 Meridian Software Systems                 █║
  5. --        ║█                                                           █║
  6. --        ║█                    Copyright (C)  1990                    █║
  7. --        ║█                                                           █║
  8. --        ║█                    ALL RIGHTS RESERVED                    █║
  9. --        ║█                                                           █║
  10. --        ║█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█║
  11. --        ╚═════════════════════════════════════════════════════════════╝
  12.  
  13. ------------------------------------------------------------------------------
  14. --
  15. --   Unit Name: Window              - package body
  16. --
  17. --   Purpose of unit:   This package is called to define window and world
  18. --                      coordinate values. This packge also sets window and
  19. --                      world coordinates global with the select routines.
  20. --                      The windows can be drawn on the screen. Windows can
  21. --                      saved and loaded to and from a disk file. The defined
  22. --                      window and world records can also be deleted with the
  23. --                      reset procedures.
  24. --
  25. ------------------------------------------------------------------------------
  26.  
  27. with SYSTEM, COMMON_DISPLAY_TYPES, DRAW, INTERRUPT, PORT;
  28. with SPY, WINDOW_IO, VIDEO, UNCHECKED_DEALLOCATION;
  29. with ADA_IO, BIT_OPS, COMMON_GRAPHIC_TYPES;
  30. use  ADA_IO, BIT_OPS, COMMON_GRAPHIC_TYPES;
  31.  
  32. package body WINDOW is
  33.  
  34.   type LIST_RECORD;
  35.   type LIST_PTR is access LIST_RECORD;
  36.  
  37.   type LIST_RECORD is
  38.     record
  39.       REC_INDEX : INDEX_NUMBER := 0;
  40.       UPRLFTX,
  41.       UPRLFTY,
  42.       LWRRGHTX,
  43.       LWRRGHTY  :  integer;
  44.       NEXT      :  LIST_PTR := null;
  45.     end record;
  46.  
  47.   procedure DISPOSE is new UNCHECKED_DEALLOCATION(LIST_RECORD, LIST_PTR);
  48.  
  49.   WDW_LIST,
  50.   WLD_LIST  : LIST_PTR := null;
  51.   WDW_REC,
  52.   WLD_REC   : LIST_RECORD;
  53.  
  54.   -- =====================================================================
  55.   --
  56.   --  FIND_RECORD_IN_LIST is called to find either the window or world
  57.   --  record by the index number in the linked list. The pointer to the
  58.   --  record will be returned if the record has been found.  The boolean
  59.   --  Found will return TRUE if pointer has a valid address (record was
  60.   --  found) or FALSE if the record was not found.
  61.   --
  62.   -- =====================================================================
  63.  
  64.   procedure FIND_RECORD_IN_LIST (INDEX    : in     INDEX_NUMBER;
  65.                  TEMP_PTR : in out LIST_PTR;
  66.                  TEMP_REC : out    LIST_RECORD;
  67.                  FOUND    : out    boolean) is
  68.  
  69.     PREVIOUS_PTR,
  70.     CURRENT_PTR   : LIST_PTR := TEMP_PTR;
  71.     IN_LIST       : boolean  := false;
  72.  
  73.   begin -- FIND_RECORD_IN_LIST
  74.  
  75.     FOUND := IN_LIST;
  76.     while CURRENT_PTR /= null and not IN_LIST loop
  77.       if CURRENT_PTR.REC_INDEX < INDEX then
  78.     PREVIOUS_PTR := CURRENT_PTR;
  79.     CURRENT_PTR := CURRENT_PTR.NEXT;
  80.       elsif CURRENT_PTR.REC_INDEX = INDEX then
  81.     FOUND := true;
  82.     TEMP_REC := CURRENT_PTR.all;
  83.     return;
  84.       else
  85.     Put_line(" Window has not been defined.");
  86.     return;
  87.       end if;
  88.     end loop;
  89.  
  90.   end FIND_RECORD_IN_LIST;
  91.  
  92.   -- ======================================================================
  93.   --
  94.   --  DELETE_LIST is called to delete all the existing records either the
  95.   --  WINDOW_LIST, or the WORLD_LIST.  A pointer to the record is passed
  96.   --  to the procedure.
  97.   --
  98.   -- ======================================================================
  99.  
  100.   procedure DELETE_LIST (LIST : in out LIST_PTR) is
  101.     TMP_PTR : LIST_PTR := LIST;
  102.   begin
  103.     while LIST /= null loop
  104.       LIST := LIST.NEXT;
  105.       DISPOSE(TMP_PTR);
  106.     end loop;
  107.   end DELETE_LIST;
  108.  
  109.   -- =======================================================================
  110.   --
  111.   --  ADD_RECORD_TO_LIST will insert a new record into the linked list for
  112.   --  either the WINDOW_LIST or the WORLD_LIST. This procedure will insert
  113.   --  the record in sequential order by INDEX_NUMBER. If the record already
  114.   --  exists, it will be modified to reflect the new data.
  115.   --
  116.   -- =======================================================================
  117.  
  118.   procedure ADD_RECORD_TO_LIST (TMP_RECORD : in out LIST_RECORD;
  119.                 TMP_PTR    : in out LIST_PTR;
  120.                 INDEX      : in INDEX_NUMBER) is
  121.     PREVIOUS_PTR,
  122.     CURRENT_PTR   : LIST_PTR := TMP_PTR;
  123.     FOUND         : boolean;
  124.  
  125.   begin
  126.     if TMP_PTR /= null then
  127.       while CURRENT_PTR /= null loop
  128.     if CURRENT_PTR.REC_INDEX < INDEX then
  129.       PREVIOUS_PTR := CURRENT_PTR;
  130.       CURRENT_PTR := CURRENT_PTR.NEXT;
  131.     elsif CURRENT_PTR.REC_INDEX = INDEX then
  132.       TMP_RECORD.NEXT := CURRENT_PTR.NEXT;
  133.       CURRENT_PTR.all := TMP_RECORD;
  134.       return;
  135.     else
  136.       if CURRENT_PTR = TMP_PTR then
  137.         TMP_RECORD.NEXT := CURRENT_PTR;
  138.         TMP_PTR := new LIST_RECORD;
  139.         TMP_PTR.all := TMP_RECORD;
  140.       else
  141.         TMP_RECORD.NEXT := CURRENT_PTR;
  142.         PREVIOUS_PTR.NEXT := new LIST_RECORD;
  143.         PREVIOUS_PTR.NEXT.all := TMP_RECORD;
  144.       end if;
  145.       return;
  146.     end if;
  147.       end loop;
  148.       TMP_RECORD.NEXT := null;
  149.       PREVIOUS_PTR.NEXT := new LIST_RECORD;
  150.       PREVIOUS_PTR.NEXT.all := TMP_RECORD;
  151.     else
  152.       TMP_PTR := new LIST_RECORD;
  153.       TMP_PTR.all := TMP_RECORD;
  154.     end if;
  155.  
  156.   end ADD_RECORD_TO_LIST;
  157.  
  158.   -- ==========================================================================
  159.   --
  160.   --                           DEFINE_WINDOW
  161.   --
  162.   -- ==========================================================================
  163.  
  164.   procedure DEFINE_WINDOW (WINDOW_INDEX : in INDEX_NUMBER;
  165.                WDWUPX, WDWUPY, WDWLWRX, WDWLWRY : in integer) is
  166.  
  167.     UPRX, UPRY,LWRX,LWRY : integer;
  168.  
  169.   begin
  170.     if WINDOW_INDEX >= 1 and WINDOW_INDEX <= 8 then
  171.       UPRX := WDWUPX * CHARACTER_PIXEL_WIDTH;
  172.       UPRY := WDWUPY * CHARACTER_PIXEL_HEIGHT;
  173.       LWRX := (WDWLWRX * CHARACTER_PIXEL_WIDTH) + (CHARACTER_PIXEL_WIDTH - 1);
  174.       LWRY := (WDWLWRY * CHARACTER_PIXEL_HEIGHT) + (CHARACTER_PIXEL_HEIGHT - 1);
  175.       if (UPRX  >= SCREEN_DIMENSION_UPPER_LEFT_X) and
  176.      (UPRX <= SCREEN_DIMENSION_LOWER_RIGHT_X) then
  177.     if (UPRY >= SCREEN_DIMENSION_UPPER_LEFT_Y) and
  178.        (UPRY <= SCREEN_DIMENSION_LOWER_RIGHT_Y) then
  179.       if (LWRX > UPRX) and (LWRX <= SCREEN_DIMENSION_LOWER_RIGHT_X) then
  180.         if (LWRY > UPRY) and (LWRY <= SCREEN_DIMENSION_LOWER_RIGHT_Y) then
  181.           WDW_REC.REC_INDEX := WINDOW_INDEX;
  182.           WDW_REC.UPRLFTX := WDWUPX;
  183.           WDW_REC.UPRLFTY := WDWUPY;
  184.           WDW_REC.LWRRGHTX := WDWLWRX;
  185.           WDW_REC.LWRRGHTY := WDWLWRY;
  186.           ADD_RECORD_TO_LIST(WDW_REC,WDW_LIST,WINDOW_INDEX);
  187.         else
  188.           Put_line("Lower Right Y coordinate incorrect.");
  189.         end if;
  190.       else
  191.         Put_line("Lower Right X coordinate incorrect.");
  192.       end if;
  193.     else
  194.       Put_line("Upper Left Y coordinate incorrect.");
  195.     end if;
  196.       else
  197.     Put_line("Upper Left X coordinate incorrect.");
  198.       end if;
  199.     else
  200.       Put_line(" Window index out of bound, index should be between 1 and 8.");
  201.     end if;
  202.  
  203.   end DEFINE_WINDOW;
  204.  
  205.   -- ==========================================================================
  206.   --
  207.   --                             SELECT_WINDOW
  208.   --
  209.   -- ==========================================================================
  210.  
  211.   procedure SELECT_WINDOW (WINDOW_INDEX      : in INDEX_NUMBER;
  212.                BORDER_COLOR,
  213.                WINDOW_FORE_COLOR,
  214.                WINDOW_BACK_COLOR : in COMMON_DISPLAY_TYPES.COLOR;
  215.                ENABLE_CLIP       : in boolean ) is
  216.  
  217.     TMP_REC      : LIST_RECORD;
  218.     TMP_PTR      : LIST_PTR := WDW_LIST;
  219.     FOUND        : boolean;
  220.     REG_FILE     : INTERRUPT.REGISTERS;
  221.     COLOR_NUMBER : integer;
  222.  
  223.   begin
  224.     FIND_RECORD_IN_LIST(WINDOW_INDEX,TMP_PTR,TMP_REC,FOUND);
  225.     if FOUND then
  226.       CURRENT_WINDOW_INDEX_NO      := WINDOW_INDEX;
  227.       CURRENT_WINDOW_UPPER_LEFT_X  := TMP_REC.UPRLFTX  * CHARACTER_PIXEL_WIDTH;
  228.       CURRENT_WINDOW_UPPER_LEFT_Y  := TMP_REC.UPRLFTY  * CHARACTER_PIXEL_HEIGHT;
  229.       CURRENT_WINDOW_LOWER_RIGHT_X := TMP_REC.LWRRGHTX * CHARACTER_PIXEL_WIDTH
  230.                       + (CHARACTER_PIXEL_WIDTH  - 1);
  231.       CURRENT_WINDOW_LOWER_RIGHT_Y := TMP_REC.LWRRGHTY * CHARACTER_PIXEL_HEIGHT
  232.                       + (CHARACTER_PIXEL_HEIGHT - 1);
  233.       DRAW.FOREGROUND_COLOR(BORDER_COLOR);
  234.       COMMON_GRAPHIC_TYPES.WINDOW_FORE_COLOR := WINDOW_FORE_COLOR;
  235.       COMMON_GRAPHIC_TYPES.WINDOW_BACK_COLOR := WINDOW_BACK_COLOR;
  236.       REG_FILE.AX := 16#0600#;
  237.       COLOR_NUMBER := COMMON_DISPLAY_TYPES.COLOR'pos(WINDOW_BACK_COLOR);
  238.       REG_FILE.BX := SHL(COLOR_NUMBER,8);
  239.       REG_FILE.CX := SHL(TMP_REC.UPRLFTY,8);
  240.       REG_FILE.CX := REG_FILE.CX or TMP_REC.UPRLFTX ;
  241.       REG_FILE.DX := SHL(TMP_REC.LWRRGHTY,8);
  242.       REG_FILE.DX := REG_FILE.DX or TMP_REC.LWRRGHTX ;
  243.       INTERRUPT.VECTOR(16#10#,REG_FILE);
  244.       DRAW.RECTANGLE(CURRENT_WINDOW_UPPER_LEFT_X,
  245.              CURRENT_WINDOW_UPPER_LEFT_Y,
  246.              CURRENT_WINDOW_LOWER_RIGHT_X,
  247.              CURRENT_WINDOW_LOWER_RIGHT_Y);
  248.       DRAW.FOREGROUND_COLOR(WINDOW_FORE_COLOR);
  249.       CLIP_ENABLE := ENABLE_CLIP;
  250.     else
  251.       Put_line("Window has not been defined.");
  252.     end if;
  253.   end SELECT_WINDOW;
  254.  
  255.   -- ==========================================================================
  256.   --
  257.   --                            SAVE_WINDOW
  258.   --
  259.   -- ==========================================================================
  260.  
  261.   procedure SAVE_WINDOW(WINDOW_INDEX : in INDEX_NUMBER;
  262.                         FILENAME     : in string) is
  263.  
  264.     MASK                     : constant COMMON_DISPLAY_TYPES.byte := 16#FF#;
  265.     BYTE_SIZE                : constant integer := 8;
  266.     ODD_ROW_MEMORY_OFFSET    : constant long_integer := 16#2000#;
  267.     SEGMENT_MULTIPLIER       : constant long_integer := 16#1000#;
  268.     RIGHT_TMP_MASK,
  269.     LEFT_TMP_MASK            : COMMON_DISPLAY_TYPES.byte := MASK;
  270.     READ_BYTE                : SPY.byte;
  271.     FOUND                    : boolean;
  272.     TMP_REC                  : LIST_RECORD;
  273.     TMP_PTR                  : LIST_PTR := WDW_LIST;
  274.     READ_WRITE_OFFSET,
  275.     INDEX                    : integer := 0;
  276.     WINDOW_UPPER_LEFT_X,
  277.     WINDOW_LOWER_RIGHT_X     : COMMON_GRAPHIC_TYPES.HORIZONTAL;
  278.     WINDOW_UPPER_LEFT_Y,
  279.     WINDOW_LOWER_RIGHT_Y     : COMMON_GRAPHIC_TYPES.VERTICAL;
  280.     LEFT_BYTE_OFFSET,
  281.     RIGHT_BYTE_OFFSET        : COMMON_DISPLAY_TYPES.byte;
  282.     EVEN_ROW_ADDRESS,
  283.     EVEN_ROW_START_ADDRESS,
  284.     ODD_ROW_ADDRESS,
  285.     ODD_ROW_START_ADDRESS,
  286.     START_ADDRESS,
  287.     SYSTEM_ADDRESS,
  288.     TMP_ADDRESS              : long_integer;
  289.     TMP_MASK,
  290.     NUMBER_OF_BYTES,
  291.     BITS_PER_PIXEL,
  292.     BYTES_PER_ROW,
  293.     WINDOW_LEFT_OFFSET,
  294.     WINDOW_RIGHT_OFFSET      : integer;
  295.     BYTE_RECORD              : WINDOW_IO.BYTE_REC ;
  296.  
  297.     -- ===========================================================================
  298.     --
  299.     --  Check to see if Window has been defined
  300.     --
  301.     -- ===========================================================================
  302.   begin -- Save_Window
  303.  
  304.     FIND_RECORD_IN_LIST(WINDOW_INDEX,TMP_PTR,TMP_REC,FOUND);
  305.     if FOUND then
  306.       if not WINDOW_IO.Create(FILE_NAME => FILENAME) then
  307.     return;
  308.       end if;
  309.  
  310.       -- ===========================================================================
  311.       --
  312.       --  Convert to pixel values
  313.       --
  314.       -- ===========================================================================
  315.  
  316.       WINDOW_UPPER_LEFT_X  := TMP_REC.UPRLFTX  * CHARACTER_PIXEL_WIDTH;
  317.       WINDOW_UPPER_LEFT_Y  := TMP_REC.UPRLFTY  * CHARACTER_PIXEL_HEIGHT;
  318.       WINDOW_LOWER_RIGHT_X := TMP_REC.LWRRGHTX * CHARACTER_PIXEL_WIDTH +
  319.                   (CHARACTER_PIXEL_WIDTH  - 1);
  320.       WINDOW_LOWER_RIGHT_Y := TMP_REC.LWRRGHTY * CHARACTER_PIXEL_HEIGHT +
  321.                   (CHARACTER_PIXEL_HEIGHT - 1);
  322.  
  323.       -- ===========================================================================
  324.       --
  325.       --  Check for graphics type to determine bits_per_pixel.  2 bits required
  326.       --  for CGA 4 color mode, all other modes have 1 bit per pixel.  The
  327.       --  graphics mode will also determine how many bytes there are per row.
  328.       --  If 350 x 200 there is 40 bytes per row otherwise, there are 80 bytes
  329.       --  to a row.  An additional offset is reqired for EGA to read all the
  330.       --  rows.
  331.       --
  332.       -- ===========================================================================
  333.       case GRAPH_SCREEN is
  334.         when 4 | 5  =>
  335.       BYTES_PER_ROW  := 80;
  336.           BITS_PER_PIXEL := 2;
  337.  
  338.         when 6 =>
  339.       BYTES_PER_ROW  := 80;
  340.           BITS_PER_PIXEL := 1;
  341.  
  342.         when 14 =>
  343.       BYTES_PER_ROW     := 40;
  344.           READ_WRITE_OFFSET := 20;
  345.       BITS_PER_PIXEL    := 1;
  346.  
  347.         when 15 =>
  348.       BYTES_PER_ROW     := 80;
  349.           READ_WRITE_OFFSET := 20;
  350.       BITS_PER_PIXEL    := 1;
  351.  
  352.         when 16 | 17 =>
  353.       BYTES_PER_ROW     := 80;
  354.           READ_WRITE_OFFSET := 0;
  355.       BITS_PER_PIXEL    := 1;
  356.  
  357.         when 18 | 19 =>
  358.       BYTES_PER_ROW     := 80;
  359.           READ_WRITE_OFFSET := 48;
  360.       BITS_PER_PIXEL    := 1;
  361.  
  362.         when others =>
  363.           null;
  364.       end case;
  365.  
  366.       -- ===========================================================================
  367.       --
  368.       -- Determine offset into first and last byte in row.  If Cga mode then
  369.       -- need to adjust rows, since odd rows are in the second 8k of memory and
  370.       -- even rows are in the first 8k of display memory.
  371.       --
  372.       -- ===========================================================================
  373.  
  374.       if GRAPH_SCREEN >= 4 and GRAPH_SCREEN <= 6 then
  375.     WINDOW_LEFT_OFFSET :=
  376.       ((BYTES_PER_ROW * WINDOW_UPPER_LEFT_Y) / 2) +
  377.       ((WINDOW_UPPER_LEFT_X * BITS_PER_PIXEL) / BYTE_SIZE);
  378.       else
  379.     WINDOW_LEFT_OFFSET :=
  380.       (BYTES_PER_ROW * WINDOW_UPPER_LEFT_Y) +
  381.       ((WINDOW_UPPER_LEFT_X * BITS_PER_PIXEL) / BYTE_SIZE);
  382.       end if;
  383.       NUMBER_OF_BYTES := ((WINDOW_LOWER_RIGHT_X - WINDOW_UPPER_LEFT_X) *
  384.               BITS_PER_PIXEL) / BYTE_SIZE;
  385.  
  386.       SYSTEM_ADDRESS := PAGE1_MEMORY_START;
  387.       LEFT_BYTE_OFFSET := (WINDOW_UPPER_LEFT_X * BITS_PER_PIXEL) mod 8;
  388.       case LEFT_BYTE_OFFSET is
  389.     when 7      =>  LEFT_TMP_MASK := 16#7F#;
  390.     when 6      =>  LEFT_TMP_MASK := 16#3F#;
  391.     when 5      =>  LEFT_TMP_MASK := 16#1F#;
  392.     when 4      =>  LEFT_TMP_MASK := 16#0F#;
  393.     when 3      =>  LEFT_TMP_MASK := 16#07#;
  394.     when 2      =>  LEFT_TMP_MASK := 16#03#;
  395.     when 1      =>  LEFT_TMP_MASK := 16#01#;
  396.     when 0      =>  LEFT_TMP_MASK := 16#00#;
  397.     when others =>  LEFT_TMP_MASK := 16#FF#;
  398.       end case;
  399.  
  400.       RIGHT_BYTE_OFFSET := (WINDOW_LOWER_RIGHT_X * BITS_PER_PIXEL) mod 8;
  401.       case RIGHT_BYTE_OFFSET is
  402.     when 7      => RIGHT_TMP_MASK := 16#FE#;
  403.     when 6      => RIGHT_TMP_MASK := 16#FC#;
  404.     when 5      => RIGHT_TMP_MASK := 16#F8#;
  405.     when 4      => RIGHT_TMP_MASK := 16#F0#;
  406.     when 3      => RIGHT_TMP_MASK := 16#E0#;
  407.     when 2      => RIGHT_TMP_MASK := 16#C0#;
  408.     when 1      => RIGHT_TMP_MASK := 16#80#;
  409.     when 0      => RIGHT_TMP_MASK := 16#00#;
  410.     when others => RIGHT_TMP_MASK := 16#FF#;
  411.       end case;
  412.  
  413.       -- ==========================================================================
  414.       --
  415.       --                         CGA MODE
  416.       --
  417.       -- ==========================================================================
  418.       if GRAPH_SCREEN >= 4  and GRAPH_SCREEN <= 6 then
  419.  
  420.         if WINDOW_UPPER_LEFT_Y mod 2 = 0 then
  421.       EVEN_ROW_START_ADDRESS := SYSTEM_ADDRESS +
  422.                     long_integer(WINDOW_LEFT_OFFSET);
  423.       ODD_ROW_START_ADDRESS  := SYSTEM_ADDRESS + ODD_ROW_MEMORY_OFFSET +
  424.                     long_integer(WINDOW_LEFT_OFFSET);
  425.         else
  426.       ODD_ROW_START_ADDRESS := SYSTEM_ADDRESS + ODD_ROW_MEMORY_OFFSET +
  427.                    long_integer(WINDOW_LEFT_OFFSET);
  428.       EVEN_ROW_START_ADDRESS := ((long_integer(WINDOW_UPPER_LEFT_Y) +
  429.                       long_integer(1) / long_integer(2)) *
  430.                      long_integer(BYTES_PER_ROW) +
  431.                      long_integer(WINDOW_LEFT_OFFSET)) +
  432.                     SYSTEM_ADDRESS;
  433.         end if;
  434.  
  435.         for ROW_NUMBER in WINDOW_UPPER_LEFT_Y..WINDOW_LOWER_RIGHT_Y loop
  436.       ODD_ROW_ADDRESS  := ODD_ROW_START_ADDRESS;
  437.           EVEN_ROW_ADDRESS := EVEN_ROW_START_ADDRESS;
  438.           if ROW_NUMBER mod 2 = 0 then
  439.             if LEFT_BYTE_OFFSET > 0 then
  440.               INDEX := INDEX + 1;
  441.               READ_BYTE := SPY.PEEK(SYSTEM.ADDRESS(EVEN_ROW_ADDRESS));
  442.               READ_BYTE := READ_BYTE and LEFT_TMP_MASK;
  443.           BYTE_RECORD.BYTE_ARRAY(INDEX) := READ_BYTE;
  444.               EVEN_ROW_ADDRESS := EVEN_ROW_ADDRESS + long_integer(1);
  445.             end if;
  446.             for COUNT in 1 .. NUMBER_OF_BYTES loop
  447.               INDEX := INDEX + 1;
  448.           BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  449.           SPY.PEEK(SYSTEM.ADDRESS(EVEN_ROW_ADDRESS));
  450.               EVEN_ROW_ADDRESS := EVEN_ROW_ADDRESS + long_integer(1);
  451.             end loop;
  452.             if RIGHT_BYTE_OFFSET >0 then
  453.           BYTE_RECORD.BYTE_ARRAY(INDEX + 1) :=
  454.         SPY.PEEK(SYSTEM.ADDRESS(EVEN_ROW_ADDRESS)) and RIGHT_TMP_MASK;
  455.             end if;
  456.         EVEN_ROW_START_ADDRESS := EVEN_ROW_START_ADDRESS +
  457.                       long_integer(BYTES_PER_ROW);
  458.           else
  459.             if LEFT_BYTE_OFFSET > 0 then
  460.               INDEX := INDEX + 1;
  461.               READ_BYTE := SPY.PEEK(SYSTEM.ADDRESS(ODD_ROW_ADDRESS));
  462.           BYTE_RECORD.BYTE_ARRAY(INDEX) := READ_BYTE and LEFT_TMP_MASK;
  463.               ODD_ROW_ADDRESS := ODD_ROW_ADDRESS + long_integer(1);
  464.             end if;
  465.             for COUNT in 1 .. NUMBER_OF_BYTES loop
  466.               INDEX := INDEX + 1;
  467.           BYTE_RECORD.BYTE_ARRAY(INDEX) := SPY.PEEK(SYSTEM.ADDRESS(ODD_ROW_ADDRESS));
  468.               ODD_ROW_ADDRESS := ODD_ROW_ADDRESS + long_integer(1);
  469.             end loop;
  470.             if RIGHT_BYTE_OFFSET > 0 then
  471.           BYTE_RECORD.BYTE_ARRAY(INDEX + 1) :=
  472.           SPY.PEEK(SYSTEM.ADDRESS(ODD_ROW_ADDRESS));
  473.             end if;
  474.         ODD_ROW_START_ADDRESS := ODD_ROW_START_ADDRESS +
  475.                      long_integer(BYTES_PER_ROW);
  476.           end if;
  477.       if not WINDOW_IO.Write(REC => BYTE_RECORD) then
  478.         return;
  479.       end if;
  480.           INDEX := 0;
  481.         end loop;
  482.  
  483.         -- ===========================================================================
  484.         --
  485.         --                        EGA MODE
  486.         --
  487.         -- ===========================================================================
  488.       else
  489.         if ACTIVE_PAGE =0 then
  490.       START_ADDRESS := PAGE1_MEMORY_START +
  491.                long_integer(WINDOW_LEFT_OFFSET);
  492.         else
  493.       START_ADDRESS := PAGE2_MEMORY_START +
  494.                long_integer(WINDOW_LEFT_OFFSET);
  495.         end if;
  496.     for ROW_COUNT in
  497.         WINDOW_UPPER_LEFT_Y .. WINDOW_LOWER_RIGHT_Y + READ_WRITE_OFFSET
  498.         loop
  499.           TMP_ADDRESS := START_ADDRESS;
  500.           INDEX := 0;
  501.           if LEFT_BYTE_OFFSET > 0 then
  502.             INDEX := INDEX + 1;
  503.             PORT.OUT_WORD(16#03CE#,16#0004#);
  504.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  505.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS));
  506.             INDEX := INDEX + 1;
  507.             PORT.OUT_WORD(16#03CE#,16#0104#);
  508.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  509.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS)) ;
  510.             INDEX := INDEX + 1;
  511.             PORT.OUT_WORD(16#03CE#,16#0204#);
  512.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  513.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS)) ;
  514.             INDEX := INDEX + 1;
  515.             PORT.OUT_WORD(16#03CE#,16#0304#);
  516.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  517.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS)) ;
  518.             TMP_ADDRESS := TMP_ADDRESS + long_integer(1);
  519.           end if;
  520.           for COUNT in 1..NUMBER_OF_BYTES  loop
  521.             INDEX := INDEX + 1;
  522.             PORT.OUT_WORD(16#03CE#,16#0004#);
  523.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  524.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS)) ;
  525.             INDEX := INDEX + 1;
  526.             PORT.OUT_WORD(16#03CE#,16#0104#);
  527.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  528.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS)) ;
  529.             INDEX := INDEX + 1;
  530.             PORT.OUT_WORD(16#03CE#,16#0204#);
  531.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  532.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS)) ;
  533.             INDEX := INDEX + 1;
  534.             PORT.OUT_WORD(16#03CE#,16#0304#);
  535.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  536.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS));
  537.             TMP_ADDRESS := TMP_ADDRESS + long_integer(1);
  538.           end loop;
  539.           if RIGHT_BYTE_OFFSET > 0 then
  540.             INDEX := INDEX + 1;
  541.             PORT.OUT_WORD(16#03CE#,16#0004#);
  542.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  543.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS));
  544.             INDEX := INDEX + 1;
  545.             PORT.OUT_WORD(16#03CE#,16#0104#);
  546.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  547.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS));
  548.             INDEX := INDEX + 1;
  549.             PORT.OUT_WORD(16#03CE#,16#0204#);
  550.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  551.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS));
  552.             INDEX := INDEX + 1;
  553.             PORT.OUT_WORD(16#03CE#,16#0304#);
  554.         BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  555.         SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS));
  556.           end if;
  557.       if not WINDOW_IO.Write(REC => BYTE_RECORD) then
  558.         return;
  559.       end if;
  560.  
  561.           START_ADDRESS := START_ADDRESS + long_integer(BYTES_PER_ROW);
  562.         end loop;
  563.       end if;
  564.       if not WINDOW_IO.Close then
  565.     return;
  566.       end if;
  567.     else
  568.       Put_line("Window hasn't been defined");
  569.     end if;
  570.  
  571.   end SAVE_WINDOW;
  572.  
  573.   -- ==========================================================================
  574.   --
  575.   --                           LOAD_WINDOW
  576.   --
  577.   -- ==========================================================================
  578.   procedure LOAD_WINDOW(WINDOW_INDEX : in INDEX_NUMBER;
  579.                         FILENAME     : in string;
  580.                         NEWX,
  581.                         NEWY         : in integer) is
  582.  
  583.     GOOD,
  584.     FOUND                  : boolean;
  585.     MASK                   : constant COMMON_DISPLAY_TYPES.byte := 16#FF#;
  586.     BYTE_SIZE              : constant := 8;
  587.     ODD_ROW_MEMORY_OFFSET  : constant long_integer := 16#2000#;
  588.     SEGMENT_MULTIPLIER     : constant long_integer := 16#1000#;
  589.     RIGHT_TMP_MASK,
  590.     LEFT_TMP_MASK          : COMMON_DISPLAY_TYPES.byte := MASK;
  591.     READ_BYTE              : SPY.byte;
  592.     TMP_REC                : LIST_RECORD;
  593.     TMP_PTR                : LIST_PTR := WDW_LIST;
  594.     WINDOW_UPPER_LEFT_X,
  595.     WINDOW_LOWER_RIGHT_X   : COMMON_GRAPHIC_TYPES.HORIZONTAL;
  596.     WINDOW_UPPER_LEFT_Y,
  597.     WINDOW_LOWER_RIGHT_Y   : COMMON_GRAPHIC_TYPES.VERTICAL;
  598.     LEFT_BYTE_OFFSET,
  599.     RIGHT_BYTE_OFFSET      : COMMON_DISPLAY_TYPES.byte;
  600.     SYSTEM_ADDRESS,
  601.     START_ADDRESS,
  602.     TMP_ADDRESS,
  603.     EVEN_ROW_ADDRESS,
  604.     ODD_ROW_ADDRESS,
  605.     EVEN_ROW_START_ADDRESS,
  606.     ODD_ROW_START_ADDRESS    : long_integer;
  607.     BYTE_RECORD              : WINDOW_IO.BYTE_REC;
  608.     BITS_PER_PIXEL,
  609.     WINDOW_LEFT_OFFSET,
  610.     WINDOW_RIGHT_OFFSET,
  611.     NUMBER_OF_BYTES,
  612.     BYTES_PER_ROW,
  613.     NEW_RIGHT_Y,
  614.     NEW_RIGHT_X,
  615.     READ_WRITE_OFFSET,
  616.     INDEX                    : integer := 0;
  617.  
  618.   begin --LOAD_WINDOW
  619.  
  620.     FIND_RECORD_IN_LIST(WINDOW_INDEX, TMP_PTR, TMP_REC, FOUND);
  621.     if FOUND then
  622.       if not WINDOW_IO.Open(FILE_NAME => FILENAME) then
  623.     return;
  624.       end if;
  625.       CURRENT_WINDOW_INDEX_NO := WINDOW_INDEX;
  626.  
  627.       -- ===========================================================================
  628.       --
  629.       --  Convert to pixel values
  630.       --
  631.       -- ===========================================================================
  632.       WINDOW_UPPER_LEFT_X  := TMP_REC.UPRLFTX  * CHARACTER_PIXEL_WIDTH;
  633.       WINDOW_UPPER_LEFT_Y  := TMP_REC.UPRLFTY  * CHARACTER_PIXEL_HEIGHT;
  634.       WINDOW_LOWER_RIGHT_X := TMP_REC.LWRRGHTX * CHARACTER_PIXEL_WIDTH +
  635.                   (CHARACTER_PIXEL_WIDTH - 1);
  636.       WINDOW_LOWER_RIGHT_Y := TMP_REC.LWRRGHTY * CHARACTER_PIXEL_HEIGHT +
  637.                   (CHARACTER_PIXEL_HEIGHT - 1);
  638.  
  639.       -- ===========================================================================
  640.       --
  641.       --  See if new coordinates are within the screen limits
  642.       --
  643.       -- ===========================================================================
  644.       if NEWX >= 0 and NEWX <= 79 and NEWY >= 0 and NEWY <= 54 then
  645.     NEW_RIGHT_X := ((NEWX + (TMP_REC.LWRRGHTX - TMP_REC.UPRLFTX)) *
  646.             CHARACTER_PIXEL_WIDTH) + CHARACTER_PIXEL_WIDTH - 1;
  647.     NEW_RIGHT_Y := ((NEWY + (TMP_REC.LWRRGHTY - TMP_REC.UPRLFTY)) *
  648.             CHARACTER_PIXEL_HEIGHT) + CHARACTER_PIXEL_HEIGHT - 1;
  649.         if NEW_RIGHT_Y <= SCREEN_DIMENSION_LOWER_RIGHT_Y and
  650.        NEW_RIGHT_X <= SCREEN_DIMENSION_LOWER_RIGHT_X then
  651.       WINDOW_UPPER_LEFT_Y  := NEWY * CHARACTER_PIXEL_HEIGHT;
  652.       WINDOW_UPPER_LEFT_X  := NEWX * CHARACTER_PIXEL_WIDTH;
  653.           WINDOW_LOWER_RIGHT_Y := NEW_RIGHT_Y;
  654.           WINDOW_LOWER_RIGHT_X := NEW_RIGHT_X;
  655.         end if;
  656.       end if;
  657.  
  658.       -- ===========================================================================
  659.       --
  660.       --  Set global values
  661.       --
  662.       -- ===========================================================================
  663.       CURRENT_WINDOW_UPPER_LEFT_X  := WINDOW_UPPER_LEFT_X;
  664.       CURRENT_WINDOW_UPPER_LEFT_Y  := WINDOW_UPPER_LEFT_Y;
  665.       CURRENT_WINDOW_LOWER_RIGHT_X := WINDOW_LOWER_RIGHT_X;
  666.       CURRENT_WINDOW_LOWER_RIGHT_Y := WINDOW_LOWER_RIGHT_Y;
  667.  
  668.       -- ===========================================================================
  669.       --
  670.       --  Check for graphics type to determine bits_per_pixel.  2 bits required
  671.       --  for CGA 4 color mode, all other modes have 1 bit per pixel.  The
  672.       --  graphics mode will also determine how many bytes there are per row.
  673.       --  If 350 x 200 there is 40 bytes per row otherwise, there are 80 bytes
  674.       --  to a row.  An additional offset is reqired for EGA to read all the
  675.       --  rows.
  676.       --
  677.       -- ===========================================================================
  678.  
  679.       case GRAPH_SCREEN is
  680.  
  681.         when 4 | 5  =>
  682.       BYTES_PER_ROW  := 80;
  683.           BITS_PER_PIXEL := 2;
  684.  
  685.         when 6 =>
  686.       BYTES_PER_ROW  := 80;
  687.           BITS_PER_PIXEL := 1;
  688.  
  689.         when 14 =>
  690.       BYTES_PER_ROW     := 40;
  691.           READ_WRITE_OFFSET := 20;
  692.       BITS_PER_PIXEL    := 1;
  693.  
  694.         when 15 =>
  695.       BYTES_PER_ROW     := 80;
  696.           READ_WRITE_OFFSET := 20;
  697.       BITS_PER_PIXEL    := 1;
  698.  
  699.         when 16 | 17 =>
  700.       BYTES_PER_ROW     := 80;
  701.           READ_WRITE_OFFSET := 0;
  702.       BITS_PER_PIXEL    := 1;
  703.  
  704.         when 18 | 19 =>
  705.       BYTES_PER_ROW     := 80;
  706.           READ_WRITE_OFFSET := 48;
  707.       BITS_PER_PIXEL    := 1;
  708.  
  709.         when others =>
  710.           null;
  711.       end case;
  712.  
  713.       -- ===========================================================================
  714.       --
  715.       -- Determine offset into first and last byte in row.  If Cga mode then
  716.       -- need to adjust rows, since odd rows are in the second 8k of memory and
  717.       -- even rows are in the first 8k of display memory.
  718.       --
  719.       -- ===========================================================================
  720.  
  721.       if GRAPH_SCREEN >= 4 and GRAPH_SCREEN <= 6 then
  722.     WINDOW_LEFT_OFFSET :=
  723.         ((WINDOW_UPPER_LEFT_Y * BYTES_PER_ROW ) / 2) +
  724.         ((WINDOW_UPPER_LEFT_X * BITS_PER_PIXEL) / BYTE_SIZE);
  725.       else
  726.     WINDOW_LEFT_OFFSET :=
  727.         ( WINDOW_UPPER_LEFT_Y * BYTES_PER_ROW ) +
  728.         ((WINDOW_UPPER_LEFT_X * BITS_PER_PIXEL) / BYTE_SIZE);
  729.       end if;
  730.       NUMBER_OF_BYTES := ((WINDOW_LOWER_RIGHT_X - WINDOW_UPPER_LEFT_X) *
  731.               BITS_PER_PIXEL) / BYTE_SIZE;
  732.       LEFT_BYTE_OFFSET := (WINDOW_UPPER_LEFT_X * BITS_PER_PIXEL) mod 8;
  733.  
  734.       case LEFT_BYTE_OFFSET is
  735.     when 7      =>  LEFT_TMP_MASK := 16#7F#;
  736.     when 6      =>  LEFT_TMP_MASK := 16#3F#;
  737.     when 5      =>  LEFT_TMP_MASK := 16#1F#;
  738.     when 4      =>  LEFT_TMP_MASK := 16#0F#;
  739.     when 3      =>  LEFT_TMP_MASK := 16#07#;
  740.     when 2      =>  LEFT_TMP_MASK := 16#03#;
  741.     when 1      =>  LEFT_TMP_MASK := 16#01#;
  742.     when 0      =>  LEFT_TMP_MASK := 16#00#;
  743.     when others =>  LEFT_TMP_MASK := 16#FF#;
  744.       end case;
  745.  
  746.       RIGHT_BYTE_OFFSET := (WINDOW_LOWER_RIGHT_X * BITS_PER_PIXEL) mod 8;
  747.       case RIGHT_BYTE_OFFSET is
  748.     when 7      =>  RIGHT_TMP_MASK := 16#FE#;
  749.     when 6      =>  RIGHT_TMP_MASK := 16#FC#;
  750.     when 5      =>  RIGHT_TMP_MASK := 16#F8#;
  751.     when 4      =>  RIGHT_TMP_MASK := 16#F0#;
  752.     when 3      =>  RIGHT_TMP_MASK := 16#E0#;
  753.     when 2      =>  RIGHT_TMP_MASK := 16#C0#;
  754.     when 1      =>  RIGHT_TMP_MASK := 16#80#;
  755.     when 0      =>  RIGHT_TMP_MASK := 16#00#;
  756.     when others =>  RIGHT_TMP_MASK := 16#FF#;
  757.       end case;
  758.  
  759.       -- ===========================================================================
  760.       --
  761.       --                             CGA MODE
  762.       --
  763.       -- ===========================================================================
  764.       if GRAPH_SCREEN >= 4 and GRAPH_SCREEN <= 6 then
  765.     SYSTEM_ADDRESS := PAGE1_MEMORY_START;
  766.         if WINDOW_UPPER_LEFT_Y mod 2 = 0 then
  767.       EVEN_ROW_START_ADDRESS := SYSTEM_ADDRESS +
  768.                     long_integer(WINDOW_LEFT_OFFSET);
  769.       ODD_ROW_START_ADDRESS  := SYSTEM_ADDRESS + ODD_ROW_MEMORY_OFFSET +
  770.                     long_integer(WINDOW_LEFT_OFFSET);
  771.         else
  772.       ODD_ROW_START_ADDRESS := SYSTEM_ADDRESS + ODD_ROW_MEMORY_OFFSET +
  773.                    long_integer(WINDOW_LEFT_OFFSET);
  774.       EVEN_ROW_START_ADDRESS := ((long_integer(WINDOW_UPPER_LEFT_Y) +
  775.                       long_integer(1) / long_integer(2)) *
  776.                      long_integer(BYTES_PER_ROW) +
  777.                      long_integer(WINDOW_LEFT_OFFSET)) +
  778.                     SYSTEM_ADDRESS;
  779.         end if;
  780.  
  781.     for ROW_NUMBER in WINDOW_UPPER_LEFT_Y .. WINDOW_LOWER_RIGHT_Y loop
  782.       EVEN_ROW_ADDRESS := EVEN_ROW_START_ADDRESS;
  783.       ODD_ROW_ADDRESS  := ODD_ROW_START_ADDRESS;
  784.       WINDOW_IO.Read(REC => BYTE_RECORD, OK => GOOD);
  785.       if not GOOD then
  786.         return;
  787.       end if;
  788.  
  789.           if ROW_NUMBER mod 2 = 0 then
  790.             if LEFT_BYTE_OFFSET > 0 then
  791.               INDEX := INDEX + 1;
  792.           BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  793.           BYTE_RECORD.BYTE_ARRAY(INDEX) and LEFT_TMP_MASK;
  794.           SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  795.                SYSTEM.ADDRESS(EVEN_ROW_ADDRESS));
  796.               EVEN_ROW_ADDRESS := EVEN_ROW_ADDRESS + long_integer(1);
  797.             end if;
  798.             for COUNT in 1 .. NUMBER_OF_BYTES loop
  799.               INDEX := INDEX + 1;
  800.           SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  801.                SYSTEM.ADDRESS(EVEN_ROW_ADDRESS));
  802.               EVEN_ROW_ADDRESS := EVEN_ROW_ADDRESS + long_integer(1);
  803.             end loop;
  804.             if RIGHT_BYTE_OFFSET > 0 then
  805.               INDEX := INDEX + 1;
  806.           BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  807.           BYTE_RECORD.BYTE_ARRAY(INDEX) and RIGHT_TMP_MASK;
  808.           SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  809.                SYSTEM.ADDRESS(EVEN_ROW_ADDRESS));
  810.             end if;
  811.         EVEN_ROW_START_ADDRESS := EVEN_ROW_START_ADDRESS +
  812.                       long_integer(BYTES_PER_ROW);
  813.           else
  814.             if LEFT_BYTE_OFFSET > 0 then
  815.               INDEX := INDEX + 1;
  816.           BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  817.           BYTE_RECORD.BYTE_ARRAY(INDEX) and LEFT_TMP_MASK;
  818.           SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  819.                SYSTEM.ADDRESS(ODD_ROW_ADDRESS));
  820.               ODD_ROW_ADDRESS := ODD_ROW_ADDRESS + long_integer(1);
  821.             end if;
  822.             for COUNT in 1 .. NUMBER_OF_BYTES loop
  823.               INDEX := INDEX + 1;
  824.           SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  825.                SYSTEM.ADDRESS(ODD_ROW_ADDRESS));
  826.               ODD_ROW_ADDRESS := ODD_ROW_ADDRESS + long_integer(1);
  827.             end loop;
  828.             if RIGHT_BYTE_OFFSET > 0 then
  829.               INDEX := INDEX + 1;
  830.           BYTE_RECORD.BYTE_ARRAY(INDEX) :=
  831.           BYTE_RECORD.BYTE_ARRAY(INDEX) and RIGHT_TMP_MASK;
  832.           SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  833.                SYSTEM.ADDRESS(ODD_ROW_ADDRESS));
  834.             end if;
  835.         ODD_ROW_START_ADDRESS := ODD_ROW_START_ADDRESS +
  836.                      long_integer(BYTES_PER_ROW);
  837.           end if;
  838.           INDEX := 0;
  839.         end loop;
  840.       else
  841.  
  842.         -- ===========================================================================
  843.         --
  844.         --                               EGA MODE
  845.         --
  846.         -- ===========================================================================
  847.         if ACTIVE_PAGE =0 then
  848.       START_ADDRESS := PAGE1_MEMORY_START +
  849.                long_integer(WINDOW_LEFT_OFFSET);
  850.         else
  851.       START_ADDRESS := PAGE2_MEMORY_START +
  852.                long_integer(WINDOW_LEFT_OFFSET);
  853.         end if;
  854.  
  855.     for ROW_COUNT in
  856.         WINDOW_UPPER_LEFT_Y .. WINDOW_LOWER_RIGHT_Y + READ_WRITE_OFFSET
  857.         loop
  858.       WINDOW_IO.Read(REC => BYTE_RECORD, OK => GOOD);
  859.       if not GOOD then
  860.         return;
  861.       end if;
  862.  
  863.           INDEX := 0;
  864.           TMP_ADDRESS := START_ADDRESS;
  865.           if LEFT_BYTE_OFFSET > 0 then
  866.             INDEX := INDEX + 1;
  867.             PORT.OUT_WORD(16#03CE#,16#0008#);
  868.             PORT.OUT_WORD(16#03CF#,LEFT_TMP_MASK);
  869.             READ_BYTE := SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS));
  870.             SPY.POKE(16#00#,SYSTEM.ADDRESS(TMP_ADDRESS));
  871.             PORT.OUT_WORD(16#03C4#,16#0002#);
  872.             PORT.OUT_WORD(16#03C5#,16#0001#);
  873.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  874.              SYSTEM.ADDRESS(TMP_ADDRESS));
  875.             INDEX := INDEX + 1;
  876.             PORT.OUT_WORD(16#03C5#,16#0002#);
  877.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  878.              SYSTEM.ADDRESS(TMP_ADDRESS));
  879.             INDEX := INDEX + 1;
  880.             PORT.OUT_WORD(16#03C5#,16#0004#);
  881.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  882.              SYSTEM.ADDRESS(TMP_ADDRESS));
  883.             INDEX := INDEX + 1;
  884.             PORT.OUT_WORD(16#03C5#,16#0008#);
  885.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  886.              SYSTEM.ADDRESS(TMP_ADDRESS));
  887.             TMP_ADDRESS := TMP_ADDRESS + long_integer(1);
  888.           end if;
  889.           for COUNT in 1..NUMBER_OF_BYTES loop
  890.             INDEX := INDEX + 1;
  891.             PORT.OUT_WORD(16#3CE#,16#0008#);
  892.             PORT.OUT_WORD(16#3CF#,16#00FF#);
  893.             READ_BYTE := SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS));
  894.             SPY.POKE(16#00#,SYSTEM.ADDRESS(TMP_ADDRESS));
  895.             PORT.OUT_WORD(16#3C4#,16#0002#);
  896.             PORT.OUT_WORD(16#03C5#,16#0001#);
  897.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  898.              SYSTEM.ADDRESS(TMP_ADDRESS));
  899.             INDEX := INDEX + 1;
  900.             PORT.OUT_WORD(16#03C5#,16#0002#);
  901.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  902.              SYSTEM.ADDRESS(TMP_ADDRESS));
  903.             INDEX := INDEX + 1;
  904.             PORT.OUT_WORD(16#03C5#,16#0004#);
  905.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  906.              SYSTEM.ADDRESS(TMP_ADDRESS));
  907.             INDEX := INDEX + 1;
  908.             PORT.OUT_WORD(16#03C5#,16#0008#);
  909.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  910.              SYSTEM.ADDRESS(TMP_ADDRESS));
  911.             TMP_ADDRESS := TMP_ADDRESS + long_integer(1);
  912.       end loop;
  913.  
  914.           if RIGHT_BYTE_OFFSET > 0 then
  915.             RIGHT_TMP_MASK := SHR(RIGHT_TMP_MASK,RIGHT_BYTE_OFFSET);
  916.             INDEX := INDEX + 1;
  917.             PORT.OUT_WORD(16#3CE#,16#0008#);
  918.             PORT.OUT_WORD(16#3CF#,16#00FF#);
  919.             READ_BYTE := SPY.PEEK(SYSTEM.ADDRESS(TMP_ADDRESS));
  920.             SPY.POKE(16#00#,SYSTEM.ADDRESS(TMP_ADDRESS));
  921.             PORT.OUT_WORD(16#3C4#,16#0002#);
  922.             PORT.OUT_WORD(16#03C5#,16#0001#);
  923.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  924.              SYSTEM.ADDRESS(TMP_ADDRESS));
  925.             INDEX := INDEX + 1;
  926.             PORT.OUT_WORD(16#03C5#,16#0002#);
  927.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  928.              SYSTEM.ADDRESS(TMP_ADDRESS));
  929.             INDEX := INDEX + 1;
  930.             PORT.OUT_WORD(16#03C5#,16#0004#);
  931.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  932.              SYSTEM.ADDRESS(TMP_ADDRESS));
  933.             INDEX := INDEX + 1;
  934.             PORT.OUT_WORD(16#03C5#,16#0008#);
  935.         SPY.POKE(BYTE_RECORD.BYTE_ARRAY(INDEX),
  936.              SYSTEM.ADDRESS(TMP_ADDRESS));
  937.           end if;
  938.           START_ADDRESS := START_ADDRESS + long_integer(BYTES_PER_ROW);
  939.         end loop;
  940.       end if;
  941.       if not WINDOW_IO.Close then
  942.      return;
  943.       end if;
  944.  
  945.     else
  946.       Put_line("Window hasn't been defined");
  947.     end if;
  948.  
  949.   end LOAD_WINDOW;
  950.  
  951.   -- ==========================================================================
  952.   --
  953.   --                              RESET_WINDOW
  954.   --
  955.   -- ==========================================================================
  956.   procedure RESET_WINDOW is
  957.   begin
  958.     CURRENT_WINDOW_INDEX_NO := 0;
  959.     CLIP_ENABLE := false;
  960.     DELETE_LIST(WDW_LIST);
  961.     CURRENT_WINDOW_UPPER_LEFT_X  := SCREEN_DIMENSION_UPPER_LEFT_X;
  962.     CURRENT_WINDOW_UPPER_LEFT_Y  := SCREEN_DIMENSION_UPPER_LEFT_Y;
  963.     CURRENT_WINDOW_LOWER_RIGHT_X := SCREEN_DIMENSION_LOWER_RIGHT_X;
  964.     CURRENT_WINDOW_LOWER_RIGHT_Y := SCREEN_DIMENSION_LOWER_RIGHT_Y;
  965.   end RESET_WINDOW;
  966.  
  967.   -- =========================================================================
  968.   --
  969.   --                          WORLD_COORDINATES
  970.   --
  971.   -- =========================================================================
  972.   procedure WORLD_COORDINATES(WORLD_INDEX      : in INDEX_NUMBER;
  973.                   WLDLWRX, WLDLWRY : in integer) is
  974.   begin
  975.     if WORLD_INDEX >= 1 and WORLD_INDEX <= 8 then
  976.       WLD_REC.REC_INDEX := WORLD_INDEX;
  977.       WLD_REC.LWRRGHTX  := WLDLWRX;
  978.       WLD_REC.LWRRGHTY  := WLDLWRY;
  979.       ADD_RECORD_TO_LIST(WLD_REC,WLD_LIST,WORLD_INDEX);
  980.     else
  981.       Put_line(" World index out of bound.");
  982.     end if;
  983.   end WORLD_COORDINATES;
  984.  
  985.   -- =========================================================================
  986.   --
  987.   --                            WORLD_SELECT
  988.   --
  989.   -- =========================================================================
  990.   procedure WORLD_SELECT(WORLD_INDEX : in INDEX_NUMBER) is
  991.  
  992.     TMP_PTR      : LIST_PTR := WLD_LIST;
  993.     TMP_REC      : LIST_RECORD;
  994.     FOUND        : boolean;
  995.     WORLD_VALUE  : integer;
  996.     SCREEN_VALUE : float;
  997.  
  998.   begin
  999.  
  1000.     FIND_RECORD_IN_LIST(WORLD_INDEX,TMP_PTR,TMP_REC,FOUND);
  1001.     if FOUND then
  1002.       CURRENT_WORLD_INDEX_NO      := WORLD_INDEX;
  1003.       CURRENT_WORLD_LOWER_RIGHT_X := TMP_REC.LWRRGHTX;
  1004.       CURRENT_WORLD_LOWER_RIGHT_Y := TMP_REC.LWRRGHTY;
  1005.       WORLD_VALUE                 := CURRENT_WORLD_LOWER_RIGHT_X -
  1006.                      CURRENT_WORLD_LEFT_X;
  1007.       SCREEN_VALUE                := float(SCREEN_DIMENSION_LOWER_RIGHT_X -
  1008.                        SCREEN_DIMENSION_UPPER_LEFT_X);
  1009.       SCREEN_WORLD_RATIO_X        := SCREEN_VALUE / (float (WORLD_VALUE));
  1010.       WORLD_VALUE                 := CURRENT_WORLD_LOWER_RIGHT_Y -
  1011.                      CURRENT_WORLD_LEFT_Y;
  1012.       SCREEN_VALUE                := float(SCREEN_DIMENSION_LOWER_RIGHT_Y -
  1013.                        SCREEN_DIMENSION_UPPER_LEFT_Y);
  1014.       SCREEN_WORLD_RATIO_Y        := SCREEN_VALUE / (float (WORLD_VALUE));
  1015.     else
  1016.       Put_line("World has not been defined.");
  1017.     end if;
  1018.  
  1019.   end WORLD_SELECT;
  1020.  
  1021.   -- ==========================================================================
  1022.   --
  1023.   --                                WORLD_RESET
  1024.   --
  1025.   -- ==========================================================================
  1026.  
  1027.   procedure WORLD_RESET is
  1028.   begin
  1029.     CURRENT_WORLD_INDEX_NO := 0;
  1030.     DELETE_LIST(WLD_LIST);
  1031.     CURRENT_WORLD_LOWER_RIGHT_X := SCREEN_DIMENSION_LOWER_RIGHT_X;
  1032.     CURRENT_WORLD_LOWER_RIGHT_Y := SCREEN_DIMENSION_LOWER_RIGHT_Y;
  1033.     SCREEN_WORLD_RATIO_X := 1.0;
  1034.     SCREEN_WORLD_RATIO_Y := 1.0;
  1035.   end WORLD_RESET;
  1036.  
  1037. end WINDOW;
  1038.