DOSSEG .286 .MODEL SMALL .CODE ASSUME cs:@code, ds:@code ;====- DATA -===== ; ;upon entry: Decompressit => loads .CMP image and decompresses it... ; ;* DS:DX = pointer to filename ;* AX != 0, image fitted to AX wide window ;* AX == 0, image decompressed using [Xsize] for width ;* [FileSeg] and [Destination] must both have valid segmnet values ; ;upon EXIT: ; ;* AX=0 if no error, 1 means error ;* Stuff in [FileSeg] is destoryed ;* Decompressed image is in [Destination] segment ;* Palette is at CmpPal ; GLOBAL DeCompressIt:NEAR GLOBAL FileSeg:WORD, Destination:WORD, CmpPal:BYTE FileSeg dw 0 Destination dw 0 CmpPal db 0,767 dup (0) Xsize dw 0 Ysize dw 0 Repeatcode db 0 ScreenWidth dw 320 SegMsg db "FATAL! You forgot to load [FileSeg] and/or [Destination]!!$" FileMsg db "FATAL! File was not openable! (Probably not found.)$" ;========- SubRoutines -======== DeCompressit proc near pusha push ds es cmp cs:[FileSeg],0 je SegError cmp cs:[Destination],0 je SegError push ax mov ax,cs mov es,ax mov ax,3d00h ;open file int 21h jnc Noabort pop ax popa mov ax,1 ;1 means file error ret SegError: mov ax,cs mov ds,ax mov ah,9 mov dx,offset SegMsg int 21h popa mov ax,2 ;2 means segment error ret Noabort: mov bx,ax mov ax,cs:[FileSeg] mov ds,ax mov ax,cs:[Destination] mov es,ax mov cx,0ffffh ;read whole file ( if < 64k ) xor dx,dx mov ah,3fh int 21h mov ah,3eh ;close source file int 21h mov al,ds:[3] ;read 4th byte (offset 3) mov cs:[repeatcode],al mov ax,ds:[4] ;xsize mov cs:[xsize],ax mov ax,ds:[6] mov cs:[ysize],ax pop ax ;from push up top mov cs:[ScreenWidth],ax or ax,ax jne WidthAx ;see if we use AX or Xsize mov ax,cs:[Xsize] ;use Xsize mov cs:[ScreenWidth],ax WidthAX: xor di,di mov si,776 mov cx,cs:[xsize] mov bx,cs:[ysize] mov dl,cs:[repeatcode] push di TryAgain: lodsb cmp al,dl ;is byte a repeatcode? je decodeloop ;yup do decode loop stosb ;nope, it's a pixel, store it jumphere: dec cx ;are we done with this line? jne tryagain ;no, do another mov cx,cs:[xsize] pop di add di,cs:[ScreenWidth] push di dec bx ;are we done with height? jne tryagain ;nope go on jmp alldone ;Yup, exit out DECODELOOP: lodsw ;ah=# of times: al= byte to repeat stosb jmp dcskip Bigloop: stosb dec ah ;are we done with this repeat sequence? je jumphere ;yup, go back up top dcskip: dec cx ;are we done with this line? jne Bigloop mov cx,cs:[xsize] pop di add di,cs:[ScreenWidth] push di dec bx ;are we done with the picture? jne Bigloop ;nope, keep going... jmp alldone ;yup AllDone: pop di ;pull garbage di off stack mov ax,cs mov es,ax ;copy palette to CmpPal mov si,8 mov di,offset CmpPal mov cx,768/2 rep movsw pop es ds popa mov ax,0 ;operation was successful ret DeCompressit endp end