Home
Introduction
Display
Strings
Graphics
Hardware
Interrupts
File Systems
Components
ASM Editors
Real&PMode
Assemblers
Libraries
Downloads
Links
Contact Us
 















;------------------------------
; boot sector disassembly by michael dehlwes
; from ms-dos 6.2, german version.

; this source will assemble exactly to my boot record
; this code will be loaded by bios to 0:7c00h
;  offset of error message:
;    7d9e        (used in code)
;    -19e        (physically)
;    ----
;    7c00
; then this code loads io.sys to 0:700h
; ss=es=ds=0 for most parts of code
; first 11 bytes of code (offset 3eh) will be overwritten with
; disk parameter table (dpt)
;name:             boot.bin
;filelength:       00200h - 512d
;start (cs:ip):    00000h
;code ende:        00200h  end
;code anfang:      00000h  begin
;datum:            sat jul 30 11:22:51 1994
CODE    SEGMENT BYTE PUBLIC 'CODE'
        ASSUME  CS:CODE,DS:CODE,ES:NOTHING,SS:NOTHING
        ORG     0
H00000: JMP     Short H0003E                        ;00000 eb3c
;---------------------------------------------------
        NOP                                         ;00002 90
;---------------------------------------------------
        DB      "MSDOS5.0"
        ; but it's a dos 6.2 harddisk. formats are the same, i think.
;---------------------------------------------------
        ; media description follows here.
        DB      0                                   ;0000b
        DB      02h                                 ;0000c
        ; bytes per sector
        DB      10h                                 ;0000d
        ; sectors per cluster
        DB      01h                                 ;0000e
        DB      00h                                 ;0000f
        ; boot sectors at beginning
        DB      02h                                 ;00010
        ; fat copies
        DB      00h                                 ;00011
        DB      02h                                 ;00012
        ; boot directory entries
        DB      00h                                 ;00013
        DB      00h                                 ;00014
        ; (unused): total sectors on disk
        DB      0F8h                                ;00015
        ; media descriptor byte
        DB      0CBh                                ;00016
        DB      00h                                 ;00017
        ; sectors per fat
        DB      38h                                 ;00018
        DB      00h                                 ;00019
        ; sectors per track
        DB      0Fh                                 ;0001a
        DB      00h                                 ;0001b
        ; sides
        DB      38h                                 ;0001c
        DB      00h                                 ;0001d
        DB      00h                                 ;0001e
        DB      00h                                 ;0001f
        ; special hidden sectors
        DB      0A8h                                ;00020
        DB      0A9h
        DB      0Ch
        DB      00h
        ; dword: big total number of sectors
        DB      80h                                 ;00024
        DB      00h                                 ;00025
        ; physical drive number 80h = harddisk 0
        DB      29h                                 ;00026
        ; extended boot record signature
        DB      0D8h,1Dh,";'"                       ;00027
        ; dword: volume serial number
        DB      "HD-MICHI   "                       ;0002b
        ; volume label
        DB      "FAT16   "
        ; file system id
;---------------------------------------------------
; following code will be overwritten with dpt
; 3eh-48h
; dd 49h = (sect/fat)*fats + hiddensectors + bootsectors@begin + bootdirsectors
;          this data is required when giving control to io.sys
; dd 50h = (sect/fat)*fats + hiddensectors + bootsectors
;          = location of root directory
H0003E: CLI
        XOR     AX,AX
        MOV     SS,AX           ;ss=0
        MOV     SP,7C00h        ;sp=7c00h
        PUSH    SS
        POP     ES              ;es=0
        MOV     BX,0078h
        LDS     SI,SS:[BX]      ;ds:si = [0:78h] int 1eh vector =
                                ;        pointer to disk parameter table
        PUSH    DS              ; 4 registers pushed, will only be poped
        PUSH    SI              ; when error occurred and int 19h is called
        PUSH    SS
        PUSH    BX
        MOV     DI,7C3Eh        ; start of code
        MOV     CX,0Bh          ; 11 bytes
        CLD                     ; overwrite first code with disk parameter
        REPZ    MOVSB           ; table (dpt)
        PUSH    ES
        POP     DS              ;ds=0
        ; after rep movsb di points to 7c49h, end of dpt
        ; [di-2] = dpt[9] = head settle time in milliseconds
        MOV     Byte Ptr [DI-02h],0Fh
        MOV     CX,DS:[7C18h]   ; get sectors per track
        ; [di-7] = dpt[4]
        MOV     [DI-07h],CL     ; store into dpt
        MOV     [BX+02h],AX     ; redirect dpt pointer to our data
        MOV     Word Ptr [BX],7C3Eh
        STI
        ; ax=0, dl=0, int 13h - reset disk system
        INT     13h             ;b-reset_fd
        JB      H000ED          ;error ? yes -> error prompt
        XOR     AX,AX
        CMP     DS:[7C13h],AX   ; check small field total sectors on disk
        JZ      H00084          ; this field is unused with big drives
                                ; so if 0 (unused), skip
        MOV     CX,DS:[7C13h]
        MOV     DS:[7C20h],CX   ; else store value to big field
H00084: MOV     AL,DS:[7C10h]   ; sectors per fat * fat copies (2 in my case)
        MUL     Word Ptr DS:[7C16h] ; -> dx:ax
        ADD     AX,DS:[7C1Ch]   ; add hidden sectors
        ADC     DX,DS:[7C1Eh]
        ADD     AX,DS:[7C0Eh]   ; add boot sectors at beginning
        ADC     DX,+00h
        MOV     DS:[7C50h],AX   ; store to [50h]
        MOV     DS:[7C52h],DX
        MOV     DS:[7C49h],AX   ; and to [49h]
        MOV     DS:[7C4Bh],DX
        MOV     AX,20h
        MUL     Word Ptr DS:[7C11h] ; calculate boot directory size in bytes
        MOV     BX,DS:[7C0Bh]
        ADD     AX,BX
        DEC     AX
        DIV     BX                      ; adjust to sectors
        ADD     DS:[7C49h],AX           ; add to dd [49h]
        ADC     Word Ptr DS:[7C4Bh],0
        MOV     BX,500h         ; load root directory to es:500h
        MOV     DX,DS:[7C52h]   ; location of root dir
        MOV     AX,DS:[7C50h]
        CALL    H00160          ;calc sector
        JB      H000ED          ;error? -> prompt for valid system disk
        MOV     AL,1            ;read 1 sector
        CALL    H00181          ;read hd sector
        JB      H000ED          ;error? -> prompt for valid system disk
        MOV     DI,BX           ;check if first entry is io.sys
        MOV     CX,0Bh          ;length "io      sys"
        MOV     SI,7DDFh        ;offset "io      sys"
        REPZ    CMPSB
        JNZ     H000ED          ;not identical? -> error prompt
        ; after previos rep cmps  si points at "msdos   sys"
        LEA     DI,[BX+20h]     ;load offset "msdos   sys" in root dir
        MOV     CX,0Bh          ;length "msdos   sys"
        REPZ    CMPSB
        JZ      H00105          ;identical? yes-> continue with file load
                                ;no-> error prompt
;---------------------------------
; invalid system disk, prompt for new one.
H000ED: MOV     SI,7D9Eh        ;offset "no system disk or drive error"
        CALL    H00152          ;print asciz string
        XOR     AX,AX
        INT     16h             ;b-next_kbd_char
        POP     SI
        POP     DS
        POP     [SI]
        POP     [SI+2]
        INT     19h             ;bios reboot
H00100: POP     AX              ;adjust stack
        POP     AX
        POP     AX
        JMP     Short H000ED    ;reboot
;---------------------------------------------------
; read file from disk (io.sys)
H00105: MOV     AX,[BX+1Ah]     ; get location of io.sys (in dir entry)
        DEC     AX
        DEC     AX
        MOV     BL,DS:[7C0Dh]
        XOR     BH,BH
        MUL     BX              ; convert to cluster
        ; dx:ax = [b 7c0dh] * ( [w bx+1ah] - 2 )
        ADD     AX,DS:[7C49h]
        ADC     DX,DS:[7C4Bh]
        ; dx:ax+= [dd 7c49h]
        MOV     BX,0700h        ; load io.sys to es:700h
        MOV     CX,3            ; load three sectors
; read next sector
H00120: PUSH    AX
        PUSH    DX
        PUSH    CX
        CALL    H00160          ;calc sector
        JC      H00100          ;error? -> prompt for valid system disk
        MOV     AL,01h          ;read 1 sector
        CALL    H00181          ;read hd sector
        POP     CX
        POP     DX
        POP     AX
        JB      H000ED          ;error? -> prompt for valid system disk
        ; advance to next sector
        ADD     AX,1
        ADC     DX,0
        ADD     BX,DS:[7C0Bh]
        LOOP    H00120
; give control to io.sys
        MOV     CH,DS:[7C15h]
        MOV     DL,DS:[7C24h]
        MOV     BX,DS:[7C49h]
        MOV     AX,DS:[7C4Bh]
        DB      0EAh
        DW      0,70h
        ; =jmp   0070h:0000h                         ;0014d ea00007000
;---------------------------------------------------
; write a 0-terminated string to tty (bios)
; offset in si
H00152: LODSB                                       ;00152
        OR      AL,AL                               ;00153
        JZ      H00180          ;jmp to ret instr.  ;00155
        MOV     AH,0Eh                              ;00157
        MOV     BX,0007h                            ;00159
        INT     10h             ;b-wr_tty_char      ;0015c
        JMP     Short H00152                        ;0015e
;---------------------------------------------------
; calculates logical sector
; on entry: dx:ax  (physical sector/cluster?)
; carry flag set on error
;   if dx >= [7c18h] goto errorexit
; dx:ax div [w 7c18h] -> ax
;         remainder+1 -> [b 7c4fh]=sector number
; 0:ax div [w 7c1ah]  -> [w 7c4dh]=cylinder number
;        remainder    -> [b 7c25h]=head number
H00160: CMP     DX,DS:[7C18h]                       ;00160
        JNB     H0017F          ; error exit        ;00164
        DIV     Word Ptr DS:[7C18h]                 ;00166
        INC     DL                                  ;0016a
        MOV     DS:[7C4Fh],DL                       ;0016c
        XOR     DX,DX                               ;00170
        DIV     Word Ptr DS:[7C1Ah]                 ;00172
        MOV     DS:[7C25h],DL                       ;00176
        MOV     DS:[7C4Dh],AX                       ;0017a
        CLC                                         ;0017d
        RET                     ;ret_near           ;0017e
H0017F: STC                                         ;0017f
H00180: RET                     ;ret_near           ;00180
;---------------------------------------------------
; read disk sector
; al (must be set on entry): number of sectors to read
; es:bx: offset data buffer
; byte [7c24h] = drive number
; byte [7c25h] = head number
; word [7c4dh] = cylinder number
; byte [7c4fh] = sector number
H00181: MOV     AH,02h  ; bios function read sector
        MOV     DX,DS:[7C4Dh]                       ;00183
        MOV     CL,06h                              ;00187
        SHL     DH,CL                               ;00189
        OR      DH,DS:[7C4Fh]                       ;0018b
        MOV     CX,DX                               ;0018f
        XCHG    CH,CL                               ;00191
        ; convert to bios call requirements
        ; cx=ccccccccccssssss
        ; ch=low eight bits of cylinder number           "c"
        ; cl=sector number (bits 0-5)                    "s"
        ;    high two bits of cylinder (bit 6-7 hd only) "c"
        MOV     DL,DS:[7C24h]                       ;00193
        ; dl=drive number (bit 7 set: hard disk)
        MOV     DH,DS:[7C25h]                       ;00197
        ; dh=head number
        INT     13h             ;bios-read disk sect;0019b
        RET                     ;ret_near           ;0019d
;---------------------------------------------------
        ; ralf brown says:
        ; 1beh  (16 bytes)  partition record for partition 1
        ; 1ceh  (16 bytes)  partition record for partition 2
        ; 1deh  (16 bytes)  partition record for partition 3
        ; 1eeh  (16 bytes)  partition record for partition 4
        ; but that's not valid in this case. funny.
        DB      13,10,"Kein System oder Laufwerksfehler"    ;0019e
                        ; no system or drive error
        DB      13,10,"Wechseln und Taste drcken",13,10,0
                        ; change [disk] and press key
        DB      "IO      SYS"                       ;001df
        DB      "MSDOS   SYS"                       ;001ea
        DB      9 DUP (0)         ; fill            ;001f5
        DB      055h,0AAh                           ;001fe
        ; signature, indicates valid boot block.
CODE    ENDS
        END     H00000

   

New Articles










 
Copyright © 2000 eFront Media, Inc.
Hosted by www.Geocities.ws

1