	.386p

;h:
;rexb egbcall

$biosCall	macro	data	;本ルーチンでは未使用
	mov	ah,data
	push	fs
	push	0110h
	pop	fs
	call	pword PTR fs:[0020h]
	pop	fs
	endm

$egb_bios	macro		;記述の簡易化の為の1行マクロ
	call	pword PTR fs:[0020h]
	endm

s_param	struc
	dd	?
cmd	dd	?
R_AL	dd	?
R_EBX	dd	?
R_ECX	dd	?
R_EDX	dd	?
R_ESI	dd	?
RETAD	dd	?
s_param	ends

CODE	segment dword public ER use32 'CODE'
	assume cs:CODE,ds:CODE

EXEC	proc	near
	cld			;自動増加を指定
;
	mov	ebp,esp		;パラメータ位置とBASICに渡されたスタックを保存
	mov	ah,byte PTR cmd[ebp]	;EGBの機能を読む
	or	ah,ah			;0(EGB_init)か?
	jne	EGB_CALL		;0以外ならEGB呼出しへ
;
	mov	edx,R_AL[ebp]	;自前のスタックエリアアドレス(スタック末尾)
	mov	ebx,R_EBX[ebp]	;ワークエリアアドレス
	mov	EGB_stack,edx	;プログラムにスタックアドレスをセット
	mov	EGB_work,ebx	;プログラムにワークエリアアドレスをセット
;
EGB_CALL:
	mov	esp,EGB_stack		;自前のスタックエリアに切り換える
	push	dword PTR 0110h		;BIOS領域のセレクタ値
	pop	fs			;BIOS領域のセレクタ値をfsにセット
;
	mov	edi,EGB_work		;ワークエリアアドレス
	mov	al,byte PTR R_AL[ebp]	;alを読み込む
	mov	ebx,R_EBX[ebp]		;ebxを読み込む
	mov	ecx,R_ECX[ebp]		;ecxを読み込む
	mov	edx,R_EDX[ebp]		;edxを読み込む
	mov	esi,R_ESI[ebp]		;esiを読み込む
	$egb_bios			;EGBをコール
egb_ret:
	cmp	dword PTR RETAD[ebp],0	;レジスタ値を返すアドレスを読む
	jz	skp_var			;0なら値は返さない
	push	esi			;返す領域は6*4=24バイト必要
	mov	esi,RETAD[ebp]
	mov	[esi],eax
	mov	4[esi],ebx
	mov	8[esi],ecx
	mov	12[esi],edx
	mov	16[esi],esi
	mov	edx,esi
	pop	esi
	mov	20[edx],edi
skp_var:
	mov	esp,ebp			;スタックを元に戻す
	movzx	eax,ah			;エラー情報をeaxにセット
	ret
EXEC	endp

	align	4
EGB_stack	dd	?
EGB_work	dd	?
;
CODE	ends

	end
