1 /* The code in this file is Public Domain */
3 #if (defined(__WATCOMC__) && defined(__NT__))
14 ----------------------------------------------------------------------
15 Tuesday, May 5, 2009 1:40pm
16 rugxulo _AT_ gmail _DOT_ com
18 This file is (obviously?) not copyrighted, "nenies proprajxo" !!
20 Tested successfully on DR-DOS 7.03, FreeDOS 1.0++, and MS-DOS 6.22.
21 (Doesn't work on XP or Vista, though.)
22 ----------------------------------------------------------------------
24 unsigned short query_con_codepage(void);
26 gets currently selected display CON codepage
28 int 21h, 6601h ("chcp") needs NLSFUNC.EXE + COUNTRY.SYS, but many
29 obscure codepages (e.g. FD's cp853 from EGA.CPX (CPIX.ZIP) or
30 Kosta Kostis' cp913 from ISOLATIN.CPI (ISOCP101.ZIP) have no
31 relevant data inside COUNTRY.SYS.
33 int 21h, 440Ch 6Ah only works in MS-DOS and DR-DOS (not FreeDOS) because
34 FreeDOS DISPLAY is an .EXE TSR, not a device driver, and hence doesn't
35 fully support IOCTL, so they use the undocumented int 2Fh, 0AD02h
36 (which doesn't work in DR-DOS!). But DR-DOS' DISPLAY doesn't respond
37 to the typical install check i.d. anyways. FreeDOS currently only
38 supports COUNTRY.SYS in their "unstable" kernel 2037, but at least
39 their KEYB, "gxoje", supports cp853 too (thanks, Henrique!).
41 P.S. For MS or DR: ren ega.cpx *.com ; upx -d ega.com ; ren ega.com *.cpi
44 Latest "stable" FreeDOS kernel is 2040, it now includes COUNTRY.SYS
45 support by default, but NLSFUNC (CHCP) 'system code page' support is
46 partially unimplemented (lacking some int 2Fh calls, yet Eduardo
47 Casino didn't seem too worried, so I dunno, nag him if necessary,
49 ----------------------------------------------------------------------
52 unsigned short query_con_codepage(void) {
55 unsigned short param_block[2] = { 0, 437 };
57 regs.d.eax = 0x440C; /* GENERIC IO FOR HANDLES */
58 regs.d.ebx = 1; /* STDOUT */
59 regs.d.ecx = 0x036A; /* 3 = CON, 0x6A = QUERY SELECTED CP */
60 regs.x.ds = __tb >> 4; /* using transfer buffer for low mem. */
61 regs.x.dx = __tb & 0x0F; /* (suggested by DJGPP FAQ, hi Eli!) */
62 regs.x.flags |= 1; /* preset carry for potential failure */
63 __dpmi_int (0x21, ®s);
65 if (!(regs.x.flags & 1)) /* if succeed (carry flag not set) */
66 dosmemget( __tb, 4, param_block);
67 else { /* (undocumented method) */
68 regs.x.ax = 0xAD02; /* 440C -> MS-DOS or DR-DOS only */
69 regs.x.bx = 0xFFFE; /* AD02 -> MS-DOS or FreeDOS only */
71 __dpmi_int(0x2F, ®s);
73 if ((!(regs.x.flags & 1)) && (regs.x.bx < 0xFFFE))
74 param_block[1] = regs.x.bx;
77 return param_block[1];
79 #elif defined(__WATCOMC__) && defined(__I86__) /* Watcom C, 16 bit Intel */
81 /* rugxulo _AT_ gmail _DOT_ com */
87 unsigned short query_con_codepage(void) {
89 unsigned short param_block[2] = { 0, 437 };
91 regs.x.ax = 0x440C; /* GENERIC IO FOR HANDLES */
92 regs.x.bx = 1; /* STDOUT */
93 regs.x.cx = 0x036A; /* 3 = CON, 0x6A = QUERY SELECTED CP */
94 regs.x.dx = (unsigned short)param_block;
95 regs.x.cflag |= 1; /* preset carry for potential failure */
96 int86(0x21, ®s, ®s);
98 if (regs.x.cflag) /* if not succeed (carry flag set) */
100 regs.x.ax = 0xAD02; /* 440C -> MS-DOS or DR-DOS only */
101 regs.x.bx = 0xFFFE; /* AD02 -> MS-DOS or FreeDOS only */
103 int86(0x2F, ®s, ®s);
106 if ((!(regs.x.cflag)) && (regs.x.bx < 0xFFFE))
107 param_block[1] = regs.x.bx;
109 return param_block[1];
113 #elif defined(__WATCOMC__) && defined(__DOS__) /* Watcom C, 32 bit DOS */
115 /* rugxulo _AT_ gmail _DOT_ com */
121 unsigned short query_con_codepage(void) {
123 unsigned short param_block[2] = { 0, 437 };
125 regs.x.eax = 0x440C; /* GENERIC IO FOR HANDLES */
126 regs.x.ebx = 1; /* STDOUT */
127 regs.x.ecx = 0x036A; /* 3 = CON, 0x6A = QUERY SELECTED CP */
128 regs.x.edx = (unsigned short)param_block;
129 regs.x.cflag |= 1; /* preset carry for potential failure */
130 int386(0x21, ®s, ®s);
132 if (regs.x.cflag) /* if not succeed (carry flag set) */
134 regs.x.eax = 0xAD02; /* 440C -> MS-DOS or DR-DOS only */
135 regs.x.ebx = 0xFFFE; /* AD02 -> MS-DOS or FreeDOS only */
137 int386(0x2F, ®s, ®s);
140 if ((!(regs.x.cflag)) && (regs.x.ebx < 0xFFFE))
141 param_block[1] = regs.x.ebx;
143 return param_block[1];
148 #elif defined (WIN32) && !defined(__CYGWIN__) /* Windows, not Cygwin */
150 /* Erwin Waterlander */
153 unsigned short query_con_codepage(void) {
155 /* Dos2unix is modelled after dos2unix under SunOS/Solaris.
156 * The original dos2unix ISO mode on SunOS supported code
157 * pages CP437, CP850, CP860, CP863, and CP865, which
158 * are DOS code pages. Therefore we request here the DOS
159 * code page of the Console. The DOS code page is used
160 * by DOS programs, for instance text editor 'edit'.
163 /* Get the console's DOS code page */
164 return((unsigned short)GetConsoleOutputCP());
166 /* Get the system's ANSI code page */
167 /* return((unsigned short)GetACP()); */
171 #elif defined (__OS2__) /* OS/2 Warp */
176 unsigned short query_con_codepage(void) {
180 DosQueryCp(sizeof(cp), cp, &cplen);
181 return((unsigned short)cp[0]);
184 #else /* Unix, other */
185 unsigned short query_con_codepage(void) {
192 printf("\nCP%u\n",query_con_codepage() ); /* should be same result as */
193 return 0; /* "mode con cp /status" */