1454 lines
51 KiB
NASM
1454 lines
51 KiB
NASM
|
; OpenDoors Online Software Programming Toolkit
|
||
|
; (C) Copyright 1991 - 1999 by Brian Pirie.
|
||
|
;
|
||
|
; This library is free software; you can redistribute it and/or
|
||
|
; modify it under the terms of the GNU Lesser General Public
|
||
|
; License as published by the Free Software Foundation; either
|
||
|
; version 2 of the License, or (at your option) any later version.
|
||
|
;
|
||
|
; This library is distributed in the hope that it will be useful,
|
||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
; Lesser General Public License for more details.
|
||
|
;
|
||
|
; You should have received a copy of the GNU Lesser General Public
|
||
|
; License along with this library; if not, write to the Free Software
|
||
|
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
;
|
||
|
;
|
||
|
; File: ODSwap.asm
|
||
|
;
|
||
|
; Description: Performs EMS/disk swapping and low level spawning
|
||
|
; activities. This file should only be included when building
|
||
|
; the MS-DOS version of OpenDoors.
|
||
|
;
|
||
|
; Revisions: Date Ver Who Change
|
||
|
; ---------------------------------------------------------------
|
||
|
; Oct 13, 1994 6.00 BP New file header format.
|
||
|
; Feb 19, 1996 6.00 BP Changed version number to 6.00.
|
||
|
; Mar 03, 1996 6.10 BP Begin version 6.10.
|
||
|
|
||
|
|
||
|
; If you have increased the file handle table size so that more than 20 files
|
||
|
; may be open in the parent process, set FHTSZ to the new size.
|
||
|
|
||
|
FHTSZ EQU 20
|
||
|
|
||
|
IFDEF LCODE
|
||
|
ARG_1 EQU 6
|
||
|
ELSE
|
||
|
ARG_1 EQU 4
|
||
|
ENDIF
|
||
|
|
||
|
arena struc ; arena header
|
||
|
sig db 0 ; 'M' or 'Z' if last block
|
||
|
own dw 0 ; PSP of owner or 0 if free
|
||
|
siz dw 0 ; size not including header
|
||
|
arena ends
|
||
|
|
||
|
vector struc
|
||
|
number db 0 ; vector number
|
||
|
flag db 0 ; 0-CURRENT,1-IRET,2-free,3-end
|
||
|
vseg dw 0 ; vector segment
|
||
|
voff dw 0 ; vector offset
|
||
|
vector ends
|
||
|
|
||
|
_TEXT SEGMENT word public 'CODE'
|
||
|
ASSUME cs:_TEXT
|
||
|
ASSUME ds:nothing
|
||
|
ASSUME es:nothing
|
||
|
ASSUME ss:nothing
|
||
|
|
||
|
; The code between slidetop and slidebot constitutes the spawn kernel. The
|
||
|
; kernel is copied to the front of the parent process immediately following the
|
||
|
; parent's PSP. The environment passed to the child is copied to immediately
|
||
|
; following the kernel.
|
||
|
|
||
|
slidetop:
|
||
|
|
||
|
path db 79 dup (0) ; program to execute
|
||
|
command db 128 dup (0) ; command-line
|
||
|
file db 79 dup (0) ; swap file
|
||
|
|
||
|
parmblk label byte ; parameter block
|
||
|
environ dw 0 ; environment block
|
||
|
cmd dw 0,0 ; command-line tail
|
||
|
fcb1 dw 0,0 ; first file control block
|
||
|
fcb2 dw 0,0 ; second file control block
|
||
|
|
||
|
fcb5c db 10h dup (0) ; first file control block
|
||
|
fcb6c db 10h dup (0) ; second file control block
|
||
|
|
||
|
cntsvl dw 0 ; count save low
|
||
|
cntsvh dw 0 ; count save high
|
||
|
tmpcode dw 0 ; temporary return code
|
||
|
env dw 0 ; environment segment
|
||
|
envlen dw 0 ; environment length
|
||
|
parsz dw 0 ; parent size
|
||
|
ttlsz dw 0 ; total size
|
||
|
oldsz dw 0 ; old size
|
||
|
newsz dw 0 ; new size
|
||
|
emsseg dw 0 ; EMS page frame segment
|
||
|
handle dw 0 ; EMS handle
|
||
|
useems db 0 ; if 0, use EMS
|
||
|
save db 4 dup (0) ; save 4 bytes at DS:[2Eh]
|
||
|
f1add dd 0 ; fnish1 address
|
||
|
last db 0 ; if 0, last block swap
|
||
|
IF FHTSZ - 20
|
||
|
fhtsv db FHTSZ dup (0) ; file handle table save
|
||
|
ENDIF
|
||
|
|
||
|
errmsg db 'spawn error',0Dh,0Ah
|
||
|
msglen EQU $-errmsg
|
||
|
|
||
|
EVEN
|
||
|
lclstk dw 64 dup (0) ; local stack
|
||
|
stktop label word ; stack top
|
||
|
|
||
|
slide1: mov ax,cs ; install local stack
|
||
|
cli
|
||
|
mov ss,ax
|
||
|
mov sp,offset stktop - offset slidetop + 100h
|
||
|
sti
|
||
|
|
||
|
; copy environment
|
||
|
|
||
|
mov bx,offset slidebot - offset slidetop + 15 + 100h
|
||
|
mov cl,4
|
||
|
shr bx,cl ; convert to paragraphs
|
||
|
add bx,ax ; add CS (actually PSP)
|
||
|
index = offset environ - offset slidetop + 100h
|
||
|
mov cs:[index],bx ; parameter block
|
||
|
mov es,bx
|
||
|
xor di,di
|
||
|
index = offset env - offset slidetop + 100h
|
||
|
mov ds,cs:[index]
|
||
|
xor si,si
|
||
|
index = offset envlen - offset slidetop + 100h
|
||
|
mov cx,cs:[index]
|
||
|
shr cx,1 ; translate to word count
|
||
|
rep movsw ; CF set if one byte left over
|
||
|
adc cx,cx ; CX = 1 or 0, depending CF
|
||
|
rep movsb ; possible final byte
|
||
|
|
||
|
dec ax ; PSP segment
|
||
|
mov es,ax ; program arena header
|
||
|
mov bx,es:[siz]
|
||
|
index = offset oldsz - offset slidetop + 100h
|
||
|
mov cs:[index],bx ; old size
|
||
|
mov byte ptr es:[sig],'M' ; not last
|
||
|
index = offset newsz - offset slidetop + 100h
|
||
|
mov bx,cs:[index] ; new size
|
||
|
mov es:[siz],bx
|
||
|
|
||
|
inc ax ; PSP segment
|
||
|
add ax,bx ; add new size
|
||
|
mov es,ax ; new last arena header
|
||
|
mov byte ptr es:[sig],'Z' ; last
|
||
|
index = offset last - offset slidetop + 100h
|
||
|
cmp byte ptr cs:[index],0
|
||
|
je slide2 ; jump if last block swap
|
||
|
mov byte ptr es:[sig],'M' ; not last
|
||
|
|
||
|
slide2: mov word ptr es:[own],0 ; free
|
||
|
index = offset ttlsz - offset slidetop + 100h
|
||
|
mov ax,cs:[index] ; total size
|
||
|
sub ax,bx ; subtract new size
|
||
|
dec ax ; account for arena header
|
||
|
mov es:[siz],ax
|
||
|
|
||
|
; save 4 bytes destroyed by DOS 2.0 at DS:2Eh
|
||
|
|
||
|
mov ax,cs ; PSP segment
|
||
|
mov es,ax
|
||
|
mov bx,es:[2Eh]
|
||
|
index = offset save - offset slidetop + 100h
|
||
|
mov cs:[index],bx
|
||
|
mov bx,es:[30h]
|
||
|
index = offset save - offset slidetop + 102h
|
||
|
mov cs:[index],bx
|
||
|
|
||
|
mov bx,offset parmblk - offset slidetop + 100h
|
||
|
mov ds,ax ; PSP segment
|
||
|
mov dx,100h ; offset path
|
||
|
mov ax,4B00h ; load and execute program
|
||
|
int 21h
|
||
|
jnc slide3 ; jump if no error
|
||
|
index = offset tmpcode - offset slidetop + 100h
|
||
|
mov cs:[index],ax ; temporary return code
|
||
|
|
||
|
slide3: mov ax,cs ; install local stack
|
||
|
cli
|
||
|
mov ss,ax
|
||
|
mov sp,offset stktop - offset slidetop + 100h
|
||
|
sti
|
||
|
|
||
|
; restore 4 bytes destroyed by DOS 2.0 at DS:2Eh
|
||
|
|
||
|
mov es,ax ; PSP segment
|
||
|
index = offset save - offset slidetop + 100h
|
||
|
mov bx,cs:[index]
|
||
|
mov es:[2Eh],bx
|
||
|
index = offset save - offset slidetop + 102h
|
||
|
mov bx,cs:[index]
|
||
|
mov es:[30h],bx
|
||
|
|
||
|
index = offset oldsz - offset slidetop + 100h
|
||
|
mov bx,cs:[index] ; old size
|
||
|
mov ah,4Ah ; resize memory block
|
||
|
int 21h
|
||
|
jnc slide7
|
||
|
|
||
|
index = offset useems - offset slidetop + 100h
|
||
|
slide4: cmp byte ptr cs:[index],0
|
||
|
jne slide6 ; jump if don't use EMS
|
||
|
index = offset handle - offset slidetop + 100h
|
||
|
mov dx,cs:[index] ; EMS handle
|
||
|
|
||
|
slide5: mov ah,45h ; release handle and memory
|
||
|
int 67h
|
||
|
cmp ah,82h ; memory manager busy?
|
||
|
je slide5 ; jump if busy
|
||
|
|
||
|
slide6: jmp slide18 ; exit
|
||
|
|
||
|
index = offset parsz - offset slidetop + 100h
|
||
|
slide7: mov bx,cs:[index] ; parent size
|
||
|
index = offset ttlsz - offset slidetop + 100h
|
||
|
mov ax,cs:[index] ; total size
|
||
|
sub ax,bx ; subtract parent size
|
||
|
or ax,ax
|
||
|
jz slide9
|
||
|
mov dx,cs ; PSP segment
|
||
|
add dx,bx ; add parent size
|
||
|
mov es,dx ; new last arena header
|
||
|
mov byte ptr es:[sig],'Z' ; last
|
||
|
index = offset last - offset slidetop + 100h
|
||
|
cmp byte ptr cs:[index],0
|
||
|
je slide8 ; jump if last block swap
|
||
|
mov byte ptr es:[sig],'M' ; not last
|
||
|
|
||
|
slide8: mov word ptr es:[own],0 ; free
|
||
|
dec ax ; account for arena header
|
||
|
mov es:[siz],ax
|
||
|
|
||
|
slide9: push cs ; PSP segment
|
||
|
index = offset useems - offset slidetop + 100h
|
||
|
cmp byte ptr cs:[index],0
|
||
|
jne slide14 ; jump if don't use EMS
|
||
|
pop es ; PSP segment
|
||
|
mov di,offset slidebot - offset slidetop + 100h
|
||
|
index = offset emsseg - offset slidetop + 100h
|
||
|
mov ds,cs:[index] ; EMS page frame segment
|
||
|
mov si,offset slidebot - offset slidetop
|
||
|
index = offset handle - offset slidetop + 100h
|
||
|
mov dx,cs:[index] ; EMS handle
|
||
|
xor bx,bx ; logical page number
|
||
|
mov cx,16384 - ( offset slidebot - offset slidetop )
|
||
|
jmp short slide13
|
||
|
|
||
|
index = offset cntsvl - offset slidetop + 100h
|
||
|
slide10: sub cs:[index],cx
|
||
|
index = offset cntsvh - offset slidetop + 100h
|
||
|
sbb word ptr cs:[index],0
|
||
|
xor al,al ; physical page number
|
||
|
|
||
|
slide11: mov ah,44h ; map memory
|
||
|
int 67h
|
||
|
or ah,ah
|
||
|
jz slide12
|
||
|
cmp ah,82h ; memory manager busy?
|
||
|
je slide11 ; jump if busy
|
||
|
jmp slide4 ; exit
|
||
|
|
||
|
slide12: shr cx,1 ; translate to word count
|
||
|
rep movsw ; CF set if one byte left over
|
||
|
adc cx,cx ; CX = 1 or 0, depending CF
|
||
|
rep movsb ; possible final byte
|
||
|
xor si,si
|
||
|
mov cx,16384 ; assume copy full block
|
||
|
inc bx ; logical page number
|
||
|
cmp bx,1
|
||
|
je slide13
|
||
|
mov ax,es
|
||
|
add ax,1024 ; 16384 bytes
|
||
|
mov es,ax
|
||
|
mov di,16640 ; 16384 + 100h
|
||
|
|
||
|
index = offset cntsvh - offset slidetop + 100h
|
||
|
slide13: cmp word ptr cs:[index],0
|
||
|
jne slide10 ; jump if more than full block
|
||
|
index = offset cntsvl - offset slidetop + 100h
|
||
|
cmp cs:[index],cx
|
||
|
jae slide10 ; jump if at least full block
|
||
|
mov cx,cs:[index] ; CX = cntsvl
|
||
|
cmp cx,0
|
||
|
jne slide10 ; jump if more left to copy
|
||
|
jmp short slide17
|
||
|
|
||
|
slide14: pop ds ; PSP segment
|
||
|
IF FHTSZ - 20
|
||
|
|
||
|
; restore the file handle table from the kernel
|
||
|
|
||
|
mov si,offset fhtsv - offset slidetop + 100h
|
||
|
mov es,ds:[36h] ; file handle table segment
|
||
|
mov di,ds:[34h] ; file handle table offset
|
||
|
mov cx,FHTSZ ; file handle table size
|
||
|
rep movsb
|
||
|
ENDIF
|
||
|
mov dx,offset file - offset slidetop + 100h
|
||
|
mov ax,3D00h ; open file read only
|
||
|
int 21h
|
||
|
jc slide18 ; exit if error
|
||
|
mov bx,ax ; handle
|
||
|
|
||
|
xor cx,cx
|
||
|
mov dx,offset slidebot - offset slidetop
|
||
|
mov ax,4200h ; move file pointer
|
||
|
int 21h ; from beginning of file
|
||
|
|
||
|
mov dx,offset slidebot - offset slidetop + 100h
|
||
|
mov cx,65520 ; assume read full block
|
||
|
jmp short slide16
|
||
|
|
||
|
index = offset cntsvl - offset slidetop + 100h
|
||
|
slide15: sub cs:[index],cx
|
||
|
index = offset cntsvh - offset slidetop + 100h
|
||
|
sbb word ptr cs:[index],0
|
||
|
mov ah,3Fh ; read file
|
||
|
int 21h
|
||
|
jc slide18 ; exit if error
|
||
|
cmp ax,cx
|
||
|
jne slide18 ; exit if not all read
|
||
|
|
||
|
mov ax,ds
|
||
|
add ax,4095 ; 65520 bytes
|
||
|
mov ds,ax
|
||
|
|
||
|
index = offset cntsvh - offset slidetop + 100h
|
||
|
slide16: cmp word ptr cs:[index],0
|
||
|
jne slide15 ; jump if more than full block
|
||
|
index = offset cntsvl - offset slidetop + 100h
|
||
|
cmp word ptr cs:[index],65520
|
||
|
jae slide15 ; jump if at least full block
|
||
|
mov cx,cs:[index] ; CX = cntsvl
|
||
|
cmp cx,0
|
||
|
jne slide15 ; jump if more left to read
|
||
|
|
||
|
index = offset tmpcode - offset slidetop + 100h
|
||
|
slide17: mov ax,cs:[index] ; temporary return code
|
||
|
index = offset f1add - offset slidetop + 100h
|
||
|
jmp dword ptr cs:[index]
|
||
|
|
||
|
slide18: push cs ; PSP segment
|
||
|
pop ds
|
||
|
mov dx,offset errmsg - offset slidetop + 100h
|
||
|
mov cx,msglen ; errmsg length
|
||
|
mov bx,2 ; standard error device handle
|
||
|
mov ah,40h ; write error message
|
||
|
int 21h
|
||
|
mov ax,4C01h ; terminate with return code
|
||
|
int 21h
|
||
|
|
||
|
handler: iret ; interrupt handler
|
||
|
|
||
|
slidebot:
|
||
|
|
||
|
cntl dw 0 ; count low
|
||
|
cnth dw 0 ; count high
|
||
|
stks dw 0 ; original SS contents
|
||
|
stkp dw 0 ; original SP contents
|
||
|
psp dw 0 ; PSP segment
|
||
|
s1add dd 0 ; slide1 address
|
||
|
rcode dw 0 ; return code
|
||
|
useems2 db 0 ; if 0, use EMS
|
||
|
vtabseg dw 0 ; vectab1 segment
|
||
|
vtaboff dw 0 ; vectab1 offset
|
||
|
|
||
|
errmsg2 db 'spawn error',0Dh,0Ah
|
||
|
msglen2 EQU $-errmsg2
|
||
|
|
||
|
;
|
||
|
; int _xspawn( char *, char *, char *, VECTOR *, int, int, char *, int );
|
||
|
;
|
||
|
|
||
|
PUBLIC __xspawn
|
||
|
IFDEF LCODE
|
||
|
__xspawn PROC far
|
||
|
ELSE
|
||
|
__xspawn PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
push di ; preserve register variables
|
||
|
push si
|
||
|
push ds
|
||
|
|
||
|
IFDEF LDATA
|
||
|
lds si,dword ptr [bp+ARG_1]
|
||
|
ELSE
|
||
|
mov si,word ptr [bp+ARG_1]
|
||
|
ENDIF
|
||
|
mov di,offset path
|
||
|
|
||
|
start1: mov al,ds:[si] ; copy path string
|
||
|
mov cs:[di],al ; to code segment
|
||
|
inc si
|
||
|
inc di
|
||
|
or al,al ; null char?
|
||
|
jnz start1 ; no, get next char
|
||
|
|
||
|
IFDEF LDATA
|
||
|
lds si,dword ptr [bp+ARG_1+4]
|
||
|
ELSE
|
||
|
mov si,word ptr [bp+ARG_1+2]
|
||
|
ENDIF
|
||
|
mov bx,si ; preserve si
|
||
|
mov di,offset command
|
||
|
mov cx,2 ; account for count and '\r'
|
||
|
add cl,byte ptr ds:[bx] ; add count byte
|
||
|
|
||
|
start2: mov al,ds:[bx] ; copy command
|
||
|
mov cs:[di],al ; to code segment
|
||
|
inc bx
|
||
|
inc di
|
||
|
loop start2 ; get next char
|
||
|
|
||
|
inc si ; skip count byte
|
||
|
push cs
|
||
|
pop es
|
||
|
mov di,offset fcb5c
|
||
|
mov ax,2901h ; parse filename
|
||
|
int 21h ; skip leading separators
|
||
|
mov di,offset fcb6c
|
||
|
mov al,1 ; parse filename
|
||
|
int 21h ; skip leading separators
|
||
|
|
||
|
IFDEF LDATA
|
||
|
mov ax,word ptr [bp+ARG_1+8]
|
||
|
ELSE
|
||
|
mov ax,word ptr [bp+ARG_1+4]
|
||
|
ENDIF
|
||
|
mov cl,4
|
||
|
shr ax,cl ; convert to paragraphs
|
||
|
IFDEF LDATA
|
||
|
mov bx,word ptr [bp+ARG_1+10]
|
||
|
ELSE
|
||
|
mov bx,ds
|
||
|
ENDIF
|
||
|
add ax,bx
|
||
|
mov cs:[env],ax ; environment segment
|
||
|
|
||
|
IFDEF LDATA
|
||
|
lds bx,dword ptr [bp+ARG_1+12] ; vectab1
|
||
|
ELSE
|
||
|
mov bx,word ptr [bp+ARG_1+6] ; vectab1
|
||
|
ENDIF
|
||
|
mov cs:[vtabseg],ds ; vectab1 segment
|
||
|
mov cs:[vtaboff],bx ; vectab1 offset
|
||
|
|
||
|
mov cs:[stks],ss ; original SS contents
|
||
|
mov cs:[stkp],sp ; original SP contents
|
||
|
mov cs:[rcode],0 ; assume success
|
||
|
|
||
|
IFDEF LDATA
|
||
|
mov ax,word ptr [bp+ARG_1+16]
|
||
|
ELSE
|
||
|
mov ax,word ptr [bp+ARG_1+8]
|
||
|
ENDIF
|
||
|
or ax,ax ; do swap?
|
||
|
jz start3 ; yes, jump
|
||
|
jmp noswap1
|
||
|
|
||
|
IFDEF LDATA
|
||
|
start3: mov ax,word ptr [bp+ARG_1+18]
|
||
|
ELSE
|
||
|
start3: mov ax,word ptr [bp+ARG_1+10]
|
||
|
ENDIF
|
||
|
mov cs:[envlen],ax ; environment length
|
||
|
add ax,offset slidebot - offset slidetop + 30 + 100h
|
||
|
mov cl,4
|
||
|
shr ax,cl ; convert to paragraphs
|
||
|
mov cs:[newsz],ax ; new size
|
||
|
|
||
|
IFDEF LDATA
|
||
|
lds si,dword ptr [bp+ARG_1+20]
|
||
|
ELSE
|
||
|
mov si,word ptr [bp+ARG_1+12]
|
||
|
ENDIF
|
||
|
mov di,offset file
|
||
|
mov cs:[useems2],1 ; assume don't use EMS
|
||
|
cmp byte ptr ds:[si],0
|
||
|
jne start4
|
||
|
mov cs:[useems2],0 ; use EMS
|
||
|
|
||
|
start4: mov al,ds:[si] ; copy file string
|
||
|
mov cs:[di],al ; to code segment
|
||
|
inc si
|
||
|
inc di
|
||
|
or al,al ; null char?
|
||
|
jnz start4 ; no, get next char
|
||
|
|
||
|
; save fnish1 address
|
||
|
|
||
|
mov word ptr cs:[f1add+2],cs
|
||
|
mov word ptr cs:[f1add],offset fnish1
|
||
|
|
||
|
; initialize parameter block
|
||
|
|
||
|
mov ax,cs:[psp] ; PSP segment
|
||
|
mov cs:[cmd],offset command - offset slidetop + 100h
|
||
|
mov cs:[cmd+2],ax
|
||
|
mov cs:[fcb1],offset fcb5c - offset slidetop + 100h
|
||
|
mov cs:[fcb1+2],ax
|
||
|
mov cs:[fcb2],offset fcb6c - offset slidetop + 100h
|
||
|
mov cs:[fcb2+2],ax
|
||
|
|
||
|
cld ; left to right direction
|
||
|
|
||
|
mov ds,ax ; PSP segment
|
||
|
IFDEF LDATA
|
||
|
mov dx,word ptr [bp+ARG_1+24]
|
||
|
ELSE
|
||
|
mov dx,word ptr [bp+ARG_1+14]
|
||
|
ENDIF
|
||
|
IF FHTSZ - 20
|
||
|
cmp word ptr ds:[32h],FHTSZ ; file handle table size
|
||
|
je start5 ; jump if OK
|
||
|
mov cs:[rcode],5
|
||
|
jmp short start6
|
||
|
ENDIF
|
||
|
|
||
|
start5: mov ax,cs:[newsz] ; new size
|
||
|
cmp ax,cs:[ttlsz] ; new size < total size?
|
||
|
jb start8 ; yes, jump
|
||
|
mov cs:[rcode],7 ; extremely unlikely
|
||
|
|
||
|
start6: cmp cs:[useems2],0
|
||
|
jne start7 ; jump if don't use EMS
|
||
|
jmp fnish2
|
||
|
|
||
|
start7: mov bx,dx ; file handle
|
||
|
jmp fnish6
|
||
|
|
||
|
start8: cmp cs:[useems2],0
|
||
|
jne start12 ; jump if don't use EMS
|
||
|
mov cs:[useems],0 ; use EMS
|
||
|
mov cs:[handle],dx ; EMS handle
|
||
|
mov es,cs:[emsseg] ; EMS page frame segment
|
||
|
xor bx,bx ; logical page number
|
||
|
jmp short start11
|
||
|
|
||
|
start9: sub cs:[cntl],cx
|
||
|
sbb cs:[cnth],0
|
||
|
call mapems
|
||
|
or ah,ah
|
||
|
jz start10 ; jump if map succeeded
|
||
|
jmp fnish2
|
||
|
|
||
|
start10: mov si,100h
|
||
|
xor di,di
|
||
|
shr cx,1 ; translate to word count
|
||
|
rep movsw ; CF set if one byte left over
|
||
|
adc cx,cx ; CX = 1 or 0, depending CF
|
||
|
rep movsb ; possible final byte
|
||
|
inc bx ; logical page number
|
||
|
mov ax,ds
|
||
|
add ax,1024 ; 16384 bytes
|
||
|
mov ds,ax
|
||
|
|
||
|
start11: mov cx,16384 ; assume copy full block
|
||
|
cmp cs:[cnth],0
|
||
|
jne start9 ; jump if more than full block
|
||
|
cmp cs:[cntl],16384
|
||
|
jae start9 ; jump if at least full block
|
||
|
mov cx,cs:[cntl]
|
||
|
cmp cx,0
|
||
|
jne start9 ; jump if more left to copy
|
||
|
jmp short start17
|
||
|
|
||
|
start12: mov cs:[useems],1 ; don't use EMS
|
||
|
mov bx,dx ; handle
|
||
|
mov dx,100h ; DS:DX segment:offset buffer
|
||
|
mov cx,65520 ; assume write full block
|
||
|
jmp short start16
|
||
|
|
||
|
start13: sub cs:[cntl],cx
|
||
|
sbb cs:[cnth],0
|
||
|
mov ah,40h ; write file
|
||
|
int 21h
|
||
|
jc start14 ; jump if error
|
||
|
cmp ax,cx
|
||
|
je start15 ; jump if all written
|
||
|
|
||
|
start14: mov ah,3Eh ; close file
|
||
|
int 21h
|
||
|
mov cs:[rcode],5
|
||
|
jmp fnish7
|
||
|
|
||
|
start15: mov ax,ds
|
||
|
add ax,4095 ; 65520 bytes
|
||
|
mov ds,ax
|
||
|
|
||
|
start16: cmp cs:[cnth],0
|
||
|
jne start13 ; jump if more than full block
|
||
|
cmp cs:[cntl],65520
|
||
|
jae start13 ; jump if at least full block
|
||
|
mov cx,cs:[cntl]
|
||
|
cmp cx,0
|
||
|
jne start13 ; jump if more left to write
|
||
|
|
||
|
mov ah,3Eh ; close file
|
||
|
int 21h
|
||
|
IF FHTSZ - 20
|
||
|
|
||
|
; save the file handle table in the kernel
|
||
|
|
||
|
mov es,cs:[psp] ; PSP segment
|
||
|
mov ds,es:[36h] ; file handle table segment
|
||
|
mov si,es:[34h] ; file handle table offset
|
||
|
push cs
|
||
|
pop es
|
||
|
mov di,offset fhtsv ; file handle table save
|
||
|
mov cx,FHTSZ ; file handle table size
|
||
|
rep movsb
|
||
|
ENDIF
|
||
|
|
||
|
start17: mov cx,cs
|
||
|
mov dx,offset handler ; interrupt handler offset
|
||
|
call safevect ; set vectors in vectab1
|
||
|
|
||
|
; time to copy the kernel
|
||
|
|
||
|
mov es,cs:[psp] ; PSP segment
|
||
|
mov di,100h
|
||
|
mov ds,cx ; DS = CS
|
||
|
mov si,offset slidetop
|
||
|
mov cx,offset slidebot - offset slidetop
|
||
|
shr cx,1 ; translate to word count
|
||
|
rep movsw ; CF set if one byte left over
|
||
|
adc cx,cx ; CX = 1 or 0, depending CF
|
||
|
rep movsb ; possible final byte
|
||
|
|
||
|
mov word ptr cs:[s1add+2],es ; PSP segment
|
||
|
index = offset slide1 - offset slidetop + 100h
|
||
|
mov word ptr cs:[s1add],index ; slide1 offset
|
||
|
|
||
|
mov cx,es ; PSP segment
|
||
|
index = offset handler - offset slidetop + 100h
|
||
|
mov dx,index ; interrupt handler offset
|
||
|
call safevect ; set vectors in vectab1
|
||
|
|
||
|
jmp dword ptr cs:[s1add] ; jump to the kernel
|
||
|
|
||
|
; If all goes well, this is where we come back to from the kernel.
|
||
|
|
||
|
fnish1: mov cs:[rcode],ax ; return code
|
||
|
|
||
|
cli ; restore original stack
|
||
|
mov ss,cs:[stks]
|
||
|
mov sp,cs:[stkp]
|
||
|
sti
|
||
|
|
||
|
push ds ; maybe EMS page frame segment
|
||
|
push dx ; maybe EMS handle
|
||
|
push bx ; maybe swap file handle
|
||
|
mov cx,cs
|
||
|
mov dx,offset handler ; interrupt handler offset
|
||
|
call safevect ; set vectors in vectab1
|
||
|
pop bx
|
||
|
pop dx
|
||
|
pop ds
|
||
|
|
||
|
cmp cs:[useems2],0
|
||
|
jne fnish4 ; jump if don't use EMS
|
||
|
|
||
|
; DS = EMS page frame segment
|
||
|
; DX = EMS handle
|
||
|
|
||
|
mov cx,offset slidebot - offset slidetop
|
||
|
mov es,cs:[psp] ; PSP segment
|
||
|
mov di,100h
|
||
|
xor si,si
|
||
|
xor bx,bx ; logical page number
|
||
|
call mapems
|
||
|
or ah,ah
|
||
|
jnz fnish3 ; jump if map failed
|
||
|
shr cx,1 ; translate to word count
|
||
|
rep movsw ; CF set if one byte left over
|
||
|
adc cx,cx ; CX = 1 or 0, depending CF
|
||
|
rep movsb ; possible final byte
|
||
|
|
||
|
fnish2: mov ah,45h ; release handle and memory
|
||
|
int 67h
|
||
|
cmp ah,82h ; memory manager busy?
|
||
|
je fnish2 ; jump if busy
|
||
|
jmp short fnish7
|
||
|
|
||
|
fnish3: mov ah,45h ; release handle and memory
|
||
|
int 67h
|
||
|
cmp ah,82h ; memory manager busy?
|
||
|
je fnish3 ; jump if busy
|
||
|
jmp short fnish5 ; exit
|
||
|
|
||
|
; BX = swap file handle
|
||
|
|
||
|
fnish4: xor cx,cx ; offset 0
|
||
|
xor dx,dx ; offset 0
|
||
|
mov ax,4200h ; move file pointer
|
||
|
int 21h ; from beginning of file
|
||
|
|
||
|
mov cx,offset slidebot - offset slidetop
|
||
|
mov ds,cs:[psp] ; PSP segment
|
||
|
mov dx,100h
|
||
|
mov ah,3Fh ; read file
|
||
|
int 21h
|
||
|
jc fnish5 ; exit if error
|
||
|
cmp ax,cx
|
||
|
je fnish6
|
||
|
|
||
|
fnish5: push cs
|
||
|
pop ds
|
||
|
mov dx,offset errmsg2
|
||
|
mov cx,msglen2 ; errmsg2 length
|
||
|
mov bx,2 ; standard error device handle
|
||
|
mov ah,40h ; write error message
|
||
|
int 21h
|
||
|
mov ax,4C01h ; terminate with return code
|
||
|
int 21h
|
||
|
|
||
|
fnish6: mov ah,3Eh ; close file
|
||
|
int 21h
|
||
|
push cs
|
||
|
pop ds
|
||
|
mov dx,offset file
|
||
|
mov ah,41h ; delete file
|
||
|
int 21h
|
||
|
|
||
|
fnish7: pop ds
|
||
|
pop si ; restore register variables
|
||
|
pop di
|
||
|
pop bp
|
||
|
|
||
|
mov ax,cs:[rcode] ; return code
|
||
|
or ax,ax
|
||
|
jz fnish11
|
||
|
push ax
|
||
|
mov ax,3000h ; get DOS version number
|
||
|
int 21h
|
||
|
cmp al,3 ; major version number
|
||
|
pop ax
|
||
|
jb fnish8
|
||
|
cmp al,34 ; unknown error - 3.0
|
||
|
jae fnish9
|
||
|
cmp al,32 ; sharing violation
|
||
|
jb fnish8
|
||
|
mov al,5 ; access denied
|
||
|
jmp short fnish10
|
||
|
|
||
|
fnish8: cmp al,19 ; unknown error - 2.0
|
||
|
jbe fnish10
|
||
|
|
||
|
fnish9: mov al,19 ; unknown error - 2.0
|
||
|
|
||
|
fnish10: xor ah,ah
|
||
|
|
||
|
fnish11: ret
|
||
|
|
||
|
; If we are not swapping, we jump here.
|
||
|
|
||
|
noswap1: mov ax,cs
|
||
|
|
||
|
; initialize parameter block
|
||
|
|
||
|
mov bx,cs:[env]
|
||
|
mov cs:[environ],bx
|
||
|
mov cs:[cmd],offset command
|
||
|
mov cs:[cmd+2],ax
|
||
|
mov cs:[fcb1],offset fcb5c
|
||
|
mov cs:[fcb1+2],ax
|
||
|
mov cs:[fcb2],offset fcb6c
|
||
|
mov cs:[fcb2+2],ax
|
||
|
|
||
|
; save 4 bytes destroyed by DOS 2.0 at DS:2Eh
|
||
|
|
||
|
mov si,cs:[2Eh]
|
||
|
mov word ptr cs:[save],si
|
||
|
mov si,cs:[30h]
|
||
|
mov word ptr cs:[save+2],si
|
||
|
|
||
|
mov cx,cs
|
||
|
mov dx,offset handler ; interrupt handler offset
|
||
|
call safevect ; set vectors in vectab1
|
||
|
|
||
|
mov es,cx ; ES = CS
|
||
|
mov bx,offset parmblk
|
||
|
mov ds,cx ; DS = CS
|
||
|
mov dx,offset path
|
||
|
mov ax,4B00h ; load and execute program
|
||
|
int 21h
|
||
|
jnc noswap2 ; jump if no error
|
||
|
mov cs:[rcode],ax ; return code
|
||
|
|
||
|
noswap2: cli ; restore original stack
|
||
|
mov ss,cs:[stks]
|
||
|
mov sp,cs:[stkp]
|
||
|
sti
|
||
|
|
||
|
; restore 4 bytes destroyed by DOS 2.0 at DS:2Eh
|
||
|
|
||
|
mov si,word ptr cs:[save]
|
||
|
mov cs:[2Eh],si
|
||
|
mov si,word ptr cs:[save+2]
|
||
|
mov cs:[30h],si
|
||
|
|
||
|
jmp fnish7
|
||
|
|
||
|
__xspawn ENDP
|
||
|
|
||
|
mapems PROC near
|
||
|
|
||
|
; DX = handle
|
||
|
; BX = logical page number
|
||
|
|
||
|
xor al,al ; physical page number
|
||
|
|
||
|
map1: mov ah,44h ; map memory
|
||
|
int 67h
|
||
|
cmp ah,82h ; memory manager busy?
|
||
|
je map1 ; jump if busy
|
||
|
|
||
|
ret
|
||
|
|
||
|
mapems ENDP
|
||
|
|
||
|
setvectsub PROC near
|
||
|
|
||
|
; ES = vector table segment
|
||
|
; BX = vector table offset
|
||
|
|
||
|
mov ah,25h ; set interrupt vector
|
||
|
|
||
|
setvectsub1: mov al,es:[bx+flag] ; 0-CURRENT,1-IRET,2-free,3-end
|
||
|
cmp al,3 ; is it the end?
|
||
|
je setvectsub3 ; yes, jump
|
||
|
cmp al,2 ; is it free?
|
||
|
je setvectsub2 ; yes, jump
|
||
|
mov al,es:[bx+number] ; vector number
|
||
|
mov ds,es:[bx+vseg] ; vector segment
|
||
|
mov dx,es:[bx+voff] ; vector offset
|
||
|
int 21h ; set interrupt vector
|
||
|
|
||
|
setvectsub2: add bx,6 ; size of vector structure
|
||
|
jmp setvectsub1 ; next
|
||
|
|
||
|
setvectsub3: ret
|
||
|
|
||
|
setvectsub ENDP
|
||
|
|
||
|
safevect PROC near
|
||
|
|
||
|
; CX = handler segment
|
||
|
; DX = handler offset
|
||
|
|
||
|
mov es,cs:[vtabseg] ; vectab1 segment
|
||
|
mov bx,cs:[vtaboff] ; vectab1 offset
|
||
|
|
||
|
safevect1: mov al,es:[bx+flag] ; 0-CURRENT,1-IRET,2-free,3-end
|
||
|
cmp al,3 ; is it the end?
|
||
|
je safevect3 ; yes, jump
|
||
|
cmp al,1 ; is it IRET?
|
||
|
jne safevect2 ; no, jump
|
||
|
mov es:[bx+vseg],cx ; handler segment
|
||
|
mov es:[bx+voff],dx ; handler offset
|
||
|
|
||
|
safevect2: add bx,6 ; size of vector structure
|
||
|
jmp safevect1 ; next
|
||
|
|
||
|
safevect3: mov bx,cs:[vtaboff] ; vectab1 offset
|
||
|
call setvectsub
|
||
|
|
||
|
ret
|
||
|
|
||
|
safevect ENDP
|
||
|
|
||
|
;
|
||
|
; int _xsize( unsigned int, long *, long * );
|
||
|
;
|
||
|
|
||
|
PUBLIC __xsize
|
||
|
IFDEF LCODE
|
||
|
__xsize PROC far
|
||
|
ELSE
|
||
|
__xsize PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
push di ; preserve register variables
|
||
|
push si
|
||
|
push ds
|
||
|
|
||
|
mov cs:[last],0 ; assume last block swap
|
||
|
mov bx,word ptr [bp+ARG_1] ; PSP segment
|
||
|
mov cs:[psp],bx
|
||
|
mov dx,bx
|
||
|
dec bx ; program arena header
|
||
|
|
||
|
size1: mov es,bx ; current arena header
|
||
|
mov ax,es:[own]
|
||
|
or ax,ax ; is it free?
|
||
|
jz size2 ; yes, count it
|
||
|
cmp ax,dx ; do we own it?
|
||
|
jne size4 ; no, jump
|
||
|
mov cx,bx ; last owned block
|
||
|
|
||
|
size2: inc bx
|
||
|
add bx,es:[siz] ; block size
|
||
|
jc size3 ; carry, arena is trashed
|
||
|
mov al,es:[sig] ; get arena signature
|
||
|
cmp al,'M' ; are we at end of memory?
|
||
|
je size1 ; no, jump
|
||
|
cmp al,'Z'
|
||
|
je size5
|
||
|
|
||
|
size3: mov bx,-1 ; request maximum memory
|
||
|
mov ah,48h ; allocate memory block
|
||
|
int 21h
|
||
|
mov cs:[rcode],7
|
||
|
jmp fnish7
|
||
|
|
||
|
size4: mov cs:[last],1 ; not last block swap
|
||
|
|
||
|
size5: sub bx,dx ; subtract PSP segment
|
||
|
mov ax,cx ; last owned block
|
||
|
mov es,cx
|
||
|
inc ax
|
||
|
add ax,es:[siz] ; block size
|
||
|
sub ax,dx ; subtract PSP segment
|
||
|
mov cs:[parsz],ax ; parent size
|
||
|
sub ax,10h ; subtract PSP size
|
||
|
xor dx,dx ; convert to bytes
|
||
|
mov cx,4
|
||
|
|
||
|
size6: shl ax,1
|
||
|
rcl dx,1
|
||
|
loop size6
|
||
|
IFDEF LDATA
|
||
|
lds si,dword ptr [bp+ARG_1+2]
|
||
|
ELSE
|
||
|
mov si,word ptr [bp+ARG_1+2]
|
||
|
ENDIF
|
||
|
mov ds:[si],ax ; swap size requirement
|
||
|
mov ds:[si+2],dx
|
||
|
mov cs:[cntl],ax ; count low
|
||
|
mov cs:[cnth],dx ; count high
|
||
|
mov cx,offset slidebot - offset slidetop
|
||
|
sub ax,cx
|
||
|
sbb dx,0
|
||
|
mov cs:[cntsvl],ax ; count save low
|
||
|
mov cs:[cntsvh],dx ; count save high
|
||
|
mov cs:[ttlsz],bx ; total size
|
||
|
xor dx,dx ; convert to bytes
|
||
|
mov cx,4
|
||
|
|
||
|
size7: shl bx,1
|
||
|
rcl dx,1
|
||
|
loop size7
|
||
|
IFDEF LDATA
|
||
|
lds si,dword ptr [bp+ARG_1+6]
|
||
|
ELSE
|
||
|
mov si,word ptr [bp+ARG_1+4]
|
||
|
ENDIF
|
||
|
mov ds:[si],bx ; parent and free memory
|
||
|
mov ds:[si+2],dx
|
||
|
|
||
|
pop ds
|
||
|
pop si ; restore register variables
|
||
|
pop di
|
||
|
pop bp
|
||
|
xor ax,ax
|
||
|
ret
|
||
|
|
||
|
__xsize ENDP
|
||
|
|
||
|
;
|
||
|
; int _chkems( char *, int * );
|
||
|
;
|
||
|
|
||
|
PUBLIC __chkems
|
||
|
IFDEF LCODE
|
||
|
__chkems PROC far
|
||
|
ELSE
|
||
|
__chkems PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
|
||
|
; determine whether expanded memory is available
|
||
|
|
||
|
IFDEF LDATA
|
||
|
push ds
|
||
|
lds dx,dword ptr [bp+ARG_1] ; EMM device driver name
|
||
|
ELSE
|
||
|
mov dx,word ptr [bp+ARG_1] ; EMM device driver name
|
||
|
ENDIF
|
||
|
mov ax,3D00h ; open file read only
|
||
|
int 21h
|
||
|
IFDEF LDATA
|
||
|
pop ds
|
||
|
ENDIF
|
||
|
jc check2 ; expanded memory unavailable
|
||
|
|
||
|
; determine whether we opened the EMM device driver or a file
|
||
|
|
||
|
mov bx,ax ; handle
|
||
|
mov ax,4400h ; IOCTL - get device info
|
||
|
int 21h
|
||
|
jc check1 ; expanded memory unavailable
|
||
|
test dx,80h ; test bit 7
|
||
|
jz check1 ; expanded memory unavailable
|
||
|
|
||
|
mov ax,4407h ; IOCTL - get output status
|
||
|
int 21h
|
||
|
jc check1 ; expanded memory unavailable
|
||
|
or al,al
|
||
|
jz check1 ; expanded memory unavailable
|
||
|
|
||
|
; close EMM device driver to reclaim handle
|
||
|
|
||
|
mov ah,3Eh ; close file
|
||
|
int 21h
|
||
|
|
||
|
; determine whether the EMM is functional
|
||
|
|
||
|
mov ah,40h ; get manager status
|
||
|
int 67h
|
||
|
or ah,ah
|
||
|
jnz check2 ; expanded memory unavailable
|
||
|
|
||
|
; check EMM version
|
||
|
|
||
|
mov ah,46h ; get EMM version
|
||
|
int 67h
|
||
|
or ah,ah
|
||
|
jnz check2 ; expanded memory unavailable
|
||
|
cmp al,32h ; version 3.2
|
||
|
jb check2 ; expanded memory unavailable
|
||
|
|
||
|
; get page frame segment
|
||
|
|
||
|
mov ah,41h ; get page frame segment
|
||
|
int 67h
|
||
|
or ah,ah
|
||
|
jnz check2 ; expanded memory unavailable
|
||
|
mov cs:[emsseg],bx ; segment
|
||
|
|
||
|
; get size of page map information
|
||
|
|
||
|
mov ax,4E03h ; get size of page map info
|
||
|
int 67h
|
||
|
or ah,ah
|
||
|
jnz check2 ; expanded memory unavailable
|
||
|
IFDEF LDATA
|
||
|
les bx,dword ptr [bp+ARG_1+4] ; mapsize address
|
||
|
mov es:[bx],ax
|
||
|
ELSE
|
||
|
mov bx,word ptr [bp+ARG_1+2] ; mapsize address
|
||
|
mov ds:[bx],ax
|
||
|
ENDIF
|
||
|
xor ax,ax ; expanded memory available
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
; close EMM device driver or file to reclaim handle
|
||
|
|
||
|
check1: mov ah,3Eh ; close file
|
||
|
int 21h
|
||
|
|
||
|
check2: mov ax,1 ; expanded memory unavailable
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__chkems ENDP
|
||
|
|
||
|
;
|
||
|
; int _savemap( char * );
|
||
|
;
|
||
|
|
||
|
PUBLIC __savemap
|
||
|
IFDEF LCODE
|
||
|
__savemap PROC far
|
||
|
ELSE
|
||
|
__savemap PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
push di ; preserve register variable
|
||
|
|
||
|
IFDEF LDATA
|
||
|
les di,dword ptr [bp+ARG_1] ; buffer address
|
||
|
ELSE
|
||
|
mov di,word ptr [bp+ARG_1] ; buffer address
|
||
|
push ds
|
||
|
pop es
|
||
|
ENDIF
|
||
|
mov ax,4E00h ; save page map
|
||
|
int 67h
|
||
|
|
||
|
pop di ; restore register variable
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__savemap ENDP
|
||
|
|
||
|
;
|
||
|
; int _restmap( char * );
|
||
|
;
|
||
|
|
||
|
PUBLIC __restmap
|
||
|
IFDEF LCODE
|
||
|
__restmap PROC far
|
||
|
ELSE
|
||
|
__restmap PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
push ds
|
||
|
push si ; preserve register variable
|
||
|
|
||
|
IFDEF LDATA
|
||
|
lds si,dword ptr [bp+ARG_1] ; buffer address
|
||
|
ELSE
|
||
|
mov si,word ptr [bp+ARG_1] ; buffer address
|
||
|
ENDIF
|
||
|
mov ax,4E01h ; restore page map
|
||
|
int 67h
|
||
|
xor al,al
|
||
|
|
||
|
pop si ; restore register variable
|
||
|
pop ds
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__restmap ENDP
|
||
|
|
||
|
;
|
||
|
; int _getems( int, int * );
|
||
|
;
|
||
|
|
||
|
PUBLIC __getems
|
||
|
IFDEF LCODE
|
||
|
__getems PROC far
|
||
|
ELSE
|
||
|
__getems PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
|
||
|
mov bx,word ptr [bp+ARG_1] ; number of pages
|
||
|
mov ah,43h ; get handle and allocate
|
||
|
; memory
|
||
|
int 67h
|
||
|
IFDEF LDATA
|
||
|
les bx,dword ptr [bp+ARG_1+2] ; handle address
|
||
|
mov es:[bx],dx ; handle
|
||
|
ELSE
|
||
|
mov bx,word ptr [bp+ARG_1+2] ; handle address
|
||
|
mov ds:[bx],dx ; handle
|
||
|
ENDIF
|
||
|
xor al,al
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__getems ENDP
|
||
|
|
||
|
;
|
||
|
; int _dskspace( int, unsigned int *, unsigned int * );
|
||
|
;
|
||
|
|
||
|
PUBLIC __dskspace
|
||
|
IFDEF LCODE
|
||
|
__dskspace PROC far
|
||
|
ELSE
|
||
|
__dskspace PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
push di ; preserve register variable
|
||
|
|
||
|
mov ah,36h ; get free disk space
|
||
|
mov dl,byte ptr [bp+ARG_1] ; drive code (0=default, 1=A)
|
||
|
int 21h
|
||
|
cmp ax,0FFFFh ; was drive invalid?
|
||
|
je space1 ; yes, jump
|
||
|
mul cx ; bytes per sector *
|
||
|
; sectors per cluster
|
||
|
IFDEF LDATA
|
||
|
les di,dword ptr [bp+ARG_1+2]
|
||
|
mov es:[di],ax ; bytes per cluster
|
||
|
ELSE
|
||
|
mov di,word ptr [bp+ARG_1+2]
|
||
|
mov ds:[di],ax ; bytes per cluster
|
||
|
ENDIF
|
||
|
IFDEF LDATA
|
||
|
les di,dword ptr [bp+ARG_1+6]
|
||
|
mov es:[di],bx ; number of available clusters
|
||
|
ELSE
|
||
|
mov di,word ptr [bp+ARG_1+4]
|
||
|
mov ds:[di],bx ; number of available clusters
|
||
|
ENDIF
|
||
|
xor ax,ax
|
||
|
|
||
|
space1: pop di ; restore register variable
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__dskspace ENDP
|
||
|
|
||
|
;
|
||
|
; int _getrc( void );
|
||
|
;
|
||
|
|
||
|
PUBLIC __getrc
|
||
|
IFDEF LCODE
|
||
|
__getrc PROC far
|
||
|
ELSE
|
||
|
__getrc PROC near
|
||
|
ENDIF
|
||
|
|
||
|
mov ah,4Dh ; get child return code
|
||
|
int 21h
|
||
|
|
||
|
ret
|
||
|
|
||
|
__getrc ENDP
|
||
|
|
||
|
;
|
||
|
; int _create( char *, int * );
|
||
|
;
|
||
|
|
||
|
PUBLIC __create
|
||
|
IFDEF LCODE
|
||
|
__create PROC far
|
||
|
ELSE
|
||
|
__create PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
IFDEF LDATA
|
||
|
push ds
|
||
|
ENDIF
|
||
|
|
||
|
mov ax,3000h ; get DOS version number
|
||
|
int 21h
|
||
|
IFDEF LDATA
|
||
|
lds dx,dword ptr [bp+ARG_1] ; file
|
||
|
ELSE
|
||
|
mov dx,word ptr [bp+ARG_1] ; file
|
||
|
ENDIF
|
||
|
xor cx,cx ; normal attribute
|
||
|
mov ah,5Bh ; create new file
|
||
|
cmp al,3 ; major version number
|
||
|
jae create1
|
||
|
mov ah,3Ch ; create file
|
||
|
|
||
|
create1: int 21h
|
||
|
jc create2
|
||
|
IFDEF LDATA
|
||
|
lds bx,dword ptr [bp+ARG_1+4] ; handle address
|
||
|
ELSE
|
||
|
mov bx,word ptr [bp+ARG_1+2] ; handle address
|
||
|
ENDIF
|
||
|
mov ds:[bx],ax
|
||
|
xor ax,ax
|
||
|
|
||
|
create2:
|
||
|
IFDEF LDATA
|
||
|
pop ds
|
||
|
ENDIF
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__create ENDP
|
||
|
|
||
|
|
||
|
;
|
||
|
; int _getcd( int, char * );
|
||
|
;
|
||
|
|
||
|
|
||
|
PUBLIC __getcd
|
||
|
IFDEF LCODE
|
||
|
__getcd PROC far
|
||
|
ELSE
|
||
|
__getcd PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
push si ; preserve register variable
|
||
|
IFDEF LDATA
|
||
|
push ds
|
||
|
ENDIF
|
||
|
|
||
|
mov dl,byte ptr [bp+ARG_1] ; drive code (0=default, 1=A)
|
||
|
IFDEF LDATA
|
||
|
lds si,dword ptr [bp+ARG_1+2] ; buffer
|
||
|
ELSE
|
||
|
mov si,word ptr [bp+ARG_1+2] ; buffer
|
||
|
ENDIF
|
||
|
mov ah,47h ; get current directory
|
||
|
int 21h
|
||
|
jc getcd1
|
||
|
xor ax,ax
|
||
|
|
||
|
getcd1:
|
||
|
IFDEF LDATA
|
||
|
pop ds
|
||
|
ENDIF
|
||
|
pop si ; restore register variable
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__getcd ENDP
|
||
|
|
||
|
;
|
||
|
; int _getdrv( void );
|
||
|
;
|
||
|
|
||
|
PUBLIC __getdrv
|
||
|
IFDEF LCODE
|
||
|
__getdrv PROC far
|
||
|
ELSE
|
||
|
__getdrv PROC near
|
||
|
ENDIF
|
||
|
|
||
|
mov ah,19h ; get default disk drive
|
||
|
int 21h
|
||
|
xor ah,ah
|
||
|
|
||
|
; AX = drive (0 = A, 1 = B, etc.)
|
||
|
|
||
|
ret
|
||
|
|
||
|
__getdrv ENDP
|
||
|
|
||
|
;
|
||
|
; void _getvect( int, unsigned int *, unsigned int * );
|
||
|
;
|
||
|
|
||
|
PUBLIC __getvect
|
||
|
IFDEF LCODE
|
||
|
__getvect PROC far
|
||
|
ELSE
|
||
|
__getvect PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
push ds
|
||
|
push si ; preserve register variable
|
||
|
|
||
|
mov ah,35h ; get interrupt vector
|
||
|
mov al,byte ptr [bp+ARG_1] ; interrupt number
|
||
|
int 21h
|
||
|
IFDEF LDATA
|
||
|
lds si,dword ptr [bp+ARG_1+2]
|
||
|
ELSE
|
||
|
mov si,word ptr [bp+ARG_1+2]
|
||
|
ENDIF
|
||
|
mov ds:[si],es ; segment
|
||
|
IFDEF LDATA
|
||
|
lds si,dword ptr [bp+ARG_1+6]
|
||
|
ELSE
|
||
|
mov si,word ptr [bp+ARG_1+4]
|
||
|
ENDIF
|
||
|
mov ds:[si],bx ; offset
|
||
|
|
||
|
pop si ; restore register variable
|
||
|
pop ds
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__getvect ENDP
|
||
|
|
||
|
;
|
||
|
; void _setvect( VECTOR * );
|
||
|
;
|
||
|
|
||
|
PUBLIC __setvect
|
||
|
IFDEF LCODE
|
||
|
__setvect PROC far
|
||
|
ELSE
|
||
|
__setvect PROC near
|
||
|
ENDIF
|
||
|
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
push ds ; modified in setvectsub
|
||
|
|
||
|
IFDEF LDATA
|
||
|
les bx,dword ptr [bp+ARG_1] ; vector table
|
||
|
ELSE
|
||
|
mov bx,word ptr [bp+ARG_1] ; vector table
|
||
|
push ds
|
||
|
pop es
|
||
|
ENDIF
|
||
|
|
||
|
call setvectsub
|
||
|
|
||
|
pop ds
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__setvect ENDP
|
||
|
|
||
|
|
||
|
;
|
||
|
; void _setdrvcd(int drive, char * string);
|
||
|
;
|
||
|
|
||
|
PUBLIC __setdrvcd
|
||
|
IFDEF LCODE
|
||
|
__setdrvcd PROC far
|
||
|
ELSE
|
||
|
__setdrvcd PROC near
|
||
|
ENDIF
|
||
|
push bp
|
||
|
mov bp,sp
|
||
|
IFDEF LDATA
|
||
|
push ds
|
||
|
ENDIF
|
||
|
mov dl,byte ptr [bp+ARG_1] ; drive code (0=A, 1=B)
|
||
|
mov ah,0eh
|
||
|
int 21h
|
||
|
IFDEF LDATA
|
||
|
lds dx,dword ptr [bp+ARG_1+2] ; buffer
|
||
|
ELSE
|
||
|
mov dx,word ptr [bp+ARG_1+2] ; buffer
|
||
|
ENDIF
|
||
|
mov ah,3bh ; set current directory
|
||
|
int 21h
|
||
|
|
||
|
IFDEF LDATA
|
||
|
pop ds
|
||
|
ENDIF
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
__setdrvcd ENDP
|
||
|
|
||
|
_TEXT ENDS
|
||
|
|
||
|
END
|
||
|
|