1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
#include "monitor.h"
#ifndef NOMONITOR
int x86 = 3; /* CPU major number */
char *x86_name = ""; /* and it's name */
int x86_emu = 0; /* Is this a PC emulator ? */
int x86_fpu = 0;
#endif
int x86_test = 0; /* In test mode */
unsigned boot_mem_top = 0x2000; /* Default 128k, the minimum */
long main_mem_top = 0; /* K of extended memory */
void cpu_check()
{
#ifndef NOMONITOR
static char *name_808x[] =
{
"8088", "8086", "80C88", "80C86", "NEC V20", "NEC V30", "808x Clone"
};
static char *name_8018x[] =
{
"80188", "80186", "8018x Clone"
};
static char cpubuf[] = "80x86+";
int c, major;
c = cputype(0);
x86_fpu = (c < 0);
major = ((c >> 8) & 0x1F);
c &= 0xFF;
x86 = (major&0xF);
if (major == 0)
{
if (c > 6) c = 6;
x86_name = name_808x[c];
}
else if (major == 1)
{
if (c > 3) c = 3;
x86_name = name_8018x[c];
}
else
{
cpubuf[2] = (major&0xF)+'0';
cpubuf[5] = (major > 15 ? '+' : '\0');
x86_name = cpubuf;
if (c & 0x01) x86_emu = 1; /* Already in protected mode !!! */
}
x86_test = x86_emu;
if (x86<3)
x86_test = 1;
#endif
#ifdef __STANDALONE__
if (__argr.x.cflag)
x86_test = 1;
#else
x86_test = 1;
#endif
}
void mem_check()
{
if (x86_test) {
main_mem_top = 0;
return;
}
#asm
int 0x12 ! Amount of boot memory
mov cl,#6
sal ax,cl ! In segments
mov [_boot_mem_top],ax
mov ah,#0x88 ! Next check for extended
int 0x15
jnc got_ext ! Error!
is_xt:
xor ax,ax
got_ext:
mov word ptr [_main_mem_top+2],#0
mov [_main_mem_top],ax
#endasm
/* Try int $15 EAX=$E820 */
{
struct e820_dat {
unsigned long base_lo, base_hi;
unsigned long len_lo, len_hi;
long addr_type;
} e820_item;
long epoll = 0;
do
{
e820_item.addr_type = 0;
#asm
mov eax,#$E820
mov ebx,.mem_check.epoll[bp]
mov ecx,#20
mov edx,#$534D4150
push ds
pop es
lea di,.mem_check.e820_item[bp]
int $15
jnc got_e820
xor ebx,ebx
got_e820:
mov .mem_check.epoll[bp],ebx
#endasm
if (e820_item.addr_type == 1
&& e820_item.base_hi == 0
&& e820_item.base_lo == 0x100000L)
{
/* XXX Later ... */
if (e820_item.len_hi) main_mem_top = 0x40000;
else
main_mem_top = (e820_item.len_lo >> 10);
return;
}
}
while(epoll);
}
/* Try int $15 EAX=$E801 */
{
unsigned int mem_64, mem_16; /* For int $15,AX=$E801 */
#asm
mov ax,#$E801
int $15
jc no_e801
mov .mem_check.mem_16[bp],ax
mov .mem_check.mem_64[bp],bx
#endasm
main_mem_top = ((unsigned long)mem_64<<6) + mem_16;
#asm
no_e801:
#endasm
}
}
#define RIGHTS (0x93000000L)
static struct {
char gdt0[8];
char gdt1[8];
unsigned short src_len;
long src_seg;
unsigned short spad;
unsigned short dst_len;
long dst_seg;
unsigned short dpad;
char gdt4[8];
char gdt5[8];
} GDT = {
"","",
0xFFFF, RIGHTS, 0,
0xFFFF, RIGHTS, 0,
""
};
mem_write(buffer, baseaddr, sectno, sectcount)
void * buffer;
long baseaddr;
unsigned sectno, sectcount;
{
if(x86_test) return 0;
/* In an EMU we can't write to high mem but
we'll pretend we can for debuggering */
baseaddr += ((long)sectno<<9);
if( baseaddr < 0xA0000L )
{
__movedata(__get_ds(), buffer,
(unsigned)(baseaddr>>4), (unsigned)(baseaddr&0xF),
sectcount * 512);
return 0;
}
GDT.src_seg = RIGHTS + (unsigned)buffer + ((long)__get_ds()<<4);
GDT.dst_seg = RIGHTS + baseaddr;
return asm_copy(sectcount << 8);
}
mem_read(buffer, baseaddr, sectno)
void * buffer;
long baseaddr;
int sectno;
{
if(x86_test) return 3;
baseaddr += ((long)sectno<<9);
GDT.dst_seg = RIGHTS + (unsigned)buffer + ((long)__get_ds()<<4);
GDT.src_seg = RIGHTS + baseaddr;
return asm_copy(256);
}
static asm_copy(length)
{
#asm
#if !__FIRST_ARG_IN_AX__
mov bx,sp
mov ax,[bx+2]
#endif
push es
push si
mov cx,ax
mov ah,#$87
push ds
pop es
mov si,#_GDT
int $15
jc err
xor ax,ax
err:
mov al,ah
xor ah,ah
pop si
pop es
#endasm
}
|