;=======================================================
;	RM.EXP (Rainbow Mouse)		1991.7/30	
;=======================================================

		.386p

EGB_WORK_SIZE	equ	600h
MOUSE_WORK_SIZE	equ	1000h

EGB		macro	no
		mov	ah,no
		call	fword ptr fs:[20h]
		endm

MOUSE		macro	no
		mov	ah,no
		call	fword ptr fs:[40h]
		endm

DGROUP		group	DATA,BSS

CODE		segment	public use32
		assume	cs:CODE,ds:DGROUP,gs:DGROUP,ss:SSEG
entry:
		cld
		mov	ax,0110h		;TBIOS sel
		mov	fs,ax
		call	init_mouse
		mov	ax,0104h		;VRAM sel
		mov	es,ax
		call	init_screen
;-----------------------------------------------
main_lp:
;wait VSYNC end
		mov	al,30			;CRTC reg#=30
		mov	dx,440h
		out	dx,al
		add	dx,3
vsync_e_lp:	in	al,dx
		test	al,80h
		je	short vsync_e_lp

;------- change -------
		mov	ecx,7
		mov	esi,offset btm_mouse_pos

chg_pos_lp:	lodsd
		mov	[esi],eax
		sub	esi,8
		loop	chg_pos_lp

		call	fword ptr fs:[48h]	;mouse sense routine

		MOUSE	03h
		test	ch,02h
		jne	finish

		test	ch,01h
		je	short pos2adrs
		add	[mouse_color],11111111h
		jnb	short pos2adrs
		mov	[mouse_color],99999999h
pos2adrs:
		movzx	edi,bx
		shl	edi,9		;y*512
		movzx	edx,dx
		shr	edx,1		;x/2
		add	edi,edx
		add	edi,40000h
		mov	[top_mouse_pos],edi

;wait VSYNC start
		mov	al,30			;CRTC reg#=30
		mov	dx,440h
		out	dx,al
		add	dx,3
vsync_s_lp:	in	al,dx
		test	al,80h
		jne	short vsync_s_lp

;------- clear -------
		mov	edi,[clr_mouse_pos]

		mov	ecx,16
		xor	eax,eax
		align	4
clr_ms_csr_lp:	stosd
		stosd
		add	edi,512-8
		loop	clr_ms_csr_lp

;------- write -------
		mov	ecx,7
		mov	ebx,offset btm_mouse_pos
		mov	ebp,[mouse_color]

		align	4
wrt_ms_lplp:	push	ecx
		mov	edi,[ebx]
		mov	ecx,16
		mov	esi,offset ms_csr_data
		align	4
wrt_ms_csr_lp:	lodsd
		mov	edx,eax
		not	edx
		and	edx,es:[edi]		;くり抜き
		and	eax,ebp			;色セット
		or	eax,edx
		stosd

		lodsd
		mov	edx,eax
		not	edx
		and	edx,es:[edi]		;くり抜き
		and	eax,ebp			;色セット
		or	eax,edx
		mov	es:[edi],eax

		add	edi,512-4
		loop	wrt_ms_csr_lp

		pop	ecx
		sub	ebx,4
		add	ebp,11111111h
		jnb	short color_ok
		mov	ebp,99999999h
color_ok:
		loop	wrt_ms_lplp

		jmp	main_lp
;-----------------------------------------------
finish:
		mov	edi,offset egb_work
		mov	ecx,EGB_WORK_SIZE
		EGB	00h			;init EGB

		MOUSE	01h			;end MOUSE

		mov	ax,4c00h
		int	21h
;-----------------------------------------------
init_screen	proc	near

		mov	edi,offset egb_work
		mov	ecx,EGB_WORK_SIZE
		EGB	00h			;init EGB

		mov	al,1
		mov	edx,3
		EGB	06h			;set priority

;make screen
		xor	edi,edi
		mov	ecx,(512/4)*40
		mov	eax,77777777h
		rep stosd

		mov	ecx,(512/4)*440
		mov	eax,88888888h
		rep stosd

		ret
init_screen	endp
;-----------------------------------------------
init_mouse	proc	near

;clear mouse_work
		mov	edi,offset mouse_work
		mov	ecx,MOUSE_WORK_SIZE/4
		xor	eax,eax
		rep stosd

		mov	edi,offset mouse_work
		mov	ecx,MOUSE_WORK_SIZE
		MOUSE	00h			;init MOUSE

;set mouse window
		xor	dx,dx
		mov	bx,639			;x
		MOUSE	07h
		mov	bx,479			;y
		MOUSE	08h

		mov	dx,320
		mov	bx,240
		MOUSE	04h			;set mouse_pos

;init mouse_pos
		mov	ecx,8
		mov	edi,offset top_mouse_pos
		mov	eax,1e0a0h+40000h
		rep stosd

		mov	[mouse_color],99999999h

		ret
init_mouse	endp

CODE		ends
;=======================================================
DATA		segment	public use32

ms_csr_data	dd	0ffffffffh,000000000h
		dd	00fffffffh,000000000h
		dd	000ffffffh,000000000h
		dd	0000fffffh,000000000h
		dd	000ffffffh,000000000h
		dd	00fff0fffh,000000000h
		dd	0fff000ffh,000000000h
		dd	0ff00000fh,00000000fh
		dd	0f0000000h,0000000ffh
		dd	000000000h,000000fffh
		dd	000000000h,00000fff0h
		dd	000000000h,000000f00h
		dd	000000000h,000000000h
		dd	000000000h,000000000h
		dd	000000000h,000000000h
		dd	000000000h,000000000h

DATA		ends
;=======================================================
BSS		segment	public use32

top_mouse_pos	dd	?
		dd	5 dup(?)
btm_mouse_pos	dd	?
clr_mouse_pos	dd	?

mouse_color	dd	?

egb_work	db	EGB_WORK_SIZE dup(?)
mouse_work	db	MOUSE_WORK_SIZE dup(?)

BSS		ends
;=======================================================
SSEG		segment	stack use32

		db	1000h dup(?)

SSEG		ends
;=======================================================
		end	entry
