Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

Obsah / Utility / LANG / Inicializace národnostních popisovačů

Zdrojový kód: INCLUDE\UTIL\LANG.INC, UTIL\LANG.ASM


Inicializace národnostních popisovačů

Funkce NationInit je volána během startu systému a slouží k inicializace tabulek národnostních informací. Funkce vytváří hashovací tabulky pro abecední třídění znaků.


; ------------- Go through all nationality descriptors

NationInit:	mov	ebp,NatTab	; EBP <- nationality descriptors

; ------------- Find similar alphabetic tables

NationInit2:	mov	edx,ebp		; EDX <- current nationality descriptor
		lea	ebx,[edx+NAT_Alphabet] ; EBX <- alphabetic order table
NationInit3:	sub	edx,NATIONAL_size ; EDX <- previous descriptor
		cmp	edx,NatTab	; check if table is valid
		jb	NationInit4	; table is not valid
		
; ------------- Compare alphabetic order table

		lea	eax,[edx+NAT_Alphabet] ; EAX <- alphabetic order table
		call	TextEqu		; compare strings
		jc	NationInit3	; tables are not equal

; ------------- Use previous hash table

		mov	eax,[edx+NAT_AlphaHash] ; EAX <- previous hash table
		mov	[ebp+NAT_AlphaHash],eax ; use previous hash table
		jmp	NationInit9

Na začátku funkce NationInit je nejdříve nastaven registr EBP na první položku seznamu jazyků NatTab. Pro zvýšení úspory paměti jsou hashovací tabulky nejdříve prohledány, zda již neobsahují stejnou třídicí tabulku. Pokud ano, použije se již existující tabulka.


; ------------- Prepare next hash table (-> EDI)

NationInit4:	mov	edi,[AlphaHashTabNxt] ; EDI <- next hash table
		mov	eax,AlphaHashNone ; EAX <- pointer to invalid table
		mov	[ebp+NAT_AlphaHash],edi ; set hash table
		mov	ecx,NAT_MAXAHASH ; ECX <- number of sub-pages
		push	edi		; push EDI
		rep	stosd		; clear hash table
		mov	[AlphaHashTabNxt],edi ; shift pointer
		pop	edi		; pop EDI

Jedná-li se o novou třídicí tabulku, je alokována nová podstránka hashovací tabulky (velikost podstránky NAT_MAXAHASH*4) a inicializována ukazateli na tabulku neplatných znaků AlphaHashNone (pro úsporu paměti je tabulka sdílena s nulovou stránkou PageEmpty).


; ------------- Prepare registers to generate hash table

		xor	edx,edx		; EDX <- position pointer
		mov	cl,7fh		; CL <- order index - 1

; ------------- Read one character from table (-> EAX)

NationInit5:	inc	ecx		; increase order index
		lea	ebx,[ebp+NAT_Alphabet] ; EBX <- alphabetic order table
		call	TextGetChar	; read one character -> EAX
		jc	NationInit9	; no next character

Obsah registru EDX je vynulován, registr EDX bude sloužit jako ukazatel pozice v textu třídicí tabulky znaků. Registr CL obsahuje třídicí kód znaku, kód bude mít hodnotu 80h a více.

Na začátku cyklu pro generování hashovací třídicí tabulky se nejdříve inkrementuje třídicí kód znaku. Do registru EBX se připraví ukazatel na textovou proměnnou obsahující text třídicí tabulky znaků a pomocí funkce TextGetChar se z tabulky z pozice EDX načte další znak. Znak bude v kódu Unicode a bude uložen do registru EAX.


; ------------- Prepare index of hash sub-page (-> EBX)

		push	eax		; push EAX
		movzx	ebx,ah		; EBX <- hash sub-page

; ------------- Check if hash sub-page is valid

		cmp	dword [edi+ebx*4],AlphaHashNone ; is sub-page valid?
		jne	NationInit6	; sub-page is valid

; ------------- Allocate hash sub-page
		
		push	eax		; push EAX
		mov	eax,[AlphaHashTabNxt] ; EAX <- next hash table
		mov	[edi+ebx*4],eax	; set hash sub-page
		add	eax,256		; shift to next table
		mov	[AlphaHashTabNxt],eax ; store new pointer
		pop	eax		; pop EAX

Unicode kód znaku je uschován do zásobníku a do registru EBX je připraven vyšší bajt znaku. Kontrolou ukazatele na podstránku je zjištěno, zda je podstránka již alokována. Není-li alokována (tj. ukazatel ukazuje na AlphaHashNone), alokuje se nová 256-bajtová podstránka.


; ------------- Get hash sub-page (-> EBX)

NationInit6:	mov	ebx,[edi+ebx*4]	; EBX <- hash sub-page

; ------------- Store order index of character

		movzx	eax,al		; EAX <- character LOW
		mov	[ebx+eax],cl	; store order index
		pop	eax		; pop EAX

Nyní je podstránka liž alokovaná. Ze seznamu podstránek je do registru EBX načten ukazatel na podstránku. Do registru EAX je připraven nižší bajt Unicode kódu znaku, jeho hodnota bude použita jako index v podstránce. Na příslušnou pozici bude z registru CL uložen třídicí kód znaku a Unicode köd znaku je navrácen ze zásobníku do registru EAX.


; ------------- Prepare change small/capital

		call	UniCharToSmaCap	; convert to small/capital

; ------------- Prepare index of hash sub-page (-> EBX)

		movzx	ebx,ah		; EBX <- hash sub-page

; ------------- Check if hash sub-page is valid

		cmp	dword [edi+ebx*4],AlphaHashNone ; is sub-page valid?
		jne	NationInit7	; sub-page is valid

; ------------- Allocate hash sub-page
		
		push	eax		; push EAX
		mov	eax,[AlphaHashTabNxt] ; EAX <- next hash table
		mov	[edi+ebx*4],eax	; set hash sub-page
		add	eax,256		; shift to next table
		mov	[AlphaHashTabNxt],eax ; store new pointer
		pop	eax		; pop EAX

; ------------- Get hash sub-page (-> EBX)

NationInit7:	mov	ebx,[edi+ebx*4]	; EBX <- hash sub-page

; ------------- Store order index of character

		movzx	eax,al		; EAX <- character LOW
		mov	[ebx+eax],cl	; store order index
		jmp	short NationInit5 ; next character

Předešlé operace byly provedeny pouze pro jednu velikost znaku (velká písmena). Stejně operace je potřeba provést i pro písmeno opačné. Znak se pomocí funkce UniCharToSmaCap zkonvertuje na opačné písmeno (malé písmeno). Testem ukazatele je ověřeno, zda je daná podstránka již alokovaná. Pokud ne, provede se alokace další 256-bajtové podstránky. Nakonec je uložen třídicí kód znaku i pro toto opačné písmeno a přejde se k obsluze dalšího znaku třídicí tabulky.


; ------------- Next nationality descriptor

NationInit9:	add	ebp,NATIONAL_size ; next nationality descriptor
		cmp	ebp,NatTab2	; end of table?
		jb	NationInit2	; next descriptor
		ret

V závěru funkce je posunut ukazatel národnostních popisovačů a je provedeno zmapování další tabulky.


; ------------- Nationality descriptors

NatTab:
NatTabEN:NATION EN,LANG_ENGLISH,SUBLANG_ENGLISH_US,CP_IBM437,":","/",".",39,";"
NatTabCZ:NATION CZ,LANG_CZECH,SUBLANG_NEUTRAL,CP_IBM852,":",".",","," ",";"
NatTab2:

; ------------- English

ShortNameEN:	CTEXTDATA 'EN'
LongNameEN:	CTEXTDATA 'English'
LangNameEN:	CTEXTDATA 'English'
AlphabetEN:	CTEXTDATA 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ShortTimeEN:	CTEXTDATA 'h:mmt'
LongTimeEN:	CTEXTDATA 'h:mm:ss tt'
ShortDateEN:	CTEXTDATA 'M/d/yy'
LongDateEN:	CTEXTDATA 'MMMM d yyyy'
ShortAMEN:	CTEXTDATA 'a'
ShortPMEN:	CTEXTDATA 'p'
LongAMEN:	CTEXTDATA 'AM'
LongPMEN:	CTEXTDATA 'PM'
ShortBCEEN:	CTEXTDATA 'BC'
ShortCEEN:	CTEXTDATA 'AD'
LongBCEEN:	CTEXTDATA 'BCE'
LongCEEN:	CTEXTDATA 'CE'
ShortWeekEN1:	CTEXTDATA 'Mon'
ShortWeekEN2:	CTEXTDATA 'Tue'
ShortWeekEN3:	CTEXTDATA 'Wed'
ShortWeekEN4:	CTEXTDATA 'Thu'
ShortWeekEN5:	CTEXTDATA 'Fri'
ShortWeekEN6:	CTEXTDATA 'Sat'
ShortWeekEN7:	CTEXTDATA 'Sun'
LongWeekEN1:	CTEXTDATA 'Monday'
LongWeekEN2:	CTEXTDATA 'Tuesday'
LongWeekEN3:	CTEXTDATA 'Wednesday'
LongWeekEN4:	CTEXTDATA 'Thursday'
LongWeekEN5:	CTEXTDATA 'Friday'
LongWeekEN6:	CTEXTDATA 'Saturday'
LongWeekEN7:	CTEXTDATA 'Sunday'
ShortMonthEN1:	CTEXTDATA 'Jan'
ShortMonthEN2:	CTEXTDATA 'Feb'
ShortMonthEN3:	CTEXTDATA 'Mar'
ShortMonthEN4:	CTEXTDATA 'Apr'
ShortMonthEN5:	CTEXTDATA 'May'
ShortMonthEN6:	CTEXTDATA 'Jun'
ShortMonthEN7:	CTEXTDATA 'Jul'
ShortMonthEN8:	CTEXTDATA 'Aug'
ShortMonthEN9:	CTEXTDATA 'Sep'
ShortMonthEN10:	CTEXTDATA 'Oct'
ShortMonthEN11:	CTEXTDATA 'Nov'
ShortMonthEN12:	CTEXTDATA 'Dec'
LongMonth1EN1:
LongMonthEN1:	CTEXTDATA 'January'
LongMonth1EN2:
LongMonthEN2:	CTEXTDATA 'February'
LongMonth1EN3:
LongMonthEN3:	CTEXTDATA 'March'
LongMonth1EN4:
LongMonthEN4:	CTEXTDATA 'April'
LongMonth1EN5:
LongMonthEN5:	CTEXTDATA 'May'
LongMonth1EN6:
LongMonthEN6:	CTEXTDATA 'June'
LongMonth1EN7:
LongMonthEN7:	CTEXTDATA 'July'
LongMonth1EN8:
LongMonthEN8:	CTEXTDATA 'August'
LongMonth1EN9:
LongMonthEN9:	CTEXTDATA 'September'
LongMonth1EN10:
LongMonthEN10:	CTEXTDATA 'October'
LongMonth1EN11:
LongMonthEN11:	CTEXTDATA 'November'
LongMonth1EN12:
LongMonthEN12:	CTEXTDATA 'December'

Tabulka NatTab popisuje jazyky použité v systému Litos. Pro jednoduchost je zde uveden pouze anglický jazyk.


; ------------- Alphabetic hash tables (1 KB)

AlphaHashTabNxt:dd	AlphaHashTab	; next hash subtable

AlphaHashTab:	resb	NATSUBPAGES
AlphaHashTab2:

AlphaHashTab je pole podstránek, které budou použity během inicializace funkcí NationInit. Jednotlivé podstránky jsou postupně obsazovány a současně je posouván ukazatel AlphaHashTabNxt, který ukazuje na příští volnou položku pole podstránek.


; ------------- Similar languages
; Macro - area of LANG_ENGLISH identifiers (%1 = number of entries)
%macro		LANGNEAR_DEF	1
		%rep	%1
		db	LANG_ENGLISH
		%endrep
%endmacro

LangNear:	LANGNEAR_DEF	(5-0)	; 0...4
		db	LANG_SLOVAK	; 5: LANG_CZECH -> LANG_SLOVAK
		LANGNEAR_DEF	(27-6)	; 6...26
		db	LANG_CZECH	; 27: LANG_SLOVAK -> LANG_CZECH
		LANGNEAR_DEF	(256-28) ; 28...255

Tabulka LangNear definuje příbuzné jazyky. Jedná se o pole o velikosti 256 bajtů, každé položce přísluší jeden náhradní jazyk. Nepoužité položky jsou vyplněny identifikátorem anglického jazyku. Tabulka se používá při vyhledání nejbližších textů ve vícejazykovém textovém poli.


Obsah / Utility / LANG / Inicializace národnostních popisovačů