;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
	title	XGA DBCS PM Driver
	subttl	Misc. functions for DBCS/MBCS support
	page	106,132
;***********************************************************************
;    Module	      : EDDJASUB.ASM
;
;    Description      : PM Display Driver DBCS handling routine
;			Misc. functions for DBCS/MBCS support
;
;    Created	      : 08/20/92
;    Author	      : Yohji Nakamura (JL04328 at YMTVM6)
;
;    Notes	      :
;	      - All functions included here were originally written in
;		C, then converted to ASM for performance.
;		So function declarations are still in misc .H files, and
;		you can look .C files for more readable source.
;
;    History	      :
;
;			OCO Source Materials
;			XXXX-XXX
;***********************************************************************
	.386p			       ; 
	.xlist
INCL_GPIBITMAPS = 1		       ; needed for xgaadapt.inc
INCL_FONTFILEFORMAT = 1 	       ; for FONTMETRICS
include os2.inc
include eddinclt.inc
include eddhtype.inc		       ; for def of FONTDETAILS
include eddjdef.inc		       ; for flags of FONTDETAILS
include eddhavio.inc		       ; for def of FONTCACHEINFO

?DF	equ	1	; we do not want _TEXT segment defined by cmacros.
include cmacros.inc

.list									;YOJN
;======================================================================
; constant			must be identical to C definitions!
;======================================================================
FLAG_NOT_IN_CACHE	equ	0ffff8000h
ERROR_CACHE_FULL	equ	0ffffffffh
				       ; value returned by LocateInCache
CACHE_RESERVED		equ	0ffffffffh
				       ; value set in cache offset
;======================================================================
; segment defs
;======================================================================
_DATA		segment use32 dword public 'DATA'
_DATA		ends

_TEXT		segment use32 dword public 'CODE'
		assume	cs:FLAT, ds:FLAT, es:FLAT

;====================== Exported Routine ===============================
;	eddj_IsSbcsOnly 		(Moved from EDDJSUB.C)
;
;  Set/Reset NLSCA_SBC_ONLY bit in NLSParseFlag by inspecting given
;	string
;
;  Usage      :
;		VOID _cdecl eddj_IsSbcsOnly( PCHAR pchString,
;					     LONG lCount,
;					     PFONTDETAILS pFontDtl );
;
;
;  Entry      :
;	      - Ptr to string
;	      - Number of bytes in the string
;	      - Ptr to FONTDETAILS structure
;		(Parsing flag and DBCS vector map are used.)
;
;  Returns    :
;	      - None.  NLSCA_SBC_ONLY bit in NLSParseFlag in given
;		FONTDETAILS struct is changed.
;
;  Error Returns :	None
;
;  Note       :
;	      - When searching DBCS leading byte, we will not check
;		the last byte in string, since:
;			if it is not DBCS leading, should be SBCS
;			if it is DBCS leading and NLSCA_CONCAT is on,
;			  it should be left unprocessed
;			if it is DBCS leading and NLSCA_CONCAT is off,
;			  it should be considered as SBCS default.
;
;	      - We do not check font type here.  Will check it later
;		when deciding NLSCA_CALL_DBCSFM value.	(Should not
;		use font type to decide NLSCA_UNIFIED_DBCS value)
;
;	      - Assumes Direction Flag is 0 on entry
;
;=======================================================================
cProc	eddj_IsSbcsOnly, <PUBLIC>, <esi,ebx>
				       ; will not use EDI...
	parmD	pchString
	parmD	lCount		       ; 
	parmD	pFontDtl	       ; 
				       ; 
cBegin				       ; 
	;--------------------------------------------------------------
	; SBCS/DBCS case... it's simple!
	;--------------------------------------------------------------
	mov	ebx, pFontDtl	       ; EBX = ptr to font details
	or	[ebx].NLSParseFlag, NLSCA_SBC_ONLY
				       ; assume YES for now
	test	[ebx].NLSParseFlag, NLSCA_SBCS
	jnz	short iso_exit	       ; if SBCS CP, of course YES

	test	[ebx].NLSParseFlag, NLSCA_DBCS
	jnz	short iso_reset_flag   ; if DBCS CP, only double bytes

	;--------------------------------------------------------------
	; MBCS case: need to check string
	;--------------------------------------------------------------
	mov	ecx, lCount
	dec	ecx		       ; need not check last byte
	jle	short iso_exit	       ; if 0 or 1 byte, it is SBC

	mov	esi, pchString
	mov	edx, [ebx].pDBCSMap
	xor	eax, eax	       ; clear upper 3 bytes of EAX

iso_next_char:
	lods	byte ptr [esi]	       ; get 1 byte from string
	cmp	byte ptr [edx+eax], 0  ; check if it is leading byte
	jnz	short iso_reset_flag   ; if YES, not only SBC

	loop	iso_next_char	       ; 
	jmp	short iso_exit	       ; no DBC found.

iso_reset_flag:
	and	[ebx].NLSParseFlag, not NLSCA_SBC_ONLY

iso_exit:
cEnd

;====================== Exported Routine ===============================
;	eddj_LocateInCache		(Moved from EDDJCACH.C)
;
;  Check if given codepoint is already in cache, and returns cache
;  index if found.
;
;  Usage      :
;
;		LONG eddj_LocateInCache( PFONTCACHEINFO pFCInfo,
;					 USHORT usCodepoint );
;
;  Entry      :
;	      - ptr to current font's FONTCACHEINFO structure
;	      - codepoint to be checked
;		(if SBCS codepoint, it should be expanded to USHORT
;		 before calling this routine)
;
;  Returns    :
;		Returns index to font cache if found
;		Returns cache index, with MSB set, when the codepoint
;			is not in cache, but could reserve new entry
;		Returns ERROR_CACHE_FULL   (0xFFFFFFFF) if not found
;			in cache, and could not reserve an entry as
;			DBCS index table was already full
;
;  Error Returns :	None
;
;  Note       :
;	      - 1 additional function of this routine is to 'reserve'
;		cache entry for given codepoint.  By this function,
;		later call to this function with same codepoint should
;		return 'Yes, Exist', hence should avoid retrieving
;		1 char's image many times from DBCS FM.  Assumes
;		caller surely put char, for which this routine
;		returns 'Not exist', into cache.
;
;	      - Assumes DF in FLAGS is already 0.  (Increasing order)
;
;	      - Register Usage:
;			EBX : ptr to FONTCACHEINFO
;			AX  : given codepoint
;
;
;=======================================================================
cProc	eddj_LocateInCache, <PUBLIC>, <edi,ebx>
	parmD	pFCInfo 	       ; ptr to font cache info
	parmW	usCodePoint	       ; C seems to put is as ULONG
	parmW	usDummy 	       ;  so this is just for safety...
				       ; 
cBegin				       ; 
	mov	ebx, pFCInfo	       ; 
	xor	eax, eax	       ; clear upper 2 bytes
	mov	ax, usCodePoint        ; 
	test	ax, 0ff00h	       ; if single byte char,
	jnz	short lic_2byte        ; 

	;--------------------------------------------------------------
	; 1 byte char given...
	;--------------------------------------------------------------
.errnz	type fci_aulCachedCharOffset - 4
	cmp	[ebx].fci_aulCachedCharOffset[eax*4], 0
	jnz	short lic_exit	       ; if already in cache, return
				       ;   with codepoint value

lic_reserve_cache:		       ; 
	mov	[ebx].fci_aulCachedCharOffset[eax*4], CACHE_RESERVED
	or	eax, FLAG_NOT_IN_CACHE ; tell not in cache yet
	jmp	short lic_exit	       ; 

	;--------------------------------------------------------------
	; 2 bytes char
	;--------------------------------------------------------------
lic_2byte:			       ; 
	movzx	ecx, [ebx].fci_usDBGITableNext
				       ; get # of valid entries
	mov	edx, ecx	       ; save it for later use
	lea	edi, [ebx].fci_ausDBGIndexTable
				       ; ptr to top of index table
	repne scasw		       ; search for given codepoint
	je	short lic_found
				       ; 
lic_not_found:			       ; 
	cmp	edx, MAX_NUM_DBCODEPOINTS
	jge	short lic_flush
				       ; 
	inc	[ebx].fci_usDBGITableNext

.errnz	type fci_ausDBGIndexTable - 2
	mov	[ebx].fci_ausDBGIndexTable[edx*2], ax
				       ; put given codepoint to table
.errnz	type fci_aulCachedCharOffset - 4
	mov	[ebx].fci_aulCachedCharOffset[edx*4+MAX_NUM_CODEPOINTS*4], \
		CACHE_RESERVED	       ; reserve this entry
	or	edx, FLAG_NOT_IN_CACHE ; 
	jmp	short lic_found_dbc    ; now EDX holds cache index

lic_flush:			       ; 
	mov	eax, ERROR_CACHE_FULL  ; 
	jmp	short lic_exit	       ; 
				       ; 
lic_found:			       ; 
	sub	edx, ecx	       ; EDX: total count, ECX: remaining
	dec	edx		       ; since ECX already decremented
				       ; 
lic_found_dbc:			       ; 
	mov	eax, edx	       ; is index for DBCS only
	add	eax, MAX_NUM_CODEPOINTS; SBCS/DBCS converged cache index

lic_exit:			       ; 
cEnd

_TEXT	ends
	end
