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čů