OSDN Git Service

[VM][FMTOWNS][MEMORY] Integrate reading/writing beyond device boundary.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / towns_memory.h
1 /*
2         FUJITSU FM Towns Emulator 'eFMTowns'
3
4         Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2017.01.07 -
6
7         [ memory ]
8 */
9
10 #ifndef _TOWNS_MEMORY_H_
11 #define _TOWNS_MEMORY_H_
12
13 #include "device.h"
14 #include "../../common.h"
15 #include "../memory.h"
16 #include "./towns_common.h"
17
18 #define SIG_FMTOWNS_MACHINE_ID  1
19 #define SIG_MEMORY_EXTNMI       2
20
21 // MAP:
22 // 00000000 - 000fffff : SYSTEM RAM PAGE 0 (Similar to FMR-50).
23 // 00100000 - 3fffffff : EXTRA RAM (for i386 native mode.Page size is 1MB.)
24 // 40000000 - 7fffffff : External I/O BOX.Not accessible.
25 // 80000000 - bfffffff : VRAM (Reserved 01020000H bytes with earlier Towns.)
26 // c0000000 - c21fffff : ROM card and dictionaly/font/DOS ROMs.
27 // c2200000 - c2200fff : PCM RAM (Banked).
28 // c2201000 - fffbffff : Reserved.
29 // FFFC0000 - FFFFFFFF : Towns System ROM.
30
31 namespace FMTOWNS {
32 enum {
33         TOWNS_MEMORY_NORMAL = 0,
34         TOWNS_MEMORY_FMR_VRAM,
35         TOWNS_MEMORY_FMR_TEXT,
36         TOWNS_MEMORY_FMR_VRAM_RESERVE,
37         TOWNS_MEMORY_SPRITE_ANKCG1,
38         TOWNS_MEMORY_ANKCG2,
39
40         TOWNS_MEMORY_MMIO_0CC,
41
42         TOWNS_MEMORY_TYPE_EXT_MMIO,
43         TOWNS_MEMORY_TYPE_LEARN_RAM,
44         TOWNS_MEMORY_TYPE_WAVERAM,
45 };
46 }
47 // Please set from config
48 #define TOWNS_EXTRAM_PAGES 6
49
50 class BEEP;
51 class I386;
52
53 namespace FMTOWNS {
54         class TOWNS_VRAM;
55         class TOWNS_SPRITE;
56         class TOWNS_ROM_CARD;
57 }
58
59 namespace FMTOWNS {
60 #undef  TOWNS_MEMORY_MAP_SHIFT
61 #define TOWNS_MEMORY_MAP_SHIFT 15
62 #undef  TOWNS_MEMORY_MAP_SIZE
63 #define  TOWNS_MEMORY_MAP_SIZE  (1 << (32 - TOWNS_MEMORY_MAP_SHIFT))
64
65 class TOWNS_MEMORY : public DEVICE
66 {
67 protected:
68         enum {
69                 WAITVAL_RAM  = -1,
70                 WAITVAL_VRAM = -2,
71         };
72         DEVICE* d_vram;
73         DEVICE* d_sprite;       // 0x81000000 - 0x8101ffff ?
74         DEVICE* d_pcm;             // 0xc2200000 - 0xc2200fff
75         DEVICE* d_timer;
76         DEVICE* d_dmac;
77         DEVICE* d_crtc;
78         DEVICE* d_planevram;
79         I386*   d_cpu;
80
81         DEVICE* d_dictionary;
82         DEVICE* d_sysrom;
83         DEVICE* d_msdos;
84         DEVICE* d_serialrom;
85         DEVICE* d_font;
86         DEVICE* d_font_20pix;
87
88         DEVICE* d_iccard[2];
89         const uint32_t  NOT_NEED_TO_OFFSET = UINT32_MAX;
90
91         typedef struct memory_device_map_s {
92                 uint8_t* mem_ptr;
93                 DEVICE* device_ptr;
94                 uint32_t base_offset;
95                 int32_t  waitval;
96         } memory_device_map_t;
97         memory_device_map_t membus_read_map[TOWNS_MEMORY_MAP_SIZE];
98         memory_device_map_t membus_write_map[TOWNS_MEMORY_MAP_SIZE];
99         memory_device_map_t dma_read_map[TOWNS_MEMORY_MAP_SIZE];
100         memory_device_map_t dma_write_map[TOWNS_MEMORY_MAP_SIZE];
101
102         outputs_t outputs_ram_wait;
103         outputs_t outputs_rom_wait;
104
105         bool bankc0_vram;
106         bool ankcg_enabled;
107         bool select_d0_rom;
108         bool select_d0_dict;
109
110         uint16_t machine_id;
111         uint8_t cpu_id;
112         bool is_compatible;
113         bool dma_is_vram;
114
115         // RAM
116         uint8_t *extra_ram;                  // 0x00000000 - (0x3fffffff) : Size is defined by extram_size + 0x00100000;
117         uint32_t extram_size;
118         uint32_t cpu_clock_val;
119         uint32_t vram_wait_val;
120         uint32_t mem_wait_val;
121
122         uint8_t wait_register_older;  // 05E0h
123         uint8_t wait_register_ram;    // 05E2h
124         uint8_t wait_register_vram;   // 05E6h
125
126         bool extra_nmi_mask;
127         bool extra_nmi_val;
128         bool nmi_mask;
129         bool software_reset;
130         bool nmi_vector_protect;
131         bool poff_status;
132         bool reset_happened;
133
134         // misc
135         uint32_t vram_size; // Normally 512KB.
136         bool initialized;
137
138         // MISC1-MISC4
139         uint8_t reg_misc3; // 0024
140         uint8_t reg_misc4; // 0025
141
142         // Functions
143         virtual void reset_wait_values();
144         virtual void set_wait_values();
145         virtual void update_machine_features();
146         virtual void __FASTCALL config_page0f(const bool sysrombank, const bool force);
147         virtual void __FASTCALL config_page0c_0e(const bool vrambank, const bool dictbank, const bool force);
148
149         virtual bool set_cpu_clock_by_wait();
150         virtual void     __FASTCALL write_fmr_ports8(uint32_t addr, uint32_t data);
151         virtual uint8_t  __FASTCALL read_fmr_ports8(uint32_t addr);
152         virtual void     __FASTCALL write_sys_ports8(uint32_t addr, uint32_t data);
153         virtual uint8_t __FASTCALL read_sys_ports8(uint32_t addr);
154
155         void __FASTCALL set_memory_devices_map_values(uint32_t start, uint32_t end, memory_device_map_t* dataptr, uint8_t* baseptr, DEVICE* device, uint32_t base_offset = UINT32_MAX);
156         void __FASTCALL set_memory_devices_map_wait(uint32_t start, uint32_t end, memory_device_map_t* dataptr, int wait = WAITVAL_RAM);
157         void __FASTCALL unset_memory_devices_map(uint32_t start, uint32_t end, memory_device_map_t* dataptr, int wait = WAITVAL_RAM);
158
159         constexpr uint32_t read_beyond_boundary_data16(memory_device_map_t *_map, const uint32_t addr, const uint32_t offset, const uint32_t mapptr, const bool is_dma, int* wait)
160         {
161                 pair16_t w;
162                 int waitvals[2] = {0};
163                 if(is_dma) {
164                         w.b.l = read_dma_data8w(addr    , &(waitvals[0]));
165                         w.b.h = read_dma_data8w(addr + 1, &(waitvals[1]));
166                 } else {
167                         w.b.l = read_data8w(addr    , &(waitvals[0]));
168                         w.b.h = read_data8w(addr + 1, &(waitvals[1]));
169                 }
170                 __LIKELY_IF(wait != NULL) {
171                         *wait = waitvals[0];
172                         //*wait = waitvals[0] + waitvals[1];
173                 }
174                 return (uint32_t)(w.w);
175         }
176         constexpr uint32_t read_beyond_boundary_data32(memory_device_map_t *_map, const uint32_t addr, const uint32_t offset, const uint32_t mapptr, const bool is_dma, int* wait)
177         {
178                 pair32_t d;
179                 pair16_t w;
180                 int waitvals[3] = {0};
181                 switch(offset & 3) {
182                 case 1:
183                 case 3:
184                         if(is_dma) {
185                                 d.b.l  = read_dma_data8w (addr    , &(waitvals[0]));
186                                 w.w    = read_dma_data16w(addr + 1, &(waitvals[1]));
187                                 d.b.h3 = read_dma_data8w (addr + 3, &(waitvals[2]));
188                         } else {
189                                 d.b.l  = read_data8w (addr    ,  &(waitvals[0]));
190                                 w.w    = read_data16w(addr + 1,  &(waitvals[1]));
191                                 d.b.h3 = read_data8w (addr + 3,  &(waitvals[2]));
192                         }
193                         d.b.h  = w.b.l;
194                         d.b.h2 = w.b.h;
195                         break;
196                 case 2:
197                         if(is_dma) {
198                                 d.w.l  = read_dma_data16w(addr    ,  &(waitvals[0]));
199                                 d.w.h  = read_dma_data16w(addr + 2,  &(waitvals[1]));
200                         } else {
201                                 d.w.l  = read_data16w(addr    ,  &(waitvals[0]));
202                                 d.w.h  = read_data16w(addr + 2,  &(waitvals[1]));
203                         }
204                         break;
205                 default:
206                         d.d = 0xffffffff;
207                         waitvals[0] = _map[mapptr].waitval;
208                         break;
209                 }
210
211                 __LIKELY_IF(wait != NULL) {
212                         for(int i = 0; i < 2; i++) {
213                                 __UNLIKELY_IF(waitvals[i] < 0) {
214                                         waitvals[i] = (waitvals[i] == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
215                                 }
216                         }
217                         *wait = waitvals[0];
218                         //*wait = waitvals[0] + waitvals[1] + waitvals[2];
219                 }
220                 return d.d;
221         }
222
223         constexpr void write_beyond_boundary_data16(memory_device_map_t *_map, const uint32_t addr, const uint32_t offset, const uint32_t mapptr, const bool is_dma, uint32_t data, int* wait)
224         {
225                 pair16_t w;
226                 w.w = data;
227                 int waitvals[2] = {0};
228                 if(is_dma) {
229                         write_dma_data8w(addr    , w.b.l, &(waitvals[0]));
230                         write_dma_data8w(addr + 1, w.b.h, &(waitvals[1]));
231                 } else {
232                         write_data8w(addr    , w.b.l, &(waitvals[0]));
233                         write_data8w(addr + 1, w.b.h, &(waitvals[1]));
234                 }
235                 __LIKELY_IF(wait != NULL) {
236                         *wait = waitvals[0];
237                         //*wait = waitvals[0] + waitvals[1];
238                 }
239         }
240         constexpr void write_beyond_boundary_data32(memory_device_map_t *_map, const uint32_t addr, const uint32_t offset, const uint32_t mapptr, const bool is_dma, uint32_t data, int* wait)
241         {
242                 pair32_t d;
243                 pair16_t w;
244                 d.d = data;
245                 int waitvals[3] = {0};
246                 switch(offset & 3) {
247                 case 1:
248                 case 3:
249                         w.b.l = d.b.h;
250                         w.b.h = d.b.h2;
251                         if(is_dma) {
252                                 write_dma_data8w (addr    , d.b.l, &(waitvals[0]));
253                                 write_dma_data16w(addr + 1, w.w, &(waitvals[1]));
254                                 write_dma_data8w (addr + 3, d.b.h3, &(waitvals[2]));
255                         } else {
256                                 write_data8w (addr    , d.b.l, &(waitvals[0]));
257                                 write_data16w(addr + 1, w.w, &(waitvals[1]));
258                                 write_data8w (addr + 3, d.b.h3, &(waitvals[2]));
259                         }
260                         break;
261                 case 2:
262                         if(is_dma) {
263                                 write_dma_data16w(addr    , d.w.l, &(waitvals[0]));
264                                 write_dma_data16w(addr + 2, d.w.h, &(waitvals[1]));
265                         } else {
266                                 write_data16w(addr    , d.w.l, &(waitvals[0]));
267                                 write_data16w(addr + 2, d.w.h, &(waitvals[1]));
268                         }
269                         break;
270                 default:
271                         waitvals[0] = _map[mapptr].waitval;
272                         break;
273                 }
274
275                 __LIKELY_IF(wait != NULL) {
276                         for(int i = 0; i < 2; i++) {
277                                 __UNLIKELY_IF(waitvals[i] < 0) {
278                                         waitvals[i] = (waitvals[i] == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
279                                 }
280                         }
281                         *wait = waitvals[0];
282                         //*wait = waitvals[0] + waitvals[1] + waitvals[2];
283                 }
284         }
285
286         constexpr bool check_device_boundary(memory_device_map_t *_map, uint32_t offset, uint32_t mapptr, const uint8_t bytewidth)
287         {
288                 __UNLIKELY_IF((offset + bytewidth) > memory_map_grain()) {
289                         __LIKELY_IF(mapptr < memory_map_size()) {
290                                 __LIKELY_IF((_map[mapptr].device_ptr == _map[mapptr + 1].device_ptr) && (_map[mapptr].mem_ptr == _map[mapptr + 1].mem_ptr)) {
291                                         return false;
292                                 }
293                                 return true;
294                         } else {
295                                 return true;
296                         }
297                 }
298                 return false;
299         }
300         constexpr uint32_t read_8bit_data(memory_device_map_t *_map, uint32_t mapptr, uint32_t addr, uint32_t offset, const bool is_dma, int* wait)
301         {
302                 uint8_t val = 0xff;
303                 int waitval;
304                 uint32_t base = _map[mapptr].base_offset;
305                 __LIKELY_IF(_map[mapptr].mem_ptr != NULL) {
306                         uint8_t* ptr = _map[mapptr].mem_ptr;
307                         __UNLIKELY_IF(base == UINT32_MAX) {
308                                 base = 0;
309                         }
310                         val = ptr[offset + base];
311                 } else if(_map[mapptr].device_ptr != NULL) {
312                         DEVICE* dev = _map[mapptr].device_ptr;
313                         __LIKELY_IF(base == UINT32_MAX) {
314                                 offset = addr;
315                         } else {
316                                 offset += base;
317                         }
318                         const bool is_this = (dev == this);
319                         if((is_dma) && !(is_this)) {
320                                 val = dev->read_dma_data8(offset);
321                         } else {
322                                 val = dev->read_memory_mapped_io8(offset);
323                         }
324                 }
325                 __LIKELY_IF(wait != NULL) {
326                         waitval = _map[mapptr].waitval;
327                         __LIKELY_IF(waitval < 0) {
328                                 waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
329                         }
330                         *wait = waitval;
331                 }
332                 return val;
333         }
334         constexpr uint32_t read_16bit_data(memory_device_map_t *_map, uint32_t mapptr, uint32_t addr, uint32_t offset, const bool is_dma, int* wait)
335         {
336                 uint16_t val = 0xffff;
337                 int waitval;
338                 uint32_t base = _map[mapptr].base_offset;
339                 __LIKELY_IF(_map[mapptr].mem_ptr != NULL) {
340                         uint8_t* ptr = _map[mapptr].mem_ptr;
341                         __UNLIKELY_IF(base == UINT32_MAX) {
342                                 base = 0;
343                         }
344                         ptr = &(ptr[offset + base]);
345                         pair16_t w;
346                         w.read_2bytes_le_from(ptr);
347                         val = w.w;
348                 } else if(_map[mapptr].device_ptr != NULL) {
349                         DEVICE* dev = _map[mapptr].device_ptr;
350                         __LIKELY_IF(base == UINT32_MAX) {
351                                 offset = addr;
352                         } else {
353                                 offset += base;
354                         }
355                         const bool is_this = (dev == this);
356                         if((is_dma) && !(is_this)) {
357                                 val = dev->read_dma_data16(offset);
358                         } else {
359                                 val = dev->read_memory_mapped_io16(offset);
360                         }
361                 }
362                 __LIKELY_IF(wait != NULL) {
363                         waitval = _map[mapptr].waitval;
364                         __LIKELY_IF(waitval < 0) {
365                                 waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
366                         }
367                         //__LIKELY_IF((offset & 1) == 0) {
368                         *wait = waitval;
369                         //} else {
370                         //      *wait = waitval * 2;
371                         //}
372                 }
373                 return val;
374         }
375         constexpr uint32_t read_32bit_data(memory_device_map_t *_map, uint32_t mapptr, uint32_t addr, uint32_t offset, const bool is_dma, int* wait)
376         {
377                 uint32_t val = 0xffffffff;
378                 uint32_t base = _map[mapptr].base_offset;
379                 __LIKELY_IF(_map[mapptr].mem_ptr != NULL) {
380                         uint8_t* ptr = _map[mapptr].mem_ptr;
381                         __UNLIKELY_IF(base == UINT32_MAX) {
382                                 base = 0;
383                         }
384                         ptr = &(ptr[offset + base]);
385                         pair32_t d;
386                         d.read_4bytes_le_from(ptr);
387                         val = d.d;
388                 } else if(_map[mapptr].device_ptr != NULL) {
389                         DEVICE* dev = _map[mapptr].device_ptr;
390                         __LIKELY_IF(base == UINT32_MAX) {
391                                 offset = addr;
392                         } else {
393                                 offset += base;
394                         }
395                         const bool is_this = (dev == this);
396                         if((is_dma) && !(is_this)) {
397                                 val = dev->read_dma_data32(offset);
398                         } else {
399                                 val = dev->read_memory_mapped_io32(offset);
400                         }
401                 }
402                 __LIKELY_IF(wait != NULL) {
403                         int waitval = _map[mapptr].waitval;
404                         __LIKELY_IF(waitval < 0) {
405                                 waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
406                         }
407                         //__LIKELY_IF((offset & 1) == 0) {
408                         *wait = waitval;
409                         //} else {
410                         //      *wait = waitval * 2;
411                         //}
412                 }
413                 return val;
414         }
415         constexpr void write_8bit_data(memory_device_map_t *_map, uint32_t mapptr, uint32_t addr, uint32_t offset, const bool is_dma, uint32_t data, int* wait)
416         {
417                 int waitval;
418                 uint32_t base = _map[mapptr].base_offset;
419                 __LIKELY_IF(_map[mapptr].mem_ptr != NULL) {
420                         uint8_t* ptr = _map[mapptr].mem_ptr;
421                         __UNLIKELY_IF(base == UINT32_MAX) {
422                                 base = 0;
423                         }
424                         ptr[offset + base] = data;
425                 } else if(_map[mapptr].device_ptr != NULL) {
426                         DEVICE* dev = _map[mapptr].device_ptr;
427                         __LIKELY_IF(base == UINT32_MAX) {
428                                 offset = addr;
429                         } else {
430                                 offset += base;
431                         }
432                         const bool is_this = (dev == this);
433                         if((is_dma) && !(is_this)) {
434                                 dev->write_dma_data8(offset, data);
435                         } else {
436                                 dev->write_memory_mapped_io8(offset, data);
437                         }
438                 }
439                 __LIKELY_IF(wait != NULL) {
440                         waitval = _map[mapptr].waitval;
441                         __LIKELY_IF(waitval < 0) {
442                                 waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
443                         }
444                         *wait = waitval;
445                 }
446         }
447
448         constexpr void write_16bit_data(memory_device_map_t *_map, uint32_t mapptr, uint32_t addr, uint32_t offset, const bool is_dma, uint32_t data, int* wait)
449         {
450                 int waitval;
451                 uint32_t base = _map[mapptr].base_offset;
452                 __LIKELY_IF(_map[mapptr].mem_ptr != NULL) {
453                         uint8_t* ptr = _map[mapptr].mem_ptr;
454                         __UNLIKELY_IF(base == UINT32_MAX) {
455                                 base = 0;
456                         }
457                         ptr = &(ptr[offset + base]);
458                         pair16_t w;
459                         w.w = data;
460                         w.write_2bytes_le_to(ptr);
461                 } else if(_map[mapptr].device_ptr != NULL) {
462                         DEVICE* dev = _map[mapptr].device_ptr;
463                         __LIKELY_IF(base == UINT32_MAX) {
464                                 offset = addr;
465                         } else {
466                                 offset += base;
467                         }
468                         const bool is_this = (dev == this);
469                         if((is_dma) && !(is_this)) {
470                                 dev->write_dma_data16(offset, data);
471                         } else {
472                                 dev->write_memory_mapped_io16(offset, data);
473                         }
474                 }
475                 __LIKELY_IF(wait != NULL) {
476                         waitval = _map[mapptr].waitval;
477                         __LIKELY_IF(waitval < 0) {
478                                 waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
479                         }
480                         //__LIKELY_IF((offset & 1) == 0) {
481                         *wait = waitval;
482                         //} else {
483                         //      *wait = waitval * 2;
484                         //}
485                 }
486         }
487         constexpr void write_32bit_data(memory_device_map_t *_map, uint32_t mapptr, uint32_t addr, uint32_t offset, const bool is_dma, uint32_t data, int* wait)
488         {
489                 uint32_t base = _map[mapptr].base_offset;
490                 __LIKELY_IF(_map[mapptr].mem_ptr != NULL) {
491                         uint8_t* ptr = _map[mapptr].mem_ptr;
492                         __UNLIKELY_IF(base == UINT32_MAX) {
493                                 base = 0;
494                         }
495                         ptr = &(ptr[offset + base]);
496                         pair32_t d;
497                         d.d = data;
498                         d.write_4bytes_le_to(ptr);
499                 } else if(_map[mapptr].device_ptr != NULL) {
500                         DEVICE* dev = _map[mapptr].device_ptr;
501                         __LIKELY_IF(base == UINT32_MAX) {
502                                 offset = addr;
503                         } else {
504                                 offset += base;
505                         }
506                         const bool is_this = (dev == this);
507                         if((is_dma) && !(is_this)) {
508                                 dev->write_dma_data32(offset, data);
509                         } else {
510                                 dev->write_memory_mapped_io32(offset, data);
511                         }
512                 }
513                 __LIKELY_IF(wait != NULL) {
514                         int waitval = _map[mapptr].waitval;
515                         __LIKELY_IF(waitval < 0) {
516                                 waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
517                         }
518                         //__LIKELY_IF((offset & 1) == 0) {
519                         *wait = waitval;
520                         //} else {
521                         //      *wait = waitval * 2;
522                         //}
523                 }
524         }
525         inline bool is_faster_wait()
526         {
527                 return ((mem_wait_val == 0) && (vram_wait_val < 3)) ? true : false;
528         }
529         /*!
530           @note Use memory map per 32KB (131072 entries) as 1st tier.
531                 And, at Some pages hadles special devices,
532                         000C8000h - 000CFFFFh : this
533                         C2140000h - C2141FFFh : DICTIONARY (CMOS)
534                         C2200000h - C2200FFFh : RF5C68 (PCM SOUND)
535                         MAP select usage:
536         */
537         inline const uint64_t memory_map_size()  { return TOWNS_MEMORY_MAP_SIZE; }
538         inline const uint64_t memory_map_shift() { return TOWNS_MEMORY_MAP_SHIFT; }
539         constexpr uint64_t memory_map_mask() { return ((1 << TOWNS_MEMORY_MAP_SHIFT) - 1); }
540         constexpr uint64_t memory_map_grain() { return (1 << TOWNS_MEMORY_MAP_SHIFT); }
541
542 public:
543         TOWNS_MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) {
544                 set_device_name(_T("FMTOWNS_MEMORY"));
545
546                 extram_size = 0x00200000; // Basically 2MB
547
548                 d_cpu = NULL;
549
550                 d_vram = NULL;
551                 d_sprite = NULL;
552                 d_pcm = NULL;
553                 d_timer = NULL;
554                 d_dmac = NULL;
555                 d_crtc = NULL;
556                 d_planevram = NULL;
557                 d_iccard[0] = NULL;
558                 d_iccard[1] = NULL;
559
560                 d_dictionary = NULL;
561                 d_sysrom = NULL;
562                 d_msdos = NULL;
563                 d_serialrom = NULL;
564                 d_font = NULL;
565                 d_font_20pix = NULL;
566                 initialized = false;
567
568                 initialize_output_signals(&outputs_ram_wait);
569                 initialize_output_signals(&outputs_rom_wait);
570                 // Note: machine id must set before initialize() from set_context_machine_id() by VM::VM().
571                 // machine_id = 0x0100;   // FM-Towns 1,2
572                 // machine_id = 0x0200 // FM-Towns  1F/2F/1H/2H
573                 // machine_id = 0x0300 // FM-Towns  UX10/UX20/UX40
574                 // machine_id = 0x0400 // FM-Towns  10F/20F/40H/80H
575                 // machine_id = 0x0500 // FM-Towns2 CX10/CX20/CX40/CX100
576                 // machine_id = 0x0600 // FM-Towns2 UG10/UG20/UG40/UG80
577                 // machine_id = 0x0700 // FM-Towns2 HR20/HR100/HR200
578                 // machine_id = 0x0800 // FM-Towns2 HG20/HG40/HG100
579                 // machine_id = 0x0900 // FM-Towns2 UR20/UR40/UR80
580                 // machine_id = 0x0b00 // FM-Towns2 MA20/MA170/MA340
581                 // machine_id = 0x0c00 // FM-Towns2 MX20/MX170/MX340
582                 // machine_id = 0x0d00 // FM-Towns2 ME20/ME170
583                 // machine_id = 0x0f00 // FM-Towns2 MF20/MF170/Fresh
584                 machine_id = 0x0100;   // FM-Towns 1,2
585
586                 // Note: cpu id must set before initialize() from set_context_cpu_id() by VM::VM().
587                 // cpu_id = 0x00; // 80286.
588                 // cpu_id = 0x01; // 80386DX.
589                 // cpu_id = 0x02; // 80486SX/DX.
590                 // cpu_id = 0x03; // 80386SX.
591                 cpu_id = 0x01; // 80386DX.
592
593                 unset_mmio_rw(0x00000000, 0xffffffff);
594                 unset_dma_rw(0x00000000, 0xffffffff);
595                 extra_ram = NULL;
596         }
597         ~TOWNS_MEMORY() {}
598
599         // common functions
600         void initialize() override;
601         void release() override;
602         void reset() override;
603
604         virtual uint32_t __FASTCALL read_data8w(uint32_t addr, int* wait) override;
605         virtual uint32_t __FASTCALL read_data16w(uint32_t addr, int* wait) override;
606         virtual uint32_t __FASTCALL read_data32w(uint32_t addr, int* wait) override;
607
608         virtual void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait) override;
609         virtual void __FASTCALL write_data16w(uint32_t addr, uint32_t data, int* wait) override;
610         virtual void __FASTCALL write_data32w(uint32_t addr, uint32_t data, int* wait) override;
611
612         virtual uint32_t __FASTCALL read_dma_data8w(uint32_t addr, int* wait) override;
613         virtual uint32_t __FASTCALL read_dma_data16w(uint32_t addr, int* wait) override;
614         virtual uint32_t __FASTCALL read_dma_data32w(uint32_t addr, int* wait) override;
615         virtual void __FASTCALL write_dma_data8w(uint32_t addr, uint32_t data, int* wait) override;
616         virtual void __FASTCALL write_dma_data16w(uint32_t addr, uint32_t data, int* wait) override;
617         virtual void __FASTCALL write_dma_data32w(uint32_t addr, uint32_t data, int* wait) override;
618
619         virtual void     __FASTCALL write_io8(uint32_t addr, uint32_t data) override;
620         virtual uint32_t __FASTCALL read_io8(uint32_t addr) override;
621
622         virtual void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data) override;
623         virtual uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr) override;
624
625         virtual void __FASTCALL write_memory_mapped_io16(uint32_t addr, uint32_t data) override;
626         virtual uint32_t __FASTCALL read_memory_mapped_io16(uint32_t addr) override;
627 ;
628         virtual void __FASTCALL write_memory_mapped_io32(uint32_t addr, uint32_t data) override;
629         virtual uint32_t __FASTCALL read_memory_mapped_io32(uint32_t addr) override;
630
631         virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask) override;
632         virtual uint32_t __FASTCALL read_signal(int ch) override;
633
634         //void event_frame();
635         virtual void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit) override;
636
637         bool process_state(FILEIO* state_fio, bool loading) override;
638
639         // unique functions
640         void set_extra_ram_size(uint32_t megabytes)
641         {
642                 uint32_t limit = 5;
643                 uint32_t minimum = 2;
644                 switch((machine_id & 0xff00) >> 8) {
645                 case 0x00:
646                 case 0x01: // Towns 1/2 : Not Supported.
647                         minimum = 1;
648                         break;
649                 case 0x03: // TOWNS2 UX
650                 case 0x06: // TOWNS2 UG
651                         minimum = 1;
652                         limit = 9; // 2MB + 4MB x 2? - 1MB
653                         break;
654                 case 0x02: // TOWNS 2F/2H
655                 case 0x04: // TOWNS 10F/10H/20F/20H
656                         minimum = 1;
657                         limit = 7; // 2MB + 2MB x 3
658                         break;
659                 case 0x05: // TOWNS II CX
660                 case 0x08: // TOWNS II HG
661                         limit = 15; // 8MB x 2 - 1MB?
662                         break;
663                 case 0x07: // Towns II HR
664                 case 0x09: // Towns II UR
665                         limit = 31; // 16MB x 2 - 1MB?
666                         break;
667                 default:   // After MA/MX/ME/MF, Fresh
668                         limit = 127; // 128MB - 1MB?
669                         break;
670                 }
671                 if(megabytes > limit) megabytes = limit;
672                 if(megabytes < minimum) megabytes = minimum;
673                 extram_size = megabytes << 20;
674         }
675
676         virtual void __FASTCALL set_mmio_memory_r(uint32_t start, uint32_t end, uint8_t* ptr, uint32_t base_offset = 0);
677         virtual void __FASTCALL set_mmio_memory_w(uint32_t start, uint32_t end, uint8_t* ptr, uint32_t base_offset = 0);
678         inline  void __FASTCALL set_mmio_memory_rw(uint32_t start, uint32_t end, uint8_t* ptr, uint32_t base_offset = 0)
679         {
680                 set_mmio_memory_r(start, end, ptr, base_offset);
681                 set_mmio_memory_w(start, end, ptr, base_offset);
682         }
683
684         virtual void  __FASTCALL set_mmio_wait_r(uint32_t start, uint32_t end, int wait);
685         virtual void  __FASTCALL set_mmio_wait_w(uint32_t start, uint32_t end, int wait);
686         inline void  __FASTCALL set_mmio_wait_rw(uint32_t start, uint32_t end, int wait)
687         {
688                 set_mmio_wait_r(start, end, wait);
689                 set_mmio_wait_w(start, end, wait);
690         }
691
692         virtual void  __FASTCALL set_mmio_device_r(uint32_t start, uint32_t end, DEVICE* baseptr, uint32_t baseaddress = UINT32_MAX);
693         virtual void  __FASTCALL set_mmio_device_w(uint32_t start, uint32_t end, DEVICE* baseptr, uint32_t baseaddress = UINT32_MAX);
694         inline void  __FASTCALL set_mmio_device_rw(uint32_t start, uint32_t end, DEVICE* baseptr, uint32_t baseaddress = UINT32_MAX)
695         {
696                 set_mmio_device_r(start, end, baseptr, baseaddress);
697                 set_mmio_device_w(start, end, baseptr, baseaddress);
698         }
699
700         virtual void  __FASTCALL set_dma_memory_r(uint32_t start, uint32_t end, uint8_t* ptr, uint32_t base_offset = 0);
701         virtual void  __FASTCALL set_dma_memory_w(uint32_t start, uint32_t end, uint8_t* ptr, uint32_t base_offset = 0);
702         inline void  __FASTCALL set_dma_memory_rw(uint32_t start, uint32_t end, uint8_t* ptr, uint32_t base_offset = 0)
703         {
704                 set_dma_memory_r(start, end, ptr, base_offset);
705                 set_dma_memory_w(start, end, ptr, base_offset);
706         }
707
708         virtual void  __FASTCALL set_dma_wait_r(uint32_t start, uint32_t end, int wait);
709         virtual void  __FASTCALL set_dma_wait_w(uint32_t start, uint32_t end, int wait);
710         inline void  __FASTCALL set_dma_wait_rw(uint32_t start, uint32_t end, int wait)
711         {
712                 set_dma_wait_r(start, end, wait);
713                 set_dma_wait_w(start, end, wait);
714         }
715
716         virtual void  __FASTCALL set_dma_device_r(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress = UINT32_MAX);
717         virtual void  __FASTCALL set_dma_device_w(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress = UINT32_MAX);
718         inline void  __FASTCALL set_dma_device_rw(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress = UINT32_MAX)
719         {
720                 set_dma_device_r(start, end, ptr, baseaddress);
721                 set_dma_device_w(start, end, ptr, baseaddress);
722         }
723
724         inline void __FASTCALL set_region_memory_r(uint32_t start, uint32_t end, uint8_t* baseptr, uint32_t base_offset = 0)
725         {
726                 set_mmio_memory_r(start, end, baseptr, base_offset);
727                 set_dma_memory_r (start, end, baseptr, base_offset);
728         }
729
730         inline void __FASTCALL set_region_memory_w(uint32_t start, uint32_t end, uint8_t* baseptr,uint32_t base_offset = 0)
731         {
732                 set_mmio_memory_w(start, end, baseptr, base_offset);
733                 set_dma_memory_w (start, end, baseptr, base_offset);
734         }
735         inline void __FASTCALL set_region_memory_rw(uint32_t start, uint32_t end, uint8_t* baseptr, uint32_t base_offset = 0)
736         {
737                 set_region_memory_r(start, end, baseptr, base_offset);
738                 set_region_memory_w(start, end, baseptr, base_offset);
739         }
740
741         inline void __FASTCALL set_region_device_r(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress = UINT32_MAX)
742         {
743                 set_mmio_device_r(start, end, ptr, baseaddress);
744                 set_dma_device_r (start, end, ptr, baseaddress);
745         }
746         inline void __FASTCALL set_region_device_w(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress = UINT32_MAX)
747         {
748                 set_mmio_device_w(start, end, ptr, baseaddress);
749                 set_dma_device_w (start, end, ptr, baseaddress);
750         }
751         inline void __FASTCALL set_region_device_rw(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress = UINT32_MAX)
752         {
753                 set_region_device_r(start, end, ptr, baseaddress);
754                 set_region_device_w(start, end, ptr, baseaddress);
755         }
756         virtual void  __FASTCALL unset_mmio_r(uint32_t start, uint32_t end, int wait = WAITVAL_RAM);
757         virtual void  __FASTCALL unset_mmio_w(uint32_t start, uint32_t end, int wait = WAITVAL_RAM);
758         inline  void  __FASTCALL unset_mmio_rw(uint32_t start, uint32_t end, int wait = WAITVAL_RAM)
759         {
760                 unset_mmio_r(start, end, wait);
761                 unset_mmio_w(start, end, wait);
762         }
763
764         virtual void  __FASTCALL unset_dma_r(uint32_t start, uint32_t end, int wait = WAITVAL_RAM);
765         virtual void  __FASTCALL unset_dma_w(uint32_t start, uint32_t end, int wait = WAITVAL_RAM);
766         inline void  __FASTCALL  unset_dma_rw(uint32_t start, uint32_t end, int wait = WAITVAL_RAM)
767         {
768                 unset_dma_r(start, end, wait);
769                 unset_dma_w(start, end, wait);
770         }
771
772         inline void  __FASTCALL unset_range_r(uint32_t start, uint32_t end, int wait = WAITVAL_RAM)
773         {
774                 unset_mmio_r(start, end, wait);
775                 unset_dma_r(start, end, wait);
776         }
777
778         inline void  __FASTCALL unset_range_w(uint32_t start, uint32_t end, int wait = WAITVAL_RAM)
779         {
780                 unset_mmio_w(start, end, wait);
781                 unset_dma_w(start, end, wait);
782         }
783         inline void  __FASTCALL unset_range_rw(uint32_t start, uint32_t end, int wait = WAITVAL_RAM)
784         {
785                 unset_range_r(start, end, wait);
786                 unset_range_w(start, end, wait);
787         }
788
789         void set_context_cpu(I386* device)
790         {
791                 d_cpu = device;
792         }
793         void set_context_dmac(DEVICE* device)
794         {
795                 d_dmac = device;
796         }
797         virtual void set_context_vram(DEVICE* device)
798         {
799                 d_vram = device;
800
801         }
802         void set_context_system_rom(DEVICE* device)
803         {
804                 d_sysrom = device;
805         }
806         void set_context_font_rom(DEVICE* device)
807         {
808                 d_font = device;
809         }
810         void set_context_font_20pix_rom(DEVICE* device)
811         {
812                 d_font_20pix = device;
813         }
814         void set_context_dictionary(DEVICE* device)
815         {
816                 d_dictionary = device;
817         }
818         void set_context_msdos(DEVICE* device)
819         {
820                 d_msdos = device;
821         }
822         void set_context_timer(DEVICE* device)
823         {
824                 d_timer = device;
825         }
826         void set_context_sprite(DEVICE* device)
827         {
828                 d_sprite = device;
829         }
830         void set_context_crtc(DEVICE* device)
831         {
832                 d_crtc = device;
833         }
834         void set_context_iccard(DEVICE* device, int num)
835         {
836                 d_iccard[num & 1] = device;
837         }
838         void set_context_pcm(DEVICE* device)
839         {
840                 d_pcm = device;
841         }
842         void set_context_serial_rom(DEVICE* device)
843         {
844                 d_serialrom = device;
845         }
846         void set_context_planevram(DEVICE *dev)
847         {
848                 d_planevram = dev;
849         }
850         void set_machine_id(uint16_t val)
851         {
852                 machine_id = val & 0xfff8;
853         }
854         void set_cpu_id(uint16_t val)
855         {
856                 cpu_id = val & 0x07;
857         }
858 };
859
860
861 }
862 #endif