📄 second.s
字号:
input: seg es ! interactive mode ? cmp byte ptr (si),#UI_MAGIC je kbinp ! yes -> get keyboard input seg es ! get non-interactive input mov al,(si) inc si jmp gotinp ! go on tolist:#ifdef BITMAP call menu_exit#endif br list ! ...kbinp: mov cx,#brto ! get a key call getkey#ifdef BITMAP cmp byte [abs_cx+1],#0 je noNull ! skip cursor keys after Tab#endif#if defined(MENU) || defined(BITMAP) cmp al,#0xE0 ! extended keyboard je toNull or al,al !#ifdef LCF_M386toNull: je near null ! cursor control#else jne gotinptoNull: br null ! null: in crt.S or bitmap.S#endif#endif#ifndef MENUnoNull: or al,al ! keyboard NUL input? je input ! yes, skip Keyboard NUL; stored command line NUL is handled differently#endifgotinp: cmp al,#9 ! TAB ? je tolist ! yes -> list images cmp al,#63 ! "?" ? je tolist ! yes -> list images or al,al ! NUL ? je nul ! yes -> go on cmp al,#8 ! BS ? je todelch ! yes -> erase one character cmp al,#13 ! CR ? je cr ! yes -> go on cmp al,#127 ! DEL ? je todelch ! yes -> erase one character ja input ! non-printable -> ignore it cmp al,#21 ! ^U ? je todell ! yes -> erase the line cmp al,#24 ! ^X ? je todell ! yes -> erase the line cmp al,#32 ! ignore non-printable characters except space jb input ja noblnk ! no space -> go on cmp (bx-1),al ! second space in a row ? je input ! yes -> ignore itnoblnk: cmp bx,#cmdline+CL_LENGTH ! at end of buffer ? je input ! yes -> ignore xor ah,ah ! cmdline is always NUL terminated mov (bx),ax ! store in the buffer inc bx ! increment pointer push bx call display ! echo#if defined(MENU) || defined(BITMAP) push ax call find_image ! we want the side effect of the hilite pop ax#endif pop bx cmp bx,#cmdline+1 ! first character ? jne input ! no -> next input#ifdef LCF_IGNORECASE call upcase ! convert to upper case#endif mov cx,#IMAGES ! check if we have a single-key entry mov di,#DESCR0 mov ah,alsklp: test word ptr (di+id_flags),#FLAG_SINGLE ! single-key entry ? jz sknext ! no -> try next mov al,(di) ! get first character#ifdef LCF_IGNORECASE call upcase ! convert to upper case#endif cmp al,ah ! do we have a match ? jne sknext ! no -> try next cmp byte ptr (di+1),#0 ! at end ? je cr ! yes -> run itsknext: add di,#id_size ! test next entry loop sklp ! next one br input ! done -> get more inputtodelch:br delch ! ...todell: br delline ! ...! End of input, process the command linenul: push bx ! automatic boot - wait for timeout mov ax,old_del call waitsh pop bx jnc crnul ! no key pressed -> continue mov bx,#msg_int ! interrupted -> display a message call say br iloop ! return to interactive promptcr:#ifdef LCF_HP_TTRC push ax ! HP TTRC boot fail workaround. mov ax, #3 ! 2000/10 <yumoto@jpn.hp.com> call setto ! reload timershort_wait: test byte ptr timeout,#1 ! timed out ? jz short_wait ! No, remain loop.. pop ax#endif mov cmdbeg,#mcmdbeg ! probably manual bootcrnul:#ifndef LCF_NOSERIAL mov byte ptr break,#0 ! clear the break flag#endif push cs ! set ES to CS pop es xor al,al ! mark end mov (bx),al mov si,#cmdline ! copy command line to save buffer mov di,#lkcbuf mov byte ptr dolock,#0 ! disable lockingcpsav: lodsb ! copy one byte stosb or al,al ! at end ? jnz cpsav ! no -> go on cmp bx,#cmdline ! empty line ? je notrspc ! yes -> boot first image cmp byte ptr (bx-1),#32 ! trailing space ? jne notrspc ! no -> go on dec bx ! remove the space mov byte ptr (bx),alnotrspc:mov si,#cmdline ! scan the command line for "vga=", "kbd=", mov di,si ! "lock" or "mem="chkvga:#ifdef LCF_BDATAvsktnbd:#ifndef LCF_M386 cmp word ptr (si),#0x6f6e ! "nobd" jne vsktv cmp word ptr (si+2),#0x6462#else cmp dword ptr (si),#0x64626f6e ! "nobd"#endif jne vsktv cmp byte (si+4),#32 ! terminated with SP or NUL? jnbe vsktv BEG_FS SEG_FS ! enter boot prompt ? or byte ptr par1_prompt+SSDIFF,#FLAG_NOBD ; suppress BIOS data collection END_FS jmp vskwd ; skip word#endifvsktv:#ifndef LCF_M386 cmp word ptr (si),#0x6776 ! "vga=" ? jne vsktk ! no -> try "kbd=" cmp word ptr (si+2),#0x3d61#else cmp dword ptr (si),#0x3d616776 ! "vga="#endif jne vsktk call setvga ! set VGA mode jc toiloop ! error -> get next command jmp vskdb ! proceed by discarding last blankvsktk:#ifndef LCF_M386 cmp word ptr (si),#0x626b ! "kbd=" ? jne vsktl ! no -> try "lock" cmp word ptr (si+2),#0x3d64#else cmp dword ptr (si),#0x3d64626b ! "kbd="#endif jne vsktl call putkbd ! pre-load keyboard buffer jmp vskdb ! proceed by discarding last blankvsktl:#ifndef LCF_M386 cmp word ptr (si),#0x6f6c ! "lock" ? jne vsktm ! no -> skip to next blank cmp word ptr (si+2),#0x6b63#else cmp dword ptr (si),#0x6b636f6c ! "lock"#endif jne vsktm cmp byte (si+4),#32 ! space? jnbe vsktm mov byte ptr dolock,#1 ! enable lockingvskwd: add si,#4 ! skip wordvskdb: dec di ! discard last blank jmp vsknb ! continuevsktm:#ifndef LCF_M386 cmp word ptr (si),#0x656d ! "mem=" ? jne vsknb ! no -> skip to next blank cmp word ptr (si+2),#0x3d6d#else cmp dword ptr (si),#0x3d6d656d ! "mem="#endif jne vsknb call getmem ! get the user-provided memory limitvsknb: lodsb ! copy one byte stosb cmp al,#32 ! space ? je chkvga ! yes -> look for options again or al,al ! at end ? jnz vsknb ! no -> go on call crlf ! write CR/LF cmp di,#cmdline+1 ! empty line ?emptyl: je bfirst ! yes -> boot first image jmp bcmd ! boot the specified imagetoiloop:br iloop ! ...toinput:br input ! ...! Find the boot image and start itbcmd:#if !defined(MENU) && !defined(BITMAP) mov cx,#IMAGES ! test all names mov bx,#DESCR0nextn: mov si,bx ! compare the names mov di,#cmdlinenextc: mov al,(si) ! get next character or al,al ! NUL ? jz dscend ! yes -> possible match ! get the character#ifdef LCF_IGNORECASE call upcase#endif mov ah,al mov al,(di)#ifdef LCF_IGNORECASE call upcase#endif cmp al,ah ! character equal ? jne skipn ! no -> try next one inc si ! test next character inc di jmp nextcdscend: cmp byte ptr (di),#32 ! space or NUL -> boot je boot cmp byte ptr (di),#0 je bootskipn: add bx,#id_size ! test next name loop nextn#else call find_image jc boot ! eureka, it was found#endif mov bx,#msg_nf ! not found -> display a message call say br iloop ! get more input! Delete one characterdelch: cmp bx,#cmdline ! at the beginning ? je toinput ! yes -> do nothing dec bx ! move the pointer push bx ! display[B BS,SPC,BS mov bx,#bs call say#if defined(MENU) || defined(BITMAP) pop bx push bx mov byte (bx),#0 ! NUL terminate the line mov ax,#cmdline sub ax,bx jz delch6 call find_image jmp delch9delch6:#ifdef LCF_VIRTUAL mov ax,[vimage]#endif mov bx,[dimage] cmp ax,bx je delch9 xchg ax,bx call lowlite xchg ax,bx call hilitedelch9:#endif pop bx jmp toinput ! go on! Delete the entire linedelline:#if !defined(MENU) && !defined(BITMAP) cmp bx,#cmdline ! done ? je toinput ! yes -> go on push bx ! display BS,SPC,BS mov bx,#bs call say pop bx dec bx ! move the pointer jmp delline ! next one#else call menu_delline push bx ! delch will do a pop xor ax,ax jmp delch6#endif! Boot first after timeoutbrto: call crlf ! display a CRLF jmp brfrst ! boot! Boot the first imagebfirst: mov byte ptr lkcbuf,#0 ! clear default cmp byte ptr cmdline,#0 ! is there a default ? jne bcmd ! yes -> boot that imagebrfrst: #if defined(MENU) || defined(BITMAP) mov bx,[dimage] imul bx,#id_size add bx,#DESCR0 ! boot the selected image#else mov bx,#DESCR0 ! boot the first image#ifdef LCF_VIRTUAL call vmtest jnc brfrst3 ! not virtual, boot BX mov cx,#IMAGESbrfrst1: test word ptr (bx+id_flags),#FLAG_VMDEFAULT jnz brfrst3 add bx,#id_size loop brfrst1 mov bx,#DESCR0 ! restore defaultbrfrst3:#endif /* LCF_VIRTUAL */#endif /* MENU || BITMAP */ mov si,bx ! copy the name to the command line mov di,#cmdlinebfcpl: lodsb ! copy one character mov (di),al inc di or al,al ! NUL ? jnz bfcpl ! no -> next one! Boot the image BX points to (with password check)boot: mov si,#cmdline ! locate start of optionslocopt: lodsb or al,al ! NUL ? je optfnd ! yes -> no options cmp al,#32 ! space ? jne locopt ! no -> continue searching cmp (si),#0 ! followed by NUL ? jne optfnd ! no -> go on mov byte ptr (si-1),#0 ! discard trailing spaceoptfnd: dec si ! adjust pointer mov options,si ! store pointer for later use#ifdef BITMAP call menu_exit#endif#ifdef LCF_VIRTUAL test word ptr [id_flags](bx),#FLAG_VMWARN jz boot9 call vmtest ; 'vmwarn' there, is it actually virt. boot jnc boot9; VMWARN set, and is virtual boot, so issue comment BEG_FS SEG_FS mov word ptr par1_timeout+SSDIFF,#0xffff ; cancel timeout END_FS push bx ; save image descriptor ptr mov bx,#msg_vmwarn call say mov cx,#vmwto ; timeout exit call getkey push ax cmp al,#0x20 ; compare to Space jb boot3 ; no echo if ctrl char call display ; echoboot3: call crlf pop ax pop bx ; restore image descriptor ptr cmp al,#0x79 ; y is yes je boot9 cmp al,#0x59 ; Y is yes je boot9vmwto: br iloopboot9:#endif test byte ptr (bx+id_flags),#FLAG_PASSWORD ! use a password jz toboot ! no -> boot test byte ptr (bx+id_flags),#FLAG_RESTR ! restricted ? jz dopw ! no -> get the password cmp byte ptr (si),#0! are there any options ? jne dopw ! yes -> password requiredtoboot: br doboot ! ...dopw:#if defined(CRC_PASSWORDS) || defined(SHS_PASSWORDS) push bx ; save the image descriptor BEG_FS SEG_FS mov word ptr par1_timeout+SSDIFF,#0xffff ; cancel timeout END_FS mov bx,#msg_pw ! display a prompt call say push bp ; save BP mov bp,sp ; save SP in BP sub sp,#CL_LENGTH ; allocate space for PW string mov si,sp ; si points at string xor di,di ; di counts characterspwloop:#ifdef DEBUG pusha mov ax,si call wout mov al,#32 call display mov ax,di call wout call crlf popa#endif mov cx,#pwtime ; get timeout exit call getkey cmp al,#13 ! CR ? je pwcr ! yes -> handle it cmp al,#21 ! ^U ? je pwdell ! yes -> erase line cmp al,#24 ! ^X je pwdell cmp al,#8 ! BS ? je pwdelch ! yes -> erase one character cmp al,#127 ! DEL je pwdelch ja pwloop ! ignore other non-printable characters cmp al,#32 jb pwloop cmp di,#CL_LENGTH ; check for buffer overflow jae pwloop ; ingnore further input seg ss mov (si),al ; store char in buffer inc si inc di mov al,#42 ; echo '*' call display jmp pwloop ; loop back for morepwdelch: or di,di jz pwloop call pwbs dec si dec di jmp pwlooppwdell: inc dipwdel: dec di jz pwloop call pwbs dec si jmp pwdelpwbs: mov bx,#bs call say retpwcr: xor cx,cx ; signal okaypwtime: ; CX != 0 if enter here inc cx call crlf sub si,di ; point SI at start of buffer push es ; save ES#if !defined(SHS_PASSWORDS) mov bx,(bp+2) ; restore image descriptor pointer push ss pop es ; ES:SI points at char string#if MAX_PW_CRC>=1#ifdef LCF_M386 push dword #CRC_POLY1#else push #CRC_POLY1>>16 push #CRC_POLY1&0xFFFF#endif call crc32#ifdef DEBUG pusha push ax mov ax,di call wout mov al,#32 call display pop ax#ifdef LCF_M386 push eax#else push dx push ax#endif call dout call crlf popa#endif#ifdef LCF_M386 cmp eax,(bx+id_password_crc)#else cmp ax,(bx+id_password_crc) jne pwcleanup cmp dx,(bx+id_password_crc+2)#endif jne pwcleanup#endif; insert other checks in here#if MAX_PW_CRC>=2#ifdef LCF_M386 push dword #CRC_POLY2#else push #CRC_POLY2>>16 push #CRC_POLY2&0xFFFF#endif call crc32#ifdef LCF_M386 cmp eax,(bx+id_password_crc+4)#else cmp ax,(bx+id_password_crc+4) jne pwcleanup cmp dx,(bx+id_password_crc+4+2)#endif jne pwcleanup#endif#if MAX_PW_CRC>=3#ifdef LCF_M386 push dword #CRC_POLY3#else push #CRC_POLY3>>16 push #CRC_POLY3&0xFFFF#endif call crc32#ifdef LCF_M386 cmp eax,(bx+id_password_crc+8)#else cmp ax,(bx+id_password_crc+8) jne pwcleanup cmp dx,(bx+id_password_crc+8+2)#endif jne pwcleanup#endif#if MAX_PW_CRC>=4#ifdef LCF_M386 push dword #CRC_POLY4#else push #CRC_POLY4>>16 push #CRC_POLY4&0xFFFF#endif call crc32#ifdef LCF_M386 cmp eax,(bx+id_password_crc+12)#else cmp ax,(bx+id_password_crc+12) jne pwcleanup cmp dx,(bx+id_password_crc+12+2)#endif jne pwcleanup#endif#if MAX_PW_CRC>=5#ifdef LCF_M386 push dword #CRC_POLY5#else push #CRC_POLY5>>16 push #CRC_POLY5&0xFFFF#endif call crc32#ifdef LCF_M386 cmp eax,(bx+id_password_crc+16)#else cmp ax,(bx+id_password_crc+16) jne pwcleanup cmp dx,(bx+id_password_crc+16+2)#endif jne pwcleanup#endif;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dec cx ; signal all okay#else /* SHS_PASSWORDS */; DI is the count; SS:SI is the password string push di push si call _shsInit call _shsUpdate call _shsFinal mov bx,(bp+2) ; restore image descriptor pointer lea di,(bx+id_password_crc) mov si,#shs_digest mov cx,#MAX_PW_CRC*4; ES==DS repe cmpsb pop si ; restore buffer ptr pop di ; clear stack push ss pop es ; ES=SS je pwcleanup ; CX will be 0 inc cx ; CX is > 0#endif /* !defined(SHS_PASSWORDS) */pwcleanup: push cx mov cx,#CL_LENGTH mov di,si xor ax,ax rep ; wipe out password in memory stosb pop cx pop es ; restore the saved ES mov sp,bp pop bp pop bx or cx,cx ; test CX==0 means all okay jz doboot; fall into pwfail #else push bx ! save the image descriptor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -