mirror of
https://github.com/SEPPDROID/DR-DOS-OpenDOS.git
synced 2025-10-22 16:04:20 +00:00
418 lines
10 KiB
Plaintext
418 lines
10 KiB
Plaintext
; File : $NLSFUNC.A86$
|
|
;
|
|
; Description :
|
|
;
|
|
; Original Author : DIGITAL RESEARCH
|
|
;
|
|
; Last Edited By : $CALDERA$
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
; Copyright Work of Caldera, Inc. All Rights Reserved.
|
|
;
|
|
; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
|
|
; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
|
|
; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
|
|
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
|
|
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
|
|
; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
|
|
; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
|
|
; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
|
|
; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
|
|
; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
|
|
; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
|
|
; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
|
|
; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
|
|
; CIVIL LIABILITY.
|
|
;-----------------------------------------------------------------------;
|
|
;
|
|
; *** Current Edit History ***
|
|
; *** End of Current Edit History ***
|
|
;
|
|
; $Log$
|
|
;
|
|
; NLSFUNC.A86 1.6 93/12/01 18:30:10
|
|
; Read in full 258 bytes of collating info
|
|
; ENDLOG
|
|
|
|
;
|
|
; We have a problem with NLSFUNC.EXE - if this isn't loaded with an INSTALL=
|
|
; in CONFIG.SYS then the calls to set language/codepage will fail.
|
|
; So we provide the same functionality that NLSFUNC.EXE does here in the
|
|
; initialisation code. "nls_hook" is called by CONFIG before the country is
|
|
; set, then "nls_unhook" is called afterwards so we can throw away this code.
|
|
;
|
|
|
|
VALID_SIG equ 0EDC1h ; valid signature in COUNTRY.SYS file
|
|
|
|
DH_NEXT equ ds:dword ptr 0 ; Dword Pointer to Next DEV
|
|
DH_ATTRIB equ ds:word ptr 4 ; device attribute bits
|
|
DH_NAME equ ds:byte ptr 10 ; 8-BYTE device name
|
|
|
|
DA_CHARDEV equ 8000h ; 1=character device, 0=block device
|
|
DA_IOCTL equ 4000h ; device supports IOCTL string I/O
|
|
DA_GETSET equ 0040h ; supports 3.2 level functionality
|
|
|
|
include config.equ
|
|
include i:msdos.equ
|
|
include i:mserror.equ
|
|
|
|
|
|
CGROUP GROUP INITCODE
|
|
INITCODE CSEG PARA 'INITCODE'
|
|
|
|
; We share our NLS buffer with other temporary users
|
|
|
|
extrn nls_temp_area:byte
|
|
|
|
Public nls_hook, nls_unhook
|
|
|
|
nls_hook:
|
|
;--------
|
|
; On Entry:
|
|
; none
|
|
; On Exit:
|
|
; none
|
|
;
|
|
push es
|
|
mov ah,MS_S_GETINT
|
|
mov al,2fh
|
|
int DOS_INT ; read and save old INT 2F vector
|
|
mov old_int2f_off,bx
|
|
mov old_int2f_seg,es
|
|
mov ah,MS_S_SETINT
|
|
mov al,2fh
|
|
mov dx,offset int2f_handler ; install our own INT 2F handler
|
|
int DOS_INT
|
|
pop es
|
|
ret
|
|
|
|
nls_unhook:
|
|
;----------
|
|
; On Entry:
|
|
; none
|
|
; On Exit:
|
|
; none
|
|
;
|
|
push ds
|
|
mov dx,old_int2f_off
|
|
mov ds,old_int2f_seg
|
|
mov ah,MS_S_SETINT ; restore INT 2F vector
|
|
mov al,2fh
|
|
int DOS_INT
|
|
pop ds
|
|
ret
|
|
|
|
|
|
old_int2f rd 0
|
|
|
|
old_int2f_off dw 0
|
|
old_int2f_seg dw 0
|
|
|
|
int2f_handler:
|
|
;-------------
|
|
cmp ah,014h ; is it for us ?
|
|
je int2f_handler10
|
|
jmpf old_int2f ; no, pass it on
|
|
|
|
int2f_handler10:
|
|
cmp al,0 ; installation check ?
|
|
jne int2f_handler20
|
|
mov al,0ffh ; we are already installed
|
|
iret
|
|
|
|
int2f_handler20:
|
|
cmp al,0ffh ; Codepage Prep ?
|
|
jne int2f_handler30
|
|
call f66_prep
|
|
retf 2 ; iret, keeping flags
|
|
|
|
int2f_handler30:
|
|
cmp al,0feh ; Country Get Data ?
|
|
jne int2f_handler40
|
|
call f65_locate_and_read
|
|
retf 2 ; iret, keeping flags
|
|
|
|
int2f_handler40:
|
|
stc ; CY to indicate an error
|
|
mov ax,-ED_FUNCTION ; function not supported
|
|
retf 2 ; return an error
|
|
|
|
|
|
f66_cp dw 0 ; INT21/66 Local Variable
|
|
cp_packet dw 2 ; Packet Size
|
|
cp_cpid dw 0 ; Request CodePage
|
|
db 0,0 ; Packet Terminators
|
|
|
|
preperr dw 0 ; Prepare function Error Code
|
|
prepname rb 9 ; Reserved for ASCIIZ Device Name
|
|
|
|
;
|
|
; Area for country.sys current pointer table
|
|
; (these are all offsets into country.sys)
|
|
;
|
|
f65xx_code dw 0 ; Country code
|
|
f65xx_cp dw 0 ; Code page
|
|
dw 0 ; +1 reserved
|
|
f65xx_data dw 0 ; Data area
|
|
dw 0 ; Upper case table
|
|
dw 0 ; +1 reserved
|
|
dw 0 ; Filename upper case table
|
|
dw 0 ; Legal file characters
|
|
dw 0 ; Collating table
|
|
dw 0 ; Double byte character set lead byte table
|
|
f65xx_ptable_len equ 20
|
|
|
|
f65xx_codepage dw 0
|
|
f65xx_country dw 0
|
|
f65xx_sig dw 0 ; Signature
|
|
c_handle dw 0
|
|
|
|
|
|
f66_prep:
|
|
;
|
|
; This function scans the complete device list and prepares
|
|
; all devices which support codepage.
|
|
;
|
|
; On Entry BX Requested CodePage
|
|
;
|
|
; On Exit AX Last Error Code
|
|
;
|
|
DA_CODEPAGE equ DA_CHARDEV+DA_IOCTL+DA_GETSET
|
|
|
|
push ds
|
|
push es
|
|
push cs
|
|
pop es
|
|
mov f66_cp,bx ; Save requested CodePage
|
|
mov preperr,0000 ; Initialize Prepare Error
|
|
mov ax,122ch ; magic hook get Device List
|
|
int 2fh ; after the NUL entry
|
|
mov ds,bx ; BX:AX -> header after INT 2F
|
|
mov bx,ax ; DS:BX -> header to be useful
|
|
f66_p10:
|
|
push ds
|
|
push bx
|
|
mov ax,DH_ATTRIB[bx]
|
|
and ax,DA_CODEPAGE ; Check for a Character Device which
|
|
cmp ax,DA_CODEPAGE ; supports IOCTL strings and GETSET
|
|
jnz f66_p40 ; otherwise skip the device
|
|
|
|
lea si,DH_NAME[bx] ; Found a matching device so
|
|
mov di,offset prepname ; open the device and select the
|
|
mov cx,8 ; requested codepage
|
|
|
|
f66_p20:
|
|
lodsb
|
|
cmp al,' '
|
|
je f66_p30
|
|
stosb
|
|
loop f66_p20
|
|
|
|
f66_p30:
|
|
xor al,al
|
|
stosb
|
|
push cs
|
|
pop ds
|
|
mov dx,offset prepname ; Write Access
|
|
mov cl,1 ; Open for write
|
|
mov ax,1226h
|
|
int 2fh ; call magic hook
|
|
jc f66_perr
|
|
mov bx,ax ; Save Device Handle in BX
|
|
|
|
mov si,f66_cp ; Get Requested CodePage in SI
|
|
mov dx,offset cp_packet ; Offset of CodePage Struct
|
|
mov cx,006Ah ; Get Unknown CodePage
|
|
push bp
|
|
mov bp,0ch ; Generic IOCTL
|
|
mov ax,122bh
|
|
int 2fh ; call magic hook
|
|
pop bp
|
|
jc f66_p32 ; Error so Select requested Code Page
|
|
|
|
cmp si,cp_cpid
|
|
je f66_p35 ; If this the currently selected
|
|
f66_p32: ; skip the select CodePage
|
|
mov cp_cpid,si
|
|
mov dx,offset cp_packet ; Offset of CodePage Struct
|
|
mov cx,004Ah ; Select Unkown CodePage
|
|
push bp
|
|
mov bp,0ch ; Generic IOCTL
|
|
mov ax,122bh
|
|
int 2fh ; call magic hook
|
|
pop bp
|
|
jnc f66_p35 ; No Error so skip the error
|
|
f66_p33:
|
|
mov preperr,ax ; save
|
|
|
|
f66_p35:
|
|
mov ax,1227h
|
|
int 2fh ; magic hook to close handle
|
|
jmp f66_p40
|
|
|
|
f66_perr:
|
|
mov preperr,ax ; Save the error code and try the
|
|
f66_p40: ; next device in the chain
|
|
pop bx ; Restore the Device offset
|
|
pop ds
|
|
lds bx,DH_NEXT[bx] ; check next character device for
|
|
cmp bx,0FFFFh ; Codepage support
|
|
jne f66_p10
|
|
|
|
mov ax,preperr ; All devices have been prepared
|
|
pop es
|
|
pop ds
|
|
or ax,ax ; now return the last error code
|
|
ret ; in AX
|
|
|
|
;
|
|
; **********************************************************************
|
|
; *** Function 65 support - routines for seeking a country/codepage ***
|
|
; *** and loading the required information into the temp data area ***
|
|
; **********************************************************************
|
|
;
|
|
; **************************************************
|
|
; *** Open country.sys and search for the ***
|
|
; *** table of offsets for the given country/ ***
|
|
; *** codepage, read it in and exit. ***
|
|
; **************************************************
|
|
|
|
f65_locate_and_read:
|
|
;-------------------
|
|
; Locate and Read info CL for Country DX Codepage BX using file DS:DI
|
|
test di,di ; valid filename ?
|
|
stc
|
|
jz f65_lr_exit
|
|
|
|
push cx
|
|
call f65x_find_info ; Will need to load up the info
|
|
pop ax
|
|
jc f65_lr_exit ; so do it if we can.
|
|
|
|
mov dx,offset nls_temp_area
|
|
mov cx,258 ; read 258 bytes into local buffer
|
|
push ax
|
|
call f65x_load_info ; Load required info
|
|
pop ax
|
|
jc f65_lr_exit
|
|
mov bx,c_handle ; Close the file first
|
|
mov ax,1227h
|
|
int 2fh ; magic hook to close handle
|
|
jc f65_lr_exit
|
|
mov si,offset nls_temp_area ; Tell subroutines where info is
|
|
f65_lr_exit:
|
|
ret
|
|
;
|
|
; Entry: dx=country code, bx=codepage
|
|
; Exit : carry set, and country.sys closed if failure
|
|
; country.sys open ready for more reads if success
|
|
;
|
|
f65x_find_info:
|
|
mov f65xx_country,dx
|
|
mov f65xx_codepage,bx
|
|
mov dx,di
|
|
xor cx,cx ; Open for read
|
|
mov ax,1226h
|
|
int 2fh ; call magic hook
|
|
push cs ; get DS pointing to this segment
|
|
pop ds ; for future reads
|
|
jnc f65x_10
|
|
ret ; Successful open?
|
|
f65x_10:
|
|
mov c_handle,ax ; Save handle
|
|
mov dx,f65xx_country
|
|
cmp f65xx_code,dx ; do we already have the information?
|
|
jne f65x_30 ; No - get it from country.sys
|
|
f65x_20:
|
|
cmp f65xx_cp,bx ; Does codepage agree too?
|
|
je f65x_35 ; Yes so exit with no more ado
|
|
f65x_30:
|
|
mov dx,007Eh
|
|
xor cx,cx ; Seek within country.sys
|
|
mov bx,c_handle
|
|
push bp
|
|
mov bp,0 ; seek from begining
|
|
mov ax,1228h
|
|
int 2fh
|
|
pop bp
|
|
jc f65x_err
|
|
mov bx,c_handle ; check them
|
|
mov cx,2
|
|
mov dx,offset f65xx_sig
|
|
mov ax,1229h
|
|
int 2fh ; read the signature bytes
|
|
jc f65x_err
|
|
cmp f65xx_sig,VALID_SIG
|
|
jne f65x_err ; If signature bad exit
|
|
f65x_32:
|
|
mov bx,c_handle ; Read from country.sys header until
|
|
mov cx,f65xx_ptable_len ; Country/codepage found or NULL
|
|
mov dx,offset f65xx_code
|
|
mov ax,1229h
|
|
int 2fh
|
|
jc f65x_err
|
|
cmp f65xx_code,0 ; Found NULL so reqd combination
|
|
je f65x_err ; was not found
|
|
mov dx,f65xx_code ; Get the country/codepage values
|
|
mov bx,f65xx_cp ; read from Country.SYS
|
|
cmp dx,f65xx_country ; Check against the requested
|
|
jne f65x_32 ; Country.
|
|
cmp f65xx_codepage,0 ; If a codepage match is not
|
|
jz f65x_35 ; then return success
|
|
cmp bx,f65xx_codepage ; Check against the requested
|
|
jne f65x_32 ; Codepage
|
|
f65x_35:
|
|
mov f65xx_country,dx ; Force the Search Country and
|
|
mov f65xx_codepage,bx ; CodePage to be Updated
|
|
ret
|
|
|
|
f65x_err:
|
|
mov bx,c_handle ; and set the carry flag before
|
|
mov ax,1227h
|
|
int 2fh ; magic hook to close handle
|
|
stc
|
|
ret
|
|
|
|
;
|
|
; **************************************************
|
|
; *** Load the type of information requested ***
|
|
; *** For the country currently active in the ***
|
|
; *** offset table ***
|
|
; **************************************************
|
|
;
|
|
; Entry: al=type of info, dx=offset of buffer to read info into cx=no of bytes
|
|
; Exit : carry set, and country.sys closed if failure
|
|
;
|
|
f65x_load_info:
|
|
push es
|
|
push cx
|
|
push dx
|
|
push ds ; Make es=ds
|
|
pop es
|
|
dec al ; 1=Data , 2=uppercase, 4=fuppercase
|
|
sub bh,bh ; 5=filechars, 6=Collating table
|
|
mov bl,al ; 7=DBCS table
|
|
shl bx,1 ; Retrieve relevant offset
|
|
mov dx,f65xx_data[bx]
|
|
xor cx,cx ; Seek within country.sys
|
|
mov bx,c_handle
|
|
push bp
|
|
mov bp,0 ; seek from begining
|
|
mov ax,1228h
|
|
int 2fh
|
|
pop bp
|
|
pop dx ; Get buffer address back
|
|
pop cx ; and number of bytes to read
|
|
jc f65x_err
|
|
test ax,ax ; zero offset is a problem
|
|
jz f65x_err ; (probably DBCS with old COUNTRY.SYS)
|
|
mov bx,c_handle ; Now read that info into our data area
|
|
mov ax,1229h
|
|
int 2fh
|
|
jc f65x_err
|
|
pop es
|
|
ret
|
|
|
|
|
|
end
|