1 /* 2 * KCemu -- The emulator for the KC85 homecomputer series and much more. 3 * Copyright (C) 1997-2010 Torsten Paul 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #ifndef __kc_memory_h 21 #define __kc_memory_h 22 23 #include <list> 24 #include <iostream> 25 26 #include "kc/system.h" 27 28 #include "kc/ic.h" 29 30 typedef enum { MEM_DISABLED, MEM_WRITE_PROTECT, MEM_ENABLED } MemState; 31 32 class MemArea; 33 class MemAreaPtr; 34 class MemAreaGroup; 35 36 class MemArea 37 { 38 public: 39 enum page_vals { 40 PAGE_SHIFT = 10, 41 PAGES = 64, 42 PAGE_MASK = 0x3ff, 43 PAGE_SIZE = 0x400 44 }; 45 46 private: 47 int _prio; 48 word_t _addr; 49 bool _active; 50 bool _readonly; 51 bool _read_through; 52 bool _write_through; 53 byte_t *_mem, *_mem_r, *_mem_w; 54 static byte_t *_scratch_r, *_scratch_w; 55 MemAreaGroup *_group; 56 57 public: 58 MemArea(MemAreaGroup *group, byte_t *mem, word_t addr, 59 int prio, bool ro); 60 virtual ~MemArea(void); 61 62 const char * get_name(void); 63 word_t get_addr(void); 64 int get_prio(void); 65 void set_active(bool active); 66 void set_readonly(bool ro); 67 void set_read_through(bool rt); 68 void set_write_through(bool wt); is_active(void)69 inline bool is_active(void) { return _active; } is_readonly(void)70 inline bool is_readonly(void) { return _readonly; } is_read_through(void)71 inline bool is_read_through(void) { return _read_through; } is_write_through(void)72 inline bool is_write_through(void) { return _write_through; } get_read_ptr(void)73 inline byte_t * get_read_ptr(void) { return _mem_r; } get_write_ptr(void)74 inline byte_t * get_write_ptr(void) { return _mem_w; } PAGE_INDEX(dword_t addr)75 static inline int PAGE_INDEX(dword_t addr) { return addr >> PAGE_SHIFT; } PAGE_ADDR(int idx)76 static inline word_t PAGE_ADDR(int idx) { return idx << PAGE_SHIFT; } 77 }; 78 79 class MemAreaGroup 80 { 81 private: 82 typedef std::list<MemArea *> mem_area_list_t; 83 84 private: 85 int _prio; 86 bool _active; 87 bool _readonly; 88 bool _read_through; 89 bool _write_through; 90 word_t _addr; 91 dword_t _size; 92 byte_t *_mem; 93 char *_name; 94 mem_area_list_t _l; 95 96 public: 97 MemAreaGroup(const char *name, word_t addr, dword_t size, 98 byte_t *mem, int prio, bool ro); 99 virtual ~MemAreaGroup(void); 100 101 void add(MemAreaPtr *area_ptr[]); 102 void remove(MemAreaPtr *area_ptr[]); 103 void set_active(bool active); 104 void set_readonly(bool ro); 105 void set_read_through(bool rt); 106 void set_write_through(bool wt); is_active(void)107 inline bool is_active(void) { return _active; } is_readonly(void)108 inline bool is_readonly(void) { return _readonly; } is_read_through(void)109 inline bool is_read_through(void) { return _read_through; } is_write_through(void)110 inline bool is_write_through(void) { return _write_through; } get_name(void)111 inline const char *get_name(void) { return _name; } 112 }; 113 114 class MemAreaPtr 115 { 116 private: 117 typedef std::list<MemArea *> mem_area_list_t; 118 119 mem_area_list_t _l; 120 121 public: 122 MemAreaPtr(void); 123 void add(MemArea *area); 124 void remove(MemArea *area); 125 void info(void); size(void)126 inline int size(void) 127 { 128 return _l.size(); 129 } 130 byte_t * get_read_ptr(void); 131 byte_t * get_write_ptr(void); 132 }; 133 134 typedef struct { 135 MemAreaGroup **group; 136 const char *name; 137 word_t addr; 138 dword_t size; 139 byte_t *mem; 140 int prio; 141 bool ro; 142 bool active; 143 int model; 144 } memory_group_t; 145 146 class Memory : public InterfaceCircuit 147 { 148 private: 149 MemAreaPtr *_mem_ptr[MemArea::PAGES]; 150 151 static unsigned int seed_x; /* the seeds for... */ 152 static unsigned int seed_y; /* ...the pseudo random... */ 153 static unsigned int seed_z; /* ...number generator */ 154 155 public: 156 byte_t *_memrptr[MemArea::PAGES]; 157 byte_t *_memwptr[MemArea::PAGES]; 158 159 static bool load_rom(const char *key, void *buf); 160 static bool load_rom(const char *filename, void *buf, long len, bool force); 161 162 protected: 163 static unsigned int mem_rand(); 164 static void mem_rand_seed(unsigned int seed1, unsigned int seed2, unsigned int seed3); 165 166 void init_memory_groups(memory_group_t mem[]); 167 virtual void loadRAM(const char *filename, word_t addr); 168 169 void * get_page_addr_r(word_t addr); 170 void * get_page_addr_w(word_t addr); 171 172 public: 173 Memory(void); 174 virtual ~Memory(void); 175 176 static void scratch_mem(byte_t *ptr, int len); 177 178 virtual void dump(word_t addr); 179 virtual void loadRAM(const char *filename); 180 virtual bool loadRAM(std::istream *is, word_t addr); 181 virtual bool loadRAM_Z1013(std::istream *is, word_t addr); 182 virtual bool loadRAM(std::istream *is, bool with_block_nr = false); 183 virtual void info(void); 184 virtual MemAreaPtr ** get_mem_ptr(void); 185 virtual MemAreaGroup * register_memory(const char *name, 186 word_t addr, dword_t size, 187 byte_t *mem, int prio, 188 bool ro); 189 virtual void unregister_memory(MemAreaGroup *group); 190 virtual void reload_mem_ptr(void); 191 192 virtual void dumpCore(void) = 0; 193 virtual byte_t memRead8(word_t addr) = 0; 194 virtual void memWrite8(word_t addr, byte_t val) = 0; 195 virtual byte_t * get_irm(void) = 0; 196 virtual byte_t * get_char_rom(void) = 0; 197 198 /* 199 * InterfaceCircuit 200 */ reti(void)201 virtual void reti(void) {} irqreq(void)202 virtual void irqreq(void) {} irqack()203 virtual word_t irqack() { return IRQ_NOT_ACK; } 204 virtual void reset(bool power_on = false) = 0; 205 }; 206 207 #endif /* __kc_memory_h */ 208