; DOS/V 用グラフィックライブラリ version1.20
; Copyright (c) 電子情報研究所 1994 / 開発：皆木　慎吾

-- Assembly part

CGROUP	GROUP	TEXT
TEXT	CSEG

; 画面モードの設定
; void vmode( unsigned char mode )
-vmode.a86
vmode_::
	mov	ah,0
	int	10h
	ret

; 文字表示位置の指定
; void setxy ( unsigned char x,unsigned char y )
;   (位置指定の値は画面左上が x=0,y=0)
-setxy.a86
setxy_::
	push	dx

	mov	dh,bl
	mov	dl,al
	mov	ah,2
	int	10h

	pop	dx
	ret

; 文字列の描画
; void putstr ( unsigned char attr,char *str,int len )
-putstr.a86
putstr_::
	push	cx
	push	dx
	push	bp
	push	es

	push	ax
	push	bx
	push	cx
	mov	ah,3
	mov	bh,0
	int	10h
	pop	cx
	pop	bx
	pop	ax

	mov	bp,bx
	mov	bx,ds
	mov	es,bx

	mov	bh,0
	mov	bl,al
	mov	ah,13h
	mov	al,0
	int	10h

	pop	es
	pop	bp
	pop	dx
	pop	cx
	ret

; ピクセルの描画
; void pixel( unsigned char color,unsigned int x,unsigned int y )
-pixel.a86
pixel_::
;  レジスタ保存
	push	cx
	push	dx
	push	es

;  カラーコード情報保存
	and	al,15
	mov	[color],al

;  セグメントレジスタ設定
	mov	ax,0a000h
	mov	es,ax

;  Ｉ／Ｏポート出力
	mov	dx,03ceh
	mov	ax,0003h
	out	dx,ax
	mov	ax,0004h
	out	dx,ax
	mov	ax,0205h
	out	dx,ax

;  ＶＲＡＭアドレス計算
	mov	ax,bx
	mov	bl,8
	div	bl
	mov	bx,ax
	and	bx,000ffh

	mov	[reg_ah],ah
	mov	ax,cx
	mov	cx,80
	mul	cx
	add	bx,ax
;    bxレジスタを退避(破壊されるbhレジスタをchレジスタに退避)
	mov	ch,bh

;  Bit Maskレジスタ用の値計算
	mov	cl,[reg_ah]
	mov	bh,10000000b
	ror	bh,cl

;  Bit Maskレジスタ設定（Ｉ／Ｏポート出力）
	mov	dx,03ceh
	mov	ah,bh
	mov	al,8
	out	dx,ax

;    bxレジスタを復元
	mov	bh,ch

;  ＶＲＡＭ読み込み（ラッチにデータを入れるため）
	mov	al,es:[bx]

;  カラーコード情報呼び出し
	mov	al,[color]

;  ＶＲＡＭ書き込み
	mov	es:[bx],al

;  レジスタ復元
	pop	es
	pop	dx
	pop	cx
	ret

color:	db	0
reg_ah:	db	0

; システムタイマをリセットする
; unsigned char treset ( void )
-treset.a86
treset_::
	push	cx
	push	dx

	mov	cx,0
	mov	dx,0

	mov	ah,1
	int	1ah

	mov	ah,2
	int	1ah
	mov	al,ch

	pop	dx
	pop	cx
	ret

; システムタイマの値を得る
; unsigned long gtime ( void )
-gtime.a86
gtime_::
	push	cx
	push	dx

	mov	ah,0
	int	1ah

	mov	bx,cx
	mov	ax,dx

	pop	dx
	pop	cx
	ret

; システムタイマの値を元に戻す
; unsigned char treturn ( void )
-treturn.a86
treturn_::
	push	cx
	push	dx

t1:	mov	ah,2
	int	1ah
	jb	t1
	push	cx

	mov	al,ch
	call	covbcd
	mov	ch,al

	mov	al,cl
	call	covbcd
	mov	cl,al

	mov	al,dh
	call	covbcd
	mov	dh,al

	mov	ah,2dh
	mov	dl,0
	int	21h

	pop	cx
	mov	al,ch

	pop	dx
	pop	cx
	ret

;  BCD形式の値を普通の値に戻す
;  [入力] al←BCD形式の値 [リターン] al←普通の値
covbcd:	mov	ah,0
	mov	bl,16
	div	bl
	mov	bh,ah
	mov	bl,10
	mul	bl
	mov	ah,bh
	add	al,ah
	ret

; 日付を１日進める
; void tforward ( void )
-tforward.a86
tforward_::
	push	cx
	push	dx

t2:	mov	ah,4
	int	1ah
	jb	t2

	mov	al,ch
	call	covbcd
	mov	bl,100
	mul	bl
	push	ax

	mov	al,cl
	call	covbcd
	mov	cl,al
	mov	ch,0
	pop	ax
	add	cx,ax

	mov	al,dh
	call	covbcd
	mov	dh,al

	mov	al,dl
	call	covbcd
	mov	dl,al
	inc	dl

	mov	ah,2bh
	int	21h
	cmp	al,0ffh
	jz	month
	jmp	return

month:	mov	dl,1
	inc	dh
	int	21h
	cmp	al,0ffh
	jz	year
	jmp	return

year:	mov	dh,1
	inc	cx
	int	21h

return:	pop	dx
	pop	cx
	ret

;  BCD形式の値を普通の値に戻す
;  [入力] al←BCD形式の値 [リターン] al←普通の値
covbcd:	mov	ah,0
	mov	bl,16
	div	bl
	mov	bh,ah
	mov	bl,10
	mul	bl
	mov	ah,bh
	add	al,ah
	ret

; リアルタイムクロックから秒を読み込む
;  （主に乱数の系列を初期化するための値として使う）
; unsigned int gsecond( void );
-gsecond.a86
gsecond_::
	push	cx
	push	dx

t3:	mov	ah,2
	int	1ah
	jb	t3

	mov	ah,cl
	mov	al,dh

	pop	dx
	pop	cx
	ret

; マウスの初期化 unsigned char mouseini(void)
-mouseini.a86
mouseini_::
;  INT 33H の割り込みベクタを得る
;  ベクタが0000:0000Hならばマウスドライバがインストールされていない
	push	es
	mov	ah,35h
	mov	al,33h
	int	21h
	mov	ax,es
	or	ax,bx
	jz	no

;  INT 33H(AX=0) を呼び出してAX=0ならばマウスが接続されていない
;  ここがアスキーのDOS/V プログラミングガイドと異なっている
;  （同書ではAX=0ならばマウスが接続されており、AX=FFFFHならばマウスが接続され
;    ていない、となっている）
	mov	ax,0
	int	33h
	cmp	ax,0
	jz	no
;  マウスが使用不可能ならば１を返す
	mov	al,1
	pop	es
	ret

;  マウスが使用不可能ならば０を返す
no:	mov	al,0
	pop	es
	ret

; マウスカーソルの表示 void mouseput(void)
-mouseput.a86
mouseput_::
	mov	ax,1
	int	33h
	ret

; マウスカーソルの消去 void mouseout(void)
-mouseout.a86
mouseout_::
	mov	ax,2
	int	33h
	ret

; マウスボタンの状態の取得 unsigned char mousepus(void)
-mousepus.a86
mousepus_::
	push	cx
	push	dx
	mov	ax,3
	int	33h
;  両方押されていなければ０、左が押されていれば１、右が押されていれば２、
;  両方押されていれば３が入る
	mov	al,bl
	pop	dx
	pop	cx
	ret

; マウスカーソル位置の取得 unsigned long mousexy(void)
-mousexy.a86
mousexy_::
	push	cx
	push	dx
	mov	ax,3
	int	33h
;  帰り値の上位１６ビットにＸ座標、下位１６ビットにＹ座標が入る
	mov	bx,cx
	mov	ax,dx
	pop	dx
	pop	cx
	ret

; カーソル位置の指定 void mousesxy(unsigned int x,unsigned int y)
-mousesxy.a86
mousesxy_::
	push	cx
	push	dx
	mov	cx,ax
	mov	dx,bx
	mov	ax,4
	int	33h
	pop	dx
	pop	cx
	ret

; 言語の取得
; unsigned int ( void )
; 返り値が０なら英語モード
-lang.a86
lang_::
	push	ds
	push	si

	mov	ax,6300h
	int	21h
	mov	ax,[si].w

	pop	si
	pop	ds
	ret
