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

View file

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