Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
701 serge 1
/****************************************************************************
2
*
3
*                            Open Watcom Project
4
*
5
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6
*
7
*  ========================================================================
8
*
9
*    This file contains Original Code and/or Modifications of Original
10
*    Code as defined in and that are subject to the Sybase Open Watcom
11
*    Public License version 1.0 (the 'License'). You may not use this file
12
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14
*    provided with the Original Code and Modifications, and is also
15
*    available at www.sybase.com/developer/opensource.
16
*
17
*    The Original Code and all software distributed under the License are
18
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22
*    NON-INFRINGEMENT. Please see the License for the specific language
23
*    governing rights and limitations under the License.
24
*
25
*  ========================================================================
26
*
27
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
28
*               DESCRIBE IT HERE!
29
*
30
****************************************************************************/
31
 
32
 
33
#include "variety.h"
34
 
35
#include 
36
#include 
37
#include "mbchar.h"
38
 
39
 
40
unsigned int __MBCodePage = 0;              /* default code page */
41
 
42
static void set_dbcs_table( int low, int high )
43
{
44
    memset( __MBCSIsTable + low + 1, _MB_LEAD, high - low + 1 );
45
}
46
 
47
static void clear_dbcs_table( void )
48
{
49
    __IsDBCS = 0;                           /* SBCS for now */
50
    __MBCodePage = 0;
51
    memset( __MBCSIsTable, 0, 257 );
52
}
53
 
54
/****
55
***** Initialize a multi-byte character set.  Returns 0 on success.
56
****/
57
 
58
int __mbinit( int codepage )
59
{
60
 
61
    /*** Handle values from _setmbcp ***/
62
    if( codepage == _MBINIT_CP_ANSI )
63
    {
64
      codepage = 0;
65
    }
66
    else
67
    if( codepage == _MBINIT_CP_OEM )
68
    {
69
      codepage = 0;
70
    }
71
    else
72
    if( codepage == _MBINIT_CP_SBCS )
73
    {
74
        clear_dbcs_table();
75
        return( 0 );
76
    }
77
    else
78
    if( codepage == _MBINIT_CP_932 )
79
    {
80
        clear_dbcs_table();
81
        set_dbcs_table( 0x81, 0x9F );
82
        set_dbcs_table( 0xE0, 0xFC );
83
        __IsDBCS = 1;
84
        __MBCodePage = 932;
85
        return( 0 );
86
    }
87
    return( 0 );                                /* return success code */
88
}
89
 
90
 
91
 
92
/****
93
***** Query DOS to find the valid lead byte ranges.
94
****/
95
 
96
#if defined(__DOS__) && !defined(__OSI__)
97
#ifndef __386__
98
 
99
// for some unknown reason NT DPMI returns for DOS service 6300h
100
// Carry=0, odd SI value and DS stay unchanged
101
// this case is also tested as wrong int 21h result
102
#if 1
103
#pragma aux             dos_get_dbcs_lead_table = \
104
        "push ds"       \
105
        "xor ax,ax"     \
106
        "mov ds,ax"     \
107
        "mov ah,63h"    /* get DBCS vector table */ \
108
        "int 21h"       \
109
        "mov di,ds"     \
110
        "jnc label1"    \
111
        "xor di,di"     \
112
        "label1:"       \
113
        "test di,di"    \
114
        "jnz exit1"     \
115
        "mov si,di"     \
116
        "exit1:"        \
117
        "pop ds"        \
118
        value           [di si] \
119
        modify          [ax bx cx dx si di es];
120
#else
121
unsigned short _WCFAR *dos_get_dbcs_lead_table( void )
122
/****************************************************/
123
{
124
    union REGS        regs;
125
    struct SREGS      sregs;
126
 
127
    regs.w.ax = 0x6300;                     /* get lead byte table code */
128
    sregs.ds = 0;
129
    sregs.es = 0;
130
    intdosx( ®s, ®s, &sregs );        /* call DOS */
131
    if( regs.w.cflag || ( sregs.ds == 0 ))  /* ensure function succeeded */
132
        return( NULL );
133
    return( MK_FP( sregs.ds, regs.w.si ) ); /* return pointer to table */
134
}
135
#endif
136
 
137
#if 0
138
unsigned short dos_get_code_page( void )
139
/**************************************/
140
{
141
    union REGS          regs;
142
    struct SREGS        sregs;
143
    unsigned char       buf[7];
144
 
145
    regs.w.ax = 0x6501;                     /* get international info */
146
    regs.w.bx = 0xFFFF;                     /* global code page */
147
    regs.w.cx = 7;                          /* buffer size */
148
    regs.w.dx = 0xFFFF;                     /* current country */
149
    regs.w.di = FP_OFF( (void __far*)buf ); /* buffer offset */
150
    sregs.es = FP_SEG( (void __far*)buf );  /* buffer segment */
151
    sregs.ds = 0;                           /* in protected mode (dos16m) DS must be initialized */
152
    intdosx( ®s, ®s, &sregs );        /* call DOS */
153
    if( regs.w.cflag )  return( 0 );        /* ensure function succeeded */
154
    return( * (unsigned short*)(buf+5) );   /* return code page */
155
}
156
#else
157
#pragma aux dos_get_code_page = \
158
        "push ds"       \
159
        "push bp"       \
160
        "mov bp,sp"     \
161
        "sub sp,8"      \
162
        "xor ax,ax"     \
163
        "mov ds,ax"     \
164
        "mov ax,6501h"  /* get international info */ \
165
        "mov bx,0ffffh" /* global code page */ \
166
        "mov cx,0007h"  /* buffer size */ \
167
        "mov dx,0ffffh" /* current country */ \
168
        "lea di,[bp-8]" /* buffer offset */ \
169
        "push ss"       \
170
        "pop es"        /* buffer segment */ \
171
        "int 21h"       /* call DOS */ \
172
        "mov ax,[bp-8+5]" /* code page */ \
173
        "jnc NoError"   \
174
        "xor ax,ax"     \
175
        "NoError:"      \
176
        "mov sp,bp"     \
177
        "pop bp"        \
178
        "pop ds"        \
179
        value           [ax] \
180
        modify          [ax bx cx dx di es];
181
#endif
182
 
183
#else
184
 
185
 
186
#pragma pack(__push,1);
187
typedef struct {
188
    unsigned short  int_num;
189
    unsigned short  real_ds;
190
    unsigned short  real_es;
191
    unsigned short  real_fs;
192
    unsigned short  real_gs;
193
    unsigned long   real_eax;
194
    unsigned long   real_edx;
195
} PHARLAP_block;
196
#pragma pack(__pop);
197
 
198
unsigned short _WCFAR *dos_get_dbcs_lead_table( void )
199
/****************************************************/
200
{
201
    union REGPACK       regs;
202
 
203
    if( _IsPharLap() ) {
204
        PHARLAP_block   pblock;
205
 
206
        memset( &pblock, 0, sizeof( pblock ) );
207
        memset( ®s, 0, sizeof( regs ) );
208
        pblock.real_eax = 0x6300;           /* get DBCS vector table */
209
        pblock.int_num = 0x21;              /* DOS call */
210
        regs.x.eax = 0x2511;                /* issue real-mode interrupt */
211
        regs.x.edx = FP_OFF( &pblock );     /* DS:EDX -> parameter block */
212
        regs.w.ds = FP_SEG( &pblock );
213
        intr( 0x21, ®s );
214
        if( pblock.real_ds != 0xFFFF ) {    /* weird OS/2 value */
215
            return( MK_FP( _ExtenderRealModeSelector,
216
                           (((unsigned)pblock.real_ds)<<4) + regs.w.si ) );
217
        }
218
    } else if( _IsRational() ) {
219
        rm_call_struct  dblock;
220
 
221
        memset( &dblock, 0, sizeof( dblock ) );
222
        dblock.eax = 0x6300;                /* get DBCS vector table */
223
        DPMISimulateRealModeInterrupt( 0x21, 0, 0, &dblock );
224
        if( (dblock.flags & 1) == 0 ) {
225
            return( MK_FP( _ExtenderRealModeSelector,
226
                           (((unsigned)dblock.ds)<<4) + dblock.esi ) );
227
        }
228
    }
229
    return( NULL );
230
}
231
 
232
unsigned short dos_get_code_page( void )
233
/**************************************/
234
{
235
    union REGPACK           regs;
236
    unsigned short __far  * temp;
237
    unsigned short          real_seg;
238
    unsigned short          codepage = 0;
239
 
240
 
241
    /*** Get the code page ***/
242
    if( _IsPharLap() ) {
243
        union REGS      r;
244
        PHARLAP_block   pblock;
245
 
246
        /*** Alloc DOS Memory under Phar Lap ***/
247
        memset( &r, 0, sizeof( r ) );
248
        r.x.ebx = 1;
249
        r.x.eax = 0x25c0;
250
        intdos( &r, &r );
251
        real_seg = r.w.ax;
252
 
253
        memset( &pblock, 0, sizeof( pblock ) );
254
        memset( ®s, 0, sizeof( regs ) );
255
        pblock.real_eax = 0x6501;           /* get international info */
256
        pblock.real_edx = 0xFFFF;           /* current country */
257
        pblock.real_es = real_seg;          /* buffer segment */
258
        regs.x.ebx = 0xFFFF;                /* global code page */
259
        regs.x.ecx = 7;                     /* buffer size */
260
        regs.x.edi = 0;                     /* buffer offset */
261
        pblock.int_num = 0x21;              /* DOS call */
262
        regs.x.eax = 0x2511;                /* issue real-mode interrupt */
263
        regs.x.edx = FP_OFF( &pblock );     /* DS:EDX -> parameter block */
264
        regs.w.ds = FP_SEG( &pblock );
265
        intr( 0x21, ®s );
266
        if( pblock.real_ds != 0xFFFF ) {    /* weird OS/2 value */
267
            temp = MK_FP( _ExtenderRealModeSelector, (real_seg<<4) + 5 );
268
            codepage = *temp;
269
        }
270
 
271
        /*** Free DOS Memory under Phar Lap ***/
272
        r.x.ecx = real_seg;
273
        r.x.eax = 0x25c1;
274
        intdos( &r, &r );
275
    } else if( _IsRational() ) {
276
        unsigned long       dpmi_rc;
277
        unsigned short      selector;
278
        rm_call_struct      dblock;
279
 
280
        /*** Allocate some DOS memory with DPMI ***/
281
        dpmi_rc = DPMIAllocateDOSMemoryBlock( 1 );      /* one paragraph is enough */
282
        real_seg = (unsigned short) dpmi_rc;
283
        selector = (unsigned short) (dpmi_rc>>16);
284
 
285
        memset( &dblock, 0, sizeof( dblock ) );
286
        dblock.eax = 0x6501;                /* get international info */
287
        dblock.ebx = 0xFFFF;                /* global code page */
288
        dblock.ecx = 7;                     /* buffer size */
289
        dblock.edx = 0xFFFF;                /* current country */
290
        dblock.edi = 0;                     /* buffer offset */
291
        dblock.es = real_seg;               /* buffer segment */
292
        DPMISimulateRealModeInterrupt( 0x21, 0, 0, &dblock );
293
        if( (dblock.flags & 1) == 0 ) {
294
            temp = MK_FP( _ExtenderRealModeSelector, (real_seg<<4) + 5 );
295
            codepage = *temp;
296
        }
297
        /*** Free DOS memory with DPMI ***/
298
        DPMIFreeDOSMemoryBlock( selector );
299
    }
300
 
301
    return( codepage );
302
}
303
 
304
 
305
#endif
306
#endif