home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd2.bin / dosutils / bootlin / bootlin.asm next >
Assembly Source File  |  1994-10-16  |  26KB  |  1,375 lines

  1.  
  2.         NAME    BootLinux
  3.  
  4. MainSeg        SEGMENT PUBLIC 'TEXT'
  5.         ASSUME cs:MainSeg, ds:MainSeg, es:MainSeg
  6.  
  7.         ORG 0100h        ; it is going to be a COM file
  8.  
  9. BootlinVersion    EQU "1.6b"
  10.  
  11. FileNameSize    EQU 80
  12. StackSize    EQU 2048
  13. PlusSize    EQU (FileNameSize+StackSize)
  14. PageOrder    EQU 12            ; 4K pages ; max is 14 (16K)
  15. DotOrder    EQU 14            ; print a dot every 16K loaded
  16. PageLength    EQU (1 SHL PageOrder)
  17. PageSegInc    EQU (PageLength SHR 4)
  18. KernelStart    EQU 1000h
  19. KernelEnd    EQU 9000h
  20. SetupPage    EQU 9000h
  21. SetupStack    EQU PageLength*2    ; multiple of PageLength
  22.                     ; startpoint of stack pointer
  23. SetupSpaceSect    EQU (((SetupStack-1) SHR 9)+1)
  24.                     ; in sectors of 512 bytes
  25. SetupSpaceInc    EQU (((SetupStack-1) SHR 4)+1)
  26.                     ; in page segment increments
  27. BootLoad    EQU 9000h
  28. BootLength    EQU 200h
  29. SetupLoad    EQU 9020h
  30. SetupLength    EQU 800h        ; this is only a default since
  31.                     ; linux v1.1
  32. MaxMemory    EQU 0A000h
  33. MinExtended    EQU 1024
  34. BootlinPage    EQU (MaxMemory-PageSegInc)
  35. VideoVGA    EQU 0FFFFh        ; 80x25
  36. VideoVGAext    EQU 0FFFEh        ; 80x50
  37. VideoASK    EQU 0FFFDh
  38. VideoUnspec    EQU 8000h
  39. ;    StatusLine    EQU 10
  40. StatusLine    EQU 9
  41. BootFlag    EQU 0AA55h
  42. ; Boot Sector Offsets (to the end)
  43. bsoBootFlag    EQU 2
  44. bsoRootDev    EQU 4
  45. bsoVideo    EQU 6
  46. bsoRamDiskSize    EQU 8
  47. bsoSwapDev    EQU 10
  48. ; These are for very old images only
  49. ;    bsoSwapDev    EQU 8
  50. ;    bsoRamDiskSize    EQU 10
  51. ; These are are since linux v1.1
  52. bsoSysSize    EQU 12
  53. bsoRootRdOnly    EQU 14
  54. bsoSetupSectors    EQU 15
  55. waitLaunch    EQU 20
  56. waitLoaded    EQU 10
  57.  
  58. ;**********************************************************
  59. ; Here is the relocated part of BootLinux
  60. ;**********************************************************
  61.  
  62. JumpStart    PROC FAR
  63.         jmp TheStart
  64. JumpStart    ENDP
  65.  
  66.         ASSUME cs:MainSeg, ds:NOTHING, es:NOTHING
  67. NewInt13    PROC FAR
  68.         cmp ax,1500h
  69.         je nobypass
  70. bypass:        jmp dword ptr cs:oldint
  71.  
  72. nobypass:    cmp byte ptr cs:[doRelocate],0
  73.         je bypass    ; linux v1.1 calls 13,..15,..13,11
  74.  
  75.         push bp
  76.         mov bp,sp
  77.         push word ptr [bp+6]
  78.         call dword ptr cs:oldint
  79.         pop bp
  80.         cli
  81.         pushf
  82.         push ds
  83.         push es
  84.         push si
  85.         push di
  86.         push ax
  87.         push bx
  88.         push cx
  89.         push dx
  90.  
  91.         mov si,cs:pageToMove
  92.         mov di,KernelStart
  93.  
  94. domove:        call MovePage
  95.         cmp si,cs:lastToMove
  96.         je endmove
  97.         cmp di,SetupPage
  98.         je endmove
  99.         cmp si,SetupPage
  100.         jne domove
  101.         add si,SetupSpaceInc
  102.         jmp short domove    ; skip the setup page
  103. endmove:
  104.  
  105.         pop dx
  106.         pop cx
  107.         pop bx
  108.         pop ax
  109.         pop di
  110.         pop si
  111.         pop es
  112.         pop ds
  113.         popf
  114.         ret 2
  115.  
  116. oldint        dd 0
  117. pageToMove    dw 0
  118. lastToMove    dw 0
  119. doRelocate    db 0
  120. NewInt13    ENDP
  121.  
  122. NewInt15    PROC FAR        ; to simulate untouched Int 15h
  123.         cmp ah,88h
  124.         je next15
  125.         jmp dword ptr cs:oldint15
  126.  
  127. next15:        mov byte ptr cs:[doRelocate],1
  128.         mov ax,cs:[extmem]
  129.         iret
  130.  
  131. oldint15    dd 0
  132. extmem        dw 0
  133. NewInt15    ENDP
  134.  
  135. NewInt11    PROC FAR        ; to simulate untouched Int 11h
  136.         cli
  137.         mov ax,cs:[equip]
  138.         iret
  139.  
  140. equip        dw 0
  141. NewInt11    ENDP
  142.  
  143.         ASSUME cs:MainSeg, ds:NOTHING, es:NOTHING
  144. MovePage    PROC NEAR        ; moves page at si:0 to frame at di:0
  145.         push ds
  146.         push es
  147.         push cx
  148.         mov ds,si
  149.         mov es,di
  150.         xor si,si
  151.         xor di,di
  152.         mov cx,(PageLength SHR 1)
  153.         cld
  154.         rep movsw
  155.         mov si,ds
  156.         mov di,es
  157.         add si,PageSegInc
  158.         add di,PageSegInc
  159.         pop cx
  160.         pop es
  161.         pop ds
  162.         ret
  163. MovePage    ENDP            ; returns di and si on next pages
  164.  
  165. ;**********************************************************
  166. ; Here the static part of BootLinux
  167. ;**********************************************************
  168.  
  169.         ASSUME cs:MainSeg, ds:MainSeg, es:MainSeg
  170.  
  171. BiosWait    PROC NEAR ; (cx=1/18th of seconds to wait)
  172.         push cx
  173.         mov ah,0
  174.         int 1Ah
  175.         pop cx
  176.         add cx,dx
  177. w1:        push cx
  178.         mov ah,0
  179.         int 1Ah
  180.         pop cx
  181.         cmp dx,cx
  182.         jc w1
  183.         ret
  184. BiosWait    ENDP
  185.  
  186. InitScr        PROC NEAR ; () -> ()
  187.         mov ah,0Fh    ; get BIOS video mode
  188.         int 10h
  189.         and al,7Fh    ; and set it again, this clears screen,
  190.         mov ah,0    ; and preserves video mode (mono/color)
  191.         int 10h
  192.         mov ax,500h
  193.         int 10h
  194.         ret
  195. InitScr        ENDP
  196.  
  197. WrChar        PROC NEAR ; (al=char to write) -> ()
  198.         mov ah,0Eh    ; this is "teletype" output
  199.         mov bx,7    ; handles CR, LF
  200.         int 10h
  201.         ret
  202. WrChar        ENDP
  203.  
  204. WrCharRep    PROC NEAR ; (al=char to write;cx=times) -> ()
  205.         jcxz eWrCharRep
  206. aWrCharRep:    mov ah,0Eh
  207.         mov bx,7
  208.         push cx
  209.         int 10h
  210.         pop cx
  211.         loop aWrCharRep
  212. eWrCharRep:    ret
  213. WrCharRep    ENDP
  214.  
  215. WrStr        PROC NEAR ; (ds:dx=ASCIIZ string to write) -> ()
  216.         mov bx,7
  217.         mov si,dx
  218.         cld
  219. aWrStr:        lodsb
  220.         cmp al,0
  221.         je eWrStr
  222.         push si
  223.         push bx
  224.         mov ah,0Eh    ; teletype output (CR, LF are OK)
  225.         int 10h
  226.         pop bx
  227.         pop si
  228.         jmp short aWrStr
  229. eWrStr:        ret
  230. WrStr        ENDP
  231.  
  232. SetCursor    PROC NEAR ; (ah=column; al=row) -> ()
  233.         push ax
  234.         mov dh,al
  235.         mov dl,ah
  236.         mov ah,2
  237.         mov bh,0
  238.         int 10h
  239.         pop ax
  240.         ret
  241. SetCursor    ENDP
  242.  
  243. ClrStatus    PROC NEAR ; () -> ()
  244.         mov ax,0600h    ; clears lines 12 down to 24 (last of screen)
  245.         mov bh,7
  246.         mov cx,(StatusLine SHL 8)
  247.         mov dx,184Fh
  248.         int 10h
  249.         mov ax,StatusLine
  250.         jmp SetCursor
  251. ClrStatus    ENDP
  252.  
  253. WrStatus    PROC NEAR ; (ds:dx=message) -> () cursor is not replaced to its original position
  254.         push dx
  255.         call ClrStatus
  256.         pop dx
  257.         jmp WrStr
  258. WrStatus    ENDP
  259.  
  260. WrNum        PROC NEAR ; (ax=number to print) -> ()
  261.         mov bx,offset numbuf
  262.         mov word ptr [bx],2020h
  263.         mov word ptr [bx+2],2020h
  264.         mov byte ptr [bx+4],'0'
  265.         add bx,5
  266.         mov cx,10
  267.         mov dl,'0'-'0'
  268. aNum:        dec bx
  269.         or ax,ax
  270.         jz nNum
  271.         xor dx,dx
  272.         div cx
  273. nNum:        push ax
  274.         mov al,dl
  275.         mov dl,' '-'0'
  276.         add al,'0'
  277.         mov [bx],al
  278.         pop ax
  279.         cmp bx,offset numbuf
  280.         jne aNum
  281.         mov dx,bx
  282.         jmp WrStr
  283. numbuf        db 5 dup (' '),0
  284. WrNum        ENDP
  285.  
  286. ShowGrid    PROC NEAR
  287.         xor ax,ax
  288.         call SetCursor
  289.         mov al,201
  290.         call WrChar
  291.         mov al,205
  292.         mov cx,77
  293.         call WrCharRep
  294.         mov al,187
  295.         call WrChar
  296.         mov al,1
  297. aShowGrid:    push ax
  298.         mov ah,0
  299.         call SetCursor
  300.         mov al,186
  301.         call WrChar
  302.         pop ax
  303.         push ax
  304.         mov ah,39
  305.         call SetCursor
  306.         mov al,179
  307.         call WrChar
  308.         pop ax
  309.         push ax
  310.         mov ah,78
  311.         call SetCursor
  312.         mov al,186
  313.         call WrChar
  314.         pop ax
  315.         inc al
  316.         cmp al,(StatusLine-2)
  317.         jc aShowGrid
  318.         mov ah,0
  319.         call SetCursor
  320.         mov al,200
  321.         call WrChar
  322.         mov al,205
  323.         mov cx,38
  324.         call WrCharRep
  325.         mov al,207
  326.         call WrChar
  327.         mov al,205
  328.         mov cx,38
  329.         call WrCharRep
  330.         mov al,188
  331.         call WrChar
  332.         mov ax,2
  333.         call SetCursor
  334.         mov al,204
  335.         call WrChar
  336.         mov al,205
  337.         mov cx,38
  338.         call WrCharRep
  339.         mov al,209
  340.         call WrChar
  341.         mov al,205
  342.         mov cx,38
  343.         call WrCharRep
  344.         mov al,185
  345.         call WrChar
  346.         mov ax,1401h
  347.         call SetCursor
  348.         mov dx,offset Copyright
  349.         call WrStr
  350. ShowGrid    ENDP
  351.  
  352. Memory        PROC NEAR ; () -> ()
  353.         mov    al,18h
  354.         out    70h,al
  355.         in    al,71h
  356.         mov    ah,al
  357.         mov    al,17h
  358.         out    70h,al
  359.         in    al,71h
  360.         mov extmem,ax
  361.         int 12h
  362.         mov basemem,ax
  363.         ret
  364. basemem        dw 0
  365. Memory        ENDP
  366.  
  367. ShowMachine    PROC NEAR ; () -> ()
  368.         call ClrStatus
  369.         mov ax,0203h
  370.         call SetCursor
  371.         mov dx,offset nCPU
  372.         call WrStr
  373.         mov ax,0204h
  374.         call SetCursor
  375.         mov dx,offset nBase
  376.         call WrStr
  377.         mov ax,0205h
  378.         call SetCursor
  379.         mov dx,offset nExtended
  380.         call WrStr
  381.         call Memory
  382.         mov ax,2004h
  383.         call SetCursor
  384.         mov ax,basemem
  385.         call WrNum
  386.         mov al,'K'
  387.         call WrChar
  388.         mov ax,2005h
  389.         call SetCursor
  390.         mov ax,extmem
  391.         mov dx,offset nNone
  392.         or ax,ax
  393.         jz mach1
  394.         call WrNum
  395.         mov al,'K'
  396.         call WrChar
  397.         jmp short mach2
  398. mach1:        call WrStr
  399. mach2:        mov ax,1703h
  400.         call SetCursor
  401.         call CheckCPU
  402.         cmp ax,offset Cpu386
  403.         jc mach3
  404.         cmp word ptr basemem,(MaxMemory SHR 6)
  405.         jc mach4
  406.         cmp word ptr extmem,MinExtended
  407.         jc mach5
  408.         mov ax,StatusLine
  409.         jmp SetCursor
  410. mach3:        mov dx,offset eCpu
  411. Infinite:    push cs
  412.         pop ds
  413.         call WrStatus
  414.         mov dx,offset eReboot
  415.         call WrStr
  416.         sti
  417. infinite:    mov ah,8
  418.         int 21h
  419.         jmp short infinite
  420. mach4:        mov dx,offset eBasMem
  421.         jmp Infinite
  422. mach5:        mov dx,offset eExtMem
  423.         jmp Infinite
  424. ShowMachine    ENDP
  425.  
  426. WrDev        PROC NEAR ; (ax=dev major/minor) -> ()
  427.         or ax,ax
  428.         jnz wd0
  429.         mov dx,offset nNone
  430.         jmp WrStr
  431. wd0:        cmp ah,2        ; floppies
  432.         jne wd1
  433.         push ax
  434.         mov al,' '
  435.         mov cx,3
  436.         call WrCharRep
  437.         mov al,'f'
  438.         call WrChar
  439.         mov al,'d'
  440.         call WrChar
  441.         pop ax
  442.         and al,1
  443.         add al,'0'
  444.         jmp WrChar
  445. wd1:        cmp ah,3        ; AT hard disks
  446.         jne wd2
  447.         push ax
  448.         mov al,' '
  449.         mov cx,2
  450.         call WrCharRep
  451.         mov al,'h'
  452.         call WrChar
  453.         mov al,'d'
  454.         call WrChar
  455.         pop ax
  456.         push ax
  457.         mov cl,6
  458.         shr al,cl
  459.         add al,'a'
  460.         call WrChar
  461.         pop ax
  462.         and al,1Fh
  463.         add al,'0'
  464.         jmp WrChar
  465. wd2:        cmp ah,8        ; SCSI hard disks
  466.         jne wd3
  467.         push ax
  468.         mov al,' '
  469.         mov cx,2
  470.         call WrCharRep
  471.         mov al,'s'
  472.         call WrChar
  473.         mov al,'d'
  474.         call WrChar
  475.         pop ax
  476.         push ax
  477.         mov cl,4
  478.         shr al,cl
  479.         add al,'a'
  480.         call WrChar
  481.         pop ax
  482.         and al,0Fh
  483.         add al,'0'
  484.         jmp WrChar
  485. wd3:        ; unknown
  486.         mov dx,offset nUnknown
  487.         jmp WrStr
  488.  
  489. WrDev        ENDP
  490.  
  491. ShowLinux    PROC NEAR ; () -> ()
  492.         call ClrStatus
  493.         mov ax,2903h
  494.         call SetCursor
  495.         mov dx,offset nSize
  496.         call WrStr
  497.         mov ax,4703h
  498.         call SetCursor
  499.         mov ax,lastToMove
  500.         cmp ax,SetupPage
  501.         jbe sl1
  502.         sub ax,PageSegInc
  503. sl1:        sub ax,pageToMove
  504.         mov klen,ax
  505.         mov cl,6
  506.         shr ax,cl
  507.         call WrNum
  508.         mov al,'K'
  509.         call WrChar
  510.         mov ax,2904h
  511.         call SetCursor
  512.         mov dx,offset nRootDev
  513.         call WrStr
  514.         mov ax,2905h
  515.         call SetCursor
  516.         mov dx,offset nVideo
  517.         call WrStr
  518. ;        mov ax,2906h
  519. ;        call SetCursor
  520. ;        mov dx,offset nSwapDev
  521. ;        call WrStr
  522.         mov ax,2906h
  523. ;        mov ax,2907h
  524.         call SetCursor
  525.         mov dx,offset nRamDisk
  526.         call WrStr
  527.         push es
  528.         mov ax,BootLoad
  529.         mov es,ax
  530.         mov ax,4704h
  531.         call SetCursor
  532.         mov ax,word ptr es:[200h-bsoRootDev]
  533.         call WrDev
  534. ;        mov ax,4706h
  535. ;        call SetCursor
  536. ;        mov ax,word ptr es:[200h-bsoSwapDev]
  537. ;        call WrDev
  538.         mov ax,4706h
  539. ;        mov ax,4707h
  540.         call SetCursor
  541.         mov ax,word ptr es:[200h-bsoRamDiskSize]
  542.         mov dx,offset nNone
  543.         or ax,ax
  544.         jz sl2
  545.         call WrNum
  546.         mov al,'K'
  547.         call WrChar
  548.         jmp short sl3
  549. sl2:        call WrStr
  550. sl3:        mov ax,4805h
  551.         call SetCursor
  552.         mov ax,word ptr es:[200h-bsoVideo]
  553.         pop es
  554.         cmp ax,VideoVGA
  555.         jne sl4
  556.         mov dx,offset n80x25
  557.         jmp WrStr
  558. sl4:        cmp ax,VideoVGAext
  559.         jne sl5
  560.         mov dx,offset n80x50
  561.         jmp WrStr
  562. sl5:        cmp ax,VideoASK
  563.         jne sl6
  564.         mov dx,offset nAsk
  565.         jmp WrStr
  566. sl6:        cmp ax,10
  567.         jae sl7
  568.         push ax
  569.         mov dx,offset nSVGA
  570.         call WrStr
  571.         pop ax
  572.         add al,'0'
  573.         jmp WrChar
  574. sl7:        mov dx,offset nUnknownSp
  575.         jmp WrStr
  576. klen        dw 0
  577. ShowLinux    ENDP
  578.  
  579. UpdateBoot    PROC NEAR ; () -> ()
  580.         push es
  581.         mov ax,BootLoad
  582.         mov es,ax
  583.         mov ax,rootdevice
  584.         or ax,ax
  585.         jz ub1
  586.         mov word ptr es:[200h-bsoRootDev],ax
  587. ub1:;        mov ax,swapdevice
  588. ;        or ax,ax
  589. ;        jz ub2
  590. ;        mov word ptr es:[200h-bsoSwapDev],ax
  591. ub2:        mov ax,videomode
  592.         cmp ax,VideoUnspec
  593.         je ub3
  594.         mov word ptr es:[200h-bsoVideo],ax
  595. ub3:        mov ax,ramdisksize
  596.         or ax,ax
  597.         jz ub4
  598.         mov word ptr es:[200h-bsoRamDiskSize],ax
  599. ub4:        pop es
  600.         ret
  601. UpdateBoot    ENDP
  602.  
  603. CheckBootDev    PROC NEAR
  604.         push es
  605.         mov ax,BootLoad
  606.         mov es,ax
  607.         mov bx,200h-bsoRootDev
  608.         cmp word ptr es:[bx],0
  609.         jnz cbd1
  610.         push es
  611.         push bx
  612.         call GetRootDevice
  613.         pop bx
  614.         pop es
  615.         mov word ptr es:[bx],ax
  616.         call ShowLinux
  617. cbd1:        pop es
  618.         ret
  619. CheckBootDev    ENDP
  620.  
  621. TheStart    PROC NEAR
  622.         call InitScr
  623.         call ShowGrid
  624.         call ShowMachine
  625.  
  626.         mov bx,offset TheEnd
  627.         add bx,PlusSize        ; compute start of the new stack
  628.  
  629.         cli
  630.         push cs
  631.         pop ss
  632.         mov sp,bx
  633.         sti            ; sets the new stack
  634.  
  635.         mov cl,4
  636.         dec bx
  637.         shr bx,cl
  638.         inc bx
  639.         mov ax,ss
  640.         add ax,bx        ; compute the segment after the stack
  641.         mov si,KernelStart
  642.         cmp ax,si
  643.         jae ts1
  644.         mov ax,si
  645. ts1:        mov pageToMove,ax    ; save it, this may be the load addr
  646.  
  647.         push ax
  648.         call ParseOptions
  649.         pop ax
  650.         push ax
  651.         call ReadLinux
  652.         mov lastToMove,ax
  653.         call UpdateBoot
  654.         call ShowLinux
  655.         mov dx,offset e512
  656.         cmp word ptr klen,8000h
  657.         ja ts1a
  658.         call CheckBootDev
  659.         mov dx,offset mEmpty
  660.         call WrStatus
  661.         mov cx,waitLaunch
  662.         cmp byte ptr launchWait,0
  663.         je ts2
  664.         mov dx,offset mLaunch
  665.         call WrStatus
  666.         mov ah,8
  667.         int 21h
  668.         xor cx,cx
  669. ts2:        call BiosWait
  670.         call InitScr
  671.         pop ax
  672.  
  673.         cmp ax,KernelStart    ; and check it doesn't overlap
  674.         ja moreComplicated
  675.  
  676.         mov ax,3515h
  677.         int 21h
  678.         mov word ptr oldint15,bx
  679.         mov word ptr [oldint15+2],es
  680.         mov dx,offset NewInt15
  681.         mov ax,2515h
  682.         int 21h
  683.         jmp short RunLinux
  684.         
  685. ts1a:        jmp Infinite
  686.  
  687. moreComplicated:
  688.         int 11h
  689.         mov equip,ax
  690.         mov ax,3513h
  691.         int 21h
  692.         mov word ptr oldint,bx
  693.         mov word ptr [oldint+2],es
  694.         mov ax,3515h
  695.         int 21h
  696.         mov word ptr oldint15,bx
  697.         mov word ptr [oldint15+2],es
  698.         mov si,cs
  699.         mov di,BootlinPage
  700.         push ds
  701.         push di
  702.         call MovePage
  703.         pop ds
  704.         mov dx,offset NewInt11
  705.         mov ax,2511h
  706.         int 21h
  707.         mov dx,offset NewInt13
  708.         mov ax,2513h
  709.         int 21h
  710.         mov dx,offset NewInt15
  711.         mov ax,2515h
  712.         int 21h
  713.         pop ds
  714.  
  715. RunLinux:
  716.         cli
  717.         mov bx,SetupPage
  718.         mov ds,bx
  719.         mov es,bx
  720.         mov ss,bx
  721.         mov sp,SetupStack    ; the setup stack ; no space for
  722.         sti            ; disk param table, because no need
  723.  
  724.         mov bx,SetupLoad     ; here I made a mistake last time
  725.         push bx
  726.         xor bx,bx
  727.         push bx
  728.         retf
  729. TheStart    ENDP
  730.  
  731.         ASSUME cs:MainSeg, ds:MainSeg, es:MainSeg
  732. ReadLinux    PROC NEAR ; (ax=page where to start loading) -> (ax=just after the last page loaded)
  733.         push ax
  734. TryAgain:
  735.         mov ax,03d00h        ; tries to open the specified file
  736.         mov dx,offset filename    ; in READ-ONLY mode
  737.         int 21h
  738.         jnc OpenIsOk
  739.  
  740.         mov dx,offset mFile    ; fail: print error msg and
  741.         call WrStatus
  742.         call AskFileName    ; asks for another file name
  743.         jmp short TryAgain    ; and try again until it succeeds
  744.  
  745. OpenIsOk:    mov filehandle,ax    ; save file handle
  746.  
  747.         mov dx,offset mBoot    ; bootsect load message
  748.         call WrStatus
  749.  
  750.         mov di,BootLoad        ; target:= 9000:0
  751.         mov cx,BootLength    ; size:= 1 sector = 512 bytes
  752.         call sectread        ; reads boot sector
  753.         jne Image        ; fail => bad length
  754.  
  755.         call bootcheck        ; checks for 0AA55h at the end
  756.         jne BootError
  757.  
  758.         mov dx,offset mSetup    ; setup load message
  759.         call WrStr
  760.  
  761.         mov di,SetupLoad    ; target:= 9000:200
  762. ; This is no more true since linux v1.1: the number of setup sectors
  763. ; to load is now indicated in the boot sector, offset 497
  764. ; (named here bsoSetupSectors)
  765. ;
  766. ;        mov cx,SetupLength    ; size:= 4 sectors = 2K
  767. ;
  768. ; Replaced with a definition check at this offset, embedded in a call
  769.         call setSetupLength    ; preserves di
  770.         call sectread        ; reads setup
  771.         jne Image        ; fail => bad length
  772.  
  773.         mov dx,offset mKernel    ; kernel load message
  774.         call WrStr
  775.  
  776.         pop di            ; start kernel loading at ????:0
  777.         mov cx,PageLength    ; read it by pages
  778.  
  779. kernrd:
  780.         cmp di,SetupPage
  781.         jne rl1
  782.         add di,PageSegInc
  783.         jmp short readpage
  784. rl1:        cmp di,BootlinPage
  785.         jne readpage
  786.         mov dx,offset eBig
  787.         jmp Infinite
  788. readpage:
  789.  
  790.         call sectread        ; reads the page
  791.  
  792.         pushf            ; save useful flags
  793.         add di,PageSegInc    ; next page
  794.         push cx
  795.         push di
  796.         mov cl,(PageOrder-4)
  797.         shr di,cl
  798.         and di,((1 SHL (DotOrder-PageOrder))-1)
  799.         jnz rl2
  800.         mov al,'.'        ; print one dot
  801.         call WrChar
  802. rl2:        pop di
  803.         pop cx
  804.         popf            ; and restore flags (Z interesting)
  805.  
  806.         jnz close        ; if the whole page has been read,
  807.                     ; continue, else close file
  808.         jmp short kernrd
  809.  
  810. BootError:
  811.         mov dx,offset eBoot
  812.         jmp Infinite
  813.  
  814. Image:        mov dx,offset eShort
  815.         jmp Infinite
  816.  
  817. close:        push di
  818.         mov ah,3eh
  819.         mov bx,filehandle
  820.         int 21h            ; otherwise, close the file
  821.  
  822.         mov dx,offset mDone    ; done message
  823.         call WrStr
  824.  
  825.         mov cx,waitLoaded
  826.         call BiosWait
  827.  
  828.         pop ax
  829.         ret
  830. ReadLinux    ENDP
  831.  
  832.         ASSUME ds:MainSeg
  833. sectread    PROC NEAR        ; tries to read cx bytes at di:0
  834.         push ds            ; returns ZF set if all bytes read
  835.         push bx
  836.         push cx
  837.         mov bx,word ptr filehandle
  838.         mov ds,di
  839.         xor dx,dx
  840.         mov ah,03fh
  841.         int 21h
  842.         mov di,ds
  843.         pop cx
  844.         pop bx
  845.         pop ds
  846.         jc dumbError
  847.         cmp ax,cx
  848.         ret
  849. dumbError:    mov dx,offset eRead
  850.         jmp Infinite
  851. sectread    ENDP
  852.  
  853.         ASSUME ds:NOTHING
  854. bootcheck    PROC NEAR
  855.         push ds
  856.         mov ax,BootLoad
  857.         mov ds,ax
  858.         mov ax,word ptr ds:[200h-bsoBootFlag]
  859.         pop ds
  860.         cmp ax,BootFlag
  861.         ret
  862. bootcheck    ENDP
  863.  
  864. setSetupLength    PROC NEAR
  865.         push di
  866.         push ds
  867.         mov ax,BootLoad
  868.         mov ds,ax
  869.         mov al,byte ptr ds:[200h-bsoSetupSectors]
  870.         mov di,SetupLength    ; This is the default value
  871.         cmp al,4        ; n<4 is not surely not valid
  872.         jc dftSetupLength
  873.         cmp al,SetupSpaceSect-3
  874.         ; setup space (?) - boot sector (1) - setup stack (2)
  875.         ja dftSetupLength    ; will this be enough ?!
  876.         xor ah,ah
  877.         mov cl,9        ; multiply by 512 to have the real size
  878.         shl ax,cl
  879.         mov di,ax
  880. dftSetupLength:    mov cx,di
  881.         pop ds
  882.         pop di
  883.         ret
  884. setSetupLength    ENDP
  885.  
  886.         ASSUME ds:MainSeg
  887. AskFileName    PROC NEAR
  888.         mov bx,offset filename
  889.         push bx
  890.         xor cx,cx
  891. checkEnd:    cmp byte ptr [bx],0
  892.         je proceed
  893.         cmp cx,FileNameSize-1
  894.         je proceed
  895.         inc cx
  896.         inc bx
  897.         jmp short checkEnd
  898. proceed:    mov byte ptr [bx],'$'
  899.         pop dx
  900.         mov ah,9
  901. int21call:    push bx
  902.         push cx
  903.         int 21h
  904.         pop cx
  905.         pop bx
  906. input:        call Inkey
  907.         cmp ax,127
  908.         jae input
  909.         cmp ax,8
  910.         je backspace
  911.         cmp ax,13
  912.         je return
  913.         cmp ax,31
  914.         jbe input
  915.         cmp cx,FileNameSize-1
  916.         jae beep
  917.         mov byte ptr [bx],al
  918.         inc bx
  919.         inc cx
  920.         mov dl,al
  921. prchar:        mov ah,2
  922.         jmp short int21call
  923. beep:        mov dl,7
  924.         jmp short prchar
  925. backspace:    jcxz beep
  926.         dec bx
  927.         dec cx
  928.         push bx
  929.         push cx
  930.         mov ah,2
  931.         mov dl,8
  932.         int 21h
  933.         mov dl,' '
  934.         int 21h
  935.         pop cx
  936.         pop bx
  937.         mov dl,8
  938.         jmp short prchar
  939. return:        mov byte ptr [bx],0
  940.         mov dx,offset SomeCrLfs
  941.         jmp WrStr
  942. AskFileName    ENDP
  943.  
  944. Inkey        PROC NEAR
  945.         push bx
  946.         push cx
  947.         mov ah,7
  948.         int 21h
  949.         mov ah,0
  950.         cmp al,0
  951.         jne endkey
  952.         mov ah,0bh
  953.         int 21h
  954.         mov ah,0
  955.         cmp al,0
  956.         je endkey
  957.         mov ah,7
  958.         int 21h
  959.         mov ah,1
  960. endkey:        pop cx
  961.         pop bx
  962.         ret
  963. Inkey        ENDP
  964.  
  965. ParseArgs    PROC NEAR
  966.         mov si,0080h
  967.         cld
  968.         lodsb
  969.         xor ch,ch
  970.         mov cl,al
  971.         mov di,offset argv
  972.         xor dx,dx
  973. pa0:        jcxz paEnd
  974. pa1:        lodsb
  975.         cmp al,' '
  976.         loope pa1        
  977.         je paEnd
  978.         dec si
  979.         inc cx
  980.         mov ax,si
  981.         stosw
  982.         inc dx
  983. pa2:        lodsb
  984.         cmp al,'a'
  985.         jb pa2a
  986.         cmp al,'z'
  987.         ja pa2a
  988.         add al,('A'-'a')
  989.         mov byte ptr [si-1],al
  990. pa2a:        cmp al,' '
  991.         loopne pa2
  992.         jcxz paEnd
  993.         mov byte ptr [si-1],0
  994.         jmp short pa1
  995. paEnd:        mov byte ptr [si],0
  996.         mov argc,dx
  997.         ret
  998. ParseArgs    ENDP
  999.  
  1000. ParseOptions    PROC NEAR
  1001.         call ParseArgs
  1002.         cld
  1003.         mov si,offset argv
  1004.         mov cx,argc
  1005.         jmp short po1
  1006. po0:        ret
  1007. po0a:        mov dx,offset eMissing
  1008. po0b:        jmp Infinite
  1009. po1:        jcxz po0
  1010.         lodsw
  1011.         dec cx
  1012.         mov bx,ax
  1013.         cmp byte ptr [bx],'-'
  1014.         je po3
  1015.         ; parse filename
  1016.         push si
  1017.         mov si,bx
  1018.         mov di,offset filename
  1019. po2:        lodsb
  1020.         stosb
  1021.         cmp al,0
  1022.         jne po2
  1023.         pop si
  1024.         jmp short po1
  1025.  
  1026. po3z:        jmp po4
  1027.  
  1028. po3:        ; parse options
  1029.         mov al,[bx+1]
  1030.         cmp al,'R'
  1031.         jne po3z
  1032.         ; -Root {hd[ab][1-9],sd[a-g][1-8],fd[01]}
  1033.         jcxz po0a
  1034.         lodsw
  1035.         dec cx
  1036.         mov bx,si
  1037.         mov si,ax
  1038.         call parsedev
  1039.         mov si,bx
  1040.         mov rootdevice,di
  1041.         jmp short po1
  1042. parsedev:    mov dx,offset eRootOpt
  1043.         lodsb
  1044.         cmp al,'F'
  1045.         jne po3a
  1046.         ; floppies
  1047.         mov di,0200h ; 2 is floppies dev's major
  1048.         lodsb
  1049.         cmp al,'D'
  1050.         jne po0b
  1051.         lodsb
  1052.         sub al,'0'
  1053.         cmp al,2
  1054.         jae po0b
  1055.         xor ah,ah
  1056.         add di,ax
  1057.         lodsb
  1058.         cmp al,0
  1059.         jne po0b
  1060.         ret
  1061.  
  1062. po3a:        cmp al,'H'
  1063.         jne po3b
  1064.         ; hard disks
  1065.         mov di,0300h ; 3 is hard disks dev's major
  1066.         lodsb
  1067.         cmp al,'D'
  1068.         jne po0b
  1069.         lodsb
  1070.         sub al,'A'
  1071.         cmp al,2
  1072.         jae po0b
  1073.         push cx
  1074.         mov cl,6
  1075.         shl al,cl
  1076.         pop cx
  1077.         xor ah,ah
  1078.         add di,ax
  1079.         lodsb
  1080.         sub al,'1'
  1081.         cmp al,9
  1082.         jae po0b
  1083.         inc al
  1084.         add di,ax
  1085.         lodsb
  1086.         cmp al,0
  1087.         jne po0B
  1088.         ret
  1089.  
  1090. po3b:        cmp al,'S'
  1091.         jne po0B
  1092.         ; scsi disks
  1093.         mov di,0800h ; 8 is scsi disks dev's major
  1094.         lodsb
  1095.         cmp al,'D'
  1096.         jne po0B
  1097.         lodsb
  1098.         sub al,'A'
  1099.         cmp al,7
  1100.         jae po0B
  1101.         push cx
  1102.         mov cl,4
  1103.         shl al,cl
  1104.         pop cx
  1105.         xor ah,ah
  1106.         add di,ax
  1107.         lodsb
  1108.         sub al,'1'
  1109.         cmp al,8
  1110.         jae po0B
  1111.         inc al
  1112.         add di,ax
  1113.         lodsb
  1114.         cmp al,0
  1115.         jne po0B
  1116.         ret
  1117.  
  1118. po0A:        mov dx,offset eMissing
  1119. po0B:        jmp Infinite
  1120.  
  1121. po4:;        cmp al,'S'
  1122. ;        jne po5
  1123. ;        ; -Swap ... (idem -Root)
  1124. ;        jcxz po0A
  1125. ;        lodsw
  1126. ;        dec cx
  1127. ;        mov bx,si
  1128. ;        mov si,ax
  1129. ;        call parsedev
  1130. ;        mov si,bx
  1131. ;        mov swapdevice,di
  1132. ;        jmp po1
  1133.  
  1134. po5:        cmp al,'D'
  1135.         jne po6
  1136.         ; -Disk n is ram disk size
  1137.         jcxz po0A
  1138.         lodsw
  1139.         dec cx
  1140.         mov bx,si
  1141.         mov si,ax
  1142.         mov dx,offset eDiskOpt
  1143.         call parsenum
  1144.         mov ramdisksize,di
  1145.         mov si,bx
  1146.         jmp po1
  1147. parsenum:    xor di,di
  1148. po5a:        lodsb
  1149.         cmp al,0
  1150.         je po5b
  1151.         sub al,'0'
  1152.         cmp al,10
  1153.         jae po0B
  1154.         push ax
  1155.         mov ax,di
  1156.         mov ch,10
  1157.         mul ch
  1158.         xor ch,ch
  1159.         mov di,ax
  1160.         pop ax
  1161.         xor ah,ah
  1162.         add di,ax
  1163.         jmp short po5a
  1164. po5b:        ret
  1165.  
  1166. po6:        cmp al,'W'
  1167.         jne po7
  1168.         mov byte ptr launchWait,1
  1169.         jmp po1
  1170.         
  1171. po7:        mov dx,offset eUnknown
  1172.         cmp al,'V'
  1173.         jne po0B
  1174.         ; -Video 80*25 or 80*50 or SVGA[1-9] or ASK
  1175.         jcxz po0A
  1176.         lodsw
  1177.         dec cx
  1178.         mov bx,si
  1179.         mov si,ax
  1180.         mov dx,offset eVideoOpt
  1181.         push cx
  1182.         mov ax,VideoVGA
  1183.         mov cx,3
  1184.         mov di,offset n80x25
  1185.         push si
  1186.         repe cmpsw
  1187.         pop si
  1188.         je po6a
  1189.         mov ax,VideoVGAext
  1190.         mov cx,3
  1191.         mov di,offset n80x50
  1192.         push si
  1193.         repe cmpsw
  1194.         pop si
  1195.         je po6a
  1196.         mov ax,VideoASK
  1197.         mov cx,2
  1198.         mov di,2+offset nAsk
  1199.         push si
  1200.         repe cmpsw
  1201.         pop si
  1202.         je po6a
  1203.         xor ax,ax
  1204.         mov cx,2
  1205.         mov di,offset nSVGA
  1206.         repe cmpsw
  1207.         jne po6B
  1208.         lodsb
  1209.         sub al,'1'
  1210.         cmp al,9
  1211.         jae po6B
  1212.         push ax
  1213.         lodsb
  1214.         or al,al
  1215.         pop ax
  1216.         jnz po6B
  1217.         inc ax
  1218. po6a:        pop cx
  1219.         mov si,bx
  1220.         mov videomode,ax
  1221.         jmp po1
  1222. po6B:        jmp Infinite
  1223. ParseOptions    ENDP
  1224.         
  1225. GetRootDevice    PROC NEAR
  1226.         push ds
  1227.         push es
  1228.         mov ax,cs
  1229.         mov ds,ax
  1230.         mov es,ax
  1231.         cld
  1232.         mov si,defaultRoot
  1233.         mov di,offset filename
  1234. cpyRootDft:    lodsb
  1235.         stosb
  1236.         cmp al,0
  1237.         jne cpyRootDft
  1238. AskRoot:    mov dx,offset mRoot
  1239.         call WrStatus
  1240.         call AskFileName
  1241.         mov si,offset filename
  1242.         mov di,si
  1243.         push si
  1244. upcRootDev:    lodsb
  1245.         cmp al,'a'
  1246.         jc noUpcRootDev
  1247.         cmp al,'z'
  1248.         ja noUpcRootDev
  1249.         add al,('A'-'a')
  1250. noUpcRootDev:    stosb
  1251.         cmp al,0
  1252.         jne upcRootDev
  1253.         pop si
  1254.         call parsedev
  1255.         mov ax,di
  1256.         pop es
  1257.         pop ds
  1258.         ret
  1259. GetRootDevice    ENDP
  1260.  
  1261. CheckCPU    PROC NEAR ; () -> (ax=message addr)
  1262.         pushf
  1263.         mov dx,offset Cpu86
  1264.         xor ax,ax
  1265.         push ax
  1266.         popf
  1267.         pushf
  1268.         pop ax
  1269.         and ax,0F000h
  1270.         cmp ax,0F000h
  1271.         je cpuend    ; 8086
  1272.         mov dx,offset Cpu286
  1273.         mov ax,0F000h
  1274.         push ax
  1275.         popf
  1276.         pushf
  1277.         pop ax
  1278.         and ax,0F000h
  1279.         jz cpuend    ; 80286
  1280.         mov dx,offset Cpu386
  1281. cpuend:        popf
  1282.         push dx
  1283.         call WrStr
  1284.         pop ax
  1285.         ret
  1286. CheckCPU    ENDP
  1287.  
  1288.  
  1289. Copyright    db "BOOTLINUX v"
  1290.         db BootlinVersion
  1291.         db " (C) 1992-1994 F.COUTANT",0
  1292. nCPU        db "Processor",0
  1293. nBase        db "Conventional Memory",0
  1294. nExtended    db "Extended Memory",0
  1295. nSize        db "Linux kernel size",0
  1296. nRootDev    db "Root FS device",0
  1297. nVideo        db "Startup Video Mode",0
  1298. ;nSwapDev    db "Swap device",0
  1299. nRamDisk    db "Ram Disk Size",0
  1300. Cpu86        db "           8086",0
  1301. Cpu286        db "    80186/80286",0
  1302. Cpu386        db "80386 or higher",0
  1303. nNone        db "(none)",0
  1304. nUnknownSp    db " "
  1305. nUnknown    db " (?)",0
  1306. n80x25        db "80*25",0
  1307. n80x50        db "80*50",0
  1308. nAsk        db "  ASK",0
  1309. nSVGA        db "SVGA",0
  1310. mFile        db "Could not open Image file. Please enter new file name"
  1311.         db 13,10,"or press Ctrl-Alt-Del to reboot:",13,10,10,0
  1312. mBoot        db "BootSector: ... ",0
  1313. mSetup        db "loaded",13,10,"LINUX Setup: ... ",0
  1314. mKernel        db "loaded",13,10,"LINUX Kernel: ",0
  1315. mDone        db " done",13,10,10,0
  1316. mRoot        db 10,"Root device is not defined. Please choose one of: ",13,10,10
  1317.         db "    FD[0-1]         floppies",13,10
  1318.         db "    HD[A-B][1-9]    AT hard disks partitions",13,10
  1319.         db "                    ([1-4] are BIOS, [5-9] are dos extended)",13,10
  1320.         db "    SD[A-G][1-8]    SCSI hard disks partitions",13,10
  1321.         db 10,"root device -> ",0
  1322. mLaunch        db "About to launch Linux. Press a key...",0
  1323. SomeCrLfs    db 10        ; this line and the following should be
  1324. mEmpty        db 13,10,0    ; together and in this order
  1325. eBoot        db "file is not a LINUX BOOT-DISK IMAGE !",13,10,0
  1326. eCpu        db "Linux requires a 80386 or higher to run.",13,10,0
  1327. eBasMem        db "640K base memory is required to load Linux Kernel.",13,10,0
  1328. eExtMem        db "A minimum of 2M total memory is required to run Linux.",13,10
  1329.         db "(4M is preferred for normal use, 8M if using X11)",13,10,0
  1330. eShort        db "file is too short to be a correct image",13,10,0
  1331. eRead        db " (read error)",13,10,0
  1332. eBig        db " not enough memory to load the kernel.",13,10
  1333.         db "Run BootLinux with less residents or build a compressed kernel.",13,10,0
  1334. e512        db "Kernel is more than 512K, so it will never load correctly.",13,10
  1335.         db "You have to build an auto-uncompressing kernel.",13,10,0
  1336. eMissing    db "missing argument for an option",13,10,0
  1337. eUnknown    db "unknown option. Recognized options are (case insensitive):",13,10
  1338.         db "    -R*    <root device>",13,10
  1339. ;        db "    -S*    <swap device>",13,10
  1340.         db "    -D*    <ramdisksizeK>",13,10
  1341.         db "    -V*    80*25 or 80*50 or SVGA[1-9] or ASK",13,10
  1342.         db "    -W*    waits for a key before lauching Linux",13,10,0
  1343. eRootOpt    db "option -Root expects 'HD[AB][1-9]', 'SD[A-G][1-8]' or 'FD[01]' as argument",13,10,0
  1344. eDiskOpt    db "option -Disk expects a numeric size in K as argument",13,10,0
  1345. eVideoOpt    db "option -Video expects '80*25' or '80*50' or 'SVGA[1-9]' or 'ASK' as argument",13,10,0
  1346. eReboot        db 10,"I can't do anything now.",13,10
  1347.         db "Please press Ctrl-Alt-Del to reboot...",13,10,10
  1348.         db "NB: if you ran BOOTLIN from the DOS command line,",13,10
  1349.         db "    you can also press Ctrl-Break here and you will",13,10
  1350.         db "    return to the DOS prompt.",13,10,10,0
  1351.  
  1352. defaultRoot    dw defaultRootTxt
  1353. defaultRootTxt    db "fd0",0
  1354.  
  1355. videomode    dw VideoUnspec
  1356. rootdevice    dw 0
  1357. swapdevice    dw 0
  1358. ramdisksize    dw 0
  1359.  
  1360. launchWait    db 0
  1361.  
  1362. argc        dw 0
  1363. argv        dw 20 dup (0)
  1364.  
  1365. filehandle    dw 0
  1366. filename    db 0
  1367.  
  1368. TheEnd        LABEL BYTE
  1369.  
  1370. MainSeg        ENDS
  1371.  
  1372.  
  1373.         END MainSeg:JumpStart
  1374.  
  1375.