Marshal the environment, command line and PSP into 32-bit memory.

This commit is contained in:
David Given 2022-08-11 23:36:23 +02:00
parent 1764c6baa2
commit 680b6b9857

View file

@ -56,6 +56,7 @@ begtext:
mov es, ax mov es, ax
o16 mov bx, ax o16 mov bx, ax
o16 mov (.doshandle), bx o16 mov (.doshandle), bx
mov es, bx
xor ecx, ecx xor ecx, ecx
xor edx, edx xor edx, edx
@ -76,63 +77,79 @@ begtext:
movb ah, 0x62 movb ah, 0x62
int 0x21 int 0x21
movzx ebx, bx movzx esi, bx
shl ebx, 4 ! convert to linear address shl esi, 4 ! convert to linear address
mov (.psp), ebx
! Get the size of the environment variables plus (if present) the ! Copy the whole thing into 32-bit memory.
! program name. Also count the number of environment variables.
xor di, di mov ecx, 0x100/4
mov es, 0x002C(di) mov edi, _psp
! ax = 0 from above cld
cwd ! dx = count of env. vars. 1:
! cx = 0 from above eseg lods
dec cx ! cx = max. str. bytes to scan mov (edi), eax
scasb ! handle special case of empty env. add edi, 4
jz is_empty_env loop 1b
size_env:
inc dx ! Find the environment.
repnz scasb
mov es, (_psp + 0x002C) ! converted to pmode segment
! Count the size of the environment variable block.
xorb al, al ! byte to test for
xor edi, edi
xor edx, edx
cld
mov ecx, -1
scasb scasb
jnz size_env jz 2f ! empty environment
is_empty_env: 1:
cmp bp, 2
jz no_argv0
scasw
repnz scasb repnz scasb
no_argv0: inc edx
scasb
jnz 1b
2:
add edi, 2 ! skip the mysterious word
repnz scasb ! program name
! Copy out the environment variables and (possibly) program name ! Copy the whole environment block onto the stack.
! onto the stack.
mov si, di mov esi, edi
dec si add esi, 3
and esi, ~3 ! round up
jz empty_environment
mov ecx, esi
shr ecx, 2 ! number of dwords
std std
copy_env: sub esi, 4
and si, -2 1:
eseg lodsw eseg lods
push ax push eax
jnz copy_env loop 1b
mov cx, sp empty_environment:
mov ecx, esp ! environment data
! Reset DF and es properly. ! Reset DF and es properly.
cld cld
push ss push ss
pop es pop es
! Reserve space for argc and the argv and envp pointers on the ! Reserve space for argc and the argv and envp pointers on the
! stack. These will be passed to __m_a_i_n later. ! stack. These will be passed to __m_a_i_n later.
sub sp, 6
mov ax, sp sub esp, 3*4
mov eax, esp
! Build up argc, argv[], and envp[]. ! Build up argc, argv[], and envp[].
push ax ! output buffer for argc, argv, envp push eax ! output buffer for argc, argv, envp
push bp ! MS-DOS version push 3 ! MS-DOS version
push cx ! env. string data push ecx ! env. string data
push dx ! count of env. vars. push edx ! count of env. vars.
mov ax, 0x0080 push _psp+0x80 ! raw command line
push ax ! raw command line
call __sys_initmain call __sys_initmain
add sp, 10 add esp, 5*4
! Bail out if something went wrong. ! Bail out if something went wrong.
test ax, ax test ax, ax
@ -190,7 +207,7 @@ no_room_msg: .ascii 'No room$'
.comm _errno, 4 .comm _errno, 4
.comm .doshandle, 2 .comm .doshandle, 2
.comm .psp, 4 .comm _psp, 256
.sect .bss .sect .bss
.space 512 .space 512