Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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 <string.h>
  36. #include <mbstring.h>
  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( &regs, &regs, &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( &regs, &regs, &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( &regs, 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, &regs );
  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( &regs, 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, &regs );
  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
  307.