plat/msdos386: fix startup code so that it works under dosemu2

- do not try to store data through code segment selectors
 - set each segment limit to segment size - 1, not segment size
 - get PSP segment while still in real/V86 mode (DPMI host
   might choose to return PM selector for int 0x21, ah = 0x62)
 - other minor fixes
This commit is contained in:
tkchia 2022-08-23 14:35:43 +00:00
parent 0165c07c7b
commit 95ed8ee484
2 changed files with 36 additions and 31 deletions

View file

@ -21,23 +21,24 @@ begtext:
! ax: pmode code segment of stub
! bx: pmode data segment of stub
! cx: rmode segment of stub
! dx: pointer to realloc routine (in stub)e
! dx: pointer to realloc routine (in stub)
! si: pointer to interrupt routine (in stub)
! di: pointer to transfer buffer (in stub)
! bp: rmode PSP segment
! Resize the segment to include the BSS.
o16 cseg mov (realloc_ptr+4), ax
cseg mov (realloc_ptr+0), edx
cseg o16 mov (pmode_cs), ax
cseg o16 mov (pmode_ds), bx
cseg o16 mov (rmode), cx
cseg o16 mov (interrupt_ptr+4), ax
cseg mov (interrupt_ptr+0), esi
cseg o16 mov (transfer_buffer_ptr), di
o16 mov (realloc_ptr+4), ax
mov (realloc_ptr+0), edx
o16 mov (pmode_cs), ax
o16 mov (pmode_ds), bx
o16 mov (rmode), cx
o16 mov (interrupt_ptr+4), ax
mov (interrupt_ptr+0), esi
o16 mov (transfer_buffer_ptr), di
mov eax, __end
cseg callf (realloc_ptr)
callf (realloc_ptr)
! Clear BSS.
@ -71,7 +72,8 @@ begtext:
xor edx, edx
o16 mov ax, 0x0007
int 0x31 ! set base address to 0
o16 mov cx, 0x0010
o16 dec dx
o16 mov cx, 0x000f
o16 mov ax, 0x0008
int 0x31 ! set limit to 1MB
@ -84,9 +86,7 @@ begtext:
! Locate the PSP.
movb ah, 0x62
int 0x21
movzx esi, bx
movzx esi, bp
shl esi, 4 ! convert to linear address
! Copy the whole thing into 32-bit memory.

View file

@ -127,7 +127,7 @@ exe_start:
mov cx, 1
int 0x31 ! allocate LDT
jc bad_dpmi
mov es, ax
mov fs, ax
mov (psegcs32), ax
mov cx, (pmemlen+0)
@ -140,12 +140,12 @@ exe_start:
mov dx, cx
mov cx, bx
mov bx, es
mov bx, fs
mov ax, 0x0007
int 0x31 ! set segment base address
jc bad_dpmi
mov bx, es
mov bx, fs
mov dx, (pmemlen+0)
mov cx, (pmemlen+2)
mov ax, 0x0008
@ -155,23 +155,23 @@ exe_start:
and cx, 3
shl cx, 5
or cx, 0xc09b ! 32-bit, big, code, non-conforming, readable
mov bx, es
mov bx, fs
mov ax, 0x0009
int 0x31 ! set descriptor access rights
! Allocate the data segment (as a simple clone of the code segment). (10e)
mov ax, 0x000a
mov bx, es
mov bx, fs
int 0x31
mov fs, ax
mov es, ax
mov (psegds32), ax
mov cx, ax
and cx, 3
shl cx, 5
or cx, 0xc093 ! 32-bit, big, data, r/w, expand-up
mov bx, fs
mov bx, es
mov ax, 0x0009
int 0x31 ! set descriptor access rights
@ -198,7 +198,7 @@ exe_start:
o32 movzx ecx, ax ! number of bytes read
o32 mov esi, transfer_buffer
cld
o32 rep movsb
rep a32 movsb
jmp 1b
2:
@ -216,9 +216,10 @@ exe_start:
o32 mov edx, realloc
o32 mov esi, interruptf
o32 mov edi, transfer_buffer
o32 movzx ebp, (pspseg)
push es
pop ds
push es
push fs
push 0
retf ! 19b
@ -253,19 +254,21 @@ realloc:
mov (pmemaddr+0), cx
mov (pmemaddr+2), bx
mov bx, (psegds32)
mov dx, (pmemlen+0)
mov cx, (pmemlen+2)
mov ax, 0x0008
int 0x31 ! set ds segment limit
jc bad_dpmi
mov bx, (psegcs32)
mov dx, (pmemaddr+0)
mov cx, (pmemaddr+2)
mov ax, 0x0007
int 0x31 ! set cs linear address
jc bad_dpmi
mov bx, (psegds32)
int 0x31 ! set ds linear address
jc bad_dpmi
mov bx, (psegcs32)
int 0x31 ! set cs linear address
mov dx, (pmemlen+0)
mov cx, (pmemlen+2)
sub dx, 1
sbb cx, 0
mov ax, 0x0008
int 0x31 ! set ds segment limit
jc bad_dpmi
popa
@ -308,6 +311,7 @@ exit_with_error:
! Simulate DOS interrupt.
int21:
o32 movzx ebx, bx
o32 or ebx, 0x210000
! Simulate interrupt in the high half of ebx.
interrupt:
@ -327,6 +331,7 @@ interrupt:
o32 mov edi, dpmi_edi
mov ax, 0x300
o32 shr ebx, 16
xor cx, cx
int 0x31 ! simulate DOS interrupt
pop es
o32 movzx eax, (dpmi_eax)