📄 rle.asm
字号:
;**************************************************************************
;*
;* RLE.ASM
;*
;* Copyright (c) 1998-2000 National Semiconductor Corporation.
;* All Rights Reserved.
;*
;* Function:
;* Decompression routines
;*
;* $Revision:: 2 $
;*
;**************************************************************************
.386
INCLUDE DEF.INC ; EQU Definitions
INCLUDE MACROS.INC
INCLUDE PORT80.INC
INCLUDE CPU.INC
_TEXT SEGMENT PUBLIC use16 'CODE'
ASSUME CS:SEGGROUP
;**************************************************************************
;*
;* findNextImage
;*
;* Find next Compressed Image in Physical ROM
;*
;* Entry:
;* EDI = Starting location to search
;* EAX = 'Image Identifier' $IMG or $BMP
;*
;* Exit:
;* EDI = Image Header pointer or same if not found
;* EAX = 00000000 if not found
;*
;* Destroys:
;*
;**************************************************************************
findNextImage PROC NEAR PUBLIC
push ebx
push ecx
push edx
mov edx, edi ; Save off start position
nextPara:
mov ecx, DWORD PTR es:[edi]
cmp eax, ecx
je foundIMG
add edi, 010h ; Next paragraph
;;;spb Need to modify this some for MDOC support. If we're booting
;;; from an MDOC then the ROM address will not be up high.
cmp edi, 001000000h ; 16 MB
ja @F ; If above, end is at 0FFFF0000h
; If below, end is at 0002F0000h
cmp edi, 0002F0000h ; We've reached the end of the CPR block
jne nextPara
jmp goAround
@@:
cmp edi, 0FFFF0000h ; We've reached the end of the CPR block
jne nextPara
goAround:
mov edi, edx ; Restore starting location since we didnt
; find an image.
mov eax, 0 ; 0 the search DWORD
foundIMG:
pop edx
pop ecx
pop ebx
ret
findNextImage ENDP
;**************************************************************************
;*
;* rle_decompress_rom
;*
;* Entry:
;* ES:EDI points to the start of the ROM image string, which has
;* the following format:
;* offset function
;* =========================================================
;* 00h '$IMG' string
;* 04h compression mode 0=byte count, 1=word count...
;* 05h destination address
;* 09h raw file length
;* 0Dh compressed file length
;* 11h checksum of the compressed file
;* 15h start of the compressed data
;*
;* Exit:
;* Destroys:
;*
;**************************************************************************
rle_decompress_rom PROC NEAR PUBLIC
push eax
push ebx
push ecx
push edx
push esi
; First check to see if the checksum is ok
; mov ecx,dword ptr es:[edi+0Dh] ; ecx has number of csum bytes
; mov ebx,edi
; add ebx,15h ; ebx points to start of data
; mov edx,0
;rle_csum_loop:
; movzx eax,byte ptr es:[ebx]
; add edx,eax
; inc ebx
; loop rle_csum_loop
; mov ebx,dword ptr es:[edi+11h] ; ebx is the stored checksum
; cmp ebx,edx
; jne rle_failed_csum
;checksum_was_ok:
; Now lets decompress the data
mov ecx,dword ptr es:[edi+0Dh] ; ecx has number of bytes
mov ebx,dword ptr es:[edi+05h] ; ebx points to the destination
cmp ebx, 0feeeeeeeh ; check for auxrom signature (FFxxxxxxh)
jb GoodAddr
and ebx, 0fffffh
GoodAddr:
mov esi,edi ; esi points to the source
add esi,15h
top_o_loop:
movzx eax,byte ptr es:[esi] ; want eax=000000xx
dec ecx ; dec the byte count
push eax
and al, 0FCh
cmp al, 0DCh
pop eax
je rle_encoded
no_rle: mov byte ptr es:[ebx],al ; not compressed
inc ebx ; inc dest pointer
inc esi ; inc source pointer
cmp ecx,0
jne top_o_loop
jmp rle_done
rle_encoded:
inc esi ; point to data value
cmp al,0DDh
je rle_dd
cmp al,0DCh
je rle_dc
cmp al,0DEh
je rle_de
cmp al,0DFh
je rle_df
; should never get here!
;
; Format DC data
;
rle_dc: movzx eax,byte ptr es:[esi] ; want eax=000000xx
dec ecx ; dec the byte count
jmp no_rle
;
; Format DD data byte_count
;
rle_dd: movzx eax,byte ptr es:[esi] ; want eax=000000xx
inc esi ; point to compressed count
sub ecx,2 ; dec the count for data/count
push ecx
movzx ecx,byte ptr es:[esi] ; want ecx=000000xx, count
inc esi ; inc source pointer
jmp rle_count_loop
;
; Format DE data word_count
;
rle_de: movzx eax,byte ptr es:[esi] ; want eax=000000xx
inc esi ; point to compressed count
sub ecx,3 ; dec count for data/count
push ecx
movzx ecx,word ptr es:[esi] ; want ecx=0000xxxx, count
add esi,2 ; inc source pointer
jmp rle_count_loop
;
; Format DF data dword_count
;
rle_df: movzx eax,byte ptr es:[esi] ; want eax=000000xx
inc esi ; point to compressed count
sub ecx,5 ; dec count for data/count
push ecx
mov ecx,dword ptr es:[esi] ; want ecx=0000xxxx, count
add esi,4 ; inc source pointer
jmp rle_count_loop
;
; compressed repeating data loop
;
rle_count_loop:
rlemovsb:
push edi
mov edi,ebx
cld
db 66h
rep stosb es:[edi]
mov ebx, edi
pop edi
pop ecx
cmp ecx,0
jne top_o_loop
jmp rle_done
rle_failed_csum: ;The checksum is screwed up!
; What the ????
rle_done:
pop esi
pop edx
pop ecx
pop ebx
pop eax
ret
rle_decompress_rom endp
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -