DPMI - how to chain user and original RM handler? (Developers)
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:
- DPMI - how to chain user and original RM handler? - Laaca, 29.04.2023, 00:41 (Developers)
- DPMI - how to chain user and original RM handler? - ecm, 29.04.2023, 08:43
- DPMI - how to chain user and original RM handler? - ecm, 29.04.2023, 08:45
- DPMI - how to chain user and original RM handler? - Laaca, 29.04.2023, 14:04
- DPMI - how to chain user and original RM handler? - ecm, 29.04.2023, 15:17
- DPMI - how to chain user and original RM handler? - Laaca, 29.04.2023, 14:04
- DPMI - how to chain user and original RM handler? - ecm, 29.04.2023, 08:45
- DPMI - how to chain user and original RM handler? - bretjohn, 04.05.2023, 04:03
- DPMI - how to chain user and original RM handler? - CandyMan, 05.05.2023, 12:36
- DPMI - how to chain user and original RM handler? - Laaca, 05.05.2023, 21:53
- DPMI - how to chain user and original RM handler? - Laaca, 12.06.2023, 23:39
- DPMI - how to chain user and original RM handler? - ecm, 29.04.2023, 08:43