📄 second.s
字号:
jz ln_do_read ; ****** call translate ; in volume.Sln_do_read: call lba_read mov al,cl ;count returned in AL, error code in AH ret ;Carry Set means error on read#ifdef LCF_VIRTUAL; vmtest -- return Carry=1 if in virtual (VMware) mode; return Carry=0 if in real mode;vmtest:#ifndef LCF_SUSPEND pushad ; save all extended registers smsw ax rcr al,1 ; PE bit in AL to Carry jc vm_ret ; exit if virtual mode#if DEBUG_NEW mov ah,#2 ! get keyboard flags int 0x16 and al,#0x50 ! Caps, Scroll Lock flags cmp al,#0x40 je vm_vir ! Caps only means virtual boot simulated#endif;; VMware(R) test for virtual mode; mov eax,#0x564D5868 ! EAX: in = 'VMXh' out = version xor ebx,ebx ! EBX: out = 'VMXh' under vmware mov edi,eax mov dx,#0x5658 ! DX: in = 'VX' mov ecx,#10 ! ECX: in = VMXGetVersion in eax,dx cmp ebx,edi ! test for vmware clc ; NOT vmware if Carry==0 jne vm_ret ! not vmware inc eax ; carry is not affected by INC jz vm_ret ; invalid version number == 0xFFFFFFFFvm_vir: stc ; signal virtual modevm_ret: popad ; restore all the extended registers ret#else /* LCF_SUSPEND changes the interpretation of "virtual" */ pusha push es test byte ptr [vm_cache],#0xFF ; test cached value jnz vm_ret mov byte ptr [vm_cache],#2 ; not virtual push ds pop es ; ES:BX mov bx,#MAP ; use this buffer mov cx,#1 ; sector 1 mov dx,#0x80 ; dos C: drive mov al,cl ; 1 sector call cread ; jc vm_ret ; not virtual if error mov cx,#PARTITION_ENTRIES ; count 4 PT entries lea bx,[PART_TABLE_OFFSET](bx) ; first partition entryvm_pt1: test byte ptr (bx),#0x80 ; active jz vm_pt2 cmp byte ptr (bx+4),#LCF_SUSPEND ; suspend partition jne vm_pt2 mov byte ptr [vm_cache],#1 ; suspend is activevm_pt2: lea bx,[PARTITION_ENTRY](bx) ; bump pointer loop vm_pt1vm_ret: mov al,[vm_cache] ; get cached value shr al,#1 pop es popa retvm_cache: .byte 0 ; 0=unknown, 1=virtual, 2=non-virtual#endif /* LCF_SUSPEND */#endif /* LCF_VIRTUAL */#if 1; crc32 -- calculate CRC-32 checksum;; call:; push dword #POLYNOMIAL;; ES:SI char string pointer; DI count of characters;; call crc32;; CRC-32 is returned in EAX or DX:AX; the arguments are popped from the stack;crc32: push bp mov bp,sp push si push di push bx push cx xor eax,eax ; initialize CRC dec eax ; EAX = 0xFFFFFFFF inc dicrc32a: dec di jz crc32d mov cx,#8 ; count 8 bits seg es mov bl,(si) ; get next character inc sicrc32b: shl bx,#1 ; get hi bit of char in BH shl eax,#1 ; shift hi bit out of CRC adc bh,#0 ; add carry to BH shr bh,#1 ; put bit in carry jnc crc32c ; skip the xor xor eax,(bp+4) ; xor in the polynomialcrc32c: loop crc32b ; loop back for 8 bits jmp crc32acrc32d: not eax ; finialize CRC pop cx pop bx pop di pop si leave ret 4#endif/* ifdef HIGHMEM_MAX */; enter with BX == Ramdisk size (in 4k pages);rd_setup: push bx ; save Ramdisk size in pages mov eax,[hma] ; user specified? or eax,eax#ifdef LCF_INITRDLOW jnz rd_have_hma#else /* ifndef LCF_INITRDLOW */ jnz near rd_have_hma BEG_FS SEG_FS test byte ptr par1_prompt+SSDIFF,#FLAG_LARGEMEM END_FS jz near no_e801; try the E820 memory map first xor edx,edx ; flag nothing found xor esi,esi ; flag size==0 xor ebx,ebx jmp e8goe8go2: or ebx,ebx ; test for end jz e8go5e8go: push edx ; save best prospect mov eax,#0xe820 mov edx,#0x534d4150 ;'SMAP' mov ecx,#20 mov di,#memmap int 0x15 ; get memory map pop edx ; restore what we have found so far jc no_e820 cmp eax,#0x534d4150 ;'SMAP' jne no_e820 cmp ecx,#20 jne no_e820#if 0 mov eax,memmap ; get start mov ecx,memmap+4 ; get high part cmp word memmap+16,#1 ; available? jne e8no1 ; go on to next or ecx,ecx jnz e8go2 cmp eax,#0x100000 ; compare to 1Mb ja e8go2 add eax,memmap+8 ; get final address adc ecx,memmap+12 ; shrd eax,ecx,#10 ; convert to 1k blocks (legacy) cmp eax,#4*1024 ; compare to 4Mb jb no_e820 xchg eax,edx ; save in edx jmp e8go2e8no1: shrd eax,ecx,#10 ; convert to 1k blocks cmp eax,#1024 ; compare to 1Mb jb e8go2 ; loop if too small cmp eax,edx ; check against HMA jae e8go2 xchg eax,edx ; compensate for buggy BIOS jmp e8go2 ; remember in EDX & loop#else cmp word memmap+16,#1 ; available? jne e8go2 mov eax,memmap+4 ; hi part of start shrd memmap,eax,#10 ; convert start to 1k mov eax,memmap+12 ; hi part of size shrd memmap+8,eax,#10 ; convert to 1k cmp dword memmap,#1024 ; below 1M jb e8go2 ; below 1M, no interest cmp esi,memmap+8 ; check size ja e8go2 ; want largest mov edx,memmap ; start (in 1k) mov esi,memmap+8 ; size (in 1k) add edx,esi ; HMA in 1k jmp e8go2#endife8go5: or edx,edx ; find anything? jz no_e820 xchg eax,edx jmp rd_have_hmano_e820:; above failed, try the older E801 block count interface xor cx,cx ; some BIOSs are buggy xor dx,dx mov ax,#0xe801 ; call stc int 0x15 jc no_e801 or cx,cx jz e801cx mov ax,cxe801cx: or dx,dx jz e801dx mov bx,dxe801dx: movzx ebx,bx movzx eax,ax shl ebx,#6 ; convert 64k to 1k mov ecx,#16*1024 cmp eax,ebx ; compare sizes ja e801eax add ebx,ecx ; add in 16M mov eax,ebx ; and use this value jmp rd_have_hmae801eax: add eax,#1024 ; add 1M cmp eax,ecx ; is it 16M jne rd_have_hma add eax,ebx ; add in ebx jmp rd_have_hma#endif /* ifndef LCF_INITRDLOW */no_e801:; above two methods failed, try the old 0x88 function mov ah,#0x88 ; get count of extended memory blocks int 0x15 movzx eax,ax ; extend to dword add eax,#1024 ; add in base 1M;rd_have_hma: ; have the HMA / 1k in EAX#if DEBUG_NEW push eax shl eax,10 ; convert to address push eax call crlf call dout ; pops its argument mov bx,#msg_hma call say pop eax#endif mov ebx,#15*1024 ; 15Mb cmp eax,ebx ; compare to 15M jbe rd_use_eax ; use lower value BEG_FS SEG_FS test byte ptr par1_prompt+SSDIFF,#FLAG_LARGEMEM END_FS jnz large_okay xchg eax,ebx ; limit to 15Mblarge_okay: mov ebx,#HIGHMEM_MAX/1024#ifdef NEW3_HDR_VERSION push ds mov ds,[initseg] ! load the original boot sector cmp word ptr [CL_HDRS_VERSION],#NEW3_HDR_VERSION jb not203 mov ebx,[CL_RAMDISK_MAX]#if DEBUG_NEW pop cx push cx mov ds,cx pushad push ebx mov bx,#hdr3 call say call dout call crlf popad#endif dec ebx shr ebx,#10 ! divide by 1024 inc ebxnot203: pop ds#endif /* ifdef NEW3_HDR_VERSION */ cmp eax,ebx jb rd_use_eax;;;rd_use_smaller: xchg eax,ebx ; must use the smallerrd_use_eax: pop bx ; get size in pages shr eax,2 ; convert to pages movzx ebx,bx ; zero high part of size sub eax,ebx ; start address of ramdisk to EAX#if DEBUG_INITRD cmp dword ptr [hma],#0x180000/1024 ; 1.5Mb jb drd_use_eax cmp dword ptr [hma],#0xF00000/1024 ; 15Mb jae drd_use_eax mov eax,[hma] ; HMA is initrd start shr eax,2drd_use_eax:#endif#if 0 cmp eax,#256 ! we probably need more than 1M for the ja rd_okay ! kernel to be useful ... mov bx,#msg_rd ! complain;;; call say ! is at zz br zz ! and halt #else cmp eax,#4*256 ! Ramdisk loaded below 4Mb jae rd_okay ! kernel to be useful ... mov bx,#msg_rd4M ! complain call say ! is at zz#endifrd_okay: shl eax,4 ! shift (12-8) -> 4 mov [rdbeg+1],ax ! set up beginning address mov [gdt+0x1b],ax ! set the GDT for the moves shr eax,16 ! get hi-byte of address mov [rdbeg+3],al ! set rest of address mov [gdt+0x1f],al ! and in the GDT, too ret/* endif / ifdef HIGHMEM_MAX *//* enter with SI pointing to DESCRIPTOR DS = CS ES unknown SI - points at the descriptor*/load_initrd: push [map] push [moff] mov word ptr [map],#MAP2 push ds pop es mov ax,(si+id_flags) ! get FLAG_TOOBIG, if any#if FLAG_LARGEMEM!=FLAG_TOOBIG# error "FLAG_LARGEMEM and FLAG_TOOBIG must be equal"#endif and al,#FLAG_TOOBIG ! separate flag BEG_FS SEG_FS or byte ptr par1_prompt+SSDIFF, al ! set FLAG_LARGEMEM END_FS add si,#id_rd_size ! point at ramdisk size long! take care of the RAM disk first xor eax,eax mov (rdbeg),eax ! clear address lodsd mov (rdszl),eax ! set rdszl+rdszh add eax,#4095 ! round up & shr eax,#12 ! convert to pages xchg bx,ax ! copy to BX lodsw ! address of the first map sector xchg cx,ax lodsw xchg dx,ax lodsb or bx,bx ! no RAM disk ? jz noramd ! yes -> skip it 2 push si ! save SI, ES, and BX (RD size) push es push bx mov bx,[map] ! load the first map sector call sread mov moff,#0#ifdef DEBUG mov bx,#stepa call say#endif/* ifdef HIGHMEM_MAX */ pop bx call rd_setup/* endif */ cmp dword ptr (rdbeg),#0 je nordpt ! no -> no need to patch header for that; setrdp:#if DEBUG_NEW push dword (rdbeg) ! print RAM disk address mov bx,#msg_rd2 call say call dout call crlf#endif mov es,[setupseg] ! load the setup codes mov eax,(rdbeg) ! get RAM disk start address seg es mov (24),eax ! store in header mov eax,rdszl seg es mov (28),eax ! set RAM disk sizenordpt: push #0 ! ES=0 is our secret code to load via GDT pop es mov bx,#gdt call lfile ! load it pop es ! restore ES and SI pop sinoramd: pop [moff] pop [map] ret#ifndef LCF_NOSERIALserLI: .byte 13,10,0x4c,0x49 ! cr,lf,"LI"BAUD_BASE = 115200 ! divisor == 1divisor: .byte BAUD_BASE / 19200 ! must be same as bsect.c table .byte BAUD_BASE / 38400 .byte BAUD_BASE / 57600 .byte BAUD_BASE / 115200 .byte BAUD_BASE / 2400 .byte BAUD_BASE / 2400 .byte BAUD_BASE / 2400 .byte BAUD_BASE / 2400; serial_setup -- do the setup for the serial line communications;; No registers are saved;serial_setup:;; BEG_FS;; SEG_FS mov dx,par2_port ! use a COM port ? ! watch out, loads par2_ser_param;; END_FS dec dl js nocom ! no -> go on xor ax,ax ! initialize the serial port xchg al,dh push ax push dx;;; or al,#0x06 ! stop bits = 2, nbits = 7 or 8 ! this OR is not needed yet (21.7) int 0x14 ! Communications Port INIT push #0x40 pop ds pop bx ! was DX shl bx,#1 mov dx,(bx) ! get the port address from the BIOS seg cs ! keep it mov slbase,dx pop bx ! special baud rate test -- was AX test bl,#0x04 ! stop bits == 2? cli ! do not disturb any code below jz stdbps ! standard BPS shr bx,#5 ! index divisor array seg cs mov bl,divisor(bx)spcbps: ! CLI: do not disturb ... push dx ! save base address add dx,#3 ! enable divisor latch access in al,dx or al,#0x80 out dx,al pop dx ! set new divisor push dx xchg ax,bx out dx,al inc dx mov al,ah out dx,al inc dx ! disable divisor latch access inc dx xchg ax,bx and al,#0x7f out dx,al pop dx ! restore base addressstdbps: ! CLI: redundant if fell in from above push dx add dx,#4 ! address Modem Control Reg.#if 0 in al,dx or al,#3 ! turn on DTR and RTS#else mov al,#3 ! turn on DTR and RTS#endif out dx,al pop dx sti ! done mov cx,#32 ! drain the queue (if any)drain: in al,dx loop drain add dx,#5 ! clear the status register in al,dx ! send "\r\nLI" to the serial port mov si,#serLI mov cx,#4ser1: seg cs lodsb call serdisp loop ser1nocom: ret#endif /* LCF_NOSERIAL */#ifdef SHS_PASSWORDS#include "shs3.S"#endif#include "read.S"#include "volume.S"#define SECOND_STAGE_LOADER#include "mapper.S"#undef SECOND_STAGE_LOADER#ifdef LCF_BDATA#include "bdata.h"#include "biosdata.S"#endif#ifdef MENU#include "graph.S"#include "menu.S"#include "strlen.S"#include "crt.S"#endif#ifdef BITMAP#include "bitmap.S"#include "strlen.S"#include "vesainfo.h"#include "display4.S"#endif! Put tokens into keyboard bufferputkbd: add si,#4 ! skip over "kbd=" push es xor ax,ax ! set ES to zero mov es,axpknext: lodsb ! get next byte or al,al ! NUL ? jz pkdone ! yes -> done cmp al,#32 ! blank ? jne pkrd ! no -> read scan codepkdone: dec si ! return last character pop es ! done retpkrd: xor cx,cx ! clear accumulatorpkrdlp: cmp al,#97 ! lower case character ? jb pknol ! no -> go on sub al,#32 ! make upper casepknol: sub al,#48 ! normalize cmp al,#10 ! >"9" ? jb pkok ! no -> okay cmp al,#17 ! <"A" ? jb pksyn ! yes -> syntax error sub al,#7 ! adjust cmp al,#16 ! >"F" ? jae pksyn ! yes -> syntax errorpkok: shl cx,1 ! shift CX jc pksyn ! carry means trouble shl cx,1 jc pksyn shl cx,1 jc pksyn shl cx,1 jc pksyn add cl,al ! put in lowest nibble lodsb ! get next byte or al,al ! NUL ? jz pkend ! yes -> at end cmp al,#32 ! space ? je pkend ! yes -> at end cmp al,#44 ! comma ? je pkmore ! yes -> end of token jmp pkrdlp ! token continuespksyn: mov bx,#msg_pks ! complain call saypkfls: lodsb ! flush to end of option or al,al jz pkdone cmp al,#32 je pkdone jmp pkflspkend: call pkput ! store token jmp pkdone ! ... and returnpkmore: call pkput ! store token jmp pknext ! handle next tokenpkput: seg es ! get buffer pointer mov bx,[KBEND] mov dx,bx add dx,#2 ! increment it cmp dx,#KBHIGH ! (wrap around end) jb pknadj mov dx,#KBLOWpknadj: seg es ! buffer full ? cmp dx,[KBBEG] je pkfull ! yes -> error seg es ! store scan code mov (bx+0x400),cx seg es ! store new pointer mov [KBEND],dx ret ! donepkfull: mov bx,#msg_pkf ! complain call say pop ax ! discard return address
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -