mirror of
https://github.com/Microsoft/MS-DOS.git
synced 2025-08-14 10:47:14 -07:00
MS-DOS v2.0 Release
This commit is contained in:
parent
fce0f75959
commit
80ab2fddfd
156 changed files with 56403 additions and 0 deletions
514
v2.0/source/EXE2BIN.ASM
Normal file
514
v2.0/source/EXE2BIN.ASM
Normal file
|
@ -0,0 +1,514 @@
|
|||
title LOCATE (EXE2BIN)
|
||||
|
||||
;Loader for EXE files under 86-DOS
|
||||
|
||||
;The following switch allows use with the "old linker", which put a version
|
||||
;number where the new linker puts the number of bytes used in the last page.
|
||||
;If enabled, this will cause a test for 0004 at this location (the old linker
|
||||
;version number), and if equal, change it to 200H so all of the last page
|
||||
;will be used.
|
||||
|
||||
;VER. 1.5
|
||||
; 05/21/82 Added rev number
|
||||
;
|
||||
;VER. 1.6
|
||||
; 07/01/82 A little less choosy about size matches
|
||||
;
|
||||
;VER. 2.0 Rev. 1 M.A.Ulloa
|
||||
; 10/08/82 Modified to use new 2.0 system calls for file i/o
|
||||
;
|
||||
; Rev. 2 M.A.Ulloa
|
||||
; 10/27/82 Added the DOS version check
|
||||
|
||||
FALSE EQU 0
|
||||
TRUE EQU NOT FALSE
|
||||
|
||||
OLDLINK EQU 0 ;1 to enable, 0 to disable
|
||||
|
||||
.xlist
|
||||
INCLUDE DOSSYM.ASM
|
||||
.list
|
||||
|
||||
|
||||
subttl Main Code Area
|
||||
page
|
||||
|
||||
|
||||
code segment byte
|
||||
code ends
|
||||
|
||||
DATA SEGMENT PUBLIC BYTE
|
||||
|
||||
|
||||
EXTRN bad_vers_err:BYTE,NOTFND:BYTE,NOROOM:BYTE,DIRFULL:BYTE
|
||||
EXTRN CANTFIX:BYTE,RDBAD:BYTE,FULL:BYTE,PROMPT:BYTE,CRLF:BYTE
|
||||
|
||||
make db "MAUlloa/Microsoft/V20"
|
||||
rev db "2"
|
||||
|
||||
file1_ext db ".EXE",00h
|
||||
file2_ext db ".BIN",00h
|
||||
|
||||
per1 db 0
|
||||
per2 db 0
|
||||
|
||||
file1 db 64 dup(?)
|
||||
handle1 dw 1 dup(?)
|
||||
|
||||
file2 db 64 dup(?)
|
||||
handle2 dw 1 dup(?)
|
||||
|
||||
|
||||
INBUF DB 5,0
|
||||
DB 5 DUP(?)
|
||||
|
||||
;The following locations must be defined for storing the header:
|
||||
|
||||
RUNVAR LABEL BYTE ;Start of RUN variables
|
||||
RELPT DW ?
|
||||
LASTP LABEL WORD
|
||||
RELSEG DW ?
|
||||
SIZ LABEL WORD ;Share these locations
|
||||
PAGES DW ?
|
||||
RELCNT DW ?
|
||||
HEADSIZ DW ?
|
||||
DW ?
|
||||
LOADLOW DW ?
|
||||
INITSS DW ?
|
||||
INITSP DW ?
|
||||
DW ?
|
||||
INITIP DW ?
|
||||
INITCS DW ?
|
||||
RELTAB DW ?
|
||||
RUNVARSIZ EQU $-RUNVAR
|
||||
|
||||
DATA ENDS
|
||||
|
||||
STACK SEGMENT WORD STACK
|
||||
DB 80H DUP (?)
|
||||
STACK ENDS
|
||||
|
||||
ZLOAD SEGMENT
|
||||
ZLOAD ENDS
|
||||
LOAD EQU ZLOAD
|
||||
|
||||
CODE SEGMENT BYTE
|
||||
|
||||
ASSUME CS:CODE
|
||||
|
||||
LOCATE PROC FAR
|
||||
JMP SHORT LOCSTRT
|
||||
|
||||
HEADER DB "Vers 2.00"
|
||||
|
||||
LOCSTRT:
|
||||
MOV SI,81H
|
||||
PUSH DS
|
||||
XOR AX,AX
|
||||
PUSH AX ;Push return address to DS:0
|
||||
|
||||
;Code to print header
|
||||
; PUSH DS
|
||||
; MOV DX,DATA
|
||||
; MOV DS,DX
|
||||
; MOV DX,OFFSET HEADER
|
||||
; MOV AH,STD_CON_STRING_OUTPUT
|
||||
; INT 21H
|
||||
; POP DS
|
||||
|
||||
;----- Check Version Number --------------------------------------------;
|
||||
mov ah,Get_Version
|
||||
int 21h
|
||||
cmp al,2
|
||||
jge vers_ok ; version >= 2, enter locate
|
||||
push ds
|
||||
mov dx,data
|
||||
mov ds,dx
|
||||
mov dx,offset bad_vers_err
|
||||
MOV AH,STD_CON_STRING_OUTPUT
|
||||
INT 21H
|
||||
pop ds
|
||||
ret ;long return to DOS
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
vers_ok:
|
||||
|
||||
|
||||
MOV BX,WORD PTR DS:2 ;Get size of memory
|
||||
MOV DX,DATA
|
||||
MOV ES,DX
|
||||
|
||||
assume es:data
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
|
||||
;----- Get the first file name
|
||||
call kill_bl
|
||||
jnc sj01
|
||||
mov ds,dx
|
||||
jmp bad_file
|
||||
sj01:
|
||||
mov di,offset file1
|
||||
sj0:
|
||||
lodsb ;get character of file name
|
||||
cmp al,' '
|
||||
je sj2
|
||||
cmp al,0dh
|
||||
je sj2
|
||||
cmp al,'.' ;an extension separator found?
|
||||
jne sj1
|
||||
mov es:[per1],-1
|
||||
sj1:
|
||||
stosb
|
||||
jmp short sj0
|
||||
sj2:
|
||||
dec si
|
||||
mov byte ptr es:[di],00h ;nul terminate the filename
|
||||
call kill_bl
|
||||
jc no_second
|
||||
|
||||
;----- Get the second file name
|
||||
mov di,offset file2
|
||||
sj3:
|
||||
lodsb ;get character of file name
|
||||
cmp al,' '
|
||||
je sj5
|
||||
cmp al,0dh
|
||||
je sj5
|
||||
cmp al,'.' ;an extension separator found?
|
||||
jne sj4
|
||||
mov es:[per2],-1
|
||||
sj4:
|
||||
stosb
|
||||
jmp short sj3
|
||||
sj5:
|
||||
mov byte ptr es:[di],00h ;nul terminate
|
||||
jmp short check_ext
|
||||
|
||||
;----- Copy file1 to file2
|
||||
no_second:
|
||||
mov ds,dx
|
||||
|
||||
assume ds:data
|
||||
|
||||
mov si,offset file1
|
||||
mov di,offset file2
|
||||
sj6:
|
||||
lodsb
|
||||
cmp al,'.'
|
||||
je sj7
|
||||
cmp al,00h
|
||||
je sj7
|
||||
stosb
|
||||
jmp short sj6
|
||||
sj7:
|
||||
mov byte ptr [di],00h
|
||||
|
||||
;----- Check that files have an extension, otherwise set default
|
||||
check_ext:
|
||||
mov ds,dx
|
||||
|
||||
assume ds:data
|
||||
|
||||
cmp [per1],-1
|
||||
je file1_ok
|
||||
mov si,offset file1
|
||||
sj8:
|
||||
lodsb
|
||||
cmp al,00h
|
||||
jne sj8
|
||||
mov di,si
|
||||
mov si,offset file1_ext
|
||||
call put_ext
|
||||
|
||||
file1_ok:
|
||||
cmp [per2],-1
|
||||
je file2_ok
|
||||
mov si,offset file2
|
||||
sj9:
|
||||
lodsb
|
||||
cmp al,00h
|
||||
jne sj9
|
||||
mov di,si
|
||||
mov si,offset file2_ext
|
||||
call put_ext
|
||||
jmp short file2_ok
|
||||
|
||||
;----- Fill in the default extent
|
||||
put_ext proc near
|
||||
dec di
|
||||
mov cx,5 ;move extent: period,extent,null
|
||||
rep movsb
|
||||
ret
|
||||
put_ext endp
|
||||
|
||||
;----- Find the first non-blank
|
||||
kill_bl proc near
|
||||
cld
|
||||
sj10:
|
||||
lodsb
|
||||
cmp al,' '
|
||||
je sj10
|
||||
dec si
|
||||
cmp al,0dh
|
||||
clc
|
||||
jne sj11
|
||||
stc
|
||||
sj11:
|
||||
ret
|
||||
kill_bl endp
|
||||
|
||||
file2_ok:
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
|
||||
mov dx,offset file1
|
||||
mov ah,open
|
||||
mov al,0 ;ror reading only
|
||||
INT 21H ;Open input file
|
||||
jc bad_file
|
||||
mov [handle1],ax
|
||||
jmp exeload
|
||||
|
||||
bad_file:
|
||||
MOV DX,OFFSET NOTFND
|
||||
xERROR:
|
||||
MOV AH,STD_CON_STRING_OUTPUT
|
||||
INT 21H
|
||||
RET ;FAR return to MS-DOS
|
||||
TOOBIG:
|
||||
MOV DX,OFFSET NOROOM
|
||||
JMP xERROR
|
||||
BADEXE:
|
||||
MOV DX,OFFSET CANTFIX
|
||||
ERRORJ: JMP xERROR
|
||||
|
||||
EXELOAD:
|
||||
MOV DX,OFFSET RUNVAR ;Read header in here
|
||||
MOV CX,RUNVARSIZ ;Amount of header info we need
|
||||
push bx
|
||||
mov bx,[handle1]
|
||||
MOV AH,read
|
||||
INT 21H ;Read in header
|
||||
pop bx
|
||||
CMP [RELPT],5A4DH ;Check signature word
|
||||
JNZ BADEXE
|
||||
MOV AX,[HEADSIZ] ;size of header in paragraphs
|
||||
ADD AX,31 ;Round up first
|
||||
CMP AX,1000H ;Must not be >=64K
|
||||
JAE TOOBIG
|
||||
AND AX,NOT 31
|
||||
MOV CL,4
|
||||
SHL AX,CL ;Header size in bytes
|
||||
|
||||
push dx
|
||||
push cx
|
||||
push ax
|
||||
push bx
|
||||
mov dx,ax
|
||||
xor cx,cx
|
||||
mov al,0
|
||||
mov bx,[handle1]
|
||||
mov ah,lseek
|
||||
int 21h
|
||||
pop bx
|
||||
pop ax
|
||||
pop cx
|
||||
pop dx
|
||||
|
||||
XCHG AL,AH
|
||||
SHR AX,1 ;Convert to pages
|
||||
MOV DX,[PAGES] ;Total size of file in 512-byte pages
|
||||
SUB DX,AX ;Size of program in pages
|
||||
CMP DX,80H ;Fit in 64K?
|
||||
JAE TOOBIG
|
||||
XCHG DH,DL
|
||||
SHL DX,1 ;Convert pages to bytes
|
||||
MOV AX,[LASTP] ;Get count of bytes in last page
|
||||
OR AX,AX ;If zero, use all of last page
|
||||
JZ WHOLEP
|
||||
|
||||
IF OLDLINK
|
||||
CMP AX,4 ;Produced by old linker?
|
||||
JZ WHOLEP ;If so, use all of last page too
|
||||
ENDIF
|
||||
|
||||
SUB DX,200H ;Subtract last page
|
||||
ADD DX,AX ;Add in byte count for last page
|
||||
WHOLEP:
|
||||
MOV [SIZ],DX
|
||||
ADD DX,15
|
||||
SHR DX,CL ;Convert bytes to paragraphs
|
||||
MOV BP,LOAD
|
||||
ADD DX,BP ;Size + start = minimum memory (paragr.)
|
||||
CMP DX,BX ;Enough memory?
|
||||
JA TOOBIG
|
||||
MOV DX,OFFSET CANTFIX
|
||||
MOV AX,[INITSS]
|
||||
OR AX,[INITSP]
|
||||
OR AX,[INITCS]
|
||||
ERRORNZ:
|
||||
jz xj
|
||||
JMP ERRORJ ;Must not have SS, SP, or CS to init.
|
||||
xj: MOV AX,[INITIP]
|
||||
OR AX,AX ;If IP=0, do binary fix
|
||||
JZ BINFIX
|
||||
CMP AX,100H ;COM file must be set up for CS:100
|
||||
JNZ ERRORNZ
|
||||
|
||||
push dx
|
||||
push cx
|
||||
push ax
|
||||
push bx
|
||||
mov dx,100h ;chop off first 100h
|
||||
xor cx,cx
|
||||
mov al,1 ;seek from current position
|
||||
mov bx,[handle1]
|
||||
mov ah,lseek
|
||||
int 21h
|
||||
pop bx
|
||||
pop ax
|
||||
pop cx
|
||||
pop dx
|
||||
|
||||
SUB [SIZ],AX ;And count decreased size
|
||||
CMP [RELCNT],0 ;Must have no fixups
|
||||
JNZ ERRORNZ
|
||||
BINFIX:
|
||||
XOR BX,BX ;Initialize fixup segment
|
||||
;See if segment fixups needed
|
||||
CMP [RELCNT],0
|
||||
JZ LOADEXE
|
||||
GETSEG:
|
||||
MOV DX,OFFSET PROMPT
|
||||
MOV AH,STD_CON_STRING_OUTPUT
|
||||
INT 21H
|
||||
MOV AH,STD_CON_STRING_INPUT
|
||||
MOV DX,OFFSET INBUF
|
||||
INT 21H ;Get user response
|
||||
MOV DX,OFFSET CRLF
|
||||
MOV AH,STD_CON_STRING_OUTPUT
|
||||
INT 21H
|
||||
MOV SI,OFFSET INBUF+2
|
||||
MOV BYTE PTR [SI-1],0 ;Any digits?
|
||||
JZ GETSEG
|
||||
DIGLP:
|
||||
LODSB
|
||||
SUB AL,"0"
|
||||
JC DIGERR
|
||||
CMP AL,10
|
||||
JB HAVDIG
|
||||
AND AL,5FH ;Convert to upper case
|
||||
SUB AL,7
|
||||
CMP AL,10
|
||||
JB DIGERR
|
||||
CMP AL,10H
|
||||
JAE DIGERR
|
||||
HAVDIG:
|
||||
SHL BX,1
|
||||
SHL BX,1
|
||||
SHL BX,1
|
||||
SHL BX,1
|
||||
OR BL,AL
|
||||
JMP DIGLP
|
||||
|
||||
DIGERR:
|
||||
CMP BYTE PTR [SI-1],0DH ;Is last char. a CR?
|
||||
JNZ GETSEG
|
||||
LOADEXE:
|
||||
XCHG BX,BP ;BX has LOAD, BP has fixup
|
||||
|
||||
MOV CX,[SIZ]
|
||||
MOV AH,read
|
||||
push di
|
||||
mov di,[handle1]
|
||||
PUSH DS
|
||||
MOV DS,BX
|
||||
XOR DX,DX
|
||||
push bx
|
||||
mov bx,di
|
||||
INT 21H ;Read in up to 64K
|
||||
pop bx
|
||||
POP DS
|
||||
pop di
|
||||
Jnc HAVEXE ;Did we get it all?
|
||||
MOV DX,OFFSET RDBAD
|
||||
jmp xERROR ;Non fatal, print warning
|
||||
HAVEXE:
|
||||
CMP [RELCNT],0 ;Any fixups to do?
|
||||
JZ STORE
|
||||
MOV AX,[RELTAB] ;Get position of table
|
||||
|
||||
push dx
|
||||
push cx
|
||||
push ax
|
||||
push bx
|
||||
mov dx,ax
|
||||
xor cx,cx
|
||||
mov al,0
|
||||
mov bx,[handle1]
|
||||
mov ah,lseek
|
||||
int 21h
|
||||
pop bx
|
||||
pop ax
|
||||
pop cx
|
||||
pop dx
|
||||
|
||||
MOV DX,OFFSET RELPT ;4-byte buffer for relocation address
|
||||
RELOC:
|
||||
MOV DX,OFFSET RELPT ;4-byte buffer for relocation address
|
||||
MOV CX,4
|
||||
MOV AH,read
|
||||
push bx
|
||||
mov bx,[handle1]
|
||||
INT 21H ;Read in one relocation pointer
|
||||
pop bx
|
||||
Jnc RDCMP
|
||||
JMP BADEXE
|
||||
RDCMP:
|
||||
MOV DI,[RELPT] ;Get offset of relocation pointer
|
||||
MOV AX,[RELSEG] ;Get segment
|
||||
ADD AX,BX ;Bias segment with actual load segment
|
||||
MOV ES,AX
|
||||
ADD ES:[DI],BP ;Relocate
|
||||
DEC [RELCNT] ;Count off
|
||||
JNZ RELOC
|
||||
STORE:
|
||||
MOV AH,CREAT
|
||||
MOV DX,OFFSET file2
|
||||
xor cx,cx
|
||||
INT 21H
|
||||
Jc MKERR
|
||||
mov [handle2],ax
|
||||
MOV CX,[SIZ]
|
||||
MOV AH,write
|
||||
push di
|
||||
mov di,[handle2]
|
||||
PUSH DS
|
||||
MOV DS,BX
|
||||
XOR DX,DX ;Address 0 in segment
|
||||
push bx
|
||||
mov bx,di
|
||||
INT 21H
|
||||
pop bx
|
||||
POP DS
|
||||
pop di
|
||||
Jc WRTERR ;Must be zero if more to come
|
||||
MOV AH,CLOSE
|
||||
push bx
|
||||
mov bx,[handle2]
|
||||
INT 21H
|
||||
pop bx
|
||||
RET
|
||||
|
||||
WRTERR:
|
||||
MOV DX,OFFSET FULL
|
||||
JMP xERROR
|
||||
MKERR:
|
||||
MOV DX,OFFSET DIRFULL
|
||||
JMP xERROR
|
||||
|
||||
LOCATE ENDP
|
||||
CODE ENDS
|
||||
END LOCATE
|
||||
|