plat/msdos86: free up program memory above 64 KiB; also check
we have enough memory for BSS
This commit is contained in:
parent
df6cfe0410
commit
1c71653d7f
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
.sect .text
|
.sect .text
|
||||||
|
|
||||||
|
#define STACK_BUFFER 128 /* number of bytes to leave for stack */
|
||||||
|
|
||||||
begtext:
|
begtext:
|
||||||
! Make sure we are running under MS-DOS 2 or above.
|
! Make sure we are running under MS-DOS 2 or above.
|
||||||
!
|
!
|
||||||
|
@ -20,9 +22,38 @@ begtext:
|
||||||
! segment. (DOS 3+ does; DOS 2.x does not.)
|
! segment. (DOS 3+ does; DOS 2.x does not.)
|
||||||
movb ah, 0x30
|
movb ah, 0x30
|
||||||
int 0x21
|
int 0x21
|
||||||
|
cbw
|
||||||
cmpb al, 2
|
cmpb al, 2
|
||||||
xchg bx, ax
|
xchg bp, ax
|
||||||
jc bad_sys
|
jnc ok_sys
|
||||||
|
|
||||||
|
mov dx, bad_sys_msg
|
||||||
|
dos_msg:
|
||||||
|
movb ah, 9
|
||||||
|
int 0x21
|
||||||
|
ret
|
||||||
|
|
||||||
|
ok_sys:
|
||||||
|
! Resize the program's memory control block (MCB) to cover only the
|
||||||
|
! program's near code and data space. Use the starting sp value as
|
||||||
|
! a guide to how much memory we can grab. Abort on any failure.
|
||||||
|
!
|
||||||
|
! As a side effect, this also frees up any memory allocated to our
|
||||||
|
! program beyond 64 KiB. (The freed memory can possibly be used by
|
||||||
|
! e.g. child processes, in the future.)
|
||||||
|
!
|
||||||
|
! Also check that we have some space between the BSS end and the
|
||||||
|
! starting sp.
|
||||||
|
cmp sp, endbss+STACK_BUFFER
|
||||||
|
jb no_room
|
||||||
|
|
||||||
|
movb ah, 0x4a
|
||||||
|
mov bx, sp
|
||||||
|
movb cl, 4
|
||||||
|
shr bx, cl
|
||||||
|
inc bx
|
||||||
|
int 0x21
|
||||||
|
jc no_room
|
||||||
|
|
||||||
! Clear BSS.
|
! Clear BSS.
|
||||||
mov di, begbss
|
mov di, begbss
|
||||||
|
@ -35,11 +66,12 @@ begtext:
|
||||||
|
|
||||||
! Get the size of the environment variables plus (if present) the
|
! Get the size of the environment variables plus (if present) the
|
||||||
! program name. Also count the number of environment variables.
|
! program name. Also count the number of environment variables.
|
||||||
mov es, (0x002C)
|
|
||||||
xor di, di
|
xor di, di
|
||||||
|
mov es, 0x002C(di)
|
||||||
! ax = 0 from above
|
! ax = 0 from above
|
||||||
cwd ! dx = count of env. vars.
|
cwd ! dx = count of env. vars.
|
||||||
mov cx, -1
|
! cx = 0 from above
|
||||||
|
dec cx ! cx = max. str. bytes to scan
|
||||||
scasb ! handle special case of empty env.
|
scasb ! handle special case of empty env.
|
||||||
jz is_empty_env
|
jz is_empty_env
|
||||||
size_env:
|
size_env:
|
||||||
|
@ -48,7 +80,7 @@ size_env:
|
||||||
scasb
|
scasb
|
||||||
jnz size_env
|
jnz size_env
|
||||||
is_empty_env:
|
is_empty_env:
|
||||||
cmpb bl, 2
|
cmp bp, 2
|
||||||
jz no_argv0
|
jz no_argv0
|
||||||
scasw
|
scasw
|
||||||
repnz scasb
|
repnz scasb
|
||||||
|
@ -58,10 +90,9 @@ no_argv0:
|
||||||
! onto the stack.
|
! onto the stack.
|
||||||
mov si, di
|
mov si, di
|
||||||
dec si
|
dec si
|
||||||
and si, -2
|
|
||||||
std
|
std
|
||||||
copy_env:
|
copy_env:
|
||||||
test si, si
|
and si, -2
|
||||||
eseg lodsw
|
eseg lodsw
|
||||||
push ax
|
push ax
|
||||||
jnz copy_env
|
jnz copy_env
|
||||||
|
@ -79,7 +110,7 @@ copy_env:
|
||||||
|
|
||||||
! Build up argc, argv[], and envp[].
|
! Build up argc, argv[], and envp[].
|
||||||
push ax ! output buffer for argc, argv, envp
|
push ax ! output buffer for argc, argv, envp
|
||||||
push bx ! MS-DOS version
|
push bp ! MS-DOS version
|
||||||
push cx ! env. string data
|
push cx ! env. string data
|
||||||
push dx ! count of env. vars.
|
push dx ! count of env. vars.
|
||||||
mov ax, 0x0080
|
mov ax, 0x0080
|
||||||
|
@ -97,13 +128,6 @@ copy_env:
|
||||||
push ax
|
push ax
|
||||||
call _exit
|
call _exit
|
||||||
|
|
||||||
bad_sys:
|
|
||||||
mov dx, bad_sys_msg
|
|
||||||
dos_msg:
|
|
||||||
movb ah, 9
|
|
||||||
int 0x21
|
|
||||||
ret
|
|
||||||
|
|
||||||
no_room:
|
no_room:
|
||||||
mov dx, no_room_msg
|
mov dx, no_room_msg
|
||||||
call dos_msg
|
call dos_msg
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct for_main {
|
||||||
* Return zero if everything went well, non-zero otherwise.
|
* Return zero if everything went well, non-zero otherwise.
|
||||||
*/
|
*/
|
||||||
int _sys_initmain(char *arg_data, size_t n_env_vars, char *env_data,
|
int _sys_initmain(char *arg_data, size_t n_env_vars, char *env_data,
|
||||||
unsigned msdos_ver, struct for_main *out)
|
unsigned msdos_ver_major, struct for_main *out)
|
||||||
{
|
{
|
||||||
char **argv, **envp;
|
char **argv, **envp;
|
||||||
char c, *p, **pp;
|
char c, *p, **pp;
|
||||||
|
@ -100,7 +100,7 @@ int _sys_initmain(char *arg_data, size_t n_env_vars, char *env_data,
|
||||||
* shortword) following the environment variables, so advance p by 3
|
* shortword) following the environment variables, so advance p by 3
|
||||||
* bytes to get at the program name.
|
* bytes to get at the program name.
|
||||||
*/
|
*/
|
||||||
if ((msdos_ver & 0x00ff) >= 3)
|
if (msdos_ver_major >= 3)
|
||||||
{
|
{
|
||||||
p += 3;
|
p += 3;
|
||||||
argv[0] = p;
|
argv[0] = p;
|
||||||
|
|
Loading…
Reference in a new issue