home *** CD-ROM | disk | FTP | other *** search
- ; >>> 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
-
-