Subversion Repositories Kolibri OS

Rev

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

  1. /********************************************************************************/
  2. /*                                                                              */
  3. /* CZ80 macro file                                                              */
  4. /* C Z80 emulator version 0.91                                                  */
  5. /* Copyright 2004-2005 Stephane Dallongeville                                   */
  6. /*                                                                              */
  7. /********************************************************************************/
  8.  
  9. #if CZ80_USE_JUMPTABLE
  10. #define _SSOP(A,B) A##B
  11. #define OP(A) _SSOP(OP,A)
  12. #define OPCB(A) _SSOP(OPCB,A)
  13. #define OPED(A) _SSOP(OPED,A)
  14. #define OPXY(A) _SSOP(OPXY,A)
  15. #define OPXYCB(A) _SSOP(OPXYCB,A)
  16. #else
  17. #define OP(A) case A
  18. #define OPCB(A) case A
  19. #define OPED(A) case A
  20. #define OPXY(A) case A
  21. #define OPXYCB(A) case A
  22. #endif
  23.  
  24. #define GET_BYTE                \
  25.         (((uint8_t *)CPU->BasePC)[PC])
  26.  
  27. #define GET_BYTE_S              \
  28.         (((int8_t *)CPU->BasePC)[PC])
  29.  
  30. #define GET_WORD                \
  31.         (((uint8_t *)CPU->BasePC)[PC] |                         \
  32.          (((uint8_t *)CPU->BasePC)[((PC + 1) & 0xffff)] << 8))
  33.  
  34. #define FETCH_BYTE              \
  35.         (((uint8_t *)CPU->BasePC)[PC++])
  36.  
  37. #define FETCH_BYTE_S            \
  38.         (((int8_t *)CPU->BasePC)[PC++])
  39.  
  40. #define FETCH_WORD(A)           \
  41.     A = GET_WORD;               \
  42.     PC += 2;
  43.  
  44. #if CZ80_SIZE_OPT
  45.     #define RET(A)              \
  46.         CCnt -= A;              \
  47.         goto Cz80_Exec_Check;
  48. #else
  49.     #define RET(A)              \
  50.         if ((CCnt -= A) <= 0) goto Cz80_Exec_End;  \
  51.         goto Cz80_Exec;
  52. #endif
  53.  
  54. #define SET_PC(A)               \
  55.     CPU->BasePC = (uintptr_t) CPU->Fetch[(A) >> CZ80_FETCH_SFT];  \
  56.     PC = ((A) & 0xffff);
  57.  
  58. #define PRE_IO                  \
  59.     CPU->CycleIO = CCnt;
  60.  
  61. #define POST_IO                 \
  62.     CCnt = CPU->CycleIO;
  63.  
  64. #define READ_BYTE(A, D)                 \
  65.     D = CPU->Read_Byte(CPU->ctx, (A));
  66.  
  67. #if CZ80_USE_WORD_HANDLER
  68. #define READ_WORD(A, D)                 \
  69.     D = CPU->Read_Word(CPU->ctx, (A));
  70. #define READ_WORD_LE(A, D) READ_WORD(A, D)
  71. #elif CZ80_LITTLE_ENDIAN
  72. #define READ_WORD(A, D)                 \
  73.     D = CPU->Read_Byte(CPU->ctx, (A)) | (CPU->Read_Byte(CPU->ctx, ((A) + 1)) << 8);
  74. #define READ_WORD_LE(A, D) READ_WORD(A, D)
  75. #else
  76. #define READ_WORD(A, D)                 \
  77.     D = (CPU->Read_Byte(CPU->ctx, (A)) << 8) | CPU->Read_Byte(CPU->ctx, ((A) + 1));
  78. #define READ_WORD_LE(A, D)              \
  79.     D = CPU->Read_Byte(CPU->ctx, (A)) | (CPU->Read_Byte(CPU->ctx, ((A) + 1)) << 8);
  80. #endif
  81.  
  82. #define READSX_BYTE(A, D)               \
  83.     D = CPU->Read_Byte(CPU->ctx, (A));
  84.  
  85. #define WRITE_BYTE(A, D)                \
  86.     CPU->Write_Byte(CPU->ctx, (A), (D));
  87.  
  88. #if CZ80_USE_WORD_HANDLER
  89. #define WRITE_WORD(A, D)                \
  90.     CPU->Write_Word(CPU->ctx, (A), (D));
  91. #define WRITE_WORD_LE(A, D) WRITE_WORD(A, D);
  92. #elif CZ80_LITTLE_ENDIAN
  93. #define WRITE_WORD(A, D)                                \
  94.     CPU->Write_Byte(CPU->ctx, (A), (D));                \
  95.     CPU->Write_Byte(CPU->ctx, ((A) + 1), ((D) >> 8));
  96. #define WRITE_WORD_LE(A, D) WRITE_WORD(A, D);
  97. #else
  98. #define WRITE_WORD(A, D)                        \
  99.     CPU->Write_Byte(CPU->ctx, (A), ((D) >> 8)); \
  100.     CPU->Write_Byte(CPU->ctx, ((A) + 1), (D));
  101. #define WRITE_WORD_LE(A, D)                             \
  102.     CPU->Write_Byte(CPU->ctx, (A), (D));                \
  103.     CPU->Write_Byte(CPU->ctx, ((A) + 1), ((D) >> 8));
  104. #endif
  105.  
  106. #define PUSH_16(A)              \
  107.     {                           \
  108.         uint16_t sp;            \
  109.                                 \
  110.         zSP -= 2;               \
  111.         sp = zSP;               \
  112.         WRITE_WORD_LE(sp, A);   \
  113.     }
  114.  
  115. #define POP_16(A)           \
  116.     {                       \
  117.         uint16_t sp;        \
  118.                             \
  119.         sp = zSP;           \
  120.         READ_WORD_LE(sp, A);\
  121.         zSP = sp + 2;       \
  122.     }
  123.  
  124. #define IN(A, D)            \
  125.     D = CPU->IN_Port(CPU->ctx, (A));
  126.  
  127. #define OUT(A, D)           \
  128.     CPU->OUT_Port(CPU->ctx, (A), (D));
  129.  
  130. #define CHECK_INT                                           \
  131.     if (CPU->Status & (zIFF1 | CZ80_HAS_NMI))               \
  132.     {                                                       \
  133.         uint16_t newPC;                                     \
  134.                                                             \
  135.         if (CPU->Status & CZ80_HAS_NMI)                     \
  136.         {                                                   \
  137.             /* NMI */                                       \
  138.             CPU->Status &= ~(CZ80_HALTED | CZ80_HAS_NMI);   \
  139.             zIFF1 = 0;                                      \
  140.             newPC = 0x66;                                   \
  141.         }                                                   \
  142.         else                                                \
  143.         {                                                   \
  144.             /* MI */                                        \
  145.             CPU->Status &= ~(CZ80_HALTED | CZ80_HAS_INT);   \
  146.             zIFF= 0;                                        \
  147.                                                             \
  148.             if (zIM == 1) newPC = 0x38;                     \
  149.             else                                            \
  150.             {                                               \
  151.                 uint16_t adr;                               \
  152.                                                             \
  153.                 Opcode = CPU->Interrupt_Ack(CPU->ctx, CPU->IntVect) & 0xFF; \
  154.                 if (zIM == 0) goto Cz80_Exec_IM0;           \
  155.                                                             \
  156.                 adr = Opcode | (zI << 8);                   \
  157.                 READ_WORD(adr, newPC)                       \
  158.                 CCnt -= 8;                                  \
  159.             }                                               \
  160.         }                                                   \
  161.                                                             \
  162.         {                                                   \
  163.             uint16_t src = PC;                              \
  164.                                                             \
  165.             PUSH_16(src)                                    \
  166.             SET_PC(newPC)                                   \
  167.             CCnt -= 11;                                     \
  168.         }                                                   \
  169.     }
  170.  
  171.