Removed several excess files.
This commit is contained in:
284
386_ref.cpp
284
386_ref.cpp
@@ -1,284 +0,0 @@
|
|||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <wchar.h>
|
|
||||||
#include <math.h>
|
|
||||||
#ifndef INFINITY
|
|
||||||
# define INFINITY (__builtin_inff())
|
|
||||||
#endif
|
|
||||||
#define HAVE_STDARG_H
|
|
||||||
#include "../86box.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "x86.h"
|
|
||||||
#include "x87.h"
|
|
||||||
#include "../nmi.h"
|
|
||||||
#include "../mem.h"
|
|
||||||
#include "../pic.h"
|
|
||||||
#include "../pit.h"
|
|
||||||
#include "../timer.h"
|
|
||||||
#include "../floppy/fdd.h"
|
|
||||||
#include "../floppy/fdc.h"
|
|
||||||
|
|
||||||
#define CPU_BLOCK_END()
|
|
||||||
|
|
||||||
uint16_t flags,eflags;
|
|
||||||
uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
|
|
||||||
|
|
||||||
x86seg gdt,ldt,idt,tr;
|
|
||||||
x86seg _cs,_ds,_es,_ss,_fs,_gs;
|
|
||||||
x86seg _oldds;
|
|
||||||
|
|
||||||
uint32_t cr2, cr3, cr4;
|
|
||||||
uint32_t dr[8];
|
|
||||||
|
|
||||||
#include "x86_flags.h"
|
|
||||||
|
|
||||||
#ifdef ENABLE_386_REF_LOG
|
|
||||||
int x386_ref_do_log = ENABLE_386_REF_LOG;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
x386_ref_log(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_386_REF_LOG
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
if (x386_do_log) {
|
|
||||||
va_start(ap, fmt);
|
|
||||||
pclog_ex(fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
enum class translate_kind
|
|
||||||
{
|
|
||||||
TRANSLATE_READ, TRANSLATE_WRITE, TRANSLATE_EXEC
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum class exception_type
|
|
||||||
{
|
|
||||||
FAULT, TRAP, ABORT
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct cpu_exception
|
|
||||||
{
|
|
||||||
exception_type type;
|
|
||||||
uint8_t fault_type;
|
|
||||||
uint32_t error_code;
|
|
||||||
bool error_code_valid;
|
|
||||||
cpu_exception(exception_type _type, uint8_t _fault_type, uint32_t errcode, bool errcodevalid)
|
|
||||||
: type(_type)
|
|
||||||
, fault_type(_fault_type)
|
|
||||||
, error_code(errcode)
|
|
||||||
, error_code_valid(errcodevalid) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
type_check_ref(x86seg* segment, uint32_t offset, translate_kind kind)
|
|
||||||
{
|
|
||||||
bool system_seg = !((segment->flags_ref >> 4) & 1);
|
|
||||||
bool executable = (segment->flags_ref >> 3) & 1;
|
|
||||||
|
|
||||||
if(!system_seg)
|
|
||||||
{
|
|
||||||
if(executable) {
|
|
||||||
bool readable = (segment->flags_ref >> 1) & 1;
|
|
||||||
switch(kind) {
|
|
||||||
case TRANSLATE_READ:
|
|
||||||
if (!readable)
|
|
||||||
throw cpu_exception(FAULT, ABRT_GPF, 0, true);
|
|
||||||
break;
|
|
||||||
case TRANSLATE_WRITE:
|
|
||||||
throw cpu_exception(FAULT, ABRT_GPF, 0, true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bool writeable = (segment->flags_ref >> 1) & 1;
|
|
||||||
switch(kind) {
|
|
||||||
case TRANSLATE_WRITE:
|
|
||||||
if (!writeable)
|
|
||||||
throw cpu_exception(FAULT, ABRT_GPF, 0, true);
|
|
||||||
break;
|
|
||||||
case TRANSLATE_EXEC:
|
|
||||||
throw cpu_exception(FAULT, ABRT_GPF, 0, true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO
|
|
||||||
x386_ref_log("type_check_ref called with a system-type segment! Execution correctness is not guaranteed past this point!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
limit_check_ref(x86seg* segment, uint32_t offset, translate_kind kind)
|
|
||||||
{
|
|
||||||
uint8_t fault_type = ABRT_GPF;
|
|
||||||
uint32_t addr = offset & ((1 << (32 - 12)) - 1);
|
|
||||||
|
|
||||||
if (segment == &_ss)
|
|
||||||
fault_type = ABRT_SS;
|
|
||||||
|
|
||||||
switch(kind) {
|
|
||||||
case translate_kind::READ:
|
|
||||||
case translate_kind::WRITE:
|
|
||||||
// Data segment.
|
|
||||||
bool expand_down = (segment->flags_ref >> 2) & 1;
|
|
||||||
bool big_seg = (segment->flags_ref >> 14) & 1; // TODO: Not sure if this is ever used. Test this!
|
|
||||||
bool granularity = (segment->flags_ref >> 15) & 1;
|
|
||||||
uint32_t lower_bound;
|
|
||||||
uint32_t upper_bound;
|
|
||||||
if (big_seg != granularity)
|
|
||||||
x386_ref_log("B bit doesn't equal granularity bit! Execution correctness is not guaranteed past this point!\n");
|
|
||||||
if (expand_down) {
|
|
||||||
if (granularity) {
|
|
||||||
lower_bound = ((addr << 12) | 0xfff) + 1;
|
|
||||||
upper_bound = 0xffffffff; //4G - 1
|
|
||||||
} else {
|
|
||||||
lower_bound = addr + 1;
|
|
||||||
upper_bound = 0xffff; //64K - 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lower_bound = 0;
|
|
||||||
if (granularity)
|
|
||||||
upper_bound = (addr << 12) | 0xfff;
|
|
||||||
else
|
|
||||||
upper_bound = addr;
|
|
||||||
}
|
|
||||||
if ((addr < lower_bound) || (addr > upper_bound))
|
|
||||||
throw cpu_exception(FAULT, fault_type, 0, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
bool granularity = (segment->flags_ref >> 15) & 1;
|
|
||||||
uint32_t limit;
|
|
||||||
|
|
||||||
if (granularity)
|
|
||||||
limit = (addr << 12) | 0xfff;
|
|
||||||
else
|
|
||||||
limit = addr;
|
|
||||||
|
|
||||||
if (addr > limit)
|
|
||||||
throw cpu_exception(FAULT, fault_type, 0, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
privilege_check_ref(x86seg* segment, uint32_t offset, translate_kind kind)
|
|
||||||
{
|
|
||||||
bool system_seg = !((segment->flags_ref >> 4) & 1);
|
|
||||||
bool executable = (segment->flags_ref >> 3) & 1;
|
|
||||||
|
|
||||||
if (!system_seg) {
|
|
||||||
if(executable) {
|
|
||||||
bool conforming = (segment->flags_ref >> 2) & 1;
|
|
||||||
if (conforming)
|
|
||||||
return;
|
|
||||||
else {
|
|
||||||
int seg_rpl = segment->seg & 3;
|
|
||||||
int dpl = (segment->flags_ref >> 5) & 3;
|
|
||||||
if (dpl < CPL)
|
|
||||||
throw cpu_exception(FAULT, ABRT_GPF, 0, true);
|
|
||||||
if (dpl < seg_rpl)
|
|
||||||
throw cpu_exception(FAULT, ABRT_GPF, 0, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int seg_rpl = segment->seg & 3;
|
|
||||||
int dpl = (segment->flags_ref >> 5) & 3;
|
|
||||||
if (dpl < CPL)
|
|
||||||
throw cpu_exception(FAULT, ABRT_GPF, 0, true);
|
|
||||||
if (dpl < seg_rpl)
|
|
||||||
throw cpu_exception(FAULT, ABRT_GPF, 0, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO
|
|
||||||
x386_ref_log("privilege_check_ref called with a system-type segment! Execution correctness is not guaranteed past this point!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define rammap(x) ((uint32_t *)(_mem_exec[(x) >> 14]))[((x) >> 2) & 0xfff]
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
translate_addr_ref(x86seg* segment, uint32_t offset, translate_kind kind)
|
|
||||||
{
|
|
||||||
// Segment-level checks.
|
|
||||||
type_check_ref(segment, offset, kind);
|
|
||||||
limit_check_ref(segment, offset, kind);
|
|
||||||
privilege_check_ref(segment, offset, kind);
|
|
||||||
|
|
||||||
uint32_t addr = segment->base + offset;
|
|
||||||
|
|
||||||
if (!(cr0 >> 31))
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
readmemb_ref(x86seg* segment, uint32_t offset)
|
|
||||||
{
|
|
||||||
uint32_t addr = translate_addr_ref(segment, offset, TRANSLATE_READ);
|
|
||||||
return mem_readb_phys_dma(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
writememb_ref(x86seg* segment, uint32_t offset, uint8_t data)
|
|
||||||
{
|
|
||||||
uint32_t addr = translate_addr_ref(segment, offset, TRANSLATE_READ);
|
|
||||||
mem_writeb_phys_dma(addr, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
exec386_ref(int cycs)
|
|
||||||
{
|
|
||||||
uint8_t temp;
|
|
||||||
uint32_t addr;
|
|
||||||
int tempi;
|
|
||||||
int cycdiff;
|
|
||||||
int oldcyc;
|
|
||||||
|
|
||||||
cycles+=cycs;
|
|
||||||
|
|
||||||
while (cycles>0) {
|
|
||||||
timer_start_period(cycles << TIMER_SHIFT);
|
|
||||||
|
|
||||||
oldcs = CS;
|
|
||||||
cpu_state.oldpc = cpu_state.pc;
|
|
||||||
oldcpl = CPL;
|
|
||||||
cpu_state.op32 = use32;
|
|
||||||
|
|
||||||
x86_was_reset = 0;
|
|
||||||
|
|
||||||
dontprint = 0;
|
|
||||||
|
|
||||||
cpu_state.ea_seg = &_ds;
|
|
||||||
cpu_state.ssegs = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
} catch(cpu_exception) {
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_end_period(cycles << TIMER_SHIFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BIN
EMM386.EX_
BIN
EMM386.EX_
Binary file not shown.
BIN
src_20180612.rar
BIN
src_20180612.rar
Binary file not shown.
BIN
src_20180624.rar
BIN
src_20180624.rar
Binary file not shown.
Reference in New Issue
Block a user