mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-11-29 17:15:47 +00:00
587 lines
22 KiB
NASM
587 lines
22 KiB
NASM
|
TITLE MS-DOS SYS Program
|
|||
|
; SYS - Copies system programs IBMBIO.COM/IO.SYS and IBMDOS.COM/MSDOS.SYS
|
|||
|
; 1.6 05/21/82 Added rev number message
|
|||
|
; 1.61 06/04/82 Allow SYS to blank disk TimP at SCP
|
|||
|
; 1.70 06/30/82 NON contiguous DOS allowed on 2.00 IBM. Allows SYS to
|
|||
|
; 1.0 1.1 disks.
|
|||
|
; 1.71 07/02/82 Put in CHDIRs to make sure everything done in root dir.
|
|||
|
; 1.80 04/26/83 MZ make sys work in small machines; use full 2.0 system
|
|||
|
; calls
|
|||
|
; 1.81 07/22/83 ARR Added check in IBM version for valid FAT ID on
|
|||
|
; destination because of IBM problem with SYSing to
|
|||
|
; unformatted disks which are really formatted.
|
|||
|
; Prints NoDest message for ridic IBM reasons, should
|
|||
|
; have a better message.
|
|||
|
|
|||
|
FALSE EQU 0
|
|||
|
TRUE EQU NOT FALSE
|
|||
|
|
|||
|
IBMJAPVER EQU FALSE
|
|||
|
IBMVER EQU FALSE
|
|||
|
MSVER EQU TRUE
|
|||
|
|
|||
|
.xlist
|
|||
|
.xcref
|
|||
|
INCLUDE DOSSYM.ASM
|
|||
|
.cref
|
|||
|
.list
|
|||
|
|
|||
|
|
|||
|
DOSVER_LOW EQU 0136H ; Lowest acceptable DOS version number
|
|||
|
DOSVER_HIGH EQU 020BH ; Highest acceptable DOS version
|
|||
|
|
|||
|
CODE SEGMENT WORD PUBLIC
|
|||
|
CODE ENDS
|
|||
|
|
|||
|
CONST SEGMENT BYTE PUBLIC
|
|||
|
CONST ENDS
|
|||
|
|
|||
|
DATA SEGMENT BYTE PUBLIC
|
|||
|
DATA ENDS
|
|||
|
|
|||
|
DG GROUP CODE,DATA,CONST
|
|||
|
|
|||
|
DATA SEGMENT PUBLIC BYTE
|
|||
|
|
|||
|
EXTRN BADDRV:BYTE, BADDRVLen:WORD
|
|||
|
EXTRN BADPARM:BYTE, BADPARMLen:WORD
|
|||
|
EXTRN GETSYS:BYTE, GETSYSLen:WORD
|
|||
|
EXTRN SYSDRV:BYTE
|
|||
|
EXTRN NODEST:BYTE, NODESTLen:WORD
|
|||
|
EXTRN BADSIZ:BYTE, BADSIZLen:WORD
|
|||
|
EXTRN DONE:BYTE, DONELen:WORD
|
|||
|
EXTRN BADVER:BYTE
|
|||
|
|
|||
|
IF IBMJAPVER
|
|||
|
EXTRN BADDISK:BYTE, BADDISKLen:WORD
|
|||
|
ENDIF
|
|||
|
|
|||
|
DEFALT DB 0
|
|||
|
IF MSVER
|
|||
|
BIOSName DB "A:\IO.SYS",0
|
|||
|
DOSName DB "A:\MSDOS.SYS",0
|
|||
|
ENDIF
|
|||
|
IF IBMVER OR IBMJAPVER
|
|||
|
BIOSName DB "A:\IBMBIO.COM",0
|
|||
|
DOSName DB "A:\IBMDOS.COM",0
|
|||
|
ENDIF
|
|||
|
|
|||
|
BIOSInFH DW ? ; file handle of source BIOS
|
|||
|
BIOSLenLow DW 2 DUP (?) ; 32-bit length of BIOS
|
|||
|
BIOSLenHigh DW 2 DUP (?) ; 32-bit length of BIOS
|
|||
|
BIOSTime DW 2 DUP (?) ; place to store time of BIOS write
|
|||
|
BIOSOutFH DW ? ; fh of BIOS destination
|
|||
|
|
|||
|
DOSInFH DW ? ; file handle of source DOS
|
|||
|
DOSLenLow DW 2 DUP (?) ; 32-bit length of DOS
|
|||
|
DOSLenHigh DW 2 DUP (?) ; 32-bit length of DOS
|
|||
|
DOSTime DW 2 DUP (?) ; place to store time of DOS write
|
|||
|
DOSOutFH DW ? ; fh of DOS destination
|
|||
|
|
|||
|
AllName DB "A:\*.*",0
|
|||
|
|
|||
|
cbBuf DW ? ; number of bytes in buffer
|
|||
|
pDOS DW ? ; offset of beginning of DOS in buffer
|
|||
|
pDOSEnd DW ? ; offset of end of DOS in buffer
|
|||
|
|
|||
|
IF IBMVER OR IBMJAPVER
|
|||
|
BOOT DW 256 DUP (0)
|
|||
|
IF IBMJAPVER
|
|||
|
LLISTBUF DW 256 DUP (0)
|
|||
|
ENDIF
|
|||
|
ENDIF
|
|||
|
|
|||
|
IF IBMJAPVER
|
|||
|
RELOC DW 1 DUP(?)
|
|||
|
STARTSECTOR DW 1 DUP(?)
|
|||
|
ENDIF
|
|||
|
|
|||
|
BUF LABEL BYTE ; beginning of area for file reads
|
|||
|
|
|||
|
DATA ENDS
|
|||
|
|
|||
|
CODE SEGMENT PUBLIC
|
|||
|
|
|||
|
ASSUME CS:DG,DS:DG,ES:DG,SS:DG
|
|||
|
|
|||
|
ORG 100H
|
|||
|
|
|||
|
Start:
|
|||
|
JMP SHORT CheckVersion
|
|||
|
|
|||
|
IF IBMVER
|
|||
|
DW OFFSET DG:BOOT
|
|||
|
ENDIF
|
|||
|
HEADER DB "Vers 1.81"
|
|||
|
CheckVersion:
|
|||
|
PUSH AX ; save drive letter validity
|
|||
|
MOV AH,GET_VERSION
|
|||
|
INT 21H ; get dos version
|
|||
|
XCHG AH,AL ; Turn it around to AH.AL
|
|||
|
CMP AX,DOSVER_LOW ; is it too low?
|
|||
|
JB GOTBADDOS ; yes, error
|
|||
|
CMP AX,DOSVER_HIGH ; too high?
|
|||
|
JBE OKDOS ; yes, go check drive letter
|
|||
|
GOTBADDOS:
|
|||
|
MOV DX,OFFSET DG:BADVER ; message to dump
|
|||
|
MOV AH,STD_CON_STRING_OUTPUT ; standard output device
|
|||
|
INT 21H
|
|||
|
INT 20H ; old style exit for compatability
|
|||
|
|
|||
|
OKDOS: POP AX ; get drive validity
|
|||
|
JMP SHORT SYS ; go process
|
|||
|
|
|||
|
ERR0: MOV DX,OFFSET DG:BADPARM ; no drive letter
|
|||
|
MOV CX,BadParmLen
|
|||
|
JMP DisplayError
|
|||
|
|
|||
|
ERR1: MOV DX,OFFSET DG:BADDRV ; drive letter invalid
|
|||
|
MOV CX,BadDrvLen
|
|||
|
JMP DisplayError
|
|||
|
|
|||
|
ERR2: MOV AL,DEFALT ; get default drive number
|
|||
|
ADD AL,'A'-1 ; turn into letter
|
|||
|
MOV SYSDRV,AL ; place into middle of message
|
|||
|
MOV DX,OFFSET DG:GETSYS
|
|||
|
MOV CX,GETSYSLen ; length for output
|
|||
|
MOV BX,stderr ; use stderr
|
|||
|
MOV AH,Write ; Ask for system disk
|
|||
|
INT 21H
|
|||
|
CALL GetKeystroke ; wait for him to type simething
|
|||
|
XOR AL,AL ; valid drive spec now...
|
|||
|
SYS:
|
|||
|
CMP DS:(BYTE PTR 5DH)," " ; Was file specified?
|
|||
|
JNZ ERR0 ; yes, no files are allowed -> error
|
|||
|
CMP AL,-1 ; Invalid drive spec?
|
|||
|
JZ ERR1 ; yes, must have valid drive -> error
|
|||
|
CMP DS:(BYTE PTR 5CH),0 ; No drive specified?
|
|||
|
JZ ERR1 ; yes, cannot sys to default drive error
|
|||
|
MOV AH,GET_DEFAULT_DRIVE ; Get default drive
|
|||
|
INT 21H
|
|||
|
INC AL ; turn from phys drive to logical drive
|
|||
|
MOV DEFALT,AL ; save it for possible printing
|
|||
|
CMP DS:(BYTE PTR 5CH),AL ; did he specify the default drive?
|
|||
|
JZ ERR1 ; yes, default drive not allowed
|
|||
|
|
|||
|
IF IBMVER ; Check for "valid" destination
|
|||
|
PUSH AX
|
|||
|
MOV AL,BYTE PTR DS:[5Ch]
|
|||
|
DEC AL
|
|||
|
MOV BX,OFFSET DG:BUF ; Temp space
|
|||
|
MOV DX,1 ; Sector 1 (first sec of FAT)
|
|||
|
MOV CX,DX ; One sector
|
|||
|
INT 25H ; Read Fat sector
|
|||
|
POP AX ; Flags
|
|||
|
POP AX ; Real AX
|
|||
|
JC OKFAT ; Don't error here, let a CREATE or
|
|||
|
; some other call to the dest
|
|||
|
; generate a more useful INT 24H
|
|||
|
; error
|
|||
|
CMP BYTE PTR [BUF],0F8H
|
|||
|
JAE OKFAT
|
|||
|
JMP ERR3
|
|||
|
OKFAT:
|
|||
|
ENDIF
|
|||
|
|
|||
|
ADD AL,'A'-1 ; turn into letter
|
|||
|
MOV BIOSName,AL ; twiddle source name
|
|||
|
MOV DOSName,AL ; twiddle source name
|
|||
|
CLD
|
|||
|
MOV DX,OFFSET DG:BIOSName ; source name
|
|||
|
MOV DI,OFFSET DG:BIOSInFH ; pointer to block of data
|
|||
|
CALL OpenFile
|
|||
|
JC Err2 ; not found, go and try again
|
|||
|
MOV DX,OFFSET DG:DOSName ; source of DOS
|
|||
|
MOV DI,OFFSET DG:DOSInFH ; pointer to block of data
|
|||
|
CALL OpenFile ; Look for DOS
|
|||
|
JC ERR2 ; not there, go ask for a system disk
|
|||
|
MOV CX,SP ; get lowest available spot
|
|||
|
SUB CX,0200h+(OFFSET DG:BUF); leave room for all sorts of things
|
|||
|
MOV cbBuf,CX ; store length away
|
|||
|
CALL FillMem ; load up memory with files
|
|||
|
|
|||
|
IF IBMJAPVER
|
|||
|
CALL READ_BOOT ; need to copy boot sector too
|
|||
|
ENDIF
|
|||
|
|
|||
|
MOV AL,DS:(BYTE PTR 5CH) ; get drive of destination
|
|||
|
|
|||
|
IF IBMJAPVER
|
|||
|
CALL CHECK_TRAN ; check for bootable device
|
|||
|
JZ DOSWRT ; ok to boot
|
|||
|
MOV DX,OFFSET DG:BADDISK ; incorrect format to boot
|
|||
|
MOV CX,BadDiskLen
|
|||
|
JMP DisplayError ; go error and quit
|
|||
|
DOSWRT:
|
|||
|
ENDIF
|
|||
|
|
|||
|
ADD AL,'A'-1 ; convert to letter
|
|||
|
MOV BIOSName,AL ; point names at destination drive
|
|||
|
MOV DOSName,AL
|
|||
|
MOV AllName,AL ; look for any files
|
|||
|
|
|||
|
MOV AH,Find_First ; look for files
|
|||
|
MOV DX,OFFSET DG:AllName ; path of where to look
|
|||
|
MOV CX,Attr_Hidden+Attr_System ; attributes to find
|
|||
|
INT 21H
|
|||
|
JC PutSys ; no files - go and copy
|
|||
|
|
|||
|
IF MSVER
|
|||
|
MOV DL,DS:(BYTE PTR 5CH) ; get drive number
|
|||
|
MOV AH,GET_DRIVE_FREESPACE ; get free space available
|
|||
|
INT 21H
|
|||
|
MUL CX ; Compute size of cluster (secsiz*secperclus)
|
|||
|
XCHG CX,AX ; move it to correct spot
|
|||
|
MOV DX,OFFSET DG:BIOSName ; who to open
|
|||
|
MOV AX,BIOSLenLow+2 ; get low part of size
|
|||
|
MOV BX,BIOSLenHigh+2 ; get high size
|
|||
|
CALL CHKLEN ; open and snoop size
|
|||
|
JNZ ERR4 ; Must fit exact so MSDOS is in right place
|
|||
|
MOV DX,OFFSET DG:DOSName ; other guy to open
|
|||
|
MOV AX,DOSLenLow+2 ; get low part of size
|
|||
|
MOV BX,DOSLenHigh+2 ; get high size
|
|||
|
CALL CHKLEN ; open and snoop second size
|
|||
|
JA ERR4 ; Must be enough (or too much) space
|
|||
|
ENDIF
|
|||
|
|
|||
|
IF IBMVER OR IBMJAPVER
|
|||
|
MOV DX,OFFSET DG:BIOSName ; open BIOS
|
|||
|
MOV CX,7 ; attributes
|
|||
|
MOV AH,Find_First
|
|||
|
INT 21H
|
|||
|
JNC FindDos
|
|||
|
Err3J: JMP Err3 ; not found, go and complain
|
|||
|
FindDos:
|
|||
|
MOV DX,OFFSET DG:DOSName ; open DOS
|
|||
|
MOV AH,Find_First
|
|||
|
INT 21H
|
|||
|
JC Err3J ; Not found, go complain
|
|||
|
ENDIF
|
|||
|
|
|||
|
PUTSYS:
|
|||
|
MOV DX,OFFSET DG:BIOSName ; who to change mode
|
|||
|
MOV CX,0 ; undo attributes
|
|||
|
MOV AX,(ChMod SHL 8) + 1 ; set the attributes
|
|||
|
INT 21h
|
|||
|
MOV DX,OFFSET DG:DOSName ; who to change mode
|
|||
|
MOV CX,0 ; undo attributes
|
|||
|
MOV AX,(ChMod SHL 8) + 1 ; set the attributes
|
|||
|
INT 21h
|
|||
|
MOV DX,OFFSET DG:BIOSName ; destination of BIOS
|
|||
|
MOV CX,7 ; fancy attributes
|
|||
|
MOV AH,Creat ; make a new one
|
|||
|
INT 21h
|
|||
|
MOV BIOSOutFH,AX ; save handle
|
|||
|
MOV DX,OFFSET DG:DOSName ; destination of DOS
|
|||
|
MOV AH,Creat ; make a new one
|
|||
|
INT 21h
|
|||
|
MOV DOSOutFH,AX ; save handle
|
|||
|
Copy:
|
|||
|
CALL DumpMem ; flush out memory
|
|||
|
MOV AX,DOSLenHigh ; more DOS?
|
|||
|
OR AX,DOSLenLow ; more low dos
|
|||
|
OR AX,BIOSLenHigh ; more high BIOS
|
|||
|
OR AX,BIOSLenLow ; more low BIOS
|
|||
|
JZ AllDone ; nope, all done
|
|||
|
CALL FillMem ; reload world
|
|||
|
JMP Copy
|
|||
|
ERR4:
|
|||
|
MOV DX,OFFSET DG:BADSIZ
|
|||
|
MOV CX,BadSizLen
|
|||
|
JMP DisplayError
|
|||
|
AllDone:
|
|||
|
MOV CX,BIOSTime ; get time and date
|
|||
|
MOV DX,BIOSTime+2
|
|||
|
MOV BX,BIOSOutFH ; where to stuff the time
|
|||
|
MOV AX,(File_Times SHL 8) + 1
|
|||
|
INT 21h
|
|||
|
MOV AH,Close
|
|||
|
INT 21h
|
|||
|
|
|||
|
MOV CX,DOSTime ; get time and date
|
|||
|
MOV DX,DOSTime+2
|
|||
|
MOV BX,DOSOutFH ; where to stuff the time
|
|||
|
MOV AX,(File_Times SHL 8) + 1
|
|||
|
INT 21h
|
|||
|
MOV AH,Close
|
|||
|
INT 21h
|
|||
|
|
|||
|
IF IBMVER OR IBMJAPVER
|
|||
|
CALL PUTBOOT ; copy the boot sector also
|
|||
|
ENDIF
|
|||
|
|
|||
|
MOV DX,OFFSET DG:DONE ; all finished message
|
|||
|
MOV CX,DoneLen
|
|||
|
XOR AL,AL ; ok error code
|
|||
|
SERROR:
|
|||
|
PUSH AX
|
|||
|
MOV BX,stderr
|
|||
|
MOV AH,Write ; convenient place to display message
|
|||
|
INT 21H
|
|||
|
POP AX
|
|||
|
ErrorExit:
|
|||
|
MOV AH,EXIT ; bye and return error code
|
|||
|
INT 21h
|
|||
|
|
|||
|
DisplayError:
|
|||
|
MOV AL,1
|
|||
|
JMP SERROR
|
|||
|
FillMem:
|
|||
|
MOV CX,cbBuf ; get length of buffer
|
|||
|
MOV BX,BIOSInFH ; get bios source handle
|
|||
|
MOV DX,OFFSET DG:BUF ; point to beginning of buffer
|
|||
|
PUSH CX ; save away total length
|
|||
|
CMP BIOSLenHigh,0 ; > 64K to read?
|
|||
|
JA UseCX ; use CX
|
|||
|
CMP BIOSLenLow,CX ; more left to read?
|
|||
|
JA UseCX ; use CX
|
|||
|
MOV CX,BIOSLenLow ; move new
|
|||
|
UseCX:
|
|||
|
MOV AH,Read
|
|||
|
INT 21h ; read in what we can
|
|||
|
ADD DX,AX ; update pointer for DOS Read
|
|||
|
MOV pDOS,DX ; point to beginning of DOS
|
|||
|
SUB BIOSLenLow,AX ; decrement remaining
|
|||
|
SBB BIOSLenHigh,0 ; do 32 bit
|
|||
|
POP CX ; get original length
|
|||
|
SUB CX,AX ; this much is left
|
|||
|
|
|||
|
MOV BX,DOSInFH ; get bios source handle
|
|||
|
CMP DOSLenHigh,0 ; > 64K to read?
|
|||
|
JA UseCXDOS ; use CX
|
|||
|
CMP DOSLenLow,CX ; more left to read?
|
|||
|
JA UseCXDOS ; use CX
|
|||
|
MOV CX,DOSLenLow ; move new
|
|||
|
UseCXDOS:
|
|||
|
MOV AH,Read
|
|||
|
INT 21h ; read in what we can
|
|||
|
ADD DX,AX ; update pointer for DOS Read
|
|||
|
MOV pDOSEnd,DX ; point to End of dos DOS
|
|||
|
SUB DOSLenLow,AX ; decrement remaining
|
|||
|
SBB DOSLenHigh,0 ; do 32 bit arithmetic
|
|||
|
return
|
|||
|
|
|||
|
OpenFile:
|
|||
|
MOV AX,(OPEN SHL 8) + 0 ; open for reading only
|
|||
|
INT 21H ; Look for BIOS
|
|||
|
retc ; not found, go and try again
|
|||
|
STOSW ; stash away handle
|
|||
|
MOV BX,AX ; get ready for seeks
|
|||
|
MOV AX,(LSeek SHL 8) + 2 ; seek relative to eof
|
|||
|
XOR CX,CX ; zero offset
|
|||
|
XOR DX,DX ; zero offset
|
|||
|
INT 21h ; get offsets
|
|||
|
STOSW ; save low part of size
|
|||
|
STOSW ; save low part of size
|
|||
|
MOV AX,DX
|
|||
|
STOSW ; save high part of size
|
|||
|
STOSW ; save high part of size
|
|||
|
XOR DX,DX ; zero offset
|
|||
|
MOV AX,(LSeek SHL 8) + 0 ; seek relative to beginning
|
|||
|
INT 21h
|
|||
|
MOV AX,(File_Times SHL 8) + 0
|
|||
|
INT 21h ; get last write times
|
|||
|
MOV AX,CX
|
|||
|
STOSW ; save time
|
|||
|
MOV AX,DX
|
|||
|
STOSW ; save date
|
|||
|
return
|
|||
|
|
|||
|
ERR3:
|
|||
|
MOV DX,OFFSET DG:NODEST
|
|||
|
MOV CX,NoDestLen
|
|||
|
JMP DisplayError
|
|||
|
|
|||
|
DumpMem:
|
|||
|
MOV DX,OFFSET DG:BUF ; get offset of bios start
|
|||
|
MOV CX,pDOS ; beginning of next guy
|
|||
|
SUB CX,DX ; difference is length
|
|||
|
JZ DumpDos ; no bios to move
|
|||
|
MOV BX,BIOSOutFH ; where to output
|
|||
|
MOV AH,Write
|
|||
|
INT 21h ; wham
|
|||
|
DumpDos:
|
|||
|
MOV DX,pDOS ; beginning of dos
|
|||
|
MOV CX,pDOSEnd ; end of dos
|
|||
|
SUB CX,DX ; difference is length
|
|||
|
retz ; if zero no write
|
|||
|
MOV BX,DOSOutFH ; where to output
|
|||
|
MOV AH,Write
|
|||
|
INT 21h ; wham
|
|||
|
ret
|
|||
|
|
|||
|
IF MSVER
|
|||
|
CHKLEN:
|
|||
|
; CX has size of cluster, DX has pointer to file name
|
|||
|
; Returns with flags set on (size of file) - (size of hole)
|
|||
|
PUSH AX ; old size low
|
|||
|
PUSH BX ; old size high
|
|||
|
PUSH CX ; old cluster size
|
|||
|
MOV AH,Find_First
|
|||
|
MOV CX,7 ; attributes to search for
|
|||
|
INT 21H
|
|||
|
JC ERR3 ; cannot find file, error
|
|||
|
POP CX ; get cluster size back
|
|||
|
MOV DX,DS:[80h+find_buf_size_h] ; get destination size high
|
|||
|
MOV AX,DS:[80h+find_buf_size_l] ; get size low
|
|||
|
ADD AX,CX ; add cluster size
|
|||
|
ADC DX,0 ; 32 bit add
|
|||
|
SUB AX,1 ; adding CLUSSIZE-1
|
|||
|
SBB DX,0 ; 32 bit dec
|
|||
|
DIV CX ; compute new cluster size
|
|||
|
POP DX ; get old high
|
|||
|
POP BX ; get old low
|
|||
|
PUSH AX ; save away dividend
|
|||
|
MOV AX,BX ; put into correct register
|
|||
|
ADD AX,CX ; do the same as above (+CLUSSIZE-1)/CLUSSIZE
|
|||
|
ADC DX,0 ; 32 bit add
|
|||
|
SUB AX,1 ; adding CLUSSIZE-1
|
|||
|
SBB DX,0 ; 32 bit dec
|
|||
|
DIV CX ; compute old cluster size
|
|||
|
POP DX ; get new size
|
|||
|
CMP AX,DX ; is old >= new?
|
|||
|
return
|
|||
|
ENDIF
|
|||
|
|
|||
|
IF IBMJAPVER
|
|||
|
PUTBOOT:
|
|||
|
CALL READ_LLIST ; Get the list sector and set new boot sector
|
|||
|
MOV AL,DS:(BYTE PTR 5CH)
|
|||
|
DEC AL ; A=0
|
|||
|
MOV CX,1
|
|||
|
XOR DX,DX
|
|||
|
MOV BX,OFFSET DG:BOOT
|
|||
|
INT 26H ; Write out new boot sector
|
|||
|
POPF
|
|||
|
CALL WRITE_LLIST ; Make and write out new list sector
|
|||
|
RET
|
|||
|
ENDIF
|
|||
|
|
|||
|
IF IBMVER
|
|||
|
PUTBOOT:
|
|||
|
MOV AH,GET_DPB
|
|||
|
MOV DL,BYTE PTR DS:[5Ch] ; Target drive
|
|||
|
INT 21H
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV AL,[BX+16H] ; Media byte
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DG
|
|||
|
CMP AL,0FEH
|
|||
|
JB RET1
|
|||
|
TEST AL,1
|
|||
|
JZ GOTBOOT
|
|||
|
MOV BX,OFFSET DG:BOOT
|
|||
|
MOV WORD PTR [BX+17],112 ; Set number of dir entries
|
|||
|
MOV WORD PTR [BX+19],2*8*40 ; Set number of sectors
|
|||
|
INC BYTE PTR [BX+21] ; Media = ff
|
|||
|
INC WORD PTR [BX+26] ; Number of heads = 2
|
|||
|
|
|||
|
GOTBOOT:
|
|||
|
MOV AL,BYTE PTR DS:[5Ch]
|
|||
|
DEC AL
|
|||
|
MOV BX,OFFSET DG:BOOT ; Boot sector
|
|||
|
XOR DX,DX ; Sector 0
|
|||
|
MOV CX,DX
|
|||
|
INC CX ; One sector
|
|||
|
INT 26H ; Write out 8 sector boot sector
|
|||
|
POP AX ; Flags
|
|||
|
RET1: RET
|
|||
|
ENDIF
|
|||
|
|
|||
|
IF IBMJAPVER
|
|||
|
READ_BOOT:
|
|||
|
MOV AL,[DEFALT]
|
|||
|
DEC AL ; A=0
|
|||
|
MOV CX,1
|
|||
|
XOR DX,DX
|
|||
|
MOV BX,OFFSET DG:BOOT
|
|||
|
INT 25H
|
|||
|
POPF
|
|||
|
MOV AX,[BOOT+108H] ; Get old first sector of data
|
|||
|
MOV [RELOC],AX
|
|||
|
RET
|
|||
|
|
|||
|
READ_LLIST:
|
|||
|
MOV AL,DS:(BYTE PTR 5CH)
|
|||
|
DEC AL ; A=0
|
|||
|
MOV CX,1
|
|||
|
MOV DX,[STARTSECTOR]
|
|||
|
MOV BX,OFFSET DG:LLISTBUF
|
|||
|
INT 25H
|
|||
|
POPF
|
|||
|
RET
|
|||
|
|
|||
|
WRITE_LLIST:
|
|||
|
MOV AX,[STARTSECTOR]
|
|||
|
MOV DX,AX
|
|||
|
SUB AX,[RELOC] ; True reloc factor
|
|||
|
MOV CL,BYTE PTR [LLISTBUF+0CH] ; Number of entries needing reloc
|
|||
|
XOR CH,CH
|
|||
|
JCXZ NO_RELOCS
|
|||
|
MOV BX,OFFSET DG:LLISTBUF + 10H
|
|||
|
RELLOOP:
|
|||
|
ADD WORD PTR [BX+2],AX
|
|||
|
ADD BX,10H
|
|||
|
LOOP RELLOOP
|
|||
|
NO_RELOCS:
|
|||
|
MOV AL,DS:(BYTE PTR 5CH)
|
|||
|
DEC AL ; A=0
|
|||
|
MOV CX,1
|
|||
|
MOV BX,OFFSET DG:LLISTBUF
|
|||
|
INT 26H
|
|||
|
POPF
|
|||
|
RET
|
|||
|
|
|||
|
CHECK_TRAN:
|
|||
|
; All registers preserved. Returns zero if SYS OK, NZ if SYS FAIL
|
|||
|
; AL is drive (1=A,...) AL=0 is not valid
|
|||
|
|
|||
|
PUSH BX
|
|||
|
PUSH AX
|
|||
|
PUSH DS
|
|||
|
MOV DL,AL
|
|||
|
MOV AH,GET_DPB
|
|||
|
INT 21H
|
|||
|
MOV AX,[BX.dpb_first_sector] ; Get new first sector of data
|
|||
|
MOV BH,[BX.dpb_media]
|
|||
|
POP DS
|
|||
|
MOV [STARTSECTOR],AX
|
|||
|
MOV [BOOT+108H],AX ; Set new start of data in boot
|
|||
|
POP AX
|
|||
|
PUSH AX
|
|||
|
MOV BL,AL
|
|||
|
INT 11H ; IBM EQUIP CALL
|
|||
|
ROL AL,1
|
|||
|
ROL AL,1
|
|||
|
AND AL,3
|
|||
|
JNZ NOT_SINGLE
|
|||
|
INC AL
|
|||
|
NOT_SINGLE:
|
|||
|
INC AL ; AL is now MAX floppy #
|
|||
|
CMP BL,AL
|
|||
|
POP AX
|
|||
|
JBE CHECK_FLOP ; Is a floppy
|
|||
|
XOR BL,BL ; Is Hard file
|
|||
|
POP BX
|
|||
|
RET
|
|||
|
|
|||
|
CHECK_FLOP:
|
|||
|
CMP BH,0FBH ; Only floppy that boots
|
|||
|
POP BX
|
|||
|
RET
|
|||
|
ENDIF
|
|||
|
|
|||
|
GetKeystroke:
|
|||
|
MOV AX,(Std_CON_Input_Flush SHL 8) + Std_CON_Input_No_Echo
|
|||
|
INT 21H
|
|||
|
MOV AX,(Std_CON_Input_Flush SHL 8) + 0
|
|||
|
INT 21H
|
|||
|
|
|||
|
return
|
|||
|
|
|||
|
CODE ENDS
|
|||
|
END START
|
|||
|
|