z80th.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. # z80jit - Z80 CPU emulator [with JIT compilation?], in rpython.
  2. # Copyright (C) 2014-2017 Jason Harris <jth@mibot.com>
  3. # Copyright (C) 2017 deesix <deesix@tuta.io>
  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 3 of the License, or
  7. # (at your option) any later version.
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. # You should have received a copy of the GNU General Public License
  13. # along with this program. If not, see <http://www.gnu.org/licenses/>
  14. #-----------------------------------------------------------------------------
  15. """
  16. Z80 CPU Emulation
  17. """
  18. #-----------------------------------------------------------------------------
  19. import z80da
  20. #-----------------------------------------------------------------------------
  21. # flags
  22. _CF = 0x01 # carry
  23. _NF = 0x02 # subtract
  24. _PF = 0x04 # parity
  25. _VF = _PF # overflow
  26. _XF = 0x08 # bit3 - undocumented
  27. _HF = 0x10 # half carry (bcd)
  28. _YF = 0x20 # bit5 - undocumented
  29. _ZF = 0x40 # zero
  30. _SF = 0x80 # sign
  31. def _signed(x):
  32. if x & 0x80:
  33. x = (x & 0x7f) - 128
  34. return x
  35. #-----------------------------------------------------------------------------
  36. class Error(Exception):
  37. pass
  38. #-----------------------------------------------------------------------------
  39. class cpu:
  40. def _str_f(self):
  41. """return the flags as a string"""
  42. flags = []
  43. flags.append(('.', 'S')[bool(self.f & _SF)])
  44. flags.append(('.', 'Z')[bool(self.f & _ZF)])
  45. flags.append(('.', 'H')[bool(self.f & _HF)])
  46. flags.append(('.', 'P')[bool(self.f & _PF)])
  47. flags.append(('.', 'V')[bool(self.f & _VF)])
  48. flags.append(('.', 'N')[bool(self.f & _NF)])
  49. flags.append(('.', 'C')[bool(self.f & _CF)])
  50. return ''.join(flags)
  51. def _add_flags(self, res, val):
  52. """set the flags for an add operation: result = a + val"""
  53. self.f = self.f_sz[res & 0xff]
  54. self.f |= ((res >> 8) & _CF)
  55. self.f |= ((self.a ^ res ^ val) & _HF)
  56. self.f |= (((val ^ self.a ^ 0x80) & (val ^ res) & 0x80) >> 5)
  57. def _add16_flags(self, res, d, s):
  58. """set the flags for an 16 bit add operation: result = d + s"""
  59. self.f = self.f & (_SF | _ZF | _VF)
  60. self.f |= (((d ^ res ^ s) >> 8) & _HF)
  61. self.f |= (((res >> 16) & _CF) | ((res >> 8) & (_YF | _XF)))
  62. def _sub16_flags(self, res, d, s):
  63. """set the flags for a 16 bit sub operation: result = d - s"""
  64. self.f = (((d ^ res ^ s) >> 8) & _HF)
  65. self.f |= _NF
  66. self.f |= ((res >> 16) & _CF)
  67. self.f |= ((res >> 8) & (_SF | _YF | _XF))
  68. self.f |= [0, _ZF][(res & 0xffff) == 0]
  69. self.f |= (((s ^ d) & (d ^ res) & 0x8000) >> 13)
  70. def _adc16_flags(self, res, d, s):
  71. """set the flags for a 16 bit adc operation: result = d + s + cf"""
  72. self.f = (((d ^ res ^ s) >> 8) & _HF)
  73. self.f |= ((res >> 16) & _CF)
  74. self.f |= ((res >> 8) & (_SF | _YF | _XF))
  75. self.f |= [0, _ZF][(res & 0xffff) == 0]
  76. self.f |= (((s ^ d ^ 0x8000) & (d ^ res) & 0x8000) >> 13)
  77. def _sub_flags(self, res, val):
  78. """set the flags for a sub operation: result = a - val"""
  79. self.f = self.f_sz[res & 0xff]
  80. self.f |= ((res >> 8) & _CF)
  81. self.f |= _NF
  82. self.f |= ((self.a ^ res ^ val) & _HF)
  83. self.f |= (((val ^ self.a) & (self.a ^ res) & 0x80) >> 5)
  84. def _neg_flags(self, res, val):
  85. """set the flags for a neg operation: result = 0 - a"""
  86. self.f = self.f_sz[res & 0xff]
  87. self.f |= _NF
  88. self.f |= ((res ^ val) & _HF)
  89. if val != 0x00: self.f |= _CF
  90. if val == 0x80: self.f |= _PF
  91. def _enter_halt(self):
  92. """enter halt mode"""
  93. self.halt = 1
  94. self._dec_pc(1)
  95. def _leave_halt(self):
  96. """leave halt mode"""
  97. if self.halt:
  98. self._inc_pc(1)
  99. self.halt = 0
  100. def _push(self, val):
  101. """push a 16 bit quantity onto the stack"""
  102. self.mem[self.sp - 1] = val >> 8
  103. self.mem[self.sp - 2] = val & 0xff
  104. self.sp = (self.sp - 2) & 0xffff
  105. def _pop(self):
  106. """pop a 16 bit quantity from the stack"""
  107. val = (self.mem[self.sp + 1] << 8) | self.mem[self.sp]
  108. self.sp = (self.sp + 2) & 0xffff
  109. return val
  110. def _peek(self, adr):
  111. """read and return the 16 bit value at mem[adr]"""
  112. return (self.mem[adr + 1] << 8) + self.mem[adr]
  113. def _poke(self, adr, val):
  114. """write the 16 bit value to mem[adr]"""
  115. self.mem[adr + 1] = val >> 8
  116. self.mem[adr] = val & 0xff
  117. def _set_af(self, val):
  118. """set the a and f registers with a 16 bit value"""
  119. self.a = (val >> 8) & 0xff
  120. self.f = val & 0xff
  121. def _get_af(self):
  122. """return the 16 bit value of the a and f registers"""
  123. return (self.a << 8) | self.f
  124. def _set_bc(self, val):
  125. """set the b and c registers with a 16 bit value"""
  126. self.b = (val >> 8) & 0xff
  127. self.c = val & 0xff
  128. def _get_bc(self):
  129. """return the 16 bit value of the b and c registers"""
  130. return (self.b << 8) | self.c
  131. def _set_de(self, val):
  132. """set the d and e registers with a 16 bit value"""
  133. self.d = (val >> 8) & 0xff
  134. self.e = val & 0xff
  135. def _get_de(self):
  136. """return the 16 bit value of the d and e registers"""
  137. return (self.d << 8) | self.e
  138. def _set_hl(self, val):
  139. """set the h and l registers with a 16 bit value"""
  140. self.h = (val >> 8) & 0xff
  141. self.l = val & 0xff
  142. def _get_hl(self):
  143. """return the 16 bit value of the h and l registers"""
  144. return (self.h << 8) | self.l
  145. def _get_pc(self):
  146. """return the 16 bit pc register"""
  147. return self.pc
  148. def _set_pc(self, val):
  149. """set the 16 bit pc register"""
  150. self.pc = val & 0xffff
  151. def _dec_pc(self, n):
  152. """decrement pc"""
  153. self.pc = (self.pc - n) & 0xffff
  154. def _inc_pc(self, n):
  155. """increment pc"""
  156. self.pc = (self.pc + n) & 0xffff
  157. def _get_nn(self):
  158. """return the 16 bit immediate at mem[pc], pc += 2"""
  159. nn = self._peek(self.pc)
  160. self._inc_pc(2)
  161. return nn
  162. def _get_n(self):
  163. """return the 8 bit immediate at mem[pc], pc += 1"""
  164. n = self.mem[self.pc]
  165. self._inc_pc(1)
  166. return n
  167. def da(self, adr):
  168. """
  169. Disassemble the instruction at mem[adr].
  170. Return the operation, operands and number of bytes.
  171. """
  172. return z80da.disassemble(self.mem, adr)
  173. def execute(self):
  174. """
  175. Execute a single instruction at the current mem[pc] location.
  176. Return the number of clock cycles taken.
  177. """
  178. self.r = (self.r + 1) & 0x7f
  179. code = self._get_n()
  180. return G_opcodes[code](self)
  181. def interrupt(self, x = 0):
  182. """
  183. Perform interrupt actions
  184. """
  185. if self.iff1 == 0:
  186. return 0
  187. self._leave_halt()
  188. self.iff1 = 0
  189. self.iff2 = 0
  190. self._push(self.pc)
  191. if self.im == 0:
  192. self.pc = x & 0x38
  193. return 13
  194. elif self.im == 1:
  195. self.pc = 0x38
  196. return 11
  197. else:
  198. self._set_pc(self._peek((self.i << 8) + (x & 0xff)))
  199. return 17
  200. def reset(self):
  201. """
  202. reset the cpu state
  203. """
  204. self.a = 0xff
  205. self.f = 0xff
  206. self.b = 0xff
  207. self.c = 0xff
  208. self.d = 0xff
  209. self.e = 0xff
  210. self.h = 0xff
  211. self.l = 0xff
  212. self.alt_af = 0xffff
  213. self.alt_bc = 0xffff
  214. self.alt_de = 0xffff
  215. self.alt_hl = 0xffff
  216. self.sp = 0xffff
  217. self.ix = 0xffff
  218. self.iy = 0xffff
  219. self.i = 0
  220. self.r = 0
  221. self.im = 0
  222. self.iff1 = 0
  223. self.iff2 = 0
  224. self.halt = 0
  225. self.pc = 0
  226. def _repeated_prefix(self):
  227. """A prefix code hase been repeated. NOP and re-run the current prefix"""
  228. self._dec_pc(1)
  229. return 0
  230. def _execute_dddd(self):
  231. return self._repeated_prefix()
  232. def _execute_ddfd(self):
  233. return self._repeated_prefix()
  234. def _execute_fddd(self):
  235. return self._repeated_prefix()
  236. def _execute_fdfd(self):
  237. return self._repeated_prefix()
  238. def _execute_cb(self):
  239. code = self._get_n()
  240. return 4 + G_opcodes_cb[code](self)
  241. def _execute_dd(self):
  242. code = self._get_n()
  243. return 4 + G_opcodes_dd[code](self)
  244. def _execute_ed(self):
  245. code = self._get_n()
  246. return 4 + G_opcodes_ed[code](self)
  247. def _execute_fd(self):
  248. code = self._get_n()
  249. return 4 + G_opcodes_fd[code](self)
  250. def _execute_ddcb(self):
  251. d = _signed(self._get_n())
  252. code = self._get_n()
  253. return 8 + G_opcodes_ddcb00[code](self, d)
  254. def _execute_fdcb(self):
  255. d = _signed(self._get_n())
  256. code = self._get_n()
  257. return 8 + G_opcodes_fdcb00[code](self, d)
  258. def __str__(self):
  259. """return a string with processor state"""
  260. regs = []
  261. regs.append('a : %02x' % self.a)
  262. regs.append('f : %02x %s' % (self.f, self._str_f()))
  263. regs.append('b c : %02x %02x' % (self.b, self.c))
  264. regs.append('d e : %02x %02x' % (self.d, self.e))
  265. regs.append('h l : %02x %02x' % (self.h, self.l))
  266. regs.append('a\'f\' : %02x %02x' % (self.alt_af >> 8, self.alt_af & 0xff))
  267. regs.append('b\'c\' : %02x %02x' % (self.alt_bc >> 8, self.alt_bc & 0xff))
  268. regs.append('d\'e\' : %02x %02x' % (self.alt_de >> 8, self.alt_de & 0xff))
  269. regs.append('h\'l\' : %02x %02x' % (self.alt_hl >> 8, self.alt_hl & 0xff))
  270. regs.append('i : %02x' % self.i)
  271. regs.append('im : %d' % self.im)
  272. regs.append('iff1 : %d' % self.iff1)
  273. regs.append('iff2 : %d' % self.iff2)
  274. regs.append('r : %02x' % self.r)
  275. regs.append('ix : %04x' % self.ix)
  276. regs.append('iy : %04x' % self.iy)
  277. regs.append('sp : %04x' % self.sp)
  278. regs.append('pc : %04x' % self.pc)
  279. return '\n'.join(regs)
  280. def __init__(self, mem, io):
  281. self.mem = mem
  282. self.io = io
  283. self.reset()