		.286
_TEXT		SEGMENT  WORD PUBLIC 'CODE'
_TEXT		ENDS
_DATA		SEGMENT  WORD PUBLIC 'DATA'
_DATA		ENDS
CONST		SEGMENT  WORD PUBLIC 'CONST'
CONST		ENDS
_BSS		SEGMENT  WORD PUBLIC 'BSS'
_BSS		ENDS
_INST		SEGMENT  WORD PUBLIC 'INST'
_INST		ENDS

DGROUP		GROUP	_TEXT, CONST, _BSS, _DATA, _INST

extrn		_setbios:near
extrn		_resetbios:near
extrn		His_init:near
extrn		His_end:near
extrn		_VDB_init:near
extrn		_Dummy_init:near
extrn		_cflush:near

regs_set	struc
regs_es		dw	?
regs_ds		dw	?
regs_di		dw	?
regs_si		dw	?
regs_bp		dw	?
regs_sp		dw	?
regs_bx		dw	?
regs_dx		dw	?
regs_cx		dw	?
regs_ax		dw	?
regs_ip		dw	?
regs_cs		dw	?
regs_cf		dw	?
regs_set	ends

_DATA		segment

Exe_Param	dw	?			; Envp Seg	+0
		dw	?			; para offset	+2
		dw	?			;      seg	+4
		dw	offset DGROUP:Exe_fcb1	; FCB1 offset	+6
		dw	?			;      seg	+8
		dw	offset DGROUP:Exe_fcb2	; FCB2 offset	+10
		dw	?			;      seg	+12

Exe_fcb1	db	16 dup (0)
Exe_fcb2	db	16 dup (0)

Command		db	'C:\COMMAND.COM'
		db	128 dup (0)
Def_Param	db	0,0Dh

		public	term_flg
		public	vdb_act_flg
		public	kyb_act_flg
		public	trap_flg

term_flg	db	0
vdb_act_flg	db	0
kyb_act_flg	db	0
trap_flg	db	0
rsget_flg	db	0

term_port	db	0
rts_flg		db	0

key_shift	db	?
key_code	dw	0FFFFh
key_addr	dw	0
key_vect	dd	far

RS_status	dw	?
RS_old_param	db	18 dup (?)

RS_param	db	?,?
RS_buf_off	dw	?
RS_buf_seg	dw	?
		dw	?,?
RS_irq_off	dw	?
RS_irq_seg	dw	?
		db	?,?,?

RS_buffer	dw	1024+4+10 dup (?)

;			+0    +1    +2    +3    +4    +5    +6    +7
;			+8    +9    +a    +b    +c    +d    +e    +f
enc_key_tbl	dw	1B10h,1E10h,2E10h,2C10h,2010h,1310h,2110h,2210h	;+00 ^@
		dw	0F00h,1000h,2410h,4E00h,2610h,1D00h,2F10h,1910h ;+08 ^H
		dw	1A10h,1110h,1410h,1F10h,1510h,1710h,2D10h,1210h	;+10 ^P
		dw	2B10h,1610h,2A10h,0100h,5100h,4F00h,4D00h,5000h ;+18 ^X
		dw	3500h,0204h,0304h,0404h,0504h,0604h,0704h,0804h	;+20 
		dw	0904h,0A04h,2804h,2704h,3100h,0C00h,3200h,3300h ;+28 (
		dw	0B00h,0200h,0300h,0400h,0500h,0600h,0700h,0800h	;+3x 0
		dw	0900h,0A00h,2800h,2700h,3104h,0C04h,3204h,3304h ;+38 8
		dw	1B00h,1E04h,2E04h,2C04h,2004h,1304h,2104h,2204h	;+40 @
		dw	2304h,1804h,2404h,2504h,2604h,3004h,2F04h,1904h ;+48 H
		dw	1A04h,1104h,1404h,1F04h,1504h,1704h,2D04h,1204h	;+50 P
		dw	2B04h,1604h,2A04h,1C00h,0E00h,2900h,0D00h,3400h ;+58 X
		dw	1B04h,1E00h,2E00h,2C00h,2000h,1300h,2100h,2200h	;+60 `
		dw	2300h,1800h,2400h,2500h,2600h,3000h,2F00h,1900h ;+68 h
		dw	1A00h,1100h,1400h,1F00h,1500h,1700h,2D00h,1200h	;+70 p
		dw	2B00h,1600h,2A00h,1C04h,0E04h,2904h,0D04h,4B00h ;+78 x

_DATA		ends

_TEXT		segment
		ASSUME CS: DGROUP, DS: DGROUP, ES: DGROUP

		org	02ch
EnvSeg		label	word

		org	080h
CmdsLine	label	word

		org	100h
entry:		jmp	main

_TEXT		ends

_INST		segment
		ASSUME CS: DGROUP, DS: DGROUP, ES: DGROUP

main		proc	near
		mov	ax,cs
		mov	ds,ax
		mov	es,ax
		cld

		call	Screen_init
		call	_setbios
		call	His_init
		call	Path_init
		call	PF_key_init
		call	RS_init

		mov	sp,offset DGROUP:Local_Stack

		mov	ax,offset DGROUP:End_of_Prog
		add	ax,15
		shr	ax,4
		push	cs
		push	ax
		call	_Dummy_init	; short Dummy_init(short seg,short cs)
		add	sp,4
		mov	bx,ax
		mov	ax,cs
		mov	es,ax
		mov	ah,4Ah
		int	21h

		mov	di,offset DGROUP:Exe_Param
		mov	ax,EnvSeg
		mov	[di+0],ax

		mov	ax,ds
		mov	[di+4],ax
		mov	[di+8],ax
		mov	[di+12],ax

		mov	si,offset DGROUP:CmdsLine
		lodsb
		cmp	al,0
		je	Def_Fork
		mov	ah,al

main_1:		cmp	ah,0
		je	Def_Fork
		dec	ah
		lodsb
		cmp	al,0Dh
		je	Def_Fork
		cmp	al,' '
		je	main_1
		cmp	al,09h
		je	main_1

		mov	bx,offset DGROUP:Command
		jmp	main_5

main_2:		cmp	ah,0
		je	main_4
		dec	ah
		lodsb
		cmp	al,0Dh
		je	main_4
		cmp	al,' '
		je	main_3
		cmp	al,09h
		je	main_3
main_5:		mov	[bx],al
		inc	bx
		jmp	short main_2

main_3:		dec	si
		mov	[si],ah
		mov	[di+2],si
		mov	byte ptr [bx],0
		jmp	short Com_Fork

main_4:		mov	byte ptr [bx],0
Def_Fork:	mov	word ptr [di+2],offset DGROUP:Def_Param

Com_Fork:	push	ds
		pop	es
		mov	si,[di+2]
		mov	di,offset DGROUP:Exe_fcb1
		mov	ax,2901h
		int	21h
		mov	di,offset DGROUP:Exe_fcb2
		mov	ax,2901h
		int	21h

		mov	dx,offset DGROUP:Command
		mov	bx,offset DGROUP:Exe_Param
		mov	ax,4B00h
		int	21h

		call	RS_end
		call	His_end
		call	_resetbios

		mov	ax,4C00h		; End of Oricon
		int	21h

main		endp

rs_getc		proc	near

		mov	ah,05h
		mov	al,[term_port]
		int	9Bh
		cmp	ah,0
		jne	rs_getc_no
		mov	cx,dx

		cmp	[rts_flg],0
		je	rs_getc_1
		cmp	cx,256
		jnb	rs_getc_1

		mov	byte ptr [rts_flg],0
		mov	ah,08h
		mov	al,[term_port]
		mov	dl,22h
		int	9Bh

rs_getc_1:	cmp	cx,0
		je	rs_getc_no

		mov	ah,06h
		mov	al,[term_port]
		push	cx
		int	9Bh
		pop	cx
		cmp	ah,0
		jne	rs_getc_no

		clc
		ret

rs_getc_no:	mov	byte ptr [rsget_flg],0
		stc
		ret

rs_getc		endp

key_strip	proc	near
		push	bx
		push	cx
		push	dx

		mov	ch,bh
key_strip_1:	mov	ah,07h
		pushf
		call	cs:[key_vect]
		cmp	bh,ch
		jne	key_strip_2
		mov	ax,0900h
		pushf
		call	cs:[key_vect]
		jmp	key_strip_1

key_strip_2:	pop	dx
		pop	cx
		pop	bx
		ret
key_strip	endp

Cheng_Screen	proc	near
		mov	ah,21h
		int	91h			; Ext VDB Command
		ret
Cheng_Screen	endp

		public	Term_in_out
Term_in_out	proc	near

		cmp	byte ptr [rsget_flg],0
		je	Term_end

		cmp	byte ptr [trap_flg],0
		jne	Term_end

		cmp	byte ptr [kyb_act_flg],0
		jne	Term_in

		mov	ax,0901h
		int	90h

Term_in:	call	rs_getc
		jc	Term_end

		mov	ah,1Dh+40h
		mov	al,dl
		int	91h

		jmp	Term_in

Term_end:	ret

Term_in_out	endp

Key_Trap	proc	near

		mov	byte ptr [kyb_act_flg],1
		cmp	word ptr [key_code],0FFFFh
		jne	key_bak_get

key_in_loop:	mov	ax,0901h
		pushf
		call	cs:[key_vect]
		mov	[key_shift],bl

		cmp	bh,69h
		je	key_cnt_chk
		cmp	bh,5Bh
		je	key_cnt_chk

		cmp	byte ptr [term_flg],0
		jne	trap_term
		cmp	byte ptr [trap_flg],0
		jne	trap_term

		cmp	dh,0FFh
		jne	key_out_ret

end_of_chk:	cmp	byte ptr [bp+regs_ax],0
		je	key_in_loop

		mov	ah,0
		mov	bh,0FFh
		mov	bl,[key_shift]
		mov	dx,0FFFFh

key_out_ret:	mov	byte ptr [bp+regs_ax+1],ah
		mov	[bp+regs_bx],bx
		mov	[bp+regs_dx],dx
		mov	byte ptr [kyb_act_flg],0
		ret					; Ret Trap

key_bak_get:	mov	ah,0
		mov	dx,[key_code]
		mov	bx,[key_addr]
		mov	word ptr [key_code],0FFFFh
		jmp	key_out_ret

key_cnt_chk:	call	key_strip
		cmp	bh,69h
		je	trep_on_off

		mov	al,[term_flg]
		xor	al,1
		mov	[term_flg],al
		call	Cheng_Screen
		jmp	key_in_loop

trep_on_off:	mov	al,[trap_flg]
		xor	al,1
		mov	[trap_flg],al
		jmp	key_in_loop

trap_term:	cmp	dh,0FFh
		je	term_chk

		mov	ah,07h
		mov	al,[term_port]
		int	9Bh
		jmp	key_in_loop

term_chk:	call	rs_getc
		jc	end_of_chk

		mov	ah,1Dh+40h
		mov	al,dl
		int	91h

		cmp	byte ptr [trap_flg],0
		je	term_chk

		cmp	dl,0Ah			; Not Ret 0Ah Key Code
		je	term_chk

		sub	bh,bh
		mov	bl,[key_shift]

		sub	dh,dh
		cmp	dl,80h
		jnb	not_enc_key

		mov	bx,dx
		add	bx,dx
		add	bx,offset DGROUP:enc_key_tbl
		mov	bx,[bx]

not_enc_key:	mov	ah,0
		jmp	key_out_ret

Key_Trap	endp

Key_Bios	proc	near
		cmp	ah,09h
		je	trep_key
		cmp	ah,07h
		je	trep_key
		jmp	cs:[key_vect]

trep_key:	pusha
		push	ds
		push	es
		mov	bp,sp

		sti
		push	cs
		pop	ds

		cmp	ah,09
		je	trep_key_1

		mov	byte ptr [bp+regs_ax],1
		call	Key_Trap
		mov	[key_code],dx
		mov	[key_addr],bx
		cmp	dh,0FFh
		jne	trep_key_2
		mov	byte ptr [bp+regs_ax],0
		jmp	trep_key_2

trep_key_1:	call	Key_Trap

trep_key_2:	pop	es
		pop	ds
		popa
		iret

Key_Bios	endp

RS_irq_ent	proc	far
		mov	byte ptr cs:[rsget_flg],1
		cmp	ah,10h
		jne	RS_irq_1
		mov	ah,08h
		mov	al,cs:[term_port]
		mov	dl,02h
		int	9Bh
		mov	byte ptr cs:[rts_flg],1
RS_irq_1:	ret
RS_irq_ent	endp

RS_end		proc	near
		mov	ah,02h
		mov	al,[term_port]
		int	9Bh

		mov	ah,03h
		mov	al,[term_port]
		mov	di,offset DGROUP:RS_old_param
		int	9Bh

		mov	dx,[RS_status]
		cmp	dh,0
		jne	RS_end_1

		mov	ah,01h
		mov	al,[term_port]
		int	9Bh

		mov	ah,08h
		mov	dx,[RS_status]
		int	9Bh

RS_end_1:	push	ds
		lds	dx,es:[key_vect]
		mov	ax,2590h		; Set 90h int Vect
		int	21h
		pop	ds

		ret
RS_end		endp

                align   16

		db	256 dup (?)

Local_Stack	label	word
		public	End_of_Prog
End_of_Prog	label	word

Pal_Tbl		db	000h,000h,000h
		db	0B0h,000h,000h
		db	000h,0B0h,000h
		db	0B0h,0B0h,000h
		db	000h,000h,0B0h
		db	0B0h,000h,0B0h
		db	000h,0B0h,0B0h
		db	0B0h,0B0h,0B0h
		db	0B0h,0B0h,0B0h
		db	0F0h,000h,000h
		db	000h,0F0h,000h
		db	0F0h,0F0h,000h
		db	000h,000h,0F0h
		db	0F0h,000h,0F0h
		db	000h,0F0h,0F0h
		db	0F0h,0F0h,0F0h

CRT_Reg_Tbl	dw	0040h,0320h,0000h,0000h
		dw	035Fh,0000h,0010h,0000h
		dw	036Fh,009Ch,031Ch,009Ch
		dw	031Ch,0040h,0360h,0040h
		dw	0360h,0000h,009Ch,0000h
		dw	0050h,0000h,009Ch,0000h
		dw	0050h,004Ah,0001h,0000h
		dw	003Fh,0003h,0000h,0150h

Palet_init	proc	near
		sub	cl,cl
		mov	si,offset DGROUP:Pal_Tbl
Pal_init_1:	mov	al,cl
		mov	dx,0FD90h
		out	dx,al
		lodsb
		mov	dx,0FD92h
		out	dx,al
		lodsb
		mov	dx,0FD94h
		out	dx,al
		lodsb
		mov	dx,0FD96h
		out	dx,al
		inc	cl
		cmp	cl,16
		jb	Pal_init_1
		ret	
Palet_init	endp

;
; SI = Data Address
;
CRTC_set	proc	near
		sub	cl,cl
CRTC_set_1:	mov	al,cl
		mov	dx,0440h
		out	dx, al
		lodsw
		mov	dx,0442h
		out	dx, ax
		inc	cl
		cmp	cl,32
		jb	CRTC_set_1
		ret	
CRTC_set	endp

;
; AL = Val
;
CRTC_onoff	proc	near
		push	ax
		mov	al,01Ch
		mov	dx,0440h
		out	dx,al
		pop	ax
		mov	dx,0443h
		out	dx,al
		ret
CRTC_onoff	endp

;
; SI = Data Address
;
CRTC_init	proc	near
		mov	al,0
		call	CRTC_onoff
		call	CRTC_set
		mov	al,byte ptr [CRT_Reg_Tbl+01Ch*2]
		or	al,80h
		call	CRTC_onoff
		ret
CRTC_init	endp

;
; AX = Val
;
Video_init	proc	near
		push	ax
		mov	al,0
		mov	dx,0448h
		out	dx,al
		pop	ax
		mov	dx,044Ah
		out	dx,al

		mov	al,1
		mov	dx,0448h
		out	dx,al
		mov	al,ah
		mov	dx,044Ah
		out	dx,al
		ret
Video_init	endp

Screen_init	proc	near

		mov	al,0
		mov	dx,0FDA0h
		out	dx,al

		mov	si,offset DGROUP:CRT_Reg_Tbl
		call	CRTC_init

		mov	ax,0815h
		call	Video_init

		call	Palet_init
		call	_VDB_init
		call	_cflush

		mov	al,0Fh
		mov	dx,0FDA0h
		out	dx,al
		ret
Screen_init	endp

pf_key_tbl	db	01h,80h, 2,1Bh,'S'	;PF1
		db	02h,80h, 2,1Bh,'T'	;PF2
		db	03h,80h, 2,1Bh,'U'	;PF3
		db	04h,80h, 2,1Bh,'V'	;PF4
		db	05h,80h, 2,1Bh,'W'	;PF5
		db	06h,80h, 2,1Bh,'E'	;PF6
		db	07h,80h, 2,1Bh,'J'	;PF7
		db	08h,80h, 2,1Bh,'P'	;PF8
		db	09h,80h, 2,1Bh,'Q'	;PF9
		db	0ah,80h, 2,1Bh,'Z'	;PF10

		db	0bh,80h, 2,1Bh,'S'	;PF11
		db	1dh,80h, 2,1Bh,'T'	;PF12
		db	21h,80h, 2,1Bh,'U'	;PF13
		db	22h,80h, 2,1Bh,'V'	;PF14
		db	23h,80h, 2,1Bh,'W'	;PF15
		db	24h,80h, 2,1Bh,'E'	;PF16
		db	25h,80h, 2,1Bh,'J'	;PF17
		db	26h,80h, 2,1Bh,'P'	;PF18
		db	27h,80h, 2,1Bh,'Q'	;PF19
		db	28h,80h, 2,1Bh,'Z'	;PF20

		db	12h,00h, 2,1Bh,'P'	;[INS]
		db	7fh,00h, 2,1Bh,'V'	;[DEL]
		db	18h,80h, 0		;[半角/全角]
		db	1ch,80h, 0		;[かな漢字]
		db	0,0

Start_Msg	db	'FM-Towns FMR50 コンソ−ルシュミレ−タ v1.09'
		db	0Dh,0Ah
		db	'                   + マルチタ−ミナル v1.00'
		db	0Dh,0Ah
		db	'Programmed by K.MIYAZAKI'
		db	0Dh,0Ah
		db	'Asistant programmer N.YAMAZAKI'
		db	0Dh,0Ah
		db	0Dh,0Ah
		db	'FM-Towns OAK/2 フロントエンドプロセッサー v1.04a'
		db	0Dh,0Ah
		db	'Programmed by N.YAMAZAKI'
		db	0Dh,0Ah
		db	'Investigated by K.MIYAZAKI Thanks a lot.'
		db	0Dh,0Ah
		db	'$'

PF_key_init	proc	near
		mov	di,offset DGROUP:pf_key_tbl
		xor	cx,cx
key_set:	mov	dx,word ptr [di]
		cmp	dx,0
		je	key_st_e
		add	di,2
		mov	cl,[di]
		inc	di
		mov	ax,0E00h
		int	90h
		add	di,cx
		jmp	key_set

key_st_e:	mov	dx,offset DGROUP:Start_Msg
		mov	ah,09h
		int	21h
		ret
PF_key_init	endp

extrn		_path_top:near

Path_init	proc	near
		ASSUME DS: nothing, ES: DGROUP

		push	ds
		push	es

		mov	ax,ds
		mov	es,ax

		mov	ds,es:[EnvSeg]
		mov	si,0
		mov	di,offset DGROUP:_path_top

_Path_1:	cmp	byte ptr ds:[si],0
		je	_Path_4

		mov	ax,ds:[si]
		and	ax,0DFDFh
		cmp	ax,'A'*256+'P'
		jne	_Path_3
		mov	ax,ds:[si+2]
		and	ax,0DFDFh
		cmp	ax,'H'*256+'T'
		jne	_Path_3
		cmp	byte ptr ds:[si+4],'='
		jne	_Path_3

		add	si,5
_Path_2:	cmp	byte ptr ds:[si],0
		je	_Path_4
		cmp	di,offset DGROUP:_path_top+127
		jnb	_Path_4
		movsb
		jmp	_Path_2

_Path_3:	lodsb
		cmp	al,0
		jne	_Path_3
		jmp	_Path_1

_Path_4:	mov	byte ptr es:[di],0
		pop	es
		pop	ds
		ret
		ASSUME DS: DGROUP, ES: nothing

Path_init	endp

RS_init		proc	near
		mov	ah,09h
		mov	al,[term_port]
		int	9Bh
		mov	[RS_status],dx

		mov	ah,02h
		mov	al,[term_port]
		int	9Bh

		mov	ah,04h
		mov	al,[term_port]
		mov	di,offset DGROUP:RS_old_param
		int	9Bh

		mov	ah,04h
		mov	al,[term_port]
		mov	di,offset DGROUP:RS_param
		int	9Bh

		mov	bx,offset DGROUP:RS_buffer+15
		and	bl,0F0h
		mov	word ptr [bx],1024
		mov	[RS_buf_off],bx
		mov	[RS_buf_seg],ds
		mov	[RS_irq_off],offset DGROUP:RS_irq_ent
		mov	[RS_irq_seg],cs

		mov	ah,03h
		mov	al,[term_port]
		mov	di,offset DGROUP:RS_param
		int	9Bh

		mov	ah,01h
		mov	al,[term_port]
		int	9Bh

		mov	ax,3590h		; Get 90h Int Vect
		int	21h
		mov	word ptr cs:[key_vect],bx
		mov	word ptr cs:[key_vect+2],es

		mov	dx,offset DGROUP:Key_Bios
		mov	ax,2590h		; Set New Vect
		int	21h

		ret
RS_init		endp

_INST		ends
		end	entry
