ReC98/th02/formats/pfopen.asm

311 lines
6.1 KiB
NASM

; master library - (pf.lib)
;
; Description:
; ファイルのオープン (TH02 version)
;
; Functions/Procedures:
; pf_t pfopen(const char *parfile,const char far *file);
;
; Parameters:
; parfile parファイル
; file オープンしたいファイル名
;
; Returns:
;
;
; Binding Target:
; Microsoft-C / Turbo-C / Turbo Pascal
;
; Running Target:
; MS-DOS
;
; Requiring Resources:
; CPU: 186
;
; Notes:
; TH02's version removes the EXE-related functionality from the original
; function, and introduces custom magic constants for compressed and
; uncompressed files that take up two bytes instead of one, losing any
; features related to the original check byte in the process. Oh, and it
; adds a pointless "seek counter" that effectively limits the number of
; files in an archive to 255.
;
; Assembly Language Note:
;
;
; Compiler/Assembler:
; TASM 3.0
; OPTASM 1.6
;
; Author:
; iR
; 恋塚昭彦
; ZUN
;
; Revision History:
; PFOPEN.ASM 5,703 94-09-17 23:22
; 95/ 1/10 Initial: pfopen.asm/master.lib 0.23
; 95/ 2/14 [M0.22k] mem_AllocID対応
; 95/ 5/22 [M0.23] small/mediumで誤動作していたので"file"をfar化
pfHeader struc
hd_type dw ? ; unsigned short type 圧縮タイプ
hd_aux db ? ; unsigned char aux 補助フラグ
hd_fnm db 13 dup(?) ; char filename[13] ファイル名
hd_psz dd ? ; long packsize 格納サイズ
hd_osz dd ? ; long orgsize オリジナルサイズ
hd_ofs dd ? ; long offset (ZUN)
hd_rsv db 4 dup(?) ; char reserve[4] 予約
pfHeader ends
; ParHeader の type の値
ZUN_PF_NONE equ 0F388h ; 無圧縮
ZUN_PF_LEN equ 9595h ; ランレングス
exeHeader struc
eh_M db ?
eh_Z db ?
eh_mod dw ?
eh_page dw ?
exeHeader ends
func PFOPEN ; pfopen() {
enter size pfHeader,0
push SI
push DI
;arg parfile:dataptr,file:dataptr
@@parfile = (RETSIZE+1+2)*2
@@file = (RETSIZE+1)*2
;local header:pfHeader
@@header = -(size pfHeader)
; PFILE用バッファ取得
mov mem_AllocID,MEMID_pfile
push size PFILE
_call HMEM_ALLOCBYTE
jnb PFOPEN_1
jmp PFOPEN_nomem
PFOPEN_1:
mov SI,AX ; PFILE構造体のセグメント
; parファイルをオープン
push word ptr [BP+@@parfile+2]
push word ptr [BP+@@parfile]
_call BOPENR
or AX,AX
jnz PFOPEN_2
jmp PFOPEN_free
PFOPEN_2:
mov ES,SI
mov ES:[pf_bf],AX
; ターゲットファイルまでシーク
lea DI,[BP+@@header]
;call SEEK Pascal,DI,SI,[BP+parfile],[BP+file]
push DI ; _ss * header
push SI ; pf
push word ptr [BP+@@parfile+2]
push word ptr [BP+@@parfile]
push word ptr [BP+@@file+2]
push word ptr [BP+@@file]
call near ptr SEEK
or AX,AX
jnz short PFOPEN_close
; 暗号化の有無に対応して内部1byte読出し関数をセットする
mov AX,offset PFGETX1
mov word ptr ES:[pf_getx],AX
; pf系関数はすべて同じセグメントである
; 復号化用キー
mov AL,pfkey
mov ES:[pf_key],AL
mov AX,SS:[DI+pfHeader.hd_type]
cmp AX,ZUN_PF_NONE
je short PFOPEN_pf_none
cmp AX,ZUN_PF_LEN
je short PFOPEN_pf_len
mov AX,PFEUNKNOWN
jmp short PFOPEN_close
PFOPEN_pf_none:
mov AX,word ptr ES:[pf_getx]
mov word ptr ES:[pf_getc],AX
jmp short PFOPEN_return
PFOPEN_pf_len:
mov word ptr ES:[pf_getc],offset PFGETC1
mov ES:[pf_cnt],0
mov ES:[pf_ch],EOF
PFOPEN_return:
mov AX,word ptr SS:[DI+pfHeader.hd_psz]
mov DX,word ptr SS:[DI+pfHeader.hd_psz + 2]
mov word ptr ES:[pf_size],AX
mov word ptr ES:[pf_size + 2],DX
mov AX,word ptr SS:[DI+pfHeader.hd_osz]
mov DX,word ptr SS:[DI+pfHeader.hd_osz + 2]
mov word ptr ES:[pf_osize],AX
mov word ptr ES:[pf_osize + 2],DX
xor AX,AX
mov word ptr ES:[pf_read],AX
mov word ptr ES:[pf_read + 2],AX
mov word ptr ES:[pf_loc],AX
mov word ptr ES:[pf_loc + 2],AX
mov AX,SI
jmp short PFOPEN_q
PFOPEN_close:
mov word ptr pferrno,AX
push ES:[pf_bf]
_call BCLOSER
PFOPEN_free:
push SI
_call HMEM_FREE
jmp short PFOPEN_error
PFOPEN_nomem:
mov byte ptr pferrno,PFENOMEM
PFOPEN_error:
xor AX,AX
PFOPEN_q:
pop DI
pop SI
leave
ret (2+DATASIZE)*2
endfunc ; }
;-----------------------------------------------------------------------------
; seek(pfHeader _ss *header, pf_t pf, const char MASTER_PTR *parfile,const char MASTER_PTR *file)
;-----------------------------------------------------------------------------
SEEK proc near ; {
enter size exeHeader,0
push SI
push DI
push ES
;arg header:dataptr,pf:word, parfile:dataptr,file:dataptr
@@header = (1+2+2+DATASIZE)*2
@@pf = (1+1+2+DATASIZE)*2
@@parfile = (1+1+2)*2
@@file = (1+1)*2
;local exeh:exeHeader
@@exeh = -(size exeHeader)
mov SI,[BP+@@pf] ; PFILE構造体のセグメント
mov ES,SI
xor AX,AX
mov word ptr ES:[pf_home],AX
mov word ptr ES:[pf_home + 2],AX
; [DX:]BX = strrchr(parfile,'.');
_push DS
push SI
CLD
xor BX,BX
_mov DX,BX
_lds SI,[BP+@@parfile]
STRRCHR_LOOP:
lodsb
cmp AL,0
jz short STRRCHR_DONE
cmp AL,'.'
jne short STRRCHR_LOOP
lea BX,[SI-1]
_mov DX,DS
jmp short STRRCHR_LOOP
STRRCHR_DONE:
pop SI
_pop DS
l_ <mov AX,DX>
l_ <or AX,BX>
s_ <test BX,BX>
jz short SEEK_seek
SEEK_seek:
mov DI,[BP+@@header]
mov pf_limit,0
SEEK_loop:
; ヘッダをリード
mov ES,SI
;call BREAD Pascal,DI,size pfHeader,ES:[pf_bf]
_push SS
push DI
push size pfHeader
push ES:[pf_bf]
_call BREAD
inc pf_limit
cmp pf_limit, 255
mov BX,PFENOTFOUND
jz short SEEK_error
cmp AX,size pfHeader
jne short SEEK_error
mov ES,SI
add word ptr ES:[pf_home],AX
adc word ptr ES:[pf_home + 2],0
; ヘッダの正当性をチェック
mov AX,SS:[DI+pfHeader.hd_type]
and ax, ax
mov BX,PFEILPFILE
jz short SEEK_error
; ファイル名が不可視の場合、比較のためもとに戻す
lea BX,[DI+pfHeader.hd_fnm]
SEEK_not: cmp byte ptr SS:[BX],0
je short SEEK_cmp
not byte ptr SS:[BX]
inc BX
jmp short SEEK_not
SEEK_cmp:
lea BX,[DI+pfHeader.hd_fnm]
push word ptr [BP+@@file+2]
push word ptr [BP+@@file]
_push SS
push BX
call near ptr STR_IEQ
mov AX,0
jnz short SEEK_return
jmp short SEEK_loop
SEEK_error:
mov AX,BX
SEEK_return:
mov ES,SI
mov AX,word ptr SS:[DI+pfHeader.hd_ofs]
mov DX,word ptr SS:[DI+pfHeader.hd_ofs + 2]
mov word ptr ES:[pf_home],AX
mov word ptr ES:[pf_home + 2],DX
push ES:[pf_bf]
push DX
push AX
push 0
_call BSEEK_
pop ES
pop DI
pop SI
leave
ret (2+2+DATASIZE)*2
SEEK endp ; }