home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2000 May
/
Chip_2000-05_cd2.bin
/
dosutils
/
loadlin
/
src
/
loadlini.asm
< prev
next >
Wrap
Assembly Source File
|
1996-04-28
|
28KB
|
1,077 lines
; >>> this is file LOADLINI.ASM
;============================================================================
; LOADLIN v1.6 (C) 1994..1996 Hans Lermen (lermen@elserv.ffm.fgan.de)
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;
;----------------------------------------------------------------------------
; Comments and bug reports are welcome and may be sent to:
; E-Mail: lermen@elserv.ffm.fgan.de
; SnailMail: Hans Lermen
; Am Muehlenweg 38
; D53424 REMAGEN-Unkelbach
; GERMANY
;
;============================================================================
relocate_setup_code proc near
; NOTE: This routine has to be updated whenever a new access to
; High_seg or High_addr is inserted in the code !
; It relocates those addresses, if the setup code is
; not loaded at 9000h
;
push_ eax,bx
mov have_relocated_setup,1
; these can simply overwriten
mov ax,High_seg
mov reloc_hseg_1,ax
mov reloc_hseg_2,ax
@@relocd macro desc
lea bx,desc
call relocate_descriptor
endm
; these descriptors have to get added the displacement
@@relocd gdt_code
@@relocd gdt_data
@@relocd gdt_ldt
@@relocd gdt_tss
; these DWORDS have to get added the displacement
sub ax,High_seg_
movsx eax,ax
shl eax,4
add our_CR3,eax
add our_GDTRptr,eax
add our_IDTRptr,eax
add laddr_GDT,eax
add laddr_IDT,eax
add pagedir_template,eax
call preset_pagedir_from_template
pop_ eax,bx
ret
relocate_setup_code endp
relocate_descriptor proc near
; input:
; AX = new 'High_seg' frame
; BX = offset of descriptor
; bases address of descriptor must be relative to 'High_seg_'
; outpout:
; all registers preserved, descriptor bases updated
push_ ecx,eax
mov ch,[bx].base24
mov cl,[bx].base16
shl ecx,16
mov cx,[bx].base0
sub ax,High_seg_
movsx eax,ax
shl eax,4
add eax,ecx
mov [bx].base0,ax
shr eax,16
mov [bx].base16,al
mov [bx].base24,ah
pop_ ecx,eax
ret
relocate_descriptor endp
read_comline_from_file proc near
;; mov ax,DOS_OPEN_FILE shl 8
;; lea dx,image_name+1
;; DosInt
push fs
call @@open
jnc @@isopen
@@err:
lea dx,err_comfile_tx
call print
mov word ptr comline-1,0
jmp @@ex
@@ioerr:
;; DosCall DOS_CLOSE_FILE
call @@close
jmp @@err
@@isopen:
mov bx,ax
cld
lea di,comline+1
@@loop:
mov dx,di
mov cx,1
;; DosCall DOS_READ_FROM_HANDLE
call @@read
jc @@ioerr
cmp ax,1
jne @@eof
mov al,byte ptr [di]
cmp al,13
je @@loop
cmp al,'#'
je @@skipeol
@@skipcontinue:
inc di
cmp di, offset comline_end-1
jnb @@eof
cmp al,' '
ja @@loop
cmp di,offset comline+2
jna @@1
cmp byte ptr [di-2],' ' ; ignore multiple spaces
jne @@1
dec di
jmp @@loop
@@1:
mov byte ptr [di-1],' '
jmp @@loop
@@eof:
mov byte ptr [di],0
mov ax,di
sub ax,offset comline+1
xchg al,ah
mov word ptr comline-1,ax
;; DosCall DOS_CLOSE_FILE
call @@close
jmp @@ex
@@skipeol:
mov dx,di
mov cx,1
;; DosCall DOS_READ_FROM_HANDLE
call @@read
jc @@ioerr
cmp ax,1
jne @@eof
cmp byte ptr [di],10
jne @@skipeol
jmp @@skipcontinue
@@ex:
pop fs
ret
; -----------
@@virtual db 0
@@open: ; virtual open routine
cmp dword ptr image_name,'ol@@'
jne @@open_d
cmp dword ptr image_name+4,'ilda'
je @@open_v
@@open_d:
mov @@virtual,0
lea dx,image_name+1
mov ax,DOS_OPEN_FILE shl 8
DosInt
ret
@@open_v:
mov @@virtual,1
mov ax,High_Seg
cmp dword ptr image_name+4+4,'@@xn'
jne @@open_vhex
mov fs,ax
lea ax,params_from_loadlinX
clc
ret
@@open_vhex:
push si
lea si,image_name+4+2
mov word ptr [si],'x0'
call value_of
mov fs,ax
xor ax,ax ; carry is also 0
pop si
ret
@@close:
cmp @@virtual,0
jz @@close_d
ret
@@close_d:
DosCall DOS_CLOSE_FILE
ret
@@read:
cmp @@virtual,0
jz @@read_d
mov al, byte ptr fs:[bx]
or al,al
jz @@read_eof
inc bx
mov byte ptr [di],al
mov ax,1
clc
ret
@@read_eof:
xor ax,ax
clc
ret
@@read_d:
DosCall DOS_READ_FROM_HANDLE
ret
read_comline_from_file endp
build_arglist proc near
; input:
; ES=DS=CS= seg of all pointers
; SI = pointing to commandline like string
; DI = target buffer
; output:
; DI = pointing to next free byte in target buffer
; all other registers preserved
@@stack struc
pushA_struc @@
@@stack ends
pusha
mov bp,sp
xor cx,cx
@@1:
inc cx
call get_token
jnz @@1
mov di,[bp].@@di
mov bx,di
inc cx
shl cx,1
add di,cx
mov si,[bp].@@si
@@2:
mov word ptr [bx],di
inc bx
inc bx
call get_token
mov di,ax
jnz @@2
mov word ptr [bx-2],0
mov [bp].@@di,ax
popa
ret
build_arglist endp
handle_response_file proc near
IF 0
call read_comline_from_file
ELSE
pushad
cld
lea di,aligned_auxbuff
mov @@list,di
call build_arglist ; we save the rest of the old commandline
mov @@ptr,di
call read_comline_from_file
cmp word ptr aligned_auxbuff,0 ; nothing left in the old ?
jz @@ex
lea si,comline+1
mov @@cptr,si
cld
mov di,@@ptr
call build_arglist ;we scan the read-in commandline
; now we check if there are overwrites
mov si,word ptr aligned_auxbuff
mov @@list,si
mov dx,@@ptr
mov si,dx
mov si,word ptr [si]
or si,si
jz @@ex_0
; check if we have to replace the image
lea di,@@image
mov bx,@@list ; string list of old args
call check_token
js @@2
mov bx,word ptr aligned_auxbuff[bx]
mov byte ptr [bx],1 ; mark as 'used'
cmp byte ptr [bx+5],0
je @@2
cmp byte ptr [bx+6],0
je @@2
lea si,[bx+6] ; take what is behind 'image='
jmp @@2
@@1:
mov si,dx
mov si,word ptr [si]
or si,si
jz @@ex_0
; we check for the special case 'ro','rw'
cmp byte ptr [si+2],0
jne @@1_3
cmp word ptr [si],'or'
jne @@1_1
lea di,@@rw ; search the opposite (rw replaces ro)
jmp @@1_2
@@1_1:
cmp word ptr [si],'wr'
jne @@1_3
lea di,@@ro ; search the opposite (ro replaces rw)
@@1_2:
mov bx,@@list ; string list of old args
call check_token
jmp @@1_4
@@1_3:
mov di,si
mov bx,@@list ; string list of old args
call check_token
@@1_4:
js @@2
; we have to take the old one
mov si,word ptr aligned_auxbuff[bx]
@@2:
push si
mov di,@@cptr
call stringcpy
pop si
mov @@cptr,di
mov byte ptr [di-1],' '
add dx,2
cmp si,@@list ; avoid overwriting our constants
jb @@1
mov byte ptr [si],1
jmp @@1
@@ex_0:
; we have to take the rest of the old commandline
lea bx,aligned_auxbuff ; string list of old args
@@ex_1:
mov si,word ptr [bx]
add bx,2
or si,si
jz @@ex_2
cmp byte ptr [si],1
je @@ex_1 ; skip, what we already replaced
mov di,@@cptr
call stringcpy
mov @@cptr,di
mov byte ptr [di-1],' '
jmp @@ex_1
@@ex_2:
mov bx,@@cptr
mov byte ptr [bx-1],0
sub bx, offset comline+1
jz @@ex_5
dec bx
@@ex_5:
xchg bh,bl
mov word ptr comline-1,bx
@@ex:
popad
ret
@@ptr dw 0
@@list dw 0
@@cptr dw 0
@@image db 'image=',0
@@rw db 'rw',0
@@ro db 'ro',0
ENDIF
handle_response_file endp
check_token proc near
; input:
; ES=DS=CS= seg of all pointers
; DI = pointing to token
; BX = pointing to string-table, terminated by a ZERO-string
; output:
; AX = -1, no match found
; = 0, found a matching string, BX = index*2 of that string
; = 1, same as AX=0, but token was terminated by '='
; DI = pointing to token behind terminator (0 or '=')
;
push_ cx,dx
cld
xor dx,dx
jmp @@loop_entry
@@loop:
pop di
inc dx
xchg bx,di
xor ax,ax
mov cx,-1
repnz scasb ; skip to next string in table
xchg bx,di
cmp byte ptr [bx],0
jz @@not_found
@@loop_entry:
push di
mov cx,size aux_token
call name_compare
jz @@loop
pop ax ; clean up stack
xchg dx,bx ; get index
shl bx,1
xor ax,ax
cmp byte ptr [di-1],'='
jne @@ex
inc ax
@@ex:
pop_ cx,dx
test ax,ax
ret
@@not_found:
mov ax,-1
jmp @@ex
check_token endp
get_setup_version proc near
mov cs:setup_version,0
cmp dword ptr ds:setup_header_sign,SIGNATURE
jne @@ex
push word ptr cs:setup_header_version
pop cs:setup_version
@@ex:
ret
get_setup_version endp
parscommandline proc near
mov image_name,0
parscommandline_:
call clear_to_default
mov cx,word ptr comline-1
xchg ch,cl
jcxz @@ex_carry
mov si,cx
mov comline[si+1],0
mov command_line,0
mov cl_pointer,offset command_line
lea si,comline+1
cld
cmp image_name,0
jnz @@1
lea di,image_name
call get_token ; get the zImage-file name
jz @@ex_carry
cmp image_name,'-'
jne @@0
mov dword ptr image_name,'amiz'
mov word ptr image_name+4,'eg'
mov image_name+6,0
jmp parscommandline_
@@0:
; got zImage-name
; try to get params
cmp image_name,'@'
jne @@1
call handle_response_file
jmp parscommandline
@@1:
lea di,image_name
call tolower
jmp @@next_token
@@token_table label byte
db 'ramdisk',0
db 'vga',0
db 'mem',0
db 'root',0
db 'ro',0
db 'rw',0
db 'no387',0
db 'single',0
db 'auto',0
db '-v',0
db '-t',0
db '-d',0
db '-rb',0
db '-rx',0
db '-ja',0
db '-clone',0
; db '-oldxd',0
db 'debug',0
db 'no-hlt',0
db 'reserve',0
db 'hd',0
db 'bmouse',0
db 'max_scsi_luns',0
db 'xd',0
db '-n',0
db '-txmode',0
db '-f',0
db 'initrd',0
db '-noheap',0
db '-wait',0
db '-dskreset',0
db 0
@@jmp_table dw @@ramdisk
dw @@vga
dw @@mem ;@@tolower ; mem
dw @@tolower ; root
dw @@tolower ; ro
dw @@tolower ; rw
dw @@tolower ; no387
dw @@tolower ; single
dw @@tolower ; auto
dw @@option_v
dw @@option_t
dw @@option_d
dw @@option_realbios
dw @@option_rx
dw @@option_ja
dw @@option_clone
; dw @@option_oldxd
dw @@tolower ; debug
dw @@tolower ; no-hlt
dw @@tolower ; reserve=
dw @@tolower ; hd=
dw @@tolower ; bmouse=
dw @@tolower ; max_scsi_luns=
dw @@tolower ; xd=
dw @@option_n
dw @@option_txmode
dw @@option_force
dw @@option_initrd
dw @@option_noheap
dw @@option_wait
dw @@option_dskreset
@@next_token:
lea di,aux_token
call get_token
jz @@ex0
lea di,aux_token
lea bx,@@token_table
call check_token
js @@not_my_token
jmp @@jmp_table[bx]
@@mem:
jz @@not_my_token
push di
lea di,aux_token
call tolower
pop di
cmp byte ptr [di],'n' ; = 'nopentium'
je @@not_my_token
xchg si,di
call value_of
call adjust_k_or_m
xchg si,di
mov end_of_physmem,eax
jmp @@not_my_token
@@option_wait:
jz @@not_my_token
push di
lea di,aux_token
call tolower
pop di
xchg si,di
call value_of
xchg si,di
mov option_wait,ax
jmp @@next_token
@@option_initrd:
jz @@not_my_token
push_ si,di
xchg si,di
lea di,rdimage_name
call stringcpy
pop_ si,di
mov option_initrd,1
jmp @@next_token
@@ramdisk: ; have ramdisk param
mov got_ram_disk,1
mov new_ram_disk,1440
jz @@next_token
xchg si,di
call value_of
cmp word ptr [si],'on' ; disable diskchange prompt ?
jne @@ramdisk_1
mov option_nodiskprompt,1
@@ramdisk_1:
xchg si,di
mov new_ram_disk,ax
jmp @@next_token
@@token_table_vga label byte
db 'normal',0
db 'extended',0
db 'ask',0
db 0
@@vga: ; have vga - param
mov got_vga_mode,1
mov new_vga_mode,-1 ; default = NORMAL
jz @@next_token
mov bx,di
cmp byte ptr [bx],'-'
jne @@vga_1
inc bx
@@vga_1:
cmp byte ptr [bx],'0'
jb @@check_vga_sym
cmp byte ptr [bx],'9'
jna @@check_vga_num
@@check_vga_sym:
; DI already pointing to value
lea bx,@@token_table_vga
call check_token
js @@next_token
shr bx,1
not bx
mov new_vga_mode,bx
jmp @@next_token
@@check_vga_num:
xchg si,di
call value_of
xchg si,di
mov new_vga_mode,ax
jmp @@next_token
@@option_t:
mov option_t,1 ; forces also option -v
@@option_v:
mov option_v,1
jmp @@next_token
@@option_noheap:
mov option_noheap,1
jmp @@next_token
@@option_d:
lea di,aux_token ; get output file name
call get_token
jz @@option_t ; no file name
push_ bx,cx,dx
xor cx,cx
lea dx,aux_token
DosCall DOS_CREATE_FILE
pop_ bx,cx,dx
jc @@option_t
mov debug_file_handle,ax
jmp @@option_t
@@option_realbios:
mov option_realbios,1
jmp @@next_token
@@option_rx:
mov option_rx,1
jmp @@next_token
@@option_ja:
mov option_ja,1
jmp @@next_token
@@option_clone:
mov option_clone,1
dec token_count
jmp @@next_token
@@option_n:
mov option_n,1
jmp @@next_token
@@option_force:
mov option_force,1
jmp @@next_token
@@option_dskreset:
mov option_dskreset,1
jmp @@next_token
@@option_txmode:
pusha
push_ ds,es
xor ax,ax
mov es,ax
mov ax,3003h ; al = color mode
and ah,byte ptr es:[0410h] ; get EQUIPPEMENT-flags
cmp ah,30h
jne @@option_txmode6
mov al,7 ; al = mono mode
@@option_txmode6:
xor ah,ah
INT 10h
pop_ ds,es
popa
jmp @@next_token
@@not_my_token:
push si
lea si,aux_token
call @@append_to_commandline
pop si
jmp @@next_token
@@tolower:
lea di,aux_token
call tolower
jmp @@not_my_token
@@ex0:
lea si,@@boot_tx
call @@append_to_commandline
dec cl_pointer
lea si,image_name
cld
mov di,si
@@ex1:
lodsb
test al,al
jz @@ex3
cmp al,':'
je @@ex2
cmp al,'\'
je @@ex2
cmp al,'/'
jne @@ex1
@@ex2:
mov di,si
jmp @@ex1
@@ex3:
mov si,di
call @@append_to_commandline
@@ex:
clc
ret
@@ex_carry:
stc
ret
@@append_to_commandline:
mov di,cl_pointer
@@append_to_1:
lodsb
stosb
test al,al
jnz @@append_to_1
mov byte ptr [di-1],' '
mov byte ptr [di],al
mov cl_pointer,di
ret
@@boot_tx db 'BOOT_IMAGE=',0
parscommandline endp
handle_kernel_specifics proc near
IF 0
cmp kernelversion,0
jz @@ex
; put here kernel dependent stuff
@@ex:
ENDIF
ret
handle_kernel_specifics endp
get_token proc near
; returns:
; ZFLAG = 1 on EOF
; AX = increased DI
push di
@@skip_loop:
lodsb
cmp al,' '
je @@skip_loop
jmp @@ok
@@loop:
lodsb
cmp al,' '
jne @@ok
xor al,al
@@ok:
stosb
test al,al
jne @@loop
dec si
mov ax,di
pop di
cmp byte ptr es:[di],0
jz @@ex
inc token_count
@@ex:
test byte ptr es:[di],255
ret
get_token endp
readstring proc near
push dx
mov comline-1,255-2
lea dx,comline-1
DosCall DOS_BUFFERED_INPUT
lea dx,newline_tx
call print
push bx
movzx bx,comline
mov comline[bx+1],0
mov comline-1,0
pop bx
pop dx
ret
readstring endp
stringcpy proc near
; input:
; DS:SI= source address
; DS:DI= target address
push_ ds,ds
pop es
cld
@@loop:
lodsb
stosb
or al,al
jnz @@loop
@@ex:
pop ds
ret
stringcpy endp
tolower proc near
; input:
; DS:DI= address to ASCIIZ-string
cld
xchg si,di
@@loop:
lodsb
or al,al
jz @@ex
cmp al,'A' ; tolower !
jb @@loop
cmp al,'Z'
ja @@loop
add byte ptr [si-1],'a'-'A'
jmp @@loop
@@ex:
xchg si,di
ret
tolower endp
name_compare proc near
; input:
; DS:DI= address to ASCIIZ-string (name1)
; (a "=" marks end of string also)
; CS:BX= address to ASCIIZ-string (name2)
; (a "=" marks end of string also)
; CX= max number of character to compare
; compare is done by ignoring upper/lower-case
; Output:
; AX= 0 if not equal else equal
; DI= as changed by lodsb, pointing behind terminator (0 or '=')
; all other register preserved
cld
push bx
xchg si,di
sub bx,si
@@m3:
lodsb
cmp al,'=' ; may be name in environement
jne short @@32
xor al,al
jmp short @@m35
@@32:
cmp al,'A' ; tolower !
jb short @@m35
cmp al,'Z'
ja short @@m35
add al,'a'-'A'
@@m35:
mov ah,al
mov al,byte ptr cs:[si+bx-1]
cmp al,'=' ; may be name in environement
jne short @@34
xor al,al
jmp short @@m36
@@34:
cmp al,'A' ; tolower !
jb short @@m36
cmp al,'Z'
ja short @@m36
add al,'a'-'A'
@@m36:
or al,al
jz short @@ex_
or ah,ah
jz short @@exfalse
cmp ah,al
jne @@exfalse
loop @@m3
@@extrue:
mov ax,1
@@ex:
xchg si,di
pop bx
or ax,ax
ret
@@ex_:
or ax,ax
jz @@extrue
@@exfalse:
xor ax,ax ; not equal
jmp @@ex
name_compare endp
get_env_variable proc near
; Input
; CS:BX= Pointer to string (ASCIIZ) of desired env-variable
; Output:
; ES:DI= pointer to string (ASCIIZ) of variable contents (without "=")
; or ZERO-string if not found
; All other registers preserved
push ds
push ax
push si
mov ds,PSP_frame
mov ds,ds:PSP_envir_frame
xor si,si
mov al,byte ptr [si]
@@m1:
mov cx,80
or al,al
mov di,si
jz @@ex
call name_compare
jnz @@found ; string is equal, found the variable
cld
@@m2: ; skip to next string
lodsb
or al,al
jnz @@m2
mov al,byte ptr [si]
jmp @@m1
@@found:
@@ex:
push ds
pop es
pop si
pop ax
pop ds
ret
get_env_variable endp
adjust_k_or_m proc near
; Input:
; DS:SI, EAX as delivered by 'value_of'
pushf
push cx
xor cx,cx
mov ch, byte ptr [si-1]
cmp ch,'k'
jne @@1
mov cl,10
@@ex:
shl eax,cl
@@ex0:
pop cx
popf
ret
@@1:
cmp ch,'m'
jne @@ex0
mov cl,20
jmp @@ex
adjust_k_or_m endp
value_of proc near
; Input:
; DS:SI= pointer to string (ASCIIZ), which contains number to be converted
; (i.e.: 1234, 0xa00, ... ), all non-digit-characters (0..9,a..f,A..F)
; are "delimiters" and mark the end of the string
; Output:
; EAX= converted number
; SI= pointing at the first byte behind the delimiter
cmp byte ptr [si],'-'
pushf
jnz @@m0
inc si
@@m0:
push_ ebx,ecx,edx,edi,esi
mov ebx,10
xor edx,edx
xor edi,edi
inc edi
cld
lodsb
call @@check_white
jc @@ex
jne @@m1
lodsb
or al,20h ; convert to lowercase
cmp al,'x'
jne @@m1
mov ebx,16
lodsb
@@m1:
call @@check_white
jb @@ex
xor ecx,ecx
@@m2:
inc ecx
lodsb
call @@check_white
jnc @@m2
std
mov [esp],esi ;advance pointer
dec si
dec si
@@m3:
lodsb
or al,20h ; convert to lowercase
cmp al,'9'
jna short @@m4
add al,9
@@m4:
and al,0fh
movzx eax,al
imul eax,edi
imul edi,ebx
add edx,eax
loop @@m3
@@ex:
mov eax,edx
pop_ ebx,ecx,edx,edi,esi
popf
jnz @@ex_
neg eax
@@ex_:
ret
@@check_white:
mov ah,'f'
cmp bl,16
je short @@7
mov ah,'9'
@@7:
or al,20h
cmp al,'0'
jb short @@9
cmp al,ah
ja short @@9
cmp al,'9'
jbe short @@8
cmp al,'a'
jae short @@8
@@9:
mov al,' '
@@8:
cmp al,'0'
ret
value_of endp