home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Jason Aller Floppy Collection
/
93.img
/
TDRAW33R.ZIP
/
UNCRUNCH.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-11-01
|
8KB
|
197 lines
;THEDRAW IMAGE UNCRUNCHING ROUTINE
;-----------------------------------------------------------------------------
;Compatible with MASM (Microsoft) and TASM v1.0 (Borland). Minor format
;changes may be required for other assemblers.
;-----------------------------------------------------------------------------
;
;This is the flash display routine used to display crunched TheDraw image
;files. It uses a custom protocol for reproducing an image with any
;possible color combinations. The control codes below 32 are reserved
;for this function. The following data structure shows the format of a
;sequence. Not all operations use the optional bytes <x> or <y>..
;
;Data Structure: <current byte>[<x>[<y>]]
;
; 0..15 = New Foreground Color
; 16..23 = New Background Color
; 24 = Go down to next line, return to same horizontal position as when
; routine was started (akin to a c/r).
; 25 = Displays <x> number of spaces.
; 26 = Displays <x> number of <y>. Also used to display ANY characters
; below #32. This function is the only way to do this although it
; uses three bytes. Otherwise the code would be interpreted as
; another command.
; 27 = Toggles on/off the foreground attribute blink flag.
;
;----------------------------------------------------------------------------
;
;To use this uncrunch routine, call the procedure with the DS:SI register
;pair pointing to the TheDraw output listing, the ES:DI register pair
;pointing to the destination display address, and the length of the image
;data in the CX register. All modified registers are restored upon exiting.
;
;Assume an output file of a 40 character by 10 line block. The label
;'IMAGEDATA' has been added for referencing purposes. ie:
;
;
; ;TheDraw Assembler Crunched Screen Image
; IMAGEDATA_WIDTH EQU 40
; IMAGEDATA_DEPTH EQU 10
; IMAGEDATA_LENGTH EQU 467
; IMAGEDATA LABEL BYTE
; DB ...list of image bytes here...
;
;
;The following assembly language code could then be used to display the
;40x10 block on the screen with:
;
; MOV SI,offset IMAGEDATA
; MOV AX,0B800h
; MOV ES,AX
; MOV DI,34*2 + 5*160-162
; MOV CX,IMAGEDATA_LENGTH
; CALL UNCRUNCH
;
;The data segment (DS register) is assumed to point at the segment ImageData
;resides in. The ES:DI register pair points at position (34,5) on the color
;graphics adapter screen, calculated as an offset from the start of the screen.
;Monochrome card users, replace the 0B800h with 0B000h.
;
;UnCrunch remembers the original horizontal (X) starting position when it
;goes down to the next line. This permits a block to be displayed correctly
;anywhere on the screen. ie:
;
; +-------------------------------------------------+
; | |
; | | <- Assume this
; | | is the video
; | ┌─────────────────────┐ | display.
; | │█████████████████████│ |
; | │█████████████████████│ |
; | │██ ImageData block ██│ |
; | │█████████████████████│ |
; | │█████████████████████│ |
; | │█████████████████████│ |
; | └─────────────────────┘ |
; | |
; | |
; | |
; +-------------------------------------------------+
;
;
;The ImageData block could just as easily been displayed in the upper-left
;corner of the screen with:
; MOV SI,offset IMAGEDATA
; MOV AX,0B800H
; MOV ES,AX
; MOV DI,1*2 + 1*160-162
; MOV CX,IMAGEDATA_LENGTH
; CALL UNCRUNCH
;
;Notice the offset address changed to the coordinates (1,1). To display
;the block in the lower-right corner you would change the DI assignment to:
;
; MOV DI,40*2 + 15*160-162
;
;The block is 40 characters wide by 10 lines deep. Therefore to display
;such a large block, we must display the block at coordinates (40,15);
;
;
;Obviously the documentation here attempts to describe the procedure by use
;of examples. This was felt to be the clearest way of explaining it. The
;routine was designed to make using it easy; however, for some people the
;best way to learn it is to experiment. Try creating a program using the
;above example information. Use TheDraw to make a 40 by 10 block (or any
;size) to experiment with. Good luck.
;
UNCRUNCH PROC NEAR
;
;Parameters Required:
; DS:SI Crunched image source pointer.
; ES:DI Display address pointer.
; CX Length of ImageData source data.
;
PUSH SI ;Save registers.
PUSH DI
PUSH AX
PUSH CX
PUSH DX
MOV DX,DI ;Save X coordinate for later.
XOR AX,AX ;Set Current attributes.
CLD
LOOPA: LODSB ;Get next character.
CMP AL,27 ;Does user want to toggle the blink
JNZ ForeGround ;attibute?
XOR AH,128 ;Done.
JMP Short Next
ForeGround:
CMP AL,16 ;If less than 16, then change the
JNC BackGround ;foreground color. Otherwise jump.
AND AH,0F0H ;Strip off old foreground.
OR AH,AL
JMP Short Next
BackGround:
CMP AL,24 ;If less than 24, then change the
JZ NextLine ;background color. If exactly 24,
JNC MultiOutput ;then jump down to next line.
SUB AL,16 ;Otherwise jump to multiple output
ADD AL,AL ;routines.
ADD AL,AL
ADD AL,AL
ADD AL,AL
AND AH,8FH ;Strip off old background.
OR AH,AL
JMP Short Next
NextLine:
ADD DX,160 ;If equal to 24,
MOV DI,DX ;then jump down to
JMP Short Next ;the next line.
MultiOutput:
CMP AL,25 ;If equal to 25,
JNZ NotMultiSpaces ;then use the
LODSB ;following code as
PUSH CX ;a count and output
XOR CH,CH ;said number of
MOV CL,AL ;spaces.
MOV AL,32
JMP Short StartOutput ;Use below loop.
NotMultiSpaces:
CMP AL,26 ;If equal to 26, then using
JNZ NormalLetter ;the following two codes, display
LODSB ;<x> number of <y> characters.
DEC CX ;Adjust main counter.
PUSH CX ;Display as many of
XOR CH,CH ;whatever the user
MOV CL,AL ;wants.
LODSB ;Get character.
StartOutput:
JCXZ Stop ;Abort if already at zilch.
LOOPB: STOSW
LOOP LOOPB
Stop: POP CX
DEC CX ;Adjust main counter.
NormalLetter:
STOSW ;Save screen letter.
Next: JCXZ Done ;Get next, unless CX
LOOP LOOPA ;has already gone to zero.
Done: POP DX ;Restore registers.
POP CX
POP AX
POP DI
POP SI
RET
UNCRUNCH ENDP