home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / WINTUTOR.ZIP / WINDO.INC next >
Encoding:
Text File  |  1986-01-29  |  25.4 KB  |  487 lines

  1. { ===================================================================== }
  2. {  WINDO - Windowing routines for Turbo PASCAL                          }
  3. {                                                                       }
  4. {     Author:   Michael Burton                                          }
  5. {               15540 Boot Hill Rd.                                     }
  6. {               Hayden Lake, ID 83835                                   }
  7. {               (208) 772-9347 (after 1800 PST)                         }
  8. {     Revision: 2.0                                                     }
  9. {     Date:     25 January 1986                                         }
  10. {                                                                       }
  11. {  Execute the WINTUTOR program for an explanation of use.              }
  12. {                                                                       }
  13. {  This is a 'Shareware' program.  If you find it to be of significant  }
  14. {  use to you, a $10 donation to the above address would be greatly     }
  15. {  appreciated.  This would also place you on our mailing list to keep  }
  16. {  you informed of upgrades to Windo and of new programs.               }
  17. { ===================================================================== }
  18. type
  19.      windimtype = record
  20.                      colb,rowb,cole,rowe,attrib,bordr,lastx,lasty : byte;
  21.                   end;
  22.      charptr = ^char;
  23.      winstr = string[80];
  24.      brdtype = record
  25.                   ul,ur,ll,lr,hz,vtl,vtr: char;
  26.                end;
  27.  
  28. const maxwin  = 30;        { Total number of windows on screen at any time }
  29.       noneb   = 0;         { No border           }
  30.       singleb = 1;         { Single border       }
  31.       doubleb = 2;         { Double border       }
  32.       mixedb  = 3;         { Mixed border        }
  33.       solidb  = 4;         { Solid border        }
  34.       dimondb = 5;         { Diamond border      }
  35.       circleb = 6;         { Circles border      }
  36.       lhatchb = 7;         { light hatch border  }
  37.       mhatchb = 8;         { medium hatch border }
  38.       dhatchb = 9;         { dense hatch border  }
  39.       brd: array[1..9] of brdtype =  (
  40.           (ul:'┌';ur:'┐';ll:'└';lr:'┘';hz:'─';vtl:'│';vtr:'│'),  { single }
  41.           (ul:'╔';ur:'╗';ll:'╚';lr:'╝';hz:'═';vtl:'║';vtr:'║'),  { double }
  42.           (ul:'╒';ur:'╕';ll:'╘';lr:'╛';hz:'═';vtl:'│';vtr:'│'),  { mixed  }
  43.           (ul:'█';ur:'█';ll:'█';lr:'█';hz:'█';vtl:'▌';vtr:'▐'),  { solid  }
  44.           (ul:' ';ur:' ';ll:' ';lr:' ';hz:' ';vtl:' ';vtr:' '),  { diamond}
  45.           (ul:' ';ur:' ';ll:' ';lr:' ';hz:' ';vtl:' ';vtr:' '),  { circle }
  46.           (ul:'░';ur:'░';ll:'░';lr:'░';hz:'░';vtl:'░';vtr:'░'),  { lhatch }
  47.           (ul:'▒';ur:'▒';ll:'▒';lr:'▒';hz:'▒';vtl:'▒';vtr:'▒'),  { mhatch }
  48.           (ul:'▓';ur:'▓';ll:'▓';lr:'▓';hz:'▓';vtl:'▓';vtr:'▓')); { dhatch }
  49.  
  50. var
  51.      wndo    : Array [0..maxwin] of windimtype; { window attributes      }
  52.      wndoptr : Array [1..maxwin] of charptr; { pointer to window on heap }
  53.      tmpptr  : charptr;                      { temporary pointer         }
  54.      l_i  : byte;                            { level index               }
  55.      wndostr : winstr;                       { string for building wndos }
  56.  
  57. { ===================================================================== }
  58. { GETDISP - Get an array of characters from the CRT display and store   }
  59. {           them in tostrng.                                            }
  60. {           The row and column inputs are relative to zero and are      }
  61. {           also relative to the entire screen, not any open window.    }
  62. {                                                                       }
  63. {    Inputs:                                                            }
  64. {       colb      : byte;    Starting column (0 - 79)                   }
  65. {       rowb      : byte;    Starting row    (0 - 24)                   }
  66. {       len       : byte;    length of array                            }
  67. {       tostrng   : charptr; Pointer to character storage               }
  68. { ===================================================================== }
  69. Procedure GetDisp(colb,rowb,len : byte; tostrng : charptr);
  70. Begin
  71.    Inline(
  72.       $1E/                    {           PUSH   DS               }
  73.       $8A/$86/rowb/           {           MOV    AL,rowb[BP]      }
  74.       $B3/$50/                {           MOV    BL,80            }
  75.       $F6/$E3/                {           MUL    BL               }
  76.       $2B/$DB/                {           SUB    BX,BX            }
  77.       $8A/$9E/colb/           {           MOV    BL,colb[BP]      }
  78.       $03/$C3/                {           ADD    AX,BX            }
  79.       $03/$C0/                {           ADD    AX,AX            }
  80.       $8B/$F8/                {           MOV    DI,AX            }
  81.       $C4/$B6/tostrng/        {           LES    SI,tostrng[BP]   }
  82.       $8A/$8E/len/            {           MOV    CL,len[BP]       }
  83.       $03/$C9/                {           ADD    CX,CX            }
  84.       $2B/$C0/                {           ADD    AX,AX            }
  85.       $8E/$D8/                {           MOV    DS,AX            }
  86.       $A0/$49/$04/            {           MOV    AL,DS:[0449H]    }
  87.       $22/$C9/                {           AND    CL,CL            }
  88.       $74/$32/                {           JZ     DONE             }
  89.       $2C/$07/                {           SUB    AL,7             }
  90.       $74/$20/                {           JZ     MONO             }
  91.       $BA/$00/$B8/            {           MOV    DX,0B800H        }
  92.       $8E/$DA/                {           MOV    DS,DX            }
  93.       $BA/$DA/$03/            {           MOV    DX,03DAH         }
  94.       $EC/                    { TESTLOW:  IN     AL,DX            }
  95.       $A8/$01/                {           TEST   AL,1             }
  96.       $75/$FB/                {           JNZ    TESTLOW          }
  97.       $FA/                    {           CLI                     }
  98.       $EC/                    { TESTHI:   IN     AL,DX            }
  99.       $A8/$01/                {           TEST   AL,1             }
  100.       $74/$FB/                {           JZ     TESTHI           }
  101.       $8A/$1D/                {           MOV    BL,DS:[DI]       }
  102.       $26/$88/$1C/            {           MOV    ES:[SI],BL       }
  103.       $47/                    {           INC    DI               }
  104.       $46/                    {           INC    SI               }
  105.       $E2/$EC/                {           LOOP   GETCHAR          }
  106.       $2A/$C0/                {           SUB    AL,AL            }
  107.       $74/$0E/                {           JZ     DONE             }
  108.       $BA/$00/$B0/            { MONO:     MOV    DX,0B000H        }
  109.       $8E/$DA/                {           MOV    DS,DX            }
  110.       $8A/$1D/                { MONO1:    MOV    BL,DS:[DI]       }
  111.       $26/$88/$1C/            {           MOV    ES:[SI],BL       }
  112.       $47/                    {           INC    DI               }
  113.       $46/                    {           INC    SI               }
  114.       $E2/$F7/                {           LOOP   MONO1            }
  115.       $1F);                   { DONE:     POP    DS               }
  116. End;
  117.  
  118. { ===================================================================== }
  119. { DISPALL - Display an array of characters and attributes on the CRT.   }
  120. {           The array is usually one that has been created using the    }
  121. {           GetDisp procedure.                                          }
  122. {           The row and column inputs are relative to zero and are      }
  123. {           also relative to the entire screen, not any open window.    }
  124. {                                                                       }
  125. {    Inputs:                                                            }
  126. {       colb      : byte;    Starting column  (0 - 79)                  }
  127. {       rowb      : byte;    Starting row     (0 - 24)                  }
  128. {       len       : byte;    length of array  (not including attributes)}
  129. {       fromstrng : charptr; Pointer to array to display                }
  130. { ===================================================================== }
  131. Procedure DispAll(colb,rowb,len : byte; fromstrng : charptr);
  132. Begin
  133.    Inline(
  134.       $1E/                    {           PUSH   DS               }
  135.       $8A/$86/rowb/           {           MOV    AL,rowb[BP]      }
  136.       $B3/$50/                {           MOV    BL,80            }
  137.       $F6/$E3/                {           MUL    BL               }
  138.       $2B/$DB/                {           SUB    BX,BX            }
  139.       $8A/$9E/colb/           {           MOV    BL,colb[BP]      }
  140.       $03/$C3/                {           ADD    AX,BX            }
  141.       $03/$C0/                {           ADD    AX,AX            }
  142.       $8B/$F8/                {           MOV    DI,AX            }
  143.       $C4/$B6/fromstrng/      {           LES    SI,fromstrng[BP] }
  144.       $8A/$8E/len/            {           MOV    CL,len[BP]       }
  145.       $03/$C9/                {           ADD    CX,CX            }
  146.       $2B/$C0/                {           ADD    AX,AX            }
  147.       $8E/$D8/                {           MOV    DS,AX            }
  148.       $A0/$49/$04/            {           MOV    AL,DS:[0449H]    }
  149.       $22/$C9/                {           AND    CL,CL            }
  150.       $74/$32/                {           JZ     DONE             }
  151.       $2C/$07/                {           SUB    AL,7             }
  152.       $74/$20/                {           JZ     MONO             }
  153.       $BA/$00/$B8/            {           MOV    DX,0B800H        }
  154.       $8E/$DA/                {           MOV    DS,DX            }
  155.       $BA/$DA/$03/            {           MOV    DX,03DAH         }
  156.       $26/$8A/$1C/            { GETCHAR:  MOV    BL,ES:[SI]       }
  157.       $EC/                    { TESTLOW:  IN     AL,DX            }
  158.       $A8/$01/                {           TEST   AL,1             }
  159.       $75/$FB/                {           JNZ    TESTLOW          }
  160.       $FA/                    {           CLI                     }
  161.       $EC/                    { TESTHI:   IN     AL,DX            }
  162.       $A8/$01/                {           TEST   AL,1             }
  163.       $74/$FB/                {           JZ     TESTHI           }
  164.       $88/$1D/                {           MOV    DS:[DI],BL       }
  165.       $47/                    {           INC    DI               }
  166.       $46/                    {           INC    SI               }
  167.       $E2/$EC/                {           LOOP   GETCHAR          }
  168.       $2A/$C0/                {           SUB    AL,AL            }
  169.       $74/$0E/                {           JZ     DONE             }
  170.       $BA/$00/$B0/            { MONO:     MOV    DX,0B000H        }
  171.       $8E/$DA/                {           MOV    DS,DX            }
  172.       $26/$8A/$1C/            { MONO1:    MOV    BL,ES:[SI]       }
  173.       $88/$1D/                {           MOV    DS:[DI],BL       }
  174.       $47/                    {           INC    DI               }
  175.       $46/                    {           INC    SI               }
  176.       $E2/$F7/                {           LOOP   MONO1            }
  177.       $1F);                   { DONE:     POP    DS               }
  178. End;
  179.  
  180. { ===================================================================== }
  181. { DISPLINE - Display a string of characters on the CRT (with the same   }
  182. {            attributes)                                                }
  183. {           The row and column inputs are relative to zero and are      }
  184. {           also relative to the entire screen, not any open window.    }
  185. {                                                                       }
  186. {    Inputs:                                                            }
  187. {       colb      : byte;       Starting column  (0 - 79)               }
  188. {       rowb      : byte;       Starting row     (0 - 24)               }
  189. {       attrib    : byte;       Line attributes                         }
  190. {       fromstrng : string[80]; String to display                       }
  191. { ===================================================================== }
  192. Procedure DispLine(colb,rowb,attrib : byte; VAR fromstrng : winstr);
  193. Begin
  194.    Inline(
  195.       $1E/                    {           PUSH   DS               }
  196.       $8A/$86/rowb/           {           MOV    AL,rowb[BP]      }
  197.       $B3/$50/                {           MOV    BL,80            }
  198.       $F6/$E3/                {           MUL    BL               }
  199.       $2B/$DB/                {           SUB    BX,BX            }
  200.       $8A/$9E/colb/           {           MOV    BL,colb[BP]      }
  201.       $03/$C3/                {           ADD    AX,BX            }
  202.       $03/$C0/                {           ADD    AX,AX            }
  203.       $8B/$F8/                {           MOV    DI,AX            }
  204.       $8A/$BE/attrib/         {           MOV    BH,attrib[BP]    }
  205.       $C4/$B6/fromstrng/      {           LES    SI,fromstrng[BP] }
  206.       $2B/$C9/                {           SUB    CX,CX            }
  207.       $26/$8A/$0C/            {           MOV    CL,ES:[SI]       }
  208.       $2B/$C0/                {           ADD    AX,AX            }
  209.       $8E/$D8/                {           MOV    DS,AX            }
  210.       $A0/$49/$04/            {           MOV    AL,DS:[0449H]    }
  211.       $22/$C9/                {           AND    CL,CL            }
  212.       $74/$34/                {           JZ     DONE             }
  213.       $2C/$07/                {           SUB    AL,7             }
  214.       $74/$21/                {           JZ     MONO             }
  215.       $BA/$00/$B8/            {           MOV    DX,0B800H        }
  216.       $8E/$DA/                {           MOV    DS,DX            }
  217.       $BA/$DA/$03/            {           MOV    DX,03DAH         }
  218.       $46/                    { GETCHAR:  INC    SI               }
  219.       $26/$8A/$1C/            {           MOV    BL,ES:[SI]       }
  220.       $EC/                    { TESTLOW:  IN     AL,DX            }
  221.       $A8/$01/                {           TEST   AL,1             }
  222.       $75/$FB/                {           JNZ    TESTLOW          }
  223.       $FA/                    {           CLI                     }
  224.       $EC/                    { TESTHI:   IN     AL,DX            }
  225.       $A8/$01/                {           TEST   AL,1             }
  226.       $74/$FB/                {           JZ     TESTHI           }
  227.       $89/$1D/                {           MOV    DS:[DI],BX       }
  228.       $47/                    {           INC    DI               }
  229.       $47/                    {           INC    DI               }
  230.       $E2/$EB/                {           LOOP   GETCHAR          }
  231.       $2A/$C0/                {           SUB    AL,AL            }
  232.       $74/$0F/                {           JZ     DONE             }
  233.       $BA/$00/$B0/            { MONO:     MOV    DX,0B000H        }
  234.       $8E/$DA/                {           MOV    DS,DX            }
  235.       $46/                    { MONO1:    INC    SI               }
  236.       $26/$8A/$1C/            {           MOV    BL,ES:[SI]       }
  237.       $89/$1D/                {           MOV    DS:[DI],BX       }
  238.       $47/                    {           INC    DI               }
  239.       $47/                    {           INC    DI               }
  240.       $E2/$F6/                {           LOOP   MONO1            }
  241.       $1F);                   { DONE:     POP    DS               }
  242. End;
  243.  
  244. { ======================================================================== }
  245. { NAME: Normalize                   VERSION: 1.0   DATE: 23 January 1986   }
  246. { AUTHOR: Michael Burton                                                   }
  247. { DESCRIPTION: Normalize coordinates                                       }
  248. { INPUTS: s,e : byte;  start and end coordinates                           }
  249. { OUTPUTS: s,e : byte; coordinates with s < e                              }
  250. {                                                                          }
  251. { ======================================================================== }
  252. Procedure Normalize(VAR s,e: byte);
  253. Var temp: byte;
  254. Begin
  255.    If s > e Then
  256.    Begin
  257.       temp := s;
  258.       s    := e;
  259.       e    := temp;
  260.    End;
  261. End;
  262.  
  263. { ======================================================================== }
  264. { NAME: Bleep                       VERSION: 1.0   DATE: 14 January 1986   }
  265. { AUTHOR: Michael Burton                                                   }
  266. { DESCRIPTION: Produce a bleeping sound times number of times              }
  267. { INPUTS: times : byte;  The number of bleeps required                     }
  268. {                                                                          }
  269. { ======================================================================== }
  270. Procedure Bleep(times : byte);
  271. Var i : byte;
  272. Begin
  273.    For i := 1 To times Do
  274.    Begin
  275.       Nosound;
  276.       Sound(880);
  277.       Delay(60);
  278.       Sound(440);
  279.       Delay(60);
  280.       Nosound;
  281.    End;
  282. End;
  283.  
  284. { ======================================================================== }
  285. { NAME: Set_Cursor                  VERSION: 1.0   DATE: 27 January 1986   }
  286. { AUTHOR:                                                                  }
  287. { DESCRIPTION: Set the cursor size                                         }
  288. { INPUTS: The number of cursor lines to display (0 -7, 0-14)               }
  289. {                                                                          }
  290. { ======================================================================== }
  291. Procedure Set_Cursor (n: byte);
  292. Type
  293.    regrec = Record
  294.               ax,bx,cx,dx,bp,si,di,ds,es,flags: integer
  295.             End;
  296. Var regpak: regrec;
  297. Begin
  298.    regpak.ax:= $100;
  299.    If Not n In [1..8] Then regpak.cx:= $0800
  300.    Else regpak.cx:= ((8-n) shl 8) or 7;
  301.    Intr($10,regpak)
  302. End;
  303.  
  304. { ===================================================================== }
  305. { INITWINDO - Initialize the window variables                           }
  306. {                                                                       }
  307. { Use this routine before using MAKEWINDO, REMOVEWINDO or TITLEWINDO    }
  308. {                                                                       }
  309. {    Inputs:                                                            }
  310. {       txtcolor  : byte;    Starting text color                        }
  311. {       bkgndclr  : byte;    Starting background color                  }
  312. { ===================================================================== }
  313. Procedure InitWindo(txtcolor,bkgndclr : byte);
  314. Begin
  315.    brd[5].ul  := chr(08);   { Set up circle border constants    }
  316.    brd[5].ur  := chr(08);
  317.    brd[5].ll  := chr(08);
  318.    brd[5].lr  := chr(08);
  319.    brd[5].hz  := chr(08);
  320.    brd[5].vtl := chr(08);
  321.    brd[5].vtr := chr(08);
  322.    brd[6].ul  := chr(10);   { Set up diamond border constants   }
  323.    brd[6].ur  := chr(10);
  324.    brd[6].ll  := chr(10);
  325.    brd[6].lr  := chr(10);
  326.    brd[6].hz  := chr(10);
  327.    brd[6].vtl := chr(10);
  328.    brd[6].vtr := chr(10);
  329.    textcolor(txtcolor);
  330.    textbackground(bkgndclr);
  331.    wndo[0].rowb   := 0;       { Initialize non-window zero }
  332.    wndo[0].rowe   := 24;
  333.    wndo[0].colb   := 0;
  334.    wndo[0].cole   := 79;
  335.    wndo[0].attrib := (bkgndclr * 16) + txtcolor;
  336.    wndo[0].bordr  := noneb;
  337.    wndo[0].lastx  := Wherex;
  338.    wndo[0].lasty  := Wherey;
  339.    l_i := 0;
  340. End;
  341.  
  342. { ===================================================================== }
  343. { MAKEWINDO - Create a window                                           }
  344. {                                                                       }
  345. {    Inputs:                                                            }
  346. {         colb     : byte;   Start column     (1 - 80)                  }
  347. {         rowb     : byte;   Start row        (1 - 25)                  }
  348. {         cole     : byte;   End column       (1 - 80)                  }
  349. {         rowe     : byte;   End row          (1 - 25)                  }
  350. {         tcolor   : byte;   Text color       (0 - 15)                  }
  351. {         tback    : byte;   Text background  (0 - 7, > 7 for blinking) }
  352. {         bordr    : boolean;   Border indicator (0 - 9)                }
  353. { ===================================================================== }
  354. Procedure MakeWindo(colb,rowb,cole,rowe,tcolor,tback:byte;bordr:byte);
  355. Var i     : byte;
  356.     wsize : integer;
  357.     pseg  : integer;
  358.     pofs  : integer;
  359. Begin
  360.    rowb := rowb - 1;  { Set coordinates relative to zero }
  361.    rowe := rowe - 1;
  362.    colb := colb - 1;
  363.    cole := cole - 1;
  364.    Normalize(rowb,rowe);
  365.    Normalize(colb,cole);
  366.    wsize := 2 * ((cole - colb + 1) * (rowe - rowb + 1));  { Total size of area }
  367.                                                      { needed to store display }
  368.    If l_i + 1 > maxwin Then
  369.    Begin
  370.       Writeln('Too many Windows!');
  371.       Bleep(4);
  372.    End
  373.    Else
  374.    Begin
  375.       If (wsize / 16 + 1) > memavail Then
  376.       Begin
  377.          Writeln('Not enough Heap space!');
  378.          Bleep(4);
  379.       End
  380.       Else
  381.       Begin
  382.          wndo[l_i].lastx  := Wherex;   { Store old cursor coordinates }
  383.          wndo[l_i].lasty  := Wherey;
  384.          l_i := l_i + 1;        { Go to next window level }
  385.          Textcolor(tcolor);
  386.          Textbackground(tback);
  387.          wndo[l_i].rowb := rowb;   { Store all variables for this window }
  388.          wndo[l_i].rowe := rowe;
  389.          wndo[l_i].colb := colb;
  390.          wndo[l_i].cole := cole;
  391.          wndo[l_i].attrib := (tback * 16) + tcolor;
  392.          wndo[l_i].bordr  := bordr;
  393.          GetMem(wndoptr[l_i],wsize);   { Get enough heap to store old display }
  394.          tmpptr := wndoptr[l_i];
  395.          For i := rowb To rowe Do  { Store old display one row at a time }
  396.          Begin
  397.             GetDisp(colb,i,(cole-colb+1),tmpptr);
  398.             pseg   := Seg(tmpptr^);
  399.             pofs   := Ofs(tmpptr^);
  400.             pofs   := pofs + 2 * (cole - colb + 1);
  401.             tmpptr := Ptr(pseg,pofs);
  402.          End;
  403.          wndostr[0] := chr(cole - colb + 1);  { Set up String length }
  404.          If bordr = noneb Then
  405.          Begin
  406.             FillChar(wndostr[1],cole-colb+1,' '); { Do no border }
  407.             For i := rowb To rowe Do DispLine(colb,i,wndo[l_i].attrib,wndostr);
  408.             Window(colb+1,rowb+1,cole+1,rowe+1); { Create actual Turbo window }
  409.          End
  410.          Else
  411.          Begin
  412.             wndostr[1] := brd[bordr].ul;      { Do border top line }
  413.             wndostr[cole-colb+1] := brd[bordr].ur;
  414.             FillChar(wndostr[2],cole-colb-1,brd[bordr].hz);
  415.             DispLine(colb,rowb,wndo[l_i].attrib,wndostr);
  416.             wndostr[1] := brd[bordr].vtl;     { Do border middle lines }
  417.             wndostr[cole-colb+1] := brd[bordr].vtr;
  418.             FillChar(wndostr[2],cole-colb-1,' ');
  419.             For i := rowb+1 To rowe-1 Do DispLine(colb,i,wndo[l_i].attrib,wndostr);
  420.             wndostr[1] := brd[bordr].ll;      { Do border bottom line }
  421.             wndostr[cole-colb+1] := brd[bordr].lr;
  422.             FillChar(wndostr[2],cole-colb-1,brd[bordr].hz);
  423.             DispLine(colb,rowe,wndo[l_i].attrib,wndostr);
  424.             Window(colb+2,rowb+2,cole,rowe);  { Create actual Turbo window }
  425.          End;
  426.          Gotoxy(1,1);
  427.       End;
  428.    End;
  429. End;
  430.  
  431. { ===================================================================== }
  432. { REMOVEWINDO - Remove the last window created from the screen.  To     }
  433. {               get back to the original screen, there must be as many  }
  434. {               Removewindos as there are Makewindos.                   }
  435. {                                                                       }
  436. {    Inputs:                                                            }
  437. {         None                                                          }
  438. { ===================================================================== }
  439. Procedure RemoveWindo;
  440. Var i    : byte;
  441.     wsize: integer;
  442.     pseg : integer;
  443.     pofs : integer;
  444. Begin
  445.    If l_i = 0 Then
  446.    Begin
  447.       Writeln('No Window To Remove!');
  448.       Bleep(4);
  449.    End
  450.    Else
  451.    Begin
  452.       wsize  := wndo[l_i].cole - wndo[l_i].colb + 1;
  453.       tmpptr := wndoptr[l_i];
  454.       For i  := wndo[l_i].rowb To wndo[l_i].rowe Do   { Put back old display }
  455.       Begin
  456.          DispAll(wndo[l_i].colb,i,wsize,tmpptr);
  457.          pseg   := Seg(tmpptr^);
  458.          pofs   := Ofs(tmpptr^);
  459.          pofs   := pofs + 2 * wsize;
  460.          tmpptr := Ptr(pseg,pofs);
  461.       End;
  462.       wsize := 2 * ((wndo[l_i].cole - wndo[l_i].colb + 1) * (wndo[l_i].rowe - wndo[l_i].rowb + 1));
  463.       FreeMem(wndoptr[l_i],wsize);      { Release heap space }
  464.       l_i := l_i - 1;                   { Go to next lower level }
  465.       Textcolor(wndo[l_i].attrib AND $0F); { Set up all for this level }
  466.       Textbackground(wndo[l_i].attrib DIV 16);
  467.       If wndo[l_i].bordr = noneb Then
  468.          Window(wndo[l_i].colb+1,wndo[l_i].rowb+1,wndo[l_i].cole+1,wndo[l_i].rowe+1)
  469.       Else
  470.          Window(wndo[l_i].colb+2,wndo[l_i].rowb+2,wndo[l_i].cole,wndo[l_i].rowe);
  471.       Gotoxy(wndo[l_i].lastx,wndo[l_i].lasty);
  472.    End;
  473. End;
  474.  
  475. { ===================================================================== }
  476. { TITLEWINDO - Place a centered title in the top border of a window.    }
  477. {                                                                       }
  478. {    Inputs:                                                            }
  479. {         title  : string[80]; The title of the window                  }
  480. { ===================================================================== }
  481. Procedure TitleWindo (title: winstr);
  482. Var i : byte;
  483. Begin
  484.    i := (((wndo[l_i].cole-wndo[l_i].colb) - length(title)) DIV 2 + 1) + wndo[l_i].colb;
  485.    DispLine(i,wndo[l_i].rowb,wndo[l_i].attrib,title);
  486. End;
  487.