;------------------------------------------------------------------------------
; PC-G850用 ひらがな表示システム HIRA-PRINT
;------------------------------------------------------------------------------
; バージョン履歴
;
; Ver.2.0 2005/9/17-2005/10/15
;	Ver.2での最大の変更点、変数の検索をつけた。検索ルーチンのパラメータを変更すれば配列のかな変換も可能。
;	変数の名前をプログラムに埋め込まず、定数で宣言することで変更に対するいくらかの柔軟性を作った。
;	LOCATEがらみ、動的割り当て変数のメモリ再解析。
;
; Ver.1.0 1998年
;	PC-E500のひらがなフォントを表示できるように移植。
;	当時の変数はKK$固定で、CLEARをかけた直後にダミー宣言をして、常に変数の位置を固定しないといけなかった。
;	1年ほどしてプログラムを紛失。

;------------------------------------------------------------------------------
; 定数宣言
;------------------------------------------------------------------------------
REGMAX	EQU	7700H		; 動的変数の最終アドレス
REGPTR	EQU	79FCH		; 動的変数の先頭ポインタ
REG1	EQU	'H'		; 検索変数名1文字目 HI$
REG2	EQU	'I'		; 検索変数名2文字目
REGTYP	EQU	0C0H		; 変数タイプ (40H)文字変数 (C0H)配列文字変数

NEXTX	EQU	7920H		; LOCATEや;で指定される文字位置 7920H=X 7921H=Y
NEXTY	EQU	7921H		;   LOCATE指定された場合は、X=(7920H),Y=(7921H)で次の表示が始まる
LASTX	EQU	7922H		; 最後にPRINTで表示された文字位置 7922H=X 7923H=Y
LASTY	EQU	7923H		;   LOCATE指定されなかった場合は、X=0,Y+1で次の表示が始まる
FLAG	EQU	797DH		; 表示コントロールフラグ
CNTNUE	EQU	0		; FLAG-0 LOCATEで位置を指定した時と、PRINTの後に;が付いた時にセットされる。[システムが使用]
KATA	EQU	1		; FLAG-1 ひらがな表示をOFFにした時に立てるフラグ
XMAX	EQU	24		; 表示できる最大桁数
YMAX	EQU	6		; 表示できる最大行数

FONTSZ	EQU	5		; フォントにより5バイト系を6バイト系を選択する。

;------------------------------------------------------------------------------
; メインプログラム
;------------------------------------------------------------------------------
	ORG	90H
START:
	LD HL,(REGPTR)		;変数の先頭アドレスをロード
SEARCH:				;変換対象の変数を検索
	PUSH	HL		;チェック中のアドレスを退避
	LD	DE,REGMAX	; 検索中の変数ポインタが最終を示しているかどうかのチェック
	AND	A		; キャリーフラグを0にする
	SBC	HL,DE		; チェック
	POP	HL		; アドレスを復帰
	RET	Z		;最後までチェックしても変数が見つからなかった場合は、何もせずリターン

	LD	E,(HL)		;メモリ上の変数名をDEレジスタへ読み込む
	INC	HL
	LD	D,(HL)
	INC	HL
	PUSH	HL		;照合のためアドレス退避
	LD	L,REG1		; 照合する名前のロード
	LD	H,REG2+REGTYP	; 変数名の2バイト目は、変数タイプによってオフセットが加わる
	AND	A		; キャリーフラグを0にする
	SBC	HL,DE		; 照合
	POP	HL		; アドレスを復帰
	JR	Z,CONVRT	;一致したなら変換処理へジャンプ

	LD	D,(HL)		;次の変数までのオフセット(2バイト)を読み込む
	INC	HL		;ちなみにこの値はなぜかビッグエンディアンになっている
	LD	E,(HL)
	INC	HL
	ADD	HL,DE		;次の変数に移動
	JR	SEARCH		;検索再開

CONVRT:				;カタカナ→ひらがな変換処理
	INC	HL		;変数要素のサイズは変数名から4バイトの所に記述されている
	INC	HL		;詳細は解析のページを参照
	INC	HL
	INC	HL
	LD	B,(HL)		;変数のサイズ分を処理ループ回数にする(配列の場合は0番が変換対象になる)
	INC	HL

CONVLP:
	PUSH	BC		;ループ回数を退避

	LD	A,(HL)		; 変数の文字をロード
	AND	A		; ループを抜ける前に00Hが来たら、文字列終了とみなして強制終了処理
	JR	Z,NULEND

	LD	A,(HL)		; 変数の文字をロード
	SUB	'~'		; '~'が来たら、エスケープ処理へ
	JR	Z,ESCAPE

	LD	A,(HL)		; 変数の文字をロード
	SUB	0A1H		; 01H〜A0Hまでは変換をかけずに文字を出力
	JR	C,CHAR

	LD	A,(HL)		; 変数の文字をロード
	SUB	0E0H		; E0H〜FFHまでは変換をかけずに文字を出力
	JR	NC,CHAR

	LD	A,(FLAG)	; フラグをロード
	BIT	KATA,A		; カタカナ表示中は変換をかけずに文字を出力
	JR	NZ,CHAR	

GRAPH:				; 文字をグラフィックに置き換えて表示
	LD	A,(HL)		; 変数の文字をロード
TILD_G:				; チルダ表示の強制ジャンプ位置。文字コードはA0Hになっている
	PUSH	HL		; HLレジスタはフォントアドレスを保持するため変数アドレスを退避
	LD	HL,FONT-FONTSZ	;  フォントアドレスをロード
	LD	DE,FONTSZ	;  フォントのサイズを読み込む
	SUB	9FH		;  9FHを引いてオフセットとする(A0Hの場合は'~'を表示)
	LD	B,A		;  掛け算用のDJNZカウンタに代入
MULTI:
	ADD	HL,DE		;  フォントデータの位置を計算する
	DJNZ	MULTI

	PUSH	AF		;  変数が壊れないように退避
	PUSH	HL		;   変数が壊れないように退避
	CALL	LOADXY		;    表示位置をロード→DEレジスタ
	CALL	C,0BFEBH	;    スクロールフラグ(C)があったらスクロール
	POP	HL		;    変数の復活
	POP	AF		;   変数の復活

	LD	B,FONTSZ	;  表示バイト数をフォントに合わせてロード
	PUSH	DE		;  表示位置をセーブするため、保持しておく
	CALL	0BFD0H		;   ビットマップ表示をコール
	POP	DE		;   表示位置を復活
	POP	HL		;  変数のアドレスを復元
	JR	CONV2		; 表示位置の保存へ

ESCAPE:				; '~'のエスケープ処理
	POP	BC		;現在変数の最終バイトかをチェック
	DEC	B
	PUSH	BC
	JR	Z,CNTEND	; 最終バイトの時は、強制ループエンド処理

	INC	HL		; 次のバイトに00Hがあるかをチェック
	LD	A,(HL)		; 変数の文字をロード
	AND	A
	JR	Z,CNTEND	; 00Hがあった場合は変数の最後に'~'があるので、強制ループエンド処理

	LD	A,(HL)		; 次のバイトに'ｰ'があるかをチェック(強制ひらがなチルダ処理)
	SUB	0B0H		; '~~~'と指定するとチルダが出力された後に変換ON/OFFが働いてしまうため、
	LD	A,0A0H		; チルダを先出しする時には'~ｰ'と指定する。
	JR	Z,TILD_G	; カタカナの後にひらがなのチルダを使うときに使用する。

	LD	A,(HL)		; 変数の文字をロード
	SUB	'~'		; 次のバイトに'~'があるかをチェック
	JR	NZ,TOGGLE	; '~'が無かった場合は変換ON/OFFなので、カタカナ→ひらがなフラグ処理へ
TILDE:				; '~'があった場合は、ひらがな表示の状態によって、チルダの表示コードを変えてジャンプする
	LD	A,(FLAG)
	BIT	KATA,A
	JR	NZ,CHAR		; カタカナ表示中は、コードは'~'のままで文字表示
	LD	A,0A0H
	JR	TILD_G		; ひらがな表示中は、コードをA0Hに変えてグラフィック表示

CHAR:				; 変換せずに文字を出力する
	CALL	LOADXY		; 表示位置をロード→DEレジスタ
	LD	A,(HL)		; 変数の文字をロード
	PUSH	DE		; 表示位置をセーブするため、保持しておく
	PUSH	HL		;  変数アドレスの退避
	PUSH	AF		;   文字コードの退避
	CALL	C,0BFEBH	;    スクロールフラグ(C)があったらスクロール
	POP	AF		;    文字コード復活
	CALL	0BE62H		;   ビットマップ表示をコール
	POP	HL		;   変数アドレスの復活
	POP	DE		;  表示位置を復活
CONV2:
	LD	A,(FLAG)	;変換中はコンティニューフラグをONにして横向きに表示を進める
	SET	CNTNUE,A
	LD	(FLAG),A
	CALL	SAVEXY		; 表示位置を保存する
LOOPEN:				; ループの共通処理
	POP	BC		;ループカウンタを復帰
	INC	HL		;変数アドレスをインクリメント
	DEC	B		;ループをカウントする
	JR	NZ,CONVLP
	SUB	A		;CNTNUEフラグとカタカナフラグをOFFにして終了
	LD	(FLAG),A
	RET

NULEND:				; ループ中に00Hが来た時の処理
	POP	BC		; ループカウンタを強制的に最終にする
	LD	B,1
	PUSH	BC
	JR	LOOPEN		; ループカウンタの処理へ

CNTEND:				; 強制ループエンド処理
	POP	BC		; ループ用カウンタを強制復帰
	LD	A,(FLAG)	;次の呼び出しのために、カタカナフラグをOFFにしておく
	RES	KATA,A
	LD	(FLAG),A
	RET			;コンティニューフラグを解除せずに強制終了

TOGGLE:				; 変換ON/OFF切り替え
	DEC	HL		; 次のバイトがチルダで無かった場合は、変数のアドレスを元に戻す
	POP	BC		;ループカウンタもデクリメントしてしまっているので、元に戻す
	INC	B
	PUSH	BC
	LD	A,(FLAG)	; ひらがな表示のフラグを反転させる
	BIT	KATA,A
	JR	NZ,HIRAON
	SET	KATA,A		; 0 の場合はカタカナ表示へ
	LD	(FLAG),A
	JR	LOOPEN		; 切り替えが終わったら終了場所へ
HIRAON:
	RES	KATA,A		; 1 の場合はひらがな表示へ
	LD	(FLAG),A
	JR	LOOPEN		; 切り替えが終わったら終了場所へ

;------------------------------------------------------------------------------
; 表示位置計算ルーチン
;------------------------------------------------------------------------------
LOADXY:				; ワークエリアから次に表示する位置を取得する(D=行,E=桁)
	AND	A		; キャリーフラグをスクロールフラグとして使う
	LD	A,(FLAG)
	BIT	CNTNUE,A	; コンティニューフラグを調べる
	JR	Z,LOAD0		; コンティニューしていない場合は分岐
LOAD1:				; コンティニュー中の処理(文字列処理中は常にコンティニューするので分岐しないようにしておく)
	LD	DE,(NEXTX)	; コンティニュー中は次の表示位置が計算されているので、ロードするだけでOK
LOAD01:				; 表示行のオーバーチェック共通部分
	LD	A,YMAX-1
	PUSH	DE		;  Dレジスタをチェックするので、一時退避
	SUB	D		;  A=YMAX-1-D (オーバーしていた時はCフラグが立つ)
	POP	DE		; Dレジスタ復帰
	RET	NC		; オーバーしていないので、そのままリターン
	LD	D,YMAX-1	; 最終行に固定
	RET			; ロード終了
LOAD0:				; コンティニューしない場合の処理
	LD	DE,(LASTX)	; 最終表示行をロード
	LD	E,0		; 改行になるので、Xを0に固定しておく
	INC	D		; Dレジスタが255の時はCLSの直後なので、
	RET	Z		; ロールオーバーで0になってリターンする
	JR	LOAD01		; 共通処理へ

SAVEXY:				; ワークエリアに表示位置を保存する(D=行,E=桁)
	LD	(LASTX),DE	; DEレジスタを現在表示位置として保存する
	LD	A,(FLAG)	; コンティニューフラグをチェックする
	BIT	CNTNUE,A
	JR	Z,SAVE0		; コンティニューしないならば、NEXTX,NEXTYも同じ値で保存する
	INC	E		; X座標を進める
	LD	A,XMAX-1	; 最大桁チェック
	PUSH	DE		;  Eレジスタをチェックするので、一時退避
	SUB	E		;  A=XMAX-1-E (オーバーしていた時はCフラグが立つ)
	POP	DE		; Eレジスタ復帰
	JR	NC,SAVE0	; オーバーしていないならば、そのまま保存
	LD	E,0		; オーバーしたら0桁目に戻し、
	INC	D		; 行数を+1して保存
SAVE0:
	LD	(NEXTX),DE	; コンティニュー用の計算された値を保存
	RET
;------------------------------------------------------------------------------
; フォントテーブル
;------------------------------------------------------------------------------
FONT:
	DB	08H,04H,08H,10H,08H	;~
	DB	70H,50H,70H,00H,00H	;｡
	DB	00H,00H,0FH,01H,01H	;｢
	DB	00H,00H,40H,40H,78H	;｣
	DB	00H,20H,40H,00H,00H	;､
	DB	00H,00H,18H,18H,00H	;･
	DB	22H,56H,5BH,6AH,48H	;ｦ
	DB	68H,58H,7CH,28H,50H	;ｧ
	DB	38H,40H,20H,08H,30H	;ｨ
	DB	14H,4CH,4CH,28H,10H	;ｩ
	DB	48H,2CH,1CH,7CH,48H	;ｪ
	DB	28H,7CH,18H,54H,28H	;ｫ
	DB	14H,18H,28H,4CH,10H	;ｬ
	DB	1CH,48H,3CH,28H,10H	;ｭ
	DB	20H,50H,7CH,28H,48H	;ｮ
	DB	10H,10H,08H,48H,30H	;ｯ
	DB	04H,08H,08H,08H,08H	;ｰ
	DB	30H,4AH,3FH,1AH,74H	;ｱ
	DB	3EH,40H,20H,02H,3CH	;ｲ
	DB	08H,45H,45H,26H,18H	;ｳ
	DB	44H,25H,15H,6EH,44H	;ｴ
	DB	32H,7FH,0AH,49H,32H	;ｵ
	DB	64H,1FH,44H,3AH,0CH	;ｶ
	DB	22H,4BH,4EH,5AH,08H	;ｷ
	DB	08H,14H,14H,22H,41H	;ｸ
	DB	3FH,00H,42H,3FH,02H	;ｹ
	DB	20H,51H,41H,45H,42H	;ｺ
	DB	24H,45H,46H,4AH,02H	;ｻ
	DB	00H,3FH,40H,40H,20H	;ｼ
	DB	02H,5AH,56H,3FH,02H	;ｽ
	DB	04H,3FH,44H,5FH,44H	;ｾ
	DB	08H,0DH,3BH,49H,08H	;ｿ
	DB	72H,0FH,22H,44H,44H	;ﾀ
	DB	02H,1FH,4AH,4AH,30H	;ﾁ
	DB	04H,04H,22H,22H,1CH	;ﾂ
	DB	02H,02H,1DH,23H,41H	;ﾃ
	DB	30H,4FH,48H,44H,44H	;ﾄ
	DB	0AH,27H,52H,3DH,22H	;ﾅ
	DB	7FH,00H,22H,42H,42H	;ﾆ
	DB	38H,4EH,34H,6FH,78H	;ﾇ
	DB	34H,7FH,04H,62H,7CH	;ﾈ
	DB	3EH,21H,1FH,41H,3EH	;ﾉ
	DB	7FH,20H,52H,3FH,22H	;ﾊ
	DB	3DH,43H,40H,3FH,02H	;ﾋ
	DB	30H,45H,7BH,02H,70H	;ﾌ
	DB	08H,04H,08H,10H,20H	;ﾍ
	DB	7FH,20H,55H,3FH,25H	;ﾎ
	DB	6AH,6AH,7FH,2AH,4AH	;ﾏ
	DB	30H,3DH,4BH,3CH,10H	;ﾐ
	DB	32H,7FH,42H,41H,22H	;ﾑ
	DB	38H,4EH,34H,0FH,78H	;ﾒ
	DB	0AH,3EH,4BH,4AH,20H	;ﾓ
	DB	05H,0EH,32H,4BH,0CH	;ﾔ
	DB	1EH,44H,3FH,22H,1CH	;ﾕ
	DB	20H,50H,3FH,12H,22H	;ﾖ
	DB	1CH,51H,49H,4AH,30H	;ﾗ
	DB	0EH,00H,40H,21H,1EH	;ﾘ
	DB	10H,69H,6DH,4BH,30H	;ﾙ
	DB	34H,7FH,08H,04H,7EH	;ﾚ
	DB	10H,49H,4DH,4BH,30H	;ﾛ
	DB	34H,7FH,04H,42H,3CH	;ﾜ
	DB	60H,1CH,33H,40H,20H	;ﾝ
	DB	02H,04H,02H,04H,00H	;ﾞ
	DB	07H,05H,07H,00H,00H	;ﾟ
	END
