home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FreeWare Collection 2
/
FreeSoftwareCollection2pd199x-jp.img
/
fbasic
/
pmgf
/
pmgf12s.com
/
SPREAD.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-05-23
|
9KB
|
352 lines
.386p
PUBLIC GLOAD
param struc
datlen dd ? ;総データ長
headlen dd ? ;ヘッダ長
;
dd ? ;使用禁止
nrefer dd ? ;変更するライン
lngth dd ? ;1ラインのバイト数(展開した時)
data dd ? ;圧縮データ格納アドレス
refer dd ? ;参照データ格納アドレス
outd dd ? ;出力データ格納アドレス
bml dd ? ;ビットマップ長
param ends
nlength EQU 1024 ;1ラインの最大長(参照データ1ライン分のデータ長も兼ねる)
worklng EQU 4*2
dbf EQU 0 ;デバッグモードフラグ(0:Debug Mode Off 1:On)
;
; MACRO
debug macro val
pushf
push eax
push edx
mov eax,val
and eax,4fh
mov edx,04ech ;Volume Meter
out dx,al
pop edx
pop eax
popf
endm
debugs macro val,val2
pushf
push eax
push edx
mov eax,val
shl eax,val2
and eax,4fh
mov edx,04ech ;Volume Meter
out dx,al
pop edx
pop eax
popf
endm
debugl macro val,val2
pushf
push eax
push edx
mov eax,val
and eax,4fh
mov edx,04ech ;Volume Meter
out dx,al
mov eax,val2
out dx,al
pop edx
pop eax
popf
endm
djmp macro val,val2
if dbf
cmp dword PTR dflag[ebp],val
je val2
endif
endm
CODE segment dword public ER use32 'CODE'
assume cs:CODE, ds:CODE
; Graphics Data Spread Routine for F-BASIC386
EXEC proc near
GLOAD:
sub esp,worklng ;ワークエリアを確保
mov ebp,esp
cld ;自動増加を指定
mov dword PTR headlen[ebp],1 ;ヘッダ長初期化
mov esi,data[ebp] ;圧縮データ格納アドレスをセット
mov edi,outd[ebp] ;展開データ 〃
;
lodsb ;1バイト読込
test al,80h ;msbチェック
jz NOTCMP ;非圧縮データ展開へ
mov bl,al ;転送
;
and bl,38h ;圧縮モードを得る
shr bl,3
; 圧縮モード分岐 ;alにラインヘッダが格納されている
cmp bl,0
jz LINES ;0なら1次元モードへ
cmp bl,1
jz CMPAGS ;1なら完全一致モードへ
mov dword PTR headlen[ebp],2 ;ヘッダ長変更
cmp bl,2
jz HIGHS ;2なら高圧縮モードへ
jmp LOWS ;それ以外なら低圧縮モードへ
;
BASE dd LP1 ;1次元圧縮モードの各パターン展開のジャンプテーブル
dd LP2
dd LP3
dd LP4
dd LP5
;
align 4
LINES: ;1次元
;
mov dl,al ;ラインヘッダ保存
and eax,7 ;総データ数を求める
test dl,40h ;2バイトチェック
jnz LIH1 ;1バイトヘッダモードフラグが立っていたら分岐
LIH2: mov ah,al ;2バイトヘッダモードなので1バイト目を256倍する
mov dword PTR headlen[ebp],2 ;ヘッダ長変更
lodsb ;2バイト目をロード
LIH1: mov edx,eax ;総データ数セット(edx)
mov datlen[ebp],eax ;データ数保存
;
align 4
L_LINS: cmp edx,0 ;残りデータは有るか
jng CALRET ;edxが0か0以下なら展開終了
lodsb ;1バイト目を読み込む
dec edx ;1バイト読み込んだのでカウンタをデクリメント
mov bl,al ;データをblに転送
mov cl,al ;clにも転送
test cl,10h ;1バイトヘッダモードフラグをチェック
jz L_LH2 ;0なら2バイトヘッダモードへ
and ecx,0fh ;パターン数セット
jmp L_LH1 ;分岐
align 4
L_LH2: mov ch,al ;1バイト目を転送
lodsb ;2バイト目
dec edx ;総データカウンタデクリメント
mov cl,al ;パターン数セット
and ecx,0fffh
L_LH1: shr bl,5 ;パターンナンバーを得る
and ebx,7
dec ebx ;オフセットを得る
jmp BASE[ebx*4] ;パターン毎の展開ルーチンへ分岐
;
align 4
LP1:
lodsb ;パターンを得る
dec edx ;総データカウンタデクリメント
rep stosb ;データ生成
jmp L_LINS ;ループ
;
align 4
LP2:
lodsw ;パターンを得る
sub edx,2 ;総データカウンタデクリメント
rep stosw ;データ生成
jmp L_LINS ;ループ
;
align 4
LP3:
lodsd ;パターンを得る
dec esi ;ポインタ補正
and eax,0ffffffh ;ブロックデータ生成
sub edx,3 ;総データカウンタデクリメント
align 4
L_LP3: stosd ;データ生成
dec edi ;ポインタ補正
loop L_LP3 ;データ生成ループアウトチェック
jmp L_LINS ;ループ
;
align 4
LP4:
lodsd ;パターンを得る
sub edx,4 ;総データカウンタデクリメント
rep stosd ;データ生成
jmp L_LINS ;ループ
;
align 4
LP5:
lodsb ;パターンを得る
mov bl,al
lodsd
sub edx,5 ;総データカウンタデクリメント
align 4
L_LP5: mov [edi],bl ;データ1バイト目生成
inc edi ;ポインタ補正
stosd ;残りデータ生成
loop L_LP5 ;データ生成ループアウトチェック
jmp L_LINS ;ループ
;
align 4
CMPAGS:
mov dword PTR datlen[ebp],0 ;総データ数保存
call DATSTO ;参照ラインのデータを転送する
jmp CALRET ;展開終了
;
align 4
DATSTO: ;alの下位3ビットに参照ラインをセットしてあること
and eax,7 ;参照ライン計算
mov esi,nlength ;1ラインの領域長を得る
xor edx,edx ;mulの前処理
mul esi ;mul
add eax,refer[ebp] ;参照アドレス計算
mov esi,eax ; 〃 セット
mov ecx,lngth[ebp] ;1ラインのバイト数を得る
DTSTin: mov edx,ecx ;4バイト転送で高速転送するために
and edx,3 ;4で割った余りのデータ数を先に転送
mov eax,[esi] ;しておく
mov [edi],eax ;取り合えず4バイト転送し、そのあとに
add edi,edx ;ポインタを補正する
add esi,edx
shr ecx,2 ;カウンタを4で割る
rep movsd ;転送
ret ;呼出元にリターン
;
align 4
HIGHS:
push esi ;デ-タ格納アドレスを保存
call DATSTO ;参照ラインを転送
pop esi ;復帰
;
xor eax,eax ;eaxクリア
lodsb ;格納データバイト数を読み込む
mov bl,al ;blに転送
and al,7fh ;格納データバイト数を得る
test bl,80h ;格納バイトヘッダ1バイトモードフラグをチェック
jnz HI1GHS ; 〃 2 〃 をスキップ
mov ah,al ;第1バイトを転送
mov dword PTR headlen[ebp],3 ;ヘッダ長変更
lodsb ;第2バイトを読み込む
HI1GHS: mov ecx,eax ;総データバイト数をセットする
mov datlen[ebp],eax ;データ数保存
;
mov edi,outd[ebp] ;データ出力アドレスセット
;
align 4
L_HIGS:
xor eax,eax ;eaxをクリア
lodsb ;ブロックヘッダを読み込む
mov dl,al ;dlにヘッダを転送
test al,80h ;データオフセット1バイトモードフラグをチェック
jz HIGS2 ;0ならば2バイトモードへ
;
and eax,3fh ;データオフセットを得る
dec eax ;オフセット補正
add edi,eax ;データストアポインタに足す
test dl,40h ;データ2バイトフラグチェック
jnz HIGS2P ;1ならデータ2バイトモードへ
movsb ;データ転送
mov edx,2 ;格納データバイト数から引く値をセットする
jmp HIGEND ;エンドチェックへ
align 4
HIGS2P: movsw ;データ転送
mov edx,3 ;格納データバイト数から引く値をセットする
jmp HIGEND ;エンドチェックへ
;
align 4
HIGS2: push ecx ;格納データバイト数を保存
mov ah,al ;第2バイトを読み込むため、第1バイトを転送
lodsb ;第2バイトを読み込む
and eax,7ffh ;データオフセットを得る
dec eax ;オフセット補正
add edi,eax ;データストアアドレスを得る
shr dl,3 ;データ長ビットを得る
and edx,15
mov ecx,edx ;データ長をカウンタにセットする
rep movsb ;データ転送
add edx,2 ;格納データバイト数から引く値をセットする
pop ecx ;格納データバイト数を復帰
HIGEND: sub ecx,edx ;残りデータ数計算
ja L_HIGS ;0でもマイナスでもなければもう一度データ転送へ
jmp CALRET ;展開終了
;
align 4
LOWS: ;低圧縮モード
push esi ;esiを保存
call DATSTO ;先に参照ラインをコピー
pop esi ;復帰
;
xor eax,eax ;eaxをクリア
lodsb ;格納データバイト数を読み込む
mov bl,al ;ラインヘッダを転送
and al,7fh ;格納データバイト数を得る
test bl,80h ;格納バイトヘッダ1バイトモードフラグをチェック
jnz LO1WS ; 〃 2 〃 をスキップ
mov ah,al ;第1バイトを転送
mov dword PTR headlen[ebp],3 ;ヘッダ長変更
lodsb ;第2バイトを読み込む
LO1WS: mov ecx,eax ;総データバイト数をセットする
mov datlen[ebp],eax ;データ数保存
;
mov edi,outd[ebp] ;データ格納アドレスをセットする
;
mov eax,esi ;eaxにビットマップアドレス
mov ecx,bml[ebp] ;ビットマップ長を得る
add esi,ecx ;esiにデータ格納アドレス
xor ebx,ebx ;ebxをクリア
push ecx ;ビットマップ長を保存
align 4
L_LOWS: inc eax ;ビットマップアドレスを進める
mov dl,[eax-1] ;ビットマップを1バイト読み込む
push eax ; 〃 を保存
and edx,0ffh ;edxの最下位バイトのみ有効にする
L_CHKL:
bsf bx,dx ;ビットスキャン
jz NEXTBT ;セットされていなければループチェック
btr dx,bx ;見つかったビットをクリア
lodsb ;データ読込
mov [ebx][edi],al ;データストア
jmp L_CHKL ;ビットチェックへジャンプ
align 4
NEXTBT: pop eax ;ビットマップアドレスを復帰
add edi,8 ;データストアアドレスを8バイト進める
dec dword PTR [esp] ;ビットマップ長をデクリメント
jnz L_LOWS ;0でなければ次のビットマップを処理しに行く
pop ecx ;スタック補正
jmp CALRET ;展開終了
;
align 4
NOTCMP: ;非圧縮モード
mov ecx,lngth[ebp] ;データ数をセット
mov datlen[ebp],ecx ;データ数保存
call DTSTin ;データ生成
;
align 4
CALRET: mov esi,outd[ebp] ;転送元アドレスセット
mov eax,nrefer[ebp] ;変更するラインをセット
mov edi,nlength ;1ラインの領域長をセット
xor edx,edx ;mulの前処理
mul edi ;オフセット計算
add eax,refer[ebp] ;転送先アドレス計算
mov edi,eax ; 〃 セット
mov ecx,lngth[ebp] ;1ラインのバイト数をセット
mov edx,ecx ;4バイト転送で高速転送するために
and edx,3 ;4で割った余りのデータ数を先に転送
mov eax,[esi] ;しておく
mov [edi],eax ;取り合えず4バイト転送し、そのあとに
add edi,edx ;ポインタを補正する
add esi,edx
shr ecx,2 ;カウンタを4で割る
rep movsd ;転送
mov eax,datlen[ebp] ;データ長を復帰
add eax,headlen[ebp] ;ヘッダ長を足す
add esp,worklng ;ワークエリア解放
ret ;呼出元にリターン
;
EXEC endp
CODE ends
end