home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 94.img / THEDRAW.ZIP / UNCRUNCH.PAS < prev   
Pascal/Delphi Source File  |  1989-11-01  |  9KB  |  165 lines

  1. procedure UNCRUNCH (var Addr1,Addr2; BlkLen:Integer);
  2.  
  3. (*
  4.  This is the flash display routine used to display crunched TheDraw image
  5.  files.  It uses a custom protocol for reproducing an image with any
  6.  possible color combinations.  The control codes below #32 are reserved
  7.  for this function.  The following data structure shows the format of a
  8.  sequence.  Not all operations use the optional bytes <x> or <y>.
  9.  
  10.  Data Structure:  <current byte>[<x>[<y>]]
  11.  
  12.     0..15 = New Foreground Color
  13.    16..23 = New Background Color
  14.        24 = Go down to next line, return to same horizontal position as when
  15.             routine was started (akin to a c/r).
  16.        25 = Displays <x> number of spaces.
  17.        26 = Displays <x> number of <y>.  Also used to display ANY characters
  18.             below #32.  This function is the only way to do this although it
  19.             uses three bytes.  Otherwise the character would be interpreted
  20.             as another command code.
  21.        27 = Toggles on/off the foreground attribute blink flag.
  22.  
  23.  
  24.  ----------------------------------------------------------------------------
  25.  
  26.  To use this routine, call the procedure with the ImageData as the
  27.  first parameter, the display address as the second parameter, and the
  28.  length of the ImageData as the third parameter.
  29.  
  30.  Assume we have an ImageData file of a 40 character by 10 line block.  Also
  31.  the following defintions.  ie:
  32.  
  33.    { TheDraw Pascal Crunched Screen Image }
  34.    const                                           <- This CONST area is
  35.      IMAGEDATA_WIDTH = 40;                            generated by TheDraw
  36.      IMAGEDATA_DEPTH = 10;
  37.      IMAGEDATA_LENGTH = 467;
  38.      IMAGEDATA : array [1..467] of Char =
  39.        (...list of image bytes here...);
  40.  
  41.    type ScreenType = array [0..3999] of Byte;
  42.    var ScreenAddr : ScreenType absolute $B800:$0000;
  43.  
  44.    begin
  45.      UnCrunch (IMAGEDATA,ScreenAddr[ (34*2) + (5*160) -162],IMAGEDATA_LENGTH);
  46.    end;
  47.  
  48.  
  49.  SCREENADDR is a variable mapped to the same location as the physical video
  50.  addresses (via Turbo's absolute addressing).   The rather messy array offset
  51.  tells UnCrunch where to start displaying the ImageData block.  The 34*2
  52.  indicates the horizontal position number 34 with the 5*160 indicating line
  53.  number 5.  This is similar to a Turbo GOTOXY (34,5) statement.
  54.  
  55.  UnCrunch remembers the original horizontal (X) starting position when it
  56.  goes down to the next line.  This permits a block to be displayed correctly
  57.  anywhere on the screen.   ie:
  58.  
  59.    +-------------------------------------------------+
  60.    |                                                 |
  61.    |                                                 | <- Pretend this
  62.    |                                                 |    is the video
  63.    |           ┌─────────────────────┐               |    display.
  64.    |           │█████████████████████│               |
  65.    |           │█████████████████████│               |
  66.    |           │██ ImageData block ██│               |
  67.    |           │█████████████████████│               |
  68.    |           │█████████████████████│               |
  69.    |           │█████████████████████│               |
  70.    |           └─────────────────────┘               |
  71.    |                                                 |
  72.    |                                                 |
  73.    |                                                 |
  74.    +-------------------------------------------------+
  75.  
  76.  
  77.  The ImageData block could just as well have been display in the upper-left
  78.  corner of the screen with:
  79.     UNCRUNCH (IMAGEDATA,ScreenAddr[ (1*2) + (1*160) -162],IMAGEDATA_LENGTH);
  80.  
  81.  Notice the array address changed to the equivilant of GOTOXY (1,1);
  82.  
  83.  To display the block in the lower-right corner you would use:
  84.     UNCRUNCH (IMAGEDATA,ScreenAddr[ (40*2) + (15*160) -162],IMAGEDATA_LENGTH);
  85.  
  86.  In this example, the block is 40 characters wide by 10 lines deep.  Thus,
  87.  to display such a large block, we must display the block at GOTOXY (40,15);
  88.  
  89.  
  90.  Obviously the documentation here attempts to describe the procedure by use
  91.  of examples.  This was felt to be the clearest way of explaining it.  The
  92.  routine was designed to make using it easy; however, for some people the
  93.  best way to learn it is to experiment.  Try creating a program using the
  94.  above example information.  Use TheDraw to make a 40 by 10 block (or any
  95.  size) to experiment with.  Good luck.
  96. *)
  97.  
  98. begin
  99.   inline (
  100.     $1E/               {       PUSH    DS}
  101.     $C5/$B6/Addr1/     {       LDS     SI,[BP+Addr1]  ;Source Address}
  102.     $C4/$BE/Addr2/     {       LES     DI,[BP+Addr2]  ;Destination Addr}
  103.     $8B/$8E/BlkLen/    {       MOV     CX,[BP+BlkLen] ;Length of block}
  104.     $8B/$D7/           {       MOV     DX,DI          ;Save X coordinate for later.}
  105.     $33/$C0/           {       XOR     AX,AX          ;Set Current attributes.}
  106.     $FC/               {       CLD                    ;Clear direction flag.}
  107.     $AC/               {LOOPA: LODSB                  ;Get next character.}
  108.     $3C/$1B/           {       CMP     AL,27          ;Does user want to toggle the blink}
  109.     $75/$05/           {       JNZ     ForeGround     ;attibute?}
  110.     $80/$F4/$80/       {       XOR     AH,128         ;Done.}
  111.     $EB/$4D/           {       JMP     Short Next}
  112.                        {ForeGround:}
  113.     $3C/$10/           {       CMP     AL,16          ;If less than 16, then change the}
  114.     $73/$07/           {       JNC     BackGround     ;foreground color.  Otherwise jump.}
  115.     $80/$E4/$70/       {       AND     AH,70H         ;Strip off old foreground.}
  116.     $0A/$E0/           {       OR      AH,AL}
  117.     $EB/$42/           {       JMP     Short Next}
  118.                        {BackGround:}
  119.     $3C/$18/           {       CMP     AL,24          ;If less than 24, then change the}
  120.     $74/$13/           {       JZ      NextLine       ;background color.  If exactly 24,}
  121.     $73/$19/           {       JNC     MultiOutput    ;then jump down to next line.}
  122.     $2C/$10/           {       SUB     AL,16          ;Otherwise jump to multiple output}
  123.     $02/$C0/           {       ADD     AL,AL          ;routines.}
  124.     $02/$C0/           {       ADD     AL,AL}
  125.     $02/$C0/           {       ADD     AL,AL}
  126.     $02/$C0/           {       ADD     AL,AL}
  127.     $80/$E4/$8F/       {       AND     AH,8FH         ;Strip off old background.}
  128.     $0A/$E0/           {       OR      AH,AL}
  129.     $EB/$2B/           {       JMP     Short Next}
  130.                        {NextLine:}
  131.     $81/$C2/$A0/$00/   {       ADD     DX,160         ;If equal to 24,}
  132.     $8B/$FA/           {       MOV     DI,DX          ;then jump down to}
  133.     $EB/$23/           {       JMP     Short Next     ;the next line.}
  134.                        {MultiOutput:}
  135.     $3C/$19/           {       CMP     AL,25          ;If equal to 25,}
  136.     $75/$0B/           {       JNZ     NotMultiSpaces ;then using the}
  137.     $AC/               {       LODSB                  ;following code as}
  138.     $51/               {       PUSH    CX             ;a count, output}
  139.     $32/$ED/           {       XOR     CH,CH          ;said number of}
  140.     $8A/$C8/           {       MOV     CL,AL          ;spaces.}
  141.     $B0/$20/           {       MOV     AL,32}
  142.     $EB/$0D/$90/       {       JMP     StartOutput    ;Use below loop.}
  143.                        {NotMultiSpaces:}
  144.     $3C/$1A/           {       CMP     AL,26          ;If equal to 26, then using}
  145.     $75/$0F/           {       JNZ     NormalLetter   ;the following two codes, display}
  146.     $AC/               {       LODSB                  ;<x> number of <y> characters.}
  147.     $49/               {       DEC     CX             ;Adjust main counter.}
  148.     $51/               {       PUSH    CX             ;Display as many of}
  149.     $32/$ED/           {       XOR     CH,CH          ;whatever the user}
  150.     $8A/$C8/           {       MOV     CL,AL          ;wants.}
  151.     $AC/               {       LODSB                  ;Get character.}
  152.                        {StartOutput:}
  153.     $E3/$03/           {       JCXZ    Stop           ;Abort if already at zilch.}
  154.     $AB/               {LOOPB: STOSW}
  155.     $E2/$FD/           {       LOOP    LOOPB}
  156.     $59/               {Stop:  POP     CX}
  157.     $49/               {       DEC     CX             ;Adjust main counter.}
  158.                        {NormalLetter:}
  159.     $AB/               {       STOSW                  ;Save screen letter.}
  160.     $E3/$02/           {Next:  JCXZ    Done           ;Get next, unless CX}
  161.     $E2/$A5/           {       LOOP    LOOPA          ;has already gone to zero.}
  162.     $1F);              {Done:  POP     DS}
  163. end; {UNCRUNCH}
  164.  
  165.