Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /********************************************************************************/
  2. /*                                                                              */
  3. /* CZ80 (Z80 CPU emulator) version 0.91                                          */
  4. /* Compiled with Dev-C++                                                        */
  5. /* Copyright 2004-2005 Stephane Dallongeville                                   */
  6. /*                                                                              */
  7. /********************************************************************************/
  8.  
  9. //#ifdef CPUZ80_CZ80_CORE
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stddef.h>
  14. #include "cz80.h"
  15.  
  16.  
  17. // include macro file
  18. //////////////////////
  19.  
  20. #include "cz80.inc"
  21.  
  22. // shared global variable
  23. //////////////////////////
  24.  
  25. cz80_struc CZ80;
  26.  
  27. static uint8_t SZXY[256];            // zero and sign flags
  28. static uint8_t SZXYP[256];           // zero, sign and parity flags
  29. static uint8_t SZXY_BIT[256];        // zero, sign and parity/overflow (=zero) flags for BIT opcode
  30. static uint8_t SZXYHV_inc[256];      // zero, sign, half carry and overflow flags INC R8
  31. static uint8_t SZXYHV_dec[256];      // zero, sign, half carry and overflow flags DEC R8
  32.  
  33. // prototype
  34. /////////////
  35.  
  36. uint8_t FASTCALL Cz80_Read_Dummy(void *ctx, const uint16_t adr);
  37. void FASTCALL Cz80_Write_Dummy(void *ctx, const uint16_t adr, uint8_t data);
  38.  
  39. uint8_t FASTCALL Cz80_Interrupt_Ack_Dummy(void *ctx, uint8_t param);
  40. void FASTCALL Cz80_RetI_Dummy(void *ctx);
  41.  
  42. // core main functions
  43. ///////////////////////
  44.  
  45. void Cz80_Init(cz80_struc *cpu)
  46. {
  47.     unsigned int i, j, p;
  48.  
  49.     memset(cpu, 0, sizeof(cz80_struc));
  50.    
  51.     // flags tables initialisation
  52.     for (i = 0; i < 256; i++)
  53.     {
  54.         SZXY[i] = i & (CZ80_SF | CZ80_YF | CZ80_XF);
  55.         if (!i) SZXY[i] |= CZ80_ZF;
  56.  
  57.         SZXY_BIT[i] = i & (CZ80_SF | CZ80_YF | CZ80_XF);
  58.         if (!i) SZXY_BIT[i] |= CZ80_ZF | CZ80_PF;
  59.        
  60.         for (j = 0, p = 0; j < 8; j++) if (i & (1 << j)) p++;
  61.         SZXYP[i] = SZXY[i];
  62.         if (!(p & 1)) SZXYP[i] |= CZ80_PF;
  63.        
  64.         SZXYHV_inc[i] = SZXY[i];
  65.         if(i == 0x80) SZXYHV_inc[i] |= CZ80_VF;
  66.         if((i & 0x0F) == 0x00) SZXYHV_inc[i] |= CZ80_HF;
  67.        
  68.         SZXYHV_dec[i] = SZXY[i] | CZ80_NF;
  69.         if (i == 0x7F) SZXYHV_dec[i] |= CZ80_VF;
  70.         if ((i & 0x0F) == 0x0F) SZXYHV_dec[i] |= CZ80_HF;
  71.     }
  72.  
  73.     Cz80_Set_Fetch(cpu, 0x0000, 0xFFFF, NULL);
  74.  
  75.     Cz80_Set_ReadB(cpu, Cz80_Read_Dummy);
  76.     Cz80_Set_WriteB(cpu, Cz80_Write_Dummy);
  77.    
  78.     cpu->Interrupt_Ack = Cz80_Interrupt_Ack_Dummy;
  79.     cpu->RetI = Cz80_RetI_Dummy;
  80. }
  81.  
  82. uint8_t Cz80_Reset(cz80_struc *cpu)
  83. {
  84.     cz80_struc *CPU = cpu;
  85.    
  86.     memset(CPU, 0, offsetof(cz80_struc, CycleSup));
  87.  
  88.     Cz80_Set_PC(CPU, 0);
  89.     zIX = 0xFFFF;
  90.     zIY = 0xFFFF;
  91. #if CZ80_DEBUG
  92.     zF = CZ80_ZF;
  93. #else
  94.     zSP = 0xFFFF;
  95.     zFA = 0xFFFF;
  96. #endif
  97.  
  98.     return CPU->Status;
  99. }
  100.  
  101. /////////////////////////////////
  102.  
  103. #include "cz80exec.inc"
  104.  
  105. /////////////////////////////////
  106.  
  107. void FASTCALL Cz80_Set_IRQ(cz80_struc *cpu, uint8_t vector)
  108. {
  109.     cpu->IntVect = vector;
  110.     cpu->Status |= CZ80_HAS_INT;
  111.     cpu->CycleSup = cpu->CycleIO;
  112.     cpu->CycleIO = 0;
  113. }
  114.  
  115. void FASTCALL Cz80_Set_NMI(cz80_struc *cpu)
  116. {
  117.     cpu->Status |= CZ80_HAS_NMI;
  118.     cpu->CycleSup = cpu->CycleIO;
  119.     cpu->CycleIO = 0;
  120. }
  121.  
  122. void FASTCALL Cz80_Clear_IRQ(cz80_struc *cpu)
  123. {
  124.     cpu->Status &= ~CZ80_HAS_INT;
  125. }
  126.  
  127. void FASTCALL Cz80_Clear_NMI(cz80_struc *cpu)
  128. {
  129.     cpu->Status &= ~CZ80_HAS_NMI;
  130. }
  131.  
  132. /////////////////////////////////
  133.  
  134. int FASTCALL Cz80_Get_CycleToDo(cz80_struc *cpu)
  135. {
  136.     if (!(cpu->Status & CZ80_RUNNING)) return -1;
  137.  
  138.     return cpu->CycleToDo;
  139. }
  140.  
  141. int FASTCALL Cz80_Get_CycleRemaining(cz80_struc *cpu)
  142. {
  143.     if (!(cpu->Status & CZ80_RUNNING)) return -1;
  144.  
  145.     return (cpu->CycleIO + cpu->CycleSup);
  146. }
  147.  
  148. int FASTCALL Cz80_Get_CycleDone(cz80_struc *cpu)
  149. {
  150.     if (!(cpu->Status & CZ80_RUNNING)) return -1;
  151.  
  152.     return (cpu->CycleToDo - (cpu->CycleIO + cpu->CycleSup));
  153. }
  154.  
  155. void FASTCALL Cz80_Release_Cycle(cz80_struc *cpu)
  156. {
  157.     if (cpu->Status & CZ80_RUNNING) cpu->CycleIO = cpu->CycleSup = 0;
  158. }
  159.  
  160. void FASTCALL Cz80_Add_Cycle(cz80_struc *cpu, unsigned int cycle)
  161. {
  162.     if (cpu->Status & CZ80_RUNNING) cpu->CycleIO -= cycle;
  163. }
  164.  
  165. // Read / Write dummy functions
  166. ////////////////////////////////
  167.  
  168. uint8_t FASTCALL Cz80_Read_Dummy(void *ctx, const uint16_t adr)
  169. {
  170.     (void)ctx;
  171.     (void)adr;
  172.     return 0;
  173. }
  174.  
  175. void FASTCALL Cz80_Write_Dummy(void *ctx, const uint16_t adr, uint8_t data)
  176. {
  177.         (void)ctx;
  178.         (void)adr;
  179.         (void)data;
  180. }
  181.  
  182. uint8_t FASTCALL Cz80_Interrupt_Ack_Dummy(void *ctx, uint8_t param)
  183. {
  184.     (void)ctx;
  185.     (void)param;
  186.  
  187.     // return vector
  188.     return -1;
  189. }
  190.  
  191. void FASTCALL Cz80_RetI_Dummy(void *ctx)
  192. {
  193.     (void)ctx;
  194. }
  195.  
  196.  
  197. // Read / Write core functions
  198. ///////////////////////////////
  199.  
  200. void Cz80_Set_Ctx(cz80_struc *cpu, void *ctx)
  201. {
  202.     cpu->ctx = ctx;
  203. }
  204.  
  205. uint8_t Cz80_Read_Byte(cz80_struc *cpu, uint16_t adr)
  206. {
  207.     return cpu->Read_Byte(cpu->ctx, adr);
  208. }
  209.  
  210. uint16_t Cz80_Read_Word(cz80_struc *cpu, uint16_t adr)
  211. {
  212. #if CZ80_USE_WORD_HANDLER
  213.     return cpu->Read_Word(cpu->ctx, adr);
  214. #elif CZ80_LITTLE_ENDIAN
  215.     return (cpu->Read_Byte(cpu->ctx, adr) |
  216.             (cpu->Read_Byte(cpu->ctx, (adr + 1)) << 8));
  217. #else
  218.     return ((cpu->Read_Byte(cpu->ctx, adr) << 8) |
  219.             cpu->Read_Byte(cpu->ctx, (adr + 1)));
  220. #endif
  221. }
  222.  
  223. void Cz80_Write_Byte(cz80_struc *cpu, uint16_t adr, uint8_t data)
  224. {
  225.     cpu->Write_Byte(cpu->ctx, adr, data);
  226. }
  227.  
  228. void Cz80_Write_Word(cz80_struc *cpu, uint16_t adr, uint16_t data)
  229. {
  230. #if CZ80_USE_WORD_HANDLER
  231.     cpu->Write_Word(cpu->ctx, adr, data);
  232. #elif CZ80_LITTLE_ENDIAN
  233.     cpu->Write_Byte(cpu->ctx, adr, (data & 0xFF));
  234.     cpu->Write_Byte(cpu->ctx, (adr + 1), (data >> 8));
  235. #else
  236.     cpu->Write_Byte(cpu->ctx, adr, (data >> 8));
  237.     cpu->Write_Byte(cpu->ctx, (adr + 1), (data & 0xFF));
  238. #endif
  239. }
  240.  
  241. // setting core functions
  242. //////////////////////////
  243.  
  244. void Cz80_Set_Fetch(cz80_struc *cpu, uint16_t low_adr, uint16_t high_adr, void *fetch_adr)
  245. {
  246.     uint16_t i, j;
  247.  
  248.     i = low_adr >> CZ80_FETCH_SFT;
  249.     j = high_adr >> CZ80_FETCH_SFT;
  250.     fetch_adr = (void *)((uintptr_t)fetch_adr - (i << CZ80_FETCH_SFT));
  251.     while (i <= j) cpu->Fetch[i++] = (uint8_t*) fetch_adr;
  252. }
  253.  
  254. void Cz80_Set_ReadB(cz80_struc *cpu, CZ80_READ *Func)
  255. {
  256.     cpu->Read_Byte = Func;
  257. }
  258.  
  259. void Cz80_Set_WriteB(cz80_struc *cpu, CZ80_WRITE *Func)
  260. {
  261.     cpu->Write_Byte = Func;
  262. }
  263.  
  264. #if CZ80_USE_WORD_HANDLER
  265. void Cz80_Set_ReadW(cz80_struc *cpu, CZ80_READ_WORD *Func)
  266. {
  267.     cpu->Read_Word = Func;
  268. }
  269.  
  270. void Cz80_Set_WriteW(cz80_struc *cpu, CZ80_WRITE_WORD *Func)
  271. {
  272.     cpu->Write_Word = Func;
  273. }
  274. #endif
  275.  
  276. void Cz80_Set_INPort(cz80_struc *cpu, CZ80_READ *Func)
  277. {
  278.     cpu->IN_Port = Func;
  279. }
  280.  
  281. void Cz80_Set_OUTPort(cz80_struc *cpu, CZ80_WRITE *Func)
  282. {
  283.     cpu->OUT_Port = Func;
  284. }
  285.  
  286. void Cz80_Set_IRQ_Callback(cz80_struc *cpu, CZ80_INT_CALLBACK *Func)
  287. {
  288.     cpu->Interrupt_Ack = Func;
  289. }
  290.  
  291. void Cz80_Set_RETI_Callback(cz80_struc *cpu, CZ80_RETI_CALLBACK *Func)
  292. {
  293.     cpu->RetI = Func;
  294. }
  295.  
  296. // externals main functions
  297. ////////////////////////////
  298.  
  299. uint16_t FASTCALL Cz80_Get_BC(cz80_struc *cpu)
  300. {
  301.     cz80_struc *CPU = cpu;
  302.     return zBC;
  303. }
  304.  
  305. uint16_t FASTCALL Cz80_Get_DE(cz80_struc *cpu)
  306. {
  307.     cz80_struc *CPU = cpu;
  308.     return zDE;
  309. }
  310.  
  311. uint16_t FASTCALL Cz80_Get_HL(cz80_struc *cpu)
  312. {
  313.     cz80_struc *CPU = cpu;
  314.     return zHL;
  315. }
  316.  
  317. uint16_t FASTCALL Cz80_Get_AF(cz80_struc *cpu)
  318. {
  319.     cz80_struc *CPU = cpu;
  320.     return (zF | (zA << 8));
  321. }
  322.  
  323. uint16_t FASTCALL Cz80_Get_BC2(cz80_struc *cpu)
  324. {
  325.     cz80_struc *CPU = cpu;
  326.     return zBC2;
  327. }
  328.  
  329. uint16_t FASTCALL Cz80_Get_DE2(cz80_struc *cpu)
  330. {
  331.     cz80_struc *CPU = cpu;
  332.     return zDE2;
  333. }
  334.  
  335. uint16_t FASTCALL Cz80_Get_HL2(cz80_struc *cpu)
  336. {
  337.     cz80_struc *CPU = cpu;
  338.     return zHL2;
  339. }
  340.  
  341. uint16_t FASTCALL Cz80_Get_AF2(cz80_struc *cpu)
  342. {
  343.     cz80_struc *CPU = cpu;
  344.     return (zF2 | (zA2 << 8));
  345. }
  346.  
  347. uint16_t FASTCALL Cz80_Get_IX(cz80_struc *cpu)
  348. {
  349.     cz80_struc *CPU = cpu;
  350.     return zIX;
  351. }
  352.  
  353. uint16_t FASTCALL Cz80_Get_IY(cz80_struc *cpu)
  354. {
  355.     cz80_struc *CPU = cpu;
  356.     return zIY;
  357. }
  358.  
  359. uint16_t FASTCALL Cz80_Get_SP(cz80_struc *cpu)
  360. {
  361.     cz80_struc *CPU = cpu;
  362.     return zSP;
  363. }
  364.  
  365. uint16_t FASTCALL Cz80_Get_PC(cz80_struc *cpu)
  366. {
  367.     cz80_struc *CPU = cpu;
  368.     return CPU->PC;
  369. }
  370.  
  371. uint16_t FASTCALL Cz80_Get_R(cz80_struc *cpu)
  372. {
  373.     cz80_struc *CPU = cpu;
  374.     return zR;
  375. }
  376.  
  377. uint16_t FASTCALL Cz80_Get_IFF(cz80_struc *cpu)
  378. {
  379.     cz80_struc *CPU = cpu;
  380.     uint16_t value = 0;
  381.  
  382.     if (zIFF1 & CZ80_IFF) value |= 1;
  383.     if (zIFF2 & CZ80_IFF) value |= 2;
  384.     return value;
  385. }
  386.  
  387. uint8_t FASTCALL Cz80_Get_IM(cz80_struc *cpu)
  388. {
  389.     cz80_struc *CPU = cpu;
  390.     return zIM;
  391. }
  392.  
  393. uint8_t FASTCALL Cz80_Get_I(cz80_struc *cpu)
  394. {
  395.     cz80_struc *CPU = cpu;
  396.     return zI;
  397. }
  398.  
  399.  
  400. void FASTCALL Cz80_Set_BC(cz80_struc *cpu, uint16_t value)
  401. {
  402.     cz80_struc *CPU = cpu;
  403.     zBC = value;
  404. }
  405.  
  406. void FASTCALL Cz80_Set_DE(cz80_struc *cpu, uint16_t value)
  407. {
  408.     cz80_struc *CPU = cpu;
  409.     zDE = value;
  410. }
  411.  
  412. void FASTCALL Cz80_Set_HL(cz80_struc *cpu, uint16_t value)
  413. {
  414.     cz80_struc *CPU = cpu;
  415.     zHL = value;
  416. }
  417.  
  418. void FASTCALL Cz80_Set_AF(cz80_struc *cpu, uint16_t val)
  419. {
  420.     cz80_struc *CPU = cpu;
  421.     zF = val;
  422.     zA = val >> 8;
  423. }
  424.  
  425. void FASTCALL Cz80_Set_BC2(cz80_struc *cpu, uint16_t value)
  426. {
  427.     cz80_struc *CPU = cpu;
  428.     zBC2 = value;
  429. }
  430.  
  431. void FASTCALL Cz80_Set_DE2(cz80_struc *cpu, uint16_t value)
  432. {
  433.     cz80_struc *CPU = cpu;
  434.     zDE2 = value;
  435. }
  436.  
  437. void FASTCALL Cz80_Set_HL2(cz80_struc *cpu, uint16_t value)
  438. {
  439.     cz80_struc *CPU = cpu;
  440.     zHL2 = value;
  441. }
  442.  
  443. void FASTCALL Cz80_Set_AF2(cz80_struc *cpu, uint16_t val)
  444. {
  445.     cz80_struc *CPU = cpu;
  446.     zF2 = val;
  447.     zA2 = val >> 8;
  448. }
  449.  
  450. void FASTCALL Cz80_Set_IX(cz80_struc *cpu, uint16_t value)
  451. {
  452.     cz80_struc *CPU = cpu;
  453.     zIX = value;
  454. }
  455.  
  456. void FASTCALL Cz80_Set_IY(cz80_struc *cpu, uint16_t value)
  457. {
  458.     cz80_struc *CPU = cpu;
  459.     zIY = value;
  460. }
  461.  
  462. void FASTCALL Cz80_Set_SP(cz80_struc *cpu, uint16_t value)
  463. {
  464.     cz80_struc *CPU = cpu;
  465.     zSP = value;
  466. }
  467.  
  468. void FASTCALL Cz80_Set_PC(cz80_struc *cpu, uint16_t val)
  469. {
  470.     cpu->BasePC = (uintptr_t) cpu->Fetch[val >> CZ80_FETCH_SFT];
  471.     cpu->PC = val;
  472. }
  473.  
  474.  
  475. void FASTCALL Cz80_Set_R(cz80_struc *cpu, uint16_t value)
  476. {
  477.     cz80_struc *CPU = cpu;
  478.     zR = value & 0xFF;
  479.     zR2 = value & 0x80;
  480. }
  481.  
  482. void FASTCALL Cz80_Set_IFF(cz80_struc *cpu, uint16_t value)
  483. {
  484.     cz80_struc *CPU = cpu;
  485.     zIFF = 0;
  486.     if (value & 1) zIFF1 = CZ80_IFF;
  487.     if (value & 2) zIFF2 = CZ80_IFF;
  488. }
  489.  
  490. void FASTCALL Cz80_Set_IM(cz80_struc *cpu, uint8_t value)
  491. {
  492.     cz80_struc *CPU = cpu;
  493.     zIM = value & 3;
  494. }
  495.  
  496. void FASTCALL Cz80_Set_I(cz80_struc *cpu, uint8_t value)
  497. {
  498.     cz80_struc *CPU = cpu;
  499.     zI = value & 0xFF;
  500. }
  501.  
  502. //#endif // CPUZ80_CZ80_CORE
  503.  
  504.  
  505.