Split the 286/386 interpreter away from the 486+ one (the 286/386 interpreter does not use the pccache's, readlookup's, and writelookup's as the emulated CPU's are too slow for them to be required, and also has more accurate FPU timings), also added a LPT status read function for future-proofing.

This commit is contained in:
OBattler
2023-08-08 19:39:52 +02:00
parent 5f72dc7d56
commit b1c5cbaf47
23 changed files with 3759 additions and 144 deletions

View File

@@ -22,6 +22,34 @@
#include <stddef.h>
#include <inttypes.h>
#ifdef OPS_286_386
#define readmemb_n(s,a,b) readmembl_no_mmut_2386((s)+(a),b)
#define readmemw_n(s,a,b) readmemwl_no_mmut_2386((s)+(a),b)
#define readmeml_n(s,a,b) readmemll_no_mmut_2386((s)+(a),b)
#define readmemb(s,a) readmembl_2386((s)+(a))
#define readmemw(s,a) readmemwl_2386((s)+(a))
#define readmeml(s,a) readmemll_2386((s)+(a))
#define readmemq(s,a) readmemql_2386((s)+(a))
#define writememb_n(s,a,b,v) writemembl_no_mmut_2386((s)+(a),b,v)
#define writememw_n(s,a,b,v) writememwl_no_mmut_2386((s)+(a),b,v)
#define writememl_n(s,a,b,v) writememll_no_mmut_2386((s)+(a),b,v)
#define writememb(s,a,v) writemembl_2386((s)+(a),v)
#define writememw(s,a,v) writememwl_2386((s)+(a),v)
#define writememl(s,a,v) writememll_2386((s)+(a),v)
#define writememq(s,a,v) writememql_2386((s)+(a),v)
#define do_mmut_rb(s,a,b) do_mmutranslate_2386((s)+(a), b, 1, 0)
#define do_mmut_rw(s,a,b) do_mmutranslate_2386((s)+(a), b, 2, 0)
#define do_mmut_rl(s,a,b) do_mmutranslate_2386((s)+(a), b, 4, 0)
#define do_mmut_rb2(s,a,b) do_mmutranslate_2386((s)+(a), b, 1, 0)
#define do_mmut_rw2(s,a,b) do_mmutranslate_2386((s)+(a), b, 2, 0)
#define do_mmut_rl2(s,a,b) do_mmutranslate_2386((s)+(a), b, 4, 0)
#define do_mmut_wb(s,a,b) do_mmutranslate_2386((s)+(a), b, 1, 1)
#define do_mmut_ww(s,a,b) do_mmutranslate_2386((s)+(a), b, 2, 1)
#define do_mmut_wl(s,a,b) do_mmutranslate_2386((s)+(a), b, 4, 1)
#else
#define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
#define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
#define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
@@ -97,6 +125,7 @@
#define do_mmut_wl(s, a, b) \
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
do_mmutranslate((s) + (a), b, 4, 1)
#endif
int checkio(uint32_t port, int mask);
@@ -191,6 +220,23 @@ int checkio(uint32_t port, int mask);
return 1; \
}
#ifdef OPS_286_386
/* TODO: Introduce functions to read exec. */
static __inline uint8_t fastreadb(uint32_t a)
{
return readmembl(a);
}
static __inline uint16_t fastreadw(uint32_t a)
{
return readmemwl(a);
}
static __inline uint32_t fastreadl(uint32_t a)
{
return readmemll(a);
}
#else
static __inline uint8_t
fastreadb(uint32_t a)
{
@@ -266,6 +312,7 @@ fastreadl(uint32_t a)
val |= (fastreadw(a + 2) << 16);
return val;
}
#endif
static __inline void *
get_ram_ptr(uint32_t a)
@@ -288,6 +335,37 @@ get_ram_ptr(uint32_t a)
extern int opcode_length[256];
#ifdef OPS_286_386
static __inline uint16_t
fastreadw_fetch(uint32_t a)
{
uint16_t val;
if ((a & 0xFFF) > 0xFFE) {
val = fastreadb(a);
if (opcode_length[val & 0xff] > 1)
val |= (fastreadb(a + 1) << 8);
return val;
}
return readmemwl(a);
}
static __inline uint32_t
fastreadl_fetch(uint32_t a)
{
uint32_t val;
if ((a & 0xFFF) > 0xFFC) {
val = fastreadw_fetch(a);
if (opcode_length[val & 0xff] > 2)
val |= (fastreadw(a + 2) << 16);
return val;
}
return readmemll(a);
}
#else
static __inline uint16_t
fastreadw_fetch(uint32_t a)
{
@@ -342,6 +420,7 @@ fastreadl_fetch(uint32_t a)
val |= (fastreadw(a + 2) << 16);
return val;
}
#endif
static __inline uint8_t
getbyte(void)
@@ -371,6 +450,67 @@ getquad(void)
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
}
#ifdef OPS_286_386
static __inline uint8_t geteab()
{
if (cpu_mod == 3)
return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm&3].b.l;
return readmemb(easeg, cpu_state.eaaddr);
}
static __inline uint16_t geteaw()
{
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].w;
return readmemw(easeg, cpu_state.eaaddr);
}
static __inline uint32_t geteal()
{
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].l;
return readmeml(easeg, cpu_state.eaaddr);
}
static __inline uint64_t geteaq()
{
return readmemq(easeg, cpu_state.eaaddr);
}
static __inline uint8_t geteab_mem()
{
return readmemb(easeg,cpu_state.eaaddr);
}
static __inline uint16_t geteaw_mem()
{
return readmemw(easeg,cpu_state.eaaddr);
}
static __inline uint32_t geteal_mem()
{
return readmeml(easeg,cpu_state.eaaddr);
}
static __inline int seteaq_cwc(void)
{
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
return 0;
}
static __inline void seteaq(uint64_t v)
{
if (seteaq_cwc())
return;
writememql(easeg + cpu_state.eaaddr, v);
}
#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); writemembl_2386(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v
#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); writememwl_2386(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v
#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememll_2386(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v
#define seteab_mem(v) writemembl_2386(easeg+cpu_state.eaaddr,v);
#define seteaw_mem(v) writememwl_2386(easeg+cpu_state.eaaddr,v);
#define seteal_mem(v) writememll_2386(easeg+cpu_state.eaaddr,v);
#else
static __inline uint8_t
geteab(void)
{
@@ -489,6 +629,7 @@ seteaq(uint64_t v)
*eal_w = v; \
else \
writememll(easeg + cpu_state.eaaddr, v);
#endif
#define getbytef() \
((uint8_t) (fetchdat)); \