home *** CD-ROM | disk | FTP | other *** search
- .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
-