📄 second.s
字号:
cwrite:#ifdef RAID_NEW BEG_FS SEG_FS test byte ptr par1_prompt+SSDIFF,#FLAG_RAID_NOWRITE ; no writes? END_FS jnz cwok ; jump if no writing allowed BEG_FS SEG_FS test byte ptr par1_prompt+SSDIFF,#FLAG_RAID ; is it a RAID write END_FS jnz cmd_raid_wrt#endif mov byte ptr (dsk_wrflag),#1 ! flag write operation call cread mov byte ptr (dsk_wrflag),#0 ! flag read operation jnc cwok ! no error - returncnok: push ax ! leave no traces push bx mov al,#87 ! "W" push ax ! display clobbers AH call display pop ax mov al,ah ! error code call bout call crlf ! leave space pop bx pop ax stc ! flag error JRCcwok:#if DEBUG_NEW pushf call pause popf#endif ret ! done#ifdef RAID_NEW; We know it is RAID, so CHS is not in effectcmd_raid_wrt: mov di,#raid_tt ; point at RAID translation table xor ah,ah ;will be zero for LINEAR xchg al,dh ;AX is possible address test dl,#LBA32_FLAG ;test for pure LINEAR ***** jz lnwrt ;jump if pure LINEAR ***** test dl,#LBA32_NOCOUNT jz lnwrt mov ah,dh ;former count is really hi-nibblelnwrt: ; address is AX:CX, DH=1, DL=device+flags, ES:BX=buffer mov dh,#1 ;set count to 1 push ax push cx push di mov byte ptr (dsk_wrflag),#1 ! flag write operation#if DEBUG_NEW pusha push ax ! save high order push cx ! save low order push dx mov bx,#cmdwr call say pop ax call bout ! device+flags mov bx,#rs_reloc call say call dout call crlf popa#endif call lnread mov byte ptr (dsk_wrflag),#0 ! flag read operation pop di pop cx jc cmdwerr pop ax mov dh,(di) ! get next raid device or dh,dh jz cwok and dl,#0xFF-DEV_MASK ! save flags or dl,dh add cx,(di+1) ! apply low order translation adc ax,(di+3) ! apply high order translation add di,#5 jmp lnwrtcmdwerr: pop cx ! was AX jmp cnok ! write dumb error message#if DEBUG_NEWcmdwr: .ascii "RAID: write to device " .byte 0#endif#endif#endifkt_read: ; KEYTABLE read call kt_set ; set for KEYTABLE i/o call cread jc keyerr mov si,#KEYTABLE ! compute a checksum of the keytable mov di,#SECTOR_SIZE - 8 ! skip the last 4+4 bytes#ifdef LCF_M386 push dword #CRC_POLY1#else push #CRC_POLY1>>16 push #CRC_POLY1&0xFFFF#endif call crc32 add di,si#ifdef LCF_M386 cmp eax,dword (di)#else cmp ax,word (di) jne keyerr cmp dx,word (di+2) #endif jz nokeyerr! Checksum errorkeyerr: mov bx,#msg_chkkey br zz ! go waitnokeyerr: ret! Sector read! trashes CX and DIcread: test dl,#LINEAR_FLAG|LBA32_FLAG jnz use_linear push ax ;save the count mov ah,#2 ;read command call dsk_do_rw ; int 0x13 with retries pop cx ;Carry Set means error on read mov al,cl ;count in AL, error code in AH retuse_linear: mov ah,hinib ;will be zero for LINEAR xchg al,dh ;AX is possible address test dl,#LBA32_FLAG ;test for LBA32/LINEAR ***** jz lnread ;pure LINEAR ***** test dl,#LBA32_NOCOUNT jz lnread mov ah,dh ;former count is really hi-nibble mov hinib,ah mov dh,#1 ;set count to 1lnread: xchg di,ax ;hi-address to DI mov al,dh ;count to AL test dl,#RAID_REL_FLAG ; ****** jz ln_do_read ; ****** BEG_FS SEG_FS add cx,par1_raid_offset+SSDIFF ; ***** RAID ****** SEG_FS adc di,par1_raid_offset+2+SSDIFF ; ***** RAID ****** END_FSln_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: 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#endif#ifdef RAID_NEW; raid_search -- search for other raid disks which parallel this one;; enter with DS:BX pointing to buffer to use (DESCR) for searches; and with ES=DS=CS;; side effect is to set up the raid translation table for writes;;raid_search: push es#if DEBUG_NEW mov byte ptr raid_nn,#0 ;set number of raid disks to 0 call crlf#endif BEG_FS SEG_FS mov dl,par1_keytab+sa_device+SSDIFF ; get map file drive; enable matching RAID boot blocks by clearing the DEFEAT flag SEG_FS and byte ptr par1_prompt+SSDIFF,#0xFF-FLAG_RAID_DEFEAT SEG_FS test byte ptr par1_prompt+SSDIFF,#FLAG_RAID END_FS#if DEBUG_NEW#ifdef LCF_M386 jz near rs_ret#else beq rs_ret#endif#else jz rs_ret#endif and dx,#0xF0 ; save LINEAR/LBA32/LBA32_NOCOUNT#if 0 cmp dl,#0x80 ; must be 0x80 for this to be raid#if DEBUG_NEW#ifdef LCF_M386 jne near rs_ret#else bne rs_ret#endif#else jne rs_ret#endif#endif mov bp,#16 ; test 16 bios devices push #raid_tt ; set pointerrs_next: push ds pop es mov cx,#1#if DEBUG_NEW pusha push dx mov bx,#rs_test call say pop ax call bout popa#endif push dx ; protect LBA32/LINEAR flags and dx,#DEV_MASK ; mask flag bits; clear DH, too (0x008F) mov al,cl ; read 1 sector call cread ; read the boot sector (MBR) ; no RAID relocation will happen ; because we use CHS addressing pop dx jc rs_done pop di call raid_compare ; watch out for DI - raid ptr in ; the stack#ifdef RAID_NEW push bx mov cx,#4 lea si,(bx+PART_TABLE_OFFSET) add bh,#SECTOR_SIZE>>8rs_chk_pri:#if 0 cmp byte ptr (si+4),#0xFD ; check for raid partition jne rs_chk_pri_next#endif cmp byte ptr (si+4),#0 ; check for empty entry je rs_chk_pri_next push cx push di#if DEBUG_NEW push bx mov bx,#rsckpar call say mov al,#5 sub al,cl call nout pop bx#endif mov al,#1 mov cx,(si+8) mov di,(si+8+2) call lba_read pop di call raid_compare pop cxrs_chk_pri_next: add si,#16 ; next partition table entry loop rs_chk_pri pop bx push di#endif /* CHECK_PRI_TOO */ inc dl ; move to next drive dec bp jnz rs_next ; try next device coders_done: pop di mov byte ptr (di),#0 ; mark zero on end#if DEBUG_NEW pusha call crlf mov bx,#rs_found call say mov si,#raid_nn lodsb call nout mov bx,#rs_found2 call sayrs_debug1: mov bx,#rs_dev call say lodsb call bout mov bx,#rs_reloc call say#ifdef LCF_M386 lodsd push eax call dout#else lodsw push ax lodsw call wout pop ax call wout#endif call crlf test byte ptr (si),#0xFF jnz rs_debug1 call pause popa#endifrs_ret: pop es ret; raid compare; ; enter with DI = raid pointer ; DS:BX points at the buffer that was read; DL is device code;raid_compare: push es push si push di mov si,bx ; compare what is read xor di,di ; to our first stage loader#ifdef LCF_M386 push fs pop es#else seg cs mov es,firstseg#endif mov cx,#par1_raid_offset-par1_cli ; signature repe cmpsb jne rs_skip2 add si,#8 add di,#8 ; skip raid_reloc & timestamp mov cx,#par1_size - par1_raid_offset - 8 repe cmpsbrs_skip2:#if DEBUG_NEW pushf pusha mov bx,#rs_nomatch jne rs_nm mov bx,#rs_matchrs_nm: call say popa popf#endif jne rs_skip; we found two boot records that are identical#if DEBUG_NEW inc raid_nn#endif#ifdef LCF_M386 mov eax,(bx+par1_raid_offset)#else mov ax,(bx+par1_raid_offset) mov cx,(bx+par1_raid_offset+2)#endif#ifdef LCF_M386 seg fs sub eax,par1_raid_offset#else seg es ; ES == FS sub ax,par1_raid_offset seg es sbb cx,par1_raid_offset+2 push ax or ax,cx ; do the zero test pop ax#endif jnz rs_insert seg es ; ES == FS cmp dl,par1_dflcmd+sa_device#if DEBUG_NEW jne rs_insert pusha mov bx,#rs_omitted call say popa jmp rs_skip#else je rs_skip#endifrs_insert: pop di mov (di),dl ; save device#ifdef LCF_M386 mov (di+1),eax ; save offset#else mov (di+1),ax ; save offset lo mov (di+1+2),cx ; save offset hi#endif add di,#5 push dirs_skip: pop di pop si pop es ret#if DEBUG_NEWraid_nn: .byte 0 ; must precede raid_tt for printout#endifraid_tt: .blkb 5*16 ; format is drive: .byte ; translate: .long .byte 0#if DEBUG_NEWrs_test: .ascii "RAID: Testing"rs_dev: .ascii " device " .byte 0rs_nomatch: .ascii " no"rs_match: .ascii " match" .byte 10,0rs_omitted: .ascii " omitted" .byte 10,0rs_found: .ascii "RAID: found " .byte 0rs_found2: .ascii " matching MBR(s)" .byte 10,0rs_reloc: .ascii " reloc " .byte 0rsckpar: .ascii " Checking partition " .byte 0#endif#endif#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#ifdef LCF_M386 mov eax,#-1 ; initialize CRC#else mov ax,#-1 cwd#endif 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#ifdef LCF_M386 shl eax,#1 ; shift hi bit out of CRC#else shl ax,#1 rcl dx,#1#endif adc bh,#0 ; add carry to BH shr bh,#1 ; put bit in carry jnc crc32c ; skip the xor#ifdef LCF_M386 xor eax,(bp+4) ; xor in the polynomial#else xor ax,(bp+4) xor dx,(bp+6)#endifcrc32c: loop crc32b ; loop back for 8 bits jmp crc32acrc32d: #ifdef LCF_M386 not eax ; finialize CRC#else not ax not dx#endif 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 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 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 & loope8go5: 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 to 1k add eax,#1024 ; add 1M to address add eax,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_hm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -