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:
parent
0165c07c7b
commit
95ed8ee484
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue