diff options
Diffstat (limited to 'querycp.c')
-rw-r--r-- | querycp.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/querycp.c b/querycp.c new file mode 100644 index 0000000..82bf58c --- /dev/null +++ b/querycp.c @@ -0,0 +1,196 @@ +/* The code in this file is Public Domain */ + +#if (defined(__WATCOMC__) && defined(__NT__)) +# define WIN32 +#endif + +#ifdef DJGPP + +#include <dpmi.h> +#include <go32.h> +#include <stdio.h> + +/* + ---------------------------------------------------------------------- + Tuesday, May 5, 2009 1:40pm + rugxulo _AT_ gmail _DOT_ com + + This file is (obviously?) not copyrighted, "nenies proprajxo" !! + + Tested successfully on DR-DOS 7.03, FreeDOS 1.0++, and MS-DOS 6.22. + (Doesn't work on XP or Vista, though.) + ---------------------------------------------------------------------- + + unsigned short query_con_codepage(void); + + gets currently selected display CON codepage + + int 21h, 6601h ("chcp") needs NLSFUNC.EXE + COUNTRY.SYS, but many + obscure codepages (e.g. FD's cp853 from EGA.CPX (CPIX.ZIP) or + Kosta Kostis' cp913 from ISOLATIN.CPI (ISOCP101.ZIP) have no + relevant data inside COUNTRY.SYS. + + int 21h, 440Ch 6Ah only works in MS-DOS and DR-DOS (not FreeDOS) because + FreeDOS DISPLAY is an .EXE TSR, not a device driver, and hence doesn't + fully support IOCTL, so they use the undocumented int 2Fh, 0AD02h + (which doesn't work in DR-DOS!). But DR-DOS' DISPLAY doesn't respond + to the typical install check i.d. anyways. FreeDOS currently only + supports COUNTRY.SYS in their "unstable" kernel 2037, but at least + their KEYB, "gxoje", supports cp853 too (thanks, Henrique!). + + P.S. For MS or DR: ren ega.cpx *.com ; upx -d ega.com ; ren ega.com *.cpi + + ADDENDUM (2011): + Latest "stable" FreeDOS kernel is 2040, it now includes COUNTRY.SYS + support by default, but NLSFUNC (CHCP) 'system code page' support is + partially unimplemented (lacking some int 2Fh calls, yet Eduardo + Casino didn't seem too worried, so I dunno, nag him if necessary, + heh). + ---------------------------------------------------------------------- +*/ + +unsigned short query_con_codepage(void) { + __dpmi_regs regs; + + unsigned short param_block[2] = { 0, 437 }; + + regs.d.eax = 0x440C; /* GENERIC IO FOR HANDLES */ + regs.d.ebx = 1; /* STDOUT */ + regs.d.ecx = 0x036A; /* 3 = CON, 0x6A = QUERY SELECTED CP */ + regs.x.ds = __tb >> 4; /* using transfer buffer for low mem. */ + regs.x.dx = __tb & 0x0F; /* (suggested by DJGPP FAQ, hi Eli!) */ + regs.x.flags |= 1; /* preset carry for potential failure */ + __dpmi_int (0x21, ®s); + + if (!(regs.x.flags & 1)) /* if succeed (carry flag not set) */ + dosmemget( __tb, 4, param_block); + else { /* (undocumented method) */ + regs.x.ax = 0xAD02; /* 440C -> MS-DOS or DR-DOS only */ + regs.x.bx = 0xFFFE; /* AD02 -> MS-DOS or FreeDOS only */ + regs.x.flags |= 1; + __dpmi_int(0x2F, ®s); + + if ((!(regs.x.flags & 1)) && (regs.x.bx < 0xFFFE)) + param_block[1] = regs.x.bx; + } + + return param_block[1]; +} +#elif defined(__WATCOMC__) && defined(__I86__) /* Watcom C, 16 bit Intel */ + +/* rugxulo _AT_ gmail _DOT_ com */ + +#include <stdio.h> +#include <dos.h> +#include <i86.h> + +unsigned short query_con_codepage(void) { + union REGS regs; + unsigned short param_block[2] = { 0, 437 }; + + regs.x.ax = 0x440C; /* GENERIC IO FOR HANDLES */ + regs.x.bx = 1; /* STDOUT */ + regs.x.cx = 0x036A; /* 3 = CON, 0x6A = QUERY SELECTED CP */ + regs.x.dx = (unsigned short)param_block; + regs.x.cflag |= 1; /* preset carry for potential failure */ + int86(0x21, ®s, ®s); + + if (regs.x.cflag) /* if not succeed (carry flag set) */ + { + regs.x.ax = 0xAD02; /* 440C -> MS-DOS or DR-DOS only */ + regs.x.bx = 0xFFFE; /* AD02 -> MS-DOS or FreeDOS only */ + regs.x.cflag |= 1; + int86(0x2F, ®s, ®s); + } + + if ((!(regs.x.cflag)) && (regs.x.bx < 0xFFFE)) + param_block[1] = regs.x.bx; + + return param_block[1]; + +} + +#elif defined(__WATCOMC__) && defined(__DOS__) /* Watcom C, 32 bit DOS */ + +/* rugxulo _AT_ gmail _DOT_ com */ + +#include <stdio.h> +#include <dos.h> +#include <i86.h> + +unsigned short query_con_codepage(void) { + union REGS regs; + unsigned short param_block[2] = { 0, 437 }; + + regs.x.eax = 0x440C; /* GENERIC IO FOR HANDLES */ + regs.x.ebx = 1; /* STDOUT */ + regs.x.ecx = 0x036A; /* 3 = CON, 0x6A = QUERY SELECTED CP */ + regs.x.edx = (unsigned short)param_block; + regs.x.cflag |= 1; /* preset carry for potential failure */ + int386(0x21, ®s, ®s); + + if (regs.x.cflag) /* if not succeed (carry flag set) */ + { + regs.x.eax = 0xAD02; /* 440C -> MS-DOS or DR-DOS only */ + regs.x.ebx = 0xFFFE; /* AD02 -> MS-DOS or FreeDOS only */ + regs.x.cflag |= 1; + int386(0x2F, ®s, ®s); + } + + if ((!(regs.x.cflag)) && (regs.x.ebx < 0xFFFE)) + param_block[1] = regs.x.ebx; + + return param_block[1]; + +} + + +#elif defined (WIN32) && !defined(__CYGWIN__) /* Windows, not Cygwin */ + +/* Erwin Waterlander */ + +#include <windows.h> +unsigned short query_con_codepage(void) { + + /* Dos2unix is modelled after dos2unix under SunOS/Solaris. + * The original dos2unix ISO mode on SunOS supported code + * pages CP437, CP850, CP860, CP863, and CP865, which + * are DOS code pages. Therefore we request here the DOS + * code page of the Console. The DOS code page is used + * by DOS programs, for instance text editor 'edit'. + */ + + /* Get the console's DOS code page */ + return((unsigned short)GetConsoleOutputCP()); + + /* Get the system's ANSI code page */ + /* return((unsigned short)GetACP()); */ + +} + +#elif defined (__OS2__) /* OS/2 Warp */ + +#define INCL_DOS +#include <os2.h> + +unsigned short query_con_codepage(void) { + ULONG cp[3]; + ULONG cplen; + + DosQueryCp(sizeof(cp), cp, &cplen); + return((unsigned short)cp[0]); +} + +#else /* Unix, other */ +unsigned short query_con_codepage(void) { + return(0); +} +#endif + +#ifdef TEST +int main() { + printf("\nCP%u\n",query_con_codepage() ); /* should be same result as */ + return 0; /* "mode con cp /status" */ +} +#endif + |