home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / HARDDISK / BOOTM13.ZIP / BOOTAUTO.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-12-17  |  6.6 KB  |  308 lines

  1.     PAGE 60,132
  2. ;    bootauto:  Auto-boot version of BOOTMENU program
  3. ;    by Gordon W. Ross, Aug 1990
  4. ;
  5. ;    See the file bootmenu.doc for user instructions.
  6. ;
  7. ;    The following is an outline of the program:
  8. ;
  9. ;    Relocate self from 0x7C00 to 0x0600
  10. ;    Display message "Booting from HD0,"
  11. ;    Search partition table for an active entry
  12. ;    If an active partition is found,
  13. ;        Delay while watching for key press (5 sec.)
  14. ;        If (key pressed) GOTO menu:
  15. ;        Else GOTO boot:
  16. ;        EndIf
  17. ;    Else (no active partition)
  18. ; menu:        Display partition menu
  19. ;        Prompt for and read user selection
  20. ;    EndIf
  21. ; boot:    Boot from the selected partition:
  22. ;    (was selected by user, or was active)
  23. ;    Read first sector of selected partition into 0x7c00
  24. ;    Verify good second-stage boot sector (magic word)
  25. ;    Set-up correct register values and jump to it.
  26. ;    If (Errors during boot) { complain; GOTO menu: }
  27. ;
  28.  
  29. DELAY    equ    5*18    ; in ticks (1/18 sec.)
  30. CODEORG    equ 0600h    ; offset of this code in code seg
  31. ; All values computed from offsets in codeseg need to be
  32. ; adjusted by adding CODEORG to each.  The obvious method,
  33. ; using "org CODEORG" causes MASM/LINK to fill in the space.
  34.  
  35. codeseg    segment
  36.     assume cs:codeseg, ds:codeseg
  37.  
  38. ; Initial program entry point
  39. ; (Assembler is told this is at offset zero.)
  40.  
  41. main:
  42.     ; Set up the stack
  43.     xor    ax,ax
  44.     mov    si,7C00h    ; just before load location
  45.     cli
  46.     mov    ss,ax
  47.     mov    sp,si
  48.     sti
  49.  
  50. ; Relocate this code from 0:7C00h to 0:CODEORG
  51.     mov    ds,ax
  52.     mov    es,ax
  53.     mov    si,7C00h    ; where this program is initially loaded
  54.     mov    di,CODEORG
  55.     mov    cx,0100h
  56.     cld
  57.     rep    movsw
  58.  
  59. ; Jump to relocated code (0:CODEORG)
  60.     jmp    far ptr begin1
  61. begin    equ    $
  62.     mov    bp,sp    ; frame pointer = 0x7C00
  63.     sub    sp,4
  64. ; 2 words of local storage:
  65. ;    [bp-2] = ptable index [0-3]
  66. ;    [bp-4] = temporary value
  67.  
  68. ; Display message "Boot device: HD0"
  69.     mov    si, offset bootdev + CODEORG
  70.     call    puts
  71.  
  72. ; Search partition table for an active entry
  73.     mov    al,0
  74. search:
  75.     call    addr_pt    ; si = & ptable[AL]
  76.     mov    DL,[si]
  77.     cmp    DL,80h
  78.     jz    found
  79.     inc    al
  80.     cmp    al,04
  81.     jb    search
  82. ; Active partition not found
  83.     jmp    menu
  84.  
  85. found:    ; Found a partition marked active.
  86.     mov    [bp-2],ax    ; Save the ptable array index
  87.  
  88. ; Delay while watching for key press (2 sec.)
  89. ; Get start time, compute end time.
  90.     mov    ah,00
  91.     int    1Ah        ; BIOS get time of day
  92.     add    dx, DELAY    ; compute end time
  93.     mov    [bp-4],dx    ; save expiration time
  94.  
  95. ; Check for key press
  96. waitkey:
  97.     mov    ah,1
  98.     int    16h        ; BIOS Keyboard
  99.     jnz    menu    ; key pressed
  100.  
  101. ; Check for expiration of delay
  102.     mov    ah,00
  103.     int    1Ah        ; BIOS get time of day
  104.     sub    dx,[bp-4]
  105.     js    waitkey    ; delay not expired
  106.  
  107. ; Delay has expired, so boot the active partition
  108.     mov    al,','
  109.     call    putc
  110.     mov    ax,[bp-2]    ; ptable index
  111.     ; the index and newline are printed later
  112.     jmp    boot
  113.  
  114. ; Display partition menu
  115. menu:
  116.     mov    ah,1        ; flush input
  117.     int    16h
  118.     jz    fl_done
  119.     mov    ah,0
  120.     int    16h
  121.     jmp    menu
  122. fl_done:
  123.  
  124. ; Print partition menu from name table
  125.  
  126.     call    putnl        ; print newline
  127.     mov    si, offset pnames ; no org fix-up here
  128.     mov    al, '1'
  129. prname:
  130.     push    si
  131.     push    ax
  132.  
  133.     call    putc
  134.     mov    al,' '
  135.     call    putc
  136.     mov    cx,8        ; maximum name length
  137.     call    putn
  138.     call    putnl
  139.  
  140.     pop    ax
  141.     pop    si
  142.     add    si,8
  143.     inc    al
  144.     cmp    al,'4'
  145.     jbe    prname
  146.  
  147. ; Prompt for and read user selection
  148. select:
  149.     call    putnl
  150.     mov    si, offset prompt + CODEORG
  151.     call    puts
  152.     ; Read a key and convert it to a number
  153.     mov    ah,0
  154.     int    16h
  155.     sub    al,'1'
  156.     cmp    al,04
  157.     jnb    select
  158.     ; The key and a newline are printed below
  159.  
  160. boot:
  161. ; Boot from the selected partition.
  162. ; On entry to this section:  AL = index of ptable element
  163.  
  164.     ; get address of ptable element
  165.     call    addr_pt    ; si = & ptable[AL]
  166.  
  167.     ; print the parition index and a newline
  168.     add    al,'1'
  169.     call    putc
  170.     call    putnl
  171.  
  172. ; Check for valid system ID (non-zero)
  173.  
  174.     mov    al,[si+4]
  175.     cmp    al,0
  176.     jnz    id_ok
  177.     mov    si, offset msgempty + CODEORG
  178.     jmp    error
  179. id_ok:
  180.  
  181. ; Read first sector of selected partition into 0x7c00
  182. ; Also, mark this entry active (in RAM only) in case the
  183. ; secondary boot program looks at it (which it may).
  184.  
  185.     mov    al,80h    ; active flag
  186.     mov    [si], al
  187.     mov    cx,5    ; retry count
  188. retry:    push    cx
  189.     mov    dx,[si]    ; drive, head
  190.     mov    cx,[si+2]    ; cyl, sector
  191.     mov    bx,7C00h    ; destination (es=0)
  192.     mov    ax,0201h    ; BIOS read one sector
  193.     int    13h
  194.     jnc    rd_ok
  195.     xor    ax,ax    ; reset disk
  196.     int    13h
  197.     pop    cx
  198.     loop    retry
  199.     mov    si, offset msgread + CODEORG
  200.     jmp    error
  201. rd_ok:    pop    cx
  202.  
  203. ; Check for valid magic number in secondary boot sector
  204.     mov    ax, 0AA55h
  205.     assume    ds:seg0        ; Actually, codeseg == seg0
  206.     cmp    ax, magic2
  207.     assume    ds:codeseg
  208.     jz    magic_ok
  209.     mov    si, offset msginvalid + CODEORG
  210.     jmp    error
  211. magic_ok:
  212.  
  213. ; Make sure ds:si points to the booted partition, and
  214. ; Jump to the secondary boot program.
  215.     jmp    far ptr begin2
  216.  
  217. ; Jump here with si=error-message
  218. error:
  219.     call    puts
  220.     call    putnl
  221.     jmp    menu
  222.  
  223. ;*************************************************************
  224. ; Subroutines
  225. ;*************************************************************
  226. CR    EQU    13
  227. LF    EQU    10
  228. TAB    EQU     9
  229.  
  230. putc    proc    near        ; print char in AL
  231.     mov    ah, 0Eh        ; uses: ax, bx
  232.     mov    bx, 07
  233.     int    10h
  234.     ret
  235. putc    endp
  236.  
  237. putnl    proc    near        ; print a newline
  238.     mov    al, CR        ; uses: ax, bx
  239.     call    putc
  240.     mov    al, LF
  241.     call    putc
  242.     ret
  243. putnl    endp
  244.  
  245. puts    proc    near        ; print string at address SI
  246.     mov    cx,80        ; Stop at null or CX chars
  247. putn:    lodsb            ; uses: ax, bx, cx, si
  248.     cmp    al,0
  249.     jz    puts_e
  250.     push    cx
  251.     call    putc
  252.     pop    cx
  253.     loop    putn
  254. puts_e:    ret
  255. puts    endp
  256.  
  257. addr_pt    proc    near        ; set SI = address of ptable[al]
  258.     push    ax        ; uses: cx (but preserves ax)
  259.     mov    si, offset ptable ; no org fix-up here
  260.     mov    cl,16    ; size of array element
  261.     mul    cl        ; ax = al * cl
  262.     add    si,ax
  263.     pop    ax
  264.     ret
  265. addr_pt    endp
  266.  
  267. ;**********************************************************
  268. ; Strings
  269. ;**********************************************************
  270.  
  271. bootdev        db    "Boot device: hd0",0
  272. prompt        db    "Boot partition? (1-4) ",0
  273. msgempty    db    "Empty!",0
  274. msgread        db    "Read error!",0
  275. msginvalid    db    "Invalid!",0
  276.     org    180h    ; this pads the length (it seems)
  277. codeseg    ends
  278.  
  279. ; Declares some offsets in segment zero
  280. seg0    segment    at 0
  281.  
  282.     org    CODEORG + (offset begin - offset main)
  283. begin1    equ    $
  284.  
  285. ; Here is the name table used for the partition menu.
  286. ; The accompanying fdisk program updates this table.
  287.     org    CODEORG + 180h
  288. pnames    db    32 dup(?)
  289.  
  290. ; The locations after 1AE are (reportedly) used by some
  291. ; Western Digital controllers in "auto-configure" mode.
  292. ; Don't put anything critical between here and ptable.
  293.  
  294. ; Here is the partition table
  295.     org    CODEORG + 1BEh
  296. ptable    db    (4 * 16) dup(?)
  297.  
  298. ; Here is where the secondary boot sector is loaded.
  299.     org    7C00h
  300. begin2    equ    $
  301.  
  302.     org    7DFEh
  303. magic2    dw    ?
  304.  
  305. seg0    ends
  306.  
  307.     end    main
  308.