cpu.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. #ifndef VDOS_CPU_H
  2. #define VDOS_CPU_H
  3. #ifndef VDOS_H
  4. #include "vDos.h"
  5. #endif
  6. #ifndef VDOS_REGS_H
  7. #include "regs.h"
  8. #endif
  9. #include "mem.h"
  10. // CPU Cycle Timing
  11. extern Bit32s CPU_Cycles;
  12. void clearFetchCache(void);
  13. void testclearFetchCache(void);
  14. // Some common Defines
  15. // A CPU Handler
  16. typedef Bits (CPU_Decoder)(void);
  17. extern CPU_Decoder * cpudecoder;
  18. Bits CPU_Core_Normal_Run(void);
  19. Bits CPU_Core_Normal_Trap_Run(void);
  20. // CPU Stuff
  21. extern Bit16u parity_lookup[256];
  22. bool CPU_LLDT(Bitu selector);
  23. bool CPU_LTR(Bitu selector);
  24. void CPU_LIDT(Bitu limit,Bitu base);
  25. void CPU_LGDT(Bitu limit,Bitu base);
  26. Bitu CPU_STR(void);
  27. Bitu CPU_SLDT(void);
  28. Bitu CPU_SIDT_base(void);
  29. Bitu CPU_SIDT_limit(void);
  30. Bitu CPU_SGDT_base(void);
  31. Bitu CPU_SGDT_limit(void);
  32. void CPU_ARPL(Bitu & dest_sel,Bitu src_sel);
  33. void CPU_LAR(Bitu selector, Bitu & ar);
  34. void CPU_LSL(Bitu selector, Bitu & limit);
  35. void CPU_SET_CRX(Bitu cr,Bitu value);
  36. bool CPU_WRITE_CRX(Bitu cr,Bitu value);
  37. Bitu CPU_GET_CRX(Bitu cr);
  38. bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue);
  39. bool CPU_WRITE_DRX(Bitu dr,Bitu value);
  40. bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue);
  41. bool CPU_WRITE_TRX(Bitu dr,Bitu value);
  42. bool CPU_READ_TRX(Bitu dr,Bit32u & retvalue);
  43. Bitu CPU_SMSW(void);
  44. bool CPU_LMSW(Bitu word);
  45. void CPU_VERR(Bitu selector);
  46. void CPU_VERW(Bitu selector);
  47. void CPU_JMP(bool use32, Bitu selector, Bitu offset);
  48. void CPU_CALL(bool use32, Bitu selector, Bitu offset, Bitu oldeip);
  49. void CPU_RET(bool use32, Bitu bytes);
  50. void CPU_IRET(bool use32);
  51. void CPU_HLT(Bitu oldeip);
  52. void CPU_POPF(Bitu use32);
  53. bool CPU_pCLI(void);
  54. bool CPU_pSTI(void);
  55. bool CPU_IO_Exception(Bitu port,Bitu size);
  56. void CPU_RunException(void);
  57. void CPU_ENTER(bool use32,Bitu bytes,Bitu level);
  58. #define CPU_INT_SOFTWARE 0x1
  59. #define CPU_INT_EXCEPTION 0x2
  60. #define CPU_INT_HAS_ERROR 0x4
  61. #define CPU_INT_NOIOPLCHECK 0x8
  62. void CPU_Interrupt(Bitu num,Bitu type, Bitu oldeip);
  63. static void CPU_HW_Interrupt(Bitu num)
  64. {
  65. CPU_Interrupt(num, 0, reg_eip);
  66. }
  67. static void CPU_SW_Interrupt(Bitu num, Bitu oldeip)
  68. {
  69. CPU_Interrupt(num, CPU_INT_SOFTWARE, oldeip);
  70. }
  71. static void CPU_SW_Interrupt_NoIOPLCheck(Bitu num, Bitu oldeip)
  72. {
  73. CPU_Interrupt(num,CPU_INT_SOFTWARE|CPU_INT_NOIOPLCHECK, oldeip);
  74. }
  75. bool CPU_PrepareException(Bitu which, Bitu error);
  76. void CPU_Exception(Bitu which, Bitu error=0);
  77. bool CPU_SetSegGeneral(SegNames seg, Bitu value);
  78. bool CPU_Pop16Seg(SegNames seg);
  79. bool CPU_Pop32Seg(SegNames seg);
  80. Bitu CPU_Pop16(void);
  81. Bitu CPU_Pop32(void);
  82. void CPU_Push16(Bitu value);
  83. void CPU_Push32(Bitu value);
  84. void CPU_SetFlags(Bitu word,Bitu mask);
  85. #define EXCEPTION_UD 6
  86. #define EXCEPTION_TS 10
  87. #define EXCEPTION_NP 11
  88. #define EXCEPTION_SS 12
  89. #define EXCEPTION_GP 13
  90. #define EXCEPTION_PF 14
  91. #define CR0_PROTECTION 0x00000001
  92. #define CR0_MONITORPROCESSOR 0x00000002
  93. #define CR0_FPUEMULATION 0x00000004
  94. #define CR0_TASKSWITCH 0x00000008
  95. #define CR0_FPUPRESENT 0x00000010
  96. #define CR0_WRITEPROTECT 0x00010000
  97. #define CR0_PAGING 0x80000000
  98. // *********************************************************************
  99. // Descriptor
  100. // *********************************************************************
  101. #define DESC_INVALID 0x00
  102. #define DESC_286_TSS_A 0x01
  103. #define DESC_LDT 0x02
  104. #define DESC_286_TSS_B 0x03
  105. #define DESC_286_CALL_GATE 0x04
  106. #define DESC_TASK_GATE 0x05
  107. #define DESC_286_INT_GATE 0x06
  108. #define DESC_286_TRAP_GATE 0x07
  109. #define DESC_386_TSS_A 0x09
  110. #define DESC_386_TSS_B 0x0b
  111. #define DESC_386_CALL_GATE 0x0c
  112. #define DESC_386_INT_GATE 0x0e
  113. #define DESC_386_TRAP_GATE 0x0f
  114. // EU/ED Expand UP/DOWN RO/RW Read Only/Read Write NA/A Accessed
  115. #define DESC_DATA_EU_RO_NA 0x10
  116. #define DESC_DATA_EU_RO_A 0x11
  117. #define DESC_DATA_EU_RW_NA 0x12
  118. #define DESC_DATA_EU_RW_A 0x13
  119. #define DESC_DATA_ED_RO_NA 0x14
  120. #define DESC_DATA_ED_RO_A 0x15
  121. #define DESC_DATA_ED_RW_NA 0x16
  122. #define DESC_DATA_ED_RW_A 0x17
  123. // N/R Readable NC/C Confirming A/NA Accessed
  124. #define DESC_CODE_N_NC_A 0x18
  125. #define DESC_CODE_N_NC_NA 0x19
  126. #define DESC_CODE_R_NC_A 0x1a
  127. #define DESC_CODE_R_NC_NA 0x1b
  128. #define DESC_CODE_N_C_A 0x1c
  129. #define DESC_CODE_N_C_NA 0x1d
  130. #define DESC_CODE_R_C_A 0x1e
  131. #define DESC_CODE_R_C_NA 0x1f
  132. #ifdef _MSC_VER
  133. #pragma pack (1)
  134. #endif
  135. struct S_Descriptor {
  136. Bit32u limit_0_15 :16;
  137. Bit32u base_0_15 :16;
  138. Bit32u base_16_23 :8;
  139. Bit32u type :5;
  140. Bit32u dpl :2;
  141. Bit32u p :1;
  142. Bit32u limit_16_19 :4;
  143. Bit32u avl :1;
  144. Bit32u r :1;
  145. Bit32u big :1;
  146. Bit32u g :1;
  147. Bit32u base_24_31 :8;
  148. };
  149. struct G_Descriptor {
  150. Bit32u offset_0_15 :16;
  151. Bit32u selector :16;
  152. Bit32u paramcount :5;
  153. Bit32u reserved :3;
  154. Bit32u type :5;
  155. Bit32u dpl :2;
  156. Bit32u p :1;
  157. Bit32u offset_16_31 :16;
  158. };
  159. struct TSS_16 {
  160. Bit16u back; /* Back link to other task */
  161. Bit16u sp0; /* The CK stack pointer */
  162. Bit16u ss0; /* The CK stack selector */
  163. Bit16u sp1; /* The parent KL stack pointer */
  164. Bit16u ss1; /* The parent KL stack selector */
  165. Bit16u sp2; /* Unused */
  166. Bit16u ss2; /* Unused */
  167. Bit16u ip; /* The instruction pointer */
  168. Bit16u flags; /* The flags */
  169. Bit16u ax, cx, dx, bx; /* The general purpose registers */
  170. Bit16u sp, bp, si, di; /* The special purpose registers */
  171. Bit16u es; /* The extra selector */
  172. Bit16u cs; /* The code selector */
  173. Bit16u ss; /* The application stack selector */
  174. Bit16u ds; /* The data selector */
  175. Bit16u ldt; /* The local descriptor table */
  176. };
  177. struct TSS_32 {
  178. Bit32u back; /* Back link to other task */
  179. Bit32u esp0; /* The CK stack pointer */
  180. Bit32u ss0; /* The CK stack selector */
  181. Bit32u esp1; /* The parent KL stack pointer */
  182. Bit32u ss1; /* The parent KL stack selector */
  183. Bit32u esp2; /* Unused */
  184. Bit32u ss2; /* Unused */
  185. Bit32u cr3; /* The page directory pointer */
  186. Bit32u eip; /* The instruction pointer */
  187. Bit32u eflags; /* The flags */
  188. Bit32u eax, ecx, edx, ebx; /* The general purpose registers */
  189. Bit32u esp, ebp, esi, edi; /* The special purpose registers */
  190. Bit32u es; /* The extra selector */
  191. Bit32u cs; /* The code selector */
  192. Bit32u ss; /* The application stack selector */
  193. Bit32u ds; /* The data selector */
  194. Bit32u fs; /* And another extra selector */
  195. Bit32u gs; /* ... and another one */
  196. Bit32u ldt; /* The local descriptor table */
  197. };
  198. #ifdef _MSC_VER
  199. #pragma pack()
  200. #endif
  201. class Descriptor
  202. {
  203. public:
  204. Descriptor()
  205. {
  206. saved.fill[0] = saved.fill[1] = 0;
  207. }
  208. void Load(PhysPt address);
  209. void Save(PhysPt address);
  210. PhysPt GetBase(void)
  211. {
  212. return (saved.seg.base_24_31<<24) | (saved.seg.base_16_23<<16) | saved.seg.base_0_15;
  213. }
  214. Bitu GetLimit(void)
  215. {
  216. Bitu limit = (saved.seg.limit_16_19<<16) | saved.seg.limit_0_15;
  217. if (saved.seg.g)
  218. return (limit<<12) | 0xFFF;
  219. return limit;
  220. }
  221. Bitu GetOffset(void)
  222. {
  223. return (saved.gate.offset_16_31 << 16) | saved.gate.offset_0_15;
  224. }
  225. Bitu GetSelector(void)
  226. {
  227. return saved.gate.selector;
  228. }
  229. Bitu Type(void)
  230. {
  231. return saved.seg.type;
  232. }
  233. Bitu DPL(void)
  234. {
  235. return saved.seg.dpl;
  236. }
  237. Bitu Big(void)
  238. {
  239. return saved.seg.big;
  240. }
  241. public:
  242. union {
  243. S_Descriptor seg;
  244. G_Descriptor gate;
  245. Bit32u fill[2];
  246. } saved;
  247. };
  248. class DescriptorTable
  249. {
  250. public:
  251. PhysPt GetBase(void)
  252. {
  253. return table_base;
  254. }
  255. Bitu GetLimit(void)
  256. {
  257. return table_limit;
  258. }
  259. void SetBase(PhysPt _base)
  260. {
  261. table_base = _base;
  262. }
  263. void SetLimit(Bitu _limit)
  264. {
  265. table_limit = _limit;
  266. }
  267. bool GetDescriptor(Bitu selector, Descriptor& desc)
  268. {
  269. selector&=~7;
  270. if (selector >= table_limit)
  271. return false;
  272. desc.Load(table_base+(selector));
  273. return true;
  274. }
  275. protected:
  276. PhysPt table_base;
  277. Bitu table_limit;
  278. };
  279. class GDTDescriptorTable : public DescriptorTable
  280. {
  281. public:
  282. bool GetDescriptor(Bitu selector, Descriptor& desc)
  283. {
  284. Bitu address = selector & ~7;
  285. if (selector & 4)
  286. {
  287. if (address >= ldt_limit)
  288. return false;
  289. desc.Load(ldt_base+address);
  290. return true;
  291. }
  292. else
  293. {
  294. if (address >= table_limit)
  295. return false;
  296. desc.Load(table_base+address);
  297. return true;
  298. }
  299. }
  300. bool SetDescriptor(Bitu selector, Descriptor& desc)
  301. {
  302. Bitu address = selector & ~7;
  303. if (selector & 4)
  304. {
  305. if (address >= ldt_limit)
  306. return false;
  307. desc.Save(ldt_base+address);
  308. return true;
  309. }
  310. else
  311. {
  312. if (address >= table_limit)
  313. return false;
  314. desc.Save(table_base+address);
  315. return true;
  316. }
  317. }
  318. Bitu SLDT(void)
  319. {
  320. return ldt_value;
  321. }
  322. bool LLDT(Bitu value)
  323. {
  324. if ((value&0xfffc) == 0)
  325. {
  326. ldt_value = 0;
  327. ldt_base = 0;
  328. ldt_limit = 0;
  329. return true;
  330. }
  331. Descriptor desc;
  332. if (!GetDescriptor(value, desc))
  333. return !CPU_PrepareException(EXCEPTION_GP, value);
  334. if (desc.Type() != DESC_LDT)
  335. return !CPU_PrepareException(EXCEPTION_GP, value);
  336. if (!desc.saved.seg.p)
  337. return !CPU_PrepareException(EXCEPTION_NP, value);
  338. ldt_base = desc.GetBase();
  339. ldt_limit = desc.GetLimit();
  340. ldt_value = value;
  341. return true;
  342. }
  343. private:
  344. PhysPt ldt_base;
  345. Bitu ldt_limit;
  346. Bitu ldt_value;
  347. };
  348. class TSS_Descriptor : public Descriptor
  349. {
  350. public:
  351. Bitu IsBusy(void)
  352. {
  353. return saved.seg.type & 2;
  354. }
  355. Bitu Is386(void)
  356. {
  357. return saved.seg.type & 8;
  358. }
  359. void SetBusy(bool busy)
  360. {
  361. if (busy)
  362. saved.seg.type |= 2;
  363. else
  364. saved.seg.type &= ~2;
  365. }
  366. };
  367. struct CPUBlock {
  368. Bitu cpl; // Current Privilege
  369. Bitu cr0;
  370. bool pmode; // Is Protected mode enabled
  371. GDTDescriptorTable gdt;
  372. DescriptorTable idt;
  373. struct {
  374. Bitu mask, notmask;
  375. bool big;
  376. } stack;
  377. struct {
  378. bool big;
  379. } code;
  380. struct {
  381. Bitu cs, eip;
  382. CPU_Decoder * old_decoder;
  383. } hlt;
  384. struct {
  385. Bitu which, error;
  386. } exception;
  387. Bits direction;
  388. bool trap_skip;
  389. Bit32u drx[8];
  390. Bit32u trx[8];
  391. };
  392. extern CPUBlock cpu;
  393. #endif