home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / KERNELS / LODLIN15.ZIP / LOADLIN / LOADLIN.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-09-05  |  50.3 KB  |  1,571 lines

  1. ;   >>> this is file LOADLIN.ASM
  2. ;============================================================================
  3. ;   LOADLIN v1.5 (C) 1994 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. ; NOTE:
  30. ;
  31. ;   This program could not have been written as quickly without
  32. ;   the information found in the source code of F.Coutant's BOOTLIN
  33. ;
  34. ;   This program contains some modified source code from
  35. ;   my protected mode extender (LDOSX (C) 1991..1994 H.Lermen),
  36. ;   which was written as a fast multitasking alternative
  37. ;   to DJ.Delorie's extender (it runs DJ-GCC compiled binaries under DOS).
  38. ;
  39. ;   I was too lazy to reprogram the subroutines completely, so,
  40. ;   if You wonder what nonsense they are doing, keep in mind that they
  41. ;   were written for an other purpose.
  42. ;
  43. ;============================================================================
  44. ;
  45. ; Contributions and bug fixes for 1.5:
  46. ;
  47. ;
  48. ;   Javier Achirica <javier@autom.uva.es>
  49. ;
  50. ;       invented the switch-out-of-setup method (Javier's method),
  51. ;       which makes the BIOSINTV and REALBIOS method superfluous on nearly
  52. ;       all machines. The trick is: let setup run in V86 and intercept
  53. ;       just before going to protected mode.
  54. ;       (Thank you Javier for this very good work).
  55. ;
  56. ;============================================================================
  57.  
  58.               name    load_linux
  59.               .386
  60.               locals
  61.               jumps
  62.  
  63. REALBIOS_FILE equ 'C:\REALBIOS.INT'
  64.  
  65. SIGNATURE                = 'SrdH' ; "HdrS"
  66.  
  67. space4k                  =     1000h
  68. space2k                  =      800h
  69. space1k                  =      400h
  70.  
  71. our_stacksize            =     space2k
  72.  
  73. kernel_start_ equ     01000h     ; here the kernel must go
  74. kernel_end    equ     09000h
  75. standard_setup_sects  equ 4      ; number of setup sectors, older kernels
  76. maximum_setup_sects   equ (32-1) ; max number of setup sectors for newer kernels
  77. High_Seg      equ     kernel_end ; here first 512 + 4*512 + n*512 bytes of image must go
  78. High_Addr     equ     (High_Seg*16)
  79.  
  80. setup_intercept_int equ   7fh
  81.  
  82.  
  83. debug_stop macro marker
  84.            mov   ax,0b800h
  85.            mov   ds,ax
  86.            mov   byte ptr ds:[1],70h
  87.            mov   byte ptr ds:[0],marker
  88.            jmp   short $
  89.            endm
  90.  
  91. align_  macro   start,val
  92.         org     (((($-start)+(val-1))/val)*val)
  93.         endm
  94.  
  95.  
  96. psp_seg segment  at 0 use16
  97.  
  98. ; -------------PSP Program Segment Prefix----------------------
  99.         org      2h
  100.   PSP_memend_frame            dw ?
  101.         org      2ch
  102.   PSP_envir_frame             dw ?
  103.         org      80h
  104.   PSP_DTA                     db ? (100h-80h) dup(?)
  105. ; -------------------------------------------------------------
  106. psp_seg ends
  107.  
  108. code    segment  para use16
  109.         assume   cs:code,ds:psp_seg,es:code
  110. code_org0     label   byte
  111.  
  112. ; ---------------------------------------------------------------------
  113. ;                        Bootsector (512 bytes)
  114. ;                        within this BEFORE start of setup:
  115. ;                        (may be set by "LOADLIN")
  116. bootsec       label   byte
  117.               org     20h
  118. CL_MAGIC      dw      ?  ;0020   commandline magic number (=0xA33F)
  119. CL_OFFSET     dw      ?  ;0022   commandline offset
  120.                          ; Address of commandline is calculated:
  121.                          ;   0x90000 + contents of CL_OFFSET
  122.                          ; The command line is parsed by "init/main.c"
  123.                          ; Value of NAME=XXXX are put into the environement
  124.                          ; and can then be interpreted by the drivers
  125.                          ; and /etc/rc. The variabel "root=xxxx" is
  126.                          ; interpreted by main directly, "single" is
  127.                          ; interpreted by init or simpleinit.
  128.               org     1F1h
  129. setup_sects   db      ?  ; no. of sectors
  130. ro_flag       dw      ?  ; =0: root file system should be mounted read-write
  131.                          ;<>0: root file system should be mounted readonly
  132.                          ; (this will be overwritten by the kernel commandline
  133.                          ;  options "ro" / "rw")
  134. ;             --------------------------------
  135. ;                        within this AFTER setup has run:
  136.               org     0
  137. curr_curs     dw      ?  ;0000 saved cursor position
  138. ext_mem_size  dw      ?  ;0002     extended memory size in Kb (from int 0x15)
  139.               org     80h
  140. hd0_disk_par  label   byte ;080     hd0-disk-parameter from intvector 0x41
  141. hd1_disk_par  label   byte ;090     hd1-disk-parameter from intvector 0x46
  142.  
  143. ;             --------------------------------
  144. ;                        within this as loaded from "zImage"
  145.               org     01F4h
  146. kernel_size   dw      ?  ; size of kernel-part in the image-file
  147.                          ; (in 16 byte units, rounded up)
  148. swap_dev      dw      ?  ; swap device
  149.  
  150. ram_disk      dw      ?  ;01F8 size of ram-disk (in 1Kb units ) or ZERO
  151.                          ; if ram_disk is nonZERO then the kernel
  152.                          ; (driver/block/ramdisk.c: rd_load() )
  153.                          ; will try to load the contents for the ram-disk
  154.                          ; from the "root_dev" which MUST then have the
  155.                          ; floppyMAJOR.
  156.                          ; The file-system on that floppy must be MINIX
  157.                          ; If rd_load() succeeds it sets the root_dev
  158.                          ; to the ramdisk for mounting it.
  159.                          ;
  160.                          ; LOADLIN parses the commandline for the string
  161.                          ; "ramdisk=nnn" where nnn is the value for "ram_disk"
  162.                          ; after the kernel images has been loaded by LOADLIN
  163.                          ; it asks for inserting the floppy.
  164.                          ; (NOTE: You may have LOADLIN in A: and root_dev in B:
  165.                          ;        or vice versa).
  166.  
  167. vga_mode      dw      ?  ;01FA VGA-Mode
  168.                          ;      -3 = ask
  169.                          ;      -2 = Extended VGA
  170.                          ;      -1 = Normal VGA
  171.                          ;       0 = as "0" was pressed
  172.                          ;       n = as "n" was pressed
  173.                          ;
  174.                          ; LOADLIN parses the commandline for the string
  175.                          ; "vga=nnn" where nnn is the value for "vga_mode"
  176.                          ; it also excepts:
  177.                          ; "vga=ask","vga=normal",'vga=extended"
  178.  
  179. root_dev      dw      ?  ;01FC Root Device (high=Major, low=minor)
  180.                          ;(this can be overwritten by the kernel commandline
  181.                          ; option "root=XXXX")
  182. bootmagic     dw      ?  ;01FE Bootsector magic (0AA55h)
  183.  
  184. ; -------------------------------------------------------------------
  185.                          ; this area will be used to pass params
  186.                          ; from LOADLINX to LOADLIN, if the params file name is @@loadlinx@@ switch
  187.                          ;
  188.                          ; NOTE: @@loadlinx@@ must NOT be used,
  189.                          ;       if starting LOADLIN without LOADLINX
  190.               org     0200h
  191. params_from_loadlinX label byte
  192.  
  193.  
  194. ; -------------------------------------------------------------------
  195.               org     0200h
  196. setup_prog    label   byte
  197.                                     ; the setup-program itself
  198.                                     ; must be started at 9020h:0 !!!
  199.                                     ;                    =======
  200.               jmp     short start_of_setup
  201.                                     ; the setup header
  202.                                     ; (if you have applied the setup.S patch,
  203.                                     ;  or later, if we have it in the standard kernel)
  204. setup_header_sign     dd    ?
  205. setup_header_version  dw    ?
  206. setup_realmode_switch dd    ?
  207. start_sys_seg         dw    ?
  208. kernel_version        dw    ?
  209.                                     ; end of header
  210. start_of_setup:
  211.               org     setup_prog
  212.               db      maximum_setup_sects*512 dup(?)
  213. ; -------------------------------------------------------------
  214. ; the following layout is private tp LOADLIN.EXE :
  215.  
  216.                 align_ code_org0,4096
  217. pagedir         dd    2 dup(0)  ; must be aligned to 4 K
  218.                                 ; NOTE: we have only 1 (one) pagetable, so we
  219.                                 ;       need only 1 pagedir entry
  220.                                 ;       All current known CPUs (386,486,PENTIUM)
  221.                                 ;       tolerate the garbage behind this,
  222.                                 ;       as long as there is no access > 4MB.
  223.                                 ;       So we may overlap the pagedir with
  224.                                 ;       our code
  225. PSP_frame       dw    0  ; our psp
  226. fhandle         dw    0  ; file handle of imagefile
  227. kernel_start    dw    0  ; place were the kernel must at time of
  228.                          ; start of setup
  229. free_mem_start  dw    0  ; frame of free memory, starting at the begin of LOADLIN.EXE
  230. kernel_load_frame dw  0  ; where to load the image
  231.  
  232.     ; ----------------------------v
  233.     ; the following values are cleared on each call to "parscommandline"
  234.     ; (see "clear_to_default")
  235. parse_switches  label byte
  236. new_setup_size  dw    0
  237. new_vga_mode    dw    0
  238. new_ram_disk    dw    0
  239. new_root_dev    dw    0
  240. new_ro_flag     dw    0
  241. cl_pointer      dw    0  ; while parsing: aux pointer to command_line
  242. got_vga_mode    db    0
  243. got_ram_disk    db    0
  244. got_root_dev    db    0
  245. got_ro_flag     db    0
  246. option_v        db    0
  247. option_t        db    0
  248. option_t_forced db    0
  249. option_realbios db    0
  250. option_rx       db    0
  251. option_ja       db    0
  252. option_clone    db    0
  253. option_oldxd    db    0
  254. option_n        db    0
  255. option_nodiskprompt db 0
  256. intv_size       dw    0
  257. wrong_realbios  db    0
  258. have_to_force_realmode db 0 ; 0 = is in realmode
  259.                             ; 1 = is in V86, have to reenter realmode before
  260.                             ;     kernel goes to protected mode
  261.                             ;
  262. have_to_intercept_setup db 0; 0 = old method, no interception
  263.                             ; 1 = intercept boot/setup.S (Javier's method)
  264.                             ;     of older kernels just before going to
  265.                             ;     protected mode.
  266.                             ; 2 = same as 1, but intercepting newer kernels
  267.                             ;     with the setup.dif patch applied.
  268.                             ;
  269.  
  270. debug_file_handle dw    0  ; set to file handle if option -d is set
  271. logo_out        db    0
  272. kernelversion   dd    0     ; binary kernel version, decoded from
  273.                             ; the version string as follows:
  274.                             ; "1.2.3 (root@...) #4" becomes 01020304h
  275.                             ; if string is only 1.2.3  ---> #0 is assumed
  276. parse_switches_end label byte
  277.     ; ----------------------------^
  278.  
  279. can_exit_to_dos db    0
  280. cannot_load_because_of_windows db 0
  281. print_dots      db    0
  282. cpu_check_status dw   0
  283.  
  284. ;NOTE: all uninitialized data has been moved to end of modul
  285. ;      since version 1.4
  286.  
  287. ; -------------------------------------------------------------
  288.  
  289.  
  290.   _DEALLOCATE_PAGES          = 45h;
  291.   _GET_VERSION               = 46h;
  292.   _ALLOCATE_RAW_PAGES        = 5A01H
  293.   EMM_int                    = 67h;
  294.  
  295.  
  296.  
  297.   descript    struc
  298.     limit     dw    ?
  299.     base0     dw    ?
  300.     base16    db    ?
  301.     typbyte   db    ?
  302.     limit16   db    ?
  303.     base24    db    ?
  304.   descript    ends
  305.  
  306.  
  307.   Gdescript struc
  308.     gateoffs0    dw      ?
  309.     gateselector dw      ?
  310.     gatenotused  db      ?
  311.     gatetyppbyte db      ?
  312.     gateoffs16   dw      ?
  313.   Gdescript ends
  314.  
  315.  
  316.   ; definition of COMMON decriptor types (bit0..4 of descript.typbyte )
  317.   ; (bit 4 of descript.typbyte =0)
  318.   data_d        =     10000b    ; data segment descriptor
  319.     writable    =     00010b    ; =1 if write acces allowed to data segment
  320.     expand_down =     00100b    ; =1 limit counts down from base
  321.   code_d        =     11000b    ; code segment
  322.     readable    =     00010b    ; =1 if code also can be read (cannot be ovwritten)
  323.     conforming  =     00100b    ; =1 code can be accesses and executed
  324.                                 ;    regardless of it's privilege level
  325.  
  326.   ; definition of SYSTEM decriptor types  (bit0..4 of descript.typbyte )
  327.   ; (bit 4 of descript.typbyte =0)
  328.   TSS286_avail_d   =  01h
  329.   LDT_d            =  02h
  330.   TSS286_busy_d    =  03h
  331.   call_gate_d      =  04h
  332.   task_gate_d      =  05h
  333.   INT286_gate_d    =  06h
  334.   TRAP286_gate_d   =  07h
  335.   TSS386_avail_d   =  09h
  336.   TSS386_busy_d    =  0bh
  337.   call386_gate_d   =  0ch
  338.   INT386_gate_d    =  0eh
  339.   TRAP386_gate_d   =  0fh
  340.  
  341.   ; definition of privilege levels (bit5..6 of descript.typbyte )
  342.   p0               =  0      ;┐
  343.   p1               =  1*32   ;├ super visor levels
  344.   p2               =  2*32   ;┘
  345.   puser            =  3*32
  346.  
  347.  
  348.   ;definition of granularity ( bits7..8 in descript.limit16 )
  349.   gran_byte        =  0
  350.   gran_page        =  10000000b  ; 4k granularity
  351.   ; for data_selectors:
  352.   data_USE16       =  0
  353.   gran_big         =  01000000b  ; big segment
  354.   data_USE32       =  gran_big   ; use 32-bit stack pointer ESP instead of SP
  355.   ;                Intel says: relevant only together with expand_down  for data_d
  356.   ;                But that is WRONG :
  357.   ;                BIG segment must be set also if the descriptor is greater 64K
  358.   ;                and is used to load SS !
  359.   ;                (because SP cannot access behind 64K)
  360.   ;
  361.   ; for code_selectors:
  362.   code_USE32       =  01000000b  ; default operand size 32 bit (for code segments)
  363.   code_USE16       =  00000000b  ; default operand size 16 bit (for code segments)
  364.  
  365.  
  366.   ; segment present bit (bit7 of descript.typbyte )
  367.   is_present       =128
  368.   not_present      =0
  369.  
  370.   descriptor macro name,typ,plevel,present,limit,gran,base
  371.   name descript <limit and 0ffffh,base and 0ffffh,low (base shr 16),typ or plevel or present,(limit shr 16) or gran,high (base shr 16)>
  372.             endm
  373.  
  374.  
  375.   ;GDT Global Descriptor Table -------------------------v
  376.              align_  code_org0,16
  377.   gdtnull    descript  <?>    ;0000   never accessable
  378.   gdtvcpi_code descript <?>   ;0008
  379.   gdtvcpi2   descript  <?>    ;0010
  380.   gdtvcpi3   descript  <?>    ;0018
  381.   descriptor gdt_core,(data_d+writable),p0,is_present,0fffffh,(gran_page+data_USE32),0
  382.   descriptor gdt_code,(code_d+readable),p0,is_present,0ffffh,(gran_byte+code_USE16),High_Addr
  383.   descriptor gdt_data,(data_d+writable),p0,is_present,0ffffh,(gran_byte+data_USE16),High_Addr
  384.   descriptor gdt_ldt,LDT_d,p0,is_present,7,gran_byte,(High_Addr+(ldtnull-code_org0))
  385.   descriptor gdt_tss,TSS286_avail_d,p0,is_present,0ffh,gran_byte,(High_Addr+(our_tss-code_org0))
  386.   gdtlast    descript  <?>    ; dummy for addressing
  387.  
  388.   g_vcpi_code equ      (gdtvcpi_code-gdtnull)
  389.   g_core     equ       (gdt_core-gdtnull)
  390.   g_code     equ       (gdt_code-gdtnull)
  391.   g_data     equ       (gdt_data-gdtnull)
  392.   g_ldt      equ       (gdt_ldt-gdtnull)
  393.   g_tss      equ       (gdt_tss-gdtnull)
  394.   ;GDT Global Descriptor Table -------------------------^
  395.  
  396.  
  397.   ;LDT Local  Descriptor Table -------------------------v
  398.   ldtnull    descript  <?>    ;0000   never accessable
  399.   ldtlast    descript  <?>    ; dummy for addressing
  400.   ;LDT Local  Descriptor Table -------------------------^
  401.  
  402.   ;                  align_  SYSTEMDATA_,1024
  403.   ;IDT Interrupt Descriptor Table -------------------------v
  404.   idtnull    descript  32 dup (<0>)
  405.   idtlast    descript  <?>    ; dummy for addressing
  406.   ;IDT Interrupt Descriptor Table -------------------------^
  407.  
  408.   our_tss    dd        128 dup (?)    ; our TSS Task State Segment
  409.  
  410.  
  411.   ;params for switching TO protected mode -------------------------v
  412.                           ;NOTE: this Data MUST be in LOW_MEM (below 1 Mbyte),
  413.                           ;      data referenced by this structure
  414.                           ;      CAN be in memory above 1 Mbyte
  415.                           ;      On switching to protected mode the server
  416.                           ;      first loads CR3 (paging base) from "our_CR3".
  417.                           ;
  418.                         ; value of CR3 to be loaded by server
  419.     our_CR3    dd       (High_Addr+(pagedir-code_org0))
  420.                         ; linear address in first Mbyte pointing to
  421.                         ; value of GDTR ("our_GDTR") to be loaded by server
  422.     our_GDTRptr dd      (High_Addr+(our_GDTR-code_org0))
  423.                         ; linear address in first Mbyte pointing to
  424.                         ; value of IDTR ("our_IDTR") to be loaded by server
  425.     our_IDTRptr dd      (High_Addr+(our_IDTR-code_org0))
  426.                         ; value of LDTR to be loaded by server
  427.     our_LDTR   dw       g_ldt
  428.                         ; value of TR to be loaded by server
  429.     our_TR     dw       g_tss
  430.                         ; Fword, pointer to code to be started by server
  431.     protected_mode_target DD ?
  432.                           DW g_code
  433.   ;  belongs to above
  434.     our_GDTR   dw       (gdtlast-gdtnull)-1    ;limit (byte gran)
  435.                         ;linear (not physical) base address of "gdtnull"
  436.     laddr_GDT  dd       (High_Addr+(gdtnull-code_org0))
  437.                dw       ?    ; (just for align "laddr_IDT" to Dword)
  438.     our_IDTR   dw       (idtlast-idtnull)-1    ;limit (byte gran)
  439.                         ;linear (not physical) base address of "Idtnull"
  440.     laddr_IDT  dd       (High_Addr+(idtnull-code_org0))
  441.   ;-------------------------------------------------------------------^
  442.  
  443.   pagedir_template dd     (High_Addr+(page0-code_org0)+3)
  444.  
  445. ; -------------------------------------------------------------
  446.  
  447.  
  448. ;=============================================================================
  449.  
  450.  
  451. DOS_WRITE_STRING        = 009h ; Display a '$' terminated string
  452. DOS_BUFFERED_INPUT      = 00Ah ; Read text and store it in a buffer
  453. DOS_OPEN_FILE           = 03Dh ; Open an existing file
  454. DOS_CREATE_FILE         = 03Ch ; create a new file
  455. DOS_CLOSE_FILE          = 03Eh ; Close a file
  456. DOS_READ_FROM_HANDLE    = 03Fh ; Read from DOS file handle
  457. DOS_WRITE_TO_HANDLE     = 040h ; write to DOS file handle
  458. DOS_TERMINATE_EXE       = 04Ch ; Terminate program
  459.  
  460. DosCall macro function_code
  461.     mov ah,function_code
  462.     int 21h
  463. endm
  464. DosInt macro
  465.     int 21h
  466. endm
  467.  
  468.  
  469.  
  470. push_ macro r1,r2,r3,r4,r5,r6,r7,r8,rx
  471.            irp   parm,<&r1,&r2,&r3,&r4,&r5,&r6,&r7,&r8,&rx>
  472.              ifndef parm
  473.                exitm
  474.              endif
  475.              push parm
  476.            endm
  477.          endm
  478. pop_  macro r1,r2,r3,r4,r5,r6,r7,r8
  479.            irp   parm,<&r8,&r7,&r6,&r5,&r4,&r3,&r2,&r1>
  480.              ifdef parm
  481.                pop parm
  482.              endif
  483.            endm
  484.          endm
  485.  
  486. pushAD_struc macro prefix
  487.            irp   parm,<edi,esi,ebp,esp,ebx,edx,ecx,eax>
  488.              prefix&&parm  dd  ?
  489.            endm
  490.          endm
  491.  
  492.  
  493.  
  494. cpu_86     equ   0
  495. cpu_286    equ   2
  496. cpu_386V86 equ   3       ; is >=386, but in virtual 86 mode
  497. cpu_386GE  equ   4       ; >=386
  498. cpu_386GE_real_paging equ 5
  499. cpu_type   dw    0
  500.  
  501. cpu_check proc near
  502.         pushf
  503.         xor     ax,ax   ;0000 to ax
  504.         push    ax
  505.         popf            ; try to put that in flags
  506.         pushf
  507.         pop     ax      ; look at what really went into flags
  508.         and     ah,0f0h ; mask off high flag bits
  509.         cmp     ah,0f0h
  510.         je      is_8086
  511.         mov     ax,0f000h
  512.         push    ax      ; try to set the high bits
  513.         popf
  514.         pushf
  515.         pop     ax      ; look at actual flags
  516.         and     ah,0f0h
  517.         je      is_80286
  518.                         ; is x86, x >= 3
  519.                         ; check for V86 or real-paging -mode
  520.         mov     ah,040h ; try to clear IOPL
  521.         push    ax
  522.         popf
  523.         pushf
  524.         pop     ax
  525.         and     ah,030h
  526.         jne     is_v86
  527.         cmp     option_clone,0
  528.         jnz     @@clone
  529.         .386p
  530.         mov     eax,cr0        ; normally this would cause a GP(0)-exception
  531.                                ; (i386 Programmers Reference Guide, INTEL 1987)
  532.                                ; if in V86-mode, but most EMMXXXX drivers
  533.                                ; seem to intercept this exception and allow
  534.                                ; reading the CR0.
  535.         .386
  536.         or      eax,eax
  537.         jz      is_v86         ; not a valid CR0, reserved bits are allways set
  538.                                ; (this may be not true on a 486 clone such as
  539.                                ;  the 486DLC, so if you have trouble with
  540.                                ;  interpreting real mode as V86 use the -clone switch
  541.                                ;
  542.         test    al,01h         ; test PE -bit
  543.         jz      is_greater_equal_80386
  544. is_v86:
  545.         mov     ax,cpu_386V86
  546. cpu_check_exit:
  547.         mov     cpu_type,ax
  548.         popf
  549.         ret
  550. is_8086:
  551.         mov     ax,cpu_86
  552.         jmp     cpu_check_exit
  553. is_80286:
  554.         mov     ax,cpu_286
  555.         jmp     cpu_check_exit
  556. is_greater_equal_80386:
  557.         test    eax,eax         ; test PG - bit
  558.         js      is_386_real_pageing
  559.         mov     ax,cpu_386GE
  560.         jmp     cpu_check_exit
  561.  
  562. is_386_real_pageing:
  563.         mov     ax,cpu_386GE_real_paging
  564.         jmp     cpu_check_exit
  565.  
  566. @@clone:                 ; on some 486 clones we have problems with CR0,
  567.                          ; so we are looking for EMM, and then
  568.                          ; we assume to be in V86, if we have EMM.
  569.         push    ds
  570.         xor     ax,ax
  571.         mov     ds,ax
  572.         mov     ds,word ptr ds:[emm_int*4+2]
  573.         mov     ax,cpu_386V86
  574.         cmp     dword ptr ds:[10+4],'0XXX'
  575.         jne     @@cl1
  576.         cmp     dword ptr ds:[10],'QMME'
  577.         je      @@clex
  578.         cmp     dword ptr ds:[10],'XMME'
  579.         je      @@clex
  580. @@cl1:
  581.         mov     ax,cpu_386GE
  582. @@clex:
  583.         pop     ds
  584.         jmp     cpu_check_exit
  585.  
  586. cpu_check endp
  587.  
  588. ;=============================================================================
  589.  
  590.  
  591. start:
  592.         .8086    ; we are not sure here if on a 368 CPU
  593.         mov      cs:PSP_frame,es
  594.         mov      ax,cs     ; switch the to our stack
  595.         mov      ss,ax
  596.         lea      sp,stack_top
  597.         mov      ds,ax
  598.         mov      es,ax
  599.         call     clear_uninitialized_data
  600.         mov      ds,cs:PSP_frame
  601.         cld
  602.         lea      si,PSP_DTA+1
  603.         lea      di,comline+1
  604.         mov      cl,PSP_DTA
  605.         xor      ch,ch
  606.         jcxz     start__2
  607. start__:                          ; skip leading blanks
  608.         cmp      byte ptr [si],' '
  609.         jne      start__2
  610.         inc      si
  611.         loop     start__
  612. start__2:
  613.         mov      comline-1,ch
  614.         mov      comline,cl
  615.         inc      cx             ; get the CR too
  616.         rep movsb               ; get the commandline out of psp
  617.  
  618.         push     cs
  619.         pop      ds
  620.         assume   ds:code
  621.                  ; from now on we have CS=DS=ES=SS
  622.  
  623.                  ; make sure that size byte is correct
  624.                  ; ( some DOS versions set only CR .. sometimes )
  625.         lea      di,comline+1
  626.         mov      al,13
  627.         call     strlen
  628.         cmp      al,comline
  629.         jnb      start_0
  630.         mov      comline,al
  631. start_0:
  632.         mov      bx,word ptr comline-1
  633.         xchg     bh,bl
  634.         mov      comline[bx+1],0  ; replace CR by ZERO
  635.  
  636.         mov      logo_out,0
  637.         mov      print_dots,0
  638.  
  639.         mov      kernel_start,kernel_start_ ; real kernel_start
  640.         mov      free_mem_start,cs  ;save CS as later freemem
  641.  
  642.                  ; now check if (on error) we can exit do DOS
  643.         lea      bx,comspec_tx
  644.         call     get_env_variable     ; we expect COMSPEC= in the environement
  645.         mov      al,byte ptr es:[di]
  646.         mov      can_exit_to_dos,al
  647.                  ; check if we are running under windows
  648.         lea      bx,windows_tx
  649.         call     get_env_variable     ; we expect WINDIR= in the environement
  650.         mov      al,byte ptr es:[di]
  651.         mov      cannot_load_because_of_windows,al
  652.         push     ds
  653.         pop      es
  654.  
  655.  
  656.         lea      ax,modul_end+15
  657.         shr      ax,4
  658.         mov      bx,ax
  659.         add      ax,High_Seg
  660.         mov      es,PSP_frame
  661.         cmp      ax,es:PSP_memend_frame
  662.         jnb      err_uppermem
  663.  
  664.         push     ds
  665.         pop      es                     ; restore es
  666.  
  667.         mov      ax,free_mem_start
  668.         mov      kernel_load_frame,ax
  669.         cmp      ax,kernel_start
  670.         jnb      start_1
  671.         mov      ax,kernel_start
  672.         mov      kernel_load_frame,ax
  673. start_1:
  674.  
  675.                  ; check if we are on the right CPU
  676.         mov      cpu_check_status,0
  677.  
  678.         call     cpu_check
  679.         lea      dx,err_wrong_cpu_tx
  680.         cmp      ax,cpu_386V86
  681.         jb       err_print    ; has no 386 or greater at all
  682.  
  683.         .386    ; now we are sure beeing on a 386(and greater) CPU
  684. m2:
  685.         call     parscommandline
  686.         call     cpu_check    ; do it once more, because of option_clone
  687.  
  688.         mov      cpu_check_status,2
  689.         call     get_default_bios_intvectors
  690.         cmp      ax,cpu_386GE
  691.         jb       m2_1
  692.         test     intv_size,0fffch
  693.         jnz      start_continue    ; has $BIOSINTV or REALBIOS.INT
  694.         cmp      option_t_forced,0
  695.         jnz      start_continue
  696.         mov      have_to_intercept_setup,1
  697.         jmp      start_continue
  698. m2_1:
  699.         mov      cpu_check_status,4
  700.                               ; have 386, but are in V86-mode
  701.         call     check_VCPI_present
  702.         jz       err_wrong_cpu   ; has no VCPI-server
  703.         mov      cpu_check_status,6
  704.         call     check_low_mem_mapping
  705.         jz       err_wrong_cpu   ; has no identical phys/log mapping
  706.         mov      have_to_force_realmode,1
  707.         test     intv_size,0fffch
  708.         jnz      plain_switch    ; has $BIOSINTV or REALBIOS.INT
  709.                                  ; has no $BIOSINTV driver loaded
  710.                                  ; but will try to start Linux anyway
  711.         cmp      option_t_forced,0
  712.         jnz      plain_switch
  713.         mov      word ptr cs:intv_buf+(4*15h+2),0
  714.         mov      have_to_intercept_setup,1
  715. plain_switch:
  716.         mov      cpu_check_status,8
  717.  
  718.  
  719. start_continue:
  720.         cmp      comline,0   ; have we an emtpy string ?
  721.         jnz      m3
  722.         lea      dx,empty_tx
  723.         jmp      err_print
  724.  
  725.                           ; have file-name at minimum
  726.                           ; trying to open it
  727. m3:
  728.         mov      ax,DOS_OPEN_FILE shl 8
  729.         lea      dx,image_name
  730.         DosInt
  731.         jnc      fileopened
  732. m4:
  733.         lea      dx,err_file_notfound_tx
  734. m4_:
  735.         call     print
  736.         lea      dx,enter_commandline_tx
  737.         call     print
  738.         call     readstring
  739.         cmp      comline,0   ; have we an emtpy string ?
  740.         jnz      m2
  741.         lea      dx,abort_tx
  742.         call     print
  743.         jmp      err_exit
  744.  
  745. fileopened:
  746.         mov      fhandle,ax
  747.                           ; first look if it is really an image
  748.         mov      bx,ax
  749.         mov      ecx,512
  750.         mov      di,cs
  751.         call     read_handle   ; read the bootsector
  752.         jnc      have_bootsect
  753. fileopened_wrong:
  754.         DosCall  DOS_CLOSE_FILE
  755.         lea      dx,err_wrong_file_tx
  756.         jmp      m4_
  757. err_wrong_setup:
  758.         DosCall  DOS_CLOSE_FILE
  759.         lea      dx,err_wrong_setup_tx
  760.         jmp      m4_
  761. err_setup_too_long:
  762.         DosCall  DOS_CLOSE_FILE
  763.         lea      dx,err_setup_too_long_tx
  764.         jmp      m4_
  765.  
  766. have_bootsect:
  767.         cmp      ax,cx
  768.         jne      fileopened_wrong
  769.         cmp      bootmagic,0AA55h
  770.         jne      fileopened_wrong
  771.                             ; ok, now get the setup part
  772.         mov      di,cs
  773.         lea      bx,setup_prog
  774.         shr      bx,4
  775.         add      di,bx
  776.         mov      bx,fhandle
  777.         xor      ecx,ecx
  778.         mov      ch,setup_sects
  779.         shl      cx,1
  780.         jnz      new_bootsect
  781.         mov      ch,2*standard_setup_sects
  782. new_bootsect:
  783.         cmp      cx,maximum_setup_sects*512
  784.         ja       err_setup_too_long
  785.         mov      new_setup_size,cx
  786.         call     read_handle   ; read setup
  787.         jc       fileopened_wrong
  788.         cmp      ax,cx
  789.         jne      fileopened_wrong
  790.         cmp      have_to_intercept_setup,0
  791.         jz       dont_patch
  792.         cmp      dword ptr ds:setup_header_sign,SIGNATURE
  793.         jnz      not_signed
  794.         mov      have_to_intercept_setup,2
  795.         mov      word ptr ds:setup_realmode_switch,offset real_switch
  796.         mov      word ptr ds:setup_realmode_switch+2,High_Seg
  797.         mov      ax,kernel_load_frame
  798.         mov      word ptr ds:start_sys_seg,ax
  799.         jmp      dont_patch
  800. not_signed:
  801.         xor      di,di
  802.         mov      cx,new_setup_size
  803.         mov      al,0FAh    ; cli
  804.         cld
  805. keep_searching:
  806.         repnz scasb
  807.         jcxz     err_wrong_setup
  808.         cmp      dword ptr [di],70E680B0h ; mov al,80h
  809.                                           ; out 70h,al
  810.         jnz      keep_searching
  811.         mov      byte ptr [di-1],0CDh   ; int op code
  812.         mov      byte ptr [di],setup_intercept_int  ; int number
  813.         mov      word ptr [di+1],4444h ; inc sp       adjust stack
  814.                                        ; inc sp       (discard flags)
  815.         mov      byte ptr [di+3],90h   ; nop
  816. dont_patch:
  817.                           ; we convert the kernel version string
  818.                           ; to a binary number
  819.         xor      eax,eax
  820.         cmp      have_to_intercept_setup,2
  821.         jne      dont_patch_
  822.         call     get_kernel_version
  823. dont_patch_:
  824.         mov      kernelversion,eax
  825.         call     handle_kernel_specifics
  826.                           ; ok, now check the size of the kernel
  827.         mov      ax,High_Seg
  828.         sub      ax,kernel_load_frame
  829.         cmp      ax,kernel_size
  830.         ja       have_space
  831.         lea      dx,err_kernel_to_big_tx
  832.         cmp      option_t,0
  833.         je       err_print
  834.  
  835. have_space:
  836.                            ; now we update the params
  837.         cmp      command_line,0
  838.         jz       no_comline
  839.         mov      CL_MAGIC,0A33Fh
  840.         lea      ax,command_line
  841.         mov      CL_OFFSET,ax
  842.         mov      si,cl_pointer
  843.         mov      byte ptr [si-1],0 ;delete the last blank
  844.  
  845.  
  846. no_comline:
  847.                            ; check for ramdisk
  848.         cmp      got_ram_disk,0
  849.         jz       no_change_on_ramdisk
  850.         mov      ax,new_ram_disk
  851.         mov      ram_disk,ax
  852. no_change_on_ramdisk:
  853.                            ; check for vga
  854.         cmp      got_vga_mode,0
  855.         jz       no_change_on_vga
  856.         mov      ax,new_vga_mode
  857.         mov      vga_mode,ax
  858.  
  859. no_change_on_vga:
  860.                            ; check for ro_flag
  861.         cmp      got_ro_flag,0
  862.         jz       no_change_on_ro
  863.         mov      ax,new_ro_flag
  864.         mov      ro_flag,ax
  865.  
  866. no_change_on_ro:
  867.                            ; check for root_dev
  868.         cmp      got_root_dev,0
  869.         jz       no_change_on_root_dev
  870.         mov      ax,new_root_dev
  871.         mov      root_dev,ax
  872.  
  873. no_change_on_root_dev:
  874.         cmp      cannot_load_because_of_windows,0
  875.         jz       no_windows
  876.         call     force_error_verbose
  877. no_windows:
  878.  
  879.                            ; check for -v option
  880.         cmp      option_v,0
  881.         jz       no_option_v
  882.                            ; option -v (verbose) is set
  883.                            ; print some information
  884.         call     print_verbose
  885.  
  886. no_option_v:
  887.                            ; check for -t option
  888.         cmp      option_t,0
  889.         jz       no_option_t
  890.         DosCall  DOS_CLOSE_FILE
  891.         lea      dx,option_t_terminate_tx
  892.         cmp      option_t_forced,0
  893.         jz       no_option_t_forced
  894.         lea      dx,option_t_forced_tx
  895. no_option_t_forced:
  896.         call     print
  897.         jmp      err_exit
  898.  
  899. no_option_t:
  900.                            ; start of critical section
  901.                            ; =========================
  902.         call     close_debug_file
  903.  
  904.         ;---------------------------------------
  905.         mov      ax,High_Seg   ; move us high
  906.         mov      es,ax
  907.         push     cs
  908.         pop      ds
  909.         xor      si,si
  910.         xor      di,di
  911.         lea      cx,modul_end+3
  912.         shr      cx,2
  913.         rep movsd
  914.         push     es
  915.         pop      ds
  916.                  ; we have move ourself up
  917.                  ; must now change cs
  918.         push     ds
  919.         lea      ax,back_from_low
  920.         push     ax
  921.         retf
  922. back_from_low:
  923.         mov      ax,ds     ; switch the stack to top
  924.         mov      ss,ax
  925.         lea      sp,stack_top
  926.                  ; from now on we have CS=DS=ES=SS=setup_memory
  927.         ;-------------------------------------------
  928.         cmp      have_to_force_realmode,0
  929.         je       back_from_low_continue
  930.                  ; we have to do this once more
  931.                  ; because some VCPI-servers rely on an unmovable page0
  932.         call     get_VCPI_interface
  933.  
  934. back_from_low_continue:
  935.  
  936.                             ; now loading the kernel
  937.         mov      bx,fhandle
  938.         movzx    ecx,kernel_size
  939.         shl      ecx,4
  940.         mov      di,kernel_load_frame
  941.         mov      print_dots,2
  942.         call     read_handle   ; read the kernel
  943.         call     print_crlf
  944.         mov      print_dots,0
  945.         call     print_crlf
  946.         jc       err_io
  947.         add      eax,15
  948.         and      al,0f0h
  949.         cmp      eax,ecx
  950.         jnz      fileopened_wrong
  951.                            ; ok, all is read into memory
  952.         DosCall  DOS_CLOSE_FILE
  953.  
  954.         cmp      ram_disk,0 ; have we a ramdisk
  955.         jz       no_ram_disk
  956.         cmp      option_nodiskprompt,0;
  957.         jnz      no_ram_disk
  958.                            ;we must prompt for insertion of floppy
  959.         lea      dx,insert_floppy_tx
  960.         call     print
  961.         call     readstring    ; just to wait for prompt
  962. no_ram_disk:
  963.  
  964.         cli
  965. ___go:
  966.         cmp      have_to_intercept_setup,1
  967.         ja       ___go_switch
  968.         je       ___go_skip_move
  969.         call     move_kernel_down
  970. ___go_skip_move:
  971.         cmp      have_to_intercept_setup,1
  972.         jne      ___go_switch
  973.         xor      ax,ax
  974.         mov      ds,ax
  975.         mov      word ptr ds:[4*setup_intercept_int],offset real_switch
  976.         mov      word ptr ds:[4*setup_intercept_int+2],cs
  977. ___go_switch:
  978.         mov      ax,High_Seg
  979.         mov      ds,ax
  980.         mov      es,ax
  981.  
  982.         cmp      have_to_intercept_setup,0
  983.         ja       ___go_continue
  984.         call     switch_to_protected_mode_and_return_in_386realmode
  985.  
  986. ___go_continue:
  987.         call     restore_bios_default_vectors
  988.         lea      bx,setup_prog
  989.         shr      bx,4
  990.         mov      ax,High_Seg
  991.         add      ax,bx
  992.         lea      sp,setup_stack_top  ; separate stack during
  993.                                      ; setup and real_switch
  994.         push     ax
  995.         push     0
  996.         mov      ax,root_dev
  997.  
  998.         retf     ; and now it's the job of setup
  999.                  ; but NOTE:
  1000.                  ;   on have_to_force_realmode >0 setup calls real_switch
  1001.  
  1002. setup_own_stack df 0
  1003.  
  1004.  
  1005. real_switch proc far
  1006.         ;  NOTE:  we have to preserve ALL registers !
  1007.         ;         to avoid conflicts with future kernels
  1008.         cli
  1009.         push_    ds,es,fs,gs
  1010.         pushad
  1011.         mov      al,80h
  1012.         out      [70h],al
  1013.         mov      ax,cs
  1014.         mov      ds,ax
  1015.         mov      es,ax
  1016.         mov      word ptr setup_own_stack+4,ss
  1017.         mov      dword ptr setup_own_stack,esp
  1018.                         ; Ok,ok, today setup has our stack (no need to switch)
  1019.         mov      ss,ax  ; ... but we want to be sure for the future,
  1020.         lea      sp,stack_top ; so we switch to our stack
  1021.         cmp      have_to_intercept_setup,2 ; have we to move the kernel down ?
  1022.         je       @@3  ; no, setup will do it (knows the location of the image)
  1023.                       ; yes, we have patched in the intercept code,
  1024.                       ; so the kernel expects the kernel at 10000h
  1025.         call     move_kernel_down
  1026. @@3:
  1027.         call     switch_to_protected_mode_and_return_in_386realmode
  1028.         lss      esp,cs:setup_own_stack ; restore setup's stack
  1029.         popad
  1030.         pop_     ds,es,fs,gs
  1031.         retf
  1032. real_switch endp
  1033.  
  1034. ;=============================================================================
  1035.  
  1036.  
  1037. move_kernel_down proc near
  1038.                            ; is the kernel at its right place ?
  1039.         cli
  1040.         mov      ax,kernel_start
  1041.         cmp      kernel_load_frame,ax
  1042.         je       short @@ex  ; yes
  1043.                            ; no, must move it down
  1044.         push_    ds,es
  1045.         cld
  1046. mgran = 08000h
  1047.         mov      bp,mgran shr 4
  1048.         mov      ax,kernel_size
  1049.         mov      bx,kernel_start
  1050.         mov      dx,kernel_load_frame
  1051. @@loop:
  1052.         mov      cx,mgran shr 2
  1053.         mov      ds,dx
  1054.         mov      es,bx
  1055.         xor      si,si
  1056.         xor      di,di
  1057.         rep movsd
  1058.         add      bx,bp
  1059.         add      dx,bp
  1060.         sub      ax,bp
  1061.         cmp      ax,bp
  1062.         ja       @@loop
  1063.         mov      cx,ax
  1064.         shl      cx,2
  1065.         mov      ds,dx
  1066.         mov      es,bx
  1067.         xor      si,si
  1068.         xor      di,di
  1069.         rep movsd
  1070.  
  1071. IF 0   ; I guess, it's not needed
  1072.                            ; now clear the space behind the kernel (BSS)
  1073. @@clear:
  1074.         push     cs
  1075.         pop      ds
  1076.         mov      bp,mgran shr 4
  1077.         mov      bx,kernel_start
  1078.         add      bx,kernel_size
  1079.         mov      dx,High_Seg
  1080.         xor      eax,eax
  1081.         sub      dx,bx     ; count of remaining space
  1082.         jc       @@ex0
  1083.         jmp      @@ctest
  1084. @@cloop:
  1085.         mov      cx,mgran shr 2
  1086.         mov      es,bx
  1087.         xor      di,di
  1088.         rep stosd
  1089.         add      bx,bp
  1090.         sub      dx,bp
  1091. @@ctest:
  1092.         cmp      dx,bp
  1093.         ja       @@cloop
  1094.         mov      cx,dx
  1095.         shl      cx,2
  1096.         mov      es,bx
  1097.         xor      di,di
  1098.         rep stosd
  1099.  
  1100. @@ex0:
  1101. ENDIF
  1102.         pop_     ds,es
  1103.         mov      ax,kernel_start
  1104.         mov      kernel_load_frame,ax
  1105. @@ex:
  1106.         ret
  1107. move_kernel_down endp
  1108.  
  1109.  
  1110. err_wrong_cpu:
  1111.         lea      dx,err_cpu_v86_tx
  1112. err_print:
  1113.         cmp      word ptr comline-1,0   ; have we an command line
  1114.         jnz      err_print_2 ; no
  1115.                              ; yes, print help and status
  1116.         push     dx
  1117.         lea      dx,usage_tx
  1118.         call     print
  1119.         pop      dx
  1120. err_print_2:
  1121.         call     print
  1122.         cmp      cpu_type,cpu_386V86
  1123.         jb       err_exit
  1124.         call     print_verbose_stat
  1125.         jmp      err_exit
  1126. err_io:
  1127.         lea      dx,err_io_tx
  1128.         call     print
  1129.         jmp      err_exit
  1130.  
  1131. err_uppermem:
  1132.         lea      dx,err_uppermem_tx
  1133.         call     print
  1134. err_exit:
  1135.         cmp      cs:can_exit_to_dos,0
  1136.         jz       idle
  1137.         mov      al,1
  1138. exit_to_dos:
  1139.         call     close_debug_file
  1140.         DosCall  DOS_TERMINATE_EXE
  1141. idle:
  1142.         lea      dx,err_in_config_sys_tx
  1143.         call     print
  1144.         call     close_debug_file
  1145. idle_:
  1146.         sti
  1147.         jmp      idle_
  1148.  
  1149. real_print   proc    near
  1150. ; input: DX = offset of string within CODE
  1151.         .8086
  1152.         push    ds
  1153.         push    cs
  1154.         pop     ds
  1155.         push_   bx,cx,si
  1156.         mov     si,dx
  1157.         cld
  1158.         xor     ax,ax
  1159. @@loop:
  1160.         lodsb
  1161.         test    ax,ax
  1162.         jz      @@ok
  1163.         cmp     al,'$'
  1164.         jnz     @@loop
  1165. @@ok:
  1166.         dec     si
  1167.         sub     si,dx
  1168.         jz      @@null
  1169.         mov     cx,si
  1170.         mov     bx,1
  1171.         DosCall DOS_WRITE_TO_HANDLE
  1172.         cmp     debug_file_handle,0
  1173.         jz      @@ex
  1174.         mov     bx,debug_file_handle
  1175.         DosCall DOS_WRITE_TO_HANDLE
  1176. @@null:
  1177. @@ex:
  1178.         pop_    bx,cx,si
  1179.         pop     ds
  1180.         ret
  1181.         .386
  1182. real_print   endp
  1183.  
  1184. print proc near
  1185.         cmp      cs:logo_out,0
  1186.         jnz      @@ex
  1187.         mov      cs:logo_out,1
  1188.         push_    ax,dx
  1189.         lea      dx,logo_tx
  1190.         call     real_print
  1191.         pop_      ax,dx
  1192. @@ex:
  1193.         call     real_print
  1194.         ret
  1195. print endp
  1196.  
  1197.  
  1198. print_crlf proc near
  1199.         pushf
  1200.         push    ax
  1201.         push    dx
  1202.         lea     dx,@@crlf
  1203.         call    print
  1204.         pop     dx
  1205.         pop     ax
  1206.         popf
  1207.         ret
  1208. @@crlf  db      13,10,'$'
  1209. print_crlf endp
  1210.  
  1211. print_dot proc  near
  1212.         pushf
  1213.         cmp     cs:print_dots,1
  1214.         jb      @@ex
  1215.         push    ax
  1216.         push    dx
  1217.         lea     dx,@@dot_tx
  1218.         je      @@1
  1219.         lea     dx,@@start_tx
  1220.         dec     cs:print_dots
  1221. @@1:
  1222.         call    print
  1223.         pop     dx
  1224.         pop     ax
  1225. @@ex:
  1226.         popf
  1227.         ret
  1228. @@start_tx db    13,10,'LOADING'
  1229. @@dot_tx  db    '.$'
  1230. print_dot endp
  1231.  
  1232. read_handle proc    near
  1233. ; input:
  1234. ;   BX=  handle
  1235. ;  ECX=  count
  1236. ;   DI=  frame of destination
  1237. ; output:
  1238. ;   CARRY =1 , then read-error
  1239. ;  EAX= number of bytes transferred (even on CARRY=1)
  1240. ;
  1241. granularity = 02000h
  1242.         push    ds
  1243.         push    esi
  1244.         push    dx
  1245.         push    ecx
  1246.         mov     ds,di
  1247.         mov     esi,ecx
  1248.         mov     ecx,granularity
  1249.         xor     dx,dx
  1250.         jmp     @@start
  1251. @@next:
  1252.         DosCall DOS_READ_FROM_HANDLE
  1253.         call    print_dot
  1254.         jc      @@err
  1255.         cmp     ax,cx
  1256.         jne     @@eof
  1257.         sub     esi,ecx
  1258.         mov     ax,ds
  1259.         add     ax,(granularity shr 4)
  1260.         mov     ds,ax
  1261. @@start:
  1262.         cmp     esi,ecx
  1263.         ja      @@next
  1264.         mov     cx,si
  1265.         DosCall DOS_READ_FROM_HANDLE
  1266.         call    print_dot
  1267.         jc      @@err
  1268. @@eof:
  1269.         movzx   eax,ax
  1270.         sub     esi,eax
  1271.         pop     ecx
  1272.         mov     eax,ecx
  1273.         sub     eax,esi
  1274.         clc
  1275. @@ex:
  1276.         pop     dx
  1277.         pop     esi
  1278.         pop     ds
  1279.         ret
  1280. @@err:
  1281.         pop     ecx
  1282.         mov     eax,ecx
  1283.         sub     eax,esi
  1284.         stc
  1285.         jmp     @@ex
  1286. read_handle endp
  1287.  
  1288.  
  1289. read_comline_from_file proc near
  1290. ;;        mov      ax,DOS_OPEN_FILE shl 8
  1291. ;;        lea      dx,image_name+1
  1292. ;;        DosInt
  1293.         push     fs
  1294.         call     @@open
  1295.         jnc      @@isopen
  1296. @@err:
  1297.         lea      dx,err_comfile_tx
  1298.         call     print
  1299.         mov      word ptr comline-1,0
  1300.         jmp      @@ex
  1301. @@ioerr:
  1302. ;;        DosCall  DOS_CLOSE_FILE
  1303.         call     @@close
  1304.         jmp      @@err
  1305. @@isopen:
  1306.         mov      bx,ax
  1307.         cld
  1308.         lea      di,comline+1
  1309. @@loop:
  1310.         mov      dx,di
  1311.         mov      cx,1
  1312. ;;        DosCall  DOS_READ_FROM_HANDLE
  1313.         call     @@read
  1314.         jc       @@ioerr
  1315.         cmp      ax,1
  1316.         jne      @@eof
  1317.         mov      al,byte ptr [di]
  1318.         cmp      al,13
  1319.         je       @@loop
  1320.         cmp      al,'#'
  1321.         je       @@skipeol
  1322. @@skipcontinue:
  1323.         inc      di
  1324.         cmp      di, offset comline_end-1
  1325.         jnb      @@eof
  1326.         cmp      al,' '
  1327.         ja       @@loop
  1328.         cmp      di,offset comline+2
  1329.         jna      @@1
  1330.         cmp      byte ptr [di-2],' '  ; ignore multiple spaces
  1331.         jne      @@1
  1332.         dec      di
  1333.         jmp      @@loop
  1334. @@1:
  1335.         mov      byte ptr [di-1],' '
  1336.         jmp      @@loop
  1337. @@eof:
  1338.         mov      byte ptr [di],0
  1339.         mov      ax,di
  1340.         sub      ax,offset comline+1
  1341.         xchg     al,ah
  1342.         mov      word ptr comline-1,ax
  1343. ;;        DosCall  DOS_CLOSE_FILE
  1344.         call     @@close
  1345.         jmp      @@ex
  1346. @@skipeol:
  1347.         mov      dx,di
  1348.         mov      cx,1
  1349. ;;        DosCall  DOS_READ_FROM_HANDLE
  1350.         call     @@read
  1351.         jc       @@ioerr
  1352.         cmp      ax,1
  1353.         jne      @@eof
  1354.         cmp      byte ptr [di],10
  1355.         jne      @@skipeol
  1356.         jmp      @@skipcontinue
  1357.  
  1358. @@ex:
  1359.         pop      fs
  1360.         ret
  1361.  
  1362. ; -----------
  1363.  
  1364. @@virtual db     0
  1365.  
  1366. @@open:                    ; virtual open routine
  1367.         cmp      dword ptr image_name,'ol@@'
  1368.         jne      @@open_d
  1369.         cmp      dword ptr image_name+4,'ilda'
  1370.         jne      @@open_d
  1371.         cmp      dword ptr image_name+4+4,'@@xn'
  1372.         je       @@open_v
  1373. @@open_d:
  1374.         mov      @@virtual,0
  1375.         lea      dx,image_name+1
  1376.         mov      ax,DOS_OPEN_FILE shl 8
  1377.         DosInt
  1378.         ret
  1379. @@open_v:
  1380.         mov      @@virtual,1
  1381.         mov      ax,High_Seg
  1382.         mov      fs,ax
  1383.         lea      ax,params_from_loadlinX
  1384.         clc
  1385.         ret
  1386.  
  1387. @@close:
  1388.         cmp      @@virtual,0
  1389.         jz       @@close_d
  1390.         ret
  1391. @@close_d:
  1392.         DosCall  DOS_CLOSE_FILE
  1393.         ret
  1394. @@read:
  1395.         cmp      @@virtual,0
  1396.         jz       @@read_d
  1397.         mov      al, byte ptr fs:[bx]
  1398.         or       al,al
  1399.         jz       @@read_eof
  1400.         inc      bx
  1401.         mov      byte ptr [di],al
  1402.         mov      ax,1
  1403.         clc
  1404.         ret
  1405. @@read_eof:
  1406.         xor      ax,ax
  1407.         clc
  1408.         ret
  1409. @@read_d:
  1410.         DosCall  DOS_READ_FROM_HANDLE
  1411.         ret
  1412.  
  1413.  
  1414. read_comline_from_file endp
  1415.  
  1416.  
  1417. check_token proc near
  1418. ; input:
  1419. ;   ES=DS=CS= seg of all pointers
  1420. ;   DI = pointing to token
  1421. ;   BX = pointing to string-table, terminated by a ZERO-string
  1422. ; output:
  1423. ;   AX = -1, no match found
  1424. ;      =  0, found a matching string, BX = index*2 of that string
  1425. ;      =  1, same as AX=0, but token was terminated by '='
  1426. ;   DI =  pointing to token behind terminator (0 or '=')
  1427. ;
  1428.         push_   cx,dx
  1429.         cld
  1430.         xor     dx,dx
  1431.         jmp     @@loop_entry
  1432. @@loop:
  1433.         pop     di
  1434.         inc     dx
  1435.         xchg    bx,di
  1436.         xor     ax,ax
  1437.         mov     cx,-1
  1438.         repnz scasb       ; skip to next string in table
  1439.         xchg    bx,di
  1440.         cmp     byte ptr [bx],0
  1441.         jz      @@not_found
  1442. @@loop_entry:
  1443.         push    di
  1444.         mov     cx,size aux_token
  1445.         call    name_compare
  1446.         jz      @@loop
  1447.         pop     ax     ; clean up stack
  1448.         xchg    dx,bx  ; get index
  1449.         shl     bx,1
  1450.         xor     ax,ax
  1451.         cmp     byte ptr [di-1],'='
  1452.         jne     @@ex
  1453.         inc     ax
  1454. @@ex:
  1455.         pop_    cx,dx
  1456.         test    ax,ax
  1457.         ret
  1458. @@not_found:
  1459.         mov     ax,-1
  1460.         jmp     @@ex
  1461. check_token endp
  1462.  
  1463.  
  1464. clear_to_default proc near
  1465.         push_    ax,di,es
  1466.         call     close_debug_file
  1467.         push     cs
  1468.         pop      es
  1469.         xor      ax,ax
  1470.         mov      cx,parse_switches_end-parse_switches
  1471.         lea      di,parse_switches
  1472.         cld
  1473.         rep stosb
  1474.         pop_     ax,di,es
  1475.         ret
  1476. clear_to_default endp
  1477.  
  1478.  
  1479. ;=============================================================================
  1480.  
  1481.  
  1482. INCLUDE LOADLINI.ASM
  1483.  
  1484. ;=============================================================================
  1485.  
  1486. ; -------------------------------------------------------------
  1487. clear_uninitialized_data proc near
  1488.         .8086
  1489.         push_   ax,cx,di
  1490.         xor     ax,ax
  1491.         lea     di,uninitialized_data_start
  1492.         mov     cx,(uninitialized_data_stop-uninitialized_data_start)/2
  1493.         cld
  1494.         rep stosw
  1495.         mov     ax,word ptr pagedir_template
  1496.         mov     word ptr pagedir,ax
  1497.         mov     ax,word ptr pagedir_template+2
  1498.         mov     word ptr pagedir+2,ax
  1499.         pop_    ax,cx,di
  1500.         ret
  1501.         .386
  1502. clear_uninitialized_data endp
  1503.  
  1504.  
  1505.           align dword
  1506.           db           space1k dup(?)
  1507. setup_stack_top label byte
  1508.           db           space1k dup(?)
  1509. stack_top label byte
  1510.  
  1511.  
  1512. uninitialized_data_start label byte
  1513.  
  1514.                 db    ?   ; belongs to comline
  1515. comline         db    128 dup(?) ; copied from PSP_DTA
  1516.                 db    2*1024-128 dup(?) ; extended commandline
  1517. comline_end     label byte
  1518. image_name      db    80 dup(?)
  1519. aux_token       db    80 dup(?)
  1520.  
  1521. command_line    db    space2k dup(?)  ; kernel accepts maximum of 2Kb
  1522.  
  1523.   ; -------------------------------v
  1524.   ; this buffer is for the "default bios interruptvectors"
  1525.   ; as is set from the BIOS,
  1526.   ; Its contents are delivered by the BIOSINTV.SYS device driver
  1527.   ; (must be AT TOP of config.sys).
  1528.   ; Or from the REALBIOS.INT file.
  1529.   ; We need this after returning from V86-mode
  1530.   ; because NOTHING is valid any more but the ROM-BIOS
  1531.   ; (and LOADLIN of cause)
  1532.   ;
  1533. intv_buf        dd     128 dup(?)   ;  intvector  0:0
  1534.                 dd     128 dup(?)
  1535. bios_data       db     256 dup(?)   ;  BIOS-data 40:0
  1536. dummy_dos_data  db     (256-4-16-2) dup(?) ; (DOS-data  50:0, not valid at boot tome
  1537. real_bios_int15 dw     ?            ; result of int15 at time of realbios
  1538. real_bios_magic dw     ?            ; must be 0a5a5h for post alpha-release
  1539. reset_jmpop     db     ?            ;  TOP BIOS FFFF:0
  1540. reset_entry     dd     ?
  1541. biosdate        db     9 dup(?)
  1542. machineid       db     ?
  1543.                 db     ?
  1544. masterIMR       db     ?            ;  port 21
  1545. slaveIMR        db     ?            ;  port A1
  1546. bios_scratch    db     1024 dup(?)  ;  scratch  9FC0:0
  1547. realbios_end    label  byte
  1548.   ; -------------------------------^
  1549.  
  1550.  
  1551.   ; -------------------------------v
  1552.                 align_ code_org0,4096
  1553. IF 0                                ; now moved at start of our code
  1554.                                     ; (overlapping our code)
  1555. pagedir         dd     1024 dup(?)  ; must be aligned to 4 K
  1556. ENDIF
  1557. page0           dd     1024 dup(?)  ; must be aligned to 4 K
  1558.   ; -------------------------------^
  1559.  
  1560.  
  1561. uninitialized_data_stop label byte
  1562. ; -------------------------------------------------------------
  1563.  
  1564.  
  1565. modul_end:
  1566.  
  1567. code    ends
  1568.  
  1569.  
  1570.         end      start
  1571.