home *** CD-ROM | disk | FTP | other *** search
/ World of Graphics / WOGRAPH.BIN / 568.UNCRUNCH.ASM < prev    next >
Assembly Source File  |  1993-03-21  |  8KB  |  199 lines

  1. ;THEDRAW IMAGE UNCRUNCHING ROUTINE
  2. ;-----------------------------------------------------------------------------
  3. ;Compatible with MASM (Microsoft) and TASM v1.0 (Borland).  Minor format
  4. ;changes may be required for other assemblers.
  5. ;-----------------------------------------------------------------------------
  6. ;
  7. ;This is the routine for displaying crunched TheDraw image files.  The
  8. ;crunched data format is a simple custom protocol for reproducing any image.
  9. ;The control codes below decimal 32 are reserved for this function.
  10. ;Characters 32 and above are written directly to the destination address.
  11. ;
  12. ;The following shows the format of a control code sequence.  Please note that
  13. ;not all functions use the optional bytes <x> or <y>.
  14. ;
  15. ;Data Structure:  <current byte>[<x>[<y>]]
  16. ;
  17. ;   0..15 = New Foreground Color
  18. ;  16..23 = New Background Color
  19. ;      24 = Go down to next line, return to same horizontal position as when
  20. ;           routine was started (akin to a c/r).
  21. ;      25 = Displays <x> number of spaces.
  22. ;      26 = Displays <x> number of <y>.  Also used to display ANY characters
  23. ;           below #32.  This function is the only way to do this although it
  24. ;           uses three bytes.  Otherwise the code would be interpreted as
  25. ;           another command.
  26. ;      27 = Toggles on/off the foreground attribute blink flag.
  27. ;  28..31 = reserved
  28. ;
  29. ;----------------------------------------------------------------------------
  30. ;
  31. ;To use the routine, call the uncrunch procedure with the DS:SI register pair
  32. ;pointing to the TheDraw output listing, the ES:DI register pair pointing to
  33. ;the destination display address, and the length of the crunched image data
  34. ;in the CX register.  All modified registers are restored upon exiting.
  35. ;
  36. ;Assume an output file of a 40 character by 10 line block.  The label
  37. ;'IMAGEDATA' has been added for referencing purposes. ie:
  38. ;
  39. ;
  40. ;     ;TheDraw Assembler Crunched Screen Image
  41. ;     IMAGEDATA_WIDTH EQU 40
  42. ;     IMAGEDATA_DEPTH EQU 10
  43. ;     IMAGEDATA_LENGTH EQU 467
  44. ;     IMAGEDATA LABEL BYTE
  45. ;                DB      ...list of image bytes here...
  46. ;
  47. ;
  48. ;The following assembly language code could then be used to display the
  49. ;40x10 block on the screen with:
  50. ;
  51. ;                MOV     SI,offset IMAGEDATA
  52. ;                MOV     AX,0B800h
  53. ;                MOV     ES,AX
  54. ;                MOV     DI,34*2 + 5*160-162
  55. ;                MOV     CX,IMAGEDATA_LENGTH
  56. ;                CALL    UNCRUNCH
  57. ;
  58. ;The data segment (DS register) is assumed to point at the segment ImageData
  59. ;resides in.   The ES:DI register pair points at position (34,5) on the color
  60. ;graphics adapter screen, calculated as an offset from the start of the screen.
  61. ;Monochrome card users, replace the 0B800h with 0B000h.
  62. ;
  63. ;The original horizontal starting offset is remembered by the uncrunch routine.
  64. ;The offset is restored upon moving down to the next line.  This permits a
  65. ;block to be displayed correctly anywhere on the screen.  ie:
  66. ;
  67. ;              ┌─ horizontal starting offset
  68. ;              V
  69. ;  +-------------------------------------------------+
  70. ;  |                                                 |
  71. ;  |                                                 | <- Assume this
  72. ;  |                                                 |    is the video
  73. ;  |           ┌─────────────────────┐               |    display.
  74. ;  |           │█████████████████████│               |
  75. ;  |           │█████████████████████│               |
  76. ;  |           │██ ImageData block ██│               |
  77. ;  |           │█████████████████████│               |
  78. ;  |           │█████████████████████│               |
  79. ;  |           │█████████████████████│               |
  80. ;  |           └─────────────────────┘               |
  81. ;  |                                                 |
  82. ;  |                                                 |
  83. ;  |                                                 |
  84. ;  +-------------------------------------------------+
  85. ;
  86. ;
  87. ;To display the block in the lower-right corner, change the DI assignment to:
  88. ;
  89. ;                MOV     DI,40*2 + 15*160-162
  90. ;
  91. ;The block is 40 characters wide by 10 lines deep.  To display on a 80 by 25
  92. ;screen, we must display the block at coordinates (40,15).  To display in
  93. ;the upper-left screen corner use:
  94. ;
  95. ;                MOV     SI,offset IMAGEDATA
  96. ;                MOV     AX,0B800H
  97. ;                MOV     ES,AX
  98. ;                MOV     DI,1*2 + 1*160-162       ;coordinates 1,1
  99. ;                MOV     CX,IMAGEDATA_LENGTH
  100. ;                CALL    UNCRUNCH
  101. ;
  102. ;Notice in both cases only the offset address changed.  Note the latter case
  103. ;is also used for displaying a full screen image (which in general are
  104. ;always displayed at coordinate 1,1).
  105. ;
  106. ;----------------------------------------------------------------------------
  107. ;
  108. ;That's it!  The routine was designed for easy use and understanding; however,
  109. ;for some people the best way is to experiment.  Create a program using the
  110. ;above examples, perhaps with a 40x10 block (or any size).  Good luck!
  111. ;
  112.  
  113. UNCRUNCH PROC NEAR
  114. ;
  115. ;Parameters Required:
  116. ;  DS:SI  Crunched image source pointer.
  117. ;  ES:DI  Display address pointer.
  118. ;  CX     Length of crunched image source data.
  119. ;
  120.        PUSH    SI                      ;Save registers.
  121.        PUSH    DI
  122.        PUSH    AX
  123.        PUSH    BX
  124.        PUSH    CX
  125.        PUSH    DX
  126.        JCXZ    Done
  127.  
  128.        MOV     DX,DI                   ;Save X coordinate for later.
  129.        XOR     AX,AX                   ;Set Current attributes.
  130.        CLD
  131.  
  132. LOOPA: LODSB                           ;Get next character.
  133.        CMP     AL,32                   ;If a control character, jump.
  134.        JC      ForeGround
  135.        STOSW                           ;Save letter on screen.
  136. Next:  LOOP    LOOPA
  137.        JMP     Short Done
  138.  
  139. ForeGround:
  140.        CMP     AL,16                   ;If less than 16, then change the
  141.        JNC     BackGround              ;foreground color.  Otherwise jump.
  142.        AND     AH,0F0H                 ;Strip off old foreground.
  143.        OR      AH,AL
  144.        JMP     Next
  145.  
  146. BackGround:
  147.        CMP     AL,24                   ;If less than 24, then change the
  148.        JZ      NextLine                ;background color.  If exactly 24,
  149.        JNC     FlashBitToggle          ;then jump down to next line.
  150.        SUB     AL,16                   ;Otherwise jump to multiple output
  151.        ADD     AL,AL                   ;routines.
  152.        ADD     AL,AL
  153.        ADD     AL,AL
  154.        ADD     AL,AL
  155.        AND     AH,8FH                  ;Strip off old background.
  156.        OR      AH,AL
  157.        JMP     Next
  158.  
  159. NextLine:
  160.        ADD     DX,160                  ;If equal to 24,
  161.        MOV     DI,DX                   ;then jump down to
  162.        JMP     Next                    ;the next line.
  163.  
  164. FlashBitToggle:
  165.        CMP     AL,27                   ;Does user want to toggle the blink
  166.        JC      MultiOutput             ;attribute?
  167.        JNZ     Next
  168.        XOR     AH,128                  ;Done.
  169.        JMP     Next
  170.  
  171. MultiOutput:
  172.        CMP     AL,25                   ;Set Z flag if multi-space output.
  173.        MOV     BX,CX                   ;Save main counter.
  174.        LODSB                           ;Get count of number of times
  175.        MOV     CL,AL                   ;to display character.
  176.        MOV     AL,32
  177.        JZ      StartOutput             ;Jump here if displaying spaces.
  178.        LODSB                           ;Otherwise get character to use.
  179.        DEC     BX                      ;Adjust main counter.
  180.  
  181. StartOutput:
  182.        XOR     CH,CH
  183.        INC     CX
  184.        REP STOSW
  185.        MOV     CX,BX
  186.        DEC     CX                      ;Adjust main counter.
  187.        LOOPNZ  LOOPA                   ;Loop if anything else to do...
  188.  
  189. Done:  POP     DX                      ;Restore registers.
  190.        POP     CX
  191.        POP     BX
  192.        POP     AX
  193.        POP     DI
  194.        POP     SI
  195.        RET
  196.  
  197. UNCRUNCH ENDP
  198.  
  199.