memory.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. # z80jit - Z80 CPU emulator [with JIT compilation?], in rpython.
  2. # Copyright (C) 2014-2017 Jason Harris <jth@mibot.com>
  3. # This program is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, either version 3 of the License, or
  6. # (at your option) any later version.
  7. # This program is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. # GNU General Public License for more details.
  11. # You should have received a copy of the GNU General Public License
  12. # along with this program. If not, see <http://www.gnu.org/licenses/>
  13. #-----------------------------------------------------------------------------
  14. """
  15. Memory Devices
  16. """
  17. #-----------------------------------------------------------------------------
  18. import array
  19. #-----------------------------------------------------------------------------
  20. _empty = 0xff
  21. #-----------------------------------------------------------------------------
  22. # Base Memory Device
  23. class memory:
  24. """Base Memory Device"""
  25. def __init__(self, bits = 0):
  26. """Create a memory device of size bytes."""
  27. size = 1 << bits
  28. self.mask = size - 1
  29. self.mem = array.array('B', (0,) * size)
  30. self.wr_notify = self.null
  31. self.rd_notify = self.null
  32. def null(self, adr):
  33. """do nothing read/write notification"""
  34. pass
  35. def __getitem__(self, adr):
  36. return _empty
  37. def __setitem__(self, adr, val):
  38. pass
  39. def load(self, adr, data):
  40. """load bytes into memory starting at a given address"""
  41. for i, val in enumerate(data):
  42. self.mem[adr + i] = val
  43. def load_file(self, adr, filename):
  44. """load file into memory starting at a given address"""
  45. for i, val in enumerate(open(filename, "rb").read()):
  46. self.mem[adr + i] = ord(val)
  47. #-----------------------------------------------------------------------------
  48. # Specific Memory Devices
  49. class ram(memory):
  50. """Read/Write Memory"""
  51. def __getitem__(self, adr):
  52. return self.mem[adr & self.mask]
  53. def __setitem__(self, adr, val):
  54. if val != self.mem[adr & self.mask]:
  55. self.wr_notify(adr)
  56. self.mem[adr & self.mask] = val
  57. class rom(memory):
  58. """Read Only Memory"""
  59. def __getitem__(self, adr):
  60. return self.mem[adr & self.mask]
  61. class wom(memory):
  62. """Write Only Memory"""
  63. def __setitem__(self, adr, val):
  64. if val != self.mem[adr & self.mask]:
  65. self.wr_notify(adr)
  66. self.mem[adr & self.mask] = val
  67. def rd(self, adr):
  68. """backdoor read"""
  69. return self.mem[adr & self.mask]
  70. class null(memory):
  71. """Unpopulated Memory"""
  72. pass
  73. #-----------------------------------------------------------------------------