📄 lodbmp.asm
字号:
;/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; this program will patch the bmp to the boot manager, first it
; will do some check on the bmp file, it assume image size is
; 320 * 200, 256 color. if either of the condition is not satisfied
; it will refuse to patch.
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
sseg segment stack
db 128 dup (0)
sseg ends
bmpimg segment para 'bmp'
rawbmp db 0ffffh dup (0)
; it occupied the whole segment
bmpimg ends
dseg segment para public 'global'
bmphdr db 54 dup (0) ; bmp file header
rawpalette db 1024 dup (0)
compbmp db 10*1024 dup (0)
resrvspace dw 0 ; reserved for '|' and last byte
palette db 768 dup (0)
bmpname db 'stuix.bmp',0
debugfile db 'compbmp.bin',0
patchfile db 'stuixldr.exe',0
filehandler dw 0 ; for stuix.bmp only
dseg ends
cseg segment para public 'code'
assume cs:cseg,ds:dseg,es:dseg,ss:sseg
extrn panic:near
start:
mov ax,dseg
mov ds,ax
mov es,ax
; if invalid bmp file, panic may result
call chkbmp
; if passed, we will convert rawpalette
; to the format which the decompressor
; can recognize directly
call covpal
; palette can directly patch to boot manager now
; so we compress the rawbmp
call compress
; compbmp can directly patch to boot manager now
call patchbm
mov ah,4ch
int 21h
;/============================================================================
;
; chkbmp
;
;============================================================================/
chkbmp proc near
push ds
push es
; read the bmp file head in
mov dx,offset bmpname
mov al,0
mov ah,3dh
int 21h
jnc cpnext1
push ax
call panic
cpnext1:
mov [filehandler],ax ; save file handler
mov bx,ax
mov cx,54
mov dx,offset bmphdr
mov ah,3fh
int 21h
jnc cpnext2
push ax
call panic
cpnext2:
; get necessary infomation and check
mov si,offset bmphdr
cmp word ptr [si],4d42h ; 'bm'
je cpnext3
mov ax,7
push ax
call panic
cpnext3:
cmp word ptr 18[si],320 ; width
je cpnext4
mov ax,8
push ax
call panic
cpnext4:
cmp word ptr 22[si],200 ; height
je cpnext5
mov ax,9
push ax
call panic
cpnext5:
cmp word ptr 46[si],0
je cpnext6
mov ax,10
push ax
call panic
cpnext6:
pop es
pop ds
ret
chkbmp endp
;/============================================================================
;
; covpal
;
;============================================================================/
covpal proc near
push ds
push es
push bp
mov bp,sp
sub sp,4
; stack arranges like this
;
; [bp-2] : raw palette pointer, four in group
; [bp-4] : palette image pointer, three in group
; [bp-6] : loop time
; read in 1024 byte raw palette
mov bx,[filehandler]
mov cx,1024
mov dx,offset rawpalette
mov ah,3fh
int 21h
jnc conext1
push ax
call panic
conext1:
; stip the reserved bytes
; ajust the RGB byte order
; shift RGB byte to 6 bit
mov word ptr [bp-2],offset rawpalette
mov word ptr [bp-4],offset palette
mov word ptr [bp-6],0
mov cl,2 ; shift count
cow1loop:
mov ax,[bp-6]
cmp ax,256
jae conext2
mov si,[bp-2]
mov di,[bp-4]
; exchange R and B
cld
lodsb
shr al,cl
mov [di+2],al
lodsb
shr al,cl
mov [di+1],al
lodsb
shr al,cl
stosb
; ajust buf pointer
add word ptr [bp-2],4 ; 4 in group
add word ptr [bp-4],3 ; 3 in group
inc word ptr [bp-6]
jmp cow1loop
conext2:
mov sp,bp
pop bp
pop es
pop ds
ret
covpal endp
;/============================================================================
;
; compress
;
;============================================================================/
compress proc near
push ds
push es
push bp
mov bp,sp
sub sp,10
; stack arranges like this
; [bp-2] : original bmp index
; [bp-4] : compressed buf index
; [bp-6] : compressed bytes counter
; [bp-8] : current byte in bmp buf
; [bp-10] : maximum count for search
mov ax,bmpimg
mov ds,ax
assume ds:bmpimg
mov bx,es:[filehandler] ; read bmp data
mov dx,offset rawbmp
mov cx,0ffffh
mov ah,3fh
int 21h
jnc compnext1
push ax
call panic
compnext1:
; read last byte
mov dx,0ffffh
mov ah,3fh
mov cx,1
int 21h
jnc compnext2
push ax
call panic
compnext2:
; bmp file is not use any more
mov ah,3eh
int 21h
; time to compress
; when a byte is encounted, we will use scasb
; instruction with that byte value to scan the
; whole bitmap until the first unmatch byte is
; encounted, we can easily determine how many
; bytes the same in contingous order. if ther's
; 0, we don't store it in compressed format,
; when we finish compressing, we will add '|'
; at tail of compressed buf to indicate compress
; bmp end here. so the decompressor doesn't
; attempt to go any futher
mov word ptr [bp-2], offset rawbmp
mov word ptr [bp-4],offset compbmp
mov word ptr [bp-6],0
mov word ptr [bp-8],0
mov word ptr [bp-10],0
compw1loop:
mov ax,[bp-6] ; the compressed size can't exceed 10k
cmp ax,10*1024
jb compnext3
mov ax,11
push ax
call panic
compnext4:
jmp compnext6 ; scal the relative jump distance
compnext3:
cmp word ptr [bp-2],0ffffh
jae compnext4
mov si,[bp-2]
cld
lodsb
mov [bp-8],al ; save current byte
inc word ptr [bp-2]
inc word ptr [bp-6]
; get maximum search count
mov cx,0ffffh
sub cx,[bp-2] ; excluding last byte prevent index wrap around
mov [bp-10],cx
mov di,si ; prepare for scasb
push es
mov ax,bmpimg
mov es,ax
assume es:bmpimg
mov al,[bp-8]
repe scasb
; determine how many bytes are the same after this byte
pop es
sub [bp-10],cx
cmp word ptr [bp-10],0
jne compnext5
; no same byte found
push es
mov ax,dseg
mov es,ax
assume es:dseg
mov di,[bp-4]
mov al,[bp-8]
stosb
inc word ptr [bp-4] ; one byte stored
pop es
jmp compw1loop
compnext5:
push es
mov ax,dseg
mov es,ax
assume es:dseg
mov di,[bp-4]
mov al,7eh ; ~
stosb
mov ax,[bp-10] ; [bp-10] is the rest contigous bytes
inc ax ; get total count
stosw
mov al,[bp-8]
stosb ; original byte
; now we have compress [bp-10] + 1 bytes to 4 bytes
mov ax,[bp-10]
add word ptr [bp-4],4
add [bp-2],ax
add [bp-6],3
pop es
jmp compw1loop
compnext6:
; deel with the last byte, add '|' to the tail
mov ax,dseg
mov es,ax
assume es:dseg
mov si,0ffffh
lodsb
mov di,[bp-4]
stosb
mov al,7ch ; '|'
stosb
mov sp,bp
pop bp
pop es
pop ds
ret
compress endp
;/============================================================================
;
; patchbm
;
;============================================================================/
patchbm proc near
push ds
push es
; must skip the DOS exe header
; also output debug file contain
; the bmp compressed image
mov dx,offset debugfile
mov cx,0
mov ah,3ch
int 21h
jnc pbmnext1
push ax
call panic
pbmnext1:
mov bx,ax
mov dx,offset compbmp
mov cx,10*1024+2
mov ah,40h
int 21h
jnc pbmnext2
push ax
call panic
pbmnext2:
mov ah,3eh
int 21h
; now patch to stuixldr.exe
mov dx,offset patchfile
mov al,2
mov ah,3dh
int 21h
jnc pbmnext3
push ax
call panic
pbmnext3:
mov bx,ax
; skip head
xor cx,cx
mov dx,512
mov al,0
mov ah,42h
int 21h
jnc pbmnext4
push ax
call panic
pbmnext4:
mov cx,10*1024+2+768
mov dx,offset compbmp
mov ah,40h
int 21h
jnc pbmnext5
push ax
call panic
pbmnext5:
pop es
pop ds
ret
patchbm endp
cseg ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -