;*******************************
; din : dump input tool
;        for FM-TOWNS
;    (C)1990.5.15 by Fumi
; #1 1990.7.2  Ver1.0 初版
; #2 1990.7.30 Ver1.1 機能追加
; #3 1990.9.3  掲載用に最終調整
; #4 1990.11.27 Ver1.2 バイト分割
;*******************************
	.386p
;
TRUE	equ	1
FALSE	equ	0
;
EGBSIZ	equ	2000	; EGB work area byte size(used  kanji font index after)
PBSIZ	equ	256	; public buffer size
;
VRAMW	equ	512	; VRAM byte width
VRAMH	equ	512	; VRAM hight
VRAMDW	equ	320	; VRAM display byte width
VRAMDH	equ	480	; VRAM display hight
VRAMSIZ	equ	VRAMH*VRAMW	; VRAM byte size (per page)
VRAMP	equ	9	; VRAM power number of two
;
MOUPATH	equ	16	; mouse pattern hight
MOUPATW	equ	8	; mouse pattern byte width
MOUPATN	equ	4	; mouse pattern species number
M$POINT	equ	0	; forefinger
M$OPEN	equ	1	; open hand
M$CATCH	equ	2	; catch hand
M$TCUP	equ	3	; tea cup
M$LEFT	equ	010000b	; mouse left button
M$RIGHT	equ	100000b	; mouse right button
;
stridx	struc		; 文字列索引構造体
 stradr	dd	?	; 文字列描画番地
 strofs	dw	?	; 文字列オフセット番地
stridx	ends
;
SBARX	equ	2/2	; system bar x byte position
SBARY	equ	2	; system bar y position
SBARW	equ	VRAMDW-2	; system bar byte width
SBARH	equ	48	; system bar hight
SBARADR	equ	VRAMW*SBARY+SBARX	; system bar VRAM address
;
ENDBX	equ	SBARX+2	; end button x byte position
ENDBY	equ	SBARY+4	; end button y position
ENDBW	equ	ENDBH/2	; end button byte width
ENDBH	equ	SBARH-8	; end button hight
ENDBADR	equ	VRAMW*ENDBY+ENDBX	; end button VRAM address
;
SMENW	equ	SM1W+SM2W+SM3W+SM4W	; system menu bar byte width
SMENH	equ	20	; system menu bar hight
SMENX	equ	ENDBX+ENDBW+2		; system menu bar x byte position
SMENY	equ	SBARY+SBARH-SMENH-4	; system menu bar y position
SMENADR	equ	VRAMW*SMENY+SMENX	; system menu bar VRAM address
SM1W	equ	10*4	; file menu byte width
SM2W	equ	6*4	; edit menu byte width
SM3W	equ	6*4	; 移動関係メニューのバイト幅
SM4W	equ	8*4	; その他メニューのバイト幅
ITEMH	equ	20	; menu item hight
;
PATHX	equ	SBARX+32	; read file path name x position
PATHY	equ	SBARY+SBARH+28	; read file path name y position
MEMSIZX	equ	SBARX+32	; text buffer amount x position
MEMSIZY	equ	SBARY+SBARH+56	; text buffer amount y position
USESIZX	equ	SBARX+32	; text buffer used amount x position
USESIZY	equ	SBARY+SBARH+76	; text buffer used amount y position
;
PREVX	equ	292/2	; previous page button
PREVY	equ	100
PREVW	equ	40/2
PREVH	equ	20
PREVADR	equ	VRAMW*PREVY+PREVX
NEXTX	equ	292/2	; next page button
NEXTY	equ	120
NEXTW	equ	40/2
NEXTH	equ	20
NEXTADR	equ	VRAMW*NEXTY+NEXTX
;
INSBX	equ	340/2	; insert button
INSBY	equ	96
INSBW	equ	40/2
INSBH	equ	20
INSBADR	equ	VRAMW*INSBY+INSBX
BSX	equ	340/2	; backspace button
BSY	equ	120
BSW	equ	40/2
BSH	equ	20
BSADR	equ	VRAMW*BSY+BSX
DELX	equ	340/2	; delete button
DELY	equ	140
DELW	equ	40/2
DELH	equ	20
DELADR	equ	VRAMW*DELY+DELX
;
TENKX	equ	388/2		; ten key area
TENKY	equ	SBARY+SBARH+10
TENKW	equ	20*4/2
TENKH	equ	20*5
TENKADR	equ	VRAMW*TENKY+TENKX
KEYBW	equ	20/2		; ten key button width
KEYBH	equ	20
;
ANKBLN	equ	4		; ANK input button line hight
ANKBX	equ	ANKX		; ANK charactor input button area
ANKBY	equ	SBARY+SBARH+42
ANKBW	equ	16*4
ANKBH	equ	ANKBLN*16
ANKBADR	equ	VRAMW*ANKBY+ANKBX
;
ROLDX	equ	ANKBX+ANKBW+2-40/2	; ANK input page roll down button
ROLDY	equ	ANKBY-4-20
ROLDW	equ	20/2
ROLDH	equ	20
ROLDADR	equ	VRAMW*ROLDY+ROLDX
;
ROLUX	equ	ANKBX+ANKBW+2-20/2	; ANK input page roll up button
ROLUY	equ	ANKBY-4-20
ROLUW	equ	20/2
ROLUH	equ	20
ROLUADR	equ	VRAMW*ROLUY+ROLUX
;
PAGX	equ	8*4		; page VRAM x position
PAGY	equ	192		; page VRAM y position
PAGW	equ	(16*3-1)*4+4	; page box byte width
PAGH	equ	16*16+8		; page box hight
PAGADR	equ	VRAMW*PAGY+PAGX	; page VRAM address
;
HADRX	equ	4		; high address x position
HADRY	equ	PAGY		; high address y position
HADRW	equ	6*4		; high address byte width
HADRADR	equ	VRAMW*HADRY+HADRX	; high address VRAM address
LADRX	equ	PAGX		; low address x position
LADRY	equ	PAGY-16-8	; low address y position
LADRW	equ	(16*3-1)*4	; low address byte width
LADRADR	equ	VRAMW*LADRY+LADRX	; low address VRAM address
;
LSUMX	equ	PAGX+16*3*4	; line sum area x position
LSUMY	equ	PAGY		; line sum area y position
LSUMADR	equ	LSUMY*VRAMW+LSUMX
CSUMX	equ	PAGX		; column sum area x position
CSUMY	equ	PAGY+16*16+8	; column sum area y position
CSUMW	equ	(16*3-1)*4	; column sum area byte width
CSUMADR	equ	CSUMY*VRAMW+CSUMX
TSUMADR	equ	CSUMY*VRAMW+LSUMX
;
ANKX	equ	LSUMX+5*4	; ANK charactor dispaly area
ANKY	equ	PAGY
ANKW	equ	16*4
ANKH	equ	16*16
ANKADR	equ	VRAMW*ANKY+ANKX
;
DSPCN	equ	3			; コード表示種数
CODESPW	equ	ANKW+4-20/2*2		; 表示文字種名表示枠データ
CODESPH	equ	20
CODESPADR	equ	VRAMW*PREVCY+ANKX-2
PREVCX	equ	ANKBX+ANKBW+2-40/2	; code spacies roll down button
PREVCY	equ	CSUMY-2
PREVCW	equ	20/2
PREVCH	equ	20
PREVCADR	equ	VRAMW*PREVCY+PREVCX
NEXTCX	equ	ANKBX+ANKBW+2-20/2	; code species page roll up button
NEXTCY	equ	CSUMY-2
NEXTCW	equ	20/2
NEXTCH	equ	20
NEXTCADR	equ	VRAMW*NEXTCY+NEXTCX
;
PROFX	equ	ENDBX+ENDBW+2+17*4	; profile trigger area x position
PROFY	equ	SBARY+4			; profile trigger area y position
PROFW	equ	6*4			; profile trigger area byte width
PROFH	equ	CHRH			; profile trigger area hight
;
WBARH	equ	20	; window bar hight
winstr	struc		; window structure
 winx	dw	?	; window x position
 winy	dw	?	; window y position
 winw	dw	?	; window byte width
 winh	dw	?	; window hight
 winttl	dw	?	; window title pointer
winstr	ends
wsidx	struc		; window string index structure
 wsposx	db	?	; position x (unit 2 pixcel)
 wsposy	db	?	; position y (unit 2 pixcel)
 wsofs	dw	?	; string data offset
wsidx	ends
wbstr	struc		; window box structure
wbposx	db	?	; position x (unit 2 pixcel)
wbposy	db	?	; position y (unit 2 pixcel)
wbwidth	db	?	; width (unit 2 pixcel)
wbhight	db	?	; hight (unit 1 pixcel)
wbstr	ends
;
ANKOFS	equ	0003D800h	; 8*16 ANK font data offset address
CHRH	equ	16		; charactor pixcel hight
;
C$INT	equ	0	; Intensity color code
C$DARK	equ	1	; Dark color code
C$PANEL	equ	2	; Panel color code
C$STR	equ	3	; String color code
C$SEL	equ	1000b	; select bit
C$CUR	equ	0100b	; cursor bit
;
C$WFRL	equ	1	; window frame low
;C$PANEL equ 2
;C$STR   equ 3
C$MOUF	equ	4	; mouse foreground
C$MOUB	equ	5	; mouse background
C$WBAR	equ	6	; window title bar
C$WFRH	equ	7	; window frame high
C$BUTL	equ	C$STR	; button frame low
C$BUTH	equ	C$SEL+C$STR	; button frame high
C$ERR	equ	C$SEL+C$MOUF	; error window frame
C$WARN	equ	C$SEL+C$MOUB	; warning window frame
;
C$SELB	equ	10001000b
C$CURD	equ	01000100010001000100010001000100b
C$PANELB	equ	22h
C$PANELD	equ	22222222h
C$WFRLD	equ	11111111h
C$WFRHD	equ	77777777h
C$WBARD	equ	66666666h
C$WBLW	equ	C$WFRH+(C$WBAR shl 4)+(C$WBAR shl 8)+(C$WBAR shl 12)
C$WBRW	equ	C$WBAR+(C$WBAR shl 4)+(C$WBAR shl 8)+(C$WFRL shl 12)
C$WFRSW	equ	C$WFRH+(C$WBAR shl 4)+(C$WBAR shl 8)+(C$WFRL shl 12)
C$ERRD	equ	0CCCCCCCCh
C$WARND	equ	0DDDDDDDDh
;
EVTNUM	equ	8	; event buffer item number
EBSIZ	equ	EVTNUM*size evtrec	; event buffer size
evtrec	struc		; event record structure
evttyp	db	?	; event type
evtdat	db	?	; event data
evttim	dw	?	; event time
evtx	dw	?	; x position
evty	dw	?	; y position
evtrec	ends
EvtNone	equ	0	; event none
EvtUpdate	equ	1	; window update event
EvtClose	equ	6	; window close event
M$LDown	equ	10b	; mouse left button down
M$LUp	equ	11b	; mouse left button up
M$RDown	equ	100b	; mouse right button down
M$RUp	equ	101b	; mouse right button up
;
DBDEVX	equ	4	; device string x position
DBDEVY	equ	WBARH+4	; device string y position
MAXDRV	equ	18	; maximum drive number
drvstr	struc		; dirve data structure
drvnam	db	3 dup(?)	; drive name(A:\,･･･)
drvpath	db	64 dup(?)	; path name(ASCIZ)
drvstr	ends
;
WBUTW	equ	20		; window button byte width
WBUTH	equ	CHRH+4		; window button hight
DBDIRX	equ	4	; disk browser directory x position
DBDIRY	equ	WBARH+24	; y position
DBBUTX	equ	8/2	; disk browser button area x position
DBBUTY	equ	WBARH+42	; y position
DBBUTW	equ	WBUTW	; disk browser button area width
DBBUTH	equ	WBUTH	; hight
DBHSNX	equ	32*4+2	; total slot number
DBHSNY	equ	WBARH+44
DBTSNX	equ	36*4+2	; total slot number
DBTSNY	equ	WBARH+44
DLLNUM	equ	10	; directory list line number
DLCNUM	equ	3	; directory list column number in wide mode
DBFILX	equ	8/2		; disk broeser file area x position
DBFILY	equ	WBARH+62	; y position
DBFILW	equ	39*4		; width
DBFILH	equ	DLLNUM*CHRH+8	; hight
MAXDSN	equ	256	; maximum directory slot number(dspdp depend on)
fildat	struc			; file data structure
fattr	db	?		; file attibute
ftime	dw	?		; file time
fdate	dw	?		; file date
fsize	dd	?		; file byte size
fname	db	13 dup(?)	; file name(ASCIZ)
fildat	ends
;
FBOXX	equ	6		; file name input box x position in window
FBOXY	equ	DBFILY+DBFILH+4	; file name input box y position in window
FBOXW	equ	12*4		; file name input box byte width
FBOXH	equ	CHRH
DELSBX	equ	60		; delete buttons x position
DELSBY	equ	DBFILY+DBFILH+2	; delete buttons y position
DELSBW	equ	WBUTW
DELSBH	equ	WBUTH
EXECX	equ	128		; execute button x position in window
EXECY	equ	DBFILY+DBFILH+32; execute button y position in window
EXECW	equ	WBUTW		; execute button byte width
EXECH	equ	WBUTH		; execute button hight
KBX	equ	4		; keyboard x position in window
KBY	equ	DBFILY+DBFILH+24; keyboard y position in window
KBBUTW	equ	8		; keyboard button byte width (fixed)
KBBUTH	equ	CHRH+1		; keyboard button hight
KBBUTCN	equ	13		; keyboard button column number
KBW	equ	KBBUTW*KBBUTCN	; keyboard area byte width
KBH	equ	KBBUTH*3	; keyboard area hight
;
JHINX	equ	24		; jump dialog box hex input area
JHINY	equ	WBARH+8
JHINW	equ	6*4
JHINH	equ	16
JHINADR	equ	JHINY*VRAMW+JHINX
JEXEX	equ	52		; jump dialog box execute button
JEXEY	equ	WBARH+6
JEXEW	equ	20
JEXEH	equ	20
JEXEADR	equ	JEXEY*VRAMW+JEXEX
;
boxstr	struc
boxadr	dd	?	; box VRAM address
boxw	dw	?	; box byte width
boxh	dw	?	; box picel hight
boxstr	ends
;
butstr	struc		; rectangle position structure
x0	dw	?
y0	dw	?
x1	dw	?
y1	dw	?
pofs	dw	?	; procedure offset
butstr	ends
;
digstr	struc
oldigit	db	10	; old date/time digit
digadr	dd	?	; digit display address
digstr	ends
;
pwadr	struc		; farword structure
pwofs	dd	?	; offset
pwsel	dw	?	; selector
pwadr	ends
;
E$MemFul	equ	0	; memory full error code
E$PNNF		equ	1	; path name not found
E$Open		equ	2	; can't open
E$Read		equ	3	; read error
E$Write		equ	4	; write error
E$Create	equ	5	; create error
E$Update	equ	6	; can't update (no read path)
E$Full		equ	7	; media full
E$BFNam		equ	8	; bad file name
E$IllAdr	equ	9	; illegal address
E$Child		equ	10	; 子プロセス異常終了

data	segment	use32 rw
;*******************************
; variables
;*******************************
nvsync	pwadr	<>	; VSYNC interrupt vector in 386 native mode
rvsync	dd	?	; VSYNC interrupt vector in real mode
simr	db	?	; slave IMR
;
mctype	db	M$POINT	; mouse cursor type
padreg	dw	?	; pad input register
moucur	dw	?,?	; mouse cursor center position
	dw	moupat	; mouse cursor pattern address
bakmx	dw	0	; mouse background pattern x position
bakmy	dw	VRAMH	; mouse background pattern y position
newmx	dw	VRAMDW/2	; new mouse cursor x position
newmy	dw	VRAMH+VRAMDH/2	; new mouse cursor y position
moustat	db	00110000b	; mouse button state
redate	db	1	; display date flag
mincnt	dw	60*60	; minute counter (unit 1/60 second)
mouflg	db	TRUE	; mouse cursor display flag
;
ebcount	db	0	; event buffer item number counter
ebhead	dw	0	; event buffer head offset pointer
ebtail	dw	0	; event buffer tail offset pointer
;
curdrv	db	?	; current drive(base 0)
drvnum	db	0	; drive total number
dbflg	db	FALSE	; directory buffer effect flag
dbwide	db	TRUE	; directory browser wide display flag
headfn	db	0	; page head file number
dbfnum	db	DLLNUM*DLCNUM	; disk browser display file number
dsnum	db	?	; directory slot total number
;
abptop	db	20h	; ANK input button page top code
curitm	db	?	; current menu item number
curmenu	dd	?	; current menu data address
dwntime	dw	?	; left button down time
;
winadr	dd	?	; current window base VRAM address
;
bufadr	dd	?	; buffer address
bufsiz	dd	?	; buffer size
datsiz	dd	0	; data size
datend	dd	?	; data end address
datchg	db	FALSE	; data change flag
nibpos	db	0	; nible position(0=high,1=low)
curptr	label	dword	; current cursor byte pointer
curb	db	0	; current byte in page
curpag	dw	0	; current page number
	db	0	; dummy highest byte
;
sfnptr	db	0	; save file name input box cursor pointer(0-11)
sfnsiz	db	0	; save file name size(1-12)
;
jmpadr	dd	0	; jump address
repcode	db	0	; 反復挿入/上書きコード
insbyte	dd	16	; 反復挿入バイト数
ovwbyte	dd	16	; 反復上書バイト数
delbyte	dd	16	; 部分削除バイト数
searlen	db	0	; 探索文字列バイト長
lastep	dd	?	; 最終変更位置
lastmp	dd	-1	; 移動開始位置
bakptr	dd	?	; ポインタ保存用領域(search)
;
codesp	db	0	; コード種
dspofs	dd	offset dspnk	; 文字列表示ルーチンオフセット番地 for dspag
clkflg	db	TRUE	; クリック音フラグ
shifts	db	00b	; キーシフト状態
;*******************************
; constants
;*******************************
tbios	dw	0110h	; TOWNS BIOS selector
vram2	dw	0120h	; TOWNS VRAM (two page mode) selector
fntsel	dw	0138h	; KANJI ROM selector
psp	dw	0004h	; PSP selector
;
paldat0N	equ	10
paldat0	db	C$PANEL,0B0h,0B0h,0B0h	; Panel
	db	C$STR,00h,00h,00h	; String
	db	C$INT,0F0h,0F0h,0F0h	; Intensity
	db	C$DARK,00h,00h,00h	; Dark
	db	C$SEL+C$PANEL,0A0h,00h,00h	; selected Panel
	db	C$SEL+C$STR,0F0h,0F0h,0F0h	; selected String
	db	C$SEL+C$INT,00h,00h,00h		; selected Intensity
	db	C$SEL+C$DARK,0F0h,0F0h,0F0h	; selected Dark
	db	C$CUR+C$PANEL,00h,00h,90h	; cursor panel
	db	C$CUR+C$STR,0F0h,0F0h,0F0h	; cursor string
;
paldat1N	equ	15
paldat1	db	C$WFRL,00h,00h,00h	; window frame low
	db	C$PANEL,0C0h,0C0h,0C0h	; Panel
	db	C$STR,00h,00h,00h	; String
	db	C$MOUF,0F0h,0F0h,0F0h	; mouse foreground color
	db	C$MOUB,00h,00h,00h	; mouse background color/menu frame
	db	C$WBAR,00h,00h,0C0h	; window title bar
	db	C$WFRH,80h,80h,0F0h	; window frame high
	db	C$SEL,0A0h,00h,00h	; selected
	db	C$SEL+C$WFRL,0A0h,00h,00h	; selected window frame low
	db	C$SEL+C$PANEL,0A0h,00h,00h	; selected panel
	db	C$SEL+C$STR,0F0h,0F0h,0F0h	; selected string
	db	C$ERR,00h,0F0h,00h		; error window frame
	db	C$WARN,00h,0F0h,0F0h		; warning window frame
	db	C$SEL+C$WBAR,0A0h,00h,00h	; selected window bar
	db	C$SEL+C$WFRH,0A0h,00h,00h	; selected window frame high
;
moupato	dw	0,0	; 人差し指
	dw	0001111111111111b,1110000000000000b
	dw	0000111111111111b,1001000000000000b
	dw	0000010000001111b,1000101111110000b
	dw	1000000000000111b,0100010010101000b
	dw	1100000000000011b,0010001001000100b
	dw	1110000000000011b,0001000100000100b
	dw	1111000000000011b,0000100000000100b
	dw	1110000000000011b,0001010000000100b
	dw	1110000000000011b,0001010000000100b
	dw	1110000000000011b,0001001000000100b
	dw	1110000000000000b,0001000000000011b
	dw	1111000000000000b,0000100000000111b
	dw	1111100000000000b,0000011110001111b
	dw	1111111110000001b,0000000001011110b
	dw	1111111111000011b,0000000000111100b
	dw	1111111111000111b,0000000000111000b
	DW	2,2	; 開いた手
	dw	1001001111111111b,0110110000000000b
	dw	0000000000111111b,1001001111000000b
	dw	1000000000011111b,0100100100100000b
	dw	0000000000001111b,1010010010010000b
	dw	0000000000000111b,1001001001001000b
	dw	0000000000000011b,1000100100000100b
	dw	1000000000000011b,0100010000000100b
	dw	1100000000000011b,0010000000000100b
	dw	1110000000000011b,0001000000000100b
	dw	1110000000000011b,0001000000000100b
	dw	1000000000000000b,0111000000000011b
	dw	0000000000000000b,1000000000000111b
	dw	0000000000000000b,1111100000001111b
	dw	1111100000000001b,0000011111011110b
	dw	1111111111000011b,0000000000111100b
	dw	1111111111000111b,0000000000111000b
	DW	4,4	; 握った手
	dw	1111111111111111b,0000000000000000b
	dw	1111100100111111b,0000011011000000b
	dw	1110000000011111b,0001100100100000b
	dw	1100000000001111b,0010010010010000b
	dw	1000000000001111b,0101001000010000b
	dw	1000000000000111b,0100100000001000b
	dw	0000000000000111b,1010000000001000b
	dw	0000000000000111b,1001000000001000b
	dw	0000000000000111b,1001100000001000b
	dw	1000000000000000b,0100000000000111b
	dw	1100000000000000b,0010000000000111b
	dw	1110000000000000b,0001110000001111b
	dw	1111110000000001b,0000001110011110b
	dw	1111111110000011b,0000000001111100b
	dw	1111111100000111b,0000000011111000b
	dw	1111111111001111b,0000000000110000b
	DW	8,8	; 湯のみ
	dw	1110110110111111b,0001001001000000b
	dw	1101101101111111b,0010010010000000b
	dw	1110110110111111b,0001001001000000b
	dw	1101101101111111b,0010010010000000b
	dw	1111111111111111b,0000000000000000b
	dw	0000000000000110b,1111111111111001b
	dw	0000000000000000b,1000001000001111b
	dw	0000000000000000b,1100001000000011b
	dw	0000000000000000b,1010000111000011b
	dw	0000000000000000b,1110000000100011b
	dw	0000000000000000b,1010000000010011b
	dw	0000000000000000b,1110000000010011b
	dw	0000000000000000b,1001000000010011b
	dw	0000000000000000b,1111000000100011b
	dw	0000000000000000b,1001000000100111b
	dw	1000000000000110b,0111111111111001b
;
qrpat	db	00010000b	; 0=上矢印
	db	00111000b
	db	01111100b
	db	11111110b
	db	11111110b	; 1=下矢印
	db	01111100b
	db	00111000b
	db	00010000b
;
fntdat	db	0,2,1
	db	0,2,1
	db	4,6,8
	db	5,7,9
	db	10,12,14
	db	11,13,15
	db	16,18,20
	db	17,19,21
	db	22,24,26
	db	23,25,27
	db	28,30,29
	db	3,3,3
fntdatN	equ	12
;
decdat	dd	10000000
	dd	1000000
	dd	100000
	dd	10000
	dd	1000
	dd	100
	dd	10
	dd	1
;
hextbl	db	"0123456789ABCDEF"
	db	"0123456789*/+-=."
	db	"ﾐﾓﾈﾙﾏﾉﾘﾅﾆﾗﾔﾕﾖﾜｾﾚ"
hextblN	equ	16*3
;
allfile	db	"*.*",0
;
tktbl	db	0Ah,0Bh,0Ch,0Dh	; ＡＢＣＤ
	db	07h,08h,09h,0Eh	; ７８９Ｅ
	db	04h,05h,06h,0Fh	; ４５６Ｆ
	db	01h,02h,03h,91	; １２３↑
	db	00h,90,89,92	; ０←→↓
;
kbstr	db	"ABCDEFGHIJKLM"
	db	"NOPQRSTUVWXYZ"
	db	"0123456789._$",0
;
tmpfn	db	"DIN$TEMP"		; 一時ファイル名
tmpext	db	".COM"			; ＣＯＭ自己展開
	db	".EXE"			; ＥＸＥ自己展開
	db	".LZH"			; ＬＨＡＲＣ
	db	".LZS"			; ＬＡＲＣ
	db	".ARC"			; ＰＫＸＡＲＣ
selfcom	db	12,"DIN$TEMP.COM"	; ＣＯＭ自己展開
selfexe	db	12,"DIN$TEMP.EXE"	; ＥＸＥ自己展開
lharc	db	09,"lharc.exe"		; ＬＨＡＲＣ
larc	db	08,"larc.exe"		; ＬＡＲＣ
pkxarc	db	10,"pkxarc.com"		; ＰＫＸＡＲＣ
cmdln1	db	0,0Dh			; 自己展開
cmdln2	db	10,"e DIN$TEMP",0Dh	; ＬＨＡＲＣ,ＬＡＲＣ
cmdln3	db	11,"-e DIN$TEMP",0Dh	; ＰＫＸＡＲＣ
cmdlns	dw	selfcom,cmdln1		; コマンドライン索引
	dw	selfexe,cmdln1
	dw	lharc,cmdln2
	dw	larc,cmdln2
	dw	pkxarc,cmdln3
parblk	pwadr	<0,0>				; 環境セグメント番地
	pwadr	<,0014h>			; コマンドライン番地
;
endbut	boxstr	<ENDBADR,ENDBW,ENDBH>	; end button outer frame
iniboxN	equ	15
inibox	boxstr	<SBARADR,SBARW,SBARH>	; system bar
	boxstr	<SMENADR,SMENW,SMENH>	; system menu bar
	boxstr	<PAGADR-VRAMW*4-2,PAGW,PAGH>	; page display box
	boxstr	<ANKADR-VRAMW*4-4/2,ANKW+8/2,ANKH+8>	; ANK display box
	boxstr	<PREVADR,PREVW,PREVH>	; previous page button
	boxstr	<NEXTADR,NEXTW,NEXTH>	; next page button
	boxstr	<INSBADR,INSBW,INSBH>	; insert button
	boxstr	<BSADR,BSW,BSH>		; backspace button
	boxstr	<DELADR,DELW,DELH>	; delete button
	boxstr	<ANKBADR-VRAMW*4-4/2,ANKBW+8/2,ANKBH+8>	; ANK button
	boxstr	<ROLDADR,ROLDW,ROLDH>	; roll down button
	boxstr	<ROLUADR,ROLUW,ROLUH>	; roll up button
	boxstr	<CODESPADR,CODESPW,CODESPH>	; display code species box
	boxstr	<PREVCADR,PREVCW,PREVCH>	; down code button
	boxstr	<NEXTCADR,NEXTCW,NEXTCH>	; up code button
;
buttbl0	db	20	; main button data table. include complex button
	butstr	<TENKX,TENKY,TENKX+TENKW-1,TENKY+TENKH-1,tenkey>; ten key
	butstr	<ANKBX,ANKBY,ANKBX+ANKBW-1,ANKBY+ANKBH-1,ankin>	; ANK input box
	butstr	<NEXTX,NEXTY,NEXTX+NEXTW-1,NEXTY+NEXTH-1,nextp>	; next page
	butstr	<PREVX,PREVY,PREVX+PREVW-1,PREVY+PREVH-1,prevp>	; previous page
	butstr	<INSBX,INSBY,INSBX+INSBW-1,INSBY+INSBH-1,insnul>; insert
	butstr	<BSX,BSY,BSX+BSW-1,BSY+BSH-1,bs>		; backspace
	butstr	<DELX,DELY,DELX+DELW-1,DELY+DELH-1,del>		; delete
sysbar	butstr	<SMENX,SMENY,SMENX+SMENW-1,SMENY+SMENH-1,smenu>	; system bar
	butstr	<ROLDX,ROLDY,ROLDX+ROLDW-1,ROLDY+ROLDH-1,rold>	; roll down
	butstr	<ROLUX,ROLUY,ROLUX+ROLUW-1,ROLUY+ROLUH-1,rolu>	; roll up
	butstr	<PREVCX,PREVCY,PREVCX+PREVCW-1,PREVCY+PREVCH-1,prevcs>
	butstr	<NEXTCX,NEXTCY,NEXTCX+NEXTCW-1,NEXTCY+PREVCH-1,nextcs>
	butstr	<PAGX,PAGY,PAGX+(16*3-1)*4-1,PAGY+16*16-1,gohex>; page box
	butstr	<LSUMX,LSUMY,LSUMX+2*4-1,LSUMY+16*16-1,goln>	; line sum
	butstr	<CSUMX,CSUMY,CSUMX+CSUMW-1,CSUMY+16-1,gocol>	; column sum
	butstr	<ANKX,ANKY,ANKX+ANKW-1,ANKY+ANKH-1,goank>	; ank box
	butstr	<HADRX,HADRY,HADRX+HADRW-1,HADRY+16*16-1,goln>	; high address
	butstr	<LADRX,LADRY,LADRX+LADRW-1,LADRY+16-1,gocol>	; low address
	butstr	<ENDBX,ENDBY,ENDBX+ENDBW-1,ENDBY+ENDBH-1,exit>	; end button
	butstr	<PROFX,PROFY,PROFX+PROFW-1,PROFY+PROFH-1,prof>	; profile
;
sysbut	dw	SMENX,SMENX+SM1W-1,menu1		; file menu
	dw	SMENX+SM1W,SMENX+SM1W+SM2W-1,menu2	; eidt menu
	dw	SMENX+SM1W+SM2W,SMENX+SMENW-SM4W-1,menu3	; 移動メニュー
	dw	SMENX+SMENW-SM4W,SMENX+SMENW-1,menu4	; その他メニュー
;
menu1	dw	SMENX,SMENY+20,SMENX+10*4-1,SMENY+20+5*ITEMH-1
	db	5
	dw	menu11,load	; 新規呼出
	dw	menu12,insert	; 挿入呼出
	dw	menu13,reload	; 再呼出
	dw	menu14,save	; 新規保存
	dw	menu15,update	; 再保存
menu2	dw	SMENX+SM1W,SMENY+20,SMENX+SM1W+12*4-1,SMENY+20+5*ITEMH-1
	db	5
	dw	menu21,repin	; 反復挿入
	dw	menu22,repov	; 反復上書
	dw	menu23,devbyte	; バイト分割
	dw	menu24,ptdel	; 部分削除
	dw	menu25,alldel	; 全文削除
menu3	dw	SMENX+SM1W+SM2W,SMENY+20
	dw	SMENX+SM1W+SM2W+14*4-1,SMENY+20+6*ITEMH-1
	db	6
	dw	menu31,gohead	; ファイル先頭
	dw	menu32,gotail	; ファイル末尾
	dw	menu33,jump	; ジャンプ
	dw	menu34,search	; 検索
	dw	menu35,golaste	; 最終変更位置
	dw	menu36,golastm	; 移動前の位置
menu4	dw	SMENX+SM1W+SM2W+SM3W,SMENY+20
	dw	SMENX+SM1W+SM2W+SM3W+12*4-1,SMENY+20+2*ITEMH-1
	db	2
	dw	menu41,melt	; 解凍
	dw	menu42,swiclk	; クリック音
;
window1	winstr	<8*4,80,41*4,256,w1title>	; load
window2	winstr	<8*4,80,41*4,256,w2title>	; insert
window3	winstr	<8*4,80,41*4,332,w3title>	; save
window4	winstr	<24*4,80,19*4,56,w4title>	; jump
window5	winstr	<25*4,100,24*4,152,w5title>	; profile
window6	winstr	<16*4,60,20*4,76,w6title>	; repin
window7	winstr	<30*4,70,12*4,124,w7title>	; melt
window8	winstr	<16*4,70,20*4,76,w8title>	; repov
window9	winstr	<16*4,80,25*4,56,w9title>	; ptdel
windowA	winstr	<25*4,100,31*4,98,wAtitle>	; search
;
inistr	stridx	<ENDBX+ENDBW+2+(SBARY+4)*VRAMW,titstr>
	stridx	<SMENX+4+(SMENY+2)*VRAMW,menstr>
	stridx	<SBARX+SBARW-17*4-2+(SBARY+4)*VRAMW,datestr>
	stridx	<PATHX-7*4+PATHY*VRAMW,pathstr>
	stridx	<MEMSIZX-7*4+MEMSIZY*VRAMW,memtstr>
	stridx	<MEMSIZX+8*4+2+MEMSIZY*VRAMW,bytestr>
	stridx	<USESIZX-7*4+USESIZY*VRAMW,usetstr>
	stridx	<USESIZX+8*4+2+USESIZY*VRAMW,bytestr>
	stridx	<PREVX+2+(PREVY+2)*VRAMW,prevstr>
	stridx	<NEXTX+2+(NEXTY+2)*VRAMW,nextstr>
	stridx	<INSBX+2+(INSBY+2)*VRAMW,insbstr>
	stridx	<BSX+2+(BSY+2)*VRAMW,bsstr>
	stridx	<DELX+2+(DELY+2)*VRAMW,delbstr>
	stridx	<CODESPADR+6+VRAMW*2,nkstr>
	stridx	<0,0>
;
titstr	db	30,"ダンプ入力ツール ＤＩＮ Ver1.2"
menstr	db	28,"ファイル  編集  移動  その他"
datestr	db	17,"月   日   時   分"
pathstr	db	13,"パス名 <新規>"
newpathL	equ	6
memtstr	db	6,"作業域"
bytestr	db	6,"バイト"
usetstr	db	6,"使用量"
prevstr	db	4,"前頁"
nextstr	db	4,"次頁"
insbstr	db	4,"挿入"
bsstr	db	4,"後退"
delbstr	db	4,"削除"
;
tenkstr	db	"ＡＢＣＤ７８９Ｅ４５６Ｆ１２３↑０←→↓"
menu11	dd	VRAMSIZ+SMENX+4+(SMENY+22)*VRAMW
	db	8,"新規呼出"
menu12	dd	VRAMSIZ+SMENX+4+(SMENY+22+ITEMH)*VRAMW
	db	8,"挿入呼出"
menu13	dd	VRAMSIZ+SMENX+4+(SMENY+22+2*ITEMH)*VRAMW
	db	6,"再呼出"
menu14	dd	VRAMSIZ+SMENX+4+(SMENY+22+3*ITEMH)*VRAMW
	db	8,"新規保存"
menu15	dd	VRAMSIZ+SMENX+4+(SMENY+22+4*ITEMH)*VRAMW
	db	6,"再保存"
menu21	dd	VRAMSIZ+SMENX+SM1W+4+(SMENY+22)*VRAMW
	db	8,"反復挿入"
menu22	dd	VRAMSIZ+SMENX+SM1W+4+(SMENY+22+ITEMH)*VRAMW
	db	8,"反復上書"
menu23	dd	VRAMSIZ+SMENX+SM1W+4+(SMENY+22+2*ITEMH)*VRAMW
	db	10,"バイト分割"
menu24	dd	VRAMSIZ+SMENX+SM1W+4+(SMENY+22+3*ITEMH)*VRAMW
	db	8,"部分削除"
menu25	dd	VRAMSIZ+SMENX+SM1W+4+(SMENY+22+4*ITEMH)*VRAMW
	db	8,"全文削除"
menu31	dd	VRAMSIZ+SMENX+SM1W+SM2W+4+(SMENY+22)*VRAMW
	db	12,"ファイル先頭"
menu32	dd	VRAMSIZ+SMENX+SM1W+SM2W+4+(SMENY+22+ITEMH)*VRAMW
	db	12,"ファイル末尾"
menu33	dd	VRAMSIZ+SMENX+SM1W+SM2W+4+(SMENY+22+2*ITEMH)*VRAMW
	db	08,"ジャンプ"
menu34	dd	VRAMSIZ+SMENX+SM1W+SM2W+4+(SMENY+22+3*ITEMH)*VRAMW
	db	10,"文字列検索"
menu35	dd	VRAMSIZ+SMENX+SM1W+SM2W+4+(SMENY+22+4*ITEMH)*VRAMW
	db	12,"最終変更位置"
menu36	dd	VRAMSIZ+SMENX+SM1W+SM2W+4+(SMENY+22+5*ITEMH)*VRAMW
	db	08,"移動取消"
menu41	dd	VRAMSIZ+SMENX+SM1W+SM2W+SM3W+4+(SMENY+22)*VRAMW
	db	04,"解凍"
menu42	dd	VRAMSIZ+SMENX+SM1W+SM2W+SM3W+4+(SMENY+22+ITEMH)*VRAMW
	db	10,"クリック音"
w1title	db	10," 新規呼出 "		; window 1 titile
w2title	db	10," 挿入呼出 "		; window 2 titile
w3title	db	10," 新規保存 "		; window 3 titile
w4title	db	10," ジャンプ "		; window 4 titile
w5title	db	6," 著者 "		; window 5 titile
w6title	db	6," 挿入 "		; window 6 titile
w7title	db	6," 解凍 "		; window 7 titile
w8title	db	6," 上書 "		; window 8 titile
w9title	db	6," 削除 "		; window 9 titile
wAtitle	db	6," 検索 "		; window A titile
dbbut	db	"前頁 次頁 表示"	; disk browser buttons
dbbutL	equ	14
delstr	db	9,"後退 削除"		; file name keyboard edit buttons
execstr	db	4,"実行"		; execute string
jumpstr	db	4,"番地"		; jump window string
;
cssidx	dw	nkstr
	dd	offset dspnk	; ＪＩＳ漢字表示
	dw	sjstr
	dd	offset dspsj	; シフトＪＩＳ文字列表示
	dw	alstr
	dd	offset dspal	; ＡＮＫ文字列表示
nkstr	db	9,"8単位符号"
sjstr	db	9,"シフトJIS"
alstr	db	9," ANK文字 "
;
profM	dw	profM1,profM2,profM3,profM4,profM5,profM6,0
profM1	db	18,"作品番号２ DIN.EXP"
profM2	db	22,"Copyright 1990 by Fumi"
profM3	db	18,"〒838 福岡県朝倉郡"
profM4	db	15,"三輪町新町478-1"
profM5	db	08,"木村文彦"
profM6	db	16,"FAX 0946-24-5032"
;
w4str	wsidx	<8/2,JHINY/2,jumpstr>		; jump window strings
	wsidx	<JEXEX+2,(JEXEY+2)/2,execstr>
	db	0
w8str	label	byte				; 反復上書ウィンドウ文字列索引
w6str	wsidx	<8/2,(WBARH+8)/2,w6str1>	; 反復挿入ウィンドウ文字列索引
	wsidx	<8/2,(WBARH+8+22)/2,w6str2>
	wsidx	<112/2,(WBARH+8)/2,execstr>
	db	0
w7str	wsidx	<8/2,(WBARH+2)/2,w7str1>	; 解凍ウィンドウ文字列索引
	wsidx	<8/2,(WBARH+2+20)/2,w7str2>
	wsidx	<8/2,(WBARH+2+2*20)/2,w7str3>
	wsidx	<8/2,(WBARH+2+3*20)/2,w7str4>
	wsidx	<8/2,(WBARH+2+4*20)/2,w7str5>
	db	0
w9str	wsidx	<8/2,(WBARH+8)/2,w6str2>	; 部分削除ウィンドウ文字列索引
	wsidx	<156/2,(WBARH+8)/2,execstr>
	db	0
wAstr	wsidx	<8/2,(WBARH+8)/2,wAstr1>	; 検索ウィンドウ文字列索引
	wsidx	<8/2,(WBARH+8+22)/2,wAstr2>
	wsidx	<48/2,(WBARH+8+2*22)/2,wAstr3>
	wsidx	<160/2,(WBARH+8+2*22)/2,wAstr4>
	db	0
w6str1	db	6,"コード"
w6str2	db	8,"バイト数"
w7str1	db	08,"COM 自爆"
w7str2	db	08,"EXE 自爆"
w7str3	db	09,"LZH LHARC"
w7str4	db	08,"LZS LARC"
w7str5	db	10,"ARC PKXARC"
wAstr1	db	4,"16進"
wAstr2	db	4,"文字"
wAstr3	db	9,"抽出 末削"
wAstr4	db	9,"後方 前方"
;
w4box	wbstr	<JHINX-2,(JHINY-2)/2,JHINW+4,JHINH+4>	; jump window boxes
	wbstr	<JEXEX,JEXEY/2,JEXEW,JEXEH>
	db	0
w8box	label	byte				; 反復上書ウィンドウボタン
w6box	wbstr	<60/2,(WBARH+6)/2,24/2,CHRH+4>	; repeat insert window boxes
	wbstr	<84/2,(WBARH+6)/2,16/2,CHRH+4>
	wbstr	<108/2,(WBARH+6)/2,40/2,CHRH+4>
	wbstr	<76/2,(WBARH+6+22)/2,72/2,CHRH+4>
	db	0
w7box	wbstr	<4/2,(WBARH)/2,88/2,CHRH+4>	; 解凍ウィンドウ
	wbstr	<4/2,(WBARH+20)/2,88/2,CHRH+4>
	wbstr	<4/2,(WBARH+2*20)/2,88/2,CHRH+4>
	wbstr	<4/2,(WBARH+3*20)/2,88/2,CHRH+4>
	wbstr	<4/2,(WBARH+4*20)/2,88/2,CHRH+4>
	db	0
w9box	wbstr	<76/2,(WBARH+6)/2,72/2,CHRH+4>	; 部分削除ウィンドウ
	wbstr	<152/2,(WBARH+6)/2,40/2,CHRH+4>
	db	0
wAbox	wbstr	<44/2,(WBARH+6)/2,24/2,CHRH+4>	; 検索ウィンドウ
	wbstr	<(44+1*24)/2,(WBARH+6)/2,24/2,CHRH+4>
	wbstr	<(44+2*24)/2,(WBARH+6)/2,24/2,CHRH+4>
	wbstr	<(44+3*24)/2,(WBARH+6)/2,24/2,CHRH+4>
	wbstr	<(44+4*24)/2,(WBARH+6)/2,24/2,CHRH+4>
	wbstr	<(44+5*24)/2,(WBARH+6)/2,24/2,CHRH+4>
	wbstr	<(44+6*24)/2,(WBARH+6)/2,24/2,CHRH+4>
	wbstr	<(44+7*24)/2,(WBARH+6)/2,24/2,CHRH+4>
	wbstr	<44/2,(WBARH+6+22)/2,16/2,CHRH+4>
	wbstr	<(44+1*24)/2,(WBARH+6+22)/2,16/2,CHRH+4>
	wbstr	<(44+2*24)/2,(WBARH+6+22)/2,16/2,CHRH+4>
	wbstr	<(44+3*24)/2,(WBARH+6+22)/2,16/2,CHRH+4>
	wbstr	<(44+4*24)/2,(WBARH+6+22)/2,16/2,CHRH+4>
	wbstr	<(44+5*24)/2,(WBARH+6+22)/2,16/2,CHRH+4>
	wbstr	<(44+6*24)/2,(WBARH+6+22)/2,16/2,CHRH+4>
	wbstr	<(44+7*24)/2,(WBARH+6+22)/2,16/2,CHRH+4>
	wbstr	<44/2,(WBARH+6+2*22)/2,40/2,CHRH+4>
	wbstr	<(44+40)/2,(WBARH+6+2*22)/2,40/2,CHRH+4>
	wbstr	<156/2,(WBARH+6+2*22)/2,40/2,CHRH+4>
	wbstr	<(156+40)/2,(WBARH+6+2*22)/2,40/2,CHRH+4>
	db	0
;
warn0	db	28,"データを保存せずに終了します"	; exit
warn1	db	32,"データを保存しなくてもよいですか"	; new read
warn2	db	18,"編集をやり直します"			; reedit
warn3	db	16,"全文を削除します"			; all delete
;
errmsg	dw	err0,err1,err2,err3,err4,err5,err6,err7,err8,err9
	dw	err10
err0	db	18,"メモリが足りません"		; E$MemFul
err1	db	24,"ファイルが見つかりません"	; E$PNNF
err2	db	18,"オープンできません"		; E$Open
err3	db	12,"読み込み失敗"		; E$Read
err4	db	12,"書き出し失敗"		; E$Write
err5	db	20,"ファイルを作れません"	; E$Create
err6	db	16,"再保存できません"		; E$Update
err7	db	22,"ディスクがいっぱいです"	; E$Full
err8	db	26,"このファイル名は使えません"	; E$BFNam
err9	db	18,"番地が大き過ぎます"		; E$IllAdr
err10	db	18,"子プロセス異常終了"		; E$Child
data	ends

;*******************************
; program code start
;*******************************
code	segment	use32 eo
	assume	cs:code,ds:data
entry:
;-------------------------------
; initialize hardware
;-------------------------------
	mov	dx,0FDA0h	; CRT output control register
	xor	al,al		; display off layer 0,1
	out	dx,al
;
	mov	fs,tbios
	mov	edi,offset egbwork
	mov	ecx,EGBSIZ
	xor	ah,ah
	call	pword ptr fs:[20h]
;
	mov	dx,0448h	; video output controler I/O address
	xor	al,al		; select control register
	out	dx,al
	mov	dx,044Ah	; video output controler I/O data
	mov	al,15h		; 16 color both layer 0,1
	out	dx,al
;
	mov	dx,0448h	; video output controler I/O address
	mov	al,01b		; select priority register
	out	dx,al
	mov	dx,044Ah	; video output controler I/O data
	mov	al,00001001b	; layer 0 pallet, forground layer 1
	out	dx,al
	mov	esi,offset paldat0
	mov	ecx,paldat0N
init12:	call	setpal		; set pallet
	add	esi,4
	loop	init12
;
	mov	dx,0448h	; video output controler I/O address
	mov	al,01b		; select priority register
	out	dx,al
	mov	dx,044Ah	; video output controler I/O data
	mov	al,00101001b	; layer 1 pallet, forground layer 1
	out	dx,al
	mov	esi,offset paldat1
	mov	ecx,paldat1N
init14:	call	setpal		; set pallet
	add	esi,4
	loop	init14
;
	in	al,12h		; read slave IMR
	mov	simr,al		; save slave IMR
	or	al,00001000b	; exhibit VSYNC
	out	12h,al
;-------------------------------
; initialize interrupt vector
;-------------------------------
	push	es
	mov	ax,2502h	; get interrupt vector in 386 native mode
	mov	cl,4Bh		; VSYNC interrupt number
	int	21h
	mov	nvsync.pwsel,es
	mov	nvsync.pwofs,ebx
	pop	es
	mov	ax,2503h	; get interrupt vector in real mode
	int	21h
	mov	rvsync,ebx
	push	ds
	mov	ax,cs
	mov	ds,ax
	mov	edx,offset vsync
	mov	ax,2506h	; set interrupt always in 386 native mode
	int	21h
	pop	ds
;-------------------------------
; initialize buffer
; in : es = system segment
;-------------------------------
	mov	gs,psp			; program segment prefix
	mov	eax,gs:[0000005Ch]	; necessary size
	mov	bufadr,eax		; set buffer base address
	mov	datend,eax		; set data end address
	mov	edx,gs:[00000060h]	; program size
	sub	edx,eax
	sub	edx,8			; 検索オーバー用
	mov	bufsiz,edx		; set buffer size
;
	mov	esi,80h			; command line
	mov	edi,offset pbbuf
	movzx	ecx,byte ptr gs:[esi]	; parameter length
	test	ecx,ecx
	jz	short init28
init20:	inc	esi			; skip leading space
	cmp	byte ptr gs:[esi],20h
	loope	init20
	je	short init28		; space only
	inc	ecx
init22:	mov	al,gs:[esi]		; copy path list
	cmp	al,20h
	jbe	short init22		; first parameter end
	stosb
	inc	esi
	loop	init22
init28:	xor	al,al
	stosb				; put terminator
;
	assume	ds:stack
	mov	sfname,al		; clear save file name buffer
	assume	ds:data
;-------------------------------
; make mouse cursor pattern
;-------------------------------
	mov	esi,offset moupato
	mov	edi,offset moupat
	mov	bh,MOUPATN	; mouse pattern counter
init30:	lodsd			; throw away center position
	mov	bl,MOUPATH	; mouse pattern pixcel hight
init32:	lodsw			; mask pattern
	call	makhm		; make left mask pattern
	mov	[edi],edx	; set left part of mask
	call	makhm		; make right mask pattern
	mov	[edi+4],edx	; set right part of mask
	lodsw			; cursor pattern
	call	makhp		; make right cursor pattern
	mov	ebp,[edi+4]
	not	ebp
	and	edx,ebp
	mov	[edi+12],edx	; set right cursor pattern
	call	makhp		; make left cursor pattern
	mov	ebp,[edi]
	not	ebp
	and	edx,ebp
	mov	[edi+8],edx	; set left cursor pattern
	add	edi,16		; next line
	dec	bl
	jnz	init32
	dec	bh
	jnz	init30
;-------------------------------
; mouse port select
; in : es = system segment
;-------------------------------
init40:	mov	dx,04D6h	; pad output register
	mov	al,00001111b
	out	dx,al
	mov	dl,16*5		; wait 50μs
init42:	dec	dl
	jnz	init42
;
	mov	dx,04D6h	; pad output register
	mov	al,00111111b	; com,trig1,trig2 of pad 1,2
	out	dx,al
	mov	dl,16*5		; wait 50μs
init44:	dec	dl
	jnz	init44
	mov	dx,04D0h	; pad 1 input register
	in	al,dx
	and	al,1111b	; extract
	cmp	al,1111b
	jne	short init48
	mov	dx,04D2h	; pad 2 input register
	in	al,dx
	and	al,1111b	; extract
	cmp	al,1111b
	je	init40
init48:	mov	padreg,dx
;-------------------------------
; make kanji font index
; in : ds,es = system data segment
;-------------------------------
	mov	esi,offset fntdat	; kanji font index data
	mov	edi,offset knjidx+5Eh*2	; kanji font index base
	mov	ebp,fntdatN	; set page set counter
init50:	lodsb			; font page number
	shl	eax,8		; font number of page head
	inc	eax
	mov	ecx,31
	call	setfp
	lodsb			; font page number
	shl	eax,8		; font number of page head
	mov	ecx,32
	call	setfp
	lodsb			; font page number
	shl	eax,8		; font number of page head
	mov	ecx,31
	call	setfp
	add	edi,4*256*2-5Eh*2
	dec	ebp
	jnz	init50
;-------------------------------
; read disk state for disk browser
;-------------------------------
	mov	ah,19h		; get current disk
	int	21h
	mov	curdrv,al	; save current drive number(0=A.･･･)
	mov	ah,0Eh		; select disk
	mov	dl,al		; current drive
	int	21h
;
	mov	edi,offset drvdat
	movzx	ecx,al		; total logical drive number
	xor	ebx,ebx		; initialize drive number
init60:	inc	ebx
	mov	ax,4408h	; check changeable
	int	21h
	jnc	short init61	; normal end
	cmp	ax,0Fh
	je	short init62	; invalid drive
init61:	inc	drvnum		; count up effective drive number
	mov	eax,ebx
	add	ax,('A'-1)+(':' shl 8)
	mov	word ptr[edi].drvnam,ax	; set drive name
	mov	word ptr[edi+2].drvnam,'\'	; set root directory stringz
	add	edi,size drvstr	; next drive data
init62:	loop	init60
;
	mov	esi,offset drvdat
	mov	al,curdrv
	add	al,'A'
	movzx	ecx,drvnum
init64:	cmp	al,[esi].drvnam
	je	short init66
	add	esi,size drvstr	; next drive data
	loop	init64
	inc	cl		; set last drive
	sub	esi,size drvstr
init66:	mov	al,drvnum
	sub	al,cl
	mov	curdrv,al	; set drive number
;
	lea	esi,[esi].drvpath
	xor	dl,dl
	mov	ah,47h		; get current directory
	int	21h
;-------------------------------
; starting screen
;-------------------------------
	mov	es,vram2		; TOWNS VRAM (two page mode) selector
	mov	fs,fntsel		; font selector
;
	xor	edi,edi
	mov	eax,C$PANELD
	call	fillscr			; clear layer 0
	mov	edi,VRAMSIZ
	xor	eax,eax
	call	fillscr			; clear layer 1
;
	mov	ebx,offset inistr	; display strings
	call	dspss
;
	mov	esi,offset inibox	; box up
	mov	ecx,iniboxN
init72:	mov	edi,[esi].boxadr
	movzx	edx,[esi].boxw
	movzx	ebx,[esi].boxh
	push	ecx
	call	boxup
	pop	ecx
	add	esi,size boxstr
	loop	init72
;
	mov	esi,offset endbut	; end button
	mov	edi,[esi].boxadr
	movzx	edx,[esi].boxw
	movzx	ebx,[esi].boxh
init74:	push	edi
	push	ebx
	call	boxup
	pop	ebx
	pop	edi
	add	edi,VRAMW*2+1
	sub	edx,2
	sub	bx,4
	ja	init74
;
	mov	esi,offset tenkstr	; hex keyboard
	mov	edi,TENKADR
	mov	cx,0504h
init76:	push	ecx
	push	edi
	add	edi,VRAMW*2+1
	mov	ecx,2
	call	dspstr
	pop	edi
	push	edi
	mov	edx,KEYBW
	mov	ebx,KEYBH
	call	boxup
	pop	edi
	pop	ecx
	inc	esi
	inc	esi
	add	edi,KEYBW
	dec	cl
	jnz	init76
	add	edi,VRAMW*KEYBH-KEYBW*4
	mov	cl,4
	dec	ch
	jnz	init76
;
	call	dspab			; display ANK input button labels
	xor	al,al			; 上矢印アイコン
	mov	edi,ROLDX+3+(ROLDY+8)*VRAMW
	call	dspq
	mov	al,1			; 下矢印アイコン
	mov	edi,ROLUX+3+(ROLUY+8)*VRAMW
	call	dspq
	xor	al,al			; 上矢印アイコン
	mov	edi,PREVCX+3+(PREVCY+8)*VRAMW
	call	dspq
	mov	al,1			; 下矢印アイコン
	mov	edi,NEXTCX+3+(NEXTCY+8)*VRAMW
	call	dspq
;-------------------------------
; display first dump page
; in : fs = font data selector
;      es = VRAM
;-------------------------------
	mov	esi,offset hextbl
	mov	edi,LADRADR
	mov	ecx,16
init80:	mov	al,'+'
	call	dspc
	lodsb
	call	dspc
	add	edi,4
	loop	init80
;
	mov	esi,offset hextbl
	add	edi,ANKX-LADRX-LADRW-4
	mov	ecx,16
init82:	lodsb
	call	dspc
	loop	init82
;
	mov	esi,offset hextbl
	mov	edi,HADRADR+4*4	; page offset VRAM address
	mov	ecx,16
init88:	lodsb
	call	dspc
	mov	al,'0'
	call	dspc
	add	edi,VRAMW*16-2*4
	loop	init88
;
	call	dspag	; dispaly null page
	call	xorcur	; xor cursor
;
	mov	dx,0FDA0h	; CRT output control register
	mov	al,00001010b	; display layer 0,1
	out	dx,al
;-------------------------------
; display buffer size and time
; in : fs = font data selector
;      es = VRAM selector
;-------------------------------
	mov	eax,bufsiz	; display text buffer size
	mov	edi,MEMSIZY*VRAMW+MEMSIZX
	call	dsp8d
	call	dsptime		; display time
	call	dspksh		; カナシフト状態表示
;-------------------------------
; VSYNC interrupt start
;-------------------------------
	mov	al,simr		; slave IMR
	and	al,11110111b	; permit VSYNC
	out	12h,al
	mov	dx,05CAh	; clear VSYNC interrupt
	out	dx,al
;-------------------------------
; initial file read
;-------------------------------
	mov	edx,offset pbbuf
	mov	al,FALSE	; not insert
	call	readf		; read file
;-------------------------------
; main event read loop
;-------------------------------
main10:	mov	ax,0600h		; キーボードバッファークリア
	int	90h
;
main12:	call	getevt
	cmp	al,M$LDown
	je	short main20		; 左ボタン押し下げ
;
	mov	ax,0901h		; キーボード読み取り
	int	90h
	test	ah,ah			; 成功？
	jnz	main12			; 読み取りエラー
	and	bl,10b			; カナシフトフラグ状態を抽出
	cmp	bl,shifts		; カナシフト状態を調べる
	je	short main13		; 変更なし
	mov	shifts,bl		; カナシフト状態フラグ変更
	call	dspksh			; カナシフト状態表示
main13:	cmp	dh,0FFh
	je	main12			; 入力文字なし
;
	cmp	dl,'a'
	jb	short main15
	cmp	dl,'z'
	ja	short main15
	add	dl,'A'-'a'
main15:	mov	ebx,offset hextbl	; 16進コード文字列
	mov	ecx,hextblN		; コード総数
main16:	cmp	dl,[ebx]		; コードを探す
	je	short main18		; 見つかった
	inc	ebx
	loop	main16
	mov	al,dl
	cmp	al,1Ch
	jb	main12			; 無効コード
	cmp	al,1Fh
	ja	main12			; 無効コード
	add	al,89-1Ch
	jmp	short main19
;
main18:	mov	al,hextblN
	sub	al,cl
	and	al,0Fh
main19:	call	xorcur			; カーソル消去
	call	overw			; 文字上書き
	call	xorcur			; カーソル消去
	jmp	main12
;-------------------------------
; check main button
; in : ecx = mouse x position
;      edx = mouse y position
;-------------------------------
main20:	mov	edi,offset buttbl0	; button data table
	movzx	ebp,byte ptr [edi]	; button number
	inc	edi
main22:	call	chkran		; check range
	jnc	short main28	; within button
	add	edi,size butstr	; next button range data
	dec	ebp
	jnz	main22
	jmp	main10
;
main28:	movsx	eax,word ptr [edi].pofs	; program offset
	jmp	eax
;-------------------------------
; exit : procedures for exit
; in : edi = button data address
;-------------------------------
exit	proc
	call	select		; intense end button
	cmp	datchg,FALSE	; check data changed
	je	short exit20	; no changed
	push	edi
	mov	esi,offset warn0
	call	warn		; warning
	pop	edi
	jnc	short exit20	; execute
	call	select		; recover end button
	jmp	main10		; go to get new event
;
exit20:	mov	al,M$TCUP	; ちょっと待っての
	call	chgmc		; マウスカーソル形状にする
	mov	al,simr		; restore slave IMR
	out	12h,al
	mov	ax,2507h	; set interrupt vector in real and native
	mov	cl,4Bh		; VSYNC interrupt number
	mov	ebx,rvsync
	lds	edx,pword ptr nvsync
	int	21h
;
	mov	ax,4C00h	; exit to DOS
	int	21h
exit	endp
;-------------------------------
; tenkey : press tenkey button
; in : ecx = mouse x position
;      edx = mouse y position
;-------------------------------
tenkey	proc
	sub	ecx,TENKX	; relative x position
	sub	edx,TENKY	; relative y position
	mov	eax,ecx
	mov	bl,KEYBW
	div	bl
	movzx	ecx,al		; column number
	mov	eax,edx
	mov	bl,KEYBH
	div	bl
	movzx	edx,al		; line number
	call	xortk		; display button press
	call	xorcur		; current cursor erase
	mov	al,tktbl[ecx+edx*4]
	call	overw		; 文字上書き/カーソル移動
	call	xorcur		; display new cursor
	call	wailu		; wait for left button up
	call	xortk		; display button press
	jmp	main10		; go to main event get routine
tenkey	endp
;-------------------------------
; ankin : ANK code input
; in : ecx = mouse x position
;      edx = mouse y position
;-------------------------------
ankin	proc
	sub	ecx,ANKBX	; relative x position
	sub	edx,ANKBY	; relative y position
	shr	ecx,2		; column number
	and	edx,0F0h	; code button relative y position
	mov	al,abptop	; ANK button page top code
	add	al,dl
	or	al,cl		; input code
	mov	ebp,ANKBADR	; ANK button page VRAM address
	shl	ecx,2		; code button relative x position
	add	ebp,ecx
	shl	edx,VRAMP	; relative y address
	add	ebp,edx		; code button VRAM address
	push	ebp		; save button address
	push	eax		; save input code
;
	mov	edx,4		; button byte width
	mov	ebx,CHRH	; button hight
	mov	al,C$SELB	; intense button
	call	xorbox
	call	xorcur		; current cursor erase
;
	pop	eax		; input code
	mov	edi,curptr	; current cursor pointer
	cmp	edi,datsiz	; check data under cursor
	jb	short akin10	; overwrite
	call	insnb		; insert null byte
	jc	short akin80	; insert error
akin10:	mov	ebx,bufadr	; buffer base address
	mov	[ebx+edi],al	; renew byte data
	mov	datchg,TRUE	; data change flag on
	mov	lastep,edi	; カレント編集位置保存
	call	dspnb		; display new byte
;
	mov	nibpos,0	; go to next byte high nible
	mov	al,1		; 低音
	call	click		; クリック音
	inc	curb
	jnz	short akin80	; same page
	inc	curpag		; next page
	call	dspag		; display new page
;
akin80:	call	xorcur		; display new cursor
	call	wailu		; wait for left button up
	pop	ebp		; button address
	mov	edx,4		; button byte width
	mov	ebx,CHRH	; button hight
	mov	al,C$SELB	; normal button
	call	xorbox
	jmp	main10		; go to main event get routine
ankin	endp
;-------------------------------
; prevp : previous page
; in : edi = button data address
;-------------------------------
prevp	proc
	push	edi
	call	select		; intense button
	call	xorcur		; erase cursor
prevp1:	cmp	curpag,0
	je	short prevp9	; no exist previous page
;
	dec	curpag		; renew page
	call	dspag		; display page
;
prevp2:	call	getevt
	cmp	al,EvtNone
	je	prevp1		; continue page scroll
	cmp	al,M$LUp
	jne	prevp2		; invalid event
prevp9:	call	xorcur		; display cursor
	pop	edi
	call	select		; normal button
	jmp	main10		; go to get event
prevp	endp
;-------------------------------
; nextp : next page
; in : edi = button data address
;-------------------------------
nextp	proc
	push	edi
	call	select		; intense button
	call	xorcur		; erase cursor
nextp1:	mov	ax,curpag
	cmp	ax,word ptr datsiz[1]
	jae	short nextp8	; no exist next page
;
	inc	curpag		; renew current page
	call	dspag		; display page
;
nextp2:	call	getevt
	cmp	al,EvtNone
	je	nextp1		; go to next page
	cmp	al,M$LUp
	jne	nextp2		; invalid event
;
nextp8:	mov	eax,datsiz	; data size
	cmp	eax,curptr	; check end
	ja	prevp9
	mov	curptr,eax	; go to tail
	mov	nibpos,0	; set nible position
	jmp	prevp9
nextp	endp
;-------------------------------
; ANK input page roll down
; in : edi = button data address
;-------------------------------
rold	proc
	mov	ah,-16		; roll down one line
rold2:	mov	al,abptop
	add	al,ah
	cmp	al,16*(16-ANKBLN)
	ja	short rold9	; invalid
	mov	abptop,al	; set new page top code
	call	select		; intense button
	push	edi
	call	dspab		; display new ANK input page
	call	wailu		; wait left button up
	pop	edi
	call	select		; normal button
rold9:	jmp	main10		; go to get event
rold	endp
;-------------------------------
; ANK input page roll up
;-------------------------------
rolu	proc
	mov	ah,16		; roll up one line
	jmp	rold2		; go to display new page
rolu	endp
;-------------------------------
; chgds : 表示文字種の変更
; in : edi = ボタンデータ番地
;-------------------------------
chgds	proc
prevcs:	mov	al,codesp	; 現在の表示文字種コード
	dec	al		; 前の表示種へ
	jns	short cgds20
	mov	al,DSPCN-1	; 最大種番号
	jmp	short cgds20
;
nextcs:	mov	al,codesp	; 現在の表示文字種コード
	inc	al		; 次の表示種へ
	cmp	al,DSPCN-1
	jbe	short cgds20
	xor	al,al		; 最小種番号
;
cgds20:	mov	codesp,al	; 表示文字種コード更新
	movzx	eax,al
	imul	eax,6
	movsx	esi,cssidx[eax]	; 文字列データ番地
	mov	eax,dword ptr cssidx[eax+2]
	mov	dspofs,eax
	call	select		; ボタン強調
	push	edi
	lodsb			; 文字列バイト長
	movzx	ecx,al
	mov	edi,CODESPADR+6+VRAMW*2
	call	dspstr
	call	xorcur		; カーソル消去
	call	dspag		; ページ再表示
	call	xorcur		; カーソル表示
	call	wailu		; 左ボタン離されるまで待つ
	pop	edi
	call	select		; ボタンを元に戻す
	jmp	main10		; 次のイベント読み込みへ
chgds	endp
;-------------------------------
; insnul : insert null byte
; in : edi = button data address
;-------------------------------
insnul	proc
	call	xorcur		; erase cursor
	call	insnb		; insert null byte
	jc	short innul8	; insert error
;
innul2:	call	select		; intense button
	call	savdcp		; データ変更位置の保存
	mov	nibpos,0	; set nible position
	call	dspag		; redisplay page
	call	xorcur		; display cursor
	mov	al,1		; 低音
	call	click		; クリック音
	call	wailu		; wait for left button up
	call	select		; normal button
	jmp	main10
;
innul8:	call	xorcur		; display cursor
	jmp	main10
insnul	endp
;-------------------------------
; bs : backspace
; in : edi = button data address
;-------------------------------
bs	proc
	call	xorcur		; erase cursor
	cmp	curptr,0	; check pointer position
	je	innul8		; can't backspace
	dec	curptr		; back pointer
	jmp	short del2
bs	endp
;-------------------------------
; del : delete
; in : edi = button data address
;-------------------------------
del	proc
	call	xorcur		; erase cursor
del2:	call	delb		; delete one byte
	jc	innul8		; delete error
	jmp	innul2		; go to display
del	endp
;-------------------------------
; smenu : system menu
; in : ecx = mouse x position
;      bx = left button down time
;-------------------------------
smenu	proc
	mov	dwntime,bx	; left button down time
	mov	esi,offset sysbut
smen10:	cmp	cx,[esi+2]
	jbe	short smen12
	add	esi,6		; next menu button
	jmp	smen10
smen12:	mov	edi,offset menpos
	mov	ax,[esi]
	mov	[edi].x0,ax
	mov	[edi].y0,SMENY+1
	mov	ax,[esi+2]
	mov	[edi].x1,ax
	mov	[edi].y1,SMENY+SMENH-2
	call	select		; intense button
	movsx	esi,word ptr [esi+4]
	mov	curmenu,esi	; save menu data address
	mov	curitm,0	; set current menu item number
	call	dspmenu		; display menu
;
smen30:	call	getevt
	cmp	al,M$LUp
	je	short smen50	; left button up
	cmp	al,M$RDown
	je	smen70		; quit
	cmp	al,M$LDown
	je	short smen58	; choose
	cmp	al,EvtNone
	jne	smen30
;
	mov	edi,curmenu	; current menu data address
	call	chkran
	jnc	short smen40	; stay within menu
	mov	edi,offset sysbar	; system bar range data address
	call	chkran		; check range
	jnc	short smen46	; stay within menu bar
smen38:	mov	edi,curmenu	; current menu data address
	xor	al,al		; out of menu
	jmp	short smen42
;
smen40:	call	makitn		; make menu item number
smen42:	cmp	al,curitm	; renew item ?
	je	smen30		; unchanged
	call	selitm		; select new item
	xchg	curitm,al	; set new item number
	call	selitm		; cancel old item
	jmp	smen30
smen46:	mov	edi,offset menpos
	cmp	cx,[edi].x0
	jb	smen68		; go to left menu
	cmp	cx,[edi].x1
	ja	smen68		; go to right menu
	jmp	smen38
;
smen50:	mov	ax,dwntime
	sub	ax,bx
	jnc	short smen52
	add	ax,60*60
smen52:	cmp	ax,8		; 8/60 second
	jbe	smen30		; click menu
;
smen58:	call	eramen		; erase system menu
	movzx	eax,curitm	; current menu item number
	dec	eax
	js	main10		; cancel
	mov	esi,curmenu	; current menu data address
	shl	eax,2
	movzx	eax,word ptr[esi+9+eax+2]
	call	eax		; call menu item procedure
	jmp	main10		; go to get next event
;
smen68:	push	ebx		; change menu
	push	ecx
	call	eramen		; erase system menu
	pop	ecx		; mouse x position
	pop	ebx		; left button down time
	jmp	smenu		; go to new menu open
;
smen70:	call	eramen		; erase system menu
	jmp	main10
smenu	endp
;-------------------------------
; goln : go cursor to the line
; in : edx = mouse y position
;-------------------------------
goln	proc
	sub	edx,PAGY	; relative y position
	and	dl,0F0h		; new high nible
	mov	eax,curptr	; current pointer
	and	al,0Fh
	or	al,dl		; new byte pointer
	cmp	eax,datsiz	; check data size
	jbe	short goln2	; movable
	and	al,0F0h		; to line head
	cmp	eax,datsiz	; check line exist
	ja	short goln9	; unmovable
	mov	eax,datsiz
goln2:	call	xorcur		; erase cursor
	mov	nibpos,0	; set nible position
goln8:	mov	curptr,eax	; renew pointer
	call	xorcur		; display cursor
goln9:	jmp	main10
goln	endp
;-------------------------------
; gocol : go cursor to the column
; in : ecx = mouse x position
;-------------------------------
gocol	proc
	mov	eax,ecx
	sub	eax,PAGX	; relative x position
	mov	cl,3*4
	div	cl
	cmp	ah,2*4
	jae	goln9		; invalid
	mov	dl,al
	mov	eax,curptr	; current pointer
	and	al,0F0h
	or	al,dl		; new pointer
	cmp	eax,datsiz	; check data size
	jbe	goln2
	sub	al,10h		; previous line
	jc	goln9		; unmovable
	jmp	goln2		; go to renew cursor
gocol	endp
;-------------------------------
; gohex : go cursor to the hex
; in : ecx = mouse x position
;      edx = mouse y position
;-------------------------------
gohex	proc
	mov	eax,ecx
	sub	eax,PAGX	; relative x position
	mov	cl,3*4
	div	cl
	cmp	ah,2*4
	jae	goln9		; invalid
	mov	bl,ah		; save nible position
	sub	dx,PAGY		; ralative y position
	and	dl,0F0h		; high nible of page pointer
	or	dl,al		; page pointer
	mov	eax,curptr	; current pointer
	mov	al,dl		; new pointer
	cmp	eax,datsiz	; check data size
	ja	goln9		; unmovable
;
	call	xorcur		; erase old cursor
	shr	bl,2
	mov	nibpos,bl	; set nible position
	jmp	goln8
gohex	endp
;-------------------------------
; goank : go cursor to the ank
; in : ecx = mouse x position
;      edx = mouse y position
;-------------------------------
goank	proc
	sub	ecx,ANKX	; relative x position
	shr	cl,2		; lowest nible of pointer
	sub	edx,ANKY	; ralative y position
	and	dl,0F0h		; high nible of page pointer
	or	dl,cl		; page pointer
	mov	eax,curptr	; current pointer
	mov	al,dl		; new pointer
	cmp	eax,datsiz	; check data size
	ja	goln9		; unmovable
	jmp	goln2		; renew cursor
goank	endp
;-------------------------------
; prof : profile
;-------------------------------
prof	proc
	mov	esi,offset window5
	call	dspwf		; display window frame
prof10:	push	esi
	mov	ebx,offset profM
	mov	ebp,winadr
	add	ebp,(WBARH+6)*VRAMH+4
prof12:	movsx	esi,word ptr [ebx]
	test	esi,esi
	jz	short prof18
	mov	edi,ebp
	lodsb
	movzx	ecx,al
	call	dspstr
	add	ebx,2
	add	ebp,20*VRAMW
	jmp	prof12
prof18:	pop	esi
prof20:	call	getew		; get event through window
	cmp	al,EvtClose
	je	short prof90	; close window
	cmp	al,EvtUpdate
	je	prof10		; display window contents
	cmp	al,M$RDown
	je	short prof90	; close window
	cmp	al,M$LDown
	jne	prof20		; invalid event
prof90:	call	erawin		; erase window
	jmp	main10
prof	endp

;*******************************
; vsync : VSYNC interrupt handler
;
; call: eramou,dspmou
;       dspbcd,putevt,getmou
;
vsync	proc
	push	ds
	push	es
	push	fs
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	esi
	push	edi
	mov	eax,0014h	; set system segment
	mov	ds,ax
	mov	es,vram2	; set VRAM segment
	mov	fs,fntsel
	cld			; direction flag clear
;-------------------------------
; check mouse
;-------------------------------
	cmp	mouflg,FALSE	; check mouse cursor display flag
	je	short vsyn40		; no display
;
	mov	edi,dword ptr bakmx	; background pattern position
	cmp	edi,dword ptr newmx	; new mouse cursor position
	je	short vsyn40		; not move
;-------------------------------
; move mouse cursor
; in : edi = current position
;-------------------------------
	call	eramou		; erase mouse cursor
	call	dspmou		; display mouse cursor
;-------------------------------
; date & time
;-------------------------------
vsyn40:	cmp	redate,1	; check date display flag
	jne	short vsyn42
	call	dspdate		; display date
	jc	short vsyn42	; RTC not ready
	dec	redate
vsyn42:	dec	mincnt		; check minute counter
	jnz	short vsyn50	; not yet
;
	mov	ebx,offset timestr
	mov	edi,(SBARY+5)*VRAMW+SBARX+SBARW-4*4-4
	mov	ax,[ebx]	; minute
	inc	eax
	aaa
	cmp	ax,0600h
	jb	short vsyn48
	xor	eax,eax
	mov	[ebx],ax
	call	dspbcd
	inc	ebx
	inc	ebx
	sub	edi,7*4
	mov	ax,[ebx]	; hour
	inc	eax
	aaa
	cmp	ax,0204h
	jb	short vsyn48
	inc	redate		; set date renew flag
	xor	eax,eax
vsyn48:	mov	[ebx],ax
	call	dspbcd
	mov	mincnt,60*60	; set minute counter
;-------------------------------
; read mouse data
;-------------------------------
vsyn50:	mov	dx,04D6h	; pad output register
	mov	al,00001111b
	out	dx,al
	mov	dx,padreg	; pad input register
	in	al,dx
	and	al,00110000b	; extract button state
	xor	al,moustat
	jz	short vsyn54	; unchange
	xor	moustat,al	; change button state
	test	al,010000b	; change left button ?
	jz	short vsyn52	; unchange
	push	eax
	mov	al,moustat
	shr	al,4
	and	al,01b
	or	al,10b		; left button change
	call	putevt
	pop	eax
	test	al,100000b	; change right button
	jz	short vsyn54	; unchange
vsyn52:	mov	al,moustat
	shr	al,5
	or	al,100b		; right button change
	call	putevt
;
vsyn54:	call	getmou		; get mouse x move
	sub	newmx,ax
	jl	short vsyn55
	cmp	newmx,VRAMDW-MOUPATW	; check new x range
	jb	short vsyn56	; ok!
vsyn55:	add	newmx,ax	; recover
vsyn56:	call	getmou		; get mouse y move
	shl	eax,1
	sub	newmy,ax
	cmp	newmy,VRAMH	; check up limit
	jae	short vsyn58	; ok!
	mov	newmy,VRAMH
vsyn58:	cmp	newmy,VRAMH+VRAMDH-MOUPATH	; check down limit
	jb	short vsyn90	; ok!
	mov	newmy,VRAMH+VRAMDH-MOUPATH
;-------------------------------
; send EOI
;-------------------------------
vsyn90:	mov	dx,05CAh	; clear VSYNC interrupt
	out	dx,al
;
	mov	al,20h	; EOI
	out	10h,al	; set EOI in slave
	mov	al,0Bh
	out	10h,al	; select slave ISR read
	in	al,10h	; read slave ISR
	test	al,0FFh	; check interrupt presence in slave
	jnz	short vsyn99	; interrupt exist in slave
	mov	al,20h	; EOI
	out	00h,al	; send EOI to master
;
vsyn99:	pop	edi
	pop	esi
	pop	edx
	pop	ecx
	pop	ebx
	pop	eax
	pop	fs
	pop	es
	pop	ds
	iretd

;*******************************
; putevt : put event record
;
; in : al = event type
;      bakmx = mouse x position
;      bakmy = mouse y position
;      evtbuf = event buffer
;      ebcount = event buffer counter
;      ebtail = event buffer tail
; use: eax,ebx,edi
;
putevt	proc
	cmp	ebcount,EVTNUM	; check event counter
	jae	short ptev90	; buffer overflow
	inc	ebcount		; count up
	mov	edi,offset evtbuf	; event buffer base
	movzx	ebx,ebtail
	mov	[edi+ebx].evttyp,al
	mov	ax,mincnt
	mov	[edi+ebx].evttim,ax
	mov	eax,dword ptr bakmx
	mov	dword ptr [edi+ebx].evtx,eax
	add	ebx,size evtrec
	and	ebx,EBSIZ-1
	mov	ebtail,bx
ptev90:	ret
putevt	endp

;*******************************
; getmou : get mouse data
;
; in : padreg = pad input register
; out: ax = amount of movement
;      cl = button state
; err: cf = mouse not ready
; use: dx
;
getmou	proc
	mov	dx,04D6h	; pad output register
	mov	al,00111111b
	out	dx,al
	mov	dl,16*5		; wait 50μs
getm10:	dec	dl
	jnz	getm10
	mov	dx,padreg	; pad input register
	in	al,dx
	shl	al,4
	mov	ah,al		; save high nible
;
	mov	dx,04D6h	; pad output register
	mov	al,00001111b
	out	dx,al
	mov	dl,16*4		; wait 40μs
getm20:	dec	dl
	jnz	getm20
	mov	dx,padreg	; pad input register
	in	al,dx
	and	al,0Fh
	or	al,ah
	cbw
	ret
getmou	endp
vsync	endp

;*******************************
; eramou : erase mouse cursor
;
; in : edi = current position
;      es = VRAM selector
; use: eax,ecx,esi,edi
;
eramou	proc
	mov	eax,edi
	xor	di,di
	shr	edi,16-VRAMP
	or	di,ax
	mov	esi,offset bakpat	; background pattern save address
	mov	ecx,MOUPATH	; mouse pattern pixcel hight
eramo1:	movsd			; recover left part
	movsd			; recover right part
	add	edi,VRAMW-8	; next line
	loop	eramo1
	ret
eramou	endp

;*******************************
; dspmou : display mouse cursor
;
; in : es = VRAM selector
; use: eax,ebx,ecx,esi,edi
;
dspmou	proc
	movzx	esi,moucur[4]	; mouse pattern address
	mov	edi,dword ptr newmx	; new mouse cursor position
	mov	dword ptr bakmx,edi	; renew bakground position
	mov	eax,edi
	xor	di,di
	shr	edi,16-VRAMP
	or	di,ax
	mov	ebx,offset bakpat	; background pattern save address
	mov	ecx,MOUPATH	; mouse pattern pixcel hight
dpmo10:	mov	eax,es:[edi]	; left part
	mov	[ebx],eax	; save
	and	eax,[esi]	; masking
	or	eax,[esi+8]
	mov	es:[edi],eax
	mov	eax,es:[edi+4]	; right part
	mov	[ebx+4],eax	; save
	and	eax,[esi+4]	; masking
	or	eax,[esi+12]
	mov	es:[edi+4],eax
	add	esi,16		; next line
	add	ebx,8
	add	edi,VRAMW
	loop	dpmo10
	ret
dspmou	endp

;*******************************
; makhm : make half mask pattern
;
; in : ax = source mask pattern
;           ah is effective
; out: edx = mask pattern maked
;      ax = left shifted by 8
; use: ecx
;
makhm	proc
	mov	ecx,8
makhm1:	shl	ax,1
	rcr	edx,1
	sar	edx,3
	loop	makhm1
	ret
makhm	endp

;*******************************
; makhp : make half cursor pattern
;
; in : ax = source cursor pattern
;           al is effective
; out: edx = cursor pattern maked
;      ax = right shifted by 8
; use: ecx
;
makhp	proc
	mov	ecx,8
makhp1:	shl	edx,4
	shr	ax,1
	jc	short makhp2
	or	edx,C$MOUF
	jmp	short makhp8
makhp2:	or	edx,C$MOUB
makhp8:	loop	makhp1
	ret
makhp	endp

;*******************************
; setpal : set pallet data
;
; in : (ds:esi) = data address
; use: dx
;
setpal	proc
	push	esi
	mov	dx,0FD90h	; pallet code
	outsb
	mov	dx,0FD92h	; blue pallet data
	outsb
	mov	dx,0FD94h	; red pallet data
	outsb
	mov	dx,0FD96h	; green pallet data
	outsb
	pop	esi
	ret
setpal	endp

;*******************************
; getevt : get event record
;
; in : evtbuf = event buffer
;      ebcount = event buffer counter
;      ebhead = event buffer head
; out: al = event type
;      bx = event occured time
;      ecx = event x position
;      edx = event y position
; use: none
;
getevt	proc
	cmp	ebcount,0	; check event counter
	je	short gtev80	; no event
	push	esi
	mov	esi,offset evtbuf	; event buffer base
	movzx	ebx,ebhead
	mov	al,[esi+ebx].evttyp
	movzx	ecx,[esi+ebx].evtx
	movzx	edx,[esi+ebx].evty
	push	ebx
	add	ebx,size evtrec	; renew head pointer
	and	ebx,EBSIZ-1
	mov	ebhead,bx
	pop	ebx
	mov	bx,[esi+ebx].evttim
	dec	ebcount		; count down
	sub	edx,VRAMH
	pop	esi
	ret
gtev80:	mov	al,EvtNone
	mov	bx,mincnt
	movzx	ecx,bakmx
	movzx	edx,bakmy
	sub	edx,VRAMH
	ret
getevt	endp

;*******************************
; dspag : display 1 page
;
; in : curpag = display page
;      curb = current byte in page
;      bufadr = buffer address
;      datend = data end address
;      fs = font data selector
;      es = VRAM selector
; call: dsphex,erak,erastr
; use: eax,ebx,ecx,edx,esi
;
dspag	proc
	push	edi
;-------------------------------
; display address line gauge
;-------------------------------
	mov	edi,HADRADR	; address VRAM offset address
	mov	esi,edi
	mov	ax,curpag	; current page number
	xchg	ah,al
	call	dsphex
	mov	al,ah
	call	dsphex
	add	edi,VRAMW*16-4*4
	mov	ecx,(16-1)*CHRH
	mov	edx,VRAMW-4*4
	push	ds
	mov	ax,es
	mov	ds,ax
dspg10:	movsd
	movsd
	movsd
	movsd
	add	esi,edx
	add	edi,edx
	loop	dspg10
	pop	ds
;-------------------------------
; initialize
;-------------------------------
	mov	ebx,offset csum	; column sum calculate buffer
	xor	eax,eax
	mov	[ebx],eax
	mov	[ebx+4],eax
	mov	[ebx+8],eax
	mov	[ebx+12],eax
	movzx	esi,curpag	; current page
	shl	esi,8
	add	esi,bufadr	; page start address
	mov	edi,PAGADR	; page start VRAM offset address
	mov	cl,16		; set line counter
;-------------------------------
; display one hex line
;-------------------------------
dspg20:	mov	ebx,offset csum	; column sum calculate buffer
	xor	dl,dl		; initialize line sum
	mov	ch,16		; set colomn counter
	push	esi
dspg22:	cmp	esi,datend	; check data end
	jae	short dspg50	; go to display last page rest
	lodsb			; load byte data
	add	dl,al		; add line sum
	add	[ebx],al	; add column sum
	call	dsphex		; display hexadecimal
	inc	ebx		; next column sum
	add	edi,4		; skip to right byte
	dec	ch		; column count down
	jnz	dspg22		; go to right column
;-------------------------------
; display one line sum
; in : dl = line sum
;-------------------------------
	mov	al,dl
	call	dsphex		; display line sum
;-------------------------------
; display ANK charactor one line
;-------------------------------
	pop	esi			; chractor data address
	add	edi,ANKX-LSUMX-2*4	; display VRAM address
	push	ecx
	mov	ecx,16			; 文字列バイト長
	call	[dspofs]		; 描画処理ルーチンへ
	pop	ecx
;
	add	edi,VRAMW*16-(16*3+2+3+16)*4	; down line VRAM address
	dec	cl			; line count down
	jnz	dspg20			; go to down line
;-------------------------------
; display column sums
;-------------------------------
dspg40:	add	edi,VRAMW*8	; column sum display address
	mov	esi,offset csum	; column sum calculate buffer
	xor	dl,dl		; initialize total sum
	mov	ecx,16		; set colomn counter
dspg42:	lodsb			; load column sum data
	add	dl,al		; add total sum
	call	dsphex		; display column sum
	add	edi,4		; skip to right sum
	loop	dspg42		; go to right column
	mov	al,dl
	call	dsphex		; display total sum
	pop	edi
	ret
;-------------------------------
; 最終行の描画
; in : cl = 残り行数
;      ch = 残り桁数
;-------------------------------
dspg50:	pop	esi		; ソース文字列番地
	movzx	ebx,cl		; 残り行数カウンタ
	movzx	ecx,ch		; 残り桁数カウンタ
	push	ecx
dspg52:	call	erak		; 行末消去
	add	edi,4		; skip to right byte
	loop	dspg52		; go to right column
;
	mov	al,dl		; 行サム表示
	call	dsphex
;
	add	edi,ANKX-LSUMX-2*4	; display ANK charactor one line
	pop	edx		; 残り桁数
	mov	ecx,16		; 行バイト長
	sub	ecx,edx		; 有効バイト長
	jbe	short dspg54	; 描画文字列なし
	call	[dspofs]	; 描画処理ルーチンへ
;
dspg54:	mov	cl,dl		; 行末消去
	call	erastr
;-------------------------------
; ページ残り空白行の消去
; in : ebx = 残り行数
;-------------------------------
dspg60:	add	edi,VRAMW*16-(16*3+2+3+16)*4	; down line VRAM address
	dec	ebx		; 行数カウントダウン
	jz	dspg40		; 列サム描画へ
;
	mov	ecx,16		; 16進文字消去
dspg62:	call	erak
	add	edi,4		; skip to right byte
	loop	dspg62		; go to right column
;
	xor	al,al		; 行サムはゼロ
	call	dsphex
;
	add	edi,ANKX-LSUMX-2*4	; display ANK charactor one line
	mov	cl,16			; 16文字列消去
	call	erastr
	jmp	dspg60
dspag	endp

;*******************************
; dspnk : 非漢字文字列行表示
;
; in : esi = 文字列番地
;      ecx = バイト長
;      edi = 描画番地
; out: esi = 次の番地
;      edi = 次の番地
; use: al,ecx
;
dspnk	proc
dpnk10:	lodsb
	call	dspc
	loop	dpnk10
	ret
dspnk	endp

;*******************************
; dspsj : シフトＪＩＳ文字列表示
;
; in : esi = 文字列番地
;      ecx = バイト長
;      edi = 描画番地
; out: esi = 次の番地
;      edi = 次の番地
; use: none
;
dspsj	proc
	call	dspstr
	add	esi,ecx		; 文字列番地更新
	ret
dspsj	endp

;*******************************
; dspal : ＡＮＫ行表示
;
; in : esi = 文字列番地
;      ecx = バイト長
;      edi = 描画番地
; out: esi = 次の番地
;      edi = 次の番地
; use: al,ecx
;
dspal	proc
dpal10:	lodsb
	cmp	al,20h
	jb	short dpal20	; 制御コード
	cmp	al,7Eh
	jbe	short dpal80	; ＡＳＣＩＩ
	cmp	al,0A1h
	jb	short dpal20	; 未定義
	cmp	al,0DFh
	jbe	short dpal80	; カナ
dpal20:	mov	al,'.'
dpal80:	call	dspc
	loop	dpal10
	ret
dspal	endp

;*******************************
; dsopnb : display new byte
;          hex,ank,sum
;
; in : al = new byte data
;      curb = byte position in page
; use: eax,ebx,esi,edi
; call: dsphex,dspc
;
dspnb	proc
	movzx	ebx,curb
	mov	edi,ebx
	and	ebx,0Fh
	imul	ebx,3*4		; relative x position
	and	edi,0F0h	; relative y position
	shl	edi,VRAMP
	push	edi
	add	edi,ebx
	add	edi,PAGADR	; current hexadecimal VRAM address
	call	dsphex		; display new hexadecimal
;
	pop	edi
	movzx	ebx,curb
	and	ebx,0Fh
	shl	ebx,2
	add	edi,ebx
	add	edi,ANKADR
	call	dspc		; dipslay ANK charactor
;
	mov	esi,bufadr
	mov	ebx,curptr
	and	bl,0F0h		; line head data pointer
	xor	al,al		; clear line sum counter
	mov	ah,16		; set column counter
dspnb1:	cmp	ebx,datsiz
	jae	short dspnb2	; data end
	add	al,[esi+ebx]	; add byte
	inc	ebx		; next byte address
	dec	ah
	jnz	dspnb1
dspnb2:	movzx	edi,curb
	and	edi,0F0h	; relative y position
	shl	edi,VRAMP
	add	edi,LSUMADR	; current line sum VRAM address
	call	dsphex		; display line sum
;
	mov	ebx,curptr
	and	bl,0Fh		; top line data pointer
	xor	al,al		; clear column sum counter
	mov	ah,16		; set line counter
dspnb3:	cmp	ebx,datsiz
	jae	short dspnb4	; data end
	add	al,[esi+ebx]	; add byte
	add	ebx,10h		; next line byte address
	dec	ah
	jnz	dspnb3
dspnb4:	movzx	edi,curb
	and	edi,0Fh
	imul	edi,3*4		; relative x position
	add	edi,CSUMADR	; current column sum VRAM address
	call	dsphex		; display column sum
;
	mov	ebx,curptr
	xor	bl,bl		; page data pointer
	xor	eax,eax		; clear total sum counter/set byte counter
dspnb5:	cmp	ebx,datsiz
	jae	short dspnb6	; data end
	add	al,[esi+ebx]	; add byte
	inc	ebx		; next byte address
	dec	ah
	jnz	dspnb5
dspnb6:	mov	edi,TSUMADR	; total sum VRAM address
	call	dsphex		; display total sum
	ret
dspnb	endp

;*******************************
; dspab : display ANK buttons
;
; in : abptop = start button code
; use: al,ecx,edx,esi,edi
; call: dspc
;
dspab	proc
	mov	edi,ANKBADR-8		; ANK input button VRAM base address
	mov	edx,ANKBLN		; set line counter
	mov	al,abptop		; start button code
	movzx	esi,al
	shr	esi,4
	add	esi,offset hextbl
dpab10:	push	eax
	lodsb
	call	dspc			; display high nible code
	add	edi,4
	pop	eax
	mov	ecx,16			; set column counter
dpab20:	call	dspc			; dipslay ANK charactor
	inc	al			; next ANK code
	loop	dpab20
	add	edi,VRAMW*CHRH-18*4	; next line address
	dec	edx
	jnz	dpab10
	ret
dspab	endp

;*******************************
; dsphex : display hexadecimal
;
; in : al = binary
;      edi = VRAM offset address
;      fs = font data selector
;      es = VRAM selector
; out: edi = right charactor address
; call: dspc
; use: none
;
dsphex	proc
	push	eax
	mov	ah,al
	shr	al,4		; high nible
	and	ah,0Fh		; low nible
	add	ax,(('A'-10) shl 8)+'A'-10	; 10-15 to A-F
	cmp	al,'A'
	jae	short dshx10
	add	al,'9'-'A'+1	; adjust high nible
dshx10:	call	dspc		; display high nible
	mov	al,ah
	cmp	al,'A'
	jae	short dshx20
	add	al,'9'+1-'A'	; adjust low nible
dshx20:	call	dspc		; display low nible
	pop	eax
	ret
dsphex	endp

;*******************************
; dspc : display code
;
; in : al = code data
;      edi = VRAM offset address
;      fs = font data selector
;      es = VRAM selector
; out: edi = right charactor address
; use: none
;
dspc	proc
	push	eax
	push	ebx
	push	ecx
	push	edx
	movzx	ebx,al		; convert byte to double word
	shl	ebx,4		; destination charactor offset
	add	ebx,ANKOFS	; destination charactor address
	mov	ecx,CHRH	; font pixcel hight
	mov	dh,10b
dspc10:	mov	dl,fs:[ebx]	; load one line font data
	xor	al,al
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	add	al,dl
	add	al,dh
	mov	es:[edi],eax	; put one line on VRAM
	inc	ebx		; next line pattern offset
	add	edi,VRAMW	; next line VRAM address
	loop	dspc10
;
	add	edi,4-VRAMW*16	; set right charactor VRAM address
	pop	edx
	pop	ecx
	pop	ebx
	pop	eax
	ret
dspc	endp

;*******************************
; dspk : display 16×16 font
;
; in : ebx = font data address
;      edi = VRAM address
;      fs = font data selector
;      es = VRAM selector
; out: edi = right address
; use: none
;
dspk	proc
	push	eax
	push	ebx
	push	ecx
	push	edx
	mov	ecx,16		; font pixcel hight
dspk10:	mov	dh,2		; horizon double word counter
dspk20:	mov	dl,fs:[ebx]	; load one line double word font data
	xor	al,al
	shr	dl,1
	adc	al,10b
	shl	eax,4
	shr	dl,1
	adc	al,10b
	shl	eax,4
	shr	dl,1
	adc	al,10b
	shl	eax,4
	shr	dl,1
	adc	al,10b
	shl	eax,4
	shr	dl,1
	adc	al,10b
	shl	eax,4
	shr	dl,1
	adc	al,10b
	shl	eax,4
	shr	dl,1
	adc	al,10b
	shl	eax,4
	add	al,dl
	add	al,10b
	stosd			; put one line double word on VRAM
	inc	ebx		; next pattern byte offset
	dec	dh
	jnz	dspk20
	add	edi,VRAMW-8	; next line VRAM address
	loop	dspk10
;
	add	edi,8-VRAMW*16	; set next charactor VRAM address
	pop	edx
	pop	ecx
	pop	ebx
	pop	eax
	ret
dspk	endp

;*******************************
; dspq : 8×4パターン表示
;
; in : al = パターン番号
;      edi = VRAMオフセット番地
;      es = VRAMセレクタ
; use: eax,ebx,ecx,edx
;
dspq	proc
	push	edi
	movzx	ebx,al
	shl	ebx,2
	add	ebx,offset qrpat
	mov	ecx,4		; pattern pixcel hight
	mov	dh,10b
dspq10:	mov	dl,[ebx]	; load one line pattern data
	xor	al,al
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	shr	dl,1
	adc	al,dh
	shl	eax,4
	add	al,dl
	add	al,dh
	mov	es:[edi],eax	; put one line on VRAM
	inc	ebx		; next line pattern offset
	add	edi,VRAMW	; next line VRAM address
	loop	dspq10
	pop	edi
	ret
dspq	endp

;*******************************
; boxup : box up
;
; in : edi = left up address
;      edx = byte width
;      ebx = pixcel hight
;      es = VRAM selector
; use: al,ebx,ecx,edi
;
boxup	proc
	mov	al,C$INT*16+C$INT
	mov	ecx,edx
	push	edi
	rep	stosb
	pop	edi
;
	sub	ebx,2
	mov	ecx,ebx
bxup10:	add	edi,VRAMW
	mov	byte ptr es:[edi],C$INT+C$PANEL*16
	mov	byte ptr es:[edi+edx-1],C$PANEL+C$DARK*16
	loop	bxup10
;
	add	edi,VRAMW
	mov	al,C$DARK*16+C$DARK
	mov	ecx,edx
	rep	stosb
	ret
boxup	endp

;*******************************
; dspss : display strings
;
; in : ebx = string index address
;      fs = font data selector
;      es = VRAM selector
; call: dspstr
; use: eax,ebx,ecx,esi,edi
;
dspss	proc
dspss1:	movsx	esi,[ebx].strofs	; string data address
	test	esi,esi			; check data end
	jz	short dspss9		; end
	mov	edi,[ebx].stradr	; display VRAM address
	lodsb				; string byte length
	movzx	ecx,al
	call	dspstr
	add	ebx,size stridx		; 次の索引番地へ
	jmp	dspss1
dspss9:	ret
dspss	endp

;*******************************
; select : set select bit
;         in rectangle
;
; in : edi = rectangle area data
; use: al,ebx,ecx,edx,ebp
; call: makadr,xorbox
;
select	proc
	call	makadr		; convert position to address
	mov	al,C$SELB	; select bit data
	call	xorbox		; xor box
	ret
select	endp

;*******************************
; selitm : select menu item
;          in layer 1
;
; in : edi = menu data addrress
;      al = selected item number
; use: none
; call: xorbox,mcoff,mcon
;
selitm	proc
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	ebp
	movzx	ebp,al
	dec	ebp
	js	short selit9	; invalidity
	imul	ebp,ITEMH
	movzx	edx,[edi].y0
	add	ebp,edx
	add	ebp,VRAMH	; to layer 1
	shl	ebp,VRAMP
	movzx	eax,[edi].x0
	or	ebp,eax		; start VRAM address
	movzx	edx,[edi].x1
	sub	edx,eax
	inc	edx		; select byte width
	mov	ebx,ITEMH	; select hight
	mov	al,C$SELB	; select bit data
	call	mcoff		; mouse cursor off
	call	xorbox		; xor box
	call	mcon		; mouse cursor on
selit9:	pop	ebp
	pop	edx
	pop	ecx
	pop	ebx
	pop	eax
	ret
selitm	endp

;*******************************
; makadr : convert position
;          to address
;
; in : edi = rectangle area data
; out: ebp = VRAM address
;      edx = byte width
;      ebx = hight
; use: none
;
makadr	proc
	movzx	ebp,[edi].y0	; y0
	shl	ebp,VRAMP
	or	bp,[edi].x0	; start VRAM address
	mov	dx,[edi].x1
	sub	dx,[edi].x0
	movzx	edx,dx
	inc	edx		; byte width
	mov	bx,[edi].y1
	sub	bx,[edi].y0
	movzx	ebx,bx
	inc	ebx		; hight
	ret
makadr	endp

;*******************************
; xorbox : xor box
;
; in : ebp = VRAM address
;      edx = byte width
;      ebx = hight
;      al = xor source
;      es = VRAM selector
; use: ebx,ecx,ebp
;
xorbox	proc
xorb10:	mov	ecx,edx
	push	ebp
xorb20:	xor	es:[ebp],al
	inc	ebp
	loop	xorb20
	pop	ebp
	add	ebp,VRAMW		; next line
	dec	ebx
	jnz	xorb10
	ret
xorbox	endp

;*******************************
; dspdate : display date
;
; in : fs = font data selector
;      es = VRAM selector
; err: cf = set by RTC not ready
; call: getrtc,dspc
; use: ax,edi
;
dspdate	proc
	in	al,70h		; read RTC data
	test	al,al		; check ready
	jns	short dsdaE0	; not ready
;
	mov	al,80h		; chip select
	out	80h,al
;
	mov	edi,(SBARY+5)*VRAMW+SBARX+SBARW-19*4-4
	mov	ah,0Ah		; high month digit address
dsda10:	call	getrtc		; get RTC data
	test	al,al		; check ready
	jns	short dsdaE2	; not ready
	add	al,80h+'0'
	cmp	al,'0'
	jne	short dsda12
	mov	al,' '
dsda12:	call	dspc		; display high digit
	dec	ah		; low digit address
	call	getrtc		; get RTC data
	test	al,al		; check ready
	jns	short dsdaE2	; not ready
	add	al,80h+'0'
	call	dspc		; display low digit
	add	edi,3*4		; day digit VRAM address
	dec	ah		; hight day digit address
	cmp	ah,8
	je	dsda10
;
	clc			; clear carry
dsda99:	pushfd
	xor	al,al		; chip select = 0
	out	80h,al
	popfd
	ret
;
dsdaE0:	stc			; set carry
	ret
dsdaE2: stc			; set carry
	jmp	dsda99
dspdate	endp

;*******************************
; dsptime : display time
;           with save time
;
; in : fs = font data selector
;      es = VRAM selector
; out: timestr
; call: getrtc,dspc
; use: ax,ebx,edi
;
dsptime	proc
dsti10:	in	al,70h		; read RTC data
	test	al,al		; check ready
	jns	dsti10		; not ready
;
	mov	al,80h		; chip select
	out	80h,al
;
	mov	ebx,offset timestr+4
	mov	edi,(SBARY+5)*VRAMW+SBARX+SBARW-9*4-4
	mov	ah,5		; high hour digit address
dsti20:	call	getrtc		; get RTC data
	test	al,al		; check ready
	jns	short dstiE0	; not ready
	and	al,111b
	dec	ebx
	mov	[ebx],al
	test	al,al
	jnz	short dsti22
	mov	al,' '-'0'
dsti22:	add	al,'0'
	call	dspc		; display high digit
	dec	ah		; low digit address
	call	getrtc		; get RTC data
	test	al,al		; check ready
	jns	short dstiE0	; not ready
	and	al,1111b
	dec	ebx
	mov	[ebx],al
	add	al,'0'
	call	dspc		; display low digit
	add	edi,3*4		; minute digit VRAM address
	dec	ah		; hight minute digit address
	cmp	ah,3
	je	dsti20
;
	xor	al,al		; chip select = 0
	out	80h,al
	ret
;
dstiE0:	xor	al,al		; chip select = 0
	out	80h,al
	jmp	dsti10		; retry
dsptime	endp

;*******************************
; getrtc : get RTC
;    need chip select before
;    and chip release after
;
; in : ah = RTC address
; out: al = data
; use: none
;
getrtc	proc
	mov	al,ah		; register address
	out	70h,al
	mov	al,81h
	out	80h,al
	dec	al
	out	80h,al
	mov	al,84h		; read data
	out	80h,al
	jmp	short $+2	; wait more than 2 micro second
	jmp	short $+2
	jmp	short $+2
	jmp	short $+2
	in	al,70h
	push	eax
	mov	al,80h		; end read
	out	80h,al
	pop	eax
	ret
getrtc	endp

;*******************************
; dspbcd : display unpacked BCD
;
; in : ax = unpacked BCD
;      edi = VRAM address
;      fs = font data selector
;      es = VRAM selector
; out: edi = right charactor address
; call: dspc
; use: none
;
dspbcd	proc
	push	eax
	add	ax,3030h	; to ascii
	xchg	ah,al
	cmp	al,'0'
	jne	short dpbcd1
	mov	al,' '
dpbcd1:	call	dspc
	mov	al,ah
	call	dspc
	pop	eax
	ret
dspbcd	endp

;*******************************
; dsphl : display horizontal line
;
; in : ebp = start VRAM address
;      edx = double word width
;      eax = line pattern
; out: ebp = next line
; use: ecx,edi
;
dsphl	proc
	mov	edi,ebp
	mov	ecx,edx		; double word width
	rep	stosd
	add	ebp,VRAMW	; next line
	ret
dsphl	endp

;*******************************
; dspmenu : display menu
;
; in : esi = menu data address
;      menpos = menu position
; call: makadr,mcon,mcoff,dsphl
; use: eax,ebx,ecx,edx,esi,edi,ebp
;
dspmenu	proc
	mov	edi,esi
	call	makadr
	add	ebp,VRAMSIZ	; page 1
	shr	edx,2		; double word width
	call	mcoff		; mouse cursor off
	mov	eax,C$WFRLD
	call	dsphl		; display top frame line
;
	dec	ebx
	dec	ebx
	dec	edx
dpmn10:	mov	edi,ebp
	mov	ax,C$WFRL+(C$PANEL shl 4)+(C$PANEL shl 8)+(C$PANEL shl 12)
	stosw
	mov	ecx,edx
	mov	eax,C$PANELD
	rep	stosd
	mov	ax,C$PANEL+(C$PANEL shl 4)+(C$PANEL shl 8)+(C$WFRL shl 12)
	stosw
	add	ebp,VRAMW	; next line
	dec	ebx
	jnz	dpmn10
;
	mov	eax,C$WFRLD
	inc	edx
	call	dsphl		; display bottom frame line
;
	add	esi,8
	lodsb			; item number
	mov	ebx,esi
dpmn20:	movsx	esi,word ptr[ebx]	; string data address
	mov	edi,[esi]		; VRAM address
	movzx	ecx,byte ptr[esi+4]	; string byte width
	add	esi,5			; string address
	call	dspstr
	add	ebx,4		; next sting index
	dec	al
	jnz	dpmn20
	call	mcon		; mouse cursor on
	ret
dspmenu	endp

;*******************************
; filbox : erase box in page 1
;
; in : ebp = VRAM address in page 0
;      edx = byte width
;      ebx = hight
;      eax = fill patern
; call: mcon,mcoff
; use: eax,ebx,ecx,edx,ebp
;
filbox	proc
	add	ebp,VRAMSIZ	; page 1
	shr	edx,2		; double word width
	call	mcoff		; mouse cursor off
flbx10:	mov	edi,ebp
	mov	ecx,edx
	rep	stosd
	add	ebp,VRAMW	; next line
	dec	ebx
	jnz	flbx10
	call	mcon		; mouse cursor on
	ret
filbox	endp

;*******************************
; dspstr : display string
;      CTRL,ANK and Shift-JIS
;
; in : esi = string data address
;      ecx = string byte length
;      edi = VRAM address
;      knjidx = font index
;      ss = font index selector
;      fs = font data selector
;      es = VRAM selector
; out: edi = string tail address
; call: dspc,dspk
; use: none
;
dspstr	proc
	test	ecx,ecx
	jz	short dps99
	push	eax
	push	ebx
	push	ecx
	push	esi
;-------------------------------
; delivery
;-------------------------------
dps10:	lodsb			; load string byte data
	cmp	al,80h
	jbe	short dps20	; CTAL,ASCII,GRAPH
	cmp	al,9Fh
	jbe	short dps40	; KANJI
	cmp	al,0E0h
	jb	short dps20	; KANA
	cmp	al,0EFh
	jbe	short dps40	; KANJI
;-------------------------------
; display single byte charactor
;-------------------------------
dps20:	call	dspc		; display charactor
	loop	dps10		; go to load next cahractor
	jmp	short dps90
;-------------------------------
; KANJI charactor
; in : al = Shift-JIS first byte
;-------------------------------
dps40:	mov	ah,al		; save shift JIS first byte
	lodsb			; load shift JIS second byte
	cmp	al,40h		; check second byte
	jae	short dps44
dps42:	dec	esi		; rewind source charactor pointer
	mov	al,ah		; load pseud-first byte
	jmp	dps20		; go to put one byte charctor on VRAM
dps44:	cmp	al,0FCh
	ja	dps42		; illegal socond byte
	cmp	ecx,2
	jb	dps42		; 漢字途中で切れている
	cmp	al,7Fh
	je	dps42		; illegal second byte
;
	adc	al,-40h-1	; calculate index pointer
	cmp	ah,9Fh
	jbe	short dps50
	sub	ah,0E0h-0A0h
dps50:	sub	ah,80h
	shl	eax,1
	cwde			; font number index pointer
	assume	ds:stack
	movzx	ebx,knjidx[eax]	; get font number
	assume	ds:data
	shl	ebx,5		; font offset address
	call	dspk		; display kanji
;
	sub	ecx,2		; count down string byte length
	ja	dps10		; go to load next cahractor
;
dps90:	pop	esi
	pop	ecx
	pop	ebx
	pop	eax
dps99:	ret
dspstr	endp

;*******************************
; setfp : set font page index
;
; in : ax = page head number
;      ecx = page width
;      (es:edi) = index pointer
; out: edi = next page pointer
; use: ax,ebx,edx,ecx
;
setfp	proc
	mov	ebx,4		; set line counter
	mov	edx,ecx		; save page width
stfp10:	push	edi
	push	eax
stfp12:	stosw			; store font number
	inc	eax		; next font number
	loop	stfp12
	pop	eax
	pop	edi
	add	edi,256*2-5Eh*2	; go to left part on next line
	add	eax,32
	mov	ecx,edx
	push	edi
	push	eax
stfp14:	stosw			; store font number
	inc	eax		; next font number
	loop	stfp14
	pop	eax
	pop	edi
	add	ax,32
	add	edi,5Eh*2	; go to right part on line
	mov	ecx,edx
	dec	ebx
	jnz	stfp10
	shl	edx,1
	add	edi,edx
	sub	edi,256*4*2	; go to right page
	ret
setfp	endp

;*******************************
; fillscr : fill screen
;
; in : eax = fill code
;      edi = VRAM address
;      es = VRAM selector
; use: ebx,ecx,edi
;
fillscr	proc
	mov	ebx,VRAMDH
filsc1:	mov	ecx,VRAMDW/4
	push	edi
	rep	stosd
	pop	edi
	add	edi,VRAMW
	dec	ebx
	jnz	filsc1
	ret
fillscr	endp

;*******************************
; chkran : check rectangle range
;
; in : edi = rectangle data address
;      cx = x position
;      dx = y position
; out: cf = clear by within
;
chkran	proc
	cmp	cx,[edi].x0	; check left range
	jb	short chkra9	; too left
	cmp	dx,[edi].y0	; check up range
	jb	short chkra9	; too up
	cmp	[edi].x1,cx	; check right range
	jb	short chkra9	; too right
	cmp	[edi].y1,dx	; check down range
chkra9:	ret
chkran	endp

;*******************************
; eramen : erase system menu
;
; in : curmenu = current menu
;      menpos = menu button
; use: all
; call: makadr,filbox,select
;
eramen	proc
	mov	edi,curmenu	; current menu data address
	call	makadr		; make address
	xor	eax,eax
	call	filbox		; erase menu
	mov	edi,offset menpos
	call	select		; normal button
	ret
eramen	endp

;*******************************
; mcoff : mouse cursor off
;
; in : es = VRAM selector
; use: none
; call: eramou
;
mcoff	proc
	push	eax
	push	ecx
	push	esi
	push	edi
	mov	al,FALSE
	xchg	mouflg,al	; mouse cursor display flag off
	cmp	al,FALSE
	je	short mcoff9	; already off
	mov	edi,dword ptr bakmx	; background pattern position
	call	eramou		; erase mouse
mcoff9:	pop	edi
	pop	esi
	pop	ecx
	pop	eax
	ret
mcoff	endp

;*******************************
; mcon : mouse cursor on
;
; in : es = VRAM selector
; use: none
; call: dspmou
;
mcon	proc
	push	eax
	push	ebx
	push	ecx
	push	esi
	push	edi
	mov	al,FALSE
	xchg	mouflg,al	; stop mouse
	cmp	al,TRUE		; check mouse cursor state
	je	short mcon8	; already on
	call	dspmou		; display mouse cursor
mcon8:	mov	mouflg,TRUE	; mouse cursor display flag on
	pop	edi
	pop	esi
	pop	ecx
	pop	ebx
	pop	eax
	ret
mcon	endp

;*******************************
; chgmc : change mouse cursor
;
; in : al = mouse pattern type
;      es = VRAM selector
; use: none
; call: eramou,dspmou
;
chgmc	proc
	cmp	al,mctype		; check same type
	je	short chgmc9		; unnecessary
	push	eax
	push	ebx
	push	ecx
	push	esi
	push	edi
	mov	bl,FALSE
	xchg	mouflg,bl		; mouse cursor display flag off
	mov	mctype,al		; renew cursor type
	cbw
	imul	ax,MOUPATH*MOUPATW*2
	add	ax,offset moupat
	mov	moucur[4],ax		; set mouse pattern address
	cmp	bl,FALSE		; was mouse cursor off ?
	je	short chgmc8		; unnecessary redrow cursor
	mov	edi,dword ptr bakmx	; background pattern position
	call	eramou			; erase mouse
	call	dspmou			; display mouse cursor
	mov	mouflg,TRUE		; mouse cursor display flag on
chgmc8:	pop	edi
	pop	esi
	pop	ecx
	pop	ebx
	pop	eax
chgmc9:	ret
chgmc	endp

;*******************************
; xorcur : xor cursor
;
; in : curb = current byte in page
; use: none
; call: xorchr
;
xorcur	proc
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	edi
	movzx	eax,curb
	mov	edx,eax
	and	al,0Fh
	imul	eax,3*4		; relative x position
	and	dl,0F0h		; relative y position
	shl	edx,VRAMP
	push	eax
	push	edx
	mov	edi,PAGADR-VRAMW*(CHRH+8)
	add	edi,eax		; column gauge address
	mov	dl,2		; column gauge charactor width
	call	xorchr		; xor column gauge
	add	edi,(16*16+8+8)*VRAMW		; column sum address
	call	xorchr		; xor column sum
	pop	edx
	pop	eax
	push	eax
	push	edx
	mov	edi,HADRADR
	add	edi,edx		; address gauge address
	mov	dl,6		; address gauge charactor width
	call	xorchr		; xor address gauge
	add	edi,(6+1+16*3)*4-VRAMW*16
	mov	dl,2
	call	xorchr		; xor line sum
	pop	edx
	pop	eax
;
	push	edx
	movzx	edi,nibpos
	shl	edi,2
	add	eax,PAGADR
	add	eax,edx
	add	edi,eax
	mov	dl,1
	call	xorchr		; xor hex charactor
	pop	edx
;
	movzx	eax,curb
	and	al,0Fh		; relative x position
	shl	al,2
	add	eax,ANKADR
	add	eax,edx
	mov	edi,eax
	mov	dl,1
	call	xorchr		; xor ascii charactor
	pop	edi
	pop	edx
	pop	ecx
	pop	ebx
	pop	eax
	ret
xorcur	endp

;*******************************
; xorchr : xor charactor
;
; in : edi = VRAM address
;      dl = charactor width
;      es = VRAM selector
; out: edi = bottom line
; use: eax,bl,ecx,edi
;
xorchr	proc
	mov	eax,C$CURD
	mov	bl,CHRH
xorc10:	movzx	ecx,dl
	push	edi
xorc20:	xor	es:[edi],eax
	add	edi,4
	loop	xorc20
	pop	edi
	add	edi,VRAMW	; next line
	dec	bl
	jnz	xorc10
	ret
xorchr	endp

;*******************************
; gohead : top of file
;
; use: all
; call: xorcur,dspag
;
gohead	proc
	call	xorcur		; erase cursor
	xor	eax,eax
	mov	nibpos,al	; set nible position
	xchg	curptr,eax	; set pointer
	mov	lastmp,eax	; 移動前の位置を保存する
	call	dspag		; display page
	call	xorcur		; display cursor
	ret
gohead	endp

;*******************************
; gotail : tail of file
;
; use: all
; call: xorcur,dspag
;
gotail	proc
	call	xorcur		; erase cursor
	mov	eax,datsiz	; file size
	xchg	curptr,eax	; set current pointer to tail
	mov	lastmp,eax	; 移動前の位置を保存する
	mov	nibpos,0	; set nible position
	call	dspag		; display page
	call	xorcur		; display cursor
	ret
gotail	endp

;*******************************
; dspadr : display address
;          on window
;
; in : edi = relative VRAM address
;      eax = address data
;      winadr = window VRAM address
; use: eax,edi
; call: dsphex
;
dspadr	proc
	add	edi,winadr	; window base VRAM address
	rol	eax,16		; high byte
	call	dsphex
	rol	eax,8		; middle byte
	call	dsphex
	rol	eax,8		; low byte
	call	dsphex
	ret
dspadr	endp

;*******************************
; dspja : display jump address
;
; use: eax,edi
; call: dspadr,mcoff,mcon
;
dspja	proc
	mov	edi,JHINADR		; hex absolute VRAM address
	mov	eax,jmpadr		; jump address
	call	mcoff			; mouse cursor off
	call	dspadr			; display jump address
	call	mcon			; mouse cursor on
	ret
dspja	endp

;*******************************
; jump : jump
;
; use: all
; call: dspwf,dspws,dspwb,dspja
;       getew,chkwb,rev6h,chkar
;       xorcur,dspag,mcon,mcoff,revwb
;
jump	proc
	mov	eax,datsiz		; ジャンプ番地初期値の修正
	cmp	eax,jmpadr
	jae	short jmp10		; 修正不要
	mov	jmpadr,eax
;-------------------------------
; display window
;-------------------------------
jmp10:	mov	esi,offset window4
	call	dspwf			; display window frame
jmp12:	call	mcoff			; erase mouse cursor
	mov	ebx,offset w4str	; display window strings
	call	dspws
	mov	ebx,offset w4box	; display window boxes
	call	dspwb
	call	dspja			; display jump address
;-------------------------------
; get event
; in : esi = window data
;-------------------------------
jmp20:	call	getew			; get event through window
	cmp	al,EvtClose
	je	jmp90			; close window
	cmp	al,EvtUpdate
	je	jmp12			; display window contents
	cmp	al,M$RDown
	je	short jmp90		; close window
	cmp	al,M$LDown
	jne	jmp20			; invalid event
;-------------------------------
; 左ボタン押し下げ位置を調べる
; in : ecx = ウィンドウ内Ｘ位置
;      edx = ウィンドウ内Ｙ位置
;      bx = 左ボタン押し下げ時刻
;-------------------------------
	mov	dwntime,bx		; 左ボタン押し下げ時刻を保存する
	mov	ebx,offset w4box	; ボックス範囲内か調べる
	call	chkwb
	jc	jmp20			; ボックス範囲外
	test	eax,eax
	jnz	short jmp70		; 上書実行
;-------------------------------
; 番地の変更
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;-------------------------------
jmp40:	mov	eax,jmpadr		; 現在番地
	call	rev6h			; 16進数を増減する
	cmp	eax,datsiz		; 番地上限のチェック
	ja	short jmp48		; 不正番地
	mov	jmpadr,eax		; 番地更新
	call	dspja			; 新ジャンプ番地の表示
jmp48:	call	chkar			; オートリピートチェック
	jnc	jmp40			; リピートする
	jmp	jmp20
;-------------------------------
; execute button press
; in : ebx = ボックスデータ番地
;-------------------------------
jmp70:	call	revwb		; button press
;
	call	xorcur		; erase cursor
	mov	nibpos,0	; set nible position to high
	mov	eax,jmpadr	; jump address
	xchg	curptr,eax	; set new pointer
	mov	lastmp,eax	; 移動前の位置を保存
	call	dspag		; display page
	call	xorcur		; display cursor
;
jmp90:	mov	esi,offset window4
	call	erawin		; erase window
	ret
jump	endp

;*******************************
; alldel : all delete
;
; use: all
; call: warn,xorcur,dspsiz,dspag
;       savdcp
;
alldel	proc
	mov	esi,offset warn3
	call	warn			; warning
	jc	short alde90		; quit
;
	call	xorcur			; erase cursor
	xor	eax,eax
	mov	datsiz,eax		; data size to zero
	mov	curptr,eax		; pointer to top
	mov	nibpos,al		; nible position high
	mov	eax,bufadr
	mov	datend,eax		; data end address to base
	call	savdcp			; データ変更位置の保存
	call	dspsiz			; 新データサイズの表示
	call	dspag			; display new page
	call	xorcur			; display cursor
;
alde90:	ret
alldel	endp

;*******************************
; makitn : make menu item number
;
; in : edi = menu data address
;      dx = cursor y position
; out: al = item number
; use: dx
;
makitn	proc
	sub	dx,[edi].y0	; relative y position
	xor	al,al		; initiarize menu item number
mkitn1:	inc	al
	sub	dx,ITEMH
	jae	mkitn1
	ret
makitn	endp

;*******************************
; erawin : erase window
;
; in : esi = window data
; use: all
; call: filbox
;
erawin	proc
	movzx	ebp,[esi].winy	; y position
	shl	ebp,VRAMP
	or	bp,[esi].winx	; VRAM address
	movzx	edx,[esi].winw	; box byte width
	movzx	ebx,[esi].winh	; box hight
	xor	eax,eax
	call	filbox	; erase box in page 1
	ret
erawin	endp

;*******************************
; strlen : get string length
;
; in : esi = string address
; out: ecx = byte length
; use: none
;
strlen	proc
	push	esi
	xor	ecx,ecx
	dec	ecx
stlen1:	inc	ecx
	inc	esi
	cmp	byte ptr [esi-1],0
	jne	stlen1
	pop	esi
	ret
strlen	endp

;*******************************
; getcd : get current directory
;         string address
;
; in : curdrv = current drive number
; out: esi = destination address
; use: none
;
getcd	proc
	movzx	esi,curdrv		; current drive number
	imul	esi,size drvstr
	add	esi,offset drvdat	; current directory string address
	ret
getcd	endp

;*******************************
; makfp : make file pathlist
;
; in : edx = file name(ASCIZ)
;      edi = save address
; use: eax
; call: getcd,strcpy
;
makfp	proc
	push	esi
	push	edi
	call	getcd		; get current directory string address
makfp1:	lodsb			; copy directory string
	test	al,al
	jz	short makfp2
	mov	[edi],al
	inc	edi
	jmp	makfp1
;
makfp2:	mov	esi,edx
	cmp	byte ptr [edi-1],'\'	; check directory last charactor
	je	short makfp3
	mov	byte ptr [edi],'\'
	inc	edi
makfp3:	call	strcpy		; copy file name
	pop	edi
	pop	esi
	ret
makfp	endp

;*******************************
; erak : 漢字文字消去
;
; in : edi = ＶＲＡＭ番地
;      es = ＶＲＡＭセレクタ
; out: edi = 文字の右の番地
; use: eax
;
erak	proc
	push	ecx
	mov	eax,C$PANELD	; パネルカラーコード
	mov	ecx,16		; 行数カウンタ
erak10:	stosd
	stosd
	add	edi,VRAMW-8	; 次の行番地へ
	loop	erak10
	add	edi,8-VRAMW*16	; 右文字先頭番地へ
	pop	ecx
	ret
erak	endp

;*******************************
; erastr : erase string
;          fill with C$PANEL
;
; in : edi = VRAM address
;      cl = string length
; out: edi = right address
; use: none
;
erastr	proc
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	ebp
	mov	bl,CHRH		; chractor hight
	movzx	edx,cl		; double word width
	mov	ebp,edx
	shl	ebp,2
	sub	ebp,VRAMW	; line distance
	mov	eax,C$PANELD	; fill pattern
erstr1:	mov	ecx,edx
	rep	stosd
	sub	edi,ebp
	dec	bl
	jnz	erstr1
	add	edi,ebp
	sub	edi,VRAMW*(CHRH-1)
	pop	ebp
	pop	edx
	pop	ecx
	pop	ebx
	pop	eax
	ret
erastr	endp

;*******************************
; dspfn : display file name
;         within 12 column
;
; in : esi = directory file slot
;      edi = start VRAM address
; out: edi = right address
; use: none
; call: strlen,dspstr,erastr
;       dspc
;
dspfn	proc
	push	ecx
	push	esi
	add	esi,offset fname
	call	strlen		; get file name string length
	test	[esi-offset fname].fattr,10000b
	jnz	dpfn5		; directory file
	call	dspstr		; display file name
dpfn2:	sub	cl,12
	neg	cl
	call	erastr		; erase rest chractor
	pop	esi
	pop	ecx
	ret
;
dpfn5:	mov	al,'<'
	call	dspc
	call	dspstr		; display file name
	mov	al,'>'
	call	dspc
	inc	ecx
	inc	ecx
	jmp	dpfn2
dspfn	endp

;*******************************
; dsp8d : display file/memory size
;         within 8 column
;
; in : eax = file byte size
;      edi = start VRAM address
; out: edi = right address
; use: none
; call: dspc,erastr
;
dsp8d	proc
	push	eax
	push	ecx
	push	edx
	push	esi
	mov	esi,offset decdat
	mov	ecx,7
dp8d10:	cmp	eax,[esi]
	jae	short dp8d20
	push	ecx
	mov	cl,1
	call	erastr		; erase 1 chractor
	pop	ecx
	add	esi,4
	loop	dp8d10
	jmp	short dp8d80
;
dp8d20:	cdq
	div	dword ptr [esi]
	add	al,'0'
	call	dspc
	add	esi,4
	mov	eax,edx
	loop	dp8d20
;
dp8d80:	add	al,'0'
	call	dspc
	pop	esi
	pop	edx
	pop	ecx
	pop	eax
	ret
dsp8d	endp

;*******************************
; dsp2dig : display 2 digit
;
; in : al = binary
;      edi = start VRAM address
; out: edi = right address
; use: none
; call: dspc
;
dsp2dig	proc
	push	eax
	push	edx
	xor	ah,ah
	mov	dl,10
	div	dl
	add	ax,3030h
	call	dspc	; display high digit
	mov	al,ah
	call	dspc	; display low digit
	pop	edx
	pop	eax
	ret
dsp2dig	endp

;*******************************
; dspfd : display file date
;         within 10 column
;
; in : ax = file date
;      edi = start VRAM address
; out: edi = right address
; use: none
; call: dspc,dsp2dig
;
dspfd	proc
	push	eax
	push	edx
	mov	edx,eax		; save date
	shr	ax,9		; year bits
	add	al,80
	cmp	al,100
	jb	dpfd10
	push	eax
	mov	al,'2'		; display high decade '20'
	call	dspc
	mov	al,'0'
	call	dspc
	pop	eax
	sub	al,100
	jmp	short dpfd12
dpfd10:	push	eax
	mov	al,'1'		; diaplay high decade '19'
	call	dspc
	mov	al,'9'
	call	dspc
	pop	eax
dpfd12:	call	dsp2dig		; display low decate
;
	mov	al,'.'		; delimiter
	call	dspc
;
	mov	eax,edx
	shr	eax,5
	and	al,1111b	; month
	call	dsp2dig		; display month
;
	mov	al,'.'		; delimiter
	call	dspc
;
	mov	al,dl
	and	al,11111b	; date
	call	dsp2dig		; display date
	pop	edx
	pop	eax
	ret
dspfd	endp

;*******************************
; dspft : display file time
;         within 5 column
;
; in : ax = file time
;      edi = start VRAM address
; out: edi = right address
; use: none
; call: dsp2dig,dspc
;
dspft	proc
	push	eax
	push	edx
	mov	edx,eax
	shr	ax,11	; hour
	call	dsp2dig	; display hour
	mov	al,':'
	call	dspc	; display delimiter
	mov	eax,edx
	shr	ax,5
	and	al,111111b
	call	dsp2dig
	pop	edx
	pop	eax
	ret
dspft	endp

;*******************************
; dsp1dec : display 1 decimal
;
; in : edi = VRAM address
;      al = binary
; use: none
; call: putc
;
dsp1dec	proc
	push	eax
	push	edx
	push	edi
	mov	dl,100
	xor	ah,ah
	div	dl
	add	al,'0'
	call	dspc
	mov	al,ah
	cbw
	mov	dl,10
	div	dl
	add	ax,3030h
	call	dspc
	mov	al,ah
	call	dspc
	pop	edi
	pop	edx
	pop	eax
	ret
dsp1dec	endp

;*******************************
; dspdsn : display directory slot
;          total number
;
; in : esi = window data
; use: eax,ebx,ecx,edx,edi,ebp
; call: dspc,dsp1dec
;
dspdsn	proc
	cmp	dbflg,TRUE	; check directory buffer ready flag
	jne	short dpdsn9	; invalid
	movzx	edi,[esi].winy	; window y position
	add	edi,VRAMH+DBTSNY	; VRAM y position
	shl	edi,VRAMP
	add	di,[esi].winx
	add	di,DBTSNX-4	; string start VRAM address
	mov	al,'/'
	call	dspc
	mov	al,dsnum	; directory slot total number
	call	dsp1dec
dpdsn9:	ret
dspdsn	endp

;*******************************
; clreb : clear event buffer
;
; use: eax
;
clreb	proc
	xor	eax,eax
	cli
	mov	ebcount,al
	mov	dword ptr ebhead,eax
	sti
	ret
clreb	endp

;*******************************
; dspdp : display directory page
;
; in : esi = window data
;      gs = PSP
; use: eax,ebx,ecx,edx,edi,ebp
; call: makfp,dspfn,dsp8d,dspfd
;       dspft,erastr,dspdsn
;       dsp1dec,clreb
;       chgmc,mcon,mcoff
;
dspdp	proc
	push	esi
	cmp	dbflg,TRUE	; check buffer ready
	je	dpdp20		; ok!
;-------------------------------
; read directory file
;-------------------------------
	mov	al,M$TCUP	; mouse cursor type
	call	chgmc		; change mouse cursor
	call	mcon		; mouse cursor on
	mov	headfn,0	; page head file number
	mov	dbflg,TRUE	; set directory buffer ready flag
	mov	dsnum,0		; initialize directory slot total number
;
	mov	edx,offset allfile
	mov	edi,offset pbbuf
	call	makfp		; make file pathlist in pbbuf
	mov	edx,edi
	mov	ah,4Eh		; find first file
	mov	ecx,16h		; hidden+system+directory
	int	21h
	jc	short dpdp18	; search error
;
	mov	ebp,offset dirbuf
dpdp10:	mov	edx,80h+15h	; file attribute offset
	mov	ecx,size fildat	; file data size
	cmp	gs:[edx].fname,'.'	; itself/parent
	je	dpdp14		; invalid
	inc	dsnum		; increment directory slot number
	jnz	short dpdp12	; exist save area
	dec	dsnum		; cut out
	jmp	short dpdp18
dpdp12:	mov	al,gs:[edx]	; copy file data
	mov	[ebp],al
	inc	edx
	inc	ebp
	loop	dpdp12
;
dpdp14:	mov	ah,4Fh		; find next file
	int	21h
	jnc	dpdp10		; existed
dpdp18:	call	mcoff		; mouse cursor off
	mov	al,M$POINT	; mouse cursor type
	call	chgmc		; change mouse cursor
	call	dspdsn		; display directory slot total number
	call	clreb		; clear event buffer
;-------------------------------
; calculate address
; in : esi = window data
;-------------------------------
dpdp20:	mov	dl,dsnum	; slot total number
	movzx	ebx,headfn	; page head file number
	sub	dl,bl
	jnc	short dpdp22
	xor	dl,dl
dpdp22:	cmp	dl,dbfnum
	jbe	short dpdp24
	mov	dl,dbfnum
dpdp24:	imul	ebx,size fildat	; make offset in buffer
	add	ebx,offset dirbuf	; directory slot start address
;
	mov	ebp,winadr	; window address
	mov	edi,ebp
	add	edi,DBHSNY*VRAMW+DBHSNX
	mov	al,headfn	; page head file number
	inc	al		; base number 1
	call	dsp1dec
	mov	edi,ebp
	add	edi,(DBFILY+4)*VRAMW+DBFILX+2
;
	cmp	dbwide,TRUE	; check wide display
	jne	short dpdp40	; detailed dispaly mode
;-------------------------------
; wide dispaly
; in : ebx = start slot address
;      edi = start VRAM address
;      dl = display item number
;-------------------------------
	mov	esi,ebx
	mov	bh,DLCNUM	; set column counter
dpdp30:	mov	bl,DLLNUM	; set line counter
dpdp32:	test	dl,dl		; check item exist
	jz	short dpdp38	; nonexistent
	call	dspfn		; display file name
	add	esi,size fildat	; next file item
	dec	dl		; count down display item number
dpdp34:	add	edi,VRAMW*CHRH-12*4
	dec	bl		; check line end
	jnz	dpdp32
	add	edi,13*4-DLLNUM*VRAMW*CHRH
	dec	bh
	jnz	dpdp30
;
	sub	edi,14*4
	mov	ch,DLLNUM	; set line counter
	mov	cl,1
dpdp36:	call	erastr
	add	edi,CHRH*VRAMW-4
	dec	ch
	jnz	dpdp36
	jmp	short dpdp50
;
dpdp38:	mov	cl,12
	call	erastr		; erase rest chractor
	jmp	dpdp34
;-------------------------------
; detailed display
; in : ebx = start slot address
;      edi = start VRAM address
;      dl = display item number
;-------------------------------
dpdp40:	mov	esi,ebx
	mov	bl,DLLNUM	; set line counter
dpdp42:	dec	dl		; count down display item number
	js	short dpdp48	; nonexistent
	call	dspfn		; display file name
	add	edi,4		; skip 1 column
	mov	eax,[esi].fsize	; file size
	call	dsp8d		; display file size
	mov	cl,1
	call	erastr		; erase 1 chractor
	mov	ax,[esi].fdate	; file date
	call	dspfd		; display file date
	mov	cl,1
	call	erastr		; erase 1 chractor
	mov	ax,[esi].ftime	; file time
	call	dspft		; display file time
dpdp44:	add	esi,size fildat	; next file item
	add	edi,VRAMW*CHRH-38*4
	dec	bl		; check line end
	jnz	dpdp42
	jmp	short dpdp50
;
dpdp48:	mov	cl,38
	call	erastr		; erase rest chractor
	jmp	dpdp44
;-------------------------------
; head file number
;-------------------------------
dpdp50:

	pop	esi
	ret
dspdp	endp

;*******************************
; wbup : window box up
;
; in : edi = left up address
;      edx = byte width
;      ebx = pixcel hight
;      es = VRAM selector
; use: al,ecx
;
wbup	proc
	push	edi
	mov	al,C$BUTH*16+C$BUTH
	mov	ecx,edx
	push	edi
	rep	stosb
	pop	edi
;
	mov	ecx,ebx
	dec	ecx
	dec	ecx
wbup10:	add	edi,VRAMW
	mov	byte ptr es:[edi],C$BUTH+C$PANEL*16
	mov	byte ptr es:[edi+edx-1],C$PANEL+C$BUTL*16
	loop	wbup10
;
	add	edi,VRAMW
	mov	al,C$BUTL*16+C$BUTL
	mov	ecx,edx
	rep	stosb
	pop	edi
	ret
wbup	endp

;*******************************
; dspcd : display current
;         directory string
;
; in : ebp = window address
;      esi = window data
; use: ecx,edi
;
dspcd	proc
	push	esi
	mov	edi,ebp
	add	edi,DBDIRY*VRAMW+DBDIRX	; directory string VRAM address
	call	getcd		; get current directory path address
	call	strlen		; get string length
	call	dspstr		; display current directory string
	pop	esi
	ret
dspcd	endp

;*******************************
; getwa : get window address
;
; in : esi = window data
; out: ebp = window address
; use: none
;
getwa	proc
	movzx	ebp,[esi].winy
	add	ebp,VRAMH	; VRAM y position
	shl	ebp,VRAMP
	add	bp,[esi].winx
	ret
getwa	endp

;*******************************
; xorcd : xor current drive
;
; in : ebp = window address
;      curdrv = current drive number
; use: eax,ebx,ecx,edx
;
xorcd	proc
	push	ebp
	add	ebp,DBDEVY*VRAMW+DBDEVX	; drive string start VRAM address
	movzx	eax,curdrv	; current drive number
	shl	eax,3
	add	ebp,eax
	mov	edx,2*4		; select byte width
	mov	ebx,CHRH	; select hight
	mov	al,C$SELB	; select bit data
	call	xorbox		; xor current drive charactor
	pop	ebp
	ret
xorcd	endp

;*******************************
; dspdb : display disk browser
;
; in : esi = window data
; use: eax,ebx,ecx,edx,edi,ebp
; call: mcoff,wbup,dspk,dspstr
;       xorcd,dspcd,dspdp,dspdsn,mcon
;
dspdb	proc
	mov	ebp,winadr	; window address
;-------------------------------
; file display area frame
; in : ebp = window address
;-------------------------------
	mov	edi,ebp
	add	edi,DBFILY*VRAMW+DBFILX
	mov	edx,DBFILW	; byte width
	mov	ebx,DBFILH	; hight
	call	mcoff		; mouse cursor off
	call	wbup		; frame up
;-------------------------------
; disk drive names
; in : ebp = window address
;-------------------------------
	mov	edi,ebp
	add	edi,DBDEVY*VRAMW+DBDEVX	; drive string start VRAM address
	mov	eax,offset drvdat	; drive data address
	movzx	ecx,drvnum		; drive total number
dpdb10:	movzx	ebx,[eax].drvnam	; drive name(ASCII)
	add	ebx,0261h-'A'		; to kanji font number
	shl	ebx,5			; to kanji font address
	call	dspk			; display kanji font
	add	eax,size drvstr		; next drive data
	loop	dpdb10
;-------------------------------
; buttons
; in : ebp = window address
;-------------------------------
	push	esi
	mov	esi,offset dbbut	; button top strings
	mov	edi,ebp
	add	edi,(DBBUTY+2)*VRAMW+DBBUTX+2
	mov	ecx,dbbutL
	call	dspstr		; display button top string
	mov	edi,ebp
	add	edi,DBBUTY*VRAMW+DBBUTX
	mov	edx,DBBUTW	; button byte width
	mov	ebx,DBBUTH	; button hight
	mov	ah,3		; button counter
dpdb20:	call	wbup		; button up
	add	edi,edx		; got to right button
	dec	ah
	jnz	dpdb20
	pop	esi
;-------------------------------
; display current directory data
; device/directory/contents
; in : ebp = window address
;      esi = window data
;-------------------------------
	call	xorcd		; intense current drive stirng
	call	dspcd		; display current directory string
	call	dspdsn		; display directory slot total number
	call	dspdp		; display directory page
	call	mcon		; mouse cursor on
	ret
dspdb	endp

;*******************************
; xorstr : xor string
;
; in : edi = VRAM address
;      cl = string length
; use: eax,ebx
; call: xorbox
;
xorstr	proc
	push	ecx
	push	edx
	push	ebp
	mov	ebp,edi
	movzx	edx,cl
	shl	edx,2		; byte width
	mov	ebx,CHRH	; hight
	mov	al,C$SELB	; select bit data
	call	xorbox		; xor current drive charactor
	pop	ebp
	pop	edx
	pop	ecx
	ret
xorstr	endp

;*******************************
; xorwb : xor window button
;
; in : ebp = button address in window
; use: eax,ebx,ecx,edx
;
xorwb	proc
	push	ebp
	add	ebp,winadr
	mov	edx,WBUTW	; select byte width
	mov	ebx,WBUTH	; select hight
	mov	al,C$SELB	; select bit data
	call	xorbox		; intense button
	pop	ebp
	ret
xorwb	endp

;*******************************
; evtdb : process event
;         in disk browser
;
; in : esi = window data
;      al = event type
;      bx = event occured time
;      ecx = relative x position
;      edx = relative y position
; out: edx = file name address
; err: cf = set by no path select
; use: eax,ebx,ecx,edx,edi,ebp
; call: mcoff,dspdp,erastr,xorcd
;       xorwb,mcon,xorfn
;       getcd,dspcd
;
evtdb	proc
	cmp	al,M$LDown	; left button down ?
	jne	short evdb99	; invalid
;-------------------------------
; check area at left down
; in : ecx = relative x position
;      edx = relative y position
;-------------------------------
	cmp	edx,DBDEVY
	jb	short evdb99
	cmp	edx,DBDEVY+CHRH
	jb	short evdb30	; go to check device change
	cmp	edx,DBDIRY
	jb	short evdb99
	cmp	edx,DBDIRY+CHRH
	jb	evdb40		; go to directory up
	cmp	edx,DBBUTY
	jb	short evdb99
	cmp	edx,DBBUTY+DBBUTH
	jb	evdb50		; go to check button
	sub	edx,DBFILY+4
	jb	short evdb99
	cmp	dx,DBFILH-8
	jb	evdb60		; go to choose file
evdb99:	stc			; quit end
	ret
;-------------------------------
; device change
; in : ecx = relative x position
;      esi = window data
;-------------------------------
evdb30:	sub	ecx,DBDEVX
	jb	short evdb39	; no change
	shr	ecx,3		; to device string number
	cmp	cl,drvnum	; check effective
	jae	short evdb39	; invalid
	cmp	cl,curdrv	; check same drive
	je	short evdb39	; invalid
	push	ecx
	call	mcoff		; mouse cursor off
	mov	ebp,winadr
	call	xorcd		; current drive stirng tp normal
	push	esi
	call	getcd		; get old directory path address
	call	strlen		; get string length
	mov	edi,ebp
	add	edi,DBDIRY*VRAMW+DBDIRX	; directory string VRAM address
	call	erastr		; erase old directory string
	pop	esi
	pop	eax
	mov	curdrv,al	; renew drive number
	call	xorcd		; intence new current drive stirng
evdb38:	mov	dbflg,FALSE	; directory buffer ready flag off
	call	dspcd		; display current directory string
	call	dspdp		; display new directory page
	call	mcon		; mouse cursor on
evdb39:	stc			; quit end
	ret
;-------------------------------
; directory up
; in : ecx = relative x position
;      esi = window data
;-------------------------------
evdb40:	sub	ecx,DBDIRX
	jb	short evdb49	; left over
	shr	ecx,2		; charactor position
	mov	edx,ecx		; save charactor position
	mov	ebp,esi		; save window data address
	call	getcd		; get current directory path address
	call	strlen		; get path length
	xchg	esi,ebp		; path address <-> window data address
evdb42:	cmp	edx,ecx
	jae	short evdb49	; right over
	cmp	byte ptr [ebp+edx],'\'
	je	short evdb44	; find new directory end
	inc	edx		; next position
	jmp	evdb42
;
evdb44:	cmp	dl,2
	jne	short evdb46
	inc	edx
evdb46:	mov	byte ptr [ebp+edx],0	; cut off directory string
	sub	ecx,edx		; erase string length
	mov	ebp,winadr
	add	ebp,DBDIRY*VRAMW+DBDIRX
	shl	edx,2
	add	ebp,edx
	mov	edi,ebp		; directory erase start VRAM address
	mov	dbflg,FALSE	; directory buffer ready flag off
	call	mcoff		; mouse cursor off
	call	erastr		; erase rest directory string
	call	dspdp		; display new directory page
	call	mcon		; mouse cursor on
evdb49:	stc			; quit end
	ret
;-------------------------------
; button press
; in : ecx = relative x position
;      esi = window data
;-------------------------------
evdb50:	sub	ecx,DBBUTX	; left side check
	jb	evdb49		; no change
	mov	ebp,DBBUTY*VRAMW	; VRAM y position
	cmp	cl,DBBUTW
	jb	short evdb54	; previous page
	cmp	cl,DBBUTW*2
	jb	short evdb56	; next page
	cmp	cl,DBBUTW*3
	jae	evdb49		; invalid
;
	add	ebp,DBBUTX+2*DBBUTW	; display button address
	cmp	dbwide,TRUE	; check current display mode
	je	short evdb52
	mov	dbwide,TRUE	; to wide display mode
	mov	dbfnum,DLLNUM*DLCNUM
	jmp	short evdb58	; go to display page
evdb52:	mov	dbwide,FALSE	; to detailed display mode
	mov	dbfnum,DLLNUM
	jmp	short evdb58	; go to display page
;
evdb54:	add	ebp,DBBUTX	; previous button address
	mov	al,headfn	; page head file number
	test	al,al
	jz	evdb49		; invalid
	sub	al,dbfnum
	jnc	short evdb57	; go to dispaly page 
	xor	al,al
	jmp	short evdb57	; go to dispaly page 
;
evdb56:	add	ebp,DBBUTX+DBBUTW	; next button address
	mov	al,headfn	; page head file number
	add	al,dbfnum
	cmp	al,dsnum	; compare slot total number
	jae	evdb49		; no page
evdb57:	mov	headfn,al	; renew page head file number
evdb58:	call	mcoff		; mouse cursor off
	call	xorwb		; button press
	push	ebp
	call	dspdp		; display directory page
	pop	ebp
	call	xorwb		; botton up
	call	mcon		; mouse cursor on
evdb59:	stc			; quit end
	ret
;-------------------------------
; choose file
; in : ecx = x position in window area
;      edx = y position in file area
;      esi = window data
;-------------------------------
evdb60:	sub	ecx,DBFILX
	jb	evdb59		; left over
	cmp	cx,DBFILW
	jae	evdb59		; right over
;
	mov	ebp,winadr	; window base address
	mov	edi,ebp
	add	edi,(DBFILY+4)*VRAMW+DBFILX+2
	shr	edx,4		; line number
	mov	eax,edx
	shl	eax,4+VRAMP
	add	edi,eax		; line address
	cmp	dbwide,TRUE	; check display mode
	jne	short evdb62	; detailed mode
	add	edi,ecx
	mov	eax,ecx
	mov	cl,13*4
	div	cl		; column number
	movzx	ecx,ah
	sub	edi,ecx		; file name address
	mov	cl,DLLNUM
	mul	cl
	add	dl,al		; file number in page
evdb62:	add	dl,headfn	; file number
	cmp	dl,dsnum	; check number
	jae	evdb59		; nonexist number
;
	imul	edx,size fildat	; make offset in buffer
	add	edx,offset dirbuf+offset fname	; directory slot name address
	call	mcoff		; mouse cursor off
	mov	cl,12		; file name length
	call	xorstr		; intense file name
	test	[edx-offset fname].fattr,10000b	; is directory ?
	jnz	short evdb70	; directory file
;
	call	mcon		; mouse cursor on
	clc			; select end
	ret
;-------------------------------
; directory down
; in : edx = directory name address
;      ebp = window VRAM address
;      esi = window data
;-------------------------------
evdb70:	push	esi
	call	getcd		; get current directory path address
	mov	edi,esi
	call	makfp		; make new directory
	pop	esi
	jmp	evdb38
evtdb	endp

;*******************************
; load : load file
;
; use: all
; call: dspwf,dspdb,getew,warn
;       evtdb,makfp,erawin,readf
;
load	proc
	cmp	datchg,FALSE	; check data change flag
	je	short load10	; not changed
	mov	esi,offset warn1
	call	warn		; overwrite warning
	jc	short load99	; quit
	mov	datchg,FALSE	; data change falg off
;
load10:	mov	esi,offset window1
	call	dspwf		; display window frame
load20:	call	dspdb		; display disk browser
load22:	call	getew		; get event through window
	cmp	al,EvtClose
	je	short load90	; close window
	cmp	al,EvtUpdate
	je	load20		; display window contents
	cmp	al,M$RDown
	je	short load90	; close window
	call	evtdb		; process event in disk browser
	jc	load22		; go to get next event
;
	mov	edi,offset pbbuf
	push	edi
	call	makfp		; make file pathlist in pbbuf
	pop	edx		; new pathlist address
	push	esi
	mov	al,FALSE	; not insert
	call	readf		; read file
	pop	esi
load90:	call	erawin		; erase window
load99:	ret
load	endp

;*******************************
; insert : load file
;
; use: all
; call: dspwf,dspdb,getew
;       evtdb,makfp,erawin,readf
;
insert	proc
	mov	esi,offset window2
	call	dspwf		; display window frame
ins10:	call	dspdb		; display disk browser
ins20:	call	getew		; get event through window
	cmp	al,EvtClose
	je	short ins90	; close window
	cmp	al,EvtUpdate
	je	ins10		; display window contents
	cmp	al,M$RDown
	je	short ins90	; close window
	call	evtdb		; process event in disk browser
	jc	ins20		; go to get next event
;
	mov	edi,offset pbbuf
	push	edi
	call	makfp		; make file pathlist in pbbuf
	pop	edx		; new pathlist address
	push	esi
	mov	al,TRUE		; insert
	call	readf		; read file
	pop	esi
ins90:	call	erawin		; erase window
	ret
insert	endp

;*******************************
; reload : reload
;
; use: all
; call: warn,readf
;
reload	proc
	cmp	datchg,FALSE		; check data changed
	je	short reld90		; no changed
	mov	edx,offset curfpn	; read path name
	cmp	byte ptr [edx],0	; check read path name
	je	short reld90		; no existence
;
	push	edx
	mov	esi,offset warn2
	call	warn			; warning
	pop	edx
	jc	short reld90		; quit
;
	mov	al,FALSE		; not insert
	call	readf			; read file
reld90:	ret
reload	endp

;*******************************
; dspsfn : display save file name
;          and cursor
;
; in : sfname = save file name
;      sfnptr = cursor pointer(0-11)
;      winadr = window base address
; out: sfnsiz = file name size
; use: eax,ebx,ecx,edi
; call: mcoff,mcon
;       strlen,dspstr,erastr,xorstr
;
dspsfn	proc
	push	esi
	mov	esi,offset sfname
	mov	edi,winadr
	add	edi,FBOXY*VRAMW+FBOXX
	push	edi
	call	strlen		; get file name string length
	mov	sfnsiz,cl	; set new file name length
	call	mcoff		; mouse cursor off
	call	dspstr		; display file name
	sub	cl,12
	neg	cl
	call	erastr		; erase rest chractor
;
	pop	edi
	movzx	eax,sfnptr	; file name pointer
	shl	eax,2
	add	edi,eax		; intense VRAM address
	mov	cl,1		; string length
	call	xorstr
	call	mcon		; mouse cursor on
	pop	esi
	ret
dspsfn	endp

;*******************************
; dspkb : display keyboard
;
; in : esi = window data
; use: eax,ebx,ecx,edx,ebp,edi
; call: mcoff,mcon,dspc
;       wbup,dspstr
;
dspkb	proc
	push	esi
	mov	ebp,winadr		; get window VRAM address
;-------------------------------
; display keyboard buttons
;-------------------------------
	mov	edi,ebp
	add	edi,(KBY+1)*VRAMW+KBX+(KBBUTW-4)/2; button string VRAM address
	mov	esi,offset kbstr	; keyboard string data address
	mov	edx,KBBUTW		; button byte width
	mov	ebx,KBBUTH		; button hight
	call	mcoff			; mouse cursor off
dpkb10:	mov	cl,KBBUTCN		; column counter
dpkb12:	lodsb				; load buttonstring
	test	al,al			; check button end
	jz	short dpkb20		; button end
	call	dspc			; display ANK charactor
	sub	edi,(KBBUTW+4)/2+VRAMW	; keybord button display VRAM address
	push	ecx
	call	wbup			; button frame up
	pop	ecx
	add	edi,KBBUTW+(KBBUTW-4)/2+VRAMW
	dec	cl			; count down
	jnz	dpkb12
	add	edi,KBBUTH*VRAMW-KBBUTW*13
	jmp	dpkb10
;-------------------------------
; display file name input box
; in : ebp = window VRAM address
;-------------------------------
dpkb20:	mov	edi,ebp
	add	edi,(FBOXY-2)*VRAMW+FBOXX-2	; file input box
	mov	edx,FBOXW+4			; box byte width
	mov	ebx,CHRH+4			; box hight
	call	wbup				; input box frame up
;-------------------------------
; display buttons
; in : ebp = window VRAM address
;-------------------------------
	mov	edi,ebp
	add	edi,(DELSBY+2)*VRAMW+DELSBX+2
	mov	esi,offset delstr	; delete button top strings
	lodsb
	movzx	ecx,al			; string byte length
	call	dspstr			; display button top string
	mov	edi,ebp
	add	edi,DELSBY*VRAMW+DELSBX
	mov	edx,DELSBW		; button byte width
	mov	ebx,DELSBH		; button hight
	call	wbup			; backspace button up
	add	edi,edx			; got to right button
	call	wbup			; delete button up
;
	mov	edi,ebp
	add	edi,EXECY*VRAMW+EXECX	; execute button address
	mov	edx,EXECW		; box byte width
	mov	ebx,EXECH		; box hight
	call	wbup			; execute button frame up
	add	edi,2*VRAMW+2
	mov	esi,offset execstr
	lodsb
	movzx	ecx,al
	call	dspstr
	call	mcon		; mouse cursor on
	pop	esi
	ret
dspkb	endp

;*******************************
; chkfn : check file name
;         length and control code
;
; in : edx = file name address
; err: cf = set by illegal
; use: none
;
chkfn	proc
	push	eax
	push	ecx
	push	edx
	mov	ecx,8+1
chkfn1:	mov	al,[edx]
	cmp	al,20h
	jbe	short chkfn8
	inc	edx
	cmp	al,'.'
	je	short chkfn2
	loop	chkfn1
;
chkfnE:	stc			; set carry
	jmp	short chkfn9	; illegal end
;
chkfn2:	mov	ecx,3+1
chkfn3:	mov	al,[edx]
	cmp	al,20h
	jbe	short chkfn4
	cmp	al,'.'
	je	chkfnE		; delimiter too much
	inc	edx
	loop	chkfn3
	jmp	chkfnE		; extension too long
chkfn4:	cmp	ecx,4
	je	chkfnE		; delimiter end or control
;
chkfn8:	test	al,al		; terminator check and clear carry
	jnz	chkfnE		; control code
chkfn9:	pop	edx
	pop	ecx
	pop	eax
	ret
chkfn	endp

;*******************************
; save : save file
;
; use: all
; call: dspwf,dspdb,dspkb,getew
;       evtdb,strcpy,dspsfn,erawin
;       makfp,writf,xorstr,mcon
;       xorwb,chkfn,wailu
;
save	proc
;-------------------------------
; display save window
;-------------------------------
save10:	mov	esi,offset window3
	call	dspwf		; display window frame
save12:	call	dspdb		; display disk browser
	call	dspkb		; display key board
save18:	call	dspsfn		; display save file name
;-------------------------------
; event get & check
;-------------------------------
save20:	call	getew		; get event through window
	cmp	al,EvtClose
	je	save90		; close window
	cmp	al,EvtUpdate
	je	save12		; update window contents
	cmp	al,M$RDown
	je	save90		; close window
	cmp	al,M$LDown
	jne	save20
;
	cmp	dx,DELSBY
	jb	short save22	; up over delete
	cmp	dx,DELSBY+DELSBH
	jae	short save22	; down over delete
	cmp	cx,DELSBX
	jb	short save22	; left over delete
	cmp	cx,DELSBX+DELSBW*2
	jb	save50		; delete button press
save22:	cmp	dx,KBY
	jb	short save24	; up over keyboard
	cmp	dx,KBY+KBH
	jae	short save24	; down over keyboard
	cmp	cx,KBX
	jb	short save24	; left over keyboard
	cmp	cx,KBX+KBW
	jb	save60		; keyboard press
save24:	cmp	dx,FBOXY
	jb	short save26	; up over file box
	cmp	dx,FBOXY+FBOXH
	jae	short save26	; down over file box
	cmp	cx,FBOXX
	jb	short save26	; left over file box
	cmp	cx,FBOXX+FBOXW
	jb	save70		; press in file box
save26:	cmp	dx,EXECY
	jb	short save40	; up over execute
	cmp	dx,EXECY+EXECH
	jae	short save40	; down over execute
	cmp	cx,EXECX
	jb	short save40	; left over execute
	cmp	cx,EXECX+EXECW
	jb	save80		; execute to save
;
save40:	call	evtdb		; process event in disk browser
	jc	save20		; go to get next event
;-------------------------------
; set extracted file name
; in : edx = file name address
;      edi = file name VRAM address
;-------------------------------
	call	mcoff
	mov	cl,12		; file name length
	call	xorstr		; release select
	call	mcon
	push	esi
	mov	esi,edx
	call	strlen		; get file name length
	cmp	cl,11
	jb	short save42
	mov	cl,11
save42:	mov	sfnptr,cl	; set file name cursor to end
	mov	edi,offset sfname
	call	strcpy		; copy choose file name on sfname
	pop	esi
	jmp	save18		; go to display file name & cursor
;-------------------------------
; delete button press
; in : cx = x position
;-------------------------------
save50:	mov	ebp,DELSBY*VRAMW+DELSBX+DELSBW
	movzx	eax,sfnptr	; file name pointer
	cmp	cx,DELSBX+DELSBW
	jae	short save52	; delete
	sub	ebp,DELSBW
	dec	eax
	js	save20		; can't to do backspace
	mov	sfnptr,al	; set new cursor position
save52:	cmp	al,sfnsiz	; check charactor exist
	jae	save20		; no exist
	mov	ebx,offset sfname
save54:	inc	eax
	cmp	al,sfnsiz
	jae	short save56
	mov	dl,[ebx+eax]
	mov	[ebx+eax-1],dl
	jmp	save54
save56:	mov	byte ptr[ebx+eax-1],0
	call	mcoff		; mouse cursor off
	call	xorwb		; button press
	call	dspsfn		; display save file name
	call	wailu		; wait for left button up
	call	mcoff		; mouse cursor off
	call	xorwb		; button up
	call	mcon		; mouse cursor on
	jmp	save20		; go to get next event
;-------------------------------
; keyboard button press
; in : cx = x position
;      dx = y position
;-------------------------------
save60:	sub	dx,KBY
	mov	eax,edx
	mov	dl,KBBUTH
	div	dl		; button line number
	movzx	edx,al		; save line number
	mov	bl,KBBUTCN
	mul	bl		; line base button number
	sub	cx,KBX
	shr	ecx,3		; column number
	add	al,cl
	movzx	eax,al
	mov	al,kbstr[eax]	; load button charactor
;
	mov	edi,offset sfname
	movzx	ebx,sfnptr	; cursor pointer
	cmp	ebx,11
	jae	short save62
	inc	sfnptr		; go to right
save62:	movzx	ebp,sfnsiz	; old file name length
	cmp	ebp,12
	jb	short save64
	dec	ebp
save64:	xchg	[edi+ebx],al
	inc	ebx
	cmp	ebx,ebp
	jbe	save64
	mov	byte ptr [edi+ebx],0	; set EOS
;
	imul	ebp,edx,KBBUTH
	add	ebp,KBY
	shl	ebp,VRAMP
	add	ebp,KBX
	imul	ecx,KBBUTW
	add	ebp,ecx
	add	ebp,winadr
	mov	edx,KBBUTW	; select byte width
	mov	ebx,KBBUTH	; select hight
	push	ebp
	push	ebx
	call	mcoff		; mouse cursor off
	mov	al,C$SELB	; select bit data
	call	xorbox		; button down
	call	dspsfn		; display save file name
	call	wailu		; wait for left button up
	call	mcoff		; mouse cursor off
	pop	ebx
	pop	ebp
	mov	al,C$SELB	; select bit data
	call	xorbox		; button up
	call	mcon		; mouse cursor on
	jmp	save20		; go to get next event
;-------------------------------
; press in file box
; in : cl = x position
;-------------------------------
save70:	sub	cl,FBOXX	; relative x byte position in file box
	shr	cl,2		; chractor position
	cmp	cl,sfnsiz	; check charactor exist
	ja	save20		; no existence
	mov	sfnptr,cl	; renew save file name pointer
	jmp	save18		; display file name & new cursor
;-------------------------------
; execute to save buffer to file
; in : esi = window data
;-------------------------------
save80:	mov	ebp,EXECY*VRAMW+EXECX
	call	mcoff		; mouse cursor off
	call	xorwb		; button press
	call	mcon
	mov	edx,offset sfname
	call	chkfn		; check file name
	jc	short saveE0	; illegal
	mov	edx,offset sfname
	mov	edi,offset pbbuf
	call	makfp		; make file pathlist in pbbuf
	push	esi
	mov	edx,edi		; new pathlist address
	call	writf		; write buffer to file
	pop	esi
save90:	call	erawin		; erase window
	ret
saveE0:	mov	al,E$BFNam	; bad file name
	call	dsperr
	jmp	save10		; redisplay window
save	endp

;*******************************
; writf : write buffer to file
;
; in : edx = file path name
; use: all
; call: create,setcpn
;
writf	proc
	call	create		; ファイル生成書き出し
	jc	short wrf90	; エラー終了
	call	setcpn		; set & display current path name
	mov	datchg,FALSE	; data change flag off
wrf90:	mov	dbflg,FALSE	; directory buffer clear
	ret
writf	endp

;*******************************
; create : ファイルを生成して
;    バッファーデータを書き出す
;
; in : edx = ファイルパスリスト
; out: esi = パスリスト番地
; err: cf = セット
; use: all
; call: chgmc,dsperr
;
create	proc
	mov	esi,edx		; save path name address
	mov	al,M$TCUP	; mouse cursor type
	call	chgmc		; change mouse cursor
;-------------------------------
; file create
; in : edx = path list address
;-------------------------------
	mov	ah,3Ch		; create handle
	xor	ecx,ecx		; normal file
	int	21h
	jc	short cretE0	; create error
;-------------------------------
; data wirte
; in : eax = file handle
;-------------------------------
	mov	ebx,eax		; write file handle
	mov	ah,40h		; write handle
	mov	edx,bufadr	; buffer base address
	mov	ecx,datsiz	; data byte size
	int	21h
	pushfd
	push	eax
	mov	ah,3Eh		; close handle
	int	21h
	pop	eax
	popfd
	jc	short cretE2	; write error
	cmp	eax,ecx		; check overflow
	jb	short cretE4	; media full
;-------------------------------
; write completed process
; in : esi = path list address
;-------------------------------
cret90:	pushf			; キャリーフラグ退避
	mov	al,M$POINT	; mouse cursor type
	call	chgmc		; change mouse cursor
	popf			; キャリーフラグ回復
	ret
;-------------------------------
; error
;-------------------------------
cretE0:	mov	al,E$Create	; can't create
	jmp	short cretE9
cretE2:	mov	al,E$Write	; write error
	jmp	short cretE8
cretE4:	mov	al,E$Full	; media full
cretE8:	push	eax
	mov	edx,esi		; path name address
	mov	ah,41h		; delete file
	int	21h
	pop	eax
cretE9:	call	dsperr
	stc			; キャリーセット
	jmp	cret90
create	endp

;*******************************
; update : update file
;
; use: all
; call: writf,dsperr
;
update	proc
	mov	edx,offset curfpn	; read path name
	cmp	byte ptr [edx],0	; check read path name
	je	short updtE0		; no existence
	call	writf			; write buffer to file
	ret
;
updtE0:	mov	al,E$Update
	call	dsperr
	ret
update	endp

;*******************************
; dspwf : display window frame
;         with title
;
; in : esi = window data
; out: winadr = window base VRAM address
; use: eax,ebx,ecx,edx,ebp,edi
; call: getwa,mcoff,mcon,dsphl,dspstr
;
dspwf	proc
	push	esi
	call	getwa		; get window base address
	mov	winadr,ebp	; set window base address
	movzx	edx,[esi].winw	; box byte width
	shr	edx,2		; double word width
	movzx	ebx,[esi].winh	; box hight
	push	esi		; save window data address
	push	ebp		; save window VRAM address
;-------------------------------
; display window frame
;-------------------------------
	call	mcoff		; mouse cursor off
	mov	eax,C$WFRHD
	call	dsphl		; display top frame line
	inc	ebp
	inc	ebp		; VRAM start address +2
	dec	edx		; window double word width -1
	mov	esi,WBARH-2	; window title bar hight
	call	dpwfA		; display title bar
	mov	eax,C$WFRLD
	call	dpwfB		; display title bar bottom
;
	sub	ebx,WBARH+1+2+1	; window text area hight
	mov	eax,C$PANELD
dpwf10:	mov	edi,ebp				; line start VRAM address
	mov	word ptr es:[edi-2],C$WFRSW	; left side
	mov	ecx,edx
	rep	stosd
	mov	word ptr es:[edi],C$WFRSW	; right side
	add	ebp,VRAMW			; next line
	dec	ebx
	jnz	dpwf10
;
	mov	eax,C$WFRHD
	call	dpwfB		; display bottom bar top
	mov	esi,2		; display bottom bar
	call	dpwfA
	dec	ebp
	dec	ebp		; VRAM start address -2
	inc	edx		; window double word width
	mov	eax,C$WFRLD
	call	dsphl		; bottom frame line
;-------------------------------
; display window title
; in : edx = window double word width
;-------------------------------
	pop	edi		; window VRAM address
	pop	ebp		; window data address
	movsx	esi,[ebp].winttl	; title string address
	lodsb			; string byte length
	movzx	ecx,al
	sub	edx,ecx
	shl	edx,1
	add	edi,edx
	add	edi,VRAMW*2
	call	dspstr		; display title
;
	call	mcon		; mouse cursor on
	pop	esi
	ret

dpwfA:	mov	eax,C$WBARD
dpwfA1:	mov	edi,ebp				; line start VRAM address
	mov	word ptr es:[edi-2],C$WBLW	; window bar left side
	mov	ecx,edx
	rep	stosd
	mov	word ptr es:[edi],C$WBRW	; window bar right side
	add	ebp,VRAMW			; next line
	dec	esi
	jnz	dpwfA1
	ret

dpwfB:	mov	edi,ebp
	mov	word ptr es:[edi-2],C$WFRSW	; left side
	mov	ecx,edx
	rep	stosd				; middle
	mov	word ptr es:[edi],C$WFRSW	; right side
	add	ebp,VRAMW			; next line
	ret
dspwf	endp


;*******************************
; xorwf : xor window frame
;       dotted line rectangle
;
; in : esi = dotted frame position
; use: eax,ebx,ecx,edx,ebp
; call: mcoff,mcon
;
xorwf	proc
	movzx	ebp,[esi].winy	; y position
	shl	ebp,VRAMP
	or	bp,[esi].winx	; VRAM address
	add	ebp,VRAMSIZ	; page 1
	movzx	edx,[esi].winw	; box byte width
	movzx	ebx,[esi].winh	; box hight
;
	mov	al,C$SELB
	mov	ecx,edx
	shr	ecx,1
	call	mcoff		; mouse cursor off
xorwf1:	xor	es:[ebp],al
	inc	ebp		; right byte
	inc	ebp		; right byte
	loop	xorwf1
;
	sub	ebp,edx		; rewind
	add	ebp,VRAMW	; next line
	dec	ebx
	shr	ebx,1
xorwf2:	xor	byte ptr es:[ebp],C$SEL
	xor	byte ptr es:[ebp+edx-1],(C$SEL shl 4)
	add	ebp,VRAMW	; next line
	xor	byte ptr es:[ebp],C$SEL
	xor	byte ptr es:[ebp+edx-1],(C$SEL shl 4)
	add	ebp,VRAMW	; next line
	dec	ebx
	jz	xorwf3
	add	ebp,VRAMW*2	; skip 2 line
	dec	ebx
	jnz	xorwf2
;
xorwf3:	mov	al,C$SELB
	mov	ecx,edx
	shr	ecx,1
xorwf4:	xor	es:[ebp],al
	inc	ebp		; right byte
	inc	ebp		; right byte
	loop	xorwf4
	call	mcon		; mouse cursor on
	ret
xorwf	endp

;*******************************
; mouloc : mouse locate
;
; in : eax = position(low=x,high=y)
; use: none
;
mouloc	proc
	add	eax,(VRAMH shl 16)
	mov	dword ptr newmx,eax
	ret
mouloc	endp

;*******************************
; getpos : get mouse position
;
; out: eax = position(low=x,high=y)
; use: none
;
getpos	proc
	mov	eax,dword ptr bakmx
	sub	eax,(VRAMH shl 16)
	ret
getpos	endp

;*******************************
; movwf : move window frame
;
; in : esi = window data address
;      bx = left down occured time
; use: eax,ebx,ecx,edx,pbbuf
; call: getpos,xorwf,getevt
;       erawin,dspwf
;
movwf	proc
	push	ebp
	push	esi
	mov	dwntime,bx	; set left down time
	call	getpos		; get mouse position
	mov	ebx,dword ptr[esi].winx
	mov	ecx,dword ptr[esi].winw
	mov	esi,offset dfpos
	mov	[esi],ebx	; set frame initial x,y
	mov	[esi+4],ecx	; set frame initial width,hight
	sub	eax,ebx
	assume	ds:stack
	mov	dword ptr[pbbuf],eax	; window relative click position
	assume	ds:data
;
movw10:	call	xorwf		; dispaly window frame
movw12:	call	getevt
	cmp	al,M$LUp
	je	short movw50	; left button up
	cmp	al,M$LDown
	je	short movw80	; left button down
	cmp	al,M$RDown
	je	movwE0		; right button down
	cmp	al,EvtNone
	jne	movw12		; invalid event
;
	pop	ebx		; window data address
	push	ebx
	assume	ds:stack
	sub	cx,word ptr[pbbuf]	; frame x position
	assume	ds:data
	jae	short movw20
	xor	ecx,ecx		; adjust left side
movw20:	mov	ax,VRAMDW-1
	sub	ax,[ebx].winw
	cmp	ax,cx
	ja	short movw22
	mov	ecx,eax		; revision new x position
	assume	ds:stack
movw22:	sub	dx,word ptr[pbbuf+2]	; frame y position
	assume	ds:data
	jae	short movw24
	xor	edx,edx		; adjust up side
movw24:	mov	ax,VRAMDH-2
	sub	ax,[ebx].winh
	cmp	ax,dx
	ja	short movw26
	mov	edx,eax		; revision new y position
movw26:	cmp	cx,[esi].winx	; check x change
	jne	short movw28	; frame move
	cmp	dx,[esi].winy	; check y change
	je	movw12		; no moving
movw28:	push	ecx		; save new x position
	push	edx		; save new y position
	call	xorwf		; erase window frame
	pop	edx
	pop	ecx
	mov	[esi].winx,cx	; set new x position
	mov	[esi].winy,dx	; set new y position
	jmp	movw10		; go to display new frame
;
movw50:	mov	ax,dwntime	; left down time
	sub	ax,bx
	jnc	short movw52
	add	ax,60*60
movw52:	cmp	ax,8		; 8/60 second
	jbe	movw12		; click
;
movw80:	pop	esi
	push	esi
	call	erawin		; erase old window
	pop	esi
	push	esi
	mov	ebx,offset dfpos
	mov	eax,[ebx]
	mov	[esi],eax	; set new window position
	call	dspwf		; display new window frame
movw90:	pop	esi
	pop	ebp
	ret
;
movwE0:	call	xorwf		; erase window frame
	jmp	movw90
movwf	endp

;*******************************
; getew : get event through window
;
; in : esi = window data address
; out: al = event type
;      bx = event occured time
;      ecx = relative x position
;      edx = relative y position
; use: none
; call: getevt,chgmc,movwf
;
getew	proc
;-------------------------------
; select mouse cursor position
;-------------------------------
getew1:	call	getevt
	sub	cx,[esi].winx
	jb	short getew7	; left out of window
	cmp	cx,[esi].winw
	jae	short getew7	; right out of window
	sub	dx,[esi].winy
	jb	short getew7	; up out of window
	cmp	dx,[esi].winh
	jae	short getew7	; down out of window
;
	cmp	cx,2
	jb	short getew5	; on frame
	cmp	dx,WBARH
	jb	short getew5	; on frame
	add	ecx,2
	add	edx,4
	cmp	cx,[esi].winw
	jae	short getew5	; on frame
	cmp	dx,[esi].winh
	jae	short getew5	; on frame
	sub	ecx,2
	sub	edx,4
;-------------------------------
; hand over event
;-------------------------------
	push	eax
	mov	al,M$POINT	; mouse cursor type
	call	chgmc		; change mouse cursor
	pop	eax
	ret
;-------------------------------
; on window frame
;-------------------------------
getew5:	push	eax
	mov	al,M$OPEN	; mouse cursor type
	call	chgmc		; change mouse cursor
	pop	eax
	cmp	al,M$RDown
	je	short getew7	; go to quit end
	cmp	al,M$LDown
	jne	getew1
;
	mov	al,M$CATCH	; mouse cursor type
	call	chgmc		; change mouse cursor
	call	movwf		; move window frame
	mov	al,EvtUpdate	; window update event
	ret
;-------------------------------
; out of window
;-------------------------------
getew7:	push	eax
	mov	al,M$POINT	; mouse cursor type
	call	chgmc		; change mouse cursor
	pop	eax
	cmp	al,M$LDown
	je	short getew9
	cmp	al,M$RDown
	jne	getew1
getew9:	mov	al,EvtClose	; window close event
	ret
getew	endp

;*******************************
; stcpn : set & display
;         current path name
;
; in : esi = new path name(not NULL)
;      curfpn = current file path name
; use: none
; call: strlen,strcpy,dspstr,erastr
;
setcpn	proc
	push	eax
	push	ebx
	push	ecx
	push	esi
	push	edi
	mov	edi,esi		; save new path name address
	mov	esi,offset curfpn
	call	strlen		; get current path length
	test	ecx,ecx
	jnz	short stcpn1
	mov	ecx,newpathL
stcpn1:	mov	eax,ecx		; save current path length
	xchg	edi,esi
	call	strcpy		; new path name copy
;
	mov	edi,PATHY*VRAMW+PATHX
	call	strlen		; get new path string length
	push	ecx
	call	dspstr		; display string
	pop	ecx
;
	sub	eax,ecx		; check tail charactor rest
	jbe	short stcpn9	; not rest
	mov	cl,al
	call	erastr		; erase tail charactor
stcpn9:	pop	edi
	pop	esi
	pop	ecx
	pop	ebx
	pop	eax
	ret
setcpn	endp

;*******************************
; strcpy : string copy
;
; in : esi = source string address
;      edi = destination address
; use: none
;
strcpy	proc
	push	eax
	push	esi
	push	edi
stcp10:	lodsb
	mov	[edi],al
	inc	edi
	test	al,al
	jnz	stcp10
	pop	edi
	pop	esi
	pop	eax
	ret
strcpy	endp

;*******************************
; dspsiz : display data size
;
; use: eax,edi
;
dspsiz	proc
	mov	eax,datsiz	; display text size
	mov	edi,USESIZY*VRAMW+USESIZX
	call	dsp8d
	ret
dspsiz	endp

;*******************************
; delb : delete one byte
;
; in : datend = data end address
;      bufadr = buffer base address
;      curptr = current pinter
; out: datsiz = data size
;      datend = data end address
; err: cf = set
; use: none
; call: dspsiz,dsperr
;
delb	proc
	push	eax
	push	ecx
	push	esi
	push	edi
	mov	edi,bufadr
	add	edi,curptr	; destination address
	mov	esi,edi
	inc	esi		; source address
	mov	ecx,datend	; data end address
	sub	ecx,esi		; copy byte number
	jb	short delbE0	; memory over
;
	push	es
	push	ds
	pop	es
	shr	ecx,1
	jnc	short delb10
	movsb
delb10:	shr	ecx,1
	jnc	short delb12
	movsw
delb12:	rep	movsd
	pop	es
;
	dec	datsiz		; renew data size
	dec	datend		; renew data end address
	call	dspsiz		; display new data size
;
	clc			; clear carry
delb99:	pop	edi
	pop	esi
	pop	ecx
	pop	eax
	ret
;
delbE0:	stc			; set carry
	jmp	delb99
delb	endp

;*******************************
; delbuf : バッファ内データを削除する
;          各種チェックなし
;
; in : datend = データ末尾番地
;      bufadr = バッファー基底番地
;      curptr = カレントポインタ
;      ecx = 削除バイト数
; out: datsiz = 新しいデータサイズ
;      datend = 新しいデータ末尾番地
; use: none
;
delbuf	proc
	push	eax
	push	ecx
	push	esi
	push	edi
	push	es
	push	ds
	pop	es
	sub	datsiz,ecx	; データサイズ更新
	mov	edi,bufadr
	add	edi,curptr	; 移動先番地
	mov	esi,edi
	add	esi,ecx		; 移動元番地
	mov	ecx,datend
	sub	ecx,esi		; 移動バイト数
	shr	ecx,1
	jnc	short debf10
	movsb
debf10:	shr	ecx,1
	jnc	short debf12
	movsw
debf12:	rep	movsd
	mov	datend,edi	; データ末尾番地更新
	pop	es
	pop	edi
	pop	esi
	pop	ecx
	pop	eax
	ret
delbuf	endp

;*******************************
; insnb : insert null one byte
;
; in : bufsiz = buffer size
;      datsiz = data size
;      datend = data end address
;      curptr = current pinter
; out: datsiz = data size
;      datend = data end address
; err: cf = set by memory over
; use: none
; call: dspsiz,dsperr
;
insnb	proc
	push	eax
	push	ecx
	push	esi
	push	edi
	mov	ecx,datsiz	; current data size
	cmp	ecx,bufsiz	; check buffer size
	jae	short innbE0	; memory over
;
	push	es
	push	ds
	pop	es
	std
	mov	edi,datend	; destination address
	mov	esi,edi
	dec	esi		; source address
	sub	ecx,curptr	; copy byte number
	shr	ecx,1
	jnc	short innb10
	movsb
innb10:	dec	esi
	dec	edi
	shr	ecx,1
	jnc	short innb12
	movsw
innb12:	sub	esi,2
	sub	edi,2
	rep	movsd
	cld
	pop	es
;
	mov	byte ptr [edi+3],0	; set null byte
	inc	datsiz		; renew data size
	inc	datend		; renew data end address
	call	dspsiz		; display new data size
;
	clc			; clear carry
innb99:	pop	edi
	pop	esi
	pop	ecx
	pop	eax
	ret
;
innbE0:	push	ebx
	push	edx
	push	ebp
	mov	al,E$MemFul	; memory full message
	call	dsperr
	pop	ebp
	pop	edx
	pop	ebx
	stc			; set carry
	jmp	innb99
insnb	endp

;*******************************
; insbuf : insert spaces in buffer
;     don't check buffer over
;
; in : curptr = insert pointer
;      bufadr = buffer base address
;      datsiz = data size
;      ecx = insert byte size
; out: datsiz = new data size
;      datend = new data tail address
; use: none
;
insbuf	proc
	push	eax
	push	ecx
	push	esi
	push	edi
	push	es
	push	ds
	pop	es
	std				; direction flag set
	mov	edi,ecx			; insert byte size
	mov	esi,bufadr		; buffer base address
	mov	ecx,datsiz		; old data size
	add	datsiz,edi		; renew data size
	add	datend,edi		; renew data end
	add	esi,ecx			; old data tail address
	sub	ecx,curptr		; copy data amount
	jbe	short inbf90		; not exist data to copy
	dec	esi			; old data bottom address
	add	edi,esi
	shr	ecx,1
	jnc	short inbf10
	movsb
inbf10:	dec	esi
	dec	edi
	shr	ecx,1
	jnc	short inbf12
	movsw
inbf12:	sub	esi,2
	sub	edi,2
	rep	movsd
inbf90:	cld				; direction flag clear
	pop	es
	pop	edi
	pop	esi
	pop	ecx
	pop	eax
	ret
insbuf	endp

;*******************************
; readf : read file
;
; in : edx = path name address
;      al = insert mode flag
;      gs = PSP
;      es = VRAM
; use: all
; call: insbuf,setcpn,dspag,savdcp
;       dspsiz,xorcur,chgmc,dsperr
;
readf	proc
	cmp	byte ptr [edx],0
	je	redf99			; quit
	mov	ebx,eax		; save insert mode flag
	mov	al,M$TCUP	; mouse cursor type
	call	chgmc		; change mouse cursor
	call	xorcur		; erase cursor
;-------------------------------
; check readable
;      bl = insert mode flag
;-------------------------------
	mov	ah,4Eh			; find first file
	mov	ecx,6			; hidden+system
	int	21h
	jc	redf80			; can't find path
;
	mov	esi,80h			; DTA address
	mov	ecx,gs:[esi+1Ah]	; file size
	xor	eax,eax
	cmp	bl,TRUE			; insert mode ?
	jne	short redf10		; overwrite
	mov	eax,datsiz		; current data size
redf10:	add	eax,ecx			; new data size
	cmp	eax,bufsiz		; check buffer size whether readable
	ja	redf82			; memory lack
;-------------------------------
; file open
; in : edx = path name address
;-------------------------------
	mov	ax,3D00h	; read open
	int	21h
	jc	redf84		; can't open
;-------------------------------
; set new file data & display
; in : ecx = read file size
;      edx = path name address
;      bl = insert mode flag
;-------------------------------
	cmp	bl,TRUE		; insert mode ?
	jne	short redf30	; overwrite
	call	insbuf		; insert speces in buffer
	call	savdcp		; データ変更位置の保存
	jmp	short redf40
;
redf30:	mov	datsiz,ecx	; set new data size
	mov	esi,edx		; new path name address
	call	setcpn		; set & display current path name
	mov	edx,bufadr
	add	edx,ecx
	mov	datend,edx	; set new data tail address
	mov	curptr,0	; set pinter to head
	mov	datchg,FALSE	; data change flag off
	mov	lastmp,-1	; 移動前位置なし
;-------------------------------
; file read in buffer
; in : ecx = read file size
;      eax = file handle
;-------------------------------
redf40:	mov	edx,bufadr
	add	edx,curptr	; data read address
	mov	ebx,eax		; set file handle
	mov	ah,3Fh		; read handle
	int	21h
	pushfd
	mov	ah,3Eh		; close handle
	int	21h
	popfd
	jc	short redf86	; read error
;-------------------------------
; diplay page
;-------------------------------
redf90:	call	dspag
	call	xorcur		; display cursor
	mov	al,M$POINT	; mouse cursor type
	call	chgmc		; change mouse cursor
redf99:	call	dspsiz		; display data size
	ret
;-------------------------------
; error message
;-------------------------------
redf80:	mov	al,E$PNNF	; can't find path
	jmp	short redf89
redf82:	mov	al,E$MemFul	; memory lack
	jmp	short redf89
redf84:	mov	al,E$Open	; can't open
	jmp	short redf89
redf86:	mov	al,E$Read	; read error
redf89:	call	dsperr
	jmp	redf90
readf	endp

;*******************************
; chgsbc : change string background color
;
; in : al = change color code
;      edi = VRAM address
;      ecx = string length
; use: none
;
chgsbc	proc
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	edi
	shl	ecx,2			; string byte width
	mov	ebx,ecx			; save byte width
	mov	dl,CHRH			; line counter
	mov	ah,al
cgsbc2:	mov	al,es:[edi]
	mov	dh,al			; save
	and	al,0F0h
	cmp	al,(C$STR shl 4)
	je	short cgsbc4
	mov	al,ah			; chenge color
	shl	al,4
cgsbc4:	and	dh,0Fh
	cmp	dh,C$STR
	je	short cgsbc6
	mov	dh,ah
cgsbc6:	or	al,dh
	stosb				; set color code
	loop	cgsbc2
	sub	edi,ebx			; rewind line head address
	add	edi,VRAMW		; next line address
	mov	ecx,ebx			; set width counter
	dec	dl			; count down line
	jnz	cgsbc2
	pop	edi
	pop	edx
	pop	ecx
	pop	ebx
	pop	eax
	ret
chgsbc	endp

;*******************************
; warn : display warning window
;
; esi = message address
; out: cf = set by quit
; use: all
; call: filbox,dspstr,chgsbc,boxup,getevt
;       mcoff,mcon
;
warn	proc
	lodsb				; string length
	add	al,2
	movzx	edx,al
	shl	edx,1			; window byte width/2
	mov	ebp,(VRAMDH/2-30)*VRAMW+VRAMDW/2
	sub	ebp,edx			; window start address in page 0
	shl	edx,1			; window byte width
	mov	ebx,2*20+16		; window hight
	mov	eax,C$WARND
	push	ebx
	push	edx
	push	ebp
	call	filbox			; display error window panel
	pop	ebp
;
	mov	edi,ebp			; display error string
	add	edi,VRAMSIZ+8*VRAMW+4	; VRAM page 1 string address
	movzx	ecx,byte ptr [esi-1]	; string length
	push	edi
	call	mcoff			; mouse cursor off
	call	dspstr
	pop	edi
	mov	al,C$WARN		; change string background color
	call	chgsbc
	mov	esi,offset execstr+1
	mov	edi,VRAMSIZ+(VRAMDH/2+2)*VRAMW+(VRAMDW-4*4)/2
	mov	ecx,4
	push	edi
	call	dspstr
	pop	edi
	mov	al,C$WARN		; change string background color
	call	chgsbc
	mov	edi,VRAMSIZ+VRAMDH/2*VRAMW+(VRAMDW-20)/2
	mov	edx,20
	mov	ebx,edx
	call	boxup
	call	mcon			; mouse cursor on
;
	mov	ah,03h			; ブザーをならす
	mov	ebx,10			; 100ms
	mov	edx,14			; 19200/14Hz
	int	9Eh
;
warn80:	call	getevt
	cmp	al,M$RDown
	je	short warnE0		; quit end
	cmp	al,M$LDown
	jne	warn80			; invalid event
;
	sub	ecx,(VRAMDW-20)/2
	jb	warn80			; left over
	cmp	ecx,20
	jae	warn80			; right over
	sub	edx,VRAMDH/2
	jb	warn80			; top over
	cmp	edx,20
	jae	warn80			; down over
;
	clc				; clear carry
warn90:	pop	edx			; byte width
	pop	ebx			; hight
	pushfd
	xor	eax,eax			; erase warning window
	call	filbox
	popfd
	ret
warnE0:	stc				; set carry
	jmp	warn90
warn	endp

;*******************************
; dsperr : display error window
;
; in : al = error code
; call: chgmc,getevt,filbox,dspstr
;       chgsbc,mcoff,mcon
; use: all
;
dsperr	proc
	mov	esi,offset errmsg	; error message string index
	movzx	eax,al
	shl	eax,1
	movsx	esi,word ptr [esi+eax]	; error string address
	lodsb				; string length
	add	al,2
	movzx	edx,al
	shl	edx,1			; window byte width/2
	mov	ebp,(VRAMDH-(CHRH+16))/2*VRAMW+VRAMDW/2
	sub	ebp,edx			; window start address in page 0
	shl	edx,1			; window byte width
	mov	ebx,CHRH+16		; window hight
	mov	eax,C$ERRD
	push	ebx
	push	edx
	push	ebp
	call	filbox			; display error window panel
	pop	ebp
;
	mov	edi,ebp			; display error string
	add	edi,VRAMSIZ+8*VRAMW+4	; VRAM page 1 string address
	movzx	ecx,byte ptr [esi-1]	; string length
	push	edi
	call	mcoff			; mouse cursor off
	call	dspstr
	pop	edi
	mov	al,C$ERR		; change string background color
	call	chgsbc
	call	mcon			; mouse cursor on
;
	mov	ah,03h			; ブザーをならす
	mov	ebx,20			; 200ms
	mov	edx,12			; 19200/12Hz
	int	9Eh
;
	mov	al,M$POINT		; normal mouse cursor
	call	chgmc
dper70:	call	getevt			; wait mouse button press
	cmp	al,M$RDown
	je	short dper80
	cmp	al,M$LDown
	jne	dper70			; invalid
;
dper80:	pop	edx			; byte width
	pop	ebx			; hight
	xor	eax,eax			; erase error window
	call	filbox
	ret
dsperr	endp

;*******************************
; xortk : xor tenkey button
;
; in : ecx = column number
;      edx = line number
; use: eax,ebx,ebp
; call: xorbox
;
xortk	proc
	push	ecx
	push	edx
	imul	ebp,edx,KEYBH
	shl	ebp,VRAMP
	imul	eax,ecx,KEYBW
	add	eax,TENKADR
	add	ebp,eax
	mov	edx,KEYBW	; button byte width
	mov	ebx,KEYBH	; button hight
	mov	al,C$SELB
	call	xorbox
	pop	edx
	pop	ecx
	ret
xortk	endp

;*******************************
; wailu : wait for left button up
;
; out: al = event type
;      bx = event occured time
; use: none
; call: getevt
;
wailu	proc
	push	ecx
	push	edx
wailu1:	call	getevt		; wait for left button up
	cmp	al,M$LUp
	jne	wailu1		; invalid event
	pop	edx
	pop	ecx
	ret
wailu	endp

;*******************************
; repin : 反復挿入
;
; use: all
; call: dspwf,mcoff,dspws,dspwb
;       dsprc,dsprn,mcon,getew
;       chkwb,rev8d,d1hex,d1chr,revwb
;       chkar,insbuf,fill,erawin,savdcp
;
repin	proc
	mov	eax,bufsiz		; 挿入上限値のチェック
	sub	eax,datsiz
	cmp	eax,insbyte
	ja	short rpin10
	mov	insbyte,eax		; 挿入バイト数初期値修正
;-------------------------------
; ウィンドウ表示
;-------------------------------
rpin10:	mov	esi,offset window6	; ウィンドウ枠の表示
	call	dspwf
rpin12:	call	mcoff			; マウスカーソル消去
	mov	ebx,offset w6str	; ウィンドウ内文字列表示
	call	dspws
	mov	ebx,offset w6box	; display window boxes
	call	dspwb
	call	dsprc			; 繰り返しコードの表示
	mov	eax,insbyte		; 挿入バイト数表示
	call	dsprn
;-------------------------------
; イベント読み込み
;-------------------------------
rpin20:	call	getew			; get event through window
	cmp	al,EvtClose
	je	rpin90			; close window
	cmp	al,EvtUpdate
	je	rpin12			; display window contents
	cmp	al,M$RDown
	je	rpin90			; close window
	cmp	al,M$LDown
	jne	rpin20			; 無効イベント
;-------------------------------
; 左ボタン押し下げ位置を調べる
; in : ecx = ウィンドウ内Ｘ位置
;      edx = ウィンドウ内Ｙ位置
;      bx = 左ボタン押し下げ時刻
;-------------------------------
	mov	dwntime,bx		; 左ボタン押し下げ時刻を保存する
	mov	ebx,offset w6box	; ボックス範囲内か調べる
	call	chkwb
	jc	rpin20			; ボックス範囲外
	test	eax,eax
	jz	short rpin50		; 16進挿入コード
	dec	eax
	jz	short rpin60		; ANK挿入コード
	dec	eax
	jz	short rpin80		; 挿入実行
;-------------------------------
; 挿入バイト数の変更
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;-------------------------------
rpin40:	mov	eax,insbyte		; 現在挿入バイト数
	call	rev8d			; 10進数を増減する
	mov	ecx,datsiz		; 挿入上限値のチェック
	add	ecx,eax
	cmp	ecx,bufsiz
	ja	short rpin48		; 挿入不可能
	mov	insbyte,eax		; 挿入バイト数更新
	call	dsprn			; 繰り返しバイト数の表示
rpin48:	call	chkar			; オートリピートチェック
	jnc	rpin40			; リピートする
	jmp	rpin20
;-------------------------------
; 16進挿入コードの変更
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;-------------------------------
rpin50:	call	d1hex			; 16進数増減値を得る
	add	repcode,al		; 挿入コード更新
	call	dsprc			; 繰り返しコードの表示
	call	chkar			; オートリピートチェック
	jnc	rpin50			; リピートする
	jmp	rpin20
;-------------------------------
; ANK挿入コードの変更
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;-------------------------------
rpin60:	call	d1chr			; ANK文字増減値を得る
	add	repcode,al		; 挿入コード更新
	call	dsprc			; 繰り返しコードの表示
	call	chkar			; オートリピートチェック
	jnc	rpin60			; リピートする
	jmp	rpin20
;-------------------------------
; 挿入の実行
; in : ebx = ボックスデータ番地
;-------------------------------
rpin80:	call	revwb			; 実行ボタン押し下げ表示
;
	mov	nibpos,0		; set nible position
	call	savdcp			; データ変更位置の保存
;
	mov	ecx,insbyte		; バッファを空ける
	call	insbuf
	call	fill			; バッファをコードで埋める
	call	dspsiz			; display new data size
;
rpin90:	mov	esi,offset window6	; ウィンドウの消去
	call	erawin
	ret
repin	endp

;*******************************
; devbyte : バイト分割
;
; in : bufsiz = buffer size
;      datsiz = data size
;      bufadr = バッファー基底番地
;      datend = data end address
;      curptr = current pinter
; out: datsiz = data size
;      datend = data end address
; use: all
; call: dspsiz,dsperr,xorcur,dspag
;       savdcp
;
devbyte	proc
	mov	eax,datsiz	; データサイズ
	cmp	eax,bufsiz	; バッファーサイズと比較
	jae	short devbE0	; メモリオーバー
;
	mov	edi,bufadr
	add	edi,curptr	; 対象データ開始番地
	mov	ecx,datend
	sub	ecx,edi		; 対象データバイト数
	jbe	short devb90	; 対象データなし
;
	call	xorcur		; カーソル消去
	call	savdcp		; データ変更位置の保存
	push	es
	push	ds
	pop	es
	mov	al,[edi]	; 分割対象のバイトデータ
	mov	dl,al
	and	al,0F0h
	shl	dl,4
	jmp	short devb18
devb10:	movzx	eax,byte ptr [edi]
	ror	ax,4
	or	al,dl
	mov	dl,ah
devb18:	stosb
	loop	devb10
	mov	[edi],dl
	pop	es
;
	inc	datsiz		; データサイズ更新
	inc	datend		; データ末尾番地更新
	mov	nibpos,1	; ニブル位置を下位へ
	call	dspsiz		; データサイズの表示
	call	dspag		; ページ再表示
	call	xorcur		; カーソル表示
devb90:	ret
;
devbE0:	mov	al,E$MemFul	; メモリフルメッセージ
	call	dsperr
	ret
devbyte	endp

;*******************************
; chkar : オートリピートチェック
;
; in : dwntime = 前回左ボタン押し下げ時刻
;      ebx = ボックスデータ番地
;      esi = ウィンドウデータ番地
; out: ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      cf = リピートするときクリア
; use: eax
; call: getevt
;
chkar	proc
	push	ebx
	push	ebp
	mov	ebp,ebx
ckar10:	call	getevt
	cmp	al,M$LUp		; 左ボタンが離されたら
	je	short ckar92		; リピートチェック終了
	cmp	al,EvtNone
	jne	ckar10			; 無効イベント
;
	sub	cx,[esi].winx
	jb	ckar10			; ウィンドウの左外
	cmp	cx,[esi].winw
	jae	ckar10			; ウィンドウの右外
	sub	dx,[esi].winy
	jb	ckar10			; ウィンドウの上外
	cmp	dx,[esi].winh
	jae	ckar10			; ウィンドウの下外
;
	sub	cl,[ebp].wbposx
	jb	ckar10			; ボックス左外
	cmp	cl,[ebp].wbwidth
	jae	ckar10			; ボックス右外
	shr	edx,1			; ボックスＹ位置は２ピクセル単位
	sub	dl,[ebp].wbposy
	jb	ckar10			; ボックス上外
	shl	edx,1			; ボックス高さは１ピクセル単位
	cmp	dl,[ebp].wbhight
	jae	ckar10			; ボックス下外
;
	mov	ax,dwntime		; リピートするかしないか調べる
	sub	ax,bx
	jnc	short ckar12
	add	ax,60*60
ckar12:	cmp	ax,8			; リピート間隔8/60秒
	jbe	ckar10			; リピートまだ
	mov	dwntime,bx		; 左ボタン押し下げ時刻を保存する
	pop	ebp
	pop	ebx
	ret
;
ckar92:	stc				; キャリーセット
	pop	ebp
	pop	ebx
	ret
chkar	endp

;*******************************
; fill : バッファをコードで埋める
;        バッファオーバーチェックなし
;        画面再表示付
;
; in : ecx = バイト数
;      repcode = コード
; use: eax,ecx,edi
; call: xorcur,dspag
;
fill	proc
	mov	al,repcode		; 挿入コード
	mov	ah,al
	mov	edi,eax
	shl	eax,16
	mov	ax,di
	mov	edi,bufadr		; バッファ基底番地
	add	edi,curptr		; カレント番地
	push	es
	push	ds
	pop	es
	shr	ecx,1
	jnc	short fill2
	stosb
fill2:	shr	ecx,1
	jnc	short fill4
	stosw
fill4:	rep	stosd
	pop	es
	call	xorcur			; カーソル消去
	call	dspag			; redisplay page
	call	xorcur			; display cursor
	ret
fill	endp

;*******************************
; d1chr : ANK文字増減値を得る
;
; in : edx = ボックス内Ｙ位置(ピクセル)
; out: al = 増減値
; use: none
;
d1chr	proc
	mov	al,1
	cmp	edx,10			; 増加 or 減少？
	jb	short d1chr9
	neg	al
d1chr9:	ret
d1chr	endp

;*******************************
; d1hex : 16進数増減値を得る
;
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
; out: al = 増減値
; use: none
;
d1hex	proc
	mov	al,1
	cmp	ecx,12/2		; 桁位置を調べる
	jae	short d1hex6
	mov	al,10h
d1hex6:	cmp	edx,10			; 増加 or 減少？
	jb	short d1hex8
	neg	al
d1hex8:	ret
d1hex	endp

;*******************************
; rev8d : ８桁数値入力ボックス内で
;         10進数を増減する
;         ラウンド禁止
;
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      eax = 修正対象のバイナリ値
; out: eax = 新しい値
; use: ecx
;
rev8d	proc
	sub	ecx,4/2
	jb	short rv8d90		; 範囲外
	shr	ecx,2
	cmp	ecx,7
	ja	short rv8d90		; 範囲外
	mov	ecx,decdat[ecx*4]	; 桁数値
	cmp	edx,10			; 増減チェック
	jb	short rv8d40
	sub	eax,ecx			; 減少
	jae	short rv8d90
	add	eax,ecx			; 元に戻す
	ret
rv8d40:	add	eax,ecx			; 増加
	jnc	short rv8d90
	sub	eax,ecx			; 元に戻す
rv8d90:	ret
rev8d	endp

;*******************************
; rev6h : 8桁16進数の増減
;         ラウンド禁止
;
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      eax = 修正対象のバイナリ値
; out: eax = 新しい値
; use: ecx
;
rev6h	proc
	sub	ecx,4/2
	jb	short rv6h90		; 範囲外

	and	cl,11111100b
	sub	cl,20
	neg	cl
	push	eax
	mov	eax,1
	shl	eax,cl
	mov	ecx,eax
	pop	eax

	cmp	edx,10			; 増減チェック
	jb	short rv6h40
	sub	eax,ecx			; 減少
	jae	short rv6h90
	add	eax,ecx			; 元に戻す
	ret
rv6h40:	add	eax,ecx			; 増加
	jnc	short rv6h90
	sub	eax,ecx			; 元に戻す
rv6h90:	ret
rev6h	endp

;*******************************
; chkwb : ボックス範囲を調べる
;
; in : ecx = ウィンドウ内Ｘ位置(バイト)
;      edx = ウィンドウ内Ｙ位置(ピクセル)
;      ebx = ボックスデータ索引
; out: eax = ボックス番号
;      ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
; err: cf = 範囲外のときセット
; use: none
;
chkwb	proc
	shr	edx,1			; ボックスＹ位置は２ピクセル単位
	xor	eax,eax			; ボックス番号初期化
chkwb1:	push	ecx
	push	edx
	sub	cl,[ebx].wbposx
	jb	short chkwb2		; 左過ぎる
	cmp	cl,[ebx].wbwidth
	jae	short chkwb2		; 右過ぎる
	sub	dl,[ebx].wbposy
	jb	short chkwb2		; 上過ぎる
	shl	edx,1			; ボックス高さは１ピクセル単位
	cmp	dl,[ebx].wbhight
	jb	short chkwb6		; 範囲内
chkwb2:	pop	edx
	pop	ecx
	add	ebx,size wbstr		; 次のボックスデータ番地へ
	inc	eax			; ボックス番号更新
	cmp	[ebx].wbposx,0		; ボックスデータ終わり確認
	jne	chkwb1			; データまだある
	stc				; キャリーセット
	ret
chkwb6:	add	esp,8			; スタックを捨てる/キャリークリア
	ret
chkwb	endp

;*******************************
; dsprc : 繰り返しコードの表示
;
; in : winadr = ウィンドウ描画番地
;      repcode = 繰り返しコード
; use: eax,edi
; call: dsphex,dspc,mcoff,mcon
;
dsprc	proc
	mov	edi,winadr			; window base address
	add	edi,(WBARH+8)*VRAMW+64/2
	mov	al,repcode			; 挿入コード16進表示
	call	mcoff				; マウスカーソル消去
	call	dsphex
	add	edi,4				; 挿入コード文字表示
	mov	al,repcode
	call	dspc
	call	mcon				; マウスカーソル表示
	ret
dsprc	endp

;*******************************
; dsprn : 繰り返しバイト数の表示
;
; in : winadr = ウィンドウ描画番地
;      eax = 繰り返しバイト数
; use: edi
; call: dsp8d,mcoff,mcon
;
dsprn	proc
	mov	edi,winadr			; ウィンドウ描画番地
	add	edi,(WBARH+30)*VRAMW+80/2
	call	mcoff				; マウスカーソル消去
	call	dsp8d
	call	mcon				; マウスカーソル表示
	ret
dsprn	endp

;*******************************
; golaste : 前回編集位置へジャンプ
;
; in : lastep = 前回編集位置
;      datchg = 変更フラグ
; out: lastmp = ジャンプ前位置
; use: all
; call: xorcur,dspag
;
golaste	proc
	cmp	datchg,TRUE		; 変更位置の存在確認
	jne	short golte9		; 変更点なし
	call	xorcur			; カーソル消去
	mov	eax,lastep		; 前回編集位置
	xchg	curptr,eax		; カレントポインタ変更
	mov	nibpos,0		; 上位ニブル位置へ
	mov	lastmp,eax		; カレントポインタを保存
	call	dspag			; ページ表示
	call	xorcur			; カーソル表示
golte9:	ret
golaste	endp

;*******************************
; golastm : 移動前の位置へジャンプ
;
; in : lastmp = 移動前の位置
; use: all
; call: xorcur,dspag
;
golastm	proc
	mov	eax,lastmp		; 移動前の位置
	test	eax,eax
	js	short goltm9		; 移動していない
	cmp	eax,datsiz		; 有効位置かどうか調べる
	jbe	short goltm2		; 有効
	mov	eax,datsiz		; 最終位置とする
goltm2:	call	xorcur			; カーソル消去
	xchg	curptr,eax		; カレントポインタ変更
	mov	nibpos,0		; 上位ニブル位置へ
	mov	lastmp,eax		; カレントポインタを保存
	call	dspag			; ページ表示
	call	xorcur			; カーソル表示
goltm9:	ret
golastm	endp

;*******************************
; dspws : ウィンドウ内文字列表示
;
; in : ebx = 文字列索引番地
;      winadr = ウィンドウ基底番地
;      fs = フォントデータセレクタ
;      es = ＶＲＡＭセレクタ
; call: dspstr
; use: eax,ebx,ecx,edi
;
dspws	proc
	push	esi
dspws1:	movzx	edi,[ebx].wsposx	; position x
	test	edi,edi			; 文字列終わりを確認
	jz	short dspws8		; 終わり
	add	edi,winadr
	movzx	ecx,[ebx].wsposy	; position y
	shl	ecx,VRAMP+1
	add	edi,ecx			; 表示ＶＲＡＭ絶対番地
	movsx	esi,[ebx].wsofs		; string data offset
	lodsb				; 文字列バイト長
	movzx	ecx,al
	call	dspstr
	add	ebx,size wsidx		; 次の文字列データ番地へ
	jmp	dspws1
dspws8:	pop	esi
	ret
dspws	endp

;*******************************
; dspwb : display window box
;
; in : ebx = data address
;      winadr = window base address
;      es = VRAM selector
; use: eax,ebx,ecx,edx,edi
; call: wbup
;
dspwb	proc
dspwb1:	movzx	edi,[ebx].wbposx	; position x
	test	edi,edi			; check box end
	jz	short dspwb9		; box data end
	add	edi,winadr
	movzx	edx,[ebx].wbposy	; position y
	shl	edx,VRAMP+1
	add	edi,edx			; box VRAM absolute address
	movzx	edx,[ebx].wbwidth	; width
	push	ebx
	movzx	ebx,[ebx].wbhight	; hight
	call	wbup
	pop	ebx
	add	ebx,size wbstr		; next box data address
	jmp	dspwb1
dspwb9:	ret
dspwb	endp

;*******************************
; overw : 文字上書き/カーソル移動
;
; in : al = 文字コード
; use: eax,ebx,edi
; call: insnb,dspnb,click,dspag
;
overw	proc
	cmp	al,0Fh
	ja	short ovw20	; move cursor
;
	mov	ebx,bufadr
	mov	edi,curptr
	cmp	edi,datsiz	; check data under cursor
	jb	short ovw10	; overwrite
	call	insnb		; insert null byte
	jc	ovw90		; insert error
ovw10:	mov	ah,[ebx+edi]	; current byte data
	cmp	nibpos,0	; check nible position
	je	short ovw12	; high nible position
	and	ah,0F0h		; clear low nible
	jmp	short ovw18
ovw12:	and	ah,0Fh		; clear high nible
	shl	al,4
ovw18:	or	al,ah		; set high/low nible
	mov	[ebx+edi],al	; renew byte data
	mov	datchg,TRUE	; data change flag on
	mov	lastep,edi	; カレント編集位置保存
	call	dspnb		; display new byte
	mov	al,nibpos	; 音程
	call	click		; クリック音
	jmp	short ovw30	; go to move cursor to right
;
ovw20:	sub	al,89
	jz	short ovw30	; move to right
	dec	al
	jz	short ovw40	; move to left
	dec	al
	jz	ovw50		; move to up
;
	mov	eax,curptr	; move cursor to next line
	add	eax,10h
	cmp	eax,datsiz	; check exist next line
	ja	ovw90		; no exist
	mov	curptr,eax	; renew pointer
	cmp	al,10h
	jb	ovw58		; next page
	jmp	ovw90		; same page
;
ovw30:	cmp	nibpos,0	; move cursor to right
	jne	short ovw32
	inc	nibpos		; go to low nible
	jmp	short ovw90
ovw32:	mov	eax,curptr	; check data bottom
	cmp	eax,datsiz
	jae	short ovw90	; can't move
	mov	nibpos,0	; go to next byte high nible
	inc	curb
	jnz	short ovw90	; same page
	inc	curpag		; next page
	jmp	short ovw58
;
ovw40:	cmp	nibpos,1	; move cursor to left
	jne	short ovw42
	dec	nibpos		; go to high nible
	jmp	short ovw90
ovw42:	cmp	curptr,0	; check top of data
	je	short ovw90	; can't move
	mov	nibpos,1	; go to previous byte low nible
	sub	curb,1
	jnc	short ovw90	; same page
	dec	curpag		; previous page
	jmp	short ovw58	; go to display page
;
ovw50:	mov	eax,curptr	; move cursor to up line
	sub	eax,10h
	jb	short ovw90	; can't move
	mov	curptr,eax	; renew pointer
	cmp	al,0E0h
	jb	short ovw90	; same page
ovw58:	push	ecx
	push	edx
	call	dspag
	pop	edx
	pop	ecx
ovw90:	ret
overw	endp

;*******************************
; click : クリック音
;
; in : clkflg = クリック音フラグ
;      al = 音程フラグ(0=高音,1=低音)
; use: none
;
click	proc
	cmp	clkflg,TRUE	; クリック音フラグを調べる
	jne	short clk90	; 鳴らさない
	push	eax
	push	ebx
	push	edx
	mov	edx,20		; 19200/20Hz
	test	al,al
	jnz	short clk20
	mov	edx,18		; 19200/18Hz
clk20:	mov	ah,03h		; ブザーをならす
	mov	ebx,2		; 20ms
	int	9Eh
	pop	edx
	pop	ebx
	pop	eax
clk90:	ret
click	endp

;*******************************
; swiclk : クリック音オン/オフ
;
; in : clkflg = クリック音フラグ
; use: al
;
swiclk	proc
	mov	al,FALSE
	cmp	clkflg,al	; 現在の状態を調べる
	jne	short swick8	; クリック音を消す
	mov	al,TRUE		; クリック音を出す
swick8:	mov	clkflg,al
	ret
swiclk	endp

;*******************************
; dspksh : カナシフト状態の表示
;
; in : shifts = キーシフト状態
; use: none
; call: dspstr
;
kanaon	db	"［カナ］"
kanaoff	db	"［英字］"
dspksh	proc
	push	ecx
	push	esi
	push	edi
	mov	esi,offset kanaon	; カナシフト状態文字列
	cmp	shifts,10b
	je	short dpksh5
	mov	esi,offset kanaoff	; カナシフトオフ状態文字列
dpksh5:	mov	ecx,8			; 文字列バイト長
	mov	edi,(SMENY+2)*VRAMW+VRAMDW-8*4-2	; 描画番地
	call	dspstr
	pop	edi
	pop	esi
	pop	ecx
	ret
dspksh	endp

;*******************************
; melt : 解凍
;
; use: all
; call: dspwf,dspws,dspwb,getew
;       mcoff,mcon,xorbox,erawin
;       maktpn,create,exec
;
melt	proc
;-------------------------------
; ウィンドウ描画
;-------------------------------
	mov	esi,offset window7	; ウィンドウ枠の表示
	call	dspwf
melt10:	call	mcoff			; マウスカーソル消去
	mov	ebx,offset w7str	; ウィンドウ内文字列表示
	call	dspws
	mov	ebx,offset w7box	; ウィンドウ内枠表示
	call	dspwb
	call	mcon			; マウスカーソル表示
;-------------------------------
; イベント読み出し
; in : esi = ウィンドウ枠データ
;-------------------------------
melt30:	call	getew			; ウィンドウイベント読み出し
	cmp	al,EvtClose
	je	melt90			; ウィンドウを閉じる
	cmp	al,EvtUpdate
	je	melt10			; ウィンドウ内部描画
	cmp	al,M$RDown
	je	melt90			; ウィンドウを閉じる
	cmp	al,M$LDown
	jne	melt30			; 次のイベント読み込みへ
;-------------------------------
; クリック位置を調べる
; in : edx = ウィンドウ内Ｙ座標
;-------------------------------
melt40:	mov	eax,edx
	sub	eax,WBARH
	cdq
	mov	ecx,20
	div	ecx
	push	eax
	imul	ebp,eax,20*VRAMW
	add	ebp,winadr
	add	ebp,WBARH*VRAMW+2
	mov	edx,11*4		; 反転バイト幅
	mov	ebx,20			; 反転ピクセル高さ
	mov	al,C$SELB		; 反転ビットコード
	call	mcoff			; マウスカーソル消去
	call	xorbox			; 矩形領域反転
	call	mcon			; マウスカーソル表示
	pop	eax
;-------------------------------
; 一時ファイル作成
; in : eax = 処理番号(0-4)
;-------------------------------
	mov	edx,offset pbbuf
	call	maktpn			; 一時ファイルパスの生成
	push	eax
	call	create			; ファイル生成書き出し
	pop	eax
	jc	short melt90		; エラー終了
	mov	dbflg,FALSE		; ディレクトリバッファクリア
;-------------------------------
; 解凍
; in : eax = 処理番号(0-4)
;-------------------------------
	mov	ebx,offset parblk	; パラメータブロックの位置
	movzx	edx,cmdlns[eax*4]	; プログラム名番地
	movzx	eax,cmdlns[eax*4+2]	; コマンドライン番地
	mov	[ebx+6],eax		; 設定
	push	es
	push	ds
	pop	es
	call	exec			; 子プロセスの実行
	pop	es
	jc	short meltE0		; 起動不能
;
	mov	ah,4Dh			; 子プロセスからリターンコードを得る
	int	21h
	test	ax,ax
	jnz	short meltE4		; 子プロセスエラー終了
;-------------------------------
; 一時ファイルの削除
;-------------------------------
melt80:	mov	edx,offset pbbuf
	mov	ah,41h
	int	21h
;-------------------------------
; 終了処理
;-------------------------------
melt90:	mov	esi,offset window7	; ウィンドウ枠データ番地
	call	erawin			; ウィンドウを消去
	ret
;
meltE0:	cmp	eax,8
	je	short meltE2
	mov	al,E$PNNF		; ファイルが見つからない
	jmp	short meltE8
meltE2:	mov	al,E$MemFul		; メモリ不足エラー
	jmp	short meltE8
meltE4:	mov	al,E$Child		; 子プロセス異常終了
meltE8:	call	dsperr
	jmp	melt80
melt	endp

;*******************************
; maktpn : 一時ファイルパスの生成
;
; in : eax = 拡張子番号(0-4)
;      edx = 格納番地
; use: none
;
maktpn	proc
	push	esi
	push	eax
	mov	esi,offset tmpfn	; ファイル名
	lodsd
	mov	[edx],eax
	lodsd
	mov	[edx+4],eax
	pop	eax
	mov	esi,dword ptr tmpext[eax*4]	; 拡張子
	mov	[edx+8],esi
	mov	byte ptr [edx+12],0	; 終端子
	pop	esi
	ret
maktpn	endp

;*******************************
; exec : 子プロセスの実行
;        環境パスサーチ付き
;
; in : (es:ebx) = パラメータブロック番地
;      (ds:edx) = 実行ファイル名(ASCIZ)
; err: cf = キャリーセット
;      eax = エラーコード
; use: ecx,edx,esi,edi,ebp
;      pbbuf+16
; call: chgmc
;
exec	proc
	push	gs
	mov	eax,002Ch		; 環境セグメントセレクタ
	mov	gs,ax
	mov	al,M$TCUP		; ちょっと待ってください
	call	chgmc
;-------------------------------
; サーチパス文字列を探す
;-------------------------------
	xor	esi,esi
exec10:	mov	al,gs:[esi]
	test	al,al
	jz	short exec18		; サーチパス指定なし
	cmp	al,"P"
	jne	short exec12		; PATH=でない
	cmp	dword ptr gs:[esi+1],"=HTA"
	je	short exec16		; PATH=見つかる
exec12:	inc	esi			; 環境文字列スキップ
	cmp	byte ptr gs:[esi],0
	jne	exec12
	inc	esi
	jmp	exec10
exec16:	add	esi,5
exec18:	mov	dword ptr ds:pbbuf[16],esi	; サーチパス文字列番地保存
;-------------------------------
; コマンド実行
;-------------------------------
	mov	ebp,edx			; ファイル名番地保存
	mov	edx,offset pbbuf+20	; パス名格納番地
	mov	edi,edx			; パス名格納番地
exec40:	mov	esi,ebp			; ファイル名番地
	lodsb				; ファイル名バイト長
	movzx	ecx,al
	rep	movsb			; ファイル名の複写
	xor	al,al			; 終端記号
	stosb
;
	mov	ax,4B00h		; プログラムの実行
	int	21h
	jnc	short exec99		; 正常終了
	cmp	eax,2
	jne	short exec96		; パス名無効以外のエラー
;-------------------------------
; 環境パスの設定
;-------------------------------
	mov	esi,dword ptr ds:pbbuf[16]
	mov	al,gs:[esi]
	test	al,al
	jz	short exec90		; 環境パスなし
;
	mov	edi,edx			; パス名格納番地
exec80:	inc	esi
	stosb
	mov	al,gs:[esi]
	test	al,al
	jz	short exec86
	cmp	al,';'
	jne	exec80
	inc	esi
exec86:	mov	al,'\'
	cmp	[edi-1],al
	je	short exec88
	stosb
exec88:	mov	dword ptr ds:pbbuf[16],esi	; 新ポインタ保存
	jmp	exec40
;-------------------------------
; 終了処理
;-------------------------------
exec90:	mov	eax,2			; ファイルなし
exec96:	stc				; キャリーセット
exec99:	pop	gs
	pushf
	push	eax
	mov	al,M$POINT		; 普通の形状に戻す
	call	chgmc
	pop	eax
	popf
	ret
exec	endp

;*******************************
; repov : 反復上書
;
; use: all
; call: dspwf,mcoff,dspws,dspwb
;       dsprc,dsprn,mcon,getew
;       chkwb,rev8d,d1hex,d1chr
;       chkar,fill,erawin,revwb
;
repov	proc
	mov	eax,bufsiz		; 上書上限値のチェック
	sub	eax,curptr
	cmp	eax,ovwbyte
	ja	short rpov10
	mov	ovwbyte,eax		; 上書バイト数初期値修正
;-------------------------------
; ウィンドウ表示
;-------------------------------
rpov10:	mov	esi,offset window8	; ウィンドウ枠の表示
	call	dspwf
rpov12:	call	mcoff			; マウスカーソル消去
	mov	ebx,offset w8str	; ウィンドウ内文字列表示
	call	dspws
	mov	ebx,offset w8box	; display window boxes
	call	dspwb
	call	dsprc			; 繰り返しコードの表示
	mov	eax,ovwbyte		; 上書バイト数表示
	call	dsprn
;-------------------------------
; イベント読み込み
;-------------------------------
rpov20:	call	getew			; get event through window
	cmp	al,EvtClose
	je	rpov90			; close window
	cmp	al,EvtUpdate
	je	rpov12			; display window contents
	cmp	al,M$RDown
	je	rpov90			; close window
	cmp	al,M$LDown
	jne	rpov20			; 無効イベント
;-------------------------------
; 左ボタン押し下げ位置を調べる
; in : ecx = ウィンドウ内Ｘ位置
;      edx = ウィンドウ内Ｙ位置
;      bx = 左ボタン押し下げ時刻
;-------------------------------
	mov	dwntime,bx		; 左ボタン押し下げ時刻を保存する
	mov	ebx,offset w8box	; ボックス範囲内か調べる
	call	chkwb
	jc	rpov20			; ボックス範囲外
	test	eax,eax
	jz	short rpov50		; 16進上書コード
	dec	eax
	jz	short rpov60		; ANK上書コード
	dec	eax
	jz	short rpov80		; 上書実行
;-------------------------------
; 上書バイト数の変更
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;-------------------------------
rpov40:	mov	eax,ovwbyte		; 現在上書バイト数
	call	rev8d			; 10進数を増減する
	mov	ecx,curptr		; 上書上限値のチェック
	add	ecx,eax
	cmp	ecx,bufsiz
	ja	short rpov48		; 上書不可能
	mov	ovwbyte,eax		; 上書バイト数更新
	call	dsprn			; 繰り返しバイト数の表示
rpov48:	call	chkar			; オートリピートチェック
	jnc	rpov40			; リピートする
	jmp	rpov20
;-------------------------------
; 16進上書コードの変更
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;-------------------------------
rpov50:	call	d1hex			; 16進数増減値を得る
	add	repcode,al		; 上書コード更新
	call	dsprc			; 繰り返しコードの表示
	call	chkar			; オートリピートチェック
	jnc	rpov50			; リピートする
	jmp	rpov20
;-------------------------------
; ANK上書コードの変更
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;-------------------------------
rpov60:	call	d1chr			; ANK文字増減値を得る
	add	repcode,al		; 挿入コード更新
	call	dsprc			; 繰り返しコードの表示
	call	chkar			; オートリピートチェック
	jnc	rpov60			; リピートする
	jmp	rpov20
;-------------------------------
; 上書の実行
; in : ebx = ボックスデータ番地
;-------------------------------
rpov80:	call	revwb			; 実行ボタン押し下げ表示
;
	mov	nibpos,0		; set nible position
	mov	datchg,TRUE		; data change flag on
	mov	eax,curptr		; カレント編集位置保存
	mov	lastep,eax
;
	mov	ecx,ovwbyte		; 上書バイト数
	add	eax,ecx			; 上書末尾位置
	cmp	eax,datsiz		; データサイズの調整
	jbe	short rpov82		; 必要なし
	mov	datsiz,eax
	add	eax,bufadr
	mov	datend,eax
	call	dspsiz			; 新データサイズの表示
rpov82:	call	fill			; バッファをコードで埋める
;
rpov90:	mov	esi,offset window8	; ウィンドウの消去
	call	erawin
	ret
repov	endp

;*******************************
; ptdel : 部分削除
;
; use: all
; call: dspwf,mcoff,dspws,dspwb
;       dspdel,mcon,getew
;       chkwb,rev8d,chkar
;       delbuf,xorcur,dspag,dspsiz
;       erawin,revwb,savcdp
;
ptdel	proc
	mov	eax,datsiz		; 削除バイト数初期値の修正
	sub	eax,curptr
	cmp	eax,delbyte
	jae	short ptde20		; 修正不要
	mov	delbyte,eax
;-------------------------------
; ウィンドウ表示
;-------------------------------
ptde20:	mov	esi,offset window9	; ウィンドウ枠の表示
	call	dspwf
ptde22:	call	mcoff			; マウスカーソル消去
	mov	ebx,offset w9str	; ウィンドウ内文字列表示
	call	dspws
	mov	ebx,offset w9box	; display window boxes
	call	dspwb
	call	dspdel			; 削除バイト数の表示
;-------------------------------
; イベント読み込み
;-------------------------------
ptde30:	call	getew			; get event through window
	cmp	al,EvtClose
	je	ptde90			; close window
	cmp	al,EvtUpdate
	je	ptde22			; display window contents
	cmp	al,M$RDown
	je	ptde90			; close window
	cmp	al,M$LDown
	jne	ptde30			; 無効イベント
;-------------------------------
; 左ボタン押し下げ位置を調べる
; in : ecx = ウィンドウ内Ｘ位置
;      edx = ウィンドウ内Ｙ位置
;      bx = 左ボタン押し下げ時刻
;-------------------------------
	mov	dwntime,bx		; 左ボタン押し下げ時刻を保存する
	mov	ebx,offset w9box	; ボックス範囲内か調べる
	call	chkwb
	jc	ptde30			; ボックス範囲外
	test	eax,eax
	jnz	short ptde80		; 上書実行
;-------------------------------
; バイト数の変更
; in : ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;-------------------------------
ptde40:	mov	eax,delbyte		; 現在削除バイト数
	call	rev8d			; 10進数を増減する
	mov	ecx,curptr		; 削除上限のチェック
	add	ecx,eax
	cmp	ecx,datsiz
	ja	short ptde48		; 削除不可能
	mov	delbyte,eax		; 削除バイト数更新
	call	dspdel			; 削除バイト数の表示
ptde48:	call	chkar			; オートリピートチェック
	jnc	ptde40			; リピートする
	jmp	ptde30
;-------------------------------
; 削除の実行
; in : ebx = ボックスデータ番地
;-------------------------------
ptde80:	call	revwb			; 実行ボタン押し下げ表示
;
	mov	nibpos,0		; set nible position
	call	savdcp			; データ変更位置の保存
;
	mov	ecx,delbyte		; バッファ内データ削除
	call	delbuf
	call	xorcur			; カーソル消去
	call	dspag			; ページの再表示
	call	xorcur			; カーソル表示
	call	dspsiz			; 新データサイズの表示
;
ptde90:	mov	esi,offset window9	; ウィンドウの消去
	call	erawin
	ret
ptdel	endp

;*******************************
; dspdel : 削除バイト数の表示
;
; in : winadr = ウィンドウ描画番地
;      delbyte = 削除バイト数
; use: eax,edi
; call: dsp8d,mcoff,mcon
;
dspdel	proc
	mov	edi,winadr			; ウィンドウ描画番地
	add	edi,(WBARH+8)*VRAMW+80/2
	mov	eax,delbyte			; 削除バイト数
	call	mcoff				; マウスカーソル消去
	call	dsp8d
	call	mcon				; マウスカーソル表示
	ret
dspdel	endp

;*******************************
; search : 検索
;
; use: all
; call: dspwf,mcoff,mcon,dspws
;       dspwb,getew,chkwb
;       d1chr,d1hex,revbyte
;       dspser,extract,erawin
;       psear,nsear,revwb,chgmc
;
search	proc
	mov	eax,curptr		; カレントポインタの保存
	mov	bakptr,eax
;-------------------------------
; ウィンドウ表示
;-------------------------------
sear10:	mov	esi,offset windowA	; ウィンドウ枠の表示
	call	dspwf
sear12:	call	mcoff			; マウスカーソル消去
	mov	ebx,offset wAstr	; ウィンドウ内文字列表示
	call	dspws
	mov	ebx,offset wAbox	; ウィンドウ内ボタン枠表示
	call	dspwb
	mov	ebp,offset searstr	; 検索文字列番地
	call	dspser			; 検索文字列の表示
	call	mcon			; マウスカーソル表示
;-------------------------------
; イベント読み込み
;-------------------------------
sear20:	mov	esi,offset windowA	; ウィンドウデータ番地
	call	getew			; ウィンドウ内イベント読み込み
	cmp	al,EvtClose
	je	sear90			; ウィンドウを閉じる
	cmp	al,EvtUpdate
	je	sear12			; ウィンドウ内容再表示
	cmp	al,M$RDown
	je	sear90			; ウィンドウを閉じる
	cmp	al,M$LDown
	jne	sear20			; 無効イベント
;-------------------------------
; 左ボタン押し下げ位置を調べる
; in : ecx = ウィンドウ内Ｘ位置
;      edx = ウィンドウ内Ｙ位置
;      bx = 左ボタン押し下げ時刻
;-------------------------------
	mov	dwntime,bx		; 左ボタン押し下げ時刻を保存する
	mov	ebx,offset wAbox	; ボックス範囲内か調べる
	call	chkwb
	jc	sear20			; ボックス範囲外
	cmp	eax,7
	jbe	sear50			; 16進コード入力
	sub	eax,8
	cmp	eax,7
	jbe	sear52			; 文字コード入力
	sub	eax,8
	jz	sear70			; コード抽出
	dec	eax
	jz	sear80			; 後退
;-------------------------------
; 前方/後方検索
; in : eax = 検索方法(1=後方,2=前方)
;      ebx = ボックスデータ番地
;-------------------------------
	cmp	searlen,0		; 検索文字列存在確認
	je	sear20			; 未設定
	call	revwb			; ボタン押し下げ表示
	mov	edi,curptr		; カレントポインタ
	dec	eax
	jnz	short sear40
;
	dec	edi			; 検索開始位置
	js	short sear48		; 検索データなし
	mov	al,M$TCUP
	call	chgmc
	call	psear			; 後方検索
	jmp	short sear44
;
sear40:	inc	edi			; 検索開始位置
	cmp	edi,datsiz
	jae	short sear48		; 検索データなし
	mov	al,M$TCUP
	call	chgmc
	call	nsear			; 前方検索
sear44:	jc	short sear46		; 見つからず
	call	xorcur			; カーソル消去
	mov	curptr,edi		; カレントポインタ更新
	mov	nibpos,0		; ニブル位置の調整
	push	ebx
	call	dspag			; ページ表示
	pop	ebx
	call	xorcur			; カーソル表示
sear46:	mov	al,M$POINT
	call	chgmc
	push	ebx
	call	wailu			; 左ボタンが離されるまで待つ
	pop	ebx
sear48:	call	revwb			; ボタン押し上げ表示
	jmp	sear20
;-------------------------------
; 16進/ANKコード入力
; in : eax = コード番号(0-7)
;      ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;      ebp = 文字列基底番地
;-------------------------------
sear50:	push	offset d1hex		; 16進増減ルーチン
	jmp	short sear58
sear52:	push	offset d1chr		; ANK増減ルーチン
sear58:	call	revbyte
	add	esp,4
	jmp	sear20
;-------------------------------
; コード抽出
; in : ebx = ボックスデータ番地
;-------------------------------
sear70:	mov	ecx,8
	movzx	edi,searlen
	sub	ecx,edi			; 抽出バイト長
	jbe	sear20			; 抽出する余裕なし
	add	edi,ebp			; 複写先番地
	call	extract			; カレント位置よりデータ抽出
	add	searlen,al		; バイト長更新
	call	mcoff			; マウスカーソル消去
	call	dspser			; 検索文字列の表示
	jmp	short sear86
;-------------------------------
; コード列末尾削除
; in : ebx = ボックスデータ番地
;-------------------------------
sear80:	movzx	eax,searlen		; 文字列バイト長
	test	eax,eax
	jz	short sear88		; 削除するコードがない
	dec	eax
	mov	searlen,al		; バイト長の更新
	imul	edi,eax,3*4
	add	edi,(WBARH+8)*VRAMW+6*8/2
	add	edi,winadr
	push	ebx
	mov	ebx,33*32		; 漢字空白文字
	xor	al,al			; ANK消去コード
	call	mcoff			; マウスカーソル消去
	call	dspk
	add	edi,VRAMW*22-2*4
	call	dspc
	pop	ebx
;
sear86:	call	revwb			; ボタン押し下げ表示
	push	ebx
	call	wailu			; 左ボタンが離されるまで待つ
	pop	ebx
	call	revwb			; ボタン押し上げ表示
sear88:	jmp	sear20
;-------------------------------
; 検索終了処理
;-------------------------------
sear90:	mov	eax,bakptr		; ポインタ移動したか調べる
	cmp	eax,curptr
	je	short sear92		; 移動していない
	mov	lastmp,eax		; 移動前保存位置の変更
sear92:	call	erawin
	ret
search	endp

;*******************************
; revwb : ウィンドウボックス反転
;
; in : ebx = ウィンドウボックスデータ番地
;      winadr = ウィンドウ表示番地
;      es = ＶＲＡＭセレクタ
; use: none
; call: mcoff,mcon,xorbox
;
revwb	proc
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	ebp
	movzx	eax,[ebx].wbposy	; Ｙ位置(２ピクセル単位)
	shl	eax,VRAMP+1
	add	eax,winadr
	movzx	ebp,[ebx].wbposx	; Ｘ位置(バイト単位)
	add	ebp,eax			; 表示ＶＲＡＭ番地
	movzx	edx,[ebx].wbwidth	; バイト幅
	movzx	ebx,[ebx].wbhight	; ピクセル高さ
	mov	al,C$SELB		; 反転ビットデータ
	call	mcoff			; マウスカーソル消去
	call	xorbox			; 矩形領域反転
	call	mcon			; マウスカーソル表示
	pop	ebp
	pop	edx
	pop	ecx
	pop	ebx
	pop	eax
	ret
revwb	endp

;*******************************
; nsear : 前方検索
;
; in : searlen = 検索文字列バイト長
;      searstr  = 検索文字列番地
;      bufadr = データ基底番地
;      datsiz = データサイズ
;      edi = 検索開始位置
; out: edi = 見つかった位置
; err: cf = 見つからないときセット
; use: eax,ecx,edx
;
nsear	proc
	push	esi
	push	es
	push	ds
	pop	es
	mov	ecx,datsiz
	sub	ecx,edi			; 検索バイト数
	add	edi,bufadr		; 検索開始番地
	assume	ds:stack
	mov	al,searstr[0]		; 検索第１文字
	assume	ds:data
	movzx	edx,searlen		; 検索文字列バイト長
	dec	edx
	js	short nsearE		; 検索文字列未設定

nsear3:	repne	scasb			; 第１文字検索
	jne	short nsearE		; 一致する文字がない
	push	ecx
	push	edi
	mov	esi,offset searstr+1	; ２文字目以降の一致を調べる
	mov	ecx,edx
	repe	cmpsb
	pop	edi
	pop	ecx
	jne	nsear3			; 一致しなかった
;
	cmp	ecx,edx
	jb	short nsearE		; データ終わりを超えていた
	dec	edi
	sub	edi,bufadr
nsear9:	pop	es
	pop	esi
	ret
;
nsearE:	stc				; キャリーセット
	jmp	nsear9
nsear	endp

;*******************************
; psear : 後方検索
;
; in : searlen = 検索文字列バイト長
;      searstr  = 検索文字列番地
;      bufadr = データ基底番地
;      datsiz = データサイズ
;      edi = 検索開始位置
; out: edi = 見つかった位置
; err: cf = 見つからないときセット
; use: eax,ecx,edx,edi
;
psear	proc
	push	esi
	push	es
	push	ds
	pop	es
	std				; ディレクションフラグセット
	mov	ecx,edi
	inc	ecx			; 検索バイト数
	add	edi,bufadr		; 検索開始番地
	assume	ds:stack
	mov	al,searstr[0]		; 検索第１文字
	assume	ds:data
	movzx	edx,searlen		; 検索文字列バイト長
	dec	edx
	js	short psearE		; 検索文字列未設定
	jz	short psear4
;
psear3:	repne	scasb			; 第１文字検索
	jne	short psearE		; 一致する文字がない
	push	ecx
	push	edi
	cld				; ディレクションフラグクリア
	mov	esi,offset searstr+1	; ２文字目以降の一致を調べる
	add	edi,2
	mov	ecx,edx
	repe	cmpsb
	std				; ディレクションフラグセット
	pop	edi
	pop	ecx
	jne	psear3			; 一致しなかった
;
psear8:	inc	edi
	sub	edi,bufadr
psear9:	cld				; ディレクションフラグクリア
	pop	es
	pop	esi
	ret
;
psear4:	repne	scasb			; １文字検索
	je	psear8			; 見つかった
;
psearE:	stc				; キャリーセット
	jmp	psear9
psear	endp

;*******************************
; dspser : 検索文字列の表示
;
; in : ebp = 検索文字列番地
;      searlen = 文字列バイト長
; use: eax,ecx,edi
; call: dspsc
;
dspser	proc
	movzx	ecx,searlen		; 検索文字列バイト長
	test	ecx,ecx
	jz	short dpser9		; 文字列なし
	xor	edi,edi			; 文字番号初期化
dpser1:	call	dspsc			; 検索文字の表示
	inc	edi			; 文字番号更新
	loop	dpser1
dpser9:	ret
dspser	endp

;*******************************
; extract : カレント位置よりデータ抽出
;
; in : edi = 複写先番地
;      ecx = 複写バイト数
; out: edi = 次の番地
;      eax = 実際に複写したバイト数
; use: eax,ecx
;
extract	proc
	push	esi
	push	ecx
	mov	esi,bufadr		; バッファ基底番地
	add	esi,curptr		; カレント番地
extrt1:	cmp	esi,datend
	jae	short extrt9		; データ終わり
	lodsb				; データバイト読み出し
	mov	[edi],al		; データバイトの複写
	inc	edi			; 次の番地へ
	loop	extrt1
extrt9:	pop	eax
	sub	eax,ecx
	pop	esi
	ret
extract	endp

;*******************************
; revbyte : バイトデータ修正
;
; in : [esp+4] = 増減ルーチン番地
;      esi = ウィンドウデータ番地
;      eax = 文字番号(0-7)
;      ecx = ボックス内Ｘ位置(バイト)
;      edx = ボックス内Ｙ位置(ピクセル)
;      ebx = ボックスデータ番地
;      ebp = 文字列基底番地
; use: eax,ebx,ecx,edx,edi
; call: dspsc,chkar,mcon,mcoff
;
revbyte	proc
	mov	edi,eax			; コード番号保存
	cmp	al,searlen		; 入力位置チェック
	ja	short rvby90		; 入力無効
	jb	short rvby10
	inc	searlen			; 新バイト追加
	mov	byte ptr [ebp+edi],0
	jmp	short rvby20
rvby10:	call	[esp+4]			; ANK文字増減値を得る
	add	[ebp+edi],al		; 検索コード更新
rvby20:	call	mcoff			; マウスカーソル消去
	call	dspsc			; 検索文字の表示
	call	mcon			; マウスカーソル表示
	call	chkar			; オートリピートチェック
	jnc	rvby10			; リピートする
rvby90:	ret
revbyte	endp

;*******************************
; dspsc : 検索文字の表示
;         16進とANK表記
;
; in : edi = 文字番号(0-7)
;      ebp = 文字列基底番地
; use: eax
; call: dsphex,dspc
;
dspsc	proc
	push	edi
	mov	al,[ebp+edi]			; 検索文字コード
	imul	edi,edi,3*4			; 16進表示
	add	edi,(WBARH+8)*VRAMW+6*8/2
	add	edi,winadr
	call	dsphex
	add	edi,VRAMW*22-2*4
	call	dspc
	pop	edi
	ret
dspsc	endp

;*******************************
; savdcp : データ変更位置の保存
;
; use: none
;
savdcp	proc
	push	eax
	mov	datchg,TRUE		; データ変更フラグの設定
	mov	eax,curptr		; カレント編集位置保存
	mov	lastep,eax
	pop	eax
	ret
savdcp	endp
code	ends

;*******************************
; stack segment
;*******************************
stack	segment stack use32 rw
bakpat	db	16*16*4/8 dup(?)	; mouse background pattern
moupat	db	MOUPATN*MOUPATH*MOUPATW*2 dup(?)	; mouse cusor pattern
evtbuf	evtrec	EVTNUM dup(<>)	; event buffer
timestr	db	4 dup(?)	; time string
drvdat	drvstr	MAXDRV dup(<>)	; drive data
dirbuf	fildat	MAXDSN dup(<>)	; directory buffer
curfpn	db	64 dup(?)	; current read file path name
csum	db	16 dup(?)	; column sum calculate buffer
menpos	dw	4 dup(?)	; current menu position data
dfpos	dw	4 dup(?)	; dotted frame position data
searstr	db	8 dup(?)	; 検索文字列格納領域
egbwork	label	byte		; EGB work area
pbbuf	db	PBSIZ dup(?)	; public buffer
sfname	db	13 dup(?)	; save file name input buffer
knjidx	dw	30h*256 dup(?)	; kanji font index
	db	6*1024 dup (?)	; stack area
stack	ends
	end entry
