First post, by superfury
I currently have the registers implemented as follows:
#include "headers/packed.h" //Packed type!
typedef struct PACKED //The registers!
{
//Info: with union, first low data then high data!
union
{
struct
{
#ifdef IS_BIG_ENDIAN
word EAXDUMMY;
#endif
struct
{
union
{
word AX;
struct
{
#ifndef IS_BIG_ENDIAN
byte AL;
byte AH;
#else
byte AH;
byte AL;
#endif
};
};
};
#ifndef IS_BIG_ENDIAN
word EAXDUMMY;
#endif
};
uint_32 EAX;
};
union
{
struct
{
#ifdef IS_BIG_ENDIAN
word EBXDUMMY;
#endif
struct
{
union
{
word BX;
struct
{
#ifndef IS_BIG_ENDIAN
byte BL;
byte BH;
#else
byte BH;
byte BL;
#endif
};
};
};
#ifndef IS_BIG_ENDIAN
word EBXDUMMY;
#endif
};
uint_32 EBX;
};
union
{
struct
{
#ifdef IS_BIG_ENDIAN
word ECXDUMMY;
#endif
struct
{
union
{
word CX;
struct
{
#ifndef IS_BIG_ENDIAN
byte CL;
byte CH;
#else
byte CH;
byte CL;
#endif
};
};
};
#ifndef IS_BIG_ENDIAN
word ECXDUMMY;
#endif
};
uint_32 ECX;
};
union
{
struct
{
#ifdef IS_BIG_ENDIAN
word EDXDUMMY;
#endif
struct
{
union
{
word DX;
struct
{
#ifndef IS_BIG_ENDIAN
byte DL;
byte DH;
#else
byte DH;
byte DL;
#endif
};
};
};
#ifndef IS_BIG_ENDIAN
word EDXDUMMY;
#endif
};
uint_32 EDX;
};
union
{
uint_32 ESP; //ESP!
struct
{
#ifdef IS_BIG_ENDIAN
word ESPDUMMY;
#endif
word SP; //Stack pointer
#ifndef IS_BIG_ENDIAN
word ESPDUMMY; //Dummy!
#endif
};
};
union
{
uint_32 EBP; //EBP!
struct
{
#ifdef IS_BIG_ENDIAN
word EBPDUMMY;
#endif
word BP; //Base pointer
#ifndef IS_BIG_ENDIAN
word EBPDUMMY; //Dummy!
#endif
};
};
union
{
uint_32 ESI; //ESI
struct
{
#ifdef IS_BIG_ENDIAN
word ESIDUMMY;
#endif
word SI; //Source index
#ifndef IS_BIG_ENDIAN
word ESIDUMMY; //Dummy!
#endif
};
};
union
{
uint_32 EDI; //EDI
struct
{
#ifdef IS_BIG_ENDIAN
word EDIDUMMY;
#endif
word DI; //Destination index
#ifndef IS_BIG_ENDIAN
word EDIDUMMY; //Dummy!
#endif
};
};
union
{
uint_32 EIP; //EIP
struct
{
#ifdef IS_BIG_ENDIAN
word EIPDUMMY;
#endif
word IP; //Instruction pointer; CS:IP=Current instruction; Reset at load of program
#ifndef IS_BIG_ENDIAN
word EIPDUMMY; //Dummy!
#endif
};
};
word CS; //Code segment: start of program code; used by instructions and jumps.
word DS; //Data segment: beginning of data storage section of memory; used by data manipulation
word ES; //Extra segment: used for operations where data is transferred from one segment to another
word SS; //Stack segment: stack segment
word FS; //???
word GS; //???
union
{
struct
{
#ifdef IS_BIG_ENDIAN
word EFLAGSDUMMY;
#endif
word FLAGS; //8086 Flags!
#ifndef IS_BIG_ENDIAN
word EFLAGSDUMMY; //Dummy!
#endif
};
uint_32 EFLAGS;
};
struct
{
//Tables:
DTR_PTR GDTR; //GDTR pointer (48-bits) Global Descriptor Table Register
DTR_PTR IDTR; //IDTR pointer (48-bits) Interrupt Descriptor Table Register
word LDTR; //LDTR pointer (16-bits) Local Descriptor Table Register (points to an index in the GDT)
word TR; //TR (16-bits) Talk Register: currently executing task (points to an index in the GDT)
union
{
uint_32 CR[8];
struct
{
uint_32 CR0;
uint_32 CR1; //Unused!
uint_32 CR2; //Page Fault Linear Address
uint_32 CR3;
uint_32 CR4; //4 unused CRs until Pentium!
uint_32 CR5;
uint_32 CR6;
uint_32 CR7;
}; //CR0-3!
}; //CR0-3!
union
{
uint_32 DR[8]; //All debugger registers! index 4=>6 and index 5=>7!
struct
{
uint_32 DR0;
uint_32 DR1;
uint_32 DR2;
uint_32 DR3;
uint_32 DR4; //Existant on Pentium+ only! Redirected to DR6 on 386+, except when enabled using CR4.
uint_32 noDRregister; //Not defined: DR5 on Pentium! Redirected to DR7 on 386+(when not disabled using CR4).
uint_32 DR6; //DR4->6 on 386+, DR6 on Pentium+!
uint_32 DR7; //DR5->7 on 386+, DR7 on Pentium+!
};
}; //DR0-7; 4=6&5=7!
union
{
uint_32 TRX[8]; //All debugger registers! index 4=>6 and index 5=>7!
struct
{
uint_32 TR0;
uint_32 TR1;
uint_32 TR2;
uint_32 TR3;
uint_32 TR4;
uint_32 TR5;
uint_32 TR6;
uint_32 TR7;
};
}; //DR0-7; 4=6&5=7!
}; //Special registers!
} CPU_registers; //Registers
#include "headers/endpacked.h" //End of packed type!
The issue with this is that with the latest (GCC 9) compiler, it complains about pretty much all of those when storing a pointer or using a pointer to it?
warning: taking address of packed member of 'struct <anonymous>' may result in an unaligned pointer value [-Waddress-of-packed-member]
Is there any way to fix this without having to change all my code in incompatible ways? How should I implement this in a cross-platform cross-compiler way?
Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io