Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

DPMI - how to chain user and original RM handler? (Developers)

posted by Laaca Homepage, Czech republic, 12.06.2023, 23:39

Ufff!
It was unexpectedly difficult to adapt your ideas to Freepascal.
It still did not work and I did not know why.

Only today I found the reason.
Normaly FPC assumes that DS=ES=SS (CS and FS are different)

But from these registers we have inside the callback only ES set to original value.
There is no problem with DS (mov ax,es;mov ds,ax) but there remains problem with SS.
If we do "mov ax,es;mov ss,ax" we get the immediate crash.
Se we have to work in unusual configuration when SS<>DS.

Fortunately it in most of cases works but not in all cases. There occur problems with several functions mixing pascal and assembler code.

And, what is relevant here, it makes problems with calling the DPMI functions which use the TRealRegs structure in situation when the TRealRegs structure is the local variable. Local variables are accessed not through DS/ES but through SS.

And as the DPMI funcs. 300h, 302h and 304h use ES:EDI for pointing the TRealRegs we can have a problem. The simple "mov edi,real_regs_struct" is not sufficient here because SS<>ES.

This issue is also the reason why inside the callbacks do not work many RTL functions like <Writeln>, <Readln> and do on. On the end they call the RTL function SimulateRealModeInterrupt (from unit Go32) which also call DPMI 300h with local variable.

(BTW: I suppose that most of this also applies to DJGPP)

However, at the end I succeed to chain user and original interrupt handler.





> Below is working assembly code that do it. Tested on true Dos.
>
>         format  Flat on "D:\CW\D3XX.EXE"
>
> StackSwitch = 0
>
> mov     [SelDS],ds
> mov     [SelFS],fs
>
> mov     edi,cRealRegs
> mov     ax,cs
> mov     ds,ax
> mov     esi,PopupStart
> mov     ax,0303h
> int     31h
> mov     ax,es
> mov     ds,ax
>
> cli
> xchg    [fs:4*15h+0],dx
> xchg    [fs:4*15h+2],cx
> mov     [PrevOfs],dx
> mov     [PrevSeg],cx
>
> mov     eax,dword [PrevOfs]
> mov     [dRealRegs+2Ah],eax     ;CS:IP
>
> sti
> @@:
> mov     ah,10h
> int     16h
> cmp     al,1Bh
> jnz     @B
>
> mov     eax,dword [PrevOfs]
> mov     [fs:4*15h],eax
>
> mov     ah,4Ch
> int     21h
>
> PopupStart:
> mov     ax,[esi]
> mov     [es:edi+2Ah],ax         ; RealIP
> mov     ax,[esi+02h]
> mov     [es:edi+2Ch],ax         ; RealCS
> add     word [es:edi+2Eh],6     ; RealSP (callfar = 4 | int = 6)
>
> push    ds es fs
> pushad
>
> cld
>
> mov     ds,[cs:SelDS]
> mov     es,ds
> mov     fs,[cs:SelFS]
> ;
> if StackSwitch
> mov     [PrevStack+4],ss
> mov     [PrevStack+0],esp
> lss     esp,[MainStack]
> end if
> ;
> cmp     [cRealRegs+1Dh],byte 4Fh        ;AH=4Fh ?
> jnz     NotFunction4F
> ;
> call    MainHandler
> ;
> NotFunction4F:
> ;
> mov     esi,cRealRegs
> mov     edi,dRealRegs
> mov     ecx,2Ah/2
> rep     movsw
> ;
> mov     ax,0302h
> mov     edi,dRealRegs
> xor     bh,bh
> xor     ecx,ecx
> mov     [edi+2Eh],ecx
> int     31h
> ;
> if StackSwitch
> lss     esp,[cs:PrevStack]
> end if
> popad
> pop     fs es ds
> iretd
>
> MainHandler:
> mov     al,'#'
> int     29h
> ret
>
> dRealRegs:      rb 50
> cRealRegs:      rb 50
>
> SelDS   dw ?
> SelFS   dw ?
>
> PrevOfs dw ?
> PrevSeg dw ?

>
> Binaries are here:
> https://megawrzuta.pl/download/52b3f37a42fc8503969ef82d717d9ab9.html
> Good luck!

---
DOS-u-akbar!

 

Complete thread:

Back to the forum
Board view  Mix view
22049 Postings in 2034 Threads, 396 registered users, 204 users online (0 registered, 204 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum