.286c
	page	,130
	title	ダンプ入力ツール
;*******************************
; DIN : ダンプ入力ツール
;    (C)1989.6.18 by Fumi
; #1 1989.6.20  初版
; #2 1989.11.2  ^KSバグ修正
;*******************************
	include	msdos.def
FMR	equ	FALSE
MINBUF	equ	1024	; 編集バッファー最小サイズ
PAGLIN	equ	16	; ページ行数
PAGWID	equ	16	; ページ幅
PAGSIZ	equ	256	; ページサイズ(固定)
;
tblitem	struc		; コマンドテーブル項目
cmdchr	db	?	; 文字コード
paddr	dw	?	; 処理番地
tblitem	ends

;*******************************
; コードセグメント
;*******************************
code	segment
	assume	cs:code,ds:data,es:data,ss:data
code_s	equ	$
;
	org	100h
entry:	jmp	main		; メインコードへ

;*******************************
; 定数データ
;*******************************
memEM	db	"メモリが足りません",CR,LF
memEL	equ	$-memEM
openEM	db	"ファイルをオープンできません",CR,LF
openEL	equ	$-openEM
readEM	db	"ファイル読み込みエラー",CR,LF
readEL	equ	$-readEM
sizeEM	db	"ファイルが大き過ぎます",CR,LF
sizeEL	equ	$-sizeEM
sucendM	db	C$ESC,"[u"	; カーソル位置および文字属性の回復
	db	C$ESC,"[2J"	; 画面全体の消去
	db	"DIN終了",CR,LF
sucendL	equ	$-sucendM
creEM	db	C$ESC,"[20;0H",C$ESC,"[0J",C$ESC,"[33m","ファイルが作れません"
creEL	equ	$-creEM
finM	db	C$ESC,"[21;0H","ファイル名:",C$ESC,"[37m",C$ESC,"[0K"
finL	equ	$-finM
;
frameP	db	C$ESC,"[s"	; カーソル位置および文字属性の保存
	db	C$ESC,"[2J"	; 画面全体の消去
cyanrP	db	C$ESC,"[7;36m"	; 水色反転
cyanrL	equ	$-cyanrP
	db	"ADDR +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F SUM"
	db	C$ESC,"[m",C$ESC,"[19;1H","SUM "
frameL	equ	$-frameP
menu1P	db	C$ESC,"[0;33m"	; 黄色
	db	C$ESC,"[20;0H",C$ESC,"[0J"
	db	"^E:上移動  ^A:左ﾊﾞｲﾄ  ^G:ﾊﾞｲﾄ削除  ^K:ﾌｧｲﾙ･ﾒﾆｭｰ",CR,LF
	db	"^X:下移動  ^F:右ﾊﾞｲﾄ  ^Y:行削除 ",CR,LF
	db	"^S:左移動  ^R:前頁    SPAC:00挿入",CR,LF
	db	"^D:右移動  ^C:次頁    ^N:空行挿入",CR,LF
	db	C$ESC,"[37m"	; 白色
menu1L	equ	$-menu1P
menu2P	db	C$ESC,"[33m"		; 黄色
	db	C$ESC,"[20;0H",C$ESC,"[0J"	; 画面下部消去
	db	"(S:保存&続行  X:保存&終了  Q:中止終了):"
	db	C$ESC,"[37m"		; 白色
menu2L	equ	$-menu2P
;
whiteP	db	C$ESC,"[0;37m"	; 白色
whiteL	equ	$-whiteP
;
; コマンドテーブル
;
cmdtbl	tblitem	<UP,curup>	; 上移動
	tblitem	<DWN,curdwn>	; 下移動
	tblitem	<LFT,curlft>	; 左移動
	tblitem	<RGT,currgt>	; 右移動
	tblitem	<Ctr_E,curup>	; 上移動
	tblitem	<Ctr_X,curdwn>	; 下移動
	tblitem	<Ctr_S,curlft>	; 左移動
	tblitem	<Ctr_D,currgt>	; 右移動
	tblitem	<Ctr_A,blft>	; 左バイト
	tblitem	<Ctr_F,brgt>	; 右バイト
	tblitem	<DEL,delb>	; １バイト削除
	tblitem	<Ctr_G,delb>	; １バイト削除
	tblitem	<Ctr_Y,dell>	; １行削除
	tblitem	<SPAC,insby>	; 空バイト挿入
	tblitem	<Ctr_N,insl>	; 空行挿入
	tblitem	<Ctr_R,pagup>	; 前ページ
	tblitem	<Ctr_C,pagdwn>	; 次ページ
	tblitem	<Ctr_K,fmenu>	; ファイルメニュー
cmdN	equ	($-cmdtbl)/size tblitem
;
; １６進数文字テーブル
;
hextbl	db	"0123456789ABCDEF"	; フルキー
	db	"0123456789*/-+=."	; テンキー
	db	"ﾐﾓﾈﾙﾏﾉﾘﾅﾆﾗﾔﾕﾖﾜｾﾚ"	; 疑似テンキー
hexN	equ	$-hextbl
;*******************************
; メインコードスタート
;*******************************
main:
;------------------------------
; メモリ初期化
;------------------------------
	mov	ax,memable		; 使用可能なバイト数(100h別)
	cmp	ax,MEMSIZ		; 必要メモリサイズと比較
	jae	main10			; 十分である
;
	assume	ds:code
	mov	dx,offset memEM		; メモリ不足
	mov	cx,memEL
	jmp	main92			; メッセージ表示終了へ
	assume	ds:data
;
main10:	add	ax,000Fh		; ラウンドアップして
	shr	ax,4			; パラグラフサイズへ変換
	add	ax,11h			; システムスタック分追加
	mov	bx,ax
	msdos	F$ChgMem		; メモリブロックサイズ変更
	jnc	main12			; 変更完了
;
	jmp	main99			; プロセスの終了へ
;
main12:	xor	ax,ax			; 変数領域クリア
	mov	di,offset bufsiz
	mov	cx,(offset csumb-offset bufsiz)/2
	rep	stosw
;
	shl	bx,4
	sub	bx,offset buffer+100h	; 編集バッファーサイズ
	mov	bufsiz,bx		; 保存
;------------------------------
; 読み込みファイルの決定
;------------------------------
	mov	si,offset cmdln+1	; 引数領域の番地
main20:	lodsb
	cmp	al,SPAC
	je	main20
	cmp	al,TAB
	je	main20
	cmp	al,CR
	je	main40			; 引数なし＝読み込みなし
;
	dec	si
	mov	dx,si
main22:	cmp	byte ptr [si],20h	; ファイル名終端探索
	jbe	main24
	inc	si
	jmp	main22
main24:	mov	byte ptr [si],0		; ファイル名終端記号
;
	mov	filnam,dx		; ファイル名ポインタ保存
	xor	al,al			; リードオープン
	msdos	F$Open
	jnc	main30			; オープン成功
	cmp	ax,02h			; ファイルがなければ
	je	main40			; 新規作成である
;
	assume	ds:code
	mov	dx,offset openEM	; オープンエラー
	mov	cx,openEL
	jmp	main92			; メッセージ表示終了へ
	assume	ds:data
;------------------------------
; ファイルの読み込み
; in : ax = ファイルハンドル
;------------------------------
main30:	mov	bx,ax			; ファイルハンドル
	mov	cx,bufsiz		; バッファーサイズ分
	mov	dx,offset buffer	; バッファー番地
	msdos	F$Read
	jnc	main32

	assume	ds:code
	mov	dx,offset readEM	; 読み込みエラー
	mov	cx,readEL
	jmp	main92			; メッセージ表示終了へ
	assume	ds:data

main32:	cmp	ax,cx			; ファイルサイズ確認
	jb	main34			; 大きすぎない
;
	assume	ds:code
	mov	dx,offset sizeEM	; ファイルサイズエラー
	mov	cx,sizeEL
	jmp	main92			; メッセージ表示終了へ
	assume	ds:data

main34:	mov	filsiz,ax		; ファイルサイズ設定
	msdos	F$Close			; 読み込みファイルクローズ
;------------------------------
; 画面表示
;------------------------------
main40:	call	dspfr			; フレーム表示＆初期化
main42:	assume	ds:code
	mov	si,offset menu1P	; 編集メニュー表示
	mov	cx,menu1L
	assume	ds:data
	call	putstr
main44:	call	dspaddr			; 番地表示
	call	dsppag			; ページ表示
;------------------------------
; キー入力処理
;------------------------------
main50:	call	curloc			; カーソルロケート
	msdos	F$ConIn			; キー入力
;
	assume	ds:code
	mov	cx,cmdN			; コマンド数
	xor	si,si
main52:	cmp	al,byte ptr cmdtbl[si]	; コード探索
	je	main58			; 見つかった
	add	si,size tblitem		; 次のコマンドへ
	loop	main52
;
	cmp	al,60h			; 小文字？
	jl	main54			; 違う
	and	al,11011111b		; 大文字化
main54:	mov	cx,hexN			; 文字数
	xor	si,si
main56:	cmp	al,hextbl[si]		; 比較
	je	chrin			; あった->文字入力へ
	inc	si			; 次の文字候補へ
	loop	main56
;
	mov	al,BEL			; 警告音
	call	putc
	jmp	main50

main58:	jmp	word ptr [si+cmdtbl+paddr]	; 該当処理へジャンプ
	assume	ds:data
;------------------------------
; カーソル移動後の処理
; in : curptr = 新ポインタ
; out: curx = 新Ｘ座標
;      cury = 新Ｙ座標
;      curpag = 新ページ
;------------------------------
main60:	mov	ax,curptr		; 新しいバッファー位置
	mov	dl,al
	and	dl,0Fh			; 下位ニブル抽出
	mov	curx,dl			; 新Ｘ座標設定
	shr	al,4			; 上位ニブル抽出
	mov	cury,al			; 新Ｙ座標設定
	cmp	ah,curpag		; 旧ページと比較
	je	main50			; 同じときはカーソルロケートのみへ
	mov	curpag,ah		; 新ページ設定
	jmp	main44			; ページ描画へ
;------------------------------
; 終了処理
;------------------------------
main90:	assume	ds:code
	mov	dx,offset sucendM	; 正常終了メッセージ
	mov	cx,sucendL
	assume	ds:data
main92:	mov	bx,STDERR
	msdos	F$Write			; メッセージ出力
main99:	xor	al,al			; リターンコード
	msdos	F$Exit			; プロセスの終了

;------------------------------
; １６進入力
; in : si = 対象文字オフセット
;------------------------------
chrin:	mov	di,curptr		; バッファオフセット
	cmp	di,filsiz		; 範囲内のときは
	jb	chri2			; 修正
	cmp	di,bufsiz		; バッファーサイズチェック
	jae	main50			; あふれた
;
	inc	filsiz			; ファイルサイズ拡張
	mov	buffer[di],0		; バイトデータは０に初期化
	mov	curnb,1			; 下位ニブル位置に
	call	curloc
	mov	al,'0'			; ０と
	call	putc			; 表示して
	mov	curnb,0			; 上位ニブル位置に
	call	curloc			; カーソルをセットする
;
chri2:	and	si,000Fh		; バイナリ数値に変換
	assume	ds:code
	mov	al,hextbl[si]		; １６進文字
	assume	ds:data
	call	putc			; ニブル表示
;
	mov	ax,si
	cmp	curnb,0			; カレントニブル位置？
	jne	chri4			; 下位ニブル位置
	shl	al,4
	and	byte ptr buffer[di],0Fh	; 上位ニブル消去
	jmp	short chri6
chri4:	and	byte ptr buffer[di],0F0h	; 下位ニブル消去
chri6:	or	buffer[di],al		; バイトデータ修正
	mov	al,cury			; 行サム計算
	call	lsum
	mov	al,curx			; 列サム計算
	call	csum
	mov	al,PAGLIN		; トータルサム計算
	call	lsum
	jmp	short currgt		; カーソル右移動へ
;------------------------------
; カーソル上移動
;------------------------------
curup:	sub	curptr,PAGWID		; ポインタを一行分上へ
	jae	blf8			; 画面処理へ
	add	curptr,PAGWID		; 元に戻す
curu8:	jmp	main50			; カーソルロケートへ
;------------------------------
; カーソル下移動
;------------------------------
curdwn:	add	curptr,PAGWID		; ポインタを一行分下へ
	mov	ax,filsiz		; ファイルサイズ
	cmp	ax,curptr		; 上限を調べる
	jae	blf8			; 範囲内なので画面処理へ
	sub	curptr,PAGWID		; 元に戻す
	jmp	main50			; カーソルロケートへ
;------------------------------
; 左バイト
;------------------------------
blft:	mov	curnb,0			; 上位ニブル
blf2:	cmp	curptr,0
	je	blf8
	dec	curptr			; 左バイトへ移動
	jmp	short blf8
	db	06,39,09,00
	nop
blf8:	jmp	main60			; 画面処理へ
;------------------------------
; 右バイト
;------------------------------
brgt:	inc	curptr
	mov	curnb,0			; 上位ニブルへ
brg2:	mov	ax,filsiz		; ファイルサイズ
	cmp	ax,curptr		; 範囲内にあるか調べる
	jae	brg8			; 画面処理へ
	mov	curptr,ax		; ファイル末尾へ
brg8:	jmp	main60			; 画面処理へ
;------------------------------
; カーソル左移動
;------------------------------
curlft:	dec	curnb			; バイト内移動
	jns	curu8			; カーソルロケートへ
	mov	curnb,1			; 下位ニブルにして
	jmp	blf2			; 左バイト移動へ
;------------------------------
; カーソル右移動
;------------------------------
currgt:	mov	ax,filsiz		; ファイルサイズ
	cmp	ax,curptr		; 範囲内にあるか調べる
	jbe	currg8			; 無効
	inc	curnb
	cmp	curnb,1
	jne	brgt			; 右バイト移動へ
currg8:	jmp	main50			; カーソルロケートへ
;------------------------------
; 前頁
;------------------------------
pagup:	sub	curptr,PAGSIZ		; ページを減らしてみる
	jae	pagu8			; 可能のときは画面処理へ
	mov	curptr,0		; できないときファイル先頭へ
pagu8:	jmp	main60			; 画面処理へ
;------------------------------
; 次頁
;------------------------------
pagdwn:	add	curptr,PAGSIZ		; ページを増やしてみる
	jmp	brg2			; 範囲チェックへ
;------------------------------
; １バイト削除
;------------------------------
delb:	mov	di,curptr		; カレントポインタ
	cmp	di,filsiz		; ファイルサイズと比較
	jae	delb9			; 削除無効
;
	dec	filsiz			; ファイルサイズ縮小
	mov	cx,filsiz
	sub	cx,di			; 移動すべきバイト数
	add	di,offset buffer
	mov	si,di
	inc	si
	rep	movsb			; バイト移動
;
	mov	curnb,0			; 上位ニブル位置へ
	call	dspdp			; ページ下部表示
delb9:	jmp	main50			; カーソルロケートへ
;------------------------------
; １行削除
;------------------------------
dell:	call	hedlin			; カーソル行頭移動
;
	mov	cx,filsiz
	mov	si,curptr
	mov	di,si
	add	si,PAGWID
	sub	cx,si			; 移動すべきバイト数
	jb	dell2			; 無効
	add	si,offset buffer
	add	di,offset buffer
	rep	movsb			; バイト移動
;
dell2:	add	cx,PAGWID		; 縮小バイト数
	sub	filsiz,cx		; ファイルサイズ更新
;
	call	dspdp			; ページ下部表示
dell8:	jmp	main50			; カーソルロケートへ
;------------------------------
; 空バイト挿入
;------------------------------
insby:	mov	cx,filsiz		; ファイルサイズ
	cmp	cx,bufsiz		; バッファー空きあるか？
	jae	insby8			; ない
;
	std
	mov	di,cx
	add	di,offset buffer	; 移動元基底番地
	mov	si,di
	dec	si			; 移動先基底番地
	sub	cx,curptr		; 移動バイト数
	rep	movsb
	mov	byte ptr [di],0		; 空バイト挿入
	cld
;
	inc	filsiz			; ファイルサイズ更新
	mov	curnb,0			; 上位ニブル位置に設定
	call	dspdp			; ページ下部表示
insby8:	jmp	main50			; カーソルロケートへ
;------------------------------
; 空行挿入
;------------------------------
insl:	mov	ax,filsiz
	mov	cx,ax
	add	ax,PAGWID		; 新ファイルサイズ
	cmp	ax,bufsiz		; バッファー内に収まる？
	ja	insl8			; 無効
;
	mov	filsiz,ax		; ファイルサイズ更新
	call	hedlin			; カーソル行頭移動
;
	mov	si,cx
	sub	cx,curptr		; 移動すべきバイト数
	add	si,offset buffer-1
	mov	di,si
	add	di,PAGWID
	std
	rep	movsb			; バイト移動
	mov	cx,PAGWID
	xor	al,al
	rep	stosb			; 空行データ書き込み
	cld
;
	call	dspdp			; ページ下部表示
insl8:	jmp	main50			; カーソルロケートへ
;------------------------------
; ファイルメニュー
;------------------------------
fmenu:	assume	ds:code
	mov	si,offset menu2P	; ファイルメニュー表示
	mov	cx,menu2L
	assume	ds:data
	call	putstr
;
	msdos	F$ConIn
	cmp	al,60h			; 小文字？
	jl	fmen1			; 違う
	and	al,11011111b		; 大文字化
fmen1:	and	al,00111111b		; Ctrコード化
	cmp	al,Ctr_S
	je	savres			; 保存＆続行
	cmp	al,Ctr_X
	je	savexi			; 保存＆終了
	cmp	al,Ctr_Q
	je	quit			; 中止終了
	cmp	al,C$ESC
	je	fmen8			; 編集モードへ
;
	mov	al,BEL			; 無効指令のときは警告音
	call	putc
;
fmen8:	assume	ds:code
	mov	si,offset menu1P	; 編集メニュー表示
	mov	cx,menu1L
	assume	ds:data
	call	putstr
	jmp	main50			; カーソルロケートへ
;------------------------------
; 保存＆続行
;------------------------------
savres:	call	save			; ファイル保存
	jmp	fmen8			; 編集メニュー表示へ
;------------------------------
; 保存＆終了
;------------------------------
savexi:	call	save			; ファイル保存
	jmp	main90			; 終了へ
;------------------------------
; 中止終了
;------------------------------
quit:	jmp	main90			; 終了へ

;*******************************
; save : ファイル保存
; in : filnam = ファイル名ポインタ
; use: ax,bx,cx,dx,si
; call: putstr
;
save	proc
	mov	dx,filnam		; ファイル名ポインタ
	test	dx,dx			; ファイル指定済み？
	jnz	save20			; はいな
;
save10:	assume	ds:code
	mov	si,offset finM		; ファイル名入力プロンプト
	mov	cx,finL
	assume	ds:data
	call	putstr
	mov	dx,offset cmdln		; 入力バッファー番地
	mov	cx,128
	mov	bx,STDIN
	msdos	F$Read
	jc	save10			; 入力エラー->やり直し
	sub	ax,2			; 文字列長さチェック
	jbe	save10			; やり直し
	mov	bx,ax
	add	bx,dx
	mov	byte ptr [bx],0		; ASCIZにする
	mov	filnam,dx		; ファイル名ポインタ設定
;
save20:	xor	cx,cx			; 普通のファイル属性
	msdos	F$Create		; 生成
	jc	saveE0			; 生成エラー
	mov	bx,ax			; ファイルハンドル
	mov	cx,filsiz		; 書き込みバイト数
	mov	dx,offset buffer	; バッファー番地
	msdos	F$Write
	msdos	F$Close			; ファイルクローズ
	ret
;
saveE0:	assume	ds:code
	mov	si,offset creEM		; 生成エラーメッセージ
	mov	cx,creEL
	assume	ds:data
	call	putstr
	jmp	save10			; ファイル名再指定へ
save	endp

;*******************************
; dspfr : フレーム表示＆初期化
; use: ax,cx,dx,si
; call: putstr,locate
;
dspfr	proc
	assume	ds:code
	mov	si,offset frameP
	mov	cx,frameL
	assume	ds:data
	call	putstr
;
	mov	dx,1100h
	call	locate
	mov	al,'-'
	mov	cx,PAGWID*3+4+4
dspfr2:	call	putc
	loop	dspfr2
;


	ret
dspfr	endp

;*******************************
; dspaddr : 番地表示
; in : curpag = カレントページ
; use: ax.cx,dx,si
; call: putstr,locate,dsphex,putc
;
dspaddr	proc
	assume	ds:code
	mov	si,offset cyanrP	; 水色反転
	mov	cx,cyanrL
	call	putstr
	assume	ds:data
;
	mov	dx,0100h		; 座標初期化
	call	locate
	xor	si,si
	mov	cx,PAGLIN
dspad1:	mov	al,curpag		; カレントページ番号
	call	dsphex			; 上位番地表示
	mov	al,hextbl[si]		; 下位番地表示
	call	putc
	mov	al,'0'
	call	putc
	mov	al,CR
	call	putc
	mov	al,LF
	call	putc
	inc	si
	loop	dspad1
;
	assume	ds:code
	mov	si,offset whiteP	; 白色
	mov	cx,whiteL
	call	putstr
	assume	ds:data
	ret
dspaddr	endp

;*******************************
; curloc : カーソルロケート
; in : curx = Ｘ座標
;      cury = Ｙ座標
; call: locate
;
curloc	proc
	push	dx
	mov	dx,word ptr curx	; カレント座標
	shl	dl,1
	add	dl,curx
	add	dx,0105h		; 画面上のバイト位置
	add	dl,curnb		; ニブル位置調整
	call	locate			; カーソルロケート
	pop	dx
	ret
curloc	endp

;*******************************
; hedlin : 行頭移動
;
hedlin	proc
	push	ax
	xor	al,al
	mov	curnb,al		; 上位ニブル位置
	mov	curx,al			; 行頭位置
	mov	al,0F0h			; 上位ニブルマスク
	and	byte ptr curptr,al	; 下位ニブルクリア＝行頭へ
	pop	ax
	ret
hedlin	endp

;*******************************
; dsppag : ページ表示
;    チェックサム作成も行う
; in : curpag = カレントページ
; use: ax,bx,,cx,dx,bp,si,di
; call: locate,dsphex,putc
;
dsppag	proc
	assume	ds:data
	mov	di,offset csumb		; チェックサムバッファー
	xor	ax,ax			; ０に初期化する
	mov	cx,PAGWID/2
	rep	stosw
;
	mov	ah,curpag		; カレントページ番号
	xor	al,al
	add	ax,offset buffer
	mov	si,ax			; ページ先頭番地
	mov	bp,filsiz		; ファイルサイズ
	add	bp,offset buffer	; 最終有効データ番地
	mov	dx,0105h		; 第一行座標
dspa2:	mov	di,offset csumb		; 列サムバッファー
	call	locate			; カーソル行頭ロケート
	xor	bl,bl			; 行サム初期化
	mov	cx,PAGWID		; 行内カウンタ初期化
dspa4:	cmp	si,bp			; データの終りを調べる
	jb	dspa5			; 有効データ
	mov	al,SPAC			; 無効データは空白で埋める
	call	putc
	call	putc
	jmp	short dspa6
dspa5:	lodsb				; バイトデータ読み出し
	call	dsphex			; １６進表示
	add	[di],al			; 列サムカウンタ更新
	add	bl,al			; 行サム更新
	inc	di			; 次の列
	mov	al,SPAC			; バイト間の空白
dspa6:	call	putc
	loop	dspa4			; 左のバイトへ
;
	mov	al,':'			; チェックサムの区切り文字表示
	call	putc
	mov	al,bl			; 行チェックサム表示
	call	dsphex
	inc	dh			; Ｙ座標進める
	cmp	dh,PAGLIN
	jbe	dspa2			; 次の行へ
;
	mov	dl,5			; 列サム表示先頭位置
	inc	dh
	call	locate
	mov	si,offset csumb		; 列サムバッファー番地
	mov	cx,PAGWID
	xor	bl,bl
dspa8:	lodsb
	add	bl,al
	call	dsphex
	mov	al,SPAC
	call	putc
	loop	dspa8
	mov	al,':'
	call	putc
	mov	al,bl			; 列サムのサム
	call	dsphex
	ret
dsppag	endp

;********************************
; dspdp : カーソル位置行から
;    ページの最後まで表示する
; use: ax,bx,cx,dx,si,di
; call: putc,dsphex,csum,lsum
;
dspdp	proc
	mov	ah,curpag		; カレントページ番号
	mov	al,cury			; カレント行
	mov	dh,al			; 開始行番号
	shl	al,4
;	add	al,curx
	add	ax,offset buffer
	mov	si,ax			; ページ先頭番地
	mov	di,filsiz		; ファイルサイズ
	add	di,offset buffer	; 最終有効データ番地
	inc	dh			; 表示開始Ｙ座標
	mov	dl,05h			; 表示開始Ｘ座標
dspd2:	call	locate			; カーソル行頭ロケート
	xor	bl,bl			; 行サム初期化
	mov	cx,PAGWID		; 行内カウンタ初期化
dspd4:	cmp	si,di			; データの終りを調べる
	jb	dspd5			; 有効データ
	mov	al,SPAC			; 無効データは空白で埋める
	call	putc
	call	putc
	jmp	short dspd6
dspd5:	lodsb				; バイトデータ読み出し
	call	dsphex			; １６進表示
	add	bl,al			; 行サム更新
	mov	al,SPAC			; バイト間の空白
dspd6:	call	putc
	loop	dspd4			; 左のバイトへ
	mov	al,':'			; チェックサムの区切り文字表示
	call	putc
	mov	al,bl			; 行チェックサム表示
	call	dsphex
	inc	dh			; Ｙ座標進める
	cmp	dh,PAGLIN
	jbe	dspd2			; 次の行へ
;
	mov	al,PAGWID-1		; 右端の列から
dspd8:	call	csum			; 列サム計算表示
	dec	al			; 次の列へ
	jns	dspd8
	mov	al,PAGLIN		; 列サムのサム
	call	lsum
	ret
dspdp	endp

;*******************************
; lsum : 行サム計算＆表示
; in : al = 行番号
; call: locate,dsphex
;
lsum	proc
	push	ax
	push	bx
	push	cx
	push	dx
	push	si
	mov	dh,al		; 表示Ｙ位置
	cmp	al,PAGLIN
	je	lsum2		; 列サムのサム
;
	mov	ah,curpag
	shl	al,4
	add	ax,offset buffer
	mov	si,ax
	jmp	short	lsum4
;
lsum2:	inc	dh		; 表示位置調整
	mov	si,offset csumb
;
lsum4:	mov	bx,filsiz	; ファイルサイズ
	add	bx,offset buffer
	xor	al,al		; サム初期化
	mov	cx,PAGWID	; 行項目数
lsum6:	cmp	si,bx		; 範囲チェック
	jae	lsum8		; 範囲外
	add	al,[si]		; バイトデータ加算
	inc	si
	loop	lsum6
;
lsum8:	mov	dl,PAGWID*3+4+2	; 表示Ｘ位置
	inc	dh
	call	locate
	call	dsphex
	pop	si
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret
lsum	endp

;*******************************
; csum : 列サム計算＆表示
; in : al = 列番号
;
csum	proc
	push	ax
	push	cx
	push	dx
	push	si
	xor	ah,ah
	push	ax
	mov	dl,al
	shl	dl,1
	add	dl,al
	add	dl,5		; 表示Ｘ位置
	mov	dh,PAGLIN+2	; 表示Ｙ位置
;
	mov	ah,curpag
	mov	si,ax		; 第一項目番地
	xor	al,al		; サム初期化
	mov	cx,PAGLIN	; ページ行数
csum2:	cmp	si,filsiz	; ファイルサイズと比較
	jae	csum8		; 範囲外
	add	al,buffer[si]	; バイトデータ加算
	add	si,PAGWID	; 次のラインへ
	loop	csum2
;
csum8:	call	locate
	call	dsphex
	pop	si

	mov	csumb[si],al	; 列サムバッファー更新
	pop	si
	pop	dx
	pop	cx
	pop	ax
	ret
csum	endp

;*******************************
; putstr : 文字列を標準出力へ
;    ^Cでブレークしない
; in : (ds:si) = 出力バッファ番地
;       cx = 書き込むバイト数
;
putstr	proc
	push	ax
	push	cx
	push	dx
	push	si
	mov	ah,06h
putst1:	mov	dl,[si]
	int	21h
	inc	si
	loop	putst1
	pop	si
	pop	dx
	pop	cx
	pop	ax
	ret
putstr	endp

;*******************************
; putc : １文字を標準出力へ
;
; in : al = 文字コード
;
putc	proc
	push	ax
	push	dx
	mov	dl,al
	msdos	F$DirCon
	pop	dx
	pop	ax
	ret
putc	endp

if	FMR
;*******************************
; loacte : カーソルロケート
;   for FMR
; in : dh = Ｙ座標(BASE0)
;      dl = Ｘ座標(BASE0)
;
locate	proc
	push	ax
	push	dx
	add	dx,0101h	; ベース変換
	mov	ah,0Dh		; カーソル位置指定
	int	91h
	pop	dx
	pop	ax
	ret
locate	endp
else
;*******************************
; locate : カーソルロケート
;   for MS-DOS
; in : dh = Ｙ座標(BASE0)
;      dl = Ｘ座標(BASE0)
; call: bndec,putstr
;
locateP	db	C$ESC,"[00;00H"
locateL	equ	$-locateP
;
locate	proc
	push	ax
	push	dx
	push	cx
	push	si
	assume	ds:code
	mov	al,dh
	inc	al
	call	bndec
	xchg	ah,al
	mov	word ptr locateP[2],ax
	mov	al,dl
	inc	al
	call	bndec
	xchg	ah,al
	mov	word ptr locateP[5],ax
;
	mov	si,offset locateP
	mov	cx,locateL
	call	putstr
	assume	ds:data
	pop	si
	pop	cx
	pop	dx
	pop	ax
	ret
locate	endp
endif

;*******************************
; bndec : バイナリを10進数ASCIIへ
;    ただし２桁とする
; in : al = バイナリ
; out: ah = 10進ASCII上位
;      al = 10進ASCII下位
;
bndec	proc
	mov	ah,'0'-1
bndec1:	inc	ah
	sub	al,10
	jae	bndec1
	add	al,10+'0'	; 下位桁
	ret
bndec	endp

;*******************************
; dsphex : １バイト16進数表示
; in : al = バイナリ値
; call: putc
;
dsphex	proc
	push	ax
	push	dx
	mov	dl,al
	shr	al,4
	cmp	al,10
	jb	dshe1
	add	al,'A'-('9'+1)
dshe1:	add	al,'0'
	call	putc		; 上位ニブル表示
;
	and	dl,0Fh
	cmp	dl,10
	jb	dshe2
	add	dl,'A'-('9'+1)
dshe2:	add	dl,'0'
	mov	al,dl
	call	putc		; 下位ニブル表示
	pop	dx
	pop	ax
	ret
dsphex	endp

CODSIZ	equ	$-code_s		; コードサイズ
code	ends

;*******************************
; 作業領域定義用セグメント
;*******************************
data	segment	at 0
data_s	equ	$
	org	06h
memable	label	word		; 使用可能バイト数
	org	80h
cmdln	label	byte		; 引数領域
	org	CODSIZ		; コード領域
	even
bufsiz	dw	?		; 編集バッファーサイズ
filnam	dw	?		; ファイル名ポインタ
filsiz	dw	?		; ファイルサイズ
;
curptr	dw	?		; カレントバッファーオフセット位置
curpag	db	?		; カレントページ番号(BASE0)
curx	db	?		; カレントバイトＸ位置(BASE0)
cury	db	?		; カレントバイトＹ位置(BASE0)
curnb	db	?		; カレントニブル(1=low|0=high)
;
csumb	db	PAGWID dup(?)	; 列チェックサムバッファー
buffer	db	MINBUF dup(?)	; 編集バッファー
MEMSIZ	equ	$-data_s
	db	100h dup(?)	; システムスタック
data	ends

	end	entry
