home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / MINIX7.ZIP / MINIX7.TD0 / tools / bootblok.s < prev    next >
Encoding:
Text File  |  1989-10-03  |  7.9 KB  |  271 lines

  1. | When the PC is powered on, it reads the first block from the floppy
  2. | disk into address 0x7C00 and jumps to it.  This boot block must contain
  3. | the boot program in this file.  The boot program first copies itself to
  4. | address 192K - 512 (to get itself out of the way).  Then it loads the 
  5. | operating system from the boot diskette into memory, and then jumps to fsck.
  6. | Loading is not trivial because the PC is unable to read a track into
  7. | memory across a 64K boundary, so the positioning of everything is critical.
  8. | The number of sectors to load is contained at address 504 of this block.
  9. | The value is put there by the build program after it has discovered how
  10. | big the operating system is.  When the bootblok program is finished loading,
  11. | it jumps indirectly to the program (fsck) which address is given by the
  12. | last two words in the boot block. 
  13. |
  14. | Summary of the words patched into the boot block by build:
  15. | Word at 504: # sectors to load
  16. | Word at 506: # DS value for fsck
  17. | Word at 508: # PC value for fsck
  18. | Word at 510: # CS value for fsck
  19. |
  20. | This version of the boot block must be assembled without separate I & D
  21. | space.  
  22.  
  23.         LOADSEG = 0x0060         | here the boot block will start loading
  24.         BIOSSEG = 0x07C0         | here the boot block itself is loaded
  25.         BOOTSEG = 0x2FE0         | here it will copy itself (192K-512b)
  26.         DSKBASE = 120            | 120 = 4 * 0x1E = ptr to disk parameters
  27.  
  28. final   = 504
  29. fsck_ds = 506
  30. fsck_pc = 508
  31. fsck_cs = 510
  32.  
  33.  
  34. .globl begtext, begdata, begbss, endtext, enddata, endbss  | asld needs these
  35. .text
  36. begtext:
  37. .data
  38. begdata:
  39. .bss
  40. begbss:
  41. .text
  42.  
  43. | copy bootblock to bootseg
  44.         mov     ax,#BIOSSEG
  45.         mov     ds,ax
  46.         xor     si,si           | ds:si - original block
  47.         mov     ax,#BOOTSEG
  48.         mov     es,ax
  49.         xor     di,di           | es:di - new block
  50.         mov     cx,#256         | #  words to move
  51.     rep
  52.     movw            | copy loop
  53.     
  54.     
  55. | start boot procedure
  56.     jmpi    start, BOOTSEG    | set cs to BOOTSEG
  57.  
  58. start:
  59.     mov     dx,cs
  60.         mov     ds,dx           | set ds to cs
  61.         xor     ax,ax
  62.         mov     es,ax           | set es to 0
  63.         mov     ss,dx           | set ss to cs i.e., stack in high core
  64.         mov     sp,#1536        | initialize sp to high core
  65.  
  66. | print greeting
  67.     mov    ax,#2        | reset video
  68.     int    0x10
  69.  
  70.         mov     ax,#0x0200    | BIOS call in put cursor in ul corner
  71.         xor     bx,bx
  72.         xor     dx,dx
  73.         int     0x10
  74.         mov     bx,#greet
  75.         call    print
  76.  
  77. | Initialize disk parameters
  78. | Try 1.2M diskette by trying to read sector 15
  79.  
  80.     xor    ax,ax
  81.     mov    es,ax
  82.     mov    dx,ds
  83.     mov    ax,#atpar
  84.     seg    es
  85.     mov    DSKBASE,ax
  86.     seg    es
  87.     mov    DSKBASE+2,dx
  88.  
  89.     xor    ax,ax    | reset drive
  90.     int    0x13
  91.  
  92.     xor    ax,ax
  93.     mov    es,ax
  94.     mov    ax,#0x0201    | read sector, #sector = 1
  95.     mov    bx,#0x0600    | es:bx buffer
  96.     mov    cx,#0x000F    | track 0, sector 15
  97.     mov    dx,#0x0000    | drive 0, head 0
  98.     int    0x13
  99.     jnb    L1
  100.  
  101. | Error. It wasn't 1.2M. Now set up for 720K
  102.  
  103.     mov    tracksiz,#9
  104.     xor    ax,ax        | ps disk parameters are in ROM F01520
  105.     mov    es,ax
  106.     mov    ax,#0x1520
  107.     seg    es
  108.     mov    DSKBASE,ax
  109.     mov    ax,#0xF000    
  110.     seg    es
  111.     mov    DSKBASE+2,ax
  112.  
  113. | Try 720K by trying to read track 64.
  114. | 360K has 40 tracks, 720 has 80 tracks.
  115.  
  116.     xor    ax,ax    | diskette reset
  117.     int    0x13
  118.     mov    tracksiz,#9
  119.  
  120.     xor    ax,ax
  121.     mov    es,ax
  122.     mov    ax,#0x0201    | read sector, number of sectors is 1
  123.     mov    bx,#0x0600    | es:bx buffer
  124.     mov    cx,#0x4001    | track 64, sector 1
  125.     mov    dx,#0x0000    | drive 0, head 0
  126.     int    0x13
  127.     jnb    L1
  128.  
  129. | Error. It wasn't 720K either. Now set up for 360K
  130.  
  131.     xor    ax,ax
  132.     mov    es,ax
  133.     mov    dx,ds
  134.     mov    ax,#pcpar
  135.     seg    es
  136.     mov    DSKBASE,ax
  137.     seg    es
  138.     mov    DSKBASE+2,dx
  139.     xor    ax,ax        | diskette reset
  140.     int    0x13
  141.  
  142. L1:
  143.  
  144. | Load the operating system from diskette.
  145. load:
  146.     call    setreg        | set up ah, cx, dx
  147.     mov    bx,disksec    | bx = number of next sector to read
  148.     add    bx,#2        | diskette sector 1 goes at 1536 ("sector" 3)
  149.     shl    bx,#1        | multiply sector number by 32
  150.     shl    bx,#1        | ditto
  151.     shl    bx,#1        | ditto
  152.     shl    bx,#1        | ditto
  153.     shl    bx,#1        | ditto
  154.     mov    es,bx        | core address is es:bx (with bx = 0)
  155.     xor    bx,bx        | see above
  156.     add    disksec,ax    | ax tells how many sectors to read
  157.     movb    ah,#2        | opcode for read
  158.     int    0x13        | call the BIOS for a read
  159.     jb    error        | jump on diskette error
  160.     mov    ax,disksec    | see if we are done loading
  161.     cmp    ax,final    | ditto
  162.     jb    load        | jump if there is more to load
  163.  
  164. | Loading done.  Finish up.
  165.         mov     dx,#0x03F2      | kill the motor
  166.         mov     ax,#0x000C
  167.         out
  168.         cli
  169.     mov    bx,tracksiz    | fsck expects # sectors/track in bx
  170.         mov     ax,fsck_ds      | set segment registers
  171.         mov     ds,ax           | when sep I&D DS != CS
  172.         mov     es,ax           | otherwise they are the same.
  173.         mov     ss,ax           | words 504 - 510 are patched by build
  174.  
  175.     seg cs
  176.     jmpi    @fsck_pc    | jmp to fsck
  177.  
  178. | Given the number of the next disk block to read, disksec, compute the
  179. | cylinder, sector, head, and number of sectors to read as follows:
  180. | ah = # sectors to read;  cl = sector #;  ch = cyl;  dh = head; dl = 0
  181. setreg:    
  182.     mov    si,tracksiz    | 9 (PC) or 15 (AT) sectors per track
  183.     mov     ax,disksec    | ax = next sector to read
  184.     xor    dx,dx        | dx:ax = 32-bit dividend
  185.     div    si        | divide sector # by track size
  186.     mov    cx,ax        | cx = track #; dx = sector (0-origin)
  187.     mov    bx,dx        | bx = sector number (0-origin)
  188.     mov    ax,disksec    | ax = next sector to read
  189.     add    ax,si        | ax = last sector to read + 1
  190.     dec    ax        | ax = last sector to read
  191.     xor    dx,dx        | dx:ax = 32-bit dividend
  192.     div    tracksiz    | divide last sector by track size
  193.     cmpb    al,cl        | is starting track = ending track
  194.     je    set1        | jump if whole read on 1 cylinder
  195.     sub    si,dx        | compute lower sector count
  196.     dec    si        | si = # sectors to read
  197.  
  198. | Check to see if this read crosses a 64K boundary (128 sectors).
  199. | Such calls must be avoided.  The BIOS gets them wrong.
  200. set1:    mov    ax,disksec    | ax = next sector to read
  201.     add    ax,#2        | disk sector 1 goes in core sector 3
  202.     mov    dx,ax        | dx = next sector to read
  203.     add    dx,si        | dx = one sector beyond end of read
  204.     dec    dx        | dx = last sector to read
  205.     shl    ax,#1        | ah = which 64K bank does read start at
  206.     shl    dx,#1        | dh = which 64K bank foes read end in
  207.     cmpb    ah,dh        | ah != dh means read crosses 64K boundary
  208.     je    set2        | jump if no boundary crossed
  209.     shrb    dl,#1        | dl = excess beyond 64K boundary
  210.     xorb    dh,dh        | dx = excess beyond 64K boundary
  211.     sub    si,dx        | adjust si
  212.     dec    si        | si = number of sectors to read
  213.  
  214. set2:    mov    ax,si        | ax = number of sectors to read
  215.     xor    dx,dx        | dh = head, dl = drive
  216.     movb    dh,cl        | dh = track
  217.     andb    dh,#0x01    | dh = head
  218.     movb    ch,cl        | ch = track to read
  219.     shrb    ch,#1        | ch = cylinder
  220.     movb    cl,bl        | cl = sector number (0-origin)
  221.     incb    cl        | cl = sector number (1-origin)
  222.     xorb    dl,dl        | dl = drive number (0)
  223.     ret            | return values in ax, cx, dx
  224.  
  225.  
  226. |-------------------------------+
  227. |    error & print routines     |
  228. |-------------------------------+
  229.  
  230. error:
  231.         push    ax
  232.         mov     bx,#fderr
  233.         call    print           | print msg
  234.     xor    cx,cx
  235. err1:    mul    0        | delay
  236.     loop    err1
  237.     int    0x19
  238.  
  239.  
  240. print:                          | print string (bx)
  241.         movb    al,(bx)            | al contains char to be printed
  242.         testb   al,al           | null char?
  243.         jne     prt1            | no
  244.         ret                     | else return
  245. prt1:   movb    ah,#14          | 14 = print char
  246.         inc     bx              | increment string pointer
  247.         push    bx              | save bx
  248.         movb    bl,#1           | foreground color
  249.     xorb    bh,bh        | page 0
  250.         int     0x10            | call BIOS VIDEO_IO
  251.         pop     bx              | restore bx
  252.         jmp     print           | next character
  253.  
  254.  
  255. disksec:.word 1
  256. pcpar:    .byte    0xDF, 0x02, 25, 2, 9, 0x2A, 0xFF, 0x50, 0xF6, 1, 3 | for pc
  257. atpar:    .byte    0xDF, 0x02, 25, 2,15, 0x1B, 0xFF, 0x54, 0xF6, 1, 8 | for at
  258.  
  259. fderr:    .asciz "Read error.  Automatic reboot.\r\n"
  260. greet:    .asciz "\rBooting MINIX 1.3.  Copyright 1988 Prentice-Hall, Inc.\r\n"
  261. tracksiz:.word 15    | changed to 9 for ps and pc
  262.  
  263. | Don't forget that words 504 - 510 are filled in by build.  The regular
  264. | code had better not get that far.
  265. .text
  266. endtext:
  267. .data
  268. enddata:
  269. .bss
  270. endbss:
  271.