; getcoll.asm ; ; This Microsoft Windows 3.1 routine gets the DOS Collate Sequence ; Table and returns the real mode pointer to the calling function. ; This routine circumvents a problem in the Windows 3.1 Standard mode ; kernel by issuing a DPMI Simulate Real Mode Interrupt call. ; ; C prototype: ; char FAR *getcoll(unsigned codepage, unsigned country); ; ; Assembly instructions: ; TASM /m2 /mx getcoll ; (that is, use two pass assembly and case sensitive exports) ; ; written on Tue 04-12-1994 by Ed Beroset ; and released to the public domain by the author ; IDEAL MODEL small, C P286N ; allow all 286 non protected mode instructions global getcoll:PROC global pascal GLOBALDOSALLOC:FAR global pascal GLOBALDOSFREE:FAR CODESEG PROC getcoll codepage:WORD, country:WORD LOCAL MemBlock:WORD, RealRegs:WORD:19h USES bx, cx, di, es mov cx,19h ; clear the RealRegs structure xor ax,ax ; zeroes will do nicely mov di,ss ; it's on the stack mov es,di ; lea di,[RealRegs] ; es:di==>RealRegs cld ; go forward rep stosw ; whip it good mov cx,5 ; allocate data bytes required call GLOBALDOSALLOC pascal,0,cx; from DOS memory mov [RealRegs+22h],dx ; save real mode segment mov [MemBlock],ax ; save prot mode descriptor or dx,ax ; if there was an error, exit jz @@exit ; mov ax,[codepage] ; recall code page mov [RealRegs+10h],ax ; put in BX entry of RealRegs mov ax,[country] ; recall country code mov [RealRegs+14h],ax ; put in DX entry of RealRegs mov [RealRegs+18h],5 ; store buff size in CX mov [RealRegs+1Ch],6506h ; the function number for DOS in AX pushf ; pop ax ; a direct pop could be used, mov [RealRegs+20h],ax ; but this is more straightforward mov bx,21h ; perform Int 21h (DOS) xor cx,cx ; pass nothing on stack mov ax,300h ; DPMI Simulate Real Mode Int mov di,ss ; point to our datablock again mov es,di ; lea di,[RealRegs] ; reload pointer offset int 31h ; do it mov es,[MemBlock] ; point to our Memory Block jc @@bogus ; if error, leave xor di,di ; point to our block again cmp [BYTE es:di],6 ; check to see if it's valid jnz @@bogus ; if it isn't, leave mov dx,[WORD es:di+3] ; pointer struc is [6, offs, seg] mov ax,[WORD es:di+1] ; return dx:ax==>table (real mode) jmp @@freemem ; @@bogus: ; xor dx,dx ; otherwise hand back a NULL ptr xor ax,ax ; @@freemem: ; push ax ; push dx ; call GLOBALDOSFREE pascal,es ; free our precious memory pop dx ; pop ax ; @@exit: RET ; a macro -- actually pops regs, too ENDP getcoll END