;SHNECH.ASM(常駐部)1990.12.15
comment	+

	ShNEch(SHow NEC98 CHaracters しねっち)(C)1992．Boko

	NEC98 特殊文字を TOWNSで表示するツール

	SHNECH(常駐部)

	int 91h(文字ディスプレイBIOS)をフックして
	Function 1dh(文字の出力)および 1eh(文字列の
	出力）で文字出力される場合に出力するコード
	がOASYS特殊文字であればそれをすり替えて表示
	する

  90/12/27 V0.5 メール配付版
  91/01/14 V0.6 DL公開版 /R /S オプションを追加
　91/04/12 V0.7 バグ修正(PSE/FMR R4.60との併用で暴走する)
　92/01/31      for FREESOFTWARE Collection 5(Towns 用の部分追加)
+
INCLUDE		SHNECH.H

EXTRN		CHAR_TABLE:	WORD
EXTRN		INITIALIZE:	NEAR

PUBLIC		MACHINE_NAME
PUBLIC		ENV_SEGMENT
PUBLIC		PARAM_LENGTH
PUBLIC		PARAM_LINE
PUBLIC		WORK
PUBLIC		WORKSIZE
PUBLIC		INT_91_VECT
PUBLIC		INT_91_SEG
PUBLIC		INT_91_OFF
PUBLIC		SHOACH_ENT
PUBLIC		STAY_MAIN

CODE	SEGMENT	WORD PUBLIC 'SHOACHCOM'
		ASSUME	CS:CODE
		ASSUME	DS:CODE
		ASSUME	ES:CODE

;		PSP の定義
;		~~~~~~~~~~
		ORG	0
		DW	?
;MAX_SEGMENT:
		DW	?
		ORG	02CH
ENV_SEGMENT	DW	?
		ORG	080H
PARAM_LENGTH	DB	?
PARAM_LINE	DB	07FH DUP(?)

;		WORK の定義(PSP内にとる)
;		~~~~~~~~~~~~~~~~~~~~~~~~
		ORG	05AH
STRING_LENGTH	DW	?
MACHINE_NAME	DB	30 DUP(?)	;機種名
WORK		LABEL	BYTE
INT_91_VECT	LABEL	DWORD		;元の91ベクトルを保存
INT_91_OFF	DW	?
INT_91_SEG	DW	?

ZENKAKU_1ST	DB	?		;変換対象の全角コードの1バイト目
LAST_CHR	DB	?		;最後に出力した文字(ESC?)
BUFF		DB	080H DUP(?)	;変換用作業領域

END_OF_WORK	LABEL	BYTE

WORKSIZE	EQU	END_OF_WORK - WORK

;		プログラムの開始
;		~~~~~~~~~~~~~~
SHOACH_ENT:	CLD
		JMP	INITIALIZE

;		常駐部メイン(INT 91H ENTRY)
;		~~~~~~~~~~~~~~~~~~~~~~~~~~~
STAY_MAIN	PROC	FAR
		CMP	AH,01DH		;FUNCTION:1DH 一文字の出力
		JE	CONV_MAIN_1D
		CMP	AH,01EH
		JE	CONV_MAIN_1E
		JMP	CS:INT_91_VECT	;それ以外の処理はパス
STAY_MAIN	ENDP

;		変換部
;		~~~~~~
CONV_MAIN_1D	PROC
		STI
		PUSH	DS
		PUSH	AX

		PUSH	CS
		POP	DS

		MOV	AH,ZENKAKU_1ST
		MOV	ZENKAKU_1ST,0	;全角フラグクリア
		OR	AH,AH
		JE	CHECK_ZEN_1ST

		CALL	CONV_OAS

;		文字の出力
ZEN_CHAR_DISP:

if	SHOACH
	;	shoach のみの処理
	;	もとの2バイト文字を
	;	エスケープ+1バイト+空白
	;	の3バイトに変換して出力

		CMP	AH,01BH
		JNE	PUTAX
		XCHG	AH,AL
		PUSH	AX
@@:
		MOV	AH,01DH
		PUSHF
		CLI
		CALL	INT_91_VECT
		POP	AX
		MOV	AL,020H
endif

PUTAX:
		PUSH	AX
		MOV	AL,AH
		MOV	AH,01DH
		PUSHF
		CLI
		CALL	INT_91_VECT
		POP	AX
		MOV	AH,01DH
		POP	DS		;ダミーポップ
		JMP SHORT NOT_CONV

;		変換対象の全角１バイト目のチェック
CHECK_ZEN_1ST:
		POP	AX
		CMP	AL,081H
		JB	NOT_CONV
		CMP	AL,0A0H
		JB	ZEN_SAVE
		CMP	AL,0E0H
		JB	NOT_CONV
		CMP	AL,0FCH
		JB	ZEN_SAVE
NOT_CONV:
		MOV	CS:LAST_CHR,AL
		POP	DS
		CLI
		JMP	CS:INT_91_VECT
ZEN_SAVE:
		CMP	LAST_CHR,01BH		;ｴｽｹｰﾌﾟの次の文字は全角ではない
		JE	NOT_CONV
		MOV	ZENKAKU_1ST,AL
		POP	DS
		IRET
CONV_MAIN_1D	ENDP

CONV_MAIN_1E	PROC
		STI
		PUSH	ES
		PUSH	CS
		POP	ES
		PUSH	AX
		PUSH	BX
		PUSH	DX
		PUSH	SI
		MOV	SI,DI
		MOV	CS:STRING_LENGTH,CX
		OR	CX,CX
		JNE	LOOP1
LOOPEND:
		POP	SI
		POP	DX
		POP	BX
		POP	AX
		POP	ES
		CLI
		IRET
CONV_MAIN_1E	ENDP

LOOP1		PROC
		;バッファクリア
		XOR	CX,CX
		MOV	DI,offset PARAM_LENGTH
LOOP2:
		;1文字(1BYTE)
		LODSB

		MOV	AH,CS:ZENKAKU_1ST
		MOV	CS:ZENKAKU_1ST,0	;全角フラグクリア
		OR	AH,AH
		JE	CHECK_ZEN_1ST2

		CALL	CONV_OAS

;		文字の出力

if	SHOACH
	;	shoach のみの処理
	;	もとの2バイト文字を
	;	エスケープ+1バイト+空白
	;	の3バイトに変換して保存

		CMP	AH,01BH
		JNE	STOSAX
		XCHG	AH,AL
;		PUSH	AX			;削除 V0.7(V0.6は暴走する)
@@:
		STOSB
		INC	CX
		MOV	AL,020H
endif

STOSAX:
		MOV	CS:LAST_CHR,AL
		XCHG	AH,AL
		STOSW
		INC	CX
		INC	CX
		JMP SHORT BUF_CHK

;		変換対象の全角１バイト目のチェック
CHECK_ZEN_1ST2:
		CMP	AL,081H
		JB	NOT_CONV2
		CMP	AL,0A0H
		JB	ZEN_SAVE2
		CMP	AL,0E0H
		JB	NOT_CONV2
		CMP	AL,0FCH
		JB	ZEN_SAVE2
NOT_CONV2:
		MOV	CS:LAST_CHR,AL
		STOSB
		INC	CX
		JMP SHORT BUF_CHK
ZEN_SAVE2:
		CMP	CS:LAST_CHR,01BH		;ｴｽｹｰﾌﾟの次の文字は全角ではない
		JE	NOT_CONV2
		MOV	CS:ZENKAKU_1ST,AL
BUF_CHK:
		DEC	CS:STRING_LENGTH
		JE	FLASH_BUF
		CMP	CX,120
		JB	LOOP2
FLASH_BUF:
		PUSH	DS
		MOV	AX,CS
		MOV	DS,AX
		MOV	AH,01EH
		MOV	DI,offset PARAM_LENGTH
		PUSHF
		CLI
		CALL	INT_91_VECT
		POP	DS
		CMP	CS:STRING_LENGTH,0
		JE	LOOPEND
		JMP	LOOP1
LOOP1		ENDP

CONV_OAS	PROC
;		変換対象のチェック
		CMP	AL,040H			;追加 V0.7
		JB	@F			;追加 V0.7
if	SHOACH
	;	しょあっち（８区〜１５区）
	;	だけを変換
		CMP	AX,0849FH
		JB	@F
		CMP	AX,0889FH
		JAE	@F
endif
if	SHOJIS
	;	しょうじす（８区の３２字）
	;	だけを変換
		CMP	AX,0849FH
		JB	@F
		CMP	AX,084BFH
		JAE	@F
endif
if	SHONEC
	;	しょうえぬいーしー（８区〜１３区）
	;	だけを変換
		CMP	AX,0849FH
		JB	@F
		CMP	AX,0879FH
		JAE	@F
endif
if	SHNECH
	;	しねっち（８区〜１３区）
	;	だけを変換
		CMP	AX,0849FH
		JB	@F
		CMP	AX,0879FH
		JAE	@F
endif

;		表による変換
		PUSH	BX
		MOV	BX,189			;BH = 0, BL = 189
		SUB	AX,08440H		;AH = 0 〜 4, AL = 0 〜 188
		XCHG	BX,AX			;AL = 0, BL = 0 〜 188
		MUL	BH			;AX = 190 * 0 〜 4
		XOR	BH,BH			;BX = 0 〜 190
		ADD	BX,AX
		SHL	BX,1
		MOV	AX,CS:[BX+offset CHAR_TABLE-190]
		POP	BX
@@:
		RET
CONV_OAS	ENDP
CODE		ENDS
		END	SHOACH_ENT
