Subversion Repositories Kolibri OS

Rev

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

  1. /*=====================================================================
  2.   Macros.c -> Macros used on the opcode execution.
  3.  
  4.  This program is free software; you can redistribute it and/or modify
  5.  it under the terms of the GNU General Public License as published by
  6.  the Free Software Foundation; either version 2 of the License, or
  7.  (at your option) any later version.
  8.  
  9.  This program is distributed in the hope that it will be useful,
  10.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  GNU General Public License for more details.
  13.  
  14.  You should have received a copy of the GNU General Public License
  15.  along with this program; if not, write to the Free Software
  16.  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.  Copyright (c) 2000 Santiago Romero Iglesias.
  19.  Email: sromero@escomposlinux.org
  20.  ======================================================================*/
  21.  
  22. /* defines for the registers: faster access to them when coding... */
  23.  
  24. #define   r_PC    regs->PC.W
  25. #define   r_PCl   regs->PC.B.l
  26. #define   r_PCh   regs->PC.B.h
  27. #define   r_SP    regs->SP.W
  28. #define   r_IFF1  regs->IFF1
  29. #define   r_IFF2  regs->IFF2
  30. #define   r_R     regs->R.W
  31.  
  32. #define   r_AF    regs->AF.W
  33. #define   r_A     regs->AF.B.h
  34. #define   r_F     regs->AF.B.l
  35. #define   r_BC    regs->BC.W
  36. #define   r_B     regs->BC.B.h
  37. #define   r_C     regs->BC.B.l
  38. #define   r_DE    regs->DE.W
  39. #define   r_D     regs->DE.B.h
  40. #define   r_E     regs->DE.B.l
  41. #define   r_HL    regs->HL.W
  42. #define   r_H     regs->HL.B.h
  43. #define   r_L     regs->HL.B.l
  44. #define   r_IX    regs->IX.W
  45. #define   r_IXh   regs->IX.B.h
  46. #define   r_IXl   regs->IX.B.l
  47. #define   r_IY    regs->IY.W
  48. #define   r_IYh   regs->IY.B.h
  49. #define   r_IYl   regs->IY.B.l
  50.  
  51. #define   r_AFs   regs->AFs.W
  52. #define   r_As    regs->AFs.B.h
  53. #define   r_Fs    regs->AFs.B.l
  54. #define   r_BCs   regs->BCs.W
  55. #define   r_Bs    regs->BCs.B.h
  56. #define   r_Cs    regs->BCs.B.l
  57. #define   r_DEs   regs->DEs.W
  58. #define   r_Ds    regs->DEs.B.h
  59. #define   r_Es    regs->DEs.B.l
  60. #define   r_HLs   regs->HLs.W
  61. #define   r_Hs    regs->HLs.B.h
  62. #define   r_Ls    regs->HLs.B.l
  63. #define   r_IXs   regs->IX.W
  64. #define   r_IXhs  regs->IX.B.h
  65. #define   r_IXls  regs->IX.B.l
  66. #define   r_IYs   regs->IY.W
  67. #define   r_IYhs  regs->IY.B.h
  68. #define   r_IYls  regs->IY.B.l
  69.  
  70. #define   r_op    ops.W
  71. #define   r_oph   ops.B.h
  72. #define   r_opl   ops.B.l
  73. #define   r_tmp   tmpreg2.W
  74. #define   r_tmph  tmpreg2.B.h
  75. #define   r_tmpl  tmpreg2.B.l
  76. #define   r_mem   mread.W
  77. #define   r_memh  mread.B.h
  78. #define   r_meml  mread.B.l
  79.  
  80. #ifndef _DISASM_
  81. /*--- Flag tables by Philip Kendall, taken from it's fuse emulator -*/
  82. /*--- I was having headache trying to emulate correctly the FLAGS,
  83.       so I finished using the FLAG tables used by P. Kendall. ------*/
  84. #define FLAG_C  0x01
  85. #define FLAG_N  0x02
  86. #define FLAG_P  0x04
  87. #define FLAG_V  FLAG_P
  88. #define FLAG_3  0x08
  89. #define FLAG_H  0x10
  90. #define FLAG_5  0x20
  91. #define FLAG_Z  0x40
  92. #define FLAG_S  0x80
  93.  
  94. /* Whether a half carry occured or not can be determined by looking at
  95.    the 3rd bit of the two arguments and the result; these are hashed
  96.    into this table in the form r12, where r is the 3rd bit of the
  97.    result, 1 is the 3rd bit of the 1st argument and 2 is the
  98.    third bit of the 2nd argument; the tables differ for add and subtract
  99.    operations */
  100.  
  101. /* Whether a half carry occured or not can be determined by looking at
  102.    the 3rd bit of the two arguments and the result; these are hashed
  103.    into this table in the form r12, where r is the 3rd bit of the
  104.    result, 1 is the 3rd bit of the 1st argument and 2 is the
  105.    third bit of the 2nd argument; the tables differ for add and subtract
  106.    operations */
  107. byte halfcarry_add_table[] = { 0, FLAG_H, FLAG_H, FLAG_H, 0, 0, 0, FLAG_H };
  108. byte halfcarry_sub_table[] = { 0, 0, FLAG_H, 0, FLAG_H, 0, FLAG_H, FLAG_H };
  109.  
  110. /* Similarly, overflow can be determined by looking at the 7th bits; again
  111.    the hash into this table is r12 */
  112. byte overflow_add_table[] = { 0, 0, 0, FLAG_V, FLAG_V, 0, 0, 0 };
  113. byte overflow_sub_table[] = { 0, FLAG_V, 0, 0, 0, 0, FLAG_V, 0 };
  114.  
  115. /* Some more tables; initialised in z80_init_tables() */
  116. byte sz53_table[0x100];   /* The S, Z, 5 and 3 bits of the temp value */
  117. byte parity_table[0x100]; /* The parity of the temp value */
  118. byte sz53p_table[0x100];  /* OR the above two tables together */
  119. /*------------------------------------------------------------------*/
  120.  
  121. // Contributed by Metalbrain to implement OUTI, etc.
  122. byte ioblock_inc1_table[64];
  123. byte ioblock_dec1_table[64];
  124. byte ioblock_2_table[0x100];
  125.  
  126. /*--- Memory Write on the A address on no bank machines -------------*/
  127. void Z80WriteMem( word where, word A, Z80Regs *regs)
  128. {
  129.   if( where >= 16384 )
  130.      regs->RAM[where] = A;
  131. }
  132.  
  133. #endif
  134.  
  135.  
  136. /*--- Memory Read from the A address on no bank machines -------------*/
  137. #define Z80ReadMem(A)   ((regs->RAM[(A)]))
  138.  
  139. //  return( regs->RAM[A] );
  140.  
  141.  
  142. /* macros to change the ICount register */
  143. #define AddCycles(n) regs->ICount-=(n)
  144.  
  145. #define SubCycles(n) regs->ICount+=(n)
  146.  
  147. //#define AddR(n) r_R = (r_R+(n))
  148. #define AddR(n) r_R = ((r_R & 0x80) | ((r_R+(n)) & 0x7f ))
  149. #define SubR(n) r_R = ((r_R & 0x80) | ((r_R-(n)) & 0x7f ))
  150.  
  151.  
  152. /* setting and resetting the flag bits: */
  153. #define SET_FLAG(flag)        (r_F |= (flag))
  154.  
  155. #define RESET_FLAG(flag)      (r_F &= ~(flag))
  156.  
  157. #define TEST_FLAG(flag)       (r_F & (flag))
  158.  
  159.  
  160. /* store a given register in the stack (hi and lo bytes) */
  161. #define PUSH(rreg)                              \
  162.   Z80WriteMem( --(r_SP), regs->rreg.B.h, regs); \
  163.   Z80WriteMem( --(r_SP), regs->rreg.B.l, regs)
  164.  
  165. #define POP(rreg)\
  166.   regs->rreg.B.l = Z80ReadMem(r_SP); r_SP++;\
  167.   regs->rreg.B.h = Z80ReadMem(r_SP); r_SP++
  168.  
  169. #define PUSH_IXYr() \
  170.   Z80WriteMem( --(r_SP), REGH, regs); \
  171.   Z80WriteMem( --(r_SP), REGL, regs)
  172.  
  173. #define POP_IXYr()\
  174.   REGL = Z80ReadMem(r_SP); r_SP++; \
  175.   REGH = Z80ReadMem(r_SP); r_SP++
  176.  
  177. #define RST(rstval)  PUSH(PC); r_PC=(rstval)
  178.  
  179.  
  180. /*--- Move data to mem or regs --------------------------------------*/
  181. #define LD_r_r(dreg, sreg)  (dreg) = (sreg)
  182.  
  183. #define STORE_r(daddreg, sreg)  Z80WriteMem((daddreg), (sreg), regs)
  184.  
  185. #define STORE_nn_rr(dreg) \
  186.                         r_opl = Z80ReadMem(r_PC); r_PC++;\
  187.                         r_oph = Z80ReadMem(r_PC); r_PC++; \
  188.                         r_tmp = dreg; \
  189.                         Z80WriteMem((r_op),r_tmpl, regs); \
  190.                         Z80WriteMem((r_op+1),r_tmph, regs)
  191.  
  192. #define STORE_nn_r(sreg) \
  193.                         r_opl = Z80ReadMem(r_PC); r_PC++; \
  194.                         r_oph = Z80ReadMem(r_PC); r_PC++; \
  195.                         Z80WriteMem((r_op),(sreg), regs)
  196.  
  197. #define LOAD_r(dreg, saddreg)   (dreg)=Z80ReadMem((saddreg))
  198.  
  199. #define LOAD_rr_nn(dreg)   r_opl = Z80ReadMem(r_PC); r_PC++; \
  200.                            r_oph = Z80ReadMem(r_PC); r_PC++; \
  201.                            r_tmpl = Z80ReadMem(r_op); \
  202.                            r_tmph = Z80ReadMem((r_op)+1); \
  203.                            dreg=r_tmp
  204.  
  205.  
  206. #define LOAD_r_nn(dreg)    r_opl = Z80ReadMem(r_PC); r_PC++; \
  207.                            r_oph = Z80ReadMem(r_PC); r_PC++; \
  208.                            dreg = Z80ReadMem(r_op)
  209.  
  210. #define LD_r_n(reg) (reg) = Z80ReadMem(r_PC++)
  211.  
  212. #define LD_rr_nn(reg)   r_opl = Z80ReadMem(r_PC); r_PC++; \
  213.                         r_oph = Z80ReadMem(r_PC); r_PC++; \
  214.                         reg = r_op
  215.  
  216. #define EX(reg1,reg2)        r_opl=(reg1); (reg1)=(reg2); (reg2)=r_opl
  217.  
  218. #define EX_WORD(reg1,reg2)   r_op=(reg1); (reg1)=(reg2); (reg2)=r_op
  219.  
  220. /*--- Increments/Decrements -----------------------------------------*/
  221. #define INC(reg)            (reg)++;                        \
  222.    r_F = ( r_F & FLAG_C ) | ( (reg)==0x80 ? FLAG_V : 0 ) |  \
  223.   ( (reg)&0x0f ? 0 : FLAG_H ) | ( (reg) ? 0 : FLAG_Z ) |    \
  224.    sz53_table[(reg)]
  225.  
  226. #define DEC(reg)                                                  \
  227.    r_F = ( r_F & FLAG_C ) | ( (reg)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
  228.    (reg)--;                                                       \
  229.    r_F |= ( (reg)==0x7f ? FLAG_V : 0 ) | sz53_table[(reg)]
  230.  
  231. // it was:
  232. //   r_F |= ( (reg)==0x79 ? FLAG_V : 0 ) | sz53_table[(reg)]
  233. // But Kak pointed my was not 0x79 -> 0x7F, changed 7-3-2001
  234.  
  235.  
  236. /*--- Bit operations ------------------------------------------------*/
  237. #define BIT_RES(b,reg) reg &= ~(0x1<<b)
  238.  
  239. #define BIT_SET(b,reg) reg |= (0x1<<b)
  240.  
  241. #define BIT_mem_RES(b,addr) r_opl = Z80ReadMem(addr); \
  242.                             r_opl &= ~(0x1<<b);       \
  243.                             Z80WriteMem(addr, r_opl, regs)
  244.  
  245. #define BIT_mem_SET(b,addr) r_opl = Z80ReadMem(addr); \
  246.                             r_opl |= (0x1<<b);        \
  247.                             Z80WriteMem(addr, r_opl, regs)
  248.  
  249. #define BIT_RES_mem(b,addr,reg)  reg &= ~(0x1<<b);    \
  250.                                  Z80WriteMem((addr), (reg), regs)
  251.  
  252. #define BIT_SET_mem(b,addr,reg) reg |= (0x1<<b);        \
  253.                                 Z80WriteMem((addr), (reg), regs)
  254.  
  255. #define BIT_BIT(b,reg)     r_F = ( r_F & FLAG_C ) | \
  256.                            ( (reg) & ( FLAG_3 | FLAG_5 ) ) |\
  257.                            (((reg) & ( 0x01 << b ) ) ? FLAG_H : \
  258.                            (FLAG_P|FLAG_H|FLAG_Z ) )
  259.  
  260. #define BIT_mem_BIT(b,reg)  r_opl = Z80ReadMem(reg); \
  261.                             r_F = ( r_F & FLAG_C ) | \
  262.                             ( (r_opl) & ( FLAG_3 | FLAG_5 ) ) |\
  263.                             (((r_opl) & ( 0x01 << b ) ) ? FLAG_H : \
  264.                             (FLAG_P|FLAG_H|FLAG_Z ) )
  265.  
  266. #define BIT_BIT7(reg)        r_F = ( r_F & FLAG_C ) | ( (reg) & \
  267.                          ( FLAG_3 | FLAG_5 ) ) |\
  268.                          (((reg) & 0x80 ) ? ( FLAG_H | FLAG_S ) :\
  269.                          ( FLAG_P | FLAG_H | FLAG_Z ) )
  270.  
  271. #define BIT_mem_BIT7(reg)    r_opl = Z80ReadMem(reg); \
  272.                          r_F = ( r_F & FLAG_C ) | ( (r_opl) & \
  273.                          ( FLAG_3 | FLAG_5 ) ) |\
  274.                          (((r_opl) & 0x80 ) ? ( FLAG_H | FLAG_S ) :\
  275.                          ( FLAG_P | FLAG_H | FLAG_Z ) )
  276.  
  277.  
  278. #define RLC(reg)  (reg) = ( (reg)<<1 ) | ( (reg)>>7 );          \
  279.                   r_F = ( (reg) & FLAG_C ) | sz53p_table[(reg)]
  280.  
  281. #define RRC(reg)  r_F = (reg) & FLAG_C;               \
  282.                   (reg) = ( (reg)>>1 ) | ( (reg)<<7 );\
  283.                    r_F |= sz53p_table[(reg)]
  284.  
  285. #define RL(reg)   r_opl = (reg);                         \
  286.                  (reg) = ( (reg)<<1 ) | ( r_F & FLAG_C );  \
  287.                   r_F = ( r_opl >> 7 ) | sz53p_table[(reg)]
  288.  
  289. #define RR(reg)   r_opl = (reg);                          \
  290.                   (reg) = ( (reg)>>1 ) | ( r_F << 7 );\
  291.                   r_F = ( r_opl & FLAG_C ) | sz53p_table[(reg)]
  292.  
  293. #define SLA(reg)  r_F = (reg) >> 7;\
  294.                   (reg) <<= 1;\
  295.                    r_F |= sz53p_table[(reg)]
  296.  
  297. #define SRA(reg)  r_F = (reg) & FLAG_C; \
  298.                  (reg) = ( (reg) & 0x80 ) | ( (reg) >> 1 );\
  299.                   r_F |= sz53p_table[(reg)]
  300.  
  301. #define SLL(reg)  r_F = (reg) >> 7;\
  302.                   (reg) = ( (reg) << 1 ) | 0x01;\
  303.                    r_F |= sz53p_table[(reg)]
  304.  
  305. #define SRL(reg)  r_F = (reg) & FLAG_C;\
  306.                   (reg) >>= 1;\
  307.                   r_F |= sz53p_table[(reg)]
  308.  
  309.  
  310.  
  311. /*--- JP operations -------------------------------------------------*/
  312. #define JP_nn()  r_opl = Z80ReadMem(r_PC); \
  313.                  r_PC++;                   \
  314.                  r_oph = Z80ReadMem(r_PC);  \
  315.                  r_PC = r_op
  316.  
  317. #define JR_n()   r_PC += (offset) (Z80ReadMem(r_PC)); r_PC++
  318.  
  319. #define RET_nn()   r_PCl = Z80ReadMem (r_SP); r_SP++; \
  320.                    r_PCh = Z80ReadMem (r_SP);  r_SP++;
  321.  
  322. #define CALL_nn()  r_opl = Z80ReadMem (r_PC); r_PC++; \
  323.                    r_oph = Z80ReadMem (r_PC); r_PC++; \
  324.                    Z80WriteMem( --(r_SP), r_PCh, regs ); \
  325.                    Z80WriteMem( --(r_SP), r_PCl, regs ); \
  326.                    r_PC = r_op
  327.  
  328.  
  329. /*--- ALU operations ------------------------------------------------*/
  330. #define AND(reg)     r_A &= (reg); \
  331.                      r_F = FLAG_H | sz53p_table[r_A]
  332.  
  333. #define OR(reg)      r_A |= (reg); \
  334.                      r_F = sz53p_table[r_A]
  335.  
  336. #define XOR(reg)     r_A ^= (reg); \
  337.                      r_F = sz53p_table[r_A]
  338.  
  339. #define AND_mem(raddress)     r_opl = Z80ReadMem(raddress); \
  340.                               r_A &= (r_opl);              \
  341.                               r_F = FLAG_H | sz53p_table[r_A]
  342.  
  343. #define OR_mem(raddress)      r_opl = Z80ReadMem(raddress); \
  344.                               r_A |= (r_opl);               \
  345.                               r_F = sz53p_table[r_A]
  346.  
  347. #define XOR_mem(raddress)     r_opl = Z80ReadMem(raddress); \
  348.                               r_A ^= (r_opl);               \
  349.                               r_F = sz53p_table[r_A]
  350.  
  351. #define ADD(val)   tempword = r_A + (val);                    \
  352.                    r_oph = ((r_A&0x88)>>3)|(((val)&0x88)>>2) | \
  353.                    ( (tempword & 0x88) >> 1 );                \
  354.                    r_A = tempword;                            \
  355.                    r_F = ( tempword & 0x100 ? FLAG_C : 0 ) |  \
  356.                    halfcarry_add_table[ r_oph & 0x07] |        \
  357.                    overflow_add_table[ r_oph >> 4] |           \
  358.                    sz53_table[r_A]
  359.  
  360. #define ADD_WORD(value1,value2)                                   \
  361.                    tempdword = (value1) + (value2);               \
  362.                    r_oph = ( ( (value1) & 0x0800 ) >> 11 ) |     \
  363.                    ( ( (value2) & 0x0800 ) >> 10 ) |              \
  364.                    ( ( tempdword & 0x0800 ) >> 9 );               \
  365.                    (value1) = tempdword;                            \
  366.                    r_F = ( r_F & ( FLAG_V | FLAG_Z | FLAG_S ) ) | \
  367.                    ( tempdword & 0x10000 ? FLAG_C : 0 ) |         \
  368.                    (( tempdword >> 8 ) & ( FLAG_3 | FLAG_5 ) ) | \
  369.                    halfcarry_add_table[r_oph]
  370.  
  371. #define ADC(value)                                                 \
  372.                    tempword = r_A + (value) + ( r_F & FLAG_C );      \
  373.             r_oph = ( (r_A & 0x88) >> 3 ) | ( ( (value) & 0x88 ) >> 2 ) |\
  374.                    ( (tempword & 0x88) >> 1 );                       \
  375.                     r_A = tempword;                                  \
  376.                     r_F = ( tempword & 0x100 ? FLAG_C : 0 ) |        \
  377.                    halfcarry_add_table[r_oph & 0x07] |            \
  378.                    overflow_add_table[r_oph >> 4] |               \
  379.                    sz53_table[r_A]
  380.  
  381. #define ADC_WORD(value)                                            \
  382.               tempdword= r_HL + (value) + ( r_F & FLAG_C );            \
  383.               r_oph = ( ( r_HL & 0x8800 ) >> 11 ) |               \
  384.               ( ( (value) & 0x8800 ) >> 10 ) |                     \
  385.               ( ( tempdword & 0x8800 ) >> 9 );                         \
  386.               r_HL = tempdword;                                        \
  387.               r_F = ( tempdword & 0x10000 ? FLAG_C : 0 )|              \
  388.               overflow_add_table[r_oph >> 4] |                    \
  389.               ( r_H & ( FLAG_3 | FLAG_5 | FLAG_S ) ) |             \
  390.               halfcarry_add_table[ r_oph & 0x0f ]|                \
  391.               ( r_HL ? 0 : FLAG_Z )
  392.  
  393. #define SUB(value)                                                 \
  394.               tempword = r_A - (value);\
  395.               r_opl = ( (r_A & 0x88) >> 3 ) |                     \
  396.               ( ( (value) & 0x88 ) >> 2 ) |                        \
  397.               ( (tempword & 0x88) >> 1 );                             \
  398.               r_A = tempword;                                         \
  399.               r_F = ( tempword & 0x100 ? FLAG_C : 0 ) | FLAG_N |      \
  400.               halfcarry_sub_table[r_opl & 0x07] |                 \
  401.               overflow_sub_table[r_opl >> 4] |                    \
  402.               sz53_table[r_A]
  403.  
  404. #define SBC(value)                                                 \
  405.               tempword = r_A - (value) - ( r_F & FLAG_C );            \
  406.               r_opl = ( (r_A & 0x88) >> 3 ) |                     \
  407.               ( ( (value) & 0x88 ) >> 2 ) |                        \
  408.               ( (tempword & 0x88) >> 1 );                             \
  409.               r_A = tempword;                                         \
  410.               r_F = ( tempword & 0x100 ? FLAG_C : 0 ) | FLAG_N |      \
  411.               halfcarry_sub_table[r_opl & 0x07] |                 \
  412.               overflow_sub_table[r_opl >> 4] |                    \
  413.               sz53_table[r_A]
  414.  
  415.  
  416. #define SBC_WORD(Rg)      \
  417.   tempword=r_F & C_FLAG; r_op=(r_HL-Rg-tempword)&0xFFFF;           \
  418.   r_F=                                                   \
  419.     N_FLAG|                                                    \
  420.     (((long)r_HL-(long)Rg-(long)tempword)&0x10000? C_FLAG:0)| \
  421.     ((r_HL^Rg)&(r_HL^r_op)&0x8000? O_FLAG:0)|        \
  422.     ((r_HL^Rg^r_op)&0x1000? H_FLAG:0)|                  \
  423.     (r_op? 0:Z_FLAG)|(r_oph&S_FLAG);                            \
  424.      r_HL=r_op
  425.  
  426. #define CP(value)                                                       \
  427.   tempword = r_A - (value);\
  428.   r_opl = ( (r_A & 0x88) >> 3 ) | ( ( (value) & 0x88 ) >> 2 ) |        \
  429.        ( (tempword & 0x88) >> 1 );                                        \
  430.   r_F = ( tempword & 0x100 ? FLAG_C : ( tempword ? 0 : FLAG_Z ) ) | FLAG_N |\
  431.   halfcarry_sub_table[r_opl & 0x07] |                                  \
  432.   overflow_sub_table[r_opl >> 4] |                                     \
  433.   ( value & ( FLAG_3 | FLAG_5 ) ) |                                     \
  434.   ( tempword & FLAG_S )
  435.  
  436. #define NEG_A()  r_opl = r_A; r_A=0; SUB(r_opl)
  437.  
  438. /*--- MISC operations -----------------------------------------------*/
  439. #define IN(reg,port)    (reg)=Z80InPort((port));                  \
  440.                          r_F = ( r_F & FLAG_C) | sz53p_table[(reg)]
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.