📄 test4.c
字号:
/* test4.c *//* Copyright 2001-2004 John Coffman. All rights reserved. Licensed under the terms contained in the file 'COPYING' in the LILO source directory.*/#include <bios.h>#include "../bdata.h"#define DISK_VERSION "2.3"#if __MSDOS__==0#define putch bios_putc#define getch bios_getc#define printf cprintf#define CR 13#else#include <stdio.h>#define putch(c) fputc((c),stdout)#define getch getchar#define CR 10#endif#define CTRL_C 03#define SPACER "\f\n"#define SEQ 0x3C4#ifndef EDD_SUBSET#define EDD_SUBSET 4#define EDD_LOCK 2#define EDD_PACKET 1#endif#ifndef SECTOR_SIZE#define SECTOR_SIZE 512#endif#define nelem(a) (sizeof(a)/sizeof((a)[0]))typedef unsigned char byte;typedef unsigned short word;typedef unsigned long dword;extern union REGS __argr;extern struct SREGS __argseg;union REGS reg, oreg;struct SREGS sreg;int last_good_disk;int video_1 = 0xF00;int num_hd = BD_MAX_HARD;int errno;dword hma; /* highest memory address */struct { long start, start_hi, length, length_hi, mtype; } mem_map;#define E820_MAGIC 0x534D4150struct gdt_entry { unsigned short limit; unsigned short base01; unsigned char base2; unsigned char dtype; /* 0x93 for data */ unsigned char limit2; /* limit in low nibble, granularity & 32-bit in high nibble */ unsigned char base3;};struct gdt_entry gdt[6];staticint hicopy (unsigned long to, unsigned long from, int wcount){ int status; unsigned char save; memset(gdt, 0, sizeof(gdt)); gdt[2].limit = gdt[3].limit = 0xFFFF; gdt[2].dtype = gdt[3].dtype = 0x93; gdt[2].base01 = from; gdt[2].base2 = from>>16; gdt[2].base3 = from>>24; gdt[3].base01 = to; gdt[3].base2 = to>>16; save = gdt[3].base3 = to>>24; segread(&sreg); sreg.es = sreg.ds; reg.h.ah = 0x87; reg.x.cx = wcount; reg.x.si = gdt;/*** gdt[3].base3 &= 0; / crosstalk */ int86x(0x15, ®, &oreg, &sreg); status = oreg.h.ah; if (oreg.x.cflag) status |= 0x100; if (save!=gdt[3].base3) status |= 0x200; errno |= status; return status;}unsigned long linear(void *ptr){ segread(&sreg); return ((unsigned long)sreg.ds<<4) + (unsigned int)ptr;}word hipeekw(long address){ word temp; hicopy(linear(&temp), address, 1); return temp;}int hipokew(long address, word value){ return hicopy(address, linear(&value), 1);}#if __MSDOS__==0staticbios_putc0(int c){ union REGS reg; if (c=='\f') {#if 0 reg.h.ah = 0x0F; int86(0x10, ®, ®); reg.h.ah = 0; int86(0x10, ®, ®);#else static word upper = 0; if (!upper) { __set_es(0x40); /* address BIOS data area */ upper = __peek_es(0x84); if (upper < 24 || upper > 50) upper = 24; upper <<= 8; reg.h.ah = 0x0F; /* get video mode */ int86(0x10, ®, ®); upper |= (reg.h.ah-1); } reg.x.ax = 0x0600; /* blank screen area */ reg.h.bh = 7; reg.x.cx = 0x0000; reg.x.dx = upper; int86(0x10, ®, ®); reg.h.ah = 2; /* set cursor position */ reg.h.bh = 0; reg.x.dx = 0x0000; int86(0x10, ®, ®);#endif } else { reg.h.al = c; reg.h.ah = 14; reg.x.bx = 7; int86(0x10, ®, ®); }}void bios_putc(char c){static int col; switch(c) { case '\t': do bios_putc(' '); while(col&7); break; case '\n': bios_putc0('\r'); /* fall into CR */ case '\f': case '\r': col=0; default: bios_putc0(c); if (c>=' ' && c<0177) col++; }}#endifstaticint a20(void) /* Return 1 if a20 is enabled, 0 if disabled */{#asm push ds push es xor ax,ax mov es,ax dec ax mov ds,ax cli mov al,[0x10] mov ah,al seg es cmp al,[0] jne a20_8 xor al,#0x5A mov [0x10],al seg es cmp al,[0] jne a20_8 xor al,al jmp a20_9a20_8: mov al,#1a20_9: mov [0x10],ah cbw sti pop es pop ds#endasm}staticvoid sizeit(unsigned long sectors){static char suf[] = "KMGT"; int fract; char *cp;/* print disk size in K,M,G,T */ sectors /= 2; cp = suf; if (sectors <= 999) { printf("%ld%c", sectors, *cp); return; } cp++; while (sectors > 999999) { sectors /= 1000; cp++; } if (sectors > 2999) { sectors *= 1024; sectors /= 1000; } sectors += 5; /* round decimal part */ sectors /= 10; fract = sectors % 100; sectors /= 100; printf("%ld.%02d%c", sectors, fract, *cp);}staticvoid banner(char *version){ printf( "\n\n\n"">>>> Disk Detection and Parameter Display <<<<\n\n\n""Version %s, Copyright (C) 1999-2004 John Coffman <johninsd@san.rr.com>\n""Portions Copyright (C) 1996-2001 Robert de Bath, used with permission\n""Re-use and redistribution rights set forth in the file \"COPYING\".\n\n", version);}staticvoid testDX(void){#if __MSDOS__==0 printf("Boot reported from DX = 0x%04x (boot device is 0x%02x in DL)\n", __argr.x.dx, __argr.h.dl); if (__argr.h.dl == 0 || __argr.h.dl == 1) { printf("If you booted from the %s floppy drive, then this is correct.", __argr.h.dl ? "second" : "first"); } else if (__argr.h.dl >= 0x80 && __argr.h.dl <= 0x8f) { printf("If you booted from %s hard drive, then this is correct.", __argr.h.dl==0x80 ? "the first" : __argr.h.dl==0x81 ? "the second" : "a" ); } else { printf("It looks like the BIOS failed to report the boot device in DL.\n"); }#endif}staticint smsw(void){#asm smsw ax#endasm}staticlong e820(long b){#asm push bp mov bp,sp push ds pop es mov di,#_mem_map mov eax,#0xE820 mov ebx,[bp+4] mov ecx,#20 mov edx,#E820_MAGIC stc int 0x15 jc e820_err cmp eax,#E820_MAGIC mov ax,#-2 jne e820_exit cmp ecx,#20 mov ax,#-3 jne e820_exit push ebx pop ax pop dx jmp e820_exite820_err: mov ax,#-1e820_err2: cwde820_exit: leave#endasm}staticint inb(int port){#asm mov bx,sp mov dx,[bx+2] in al,dx xor ah,ah#endasm}staticint outb(int port, int data){#asm mov bx,sp mov dx,[bx+2] mov ax,[bx+4] out dx,al#endasm}staticvoid v86test(void){static char s1[] = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"; if (smsw()&1) { printf(s1); printf( "!!! *** Warning: DOS is not running in REAL mode *** !!!\n" "!!! *** Reported results may not be accurate *** !!!\n" ); printf(s1); }}staticvoid yesno(int i){ printf("%s\n", i?"yes":"no");}staticvoid decimal(unsigned long value){ unsigned int v[4]; int i; for (i=0; i<4; i++) { v[i] = value % 1000; value /= 1000; } if (v[3]) printf("%d,%03d,%03d,%03d", v[3], v[2], v[1], v[0]); else if (v[2]) printf("%d,%03d,%03d", v[2], v[1], v[0]); else if (v[1]) printf("%d,%03d", v[1], v[0]); else printf("%d", v[0]);}staticvoid print_regs(union REGS *reg) { printf("AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x\n", reg->x.ax, reg->x.bx, reg->x.cx, reg->x.dx, reg->x.si, reg->x.di);}static void print_sregs(struct SREGS *sreg) { printf("DS=%04x ES=%04x CS=%04x SS=%04x\n", sreg->ds, sreg->es, sreg->cs, sreg->ss);}staticint is_msdos(void){#if __MSDOS__ return 1;#else return (__argseg.es+0x10 == __argseg.cs);#endif}staticvoid pause(void){ char ch;/* Must be standalone */ printf("\n\n\nHit <Enter> to continue, <^C> to quit ..."); do { ch = getch(); if (ch==CTRL_C) exit(0);#if DEBUG>=1 if (ch != CR) printf(" %o", ch);#endif } while (ch != CR); printf("\n");}staticvoid video_fix(void){ outb(SEQ, 1); video_1 = inb(SEQ+1);/* dirty hack for DELL Dimension 4300 computers */ printf("\f\n");}static void print_carry(int flag){ printf(" Carry = %d\n", flag);}staticvoid get_equip_cfg(void){static char *vmode[4] = { "reserved", "40x25 color", "80x25 color", "80x25 monochrome" }; word flag; int n; pause(); printf(SPACER "Int 11h\t\t\t\t[PC][AT][PS/2]\n" "Get Equipment Configuration\n\n" "Returns:\n "); flag = int86(0x11, ®, ®); print_regs(®); printf("\nHas floppy drive(s): "); yesno(flag&1); printf("Has math coprocessor: "); yesno(flag&2); printf("Has pointing device: "); yesno(flag&4); printf("Initial video mode: %s\n", vmode[(flag>>4)&3]); n = flag&1 ? ((flag>>6)&3)+1 : 0; if (n) printf("Floppy drives installed: %d\n", ((flag>>6)&3)+1 ); n = (flag>>9)&7; printf("Serial interfaces: %d\n", n); printf("Has game adapter: "); yesno(flag&4096); n = (flag>>14)&3; printf("Parallel interfaces: %d\n", n);}staticvoid get_conv_mem(void){ int mem; pause(); printf(SPACER "Int 12h\t\t\t\t[PC][AT][PS/2]\n" "Get Conventional Memory Size\n\n" "Returns:\n "); mem = int86(0x12, ®, ®); print_regs(®); printf("\nThere is %dK of low memory. EBDA size = %dK EBDA starts at 0x%lx\n", mem, 640-mem, (long)mem<<10 ); printf("\n(The A20 line is %sabled.)\n", a20() ? "en" : "dis");}staticvoid mov_ext_mem(void){ word status, temp, vtemp; dword high, veryhigh; pause(); segread(&sreg); sreg.es = sreg.ds; printf(SPACER "Int 15h Function 87h\t\t[AT][PS/2]\n" "Move Extended Memory Block\n\n" "Call With:\n "); print_sregs(&sreg); reg.x.ax = 0x8700; reg.x.cx = 1; reg.x.si = &gdt; printf(" "); print_regs(®); high = 1024L*(1024L+128)-2; /* 1Mb + 128K */ veryhigh = high+16L*1024L*1024L; if (veryhigh >= hma) veryhigh=0;#define WORDA 0xA5C6#define WORDB 0x6CA5 errno = 0; temp = hipeekw(high); status = hipokew(high, WORDA^temp); printf("\nReturns:\n "); print_sregs(&sreg); printf(" "); print_regs(&oreg); print_carry((status>>8) & 1); printf("\nR/W test at address %08lx ", high); if (hipeekw(high) != (WORDA^temp)) errno |= 0x400; hipokew(high, temp); if (hipeekw(high) != temp) errno |= 0x800; printf("%ssuccessful\n", errno ? "un" : ""); if (errno) printf("Error code = 0x%04x\n", errno); if (veryhigh) { printf("R/W test at address %08lx ", veryhigh); vtemp = hipeekw(veryhigh); hipokew(veryhigh, WORDB^vtemp); if (hipeekw(high) != temp) errno |= 0x200; if (hipeekw(veryhigh) != (WORDB^vtemp)) errno |= 0x400; hipokew(veryhigh, vtemp); if (hipeekw(high) != temp) errno |= 0x200; if (hipeekw(veryhigh) != vtemp) errno |= 0x800; printf("%ssuccessful\n", errno ? "un" : ""); if (errno) printf("Error code = 0x%04x\n", errno); } if (errno & 0xE00) printf("\nThere is crosstalk between the two addresses\n" "The function does not support full 386 32-bit addressing.\n");}#define NAREA 32staticvoid get_ext_mem(void){ long b, b1; dword t; int i; pause(); printf(SPACER "Int 15h Function E820h\t\t[EXT]\n" "Get Memory Map\n\n" "Call With:\n" " EAX=0000E820 EBX=00000000 ECX=00000014 EDX=%lx\n\n", E820_MAGIC ); b = e820(b1=i=0); if (b > 0) { dword start[NAREA], length[NAREA]; int j, k, ovlap; /* 00 000000000000 000000000000 (1) avail */ printf("EBX Start Length Type\n\n"); do { printf(" %02lx %04hx%08lx %04hx%08lx (%d) %s\n", b1, (short)mem_map.start_hi, mem_map.start, (short)mem_map.length_hi, mem_map.length, (int)mem_map.mtype, mem_map.mtype == 1 ? "available" : mem_map.mtype == 2 ? "reserved" : mem_map.mtype == 3 ? "ACPI" : mem_map.mtype == 4 ? "NVS" : "unknown-reserved"); if (mem_map.mtype==1 && mem_map.start_hi==0 && mem_map.start<=1024L*1024L) { if (mem_map.length_hi==0) hma = mem_map.start+mem_map.length; else hma = 0xFFF00000L; } if (i < NAREA) { start[i] = *(dword*)(((char*)&mem_map.start)+1); length[i] = *(dword*)(((char*)&mem_map.length)+1); } i++; b = e820(b1=b); } while (b1 > 0); printf("\n"); if (i > NAREA) { i = NAREA; } ovlap = 0; for (k=0; k<i-1; k++) { dword s, e; s = start[k]; e = s + length[k]; for (j=k+1; j<i; j++) { dword ss, ee; ss = start[j]; ee = ss + length[j]; if (!(ss < s && ee <= s || ss >= e && ee > e)) { printf("*** Memory areas %d and %d overlap ***\n", k, j); ovlap++; } } } if (!ovlap) printf("No memory areas overlap\n"); } else { printf("Returns:\n"); if (b==-1) print_carry(1); else if (b==-2) printf(" EAX=<trash>\n"); else if (b==-3) printf(" EAX=%lx EBX=******** ECX=<trash>\n", E820_MAGIC);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -