home *** CD-ROM | disk | FTP | other *** search
/ Boot Disc 15 / boot-disc-1997-11.iso / Debian / Tools / LODLIN16.ZIP / LODLIN16 / SRC / LOADLINJ.ASM < prev    next >
Assembly Source File  |  1996-04-28  |  36KB  |  1,093 lines

  1. ;   >>> this is file LOADLINj.ASM
  2. ;============================================================================
  3. ;   LOADLIN v1.6 (C) 1994..1996 Hans Lermen (lermen@elserv.ffm.fgan.de)
  4. ;
  5. ;   This program is free software; you can redistribute it and/or modify
  6. ;   it under the terms of the GNU General Public License as published by
  7. ;   the Free Software Foundation; either version 2 of the License, or
  8. ;   (at your option) any later version.
  9. ;
  10. ;   This program is distributed in the hope that it will be useful,
  11. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ;   GNU General Public License for more details.
  14. ;
  15. ;   You should have received a copy of the GNU General Public License
  16. ;   along with this program; if not, write to the Free Software
  17. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ;
  19. ;----------------------------------------------------------------------------
  20. ;   Comments and bug reports are welcome and may be sent to:
  21. ;   E-Mail:    lermen@elserv.ffm.fgan.de
  22. ;   SnailMail: Hans Lermen
  23. ;              Am Muehlenweg 38
  24. ;              D53424 REMAGEN-Unkelbach
  25. ;              GERMANY
  26. ;
  27. ;============================================================================
  28.  
  29. check_VCPI_present proc near
  30.           pushad
  31.           push    es
  32.           push    ds
  33.           lea     esp,[esp-4] ; local space
  34. @@stack struc
  35.   @@handle dw   ?
  36.            dw   ?
  37.   @@ds     dw   ?
  38.   @@es     dw   ?
  39.   pushad_struc @@
  40. @@stack ends
  41.           xor     eax,eax      ; check EMM_interrupt present
  42.           mov     [esp].@@eax,eax
  43.           mov     es,ax
  44.           mov     es,word ptr es:[emm_int*4+2]
  45.           cmp     Dword ptr es:[10+4],'0XXX'
  46.           jne     @@ex
  47.           cmp     dword ptr es:[10],'XMME'
  48.           je      @@ok
  49.           cmp     dword ptr es:[10],'QMME' ; this also works (as told by <J.S.Peatfield@damtp.cambridge.ac.uk>)
  50.           jne     @@ex
  51. @@ok:
  52.           mov     ax,4000h   ; check emm menager status
  53.           int     emm_int
  54.           or      ah,ah
  55.           jnz     @@ex
  56.           mov     ax,_GET_VERSION*256   ; get version
  57.           int     emm_int
  58.           cmp     ax,40h     ; version must be greater 4.0
  59.           jb      @@ex
  60.  
  61.           mov     ax,_ALLOCATE_RAW_PAGES
  62.           mov     bx,4
  63.           int     emm_int
  64.           cmp     ah,0
  65.           jnz     @@ex
  66.           mov     word ptr [esp].@@handle,dx     ; save handle
  67.           mov     ax,0DE00h   ; check for VCPI present
  68.           int     emm_int
  69.           cmp     ah,0
  70.           jne     short @@notok
  71.           mov     byte ptr [esp].@@eax,1
  72. @@notok:
  73.           mov     dx,word ptr [esp].@@handle
  74.           mov     ax,_DEALLOCATE_PAGES*256
  75.           int     emm_int
  76. @@ex:
  77.           lea     esp,[esp+4] ; discar local space
  78.           pop     ds
  79.           pop     es
  80.           popad
  81.           or      ax,ax
  82.           ret
  83. check_VCPI_present endp
  84.  
  85. get_VCPI_interface proc near
  86.           push    cs                  ;* buffer for server GDT entries
  87.           push    offset gdtvcpi_code ;*
  88.           push    cs                  ;* buffer for server page0
  89.           push    offset page0        ;*
  90.           call    get_protected_mode_interface
  91.           ret
  92. get_VCPI_interface endp
  93.  
  94.  
  95. check_low_mem_mapping proc near
  96.           call    get_VCPI_interface
  97.           xor     edx,edx
  98.           lea     si,page0
  99.           cld
  100.           mov     cx,(640/4)
  101. @@loop:
  102.           lodsd
  103.           and     ax,0f000h
  104.           cmp     eax,edx
  105.           jne     @@ex_false
  106.           add     edx,1000h
  107.           loop    @@loop
  108.           mov     ax,1
  109. @@ex:
  110.           or      ax,ax
  111.           ret
  112. @@ex_false:
  113.           xor     ax,ax
  114.           jmp     @@ex
  115. check_low_mem_mapping endp
  116.  
  117.  
  118. get_protected_mode_interface proc near
  119.           ARG     server_pagebuffer:dword,server_selectors:dword = returnpop
  120.           push    bp
  121.           mov     bp,sp
  122.           push    si
  123.           push    di
  124.           push    ds
  125.           push    es
  126.  
  127.                                     ; convert pagebuffer to linear address
  128.           movzx   eax,word ptr server_pagebuffer+2
  129.           movzx   ebx,word ptr server_pagebuffer
  130.           shl     eax,4
  131.           add     eax,ebx
  132.           shr     eax,4      ; make real mode address
  133.  
  134.           ;XXXXXXXXXX
  135.           push    ds
  136.           mov     es,ax                ; ES = frame of server_pagebuf
  137.           xor     di,di                ; ES:DI = >buffer for page0-table<
  138.           lds     si,server_selectors ; DS:DI = >3 GDT entries for VCPI
  139.                                ; calling VCPI server
  140.           mov     ax,0DE01h
  141.           int     emm_int
  142.           pop     ds
  143.  
  144.                                       ; save VCPI server entry for protected mode
  145.           mov     dword ptr server_vcpi_entry,ebx
  146.                                       ; set the VCPI-Code selector
  147.           mov     word ptr server_vcpi_entry+4,g_vcpi_code
  148.           ;XXXXXXXXXXX
  149.  
  150.  
  151.  
  152.           pop     es
  153.           pop     ds
  154.           pop     di
  155.           pop     si
  156.           pop     bp
  157.           ret     returnpop
  158. get_protected_mode_interface endp
  159.  
  160.  
  161. try_biosintv proc near
  162.           pushad
  163.           mov      ax,DOS_OPEN_FILE shl 8
  164.           lea      dx,@@fname
  165.           DosInt
  166.           jc       @@ex_false
  167.           mov      bx,ax
  168.           mov      ax,4402h
  169.           mov      cx,size intv_buf
  170.           lea      dx,intv_buf
  171.           DosInt
  172.           pushf
  173.           push     ax
  174.           DosCall  DOS_CLOSE_FILE
  175.           pop      ax
  176.           popf
  177.           jc       @@ex_false
  178.           mov      intv_size,ax
  179.           mov      ax,1
  180. @@ex:
  181.           or       ax,ax
  182.           popad
  183.           ret
  184. @@ex_false:
  185.           xor     ax,ax
  186.           jmp     @@ex
  187. @@fname   db     '$BIOSINT',0
  188. try_biosintv endp
  189.  
  190. try_realbios proc near
  191.           pushad
  192.           mov      ax,DOS_OPEN_FILE shl 8
  193.           lea      dx,@@fname_realbios
  194.           DosInt
  195.           jc       @@ex_false
  196.           mov      bx,ax
  197.           lea      dx,intv_buf
  198.           mov      cx,realbios_end-intv_buf
  199.           DosCall  DOS_READ_FROM_HANDLE
  200.           pushf
  201.           push     ax
  202.           DosCall  DOS_CLOSE_FILE
  203.           pop      ax
  204.           popf
  205.           jc       @@ex_false
  206.           cmp      ax,realbios_end-intv_buf
  207.           jne      @@ex_false
  208.           mov      intv_size,ax
  209.           cmp      cs:option_rx,1
  210.           je       @@ex_true
  211.                    ; we now check the BIOS-revision to be sure
  212.                    ; that we have the right file
  213.           push     es
  214.           mov      ax,0ffffh
  215.           mov      es,ax
  216.           mov      eax,dword ptr es:[biosdate-reset_jmpop]
  217.           cmp      eax,dword ptr cs:biosdate
  218.           jne      @@ex_wrong_bios
  219.           mov      eax,dword ptr es:[(biosdate-reset_jmpop)+4]
  220.           cmp      eax,dword ptr cs:biosdate+4
  221.           jne      @@ex_wrong_bios
  222.                    ; we check the real_bios_magic
  223.           cmp      cs:real_bios_magic,0a5a5h
  224.           jne      @@ex_wrong_bios
  225. @@ex_true:
  226.           mov      ax,1
  227.           pop      es
  228. @@ex:
  229.           or       ax,ax
  230.           popad
  231.           ret
  232. @@ex_false:
  233.           mov     intv_size,0
  234.           xor     ax,ax
  235.           jmp     @@ex
  236. @@ex_wrong_bios:
  237.           pop     es
  238.           mov     wrong_realbios,1
  239.           call    force_error_verbose
  240.           jmp     @@ex_false
  241.  
  242. @@fname_realbios db REALBIOS_FILE,0
  243. try_realbios endp
  244.  
  245. get_default_bios_intvectors proc near
  246.           cmp      option_ja,0
  247.           jnz      @@first_javier
  248.           cmp      option_realbios,0
  249.           jnz      @@first_realbios
  250.           call     try_biosintv
  251.           jnz      @@ex
  252.           call     try_realbios
  253. @@ex:
  254.           ret
  255. @@first_realbios:
  256.           call     try_realbios
  257.           jnz      @@ex
  258.           call     try_biosintv
  259.           jmp      @@ex
  260. @@first_javier:
  261.           mov      intv_size,0
  262.           jmp      @@ex
  263. get_default_bios_intvectors endp
  264.  
  265.  
  266. pmode_return_esp   dd   ?  ; used to return from real-mode-switch
  267. real_IDTR          dw       03ffh    ;needed to load real intvector after switch
  268.                    dd       0
  269.  
  270. pmode_task proc near
  271. ; We come here in protected mode via VCPI-CALL
  272. ; have only to set up all things to switch back to 386-realmode
  273. ;
  274. ; We follow the INTEL recomended procedure to do this
  275. ; (80386 Programmer's Reference Manual, Chapter 14.5)
  276. ;
  277.           .386p
  278.           CLI  ; just to be sure
  279.  
  280.           ; 1. We know, that paging is enabled,
  281.           ;             that linear addresses have identical mapping
  282.           ;    so we can clear the PG bit
  283.  
  284.           mov     eax,CR0
  285.           and     eax,07fffffffh
  286.           mov     CR0,eax    ; paging is off
  287.           xor     eax,eax
  288.           mov     CR3,eax    ; clear out paging cache
  289.  
  290.           ; 2. We must transfer control to segment with 64K limit
  291.           ;    we ARE on such a segment, no need to do it here
  292.  
  293.           ; 3. Load segment registers SS,DS,ES,FS,GS with a selector
  294.           ;    that points to a descriptor containing the the values:
  295.           ;      limit 64k     =  0FFFFh
  296.           ;      byte granularity
  297.           ;      Expand up
  298.           ;      writable
  299.           ;      present
  300.           ;
  301.           ;    We have that descriptor, its our gdt_data.
  302.           mov     ax,g_data
  303.           mov     ss,ax
  304.           mov     ds,ax
  305.           mov     es,ax
  306.           mov     fs,ax
  307.           mov     gs,ax
  308.  
  309.           ; 4. Disable Interrrupts
  310.           ;    ( we did that above )
  311.           ; 5. Clear the PE bit in CR0
  312.           mov     eax,CR0
  313.           and     al,0feh
  314.           mov     CR0,eax  ; we are go back to realmode
  315.  
  316.           ; 6. Flush the instruction queue and load CS with approritate value
  317.           ;jmp     far ptr @@here
  318.           db      0EAh
  319.           dw      @@here
  320. reloc_hseg_1  dw  High_Seg_
  321. @@here    label   far
  322.  
  323.           ; 7. Use LIDT instruction to load the base and limits of the
  324.           ;    real-mode interrupt vector table
  325.           lidt    fword ptr cs:real_IDTR
  326.  
  327.           .386
  328.           ; 8. Enable interrupts (we are doing this later)
  329.           ; 9. Load segment register
  330.           mov     ax,High_Seg_
  331. reloc_hseg_2  equ word ptr ($-2)
  332.           mov     ss,ax
  333.           mov     ds,ax
  334.           mov     es,ax
  335.           mov     fs,ax
  336.           mov     gs,ax
  337.           mov     esp,pmode_return_esp
  338.           ; now we are in "real" real-mode
  339.  
  340.           call    restore_bios_default_vectors
  341. @@ex:
  342.           popad
  343.           ret
  344. pmode_task endp
  345.  
  346. iodelay   macro
  347.             jmp short $+2
  348.             jmp short $+2
  349.           endm
  350.  
  351. get_mem_from_CMOS proc near
  352.           pushf
  353.           cli
  354.           push    bx
  355.           mov     al,18h
  356.           out     [070h],al
  357.           dec     al
  358.           mov     bl,al
  359.           iodelay
  360.           in      al,[071h]
  361.           mov     ah,al
  362.           mov     al,bl
  363.           iodelay
  364.           out     [070h],al
  365.           iodelay
  366.           in      al,[071h] ; extended mem read from CMOS
  367.           pop     bx
  368.           popf
  369.           ret
  370. get_mem_from_CMOS endp
  371.  
  372.  
  373.  
  374. restore_bios_default_vectors proc near
  375.           push_   es,ds,ax,cx,si,di
  376.           xor     di,di
  377.           mov     es,di
  378.           cmp     cs:have_to_intercept_setup,0
  379.           jz      @@p2
  380.                               ; No REALBIOS or device driver
  381.           cmp     word ptr cs:intv_buf+(4*15h+2),0
  382.           jne     @@ex        ; Only once
  383.           mov     eax,dword ptr es:[4*15h]
  384.           mov     dword ptr cs:intv_buf+(4*15h),eax
  385.           call    get_mem_from_CMOS
  386.           mov     cs:real_bios_int15,ax
  387.           jmp     @@p1
  388. @@p2:
  389.           mov     cx,cs:intv_size
  390.           shr     cx,2
  391.           jcxz    @@ex
  392.           ; we now reset the intvector to bios-defaults
  393.           push    cs
  394.           pop     ds
  395.           cmp     cx,(size intv_buf)/4  ; have we REALBIOS
  396.           jna     @@1     ; no
  397.                           ; yes
  398.                           ; restoring BIOSdata also
  399.           mov     cx,(dummy_dos_data-intv_buf)/4
  400. @@1:
  401.           lea     si,intv_buf
  402.           cld
  403.           rep movsd
  404.           cmp     cs:intv_size,(size intv_buf)  ; have we REALBIOS
  405.           jna     @@8      ; no
  406.                            ; yes, restoring BIOSscratch also
  407.           mov     di,09FC0h
  408.           mov     es,di
  409.           xor     di,di
  410.           lea     si,bios_scratch
  411.           mov     cx,(size bios_scratch)/4
  412.           rep movsd
  413.                            ; now reprogram the PICs (8259A)
  414.                            ; (may be redirected by VCPI-client)
  415.           mov     al,11h        ; enter programming mode
  416.           out     [20h],al      ; master
  417.           iodelay
  418.           out     [0A0h],al     ; slave
  419.           iodelay
  420.           mov     al,8          ; IRQ0..7 --> INT8..F
  421.           out     [21h],al      ; master
  422.           iodelay
  423.           mov     al,70h        ; IRQ8..F --> INT70..77
  424.           out     [0A1h],al     ; slave
  425.           iodelay
  426.           mov     al,4          ; master bit
  427.           out     [21h],al      ; master
  428.           iodelay
  429.           mov     al,2          ; slave bit
  430.           out     [0A1h],al     ; slave
  431.           iodelay
  432.           mov     al,1          ; 8086 mode
  433.           out     [21h],al      ; master
  434.           iodelay
  435.           out     [0A1h],al     ; slave
  436.           iodelay
  437.           mov     al,cs:slaveIMR
  438.           out     [0A1h],al     ; slave
  439.           iodelay
  440.           mov     al,cs:masterIMR
  441.           out     [21h],al      ; master
  442.  
  443. @@p1:                      ; we hook on the INT15
  444.           xor     ax,ax
  445.           mov     es,ax
  446.           mov     word ptr es:[4*15h],offset our_int15
  447.           mov     word ptr es:[4*15h+2],cs
  448.                            ; now we must reinit the video controler
  449.                            ; to the values just set in the BIOS-data
  450.                            ; we do it by calling the appropriate INT 10h
  451.           mov     ax,3003h ; al = color mode
  452.           and     ah,byte ptr cs:bios_data+10h ; get EQUIPPEMENT-flags
  453.           cmp     ah,30h
  454.           jne     @@6
  455.           mov     al,7     ; al = mono mode
  456. @@6:
  457.           xor     ah,ah
  458.           INT     10h
  459. @@8:
  460.           push    ds
  461.           pop     es
  462. @@ex:
  463.           mov     cs:intv_size,0   ; avoid second call
  464.           pop_    es,ds,ax,cx,si,di
  465.           ret
  466. restore_bios_default_vectors endp
  467.  
  468.  
  469. our_int15 proc near
  470. ; interrupt 15 hook, in case of realbios
  471.           cmp     ah,88h
  472.           je      @@we_do_it
  473.           jmp     dword ptr cs:intv_buf+(4*15H)
  474. @@we_do_it:
  475.           mov     ax,cs:real_bios_int15
  476. ;;;test          mov     ax,0c00h*4
  477.           iret
  478. our_int15 endp
  479.  
  480.  
  481.  
  482. switch_to_protected_mode_and_return_in_386realmode proc near
  483. ; NOTE: must have called get_VCPI_interface before this
  484. ;
  485. ; returns with interrpts disabled
  486. ; all registers preserved, all segment registers = "High_Seg"
  487.           cmp    cs:have_to_force_realmode,0
  488.           jnz    @@goon
  489.           ret
  490. @@goon:
  491.           mov    cs:have_to_force_realmode,0
  492.           pushad
  493.           mov    pmode_return_esp,esp
  494.           lea    ax,pmode_task
  495.           movzx  eax,ax
  496.           mov    dword ptr protected_mode_target,eax
  497.           mov    word ptr protected_mode_target+4,g_code
  498.           movzx   esi,High_Seg
  499.           shl     esi,4
  500.           lea     si,our_CR3[si]
  501.           CLI
  502.           mov     ax,0DE0Ch
  503.           int     emm_int    ; jumps to protected mode
  504.           ; does NOT return here
  505.           ; "pmode_task" does return directly to our caller
  506. switch_to_protected_mode_and_return_in_386realmode endp
  507.  
  508.  
  509. ; input:
  510. ;   ES:DI   pointer to string
  511. ;   AL       = terminating character
  512. ; output:
  513. ;   AX=       length of string, not counting terminating character
  514. ;   all other registers preserved
  515. strlen proc near
  516.         .8086
  517.         push_  di,cx
  518.         xor     cx,cx
  519.         dec     cx
  520.         cld
  521.         repne   scasb
  522.         mov     ax,di
  523.         dec     ax
  524.         pop_    di,cx
  525.         sub     ax,di
  526.         .386
  527.         ret
  528. strlen endp
  529.  
  530.  
  531. get_kernel_version proc near
  532.   ; Input:
  533.   ;   DS=CS
  534.   ; Output:
  535.   ;   EAX= converted verion number as:
  536.   ;        1.2.3 (root:pipapo) #4 ...  --->  EAX= 01020304h
  537.   ;        1.2.3                       --->  EAX= 01020300h
  538.   ;   all other registers preserved
  539.          xor      eax,eax
  540.          cmp      have_to_intercept_setup,2
  541.          jne      @@ex
  542.          cmp      setup_header_version,0105h
  543.          jb       @@ex
  544.          cmp      kernel_version,0
  545.          jz       @@ex
  546.          push_    esi,edx
  547.          mov      si,kernel_version
  548.          lea      si,setup_prog[si]
  549.          call     value_of
  550.          mov      edx,eax
  551.          call     value_of
  552.          ror      eax,8
  553.          shld     edx,eax,8
  554.          call     value_of
  555.          ror      eax,8
  556.          shld     edx,eax,8
  557.          xor      eax,eax
  558.          cmp      byte ptr [si-1],0  ; end of string ?
  559.          je       @@ex_
  560.          cld
  561. @@loop:
  562.          lodsb
  563.          test     ax,ax
  564.          jz       @@ex_
  565.          cmp      al,'#'
  566.          jne      @@loop
  567.          call     value_of
  568.          ror      eax,8
  569. @@ex_:
  570.          shld     edx,eax,8
  571.          mov      eax,edx
  572.          pop_     esi,edx
  573. @@ex:
  574.          ret
  575. get_kernel_version endp
  576.  
  577. writechar proc near
  578.          push_   eax,edx
  579.          push    eax
  580.          mov     byte ptr [esp+1],'$'
  581.          mov     dx,sp
  582.          call    print
  583.          add     sp,4
  584.          pop_    eax,edx
  585.          ret
  586. writechar endp
  587.  
  588.  
  589. writestring proc near
  590.          cld
  591. @@1:
  592.          lodsb
  593.          test    al,al
  594.          jz      @@ex
  595.          call    writechar
  596.          loop    @@1
  597. @@ex:
  598.          ret
  599. writestring endp
  600.  
  601. writehexdigit proc near
  602.          push  eax
  603.          and   al,0fh
  604.          add   al,'0'
  605.          cmp   al,'9'
  606.          jna   @@m1
  607.          add   al,'A'-('9'+1)
  608. @@m1:
  609.          call  writechar
  610.          pop   eax
  611.          ret
  612. writehexdigit endp
  613.  
  614. writehexbyte proc  near
  615.          push    eax
  616.          ror     eax,4
  617.          call    writehexdigit
  618.          rol     eax,4
  619.          call    writehexdigit
  620.          pop     eax
  621.          ret
  622. writehexbyte endp
  623.  
  624.  
  625. writehexword proc near
  626.          push    eax
  627.          ror     eax,8
  628.          call    writehexbyte
  629.          rol     eax,8
  630.          call    writehexbyte
  631.          pop     eax
  632.          ret
  633. writehexword endp
  634.  
  635.  
  636. writehexdword proc near
  637.          push    eax
  638.          ror     eax,16
  639.          call    writehexword
  640.          rol     eax,16
  641.          call    writehexword
  642.          pop     eax
  643.          ret
  644. writehexdword endp
  645.  
  646.  
  647. force_error_verbose proc near
  648.         mov      option_v,1
  649.         mov      option_t,1
  650.         mov      option_t_forced,1
  651.         ret
  652. force_error_verbose endp
  653.  
  654.  
  655. get_effective_physmem proc near
  656. ; input: none
  657. ; output: EAX = number of total physical RAM in bytes
  658. ;         (may be set by mem= param)
  659.          cmp      end_of_physmem,0
  660.          jz       @@continue
  661.          mov      eax,end_of_physmem
  662.          ret
  663. @@continue:
  664.          mov      ah,88h
  665.          cmp      intv_size,15h*4
  666.          jnb      @@sim_int15
  667.          cmp      have_to_intercept_setup,0
  668.          jz       @@sim_int15_1
  669.          call     get_mem_from_CMOS
  670.          jmp      @@1
  671.          ; we take int 15 as is, result may be wrong
  672.          ;                       but Linux takes this as memory
  673. @@sim_int15_1:
  674.          int      15h
  675.          jmp      @@1
  676. @@sim_int15:
  677.          cmp      wrong_realbios,0
  678.          jne      @@sim_int15_1
  679.          cmp      cs:real_bios_magic,0a5a5h  ; have we a saved value
  680.          jne      @@sim_int15_2              ; no
  681.          mov      ax,cs:real_bios_int15      ; yes
  682.          jmp      @@1
  683. @@sim_int15_2:
  684.          ; we take int 15 routine as saved by BIOSINTV
  685.          ; hopefully this gets better result
  686.          pushf
  687.          cli
  688.          push     cs
  689.          push     offset @@1
  690.          push     dword ptr intv_buf+(15h*4)
  691.          retf
  692. @@1:
  693.          movzx    eax,ax
  694.          shl      eax,10      ; now have extended mem in bytes
  695.          add      eax,100000h ; we add we 1Meg of conventional mem
  696.          ret
  697. get_effective_physmem endp
  698.  
  699.  
  700.  
  701. print_verbose proc near
  702.          pushad
  703.          push_  ds,es
  704.  
  705. @@print  macro  tx
  706.           lea    dx,tx
  707.           call   print
  708.          endm
  709. @@cr     macro
  710.           call   print_crlf
  711.          endm
  712. @@prints macro  tx,count
  713.           mov    cx,count
  714.           lea    si,tx
  715.           call   writestring
  716.          endm
  717. @@hexw   macro  v
  718.           mov    ax,v
  719.           call   writehexword
  720.          endm
  721.  
  722.          @@print  @@t1
  723.          @@prints image_name,<size image_name>
  724.          cmp      have_to_intercept_setup,2
  725.          jne      @@m1
  726.          cmp      setup_header_version,0105h
  727.          jb       @@m1
  728.          cmp      kernel_version,0
  729.          jz       @@m1
  730.          @@print  @@t1_
  731.          mov      dx,kernel_version
  732.          add      dx,offset setup_prog
  733.          call     print
  734. @@m1:
  735.          @@print  @@t2
  736.          @@hexw   kernel_size
  737.          cmp      have_big_kernel,0
  738.          jz       @@m1_1
  739.          @@print  @@t2_big
  740.          jmp      @@m1_2
  741. @@m1_1:
  742.          @@print  @@t2_
  743. @@m1_2:
  744.          @@hexw   new_setup_size
  745.          cmp      setup_version,0201h
  746.          jb       @@m1_5
  747.          test     loadflags,CAN_USE_HEAP
  748.          jz       @@m1_5
  749.          @@print  @@t2_heap
  750.          mov      ax,heap_end_ptr
  751.          sub      ax,new_setup_size
  752.          @@hexw   ax
  753. @@m1_5:
  754.          @@print  @@v1
  755.          @@hexw   vga_mode
  756.          @@print  @@c2
  757.          lea      di,command_line
  758.          xor      ax,ax
  759.          call     strlen
  760.          push     ax
  761.          call   writehexword
  762.          @@print  @@c1
  763.          pop      cx
  764.          @@prints command_line,cx
  765.          @@cr
  766.  
  767. @@verbose_stat:
  768.          @@print  @@t21
  769.          mov      eax,load_buffer_size
  770.          call   writehexdword
  771.  
  772.          movzx    bx,high_mem_access
  773.          shl      bx,1
  774.          mov      dx,@@hmtable[bx]
  775.          call   print
  776.  
  777.          @@print  @@t21_
  778.          mov      ax,maximum_setup_sects*512
  779.          call   writehexword
  780.          cmp      have_relocated_setup,0
  781.          jz       @@mmt22
  782.          @@print  @@t21_oc
  783. @@mmt22:
  784.          cmp      high_mem_access,0
  785.          jz       @@mmt23
  786.          @@print  @@t22low
  787.          mov      eax,heap_end
  788.          sub      eax,heap_ptr
  789.          call   writehexdword
  790.          @@print  @@t22low2
  791. @@mmt23:
  792.          @@print  @@t22
  793.          call   get_effective_physmem
  794.          call   writehexdword
  795.  
  796.  
  797.          @@print  @@t5
  798.          lea      dx,@@real_
  799.          cmp      cpu_type,cpu_386GE
  800.          je       @@3
  801.          lea      dx,@@real_p
  802.          ja       @@3
  803.          lea      dx,@@v86
  804. @@3:
  805.          call   print
  806.          cmp      wrong_realbios,0
  807.          je       @@3__
  808.          @@print  @@t6_
  809.          lea      dx,@@t6__
  810.          jmp      @@3_1
  811. @@3__:
  812.          cmp      intv_size,0
  813.          jz       @@3_1_
  814.          lea      dx,@@t6
  815.          cmp      intv_size,(size intv_buf)  ; have we REALBIOS
  816.          jna      @@3_
  817.          lea      dx,@@t6_
  818. @@3_:
  819.          call   print
  820.          lea      dx,@@no
  821.          cmp      intv_size,0
  822.          jz       @@3_1
  823.          lea      dx,@@yes
  824. @@3_1:
  825.          call   print
  826. @@3_1_:
  827.          @@print  @@t7
  828.          lea      dx,@@no
  829.          cmp      have_to_intercept_setup,1
  830.          jb       @@3_2
  831.          lea      dx,@@setup_
  832.          je       @@3_2
  833.          lea      dx,@@setup
  834.          call   print
  835.          mov      ax,setup_version
  836.          call   writehexword
  837.          jmp      @@3_2_1
  838. @@3_2:
  839.          call   print
  840. @@3_2_1:
  841.          @@print  @@s
  842.          mov      bx,cpu_check_status
  843.          mov      dx,@@stable[bx]
  844.          call   print
  845.          @@print  @@cc2
  846.          lea      di,comline+1
  847.          xor      ax,ax
  848.          call     strlen
  849.          push     ax
  850.          call   writehexword
  851.          @@print  @@cc1
  852.          pop      cx
  853.          @@prints comline+1,cx
  854.          @@print  @@started
  855.          lea      dx,@@rundos
  856.          cmp      can_exit_to_dos,0
  857.          jnz      @@4_1
  858.          lea      dx,@@runshell
  859. @@4_1:
  860.          call     print
  861.  
  862.          cmp      cannot_load_because_of_windows,0
  863.          jz       @@5
  864.          @@print  @@sw
  865. @@5:
  866.          cmp      cpu_type,cpu_386GE_real_paging
  867.          jne      @@6
  868.          @@print  @@w1
  869. @@6:
  870.  
  871.          movzx    eax,kernel_size
  872.          shl      eax,4
  873.          cmp      eax,load_buffer_size
  874.          jb       @@7
  875.          @@print  @@w2
  876. @@7:
  877.          cmp      new_setup_size,maximum_setup_sects*512
  878.          jna      @@8
  879.          @@print  @@w3
  880. @@8:
  881.          cmp      option_force,0
  882.          jz       @@8_1
  883.          @@print  @@w4
  884. @@8_1:
  885.          pop_   ds,es
  886.          popad
  887.          ret
  888.  
  889. @@t1     db         13,10,'Your current LINUX kernel boot configuration is:'
  890.          db         13,10,'  image file:       $'
  891. @@t1_    db         13,10,'  kernel version    $'
  892. @@t2     db         13,10,'  kernel size:     0x$'
  893. @@t2_    db               '0                  setup size:  0x$'
  894. @@t2_big db               '0 (high loaded)    setup size:  0x$'
  895. @@t2_heap db                                                  ', heap: 0x$'
  896.  
  897. IF 0
  898. @@t3     db         13,10,'  ram disk size:    0x$'
  899. @@t4     db         13,10,'  root device:      0x$'
  900. @@tro    db     '  read only$'
  901. @@trw    db     '  read/write$'
  902. ENDIF
  903.  
  904. @@v1     db         13,10,'  VGA mode:         0x$'
  905. @@c2     db         13,10,'  command line (size 0x$'
  906. @@c1     db                                         '):'
  907.          db         13,10,'    $'
  908. @@t21    db         13,10,'Your current DOS/CPU configuration is:'
  909.          db         13,10,'  load buffer size: 0x$'
  910. @@hmtable dw    @@lowtx,@@vcpitx,@@int15tx,@@xmstx
  911. @@lowtx  db     '     $'
  912. @@vcpitx db     ' VCPI$'
  913. @@int15tx db    ' EXT $'
  914. @@xmstx  db     ' XMS $'
  915. @@t21_   db               ', setup buffer size:  0x$'
  916. @@t21_oc db                                              ' (reloc setup)$'
  917. @@t22low db         13,10,'  lowmem buffer:    0x$'
  918. @@t22low2 db                                     ' (part of load buffer)$'
  919. @@t22    db         13,10,'  total memory:     0x$'
  920. @@t5     db         13,10,'  CPU is in $'
  921. @@t6     db                               ',  BIOSINTV.SYS:   $'
  922. @@t6_    db                               ',  REALBIOS:       $'
  923. @@t6__   db     'YES, but ROM-BIOS-DATE differs, must rerun REALBIOS.EXE$'
  924. @@t7     db         13,10,'  SetupIntercept: $'
  925. @@yes    db     'YES$'
  926. @@no     db     'NO$'
  927. @@v86    db     'V86 mode$'
  928. @@real_  db     'REAL mode$'
  929. @@real_p db     'undocumented REAL PAGING mode, trying any way$'
  930. @@setup_ db     'YES, patching setup code$'
  931. @@setup  db     'YES, legal intercept, setup header version $'
  932. @@s      db         13,10,'  stat$'
  933. @@s8     db     '4: VCPI_present, physmap=logmap, all OK for switch to realmode$'
  934. @@s6     db     '3: VCPI_present, but physmap != logmap (check aborted)$'
  935. @@s4     db     '2: cpu_V86, but no VCPI available (check aborted)$'
  936. @@s2     db     '1: cpu in real 386 mode, no need to backswitch$'
  937. @@s0     db     '0: cpu < 386$'
  938. @@stable dw     @@s0,@@s2,@@s4,@@s6,@@s8
  939. @@cc2    db         13,10,'  input params (size 0x$'
  940. @@cc1    db                                         '):'
  941.          db         13,10,'    $'
  942. @@started db        13,10,'  LOADLIN started from $'
  943. @@rundos db               'DOS-prompt',13,10,'$'
  944. @@runshell db             'CONFIG.SYS (shell= ...)',13,10,'$'
  945. @@sw     db     '  You are running under MS-WINDOWS or Windows 95',13,10,'$'
  946. @@w1     db     'WARNING:',13,10
  947.          db     '  Your CPU is in realmode, but PAGING is enabled !',13,10
  948.          db     '  This is possible, but neither documented nor supported by INTEL.',13,10
  949.          db     "  May be your motherboard's BIOS is mapping shadow ram this way,",13,10
  950.          db     '  or you are using one of those old and strange EMM managers,',13,10
  951.          db     '  but probably this is an indication of a not exactly compatible',13,10
  952.          db     '  486 clone. If you are not using one of the older EMM-managers',13,10
  953.          db     '  you better should use the -clone switch to work around.',13,10,'$'
  954. @@w2     db     'WARNING: Not enough free memory (load buffer size)$',13,10
  955. @@w3     db     'WARNING: The setup buffer of LOADLIN is too small (must recompile)$',13,10
  956. @@w4     db     'WARNING: Option -f set, CPU-Check bypassed !$',13,10
  957.  
  958. print_verbose_stat:
  959.          pushad
  960.          push_  ds,es
  961.          jmp    @@verbose_stat
  962. print_verbose endp
  963.  
  964.  
  965. close_debug_file proc near
  966.          cmp     debug_file_handle,0
  967.          jz      @@ex
  968.          push_   ax,bx
  969.          mov     bx,debug_file_handle
  970.          DosCall DOS_CLOSE_FILE
  971.          mov     debug_file_handle,0
  972.          pop_    ax,bx
  973. @@ex:
  974.          ret
  975. close_debug_file endp
  976.  
  977.  
  978. wait_and_reset_dsk proc near
  979.          pushad
  980.          push_   ds,es,fs,gs
  981.          pushf
  982.          sti
  983.          cmp     cs:option_dskreset,0
  984.          jz      @@wait
  985.          mov     ax,0
  986.          mov     dl,80h            ; reset the whole disk system
  987.          int     13h
  988.          cmp     cs:option_wait,0
  989.          jnz     @@wait
  990.          mov     cs:option_wait,9  ; wait at least 1/2 a second
  991. @@wait:
  992.          cmp     cs:option_wait,0
  993.          jz      @@ex
  994.          cli
  995.          mov     ax,40h
  996.          mov     ds,ax
  997.          movzx   eax,cs:option_wait
  998.          add     eax,dword ptr ds:[6ch]
  999.          sti
  1000.          nop
  1001. @@loop:
  1002.          nop
  1003.          cli
  1004.          cmp     eax,dword ptr ds:[6ch]
  1005.          sti
  1006.          ja      @@loop
  1007. @@ex:
  1008.          popf
  1009.          pop_    ds,es,fs,gs
  1010.          popad
  1011.          ret
  1012. wait_and_reset_dsk endp
  1013.  
  1014.  
  1015. ;=============================================================================
  1016. logo_tx               label byte
  1017. IFDEF ALPHA
  1018.   INCLUDE LOADLINA.ASM
  1019. ENDIF
  1020.                       db   'LOADLIN v',LOADLIN_VERSION,' (C) 1994..1996 Hans Lermen <lermen@elserv.ffm.fgan.de>',13,10,'$'
  1021. comspec_tx            db   'comspec',0
  1022. windows_tx            db   'windir',0
  1023. err_uppermem_tx       db   'Not enough free memory between 90000h and 9ffffh,',13,10
  1024.                       db   'may be you have some zombie programs, try to reboot.',13,10
  1025.                       db   "If this doesn't help, try to find out what driver occupies this space."
  1026. newline_tx            db   13,10,'$'
  1027. enter_commandline_tx  db   'Please enter name of kernel image file followed by optional ',13,10
  1028.                       db   'command line parameters for Linux (e.g.  root=XXXX)',13,10
  1029.                       db   'or @file ( file = param file ) or "empty string" to abort:',13,10,'$'
  1030. abort_tx              db   'LOADLIN aborted by user',13,10,'$'
  1031. err_file_notfound_tx  db   'Image file not found,',13,10,'$'
  1032. enter_file_tx         db   'enter file name of Image:',13,10,'$'
  1033. err_wrong_file_tx     db   'not an Image file,',13,10,'$'
  1034. err_wrong_setup_tx    db   'Your current configuration needs interception of "setup.S,"',13,10
  1035.                       db   'but the setup-code in your Image file is *very* old (or wrong)',13,10
  1036.                       db   'Please use BIOSINTV/REALBIOS or try an other Image file',13,10,'$'
  1037. err_setup_too_long_tx db   'Ooops..., size of "setup.S" has become too long for LOADLIN,',13,10
  1038.                       db   'please E-mail this condition to lermen@elserv.ffm.fgan.de !',13,10,'$'
  1039. err_kernel_to_big_tx  db   'not enough memory below 90000h to load kernel',13,10,'$'
  1040. err_io_tx             db   'IO Error during load',13,10,'$'
  1041. insert_floppy_tx      db   'Insert floppy disk for loading into RAMDISK',13,10,'$'
  1042. err_cpu_v86_tx        db   13,10,'CPU is in V86-mode (may be WINDOWS, EMM386, QEMM, 386MAX, ...)',13,10
  1043.                       db   'You need pure 386/486 real mode or a VCPI server to boot Linux',13,10
  1044.                       db   'VCPI is supported by most EMS drivers (if EMS is enabled),',13,10
  1045.                       db   "but never under WINDOWS-3.1 or WINDOWS'95.",13,10
  1046.                       db   "(However, real DOS-Mode of WINDOWS'95 can have EMS driver with VCPI)",13,10
  1047.                       db   'If loading via VCPI you also MUST have:',13,10
  1048.                       db   '  1. An interceptable setup-code (see MANUAL.TXT)',13,10
  1049.                       db   '  2. Identical Physical-to-Virtual mapping for the first 640 Kbytes',13,10,'$'
  1050. err_wrong_cpu_tx      db   'You need a 386 CPU at minimum, but you haven''t !',13,10,'$'
  1051. err_comfile_tx        db   'error on reading command line response file',13,10,'$'
  1052. option_t_terminate_tx db   13,10,'Option -t set, Linux not loaded',13,10,'$'
  1053. option_t_forced_tx    db   13,10,'ERROR detected, Linux not loaded',13,10,'$'
  1054. err_in_config_sys_tx  db   13,10,'LOADLIN holding in idle loop (You must reboot)',13,10,'$'
  1055. ;-----------------------------------------------------------------------------
  1056. usage_tx  db  13,10
  1057.           db  'USAGE:',13,10
  1058.           db  '  LOADLIN @params',13,10
  1059.           db  '  LOADLIN [zimage_file] [options] [boot_params]',13,10
  1060.           db  '    without any params, LOADLIN displays this help message.',13,10
  1061.           db  '    @params:',13,10
  1062.           db  '       params is a DOS file containing all other options',13,10
  1063.           db  '    zimage_file:',13,10
  1064.           db  '       DOS file name of compressed Linux kernel image',13,10
  1065.           db  '    options:',13,10
  1066.           db  '       -v        verbose, show information on params and configuration',13,10
  1067.           db  '       -t        test mode, do all but starting Linux, also sets -v',13,10
  1068.           db  '       -d file   debug mode, same as -t, but duplicates output to "file"',13,10
  1069.           db  "       -clone    ( Please read MANUAL.TXT before using this switch! )",13,10
  1070.           db  "       -n        no translation for root=/dev/...",13,10
  1071.           db  "       -txmode   switch to textmode 80x25 on startup",13,10
  1072.           db  "       -noheap   disable use of setup heap",13,10
  1073.           db  "       -wait=nn  after loading wait nn (DOS)ticks before booting Linux",13,10
  1074.           db  "       -dskreset after loading reset all disks before booting Linux",13,10
  1075.           db  '    boot_params:',13,10
  1076.           db  '       root=xxx  filesystem to be mounted by Linux as "/"',13,10
  1077.           db  '                 (string passed unchanged to the kernel)',13,10
  1078.           db  '            xxx = hex number (e.g. root=201 for /dev/fd1)',13,10
  1079.           db  '                = /dev/mmmn (e.g. root=/dev/hda2)',13,10
  1080.           db  '                       mmm = fd,hda,hdb,sda,sdb...',13,10
  1081.           db  '                       n   = 1..10.. decimal',13,10
  1082.           db  '       ro        mount "/" readonly',13,10
  1083.           db  '       rw        mount "/" read/write',13,10
  1084.           db  '       initrd=x  (for kernels > 1.3.72) load file x into /dev/ram. If FS in x',13,10
  1085.           db  '                 contains /linuxrc, execute it, and then remount to root=xxx.',13,10
  1086.           db  '                 If root=/dev/ram, just load, bypass execution of /linuxrc',13,10,13,10
  1087.           db  '    for more boot params see PARAMS.TXT or Paul Gortmakers HOWTO:',13,10
  1088.           db  '      http://sunsite.unc.edu/mdw/HOWTO/BootPrompt-HOWTO.html',13,10
  1089.           db  '      http://rsphy1.anu.edu/~gpg109/BootPrompt-HOWTO.html',13,10
  1090. empty_tx  db  '$'
  1091.  
  1092.  
  1093.