четвер, 13 червня 2013 р.

Аналіз SYS.COM версії 1.81 з Compaq-DOS 2.12

Як вже згадувалося раніше, знайти SYS.COM з оригінальної MS-DOS 2.11 не вдалося. Однак, у файлі "Microsoft DOS 2.12 [Compaq OEM] (5.25).7z" трапився SYS.COM, з стрічкою "Vers 1.81" --- попередньою до тієї, що у оригінальному SYS.COM з PC-DOS 2.10 (стрічка "Vers 1.82"). Подумав, що вона може бути цікавою, як для аналізу розвитку конкретної програм так і способів програмування від Microsoft взагалі. Сподівання виправдалися. :-)

Детально її розбирати не буду --- вона дуже схожа на версію 1.82. Взагалі, природно було б починати саме з цієї, 1.81, потім переходити до новішої. Однак, з одного боку, побачив я її значно пізніше, з іншого, вона явно містить модифікації від Compaq, тобто є менш "автентичною", чи що. Тому зупинюся лише на важливих відмінностях.

ReadFilesToMem майже тотожні, за одним винятком --- у 1.81 немає перевірки помилок. Для ілюстрація, два фрагменти. (Відсутність перевірок є і в інших місцях цієї функції.)


                mov     ah, 3Fh
  int     21h             ; DOS - 2+ - READ FROM FILE WITH HANDLE
     ; BX = file handle, CX = number of bytes to read
     ; DS:DX -> buffer
     ;
     ; http://www.ctyme.com/intr/rb-2783.htm
     ; Returns AX = number of bytes actually read
  jb      short RestoreStackNExit ; Error -- exit
  cmp     ax, cx          ; Readed less than file size
  jnz     short RestoreStackNExit
  add     dx, ax          ; Calculate first free byte address
  mov     IBMDOS_buffer_addr, dx
  sub     IBMBIO_size_lo_1, ax ; Calculate, how much left to read
  sbb     IBMBIO_size_hi_1, 0

Vers 1.81:

                mov     ah, 3Fh
                int     21h             ; DOS - 2+ - READ FROM FILE WITH HANDLE
                                        ; BX = file handle, CX = number of bytes to read
                                        ; DS:DX -> buffer
     ;
     ; http://www.ctyme.com/intr/rb-2783.htm
     ; Returns AX = number of bytes actually read
 
  add     dx, ax          ; Calculate first free byte address
                mov     IBMDOS_buffer_addr, dx
                sub     IBMBIO_size_lo_1, ax ; Calculate, how much left to read
                sbb     IBMBIO_size_hi_1, 0

Аналогічно немає перевірки у точці виклику:

  call    ReadFilesToMem
  jb      short locContinuerOrError 
  mov     al, [ds:5Ch]    ; Get target drive

Vers 1.81:

  call    ReadFilesToMem
  mov     al, [ds:5Ch]    ; Get target drive

Так само, не перевіряються і помилки WriteSysFilesFromMem, ні всередині, ні в місці її виклику.
Не робиться спроби відновити поточну директорію для жодного із дисків.

Крім того, присутній явно Compaq-специфічний, і здається, не завершений код -- спроба вважати системними файлами також пару "IOSYS.COM" і "MSDOS.COM". Програми від MS-DOS так ніколи не робили --- на крайній випадок, могли б шукати IO.SYS та MSDOS.SYS.

Тобто, між версією 1.81 і 1.82 чітко видно прогрес --- різке покращення обробки помилок, "повага" до вихідної поточної директорії. Навряд чи ці зміни, особливо стосовно обробки помилок, можна пов'язати із "самодіяльністю" OEM --- чого б вони перевірки викидали?

Повний код нижче, скачати його, разом із лістингом, згенерованим IDA, скомпільованим файлом та, для порівняння, оригінальним SYS.COM, можна тут


;  This file is generated by The Interactive Disassembler (IDA)     
;  Copyright (c) 2010 by Hex-Rays SA, <support@hex-rays.com>     
;     Licensed to: Freeware version       
;
; Modified to compile by fasm and commented by Indrekis, indrekis2.blogspot.com
;
; Input MD5   : 36E7D18FE6307CA5F678E1DE3E758158

; Modified to compile by fasm and commented by Indrekis, indrekis2.blogspot.com
;
; File Name   : Microsoft DOS 2.12 [Compaq OEM] (5.25)\SYS.COM
; Format      : MS-DOS COM-file
; Base Address: 0h Range: 100h-740h Loaded length: 640h

ReadedIBMDOS  = 740h

  ;.8086
  use16
  org 100h

  include "my_fcb_2b.inc"

start: 
  jmp short EntryPoint1
; ===========================================================================
  db  40h ; @
  db    5
aVers1_81 db 'Vers 1.81'
; ===========================================================================
; COM-format executables begin running with the following register values:
;   AL = 00h if first FCB has valid drive letter, FFh if not
;   AH = 00h if second FCB has valid drive letter, FFh if not
; CS,DS,ES,SS = PSP segment SP = offset of last word available in first 64K segment
; ( http://www.ctyme.com/intr/rb-2939.htm )

EntryPoint1:    ; CODE XREF: start j
  push ax  ; Save AX
  mov ah, 30h
  int 21h  ; DOS - GET DOS VERSION
     ; Return: AL = major version number (00h for DOS 1.x)
  xchg ah, al
  cmp ax, 136h
  jb short WrongDOSVersion
  cmp ax, 20Ah
  jbe short DosVersionOK

WrongDOSVersion:   ; CODE XREF: start+17 j
  mov dx, aIncorrectDosVe ; "Incorrect DOS version\r\n$"
  mov ah, 9
  int 21h  ; DOS - PRINT STRING
     ; DS:DX -> string terminated by "$"
  int 20h  ; DOS - PROGRAM TERMINATION
     ; returns to DOS--identical to INT 21/AH=00h
; ===========================================================================

DosVersionOK:    ; CODE XREF: start+1C j
  pop ax  ;  Restore initial AX, with default FCBs disk states.
  jmp short EntryPoint2CorrectVer
; ===========================================================================

ArgIsInvalid:    ; CODE XREF: start+5E j
  mov dx, aInvalidParamet ; "Invalid parameter"
  mov cx, [InvalidParametSize]
  jmp ExitWithCode1
; ===========================================================================

BadDriveLetter:    ; CODE XREF: start+62 j start+69 j ...
  mov dx, aInvalidDriveSp
  mov cx, [InvalidDriveSpSize]
  jmp ExitWithCode1
; ===========================================================================

AskToInsertSysDisk:   ; CODE XREF: start+AA j start+B5 j
  mov al, [currentDrive]
  add al, 40h
  mov [aDriverLetter1], al
  mov dx, aInsertSystemDi ; "Insert system disk in drive "
  mov cx, [InsertSystemDiskFullSize]
  mov bx, 2  ; Standard Error Device handler (STDERR)
     ; http://stanislavs.org/helppc/file_handles.html
  mov ah, 40h
  int 21h  ; DOS - 2+ - WRITE TO FILE WITH HANDLE
     ; BX = file handle, CX = number of bytes to write, DS:DX -> buffer
  call WaitForAnyKey ; Clears buffer before and after
  xor al, al

EntryPoint2CorrectVer:   ; CODE XREF: start+28 j
  cmp byte [ds:5Dh], 20h
  jnz short ArgIsInvalid
  cmp al, 0FFh
  jz short BadDriveLetter
;
; Check for attempt to write system files into
; disk, we are running (and reading them from)
  cmp byte [ds:5Ch], 0
  jz short BadDriveLetter
  mov ah, 19h
  int 21h  ; DOS - GET DEFAULT DISK NUMBER
  inc al
  mov [currentDrive], al
  cmp [ds:5Ch], al
  jz short BadDriveLetter
; Check FAT on destination disk
  push ax
  mov al, [ds:5Ch]
  dec al
  mov bx, ReadedIBMDOS; Stores in memory just above its code. 
     ; ReadedIBMDOS -- constant, not a variable!
  mov dx, 1
  mov cx, dx
  int 25h  ; DOS - ABSOLUTE DISK READ (except DOS 4.0/COMPAQ DOS 3.31 >32M partitn)
     ; AL = drive number (0=A, 1=B, etc), DS:BX = Disk Transfer Address (buffer)
     ; CX = number of sectors to read, DX = first relative sector to read
     ; Return: CF set on error
  pop ax
  pop ax
  jb short CheckSysFiles
  cmp byte [ds:ReadedIBMDOS], 0F8h
  jnb short CheckSysFiles
  jmp noRoomForSys
; ===========================================================================

CheckSysFiles:    ; CODE XREF: start+8C j start+93 j
  add al, 40h
  mov byte [aAIbmbio_com], al ; "A:\\IBMBIO.COM"
  mov byte [aAIbmdos_com], al ; "A:\\IBMDOS.COM"
  cld
  mov dx, aAIbmbio_com ; "A:\\IBMBIO.COM"
  mov di, IBMBIO_hndlr
; Try to open both system files.
; Determine their size, time and date. Save them
; both with file handlers. In case of error --
; ask to insert system disk
  call GetFileSizeDateTime ; DX -- filename string
     ; DI -- address of file handler variable
     ; CF -- on error,
     ; If OK, Size, Time and Date are saved after the Handler
     ; Strange that size is saved twice -- two times lo word
     ; and two times hi word.
  jb short AskToInsertSysDisk
  mov dx, aAIbmdos_com ; "A:\\IBMDOS.COM"
  mov di, IBMDOS_hndlr
  call GetFileSizeDateTime ; DX -- filename string
     ; DI -- address of file handler variable
     ; CF -- on error,
     ; If OK, Size, Time and Date are saved after the Handler
     ; Strange that size is saved twice -- two times lo word
     ; and two times hi word.
  jb short AskToInsertSysDisk
; Both files exist and successfully opened
  mov cx, sp
  sub cx, 940h ; Approximation of code+stack size?
  mov [PutativeMaxFreeMem], cx
  call ReadFilesToMem ; Tries to read IBMBIO and IBMDOS to memory.
     ; Read as much as fits.
     ;
; Unlike 1.82, no error checking after the call
  mov al, [ds:5Ch]
  mov [FCBext_forFind.Driver], al
; Set destination driver letter to all relevant strings
  add al, 40h
  mov byte [aAIbmbio_com], al ; "A:\\IBMBIO.COM"
  mov byte [aAIbmdos_com], al ; "A:\\IBMDOS.COM"
  mov byte [aAIosys_com], al ; "A:\\IOSYS.COM"
  mov byte [aAMsdos_com], al ; "A:\\MSDOS.COM"
  mov byte [anyFileMask], al ; "A:\\*.*"
;
; Unlike 1.82 --- no attempt to save and restore current dir.
;
  mov ah, 4Eh
  mov dx, anyFileMask ; "A:\\*.*"
  mov cx, 6
  int 21h  ; DOS - 2+ - FIND FIRST ASCIZ (FINDFIRST)
     ; CX = search attributes
     ; DS:DX -> ASCIZ filespec
     ; (drive, path, and wildcards allowed)
  jnb short SomeFilesFoundOnTrg
  mov ah, 11h
  mov dx, FCBext_forFind
  int 21h  ; DOS - SEARCH FIRST USING FCB
     ; DS:DX -> FCB
  cmp al, 0FFh
  jz short FoundVolLable ; What does it means?! (See SYS.COM ver. 1.82 for comparison)
  jmp noRoomForSys
; ===========================================================================
; Checks both for IBM and MS-DOS-similar filenames. Compaq modification?

SomeFilesFoundOnTrg:   ; CODE XREF: start+E5 j
  mov dx, aAIbmbio_com ; "A:\\IBMBIO.COM"
  mov cx, 7
  mov ah, 4Eh
  int 21h  ; DOS - 2+ - FIND FIRST ASCIZ (FINDFIRST)
     ; CX = search attributes
     ; DS:DX -> ASCIZ filespec
     ; (drive, path, and wildcards allowed)
  jnb short IBMBIO_found
  mov dx, aAIosys_com ; "A:\\IOSYS.COM"
  mov cx, 7
  mov ah, 4Eh
  int 21h  ; DOS - 2+ - FIND FIRST ASCIZ (FINDFIRST)
     ; CX = search attributes
     ; DS:DX -> ASCIZ filespec
     ; (drive, path, and wildcards allowed)
  jnb short CheckForMSDOS_COM

loc20D_noRoomForSys:   ; CODE XREF: start+117 j start+131 j
  jmp noRoomForSys
; ===========================================================================

CheckForMSDOS_COM:   ; CODE XREF: start+10B j
  mov dx, aAMsdos_com ; "A:\\MSDOS.COM"
  mov ah, 4Eh
  int 21h  ; DOS - 2+ - FIND FIRST ASCIZ (FINDFIRST)
     ; CX = search attributes
     ; DS:DX -> ASCIZ filespec
     ; (drive, path, and wildcards allowed)
  jb short loc20D_noRoomForSys
; If IOSYS.COM and MSDOS.COM found --- delete both
  mov dx, aAIosys_com ; "A:\\IOSYS.COM"
  mov ah, 41h
  int 21h  ; DOS - 2+ - DELETE A FILE (UNLINK)
     ; DS:DX -> ASCIZ pathname of file to delete (no wildcards allowed)
  mov dx, aAMsdos_com ; "A:\\MSDOS.COM"
  mov ah, 41h
  int 21h  ; DOS - 2+ - DELETE A FILE (UNLINK)
     ; DS:DX -> ASCIZ pathname of file to delete (no wildcards allowed)
  jmp short FoundVolLable
; ===========================================================================
  nop

IBMBIO_found:    ; CODE XREF: start+FF j
  mov dx, aAIbmdos_com ; "A:\\IBMDOS.COM"
  mov ah, 4Eh
  int 21h  ; DOS - 2+ - FIND FIRST ASCIZ (FINDFIRST)
     ; CX = search attributes
     ; DS:DX -> ASCIZ filespec
     ; (drive, path, and wildcards allowed)
  jb short loc20D_noRoomForSys
; Here we found IBM-style sys-files, or deleted MS-like...
; Setting attributes. But, only for IBM-style. Bug?

; Difference from ver. 1.82 --- check for MS-DOS-like (but not exactly) files

FoundVolLable:    ; CODE XREF: start+F0 j start+127 j
  mov dx, aAIbmbio_com ; "A:\\IBMBIO.COM"
  mov cx, 0
  mov ax, 4301h
  int 21h  ; DOS - 2+ - SET FILE ATTRIBUTES
     ; DS:DX -> ASCIZ file name
     ; CX = file attribute bits
  mov dx, aAIbmdos_com ; "A:\\IBMDOS.COM"
  mov cx, 0
  mov ax, 4301h
  int 21h  ; DOS - 2+ - SET FILE ATTRIBUTES
     ; DS:DX -> ASCIZ file name
     ; CX = file attribute bits
  mov dx, aAIbmbio_com ; "A:\\IBMBIO.COM"
  mov cx, 7
  mov ah, 3Ch
  int 21h  ; DOS - 2+ - CREATE A FILE WITH HANDLE (CREAT)
     ; CX = attributes for file
     ; DS:DX -> ASCIZ filename (may include drive and path)
  mov [TargetIBMBIO_hndlr], ax
  mov dx, aAIbmdos_com ; "A:\\IBMDOS.COM"
  mov ah, 3Ch
  int 21h  ; DOS - 2+ - CREATE A FILE WITH HANDLE (CREAT)
     ; CX = attributes for file
     ; DS:DX -> ASCIZ filename (may include drive and path)
  mov [TargetIBMDOS_hndlr], ax

ReadNWriteNextPart:   ; CODE XREF: start+177 j
  call WriteSysFilesFromMem
  mov ax, [IBMDOS_size_hi_1]
  or ax, [IBMDOS_size_lo_1]
  or ax, [IBMBIO_size_hi_1]
  or ax, [IBMBIO_size_lo_1]
  jz short RestoreFilesDateNTime
  call ReadFilesToMem ; Tries to read IBMBIO and IBMDOS to memory.
     ; Read as much as fits.
     ;
  jmp short ReadNWriteNextPart
; ===========================================================================
;Unused code!
  mov dx, aIncompatibleSy ; "Incompatible system size"
  mov cx, [IncompatibleSySize]
  jmp short ExitWithCode1
; ===========================================================================
  nop

RestoreFilesDateNTime:   ; CODE XREF: start+172 j
  mov cx, [IBMBIO_time]
  mov dx, [IBMBIO_date]
  mov bx, [TargetIBMBIO_hndlr]
  mov ax, 5701h
  int 21h  ; DOS - 2+ - SET FILE'S DATE/TIME
     ; BX = file handle, CX = time to be set
     ; DX = date to be set
  mov ah, 3Eh
  int 21h  ; DOS - 2+ - CLOSE A FILE WITH HANDLE
     ; BX = file handle
  mov cx, [IBMDOS_time]
  mov dx, [IBMDOS_date]
  mov bx, [TargetIBMDOS_hndlr]
  mov ax, 5701h
  int 21h  ; DOS - 2+ - SET FILE'S DATE/TIME
     ; BX = file handle, CX = time to be set
     ; DX = date to be set
  mov ah, 3Eh
  int 21h  ; DOS - 2+ - CLOSE A FILE WITH HANDLE
     ; BX = file handle
  call WriteBoot ; ; See description of version 1.82
  mov dx, aSystemTransfer ; "System transferred"
  mov cx, [SystemTransferSize]
  xor al, al

PrnMsgNExitWithCode:   ; CODE XREF: start+1C8 j
  push ax
  mov bx, 2  ; Standard Error Device handler - can be redirected (STDERR)
     ; http://stanislavs.org/helppc/file_handles.html
  mov ah, 40h
  int 21h  ; DOS - 2+ - WRITE TO FILE WITH HANDLE
     ; BX = file handle, CX = number of bytes to write, DS:DX -> buffer
  pop ax
  mov ah, 4Ch
  int 21h  ; DOS - 2+ - QUIT WITH EXIT CODE (EXIT)
     ; AL = exit code
; ===========================================================================

ExitWithCode1:    ; CODE XREF: start+31 j start+3B j ...
  mov al, 1
  jmp short PrnMsgNExitWithCode
;start  endp


; ============== subroutine =================================================

; Tries to read IBMBIO and IBMDOS to memory.
; Read as much as fits.
;

ReadFilesToMem:
  mov cx, [PutativeMaxFreeMem]
  mov bx, [IBMBIO_hndlr]
  mov dx, ReadedIBMDOS ; ReadedIBMDOS -- constant!
  push cx
  cmp [IBMBIO_size_hi_1], 0 ; If size above 64k -- read max size, which can be
     ; disposed in free mem.
  ja short PRoceedToRead
  cmp [IBMBIO_size_lo_1], cx ; If size is large than can feet in memory --
     ; read max size, which can be disposed in free mem.
  ja short PRoceedToRead
  mov cx, [IBMBIO_size_lo_1] ; Else read exactly file size bytes

PRoceedToRead:    ; CODE XREF: ReadFilesToMem+11 j
     ; ReadFilesToMem+17 j
  mov ah, 3Fh
  int 21h  ; DOS - 2+ - READ FROM FILE WITH HANDLE
     ; BX = file handle, CX = number of bytes to read
     ; DS:DX -> buffer
; Unlike 1.82, no error checking!
  add dx, ax  ; Calculate first free byte address
  mov [IBMDOS_buffer_addr], dx
  sub [IBMBIO_size_lo_1], ax
  sbb [IBMBIO_size_hi_1], 0
  pop cx
  sub cx, ax  ; Calculate free memory left
  mov bx, [IBMDOS_hndlr]
  cmp [IBMDOS_size_hi_1], 0 ; If size above 64k -- read max size, which can be
     ; disposed in free mem.
  ja short PRoceedToRead2
  cmp [IBMDOS_size_lo_1], cx ; If size is large than can feet in memory --
     ; read max size, which can be disposed in free mem.
  ja short PRoceedToRead2
  mov cx, [IBMDOS_size_lo_1] ; Else read exactly file size bytes

PRoceedToRead2:    ; CODE XREF: ReadFilesToMem+3C j
     ; ReadFilesToMem+42 j
  mov ah, 3Fh
  int 21h  ; DOS - 2+ - READ FROM FILE WITH HANDLE
     ; BX = file handle, CX = number of bytes to read
     ; DS:DX -> buffer
; Unlike 1.82, no error checking!
  add dx, ax
  mov [After_IBMDOS_buffer], dx
  sub [IBMDOS_size_lo_1], ax ; Calculate, how much left to read
  sbb [IBMDOS_size_hi_1], 0

Retn_325:    ; CODE XREF: GetFileSizeDateTime+5 j
  retn
;ReadFilesToMem endp


; ============== subroutine =================================================

; DX -- filename string
; DI -- address of file handler variable
; CF -- on error,
; If OK, Size, Time and Date are saved after the Handler
; Strange that size is saved twice -- two times lo word
; and two times hi word.

GetFileSizeDateTime:
  mov ax, 3D00h
  int 21h  ; DOS - 2+ - OPEN DISK FILE WITH HANDLE
     ; DS:DX -> ASCIZ filename
     ; AL = access mode
     ; 0 - read
  jb short Retn_325
  stosw
; Determine and save file size
  mov bx, ax
  mov ax, 4202h
  xor cx, cx
  xor dx, dx
  int 21h  ; DOS - 2+ - MOVE FILE READ/WRITE POINTER (LSEEK)
     ; AL = method: offset from end of file
  stosw
  stosw
  mov ax, dx
  stosw
  stosw
  xor dx, dx
  mov ax, 4200h
  int 21h  ; DOS - 2+ - MOVE FILE READ/WRITE POINTER (LSEEK)
     ; AL = method: offset from beginning of file
  mov ax, 5700h
  int 21h  ; DOS - 2+ - GET FILE'S DATE/TIME
     ; BX = file handle
  mov ax, cx
  stosw
  mov ax, dx
  stosw

retGetFileSizeDateTime:   ; CODE XREF: WriteSysFilesFromMem+1D j
  retn
;GetFileSizeDateTime endp

; ===========================================================================
; START OF FUNCTION CHUNK FOR start

noRoomForSys: 
  mov dx, aNoRoomForSyste ; "No room for system on destination disk"
  mov cx, [NoRoomForSysteSize]
  jmp ExitWithCode1
; END OF FUNCTION CHUNK FOR start

; ============== subroutine =================================================

WriteSysFilesFromMem:
  mov dx, ReadedIBMDOS ; ReadedIBMDOS -- constant!
  mov cx, [IBMDOS_buffer_addr]
  sub cx, dx
  jz short ProceedToIBMDO
  mov bx, [TargetIBMBIO_hndlr]
  mov ah, 40h
  int 21h  ; DOS - 2+ - WRITE TO FILE WITH HANDLE
     ; BX = file handle, CX = number of bytes to write, DS:DX -> buffer
; Unlike ver 1.82 --- no error checking!

ProceedToIBMDO:    ; CODE XREF: WriteSysFilesFromMem+9 j
  mov dx, [IBMDOS_buffer_addr]
  mov cx, [After_IBMDOS_buffer]
  sub cx, dx
  jz short retGetFileSizeDateTime
  mov bx, [TargetIBMDOS_hndlr]
  mov ah, 40h
  int 21h  ; DOS - 2+ - WRITE TO FILE WITH HANDLE
     ; BX = file handle, CX = number of bytes to write, DS:DX -> buffer
  retn
;WriteSysFilesFromMem endp


; ============== subroutine =================================================

; ; See description of version 1.82

WriteBoot:
  mov ah, 32h
  mov dl, [ds:5Ch]
  int 21h  ; DOS - 2+ internal - GET DRIVE PARAMETER BLOCK
     ; DL = drive number, 0 = default, 1 = A, etc.
  mov al, [bx+16h]
  push cs
  pop ds
  cmp al, 0FEh
  jb short WriteBootExit
  test al, 1
  jz short DoWriteBoot
; Update boot image for double-sided disk
  mov bx, NewBoot
  inc byte [bx+0Dh]
  mov word [bx+11h], 70h
  mov word [bx+13h], 280h
  inc byte [bx+15h]
  inc word [bx+1Ah]

DoWriteBoot:    ; CODE XREF: WriteBoot+13 j
  mov al, [ds:5Ch]
  dec al
  mov bx, NewBoot
  xor dx, dx
  mov cx, dx
  inc cx
  int 26h  ; DOS - ABSOLUTE DISK WRITE (except DOS 4.0/COMPAQ DOS 3.31 >32M partn)
     ; AL = drive number (0=A, 1=B, etc), DS:BX = Disk Transfer Address (buffer)
     ; CX = number of sectors to write, DX = first relative sector to write
     ; Return: CF set on error
  pop ax

WriteBootExit:    ; CODE XREF: WriteBoot+F j
  retn
;WriteBoot endp 


; ============== subroutine =================================================

; Clears buffer before and after

WaitForAnyKey:
  mov ax, 0C08h
  int 21h  ; DOS - CLEAR KEYBOARD BUFFER
     ; AL must be 01h, 06h, 07h, 08h, or 0Ah.
  mov ax, 0C00h
  int 21h  ; DOS - CLEAR KEYBOARD BUFFER
     ; AL must be 01h, 06h, 07h, 08h, or 0Ah.
  retn
;WaitForAnyKey endp

; ===========================================================================
aIncorrectDosVe db 'Incorrect DOS version',0Dh,0Ah,'$' ; DATA XREF: start:WrongDOSVersion o
aInvalidDriveSp db 'Invalid drive specification'
InvalidDriveSpSize dw 1Bh  ; DATA XREF: start+37 r
aInvalidParamet db 'Invalid parameter'  ; DATA XREF: start:ArgIsInvalid o
InvalidParametSize dw 11h  ; DATA XREF: start+2D t
aNoRoomForSyste db 'No room for system on destination disk' ; DATA XREF: start:noRoomForSys o
NoRoomForSysteSize dw 26h  ; DATA XREF: start+255 r
aIncompatibleSy db 'Incompatible system size' ; DATA XREF: start+179 o
IncompatibleSySize dw 18h  ; DATA XREF: start+17C r
aSystemTransfer db 'System transferred' ; DATA XREF: start+1B0 o
SystemTransferSize dw 12h  ; DATA XREF: start+1B3 r
aInsertSystemDi db 'Insert system disk in drive ' ; DATA XREF: start+46 o
aDriverLetter1 db 41h   ; DATA XREF: start+43 t
aAndStrikeAnyKe db 0Dh,0Ah
  db 'and strike any key when ready',0Dh,0Ah
InsertSystemDiskFullSize dw 3Eh  ; DATA XREF: start+49 r
currentDrive db 0   ; DATA XREF: start:AskToInsertSysDisk t
     ; start+71 t
aAIbmbio_com db 'A:\IBMBIO.COM',0    ; DATA XREF: start+9A t start+A1 o ...
aAIbmdos_com db 'A:\IBMDOS.COM',0    ; DATA XREF: start+9D t start+AC o ...
aAIosys_com db 'A:\IOSYS.COM',0     ; DATA XREF: start+D2 w start+101 o ...
aAMsdos_com db 'A:\MSDOS.COM',0     ; DATA XREF: start+D5 w
     ; start:CheckForMSDOS_COM o ...

; 0x01 file is read only
; 0x02 hidden file
; 0x04 system file
; 0x08 a special entry containing the disk's volume label
; 0x10 The entry describes a subdirectory.
; 0x20 This is the archive flag.
; 0x40 Not used; must be set to 0.
; 0x80 Not used; must be set to 0.
;
; 8h -- volume lable
FCBext_forFind ExtFCB_t 1,"????????", "???", 0,8h,0
;FCBext_forFind db 0FFh   ; ExtMarker ; DATA XREF: start+C7 t
;     ; start+E9 o
;  db 5 dup(0)  ; Reserved1
;  db 8   ; Attribute
;  db 1   ; Driver
;  db 8 dup('?')           ; FileName
;  db 3 dup('?')           ; FileExt
;  db 2 dup(0)  ; CurBlock
;  db 2 dup(0)  ; RecordSize
;  db 4 dup(0)  ; FileSize
;  db 2 dup(0)  ; FileDate
;  db 2 dup(0)  ; FileTime
;  db 8 dup(0)  ; Reserved2
;  db 0   ; CurRecord
;  db 4 dup(0)  ; DirectRecord
;
; IBMBIO.COM data
IBMBIO_hndlr dw 0   ; DATA XREF: start+A4 o
     ; ReadFilesToMem+4 r
IBMBIO_size_lo_1 dw 0   ; DATA XREF: start+16E t
     ; ReadFilesToMem+13 r ...
IBMBIO_size_lo_2 dw 0
IBMBIO_size_hi_1 dw 0   ; DATA XREF: start+16A t
     ; ReadFilesToMem+C r ...
IBMBIO_size_hi_2 dw 0
IBMBIO_time dw 0   ; DATA XREF: start:RestoreFilesDateNTime r
IBMBIO_date dw 0   ; DATA XREF: start+187 r
TargetIBMBIO_hndlr dw 0   ; DATA XREF: start+153 w start+18B r ...
;
; IBMDOS.COM data
IBMDOS_hndlr dw 0   ; DATA XREF: start+AF o
     ; ReadFilesToMem+33 r
IBMDOS_size_lo_1 dw 0   ; DATA XREF: start+166 t
     ; ReadFilesToMem+3E r ...
IBMDOS_size_lo_2 dw 0
IBMDOS_size_hi_1 dw 0   ; DATA XREF: start+163 t
     ; ReadFilesToMem+37 r ...
IBMDOS_size_hi_2 dw 0
IBMDOS_time dw 0   ; DATA XREF: start+198 r
IBMDOS_date dw 0   ; DATA XREF: start+19C r
TargetIBMDOS_hndlr dw 0   ; DATA XREF: start+15D w start+1A0 r ...
anyFileMask db 'A:\*.*',0           ; DATA XREF: start+D8 w start+DD o
PutativeMaxFreeMem dw 0   ; DATA XREF: start+BD w ReadFilesToMem t
IBMDOS_buffer_addr dw 0   ; DATA XREF: ReadFilesToMem+23 w
     ; WriteSysFilesFromMem+3 t ...
After_IBMDOS_buffer dw 0  ; DATA XREF: ReadFilesToMem+4E w
     ; WriteSysFilesFromMem+17 t
  db    0
  db    0
  db    0
  db    0
  db    0
  db    0
  db    0
NewBoot  db 0EBh, 35h, 90h, 49h, 42h, 4Dh, 20h, 20h, 32h, 2Eh, 30h, 0, 2, 1, 1, 0; 0
     ; DATA XREF: WriteBoot+15 o
     ; WriteBoot+30 o
  db 2, 40h, 0, 40h, 1, 0FEh, 1, 0, 8, 0, 1, 0, 0, 0, 0DFh, 2; 16
  db 25h, 2, 9, 2Ah, 0FFh, 50h, 0F6h, 0, 2, 0, 0, 0, 0, 0, 0, 0; 32
  db 0, 0BEh, 8Ch, 1, 0E9h, 15h, 1, 0C4h, 5Ch, 8, 33h, 0EDh, 0B8h, 0C0h, 7, 8Eh; 48
  db 0D8h, 0Ah, 0D2h, 79h, 12h, 89h, 1Eh, 29h, 0, 8Ch, 6, 2Bh, 0, 88h, 16h, 2Dh; 64
  db 0, 0C7h, 6, 2Fh, 0, 2, 0, 8Eh, 0C5h, 8Eh, 0D5h, 0BCh, 0, 7Ch, 0FCh, 0BFh; 80
  db 78h, 0, 0B8h, 1Eh, 0, 0ABh, 8Ch, 0D8h, 0ABh, 0A1h, 16h, 0, 0D1h, 0E0h, 40h, 1; 96
  db 6, 29h, 0, 11h, 2Eh, 2Bh, 0, 0E8h, 67h, 0, 0BBh, 0, 5, 53h, 0B0h, 1; 112
  db 0E8h, 94h, 0, 5Fh, 0BEh, 76h, 1, 0B9h, 0Bh, 0, 0F3h, 0A6h, 75h, 0A3h, 83h, 0C7h; 128
  db 15h, 0B1h, 0Bh, 0F3h, 0A6h, 75h, 9Ah, 0A1h, 11h, 0, 0B1h, 4, 0D3h, 0E8h, 1, 6; 144
  db 29h, 0, 11h, 2Eh, 2Bh, 0, 0FFh, 36h, 29h, 0, 0C4h, 1Eh, 72h, 1, 0E8h, 30h; 160
  db 0, 0, 6, 2Eh, 0, 0E8h, 5Fh, 0, 1, 6, 29h, 0, 11h, 2Eh, 2Bh, 0; 176
  db 80h, 3Eh, 2Eh, 0, 11h, 72h, 0E7h, 0CDh, 11h, 0D1h, 0E0h, 0D1h, 0E0h, 80h, 0E4h, 3; 192
  db 0B9h, 2, 0, 74h, 4, 0FEh, 0C4h, 8Ah, 0CCh, 0A1h, 2Fh, 0, 5Bh, 0FFh, 2Eh, 72h; 208
  db 1, 0A1h, 18h, 0, 0F6h, 26h, 1Ah, 0, 91h, 0A1h, 29h, 0, 8Bh, 16h, 2Bh, 0; 224
  db 0F7h, 0F1h, 92h, 8Bh, 0Eh, 18h, 0, 0F6h, 0F1h, 0FEh, 0C4h, 86h, 0CCh, 0D0h, 0CEh, 0D0h; 240
  db 0CEh, 0Ah, 0CEh, 8Ah, 0EAh, 8Ah, 0F0h, 8Ah, 16h, 2Dh, 0, 51h, 80h, 0E1h, 3Fh, 2Ah; 256
  db 0E1h, 0FEh, 0C4h, 8Ah, 0C4h, 59h, 0C3h, 98h, 96h, 56h, 0BFh, 5, 0, 0B8h, 1, 2; 272
  db 0CDh, 13h, 72h, 0Ah, 80h, 0C7h, 2, 0FEh, 0C1h, 4Eh, 75h, 0F1h, 58h, 0C3h, 80h, 0FCh; 288
  db 11h, 75h, 0Fh, 1Eh, 0B8h, 0, 0C8h, 8Eh, 0D8h, 81h, 3Eh, 0EAh, 1Fh, 43h, 4Fh, 1Fh; 304
  db 74h, 0E2h, 33h, 0C0h, 0CDh, 13h, 4Fh, 75h, 0D4h, 0BEh, 0D6h, 1, 0E8h, 1Dh, 0, 0BEh; 320
  db 0ACh, 1, 0E8h, 17h, 0, 33h, 0C0h, 0CDh, 16h, 26h, 0C7h, 6, 72h, 4, 34h, 12h; 336
  db 0EAh, 0, 0, 0FFh, 0FFh, 0B4h, 0Eh, 0BBh, 7, 0, 0CDh, 10h, 0ACh, 3Ch, 24h, 75h; 352
  db 0F4h, 0C3h, 0, 0, 70h, 0, 49h, 42h, 4Dh, 42h, 49h, 4Fh, 20h, 20h, 43h, 4Fh; 368
  db 4Dh, 49h, 42h, 4Dh, 44h, 4Fh, 53h, 20h, 20h, 43h, 4Fh, 4Dh, 0Ah, 0Dh, 4Eh, 6Fh; 384
  db 6Eh, 2Dh, 53h, 79h, 73h, 74h, 65h, 6Dh, 20h, 64h, 69h, 73h, 6Bh, 20h, 6Fh, 72h; 400
  db 20h, 64h, 69h, 73h, 6Bh, 20h, 65h, 72h, 72h, 6Fh, 72h, 24h, 0Ah, 0Dh, 52h, 65h; 416
  db 70h, 6Ch, 61h, 63h, 65h, 20h, 61h, 6Eh, 64h, 20h, 73h, 74h, 72h, 69h, 6Bh, 65h; 432
  db 20h, 61h, 6Eh, 79h, 20h, 6Bh, 65h, 79h, 20h, 77h, 68h, 65h, 6Eh, 20h, 72h, 65h; 448
  db 61h, 64h, 79h, 0Ah, 0Dh, 24h, 0Ah, 0Dh, 44h, 69h, 73h, 6Bh, 20h, 62h, 6Fh, 6Fh; 464
  db 74h, 20h, 66h, 61h, 69h, 6Ch, 75h, 72h, 65h, 24h, 43h, 6Fh, 70h, 72h, 2Eh, 20h; 480
  db 43h, 4Fh, 4Dh, 50h, 41h, 51h, 20h, 31h, 39h, 38h, 33h, 2Ch, 38h, 34h, 55h, 0AAh; 496




Немає коментарів:

Дописати коментар