;===============================================================
;	CHIT ver0.20 for FM-TOWNS (exCHange ITem)		
;	Copyright(c) 1991 Fuzzball	1991.1/27->1991.5/23	
;===============================================================

		.386p

CODE		segment	public dword use32
CODE		ends
DATA		segment	public dword use32
DATA		ends
BSS		segment	public dword use32
BSS		ends
SSEG		segment	stack dword use32
SSEG		ends
DGROUP		group	DATA,BSS

KEYIN		macro
		mov	ax,0900h
		int	90h
		endm

EGB		macro	no
		mov	ah,no
		call	pword ptr fs:[20h]
		endm

EGB_WORK_SIZE	equ	600h
INF_BUF_SIZE	equ	4000h

LF		equ	0ah
CR		equ	0dh
ESCAPE		equ	1bh
CSR_R		equ	1ch
CSR_L		equ	1dh
CSR_U		equ	1eh
CSR_D		equ	1fh
SPACE		equ	20h

DISP_HOME	equ	0501h
TITLE_SIZE	equ	12
MAX_ITEM	equ	125

		extrn	disp_str:near
		extrn	disp_str2:near
		extrn	disp_msg:near
;===============================================================
CODE		segment
		assume	cs:CODE,ds:DGROUP,ss:SSEG
entry:
		cld
		mov	ax,0110h		;TBIOS sel
		mov	fs,ax

		mov	edi,offset egb_work	;EGB work
		mov	ecx,EGB_WORK_SIZE
		EGB	00h			;init EGB

		mov	bl,0fh			;white
		mov	dx,0000h		;locate0,0
		mov	esi,offset msg_title
		call	disp_str

		call	chk_para
		call	inf_read
;===============================================
;	main routine start			
;===============================================
init_start:	call	make_screen

main_lp:
;disp_parameter
		mov	bl,0fh			;white
		mov	ecx,40h			;len=40h
		mov	dx,030ah
		movzx	esi,word ptr [now_item]
		shl	esi,7			;esi=item#*80h
		lea	esi,[esi+inf_buf+40h]	;offset path+opt
		call	disp_str2		;disp param

		mov	bl,0e0h			;rev_yellow
		mov	ax,[now_item]
		cmp	ax,[keep_item]
		jne	short set_bar
		mov	bl,0f0h			;rev_white
set_bar:	call	disp_item		;chg_atrb

		KEYIN

		mov	bl,0fh			;white
		mov	ax,[now_item]
		cmp	ax,[keep_item]
		jne	short reset_bar
		mov	bl,0a0h			;rev_red
reset_bar:	call	disp_item		;chg_atrb

		mov	al,dl
		mov	edi,offset key_chk_str
		mov	ecx,len_chk_str
		mov	esi,ecx
		repne scasb
		jne	main_lp
		inc	ecx
		sub	esi,ecx
		shl	esi,2
		mov	ax,[now_item]
		jmp	cs:[key_jmp_tbl+esi]

key_chk_str	db	SPACE,CSR_R,CSR_L,CSR_U
		db	CSR_D,CR,ESCAPE
len_chk_str	equ	$-key_chk_str
		align	4
key_jmp_tbl	dd	set_keep,mov_right,mov_left,mov_up
		dd	mov_down,save_chk,end_chk
;===============================================
;	main routine end			
;===============================================
;---------------------------------------------------------------
set_keep:	cmp	ax,[keep_item]
		je	short reset_keep
		cmp	word ptr [keep_item],-1
		je	short keep_ok
		call	exchg_item
reset_keep:	mov	ax,-1
keep_ok:	mov	[keep_item],ax
		jmp	main_lp
;-----------------------
mov_right:	inc	ax
		cmp	ax,[num_item]
		jne	set_now_item
		xor	ax,ax
		jmp	set_now_item
;-----------------------
mov_left:	and	ax,ax			;ax=0?
		jne	short left_ok
		mov	ax,[num_item]
left_ok:	dec	ax
		jmp	set_now_item
;-----------------------
mov_up:		sub	ax,5
		jge	short set_now_item
		mov	bx,[num_item]
		sub	bx,5
mov_up_lp:	add	ax,5
		cmp	bx,ax
		jg	short mov_up_lp
		jmp	short set_now_item
;-----------------------
mov_down:	add	ax,5
		cmp	ax,[num_item]
		jl	short set_now_item
mov_down_lp:	sub	ax,5
		cmp	ax,5
		jge	short mov_down_lp

set_now_item:	mov	[now_item],ax
		jmp	main_lp
;-----------------------
save_chk:	mov	esi,offset msg_save?
		call	disp_msg
		call	keyin_yn?
		jb	short not_save		;[ESC]
		call	inf_save
not_save:	jmp	init_start
;-----------------------
end_chk:	mov	esi,offset msg_end?
		call	disp_msg
		call	keyin_yn?
		jnb	short main_end
		jmp	init_start

main_end:	xor	al,al			;ret code

finish:		push	eax
		mov	edi,offset egb_work
		mov	ecx,EGB_WORK_SIZE
		EGB	00h			;init EGB
		pop	eax

		mov	ah,4ch
		int	21h
;---------------------------------------------------------------
inf_read	proc	near

		mov	ax,3d00h		;open/read
		mov	edx,offset path
		int	21h			;ret:ax=handle
		jb	short open_err
		mov	bx,ax			;handle

		mov	edx,offset inf_buf	;ds:edx=buf adrs
		mov	ecx,MAX_ITEM*80h	;size
		mov	ah,3fh			;read
		int	21h			;ret:ax=read size

		shr	ax,7			;ax=ax/80h=num_item
		mov	[num_item],ax

		mov	ah,3eh			;close
		int	21h
		ret
open_err:
		mov	esi,offset msg_open_err
		call	disp_msg
		KEYIN

		mov	al,1			;ret code
		jmp	finish
inf_read	endp
;---------------------------------------------------------------
inf_save	proc	near

		mov	edx,offset path
		mov	ax,3d01h		;open/write
		int	21h
		mov	bx,ax			;handle

		mov	edx,offset inf_buf	;ds:edx=buf adrs
		mov	ax,[num_item]
		shl	ax,7
		movzx	ecx,ax			;size=num_item*80h
		mov	ah,40h
		int	21h			;write
		jnb	short file_close

		mov	esi,offset msg_save_err
		call	disp_msg
		KEYIN

file_close:	mov	ah,3eh
		int	21h			;close
		ret
inf_save	endp
;---------------------------------------------------------------
chk_para	proc	near
		push	ds

		mov	ax,0004h		;PSP sel
		mov	ds,ax

		mov	esi,80h			;parameter adrs
		lodsb
		and	al,al
		je	short get_crnt_drv
		movzx	ecx,al			;ecx=para length

chk_para_lp:	lodsb
		cmp	al,SPACE
		jne	short write_drv
		loop	chk_para_lp

get_crnt_drv:
		mov	ah,19h			;get current drv
		int	21h
		add	al,'A'
write_drv:	and	al,0dfh			;toupper

		pop	ds

		mov	[path],al
		mov	byte ptr [msg_open_err+6],al
		mov	byte ptr [msg_save?+6],al

		ret
chk_para	endp
;---------------------------------------------------------------
make_screen	proc	near

		mov	edi,offset egb_work
		EGB	20h			;cls

		mov	bl,0fh			;white
		mov	dx,0000h
		mov	esi,offset msg_title
		call	disp_str
		add	dh,2
		mov	esi,offset msg_drive
		call	disp_str
		inc	dh
		mov	esi,offset msg_param
		call	disp_str

		movzx	ecx,word ptr [num_item]
		and	ecx,ecx
		je	short disp_item_e
		xor	ax,ax
		mov	bl,0fh			;white
disp_item_lp:	call	disp_item
		inc	ax
		loop	disp_item_lp
disp_item_e:
		mov	ax,[keep_item]
		cmp	ax,-1
		je	short no_keep_item
		mov	bl,0a0h			;rev_red
		call	disp_item
no_keep_item:
		ret
make_screen	endp
;---------------------------------------------------------------
num2loc		proc	near
;in:	ax=item#
;out:	dx=locate
;break:	nothing
		push	eax

		mov	dl,5
		div	dl			;ax/5=al...ah
		xchg	ah,al
		shl	al,4
		mov	dx,ax
		add	dx,DISP_HOME

		pop	eax
		ret
num2loc		endp
;---------------------------------------------------------------
exchg_item	proc	near
;in:	[now_item],[keep_item]
;break:	nothing
		pushad

		xor	esi,esi
		xor	edi,edi
		mov	si,[now_item]
		mov	di,[keep_item]
		shl	si,7		;si*=80h
		shl	di,7		;di*=80h
		mov	eax,offset inf_buf
		add	esi,eax		;now_item  adrs
		add	edi,eax		;keep_item adrs

		mov	ecx,80h/2	;=40h word

exchg_lp:	mov	ax,[esi]
		xchg	ax,[edi]
		mov	[esi],ax
		add	esi,2
		add	edi,2
		loop	exchg_lp

		mov	bl,0fh			;white
		mov	ax,[now_item]
		call	disp_item
		mov	ax,[keep_item]
		call	disp_item

		popad
		ret
exchg_item	endp
;---------------------------------------------------------------
disp_item	proc	near
;in:	ax=item#
;	bl=color
;break:	nothing
		pushad

		call	num2loc			;dx=locate

		movzx	esi,ax
		shl	esi,7
		lea	esi,[esi+inf_buf+33h]	;offset title

		mov	ecx,TITLE_SIZE
		call	disp_str2		;disp_item

		popad
		ret
disp_item	endp
;---------------------------------------------------------------
keyin_yn?	proc	near
;in:	nothing
;out:	CF=0 ... yes=[RETURN]
;	CF=1 ... no =[ESC]
;break:	nothing
		push	eax
		push	ebx
		push	edx

keyin_yn_lp:	KEYIN

		cmp	dl,CR
		je	keyin_CR
		cmp	dl,ESCAPE
		jne	keyin_yn_lp
		stc
keyin_CR:
		pop	edx
		pop	ebx
		pop	eax
		ret
keyin_yn?	endp
;---------------------------------------------------------------
CODE		ends
;===============================================================
DATA		segment

keep_item	dw	-1

msg_title	db	'CHIT ver0.20 for FM-TOWNS'
		db	' Copyright(c) 1991 Fuzzball',0
msg_param	db	'Parameter=',0
msg_drive	db	'Path='
path		db	'X:\TMENU.INF',0

msg_open_err	dw	0a16h,0524h		;pos_yx,size_yx
		db	'  X:\TMENU.INFが見つかりません。',0
		db	0
		db	'   何かキーを押すと終了します。',0

msg_save_err	dw	0c16h,0524h
		db	'     セーブ出来ませんでした。',0
		db	0
		db	'    何かキーを押してください。',0

msg_save?	dw	0c16h,0524h
		db	'  X:\TMENU.INFをセーブしますか？',0
		db	0
		db	'      Yes=[RETURN], No=[ESC]',0

msg_end?	dw	0c19h,051eh
		db	'    CHITを終了しますか？',0
		db	0
		db	'    Yes=[RET], No=[ESC]',0

DATA		ends
;===============================================================
BSS		segment

num_item	dw	?
now_item	dw	?

egb_work	db	EGB_WORK_SIZE dup(?)	;egb_work_area
inf_buf		db	INF_BUF_SIZE dup(?)	;info_buffer

BSS		ends
;===============================================================
SSEG		segment

		db	1000h dup(?)		;stack area

SSEG		ends
;===============================================================
		end	entry
