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