OSDN Git Service

[VM][FMTOWNS][MEMORY] Remove read_io8w() and write_io8w() .
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / towns_memory.cpp
1 /*
2         FUJITSU FM Towns Emulator 'eFMTowns'
3
4         Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2017.01.01 -
6
7         [memory]
8 */
9
10 #include "../../fileio.h"
11 #include "./towns_memory.h"
12 #include "./dmac.h"
13 #include "./vram.h"
14 #include "./planevram.h"
15 #include "./sprite.h"
16 #include "./fontroms.h"
17 #include "./serialrom.h"
18 #include "./crtc.h"
19 #include "./timer.h"
20
21 #include "../i386_np21.h"
22 //#include "../i386.h"
23
24 #include <math.h>
25
26 namespace FMTOWNS {
27
28 void TOWNS_MEMORY::initialize()
29 {
30         if(initialized) return;
31         //MEMORY::initialize();
32
33         update_machine_features();
34         extra_nmi_mask = true;
35         extra_nmi_val = false;
36         poff_status = false;
37         reset_happened = false;
38
39         vram_wait_val = 6;
40         mem_wait_val = 3;
41 //      if((cpu_id == 0x01) || (cpu_id == 0x03)) {
42 //              wait_register_older = vram_wait_val;
43 //              wait_register_vram = vram_wait_val;
44 //              wait_register_ram = mem_wait_val;
45 //      } else {
46                 wait_register_older  = 3;
47                 wait_register_vram = 0x06;
48                 wait_register_ram  = 0x03;
49 //      }
50         //cpu_clock_val = 16 * 1000 * 1000;
51         //cpu_clock_val = get_cpu_clocks(d_cpu);
52         set_cpu_clock_by_wait();
53         extram_size = extram_size & 0x3ff00000;
54         set_extra_ram_size(extram_size >> 20); // Check extra ram size.
55
56         unset_range_rw(0x00000000, 0xffffffff);
57
58         reset_wait_values();
59
60         set_region_memory_rw(0x00000000, 0x000bffff, ram_page0);
61         set_region_memory_rw(0x000c0000, 0x000fffff, ram_pagec);
62         memset(ram_page0, 0x00, sizeof(ram_page0));
63         memset(ram_pagec, 0x00, sizeof(ram_pagec));
64
65         if(extram_size >= 0x00100000) {
66                 __UNLIKELY_IF(extra_ram == NULL) {
67                         extra_ram = (uint8_t*)malloc(extram_size);
68                         __LIKELY_IF(extra_ram != NULL) {
69                                 set_region_memory_rw(0x00100000, (extram_size + 0x00100000) - 1, extra_ram);
70                                 memset(extra_ram, 0x00, extram_size);
71                         }
72                 }
73         }
74
75
76         initialized = true;
77
78         // Lower 100000h
79
80         config_page0c_0e(true, false, true);
81         config_page0f(true, true);
82
83         set_region_device_rw(0x80000000, 0x8007ffff, d_vram, NOT_NEED_TO_OFFSET);
84         set_region_device_rw(0x80100000, 0x8017ffff, d_vram, NOT_NEED_TO_OFFSET);
85
86         set_region_device_rw(0x81000000, 0x8101ffff, d_sprite, NOT_NEED_TO_OFFSET);
87         set_region_device_rw(0xc0000000, 0xc0ffffff, d_iccard[0], 0);
88         set_region_device_rw(0xc1000000, 0xc1ffffff, d_iccard[1], 0);
89 //      set_wait_rw(0x00000000, 0xffffffff,  vram_wait_val);
90
91         set_region_device_r (0xc2000000, 0xc207ffff, d_msdos, NOT_NEED_TO_OFFSET);
92         set_region_device_r (0xc2080000, 0xc20fffff, d_dictionary, NOT_NEED_TO_OFFSET);
93         set_region_device_r (0xc2100000, 0xc213ffff, d_font, NOT_NEED_TO_OFFSET);
94         // REAL IS C2140000h - C2141FFFh, but grain may be 8000h bytes.
95         set_region_device_rw(0xc2140000, 0xc2140000 + memory_map_grain() - 1, d_dictionary, NOT_NEED_TO_OFFSET);
96         if(d_font_20pix != NULL) {
97                 set_region_device_r (0xc2180000, 0xc21fffff, d_font_20pix, NOT_NEED_TO_OFFSET);
98         }
99         // REAL IS C2200000h - C2200FFFh, but grain may be 8000h bytes.
100         set_region_device_rw(0xc2200000, 0xc2200000 + memory_map_grain() - 1, d_pcm, NOT_NEED_TO_OFFSET);
101         set_region_device_r (0xfffc0000, 0xffffffff, d_sysrom, NOT_NEED_TO_OFFSET);
102         // Another devices are blank
103
104         // load rom image
105         // ToDo: More smart.
106         vram_size = 0x80000; // OK?
107 }
108
109 void TOWNS_MEMORY::reset_wait_values()
110 {
111         set_mmio_wait_rw(0x00000000, 0x7fffffff, WAITVAL_RAM);
112         set_dma_wait_rw (0x00000000, 0x7fffffff, WAITVAL_RAM);
113         set_mmio_wait_rw(0x80000000, 0x803fffff, WAITVAL_VRAM); // Default Value
114         set_dma_wait_rw (0x80000000, 0x803fffff, WAITVAL_VRAM); // Default Value
115         set_mmio_wait_rw(0x80400000, 0xffffffff, WAITVAL_RAM);
116         set_dma_wait_rw (0x80400000, 0xffffffff, WAITVAL_RAM);
117 }
118
119 void TOWNS_MEMORY::config_page0c_0e(const bool vrambank, const bool dictbank, const bool force)
120 {
121         const bool is_vram_bak = dma_is_vram;
122         const bool is_dict_bak = select_d0_dict;
123         __UNLIKELY_IF((vrambank != is_vram_bak) || (force)){
124                 if(vrambank) { // VRAM AND around TEXT
125                         set_region_device_rw(0x000c0000, 0x000c7fff, d_planevram, NOT_NEED_TO_OFFSET);
126                         set_region_device_rw(0x000c8000, 0x000cffff, this, NOT_NEED_TO_OFFSET);
127
128                         unset_range_rw(0x000e0000, 0x000effff); // OK?
129
130                         set_mmio_wait_rw(0x000c0000, 0x000cffff, WAITVAL_VRAM); // Default Value
131                         set_dma_wait_rw (0x000c0000, 0x000cffff, WAITVAL_VRAM); // Default Value
132                 } else {
133                         set_region_memory_rw(0x000c0000, 0x000cffff, ram_pagec);
134                         set_region_memory_rw(0x000e0000, 0x000effff, &(ram_pagec[0x20000]));
135                         set_mmio_wait_rw(0x000c0000, 0x000cffff, WAITVAL_RAM); // Default Value
136                         set_dma_wait_rw (0x000c0000, 0x000cffff, WAITVAL_VRAM); // Default Value
137                 }
138         }
139         __UNLIKELY_IF((vrambank != is_vram_bak) || (dictbank != is_dict_bak) || (force)){
140                 if(vrambank) { // VRAM AND around TEXT
141                         if(dictbank) {
142                                 set_region_device_r(0x000d0000, 0x000d7fff, d_dictionary, NOT_NEED_TO_OFFSET);
143                                 unset_range_w(0x000d0000, 0x000d7fff);
144                                 // REAL IS 0000D8000h - 000D9FFFh, but grain may be 8000h bytes.
145                                 set_region_device_rw(0x000d8000, 0x000d8000 + memory_map_grain() - 1, d_dictionary, NOT_NEED_TO_OFFSET);
146                         } else {
147                                 unset_range_rw(0x000d0000, 0x000dffff);
148                         }
149                 } else {
150                         set_region_memory_rw(0x000d0000, 0x000dffff, &(ram_pagec[0x10000]));
151                 }
152         }
153         dma_is_vram = vrambank;
154         select_d0_dict = dictbank;
155 }
156 void TOWNS_MEMORY::config_page0f(const bool sysrombank, const bool force)
157 {
158         bool sysrom_bak = select_d0_rom;
159         set_region_memory_rw(0x000f0000, 0x000f7fff, &(ram_pagec[0x30000]));
160         __UNLIKELY_IF((sysrombank != sysrom_bak) || (force)) {
161                 if(sysrombank) {
162                         unset_range_w(0x000f8000, 0x000fffff);
163                         set_region_device_rw(0x000f8000, 0x000fffff, d_sysrom, NOT_NEED_TO_OFFSET);
164                 } else {
165                         set_region_memory_rw(0x000f8000, 0x000fffff, &(ram_pagec[0x38000]));
166                 }
167         }
168         select_d0_rom = sysrombank;
169 }
170
171
172 void TOWNS_MEMORY::set_mmio_memory_r(uint32_t start, uint32_t end, uint8_t* baseptr)
173 {
174         uint64_t _start = (uint64_t)start;
175         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
176
177         _start &= ~(memory_map_mask());
178         _end &= ~(memory_map_mask());
179
180         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
181         const uint64_t _incval = memory_map_grain();
182         uint32_t realoffset = 0;
183         for(uint64_t addr = _start; addr < _end; addr += _incval) {
184                 mmio_memory_map_r[mapptr] = &(baseptr[realoffset]);
185                 mmio_devices_map_r[mapptr] = NULL;
186                 realoffset += _incval;
187                 mapptr++;
188         }
189 }
190
191 void TOWNS_MEMORY::set_mmio_memory_w(uint32_t start, uint32_t end, uint8_t* baseptr)
192 {
193         uint64_t _start = (uint64_t)start;
194         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
195
196         _start &= ~(memory_map_mask());
197         _end &= ~(memory_map_mask());
198
199         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
200         const uint64_t _incval = memory_map_grain();
201         uint32_t realoffset = 0;
202         for(uint64_t addr = _start; addr < _end; addr += _incval) {
203                 mmio_memory_map_w[mapptr] = &(baseptr[realoffset]);
204                 mmio_devices_map_w[mapptr] = NULL;
205                 realoffset += _incval;
206                 mapptr++;
207         }
208 }
209
210 void  __FASTCALL TOWNS_MEMORY::set_mmio_device_r(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress)
211 {
212         uint64_t _start = (uint64_t)start;
213         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
214
215         _start &= ~(memory_map_mask());
216         _end &= ~(memory_map_mask());
217
218         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
219         const uint64_t _incval = memory_map_grain();
220         uint32_t realoffset = 0;
221         for(uint64_t addr = _start; addr < _end; addr += _incval) {
222                 mmio_memory_map_r[mapptr] = NULL;
223                 mmio_devices_map_r[mapptr] = ptr;
224                 __LIKELY_IF(baseaddress == UINT32_MAX) {
225                         mmio_devices_base_r[mapptr] = UINT32_MAX;
226                 } else {
227                         mmio_devices_base_r[mapptr] = baseaddress + realoffset;
228                 }
229                 realoffset += _incval;
230                 mapptr++;
231         }
232 }
233
234 void  __FASTCALL TOWNS_MEMORY::set_mmio_device_w(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress)
235 {
236         uint64_t _start = (uint64_t)start;
237         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
238
239         _start &= ~(memory_map_mask());
240         _end &= ~(memory_map_mask());
241
242         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
243         const uint64_t _incval = memory_map_grain();
244         uint32_t realoffset = 0;
245         for(uint64_t addr = _start; addr < _end; addr += _incval) {
246                 mmio_memory_map_w[mapptr] = NULL;
247                 mmio_devices_map_w[mapptr] = ptr;
248                 __LIKELY_IF(baseaddress == UINT32_MAX) {
249                         mmio_devices_base_w[mapptr] = UINT32_MAX;
250                 } else {
251                         mmio_devices_base_w[mapptr] = baseaddress + realoffset;
252                 }
253                 realoffset += _incval;
254                 mapptr++;
255         }
256 }
257
258 void  __FASTCALL TOWNS_MEMORY::set_mmio_wait_r(uint32_t start, uint32_t end, int wait)
259 {
260         uint64_t _start = (uint64_t)start;
261         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
262
263         _start &= ~(memory_map_mask());
264         _end &= ~(memory_map_mask());
265
266         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
267         const uint64_t _incval = memory_map_grain();
268         uint32_t realoffset = 0;
269         for(uint64_t addr = _start; addr < _end; addr += _incval) {
270                 mmio_wait_map_w[mapptr] = wait;
271                 mapptr++;
272         }
273 }
274
275 void  __FASTCALL TOWNS_MEMORY::set_mmio_wait_w(uint32_t start, uint32_t end, int wait)
276 {
277         uint64_t _start = (uint64_t)start;
278         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
279
280         _start &= ~(memory_map_mask());
281         _end &= ~(memory_map_mask());
282
283         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
284         const uint64_t _incval = memory_map_grain();
285         uint32_t realoffset = 0;
286         for(uint64_t addr = _start; addr < _end; addr += _incval) {
287                 mmio_wait_map_r[mapptr] = wait;
288                 mapptr++;
289         }
290 }
291
292 void TOWNS_MEMORY::unset_mmio_r(uint32_t start, uint32_t end)
293 {
294         uint64_t _start = (uint64_t)start;
295         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
296
297         _start &= ~(memory_map_mask());
298         _end &= ~(memory_map_mask());
299
300         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
301         const uint64_t _incval = memory_map_grain();
302         uint32_t realoffset = 0;
303         for(uint64_t addr = _start; addr < _end; addr += _incval) {
304                 mmio_memory_map_r[mapptr] = NULL;
305                 mmio_devices_map_r[mapptr] = NULL;
306                 mmio_wait_map_r[mapptr] = WAITVAL_RAM;
307                 realoffset += _incval;
308                 mapptr++;
309         }
310 }
311
312 void TOWNS_MEMORY::unset_mmio_w(uint32_t start, uint32_t end)
313 {
314         uint64_t _start = (uint64_t)start;
315         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
316
317         _start &= ~(memory_map_mask());
318         _end &= ~(memory_map_mask());
319
320         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
321         const uint64_t _incval = memory_map_grain();
322         uint32_t realoffset = 0;
323         for(uint64_t addr = _start; addr < _end; addr += _incval) {
324                 mmio_memory_map_w[mapptr] = NULL;
325                 mmio_devices_map_w[mapptr] = NULL;
326                 mmio_wait_map_w[mapptr] = WAITVAL_RAM;
327                 realoffset += _incval;
328                 mapptr++;
329         }
330 }
331
332 void TOWNS_MEMORY::unset_dma_r(uint32_t start, uint32_t end)
333 {
334         uint64_t _start = (uint64_t)start;
335         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
336
337         _start &= ~(memory_map_mask());
338         _end &= ~(memory_map_mask());
339
340         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
341         const uint64_t _incval = memory_map_grain();
342         uint32_t realoffset = 0;
343         for(uint64_t addr = _start; addr < _end; addr += _incval) {
344                 dma_memory_map_w[mapptr] = NULL;
345                 dma_devices_map_w[mapptr] = NULL;
346                 dma_wait_map_w[mapptr] = WAITVAL_RAM;
347                 realoffset += _incval;
348                 mapptr++;
349         }
350 }
351
352 void TOWNS_MEMORY::unset_dma_w(uint32_t start, uint32_t end)
353 {
354         uint64_t _start = (uint64_t)start;
355         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
356
357         _start &= ~(memory_map_mask());
358         _end &= ~(memory_map_mask());
359
360         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
361         const uint64_t _incval = memory_map_grain();
362         uint32_t realoffset = 0;
363         for(uint64_t addr = _start; addr < _end; addr += _incval) {
364                 dma_memory_map_w[mapptr] = NULL;
365                 dma_devices_map_w[mapptr] = NULL;
366                 dma_wait_map_w[mapptr] = WAITVAL_RAM;
367                 realoffset += _incval;
368                 mapptr++;
369         }
370 }
371
372 void TOWNS_MEMORY::set_dma_memory_r(uint32_t start, uint32_t end, uint8_t* baseptr)
373 {
374         uint64_t _start = (uint64_t)start;
375         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
376
377         _start &= ~(memory_map_mask());
378         _end &= ~(memory_map_mask());
379
380         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
381         const uint64_t _incval = memory_map_grain();
382         uint32_t realoffset = 0;
383         for(uint64_t addr = _start; addr < _end; addr += _incval) {
384                 dma_memory_map_r[mapptr] = &(baseptr[realoffset]);
385                 dma_devices_map_r[mapptr] = NULL;
386                 realoffset += _incval;
387                 mapptr++;
388         }
389 }
390
391 void TOWNS_MEMORY::set_dma_memory_w(uint32_t start, uint32_t end, uint8_t* baseptr)
392 {
393         uint64_t _start = (uint64_t)start;
394         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
395
396         _start &= ~(memory_map_mask());
397         _end &= ~(memory_map_mask());
398
399         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
400         const uint64_t _incval = memory_map_grain();
401         uint32_t realoffset = 0;
402         for(uint64_t addr = _start; addr < _end; addr += _incval) {
403                 dma_memory_map_w[mapptr] = &(baseptr[realoffset]);
404                 dma_devices_map_w[mapptr] = NULL;
405                 realoffset += _incval;
406                 mapptr++;
407         }
408 }
409
410 void  __FASTCALL TOWNS_MEMORY::set_dma_device_r(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress)
411 {
412         uint64_t _start = (uint64_t)start;
413         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
414
415         _start &= ~(memory_map_mask());
416         _end &= ~(memory_map_mask());
417
418         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
419         const uint64_t _incval = memory_map_grain();
420         uint32_t realoffset = 0;
421         for(uint64_t addr = _start; addr < _end; addr += _incval) {
422                 dma_memory_map_r[mapptr] = NULL;
423                 dma_devices_map_r[mapptr] = ptr;
424                 __LIKELY_IF(baseaddress == UINT32_MAX) {
425                         dma_devices_base_r[mapptr] = UINT32_MAX;
426                 } else {
427                         dma_devices_base_r[mapptr] = baseaddress + realoffset;
428                 }
429                 realoffset += _incval;
430                 mapptr++;
431         }
432 }
433
434 void  __FASTCALL TOWNS_MEMORY::set_dma_device_w(uint32_t start, uint32_t end, DEVICE* ptr, uint32_t baseaddress)
435 {
436         uint64_t _start = (uint64_t)start;
437         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
438
439         _start &= ~(memory_map_mask());
440         _end &= ~(memory_map_mask());
441
442         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
443         const uint64_t _incval = memory_map_grain();
444         uint32_t realoffset = 0;
445         for(uint64_t addr = _start; addr < _end; addr += _incval) {
446                 dma_memory_map_w[mapptr] = NULL;
447                 dma_devices_map_w[mapptr] = ptr;
448                 __LIKELY_IF(baseaddress == UINT32_MAX) {
449                         dma_devices_base_w[mapptr] = UINT32_MAX;
450                 } else {
451                         dma_devices_base_w[mapptr] = baseaddress + realoffset;
452                 }
453                 realoffset += _incval;
454                 mapptr++;
455         }
456 }
457
458 void  __FASTCALL TOWNS_MEMORY::set_dma_wait_r(uint32_t start, uint32_t end, int wait)
459 {
460         uint64_t _start = (uint64_t)start;
461         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
462
463         _start &= ~(memory_map_mask());
464         _end &= ~(memory_map_mask());
465
466         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
467         const uint64_t _incval = memory_map_grain();
468         uint32_t realoffset = 0;
469         for(uint64_t addr = _start; addr < _end; addr += _incval) {
470                 dma_wait_map_w[mapptr] = wait;
471                 mapptr++;
472         }
473 }
474
475 void  __FASTCALL TOWNS_MEMORY::set_dma_wait_w(uint32_t start, uint32_t end, int wait)
476 {
477         uint64_t _start = (uint64_t)start;
478         uint64_t _end =   (end == 0xffffffff) ? 0x100000000 : (uint64_t)(end + 1);
479
480         _start &= ~(memory_map_mask());
481         _end &= ~(memory_map_mask());
482
483         uint32_t mapptr = (uint32_t)(_start >> memory_map_shift());
484         const uint64_t _incval = memory_map_grain();
485         uint32_t realoffset = 0;
486         for(uint64_t addr = _start; addr < _end; addr += _incval) {
487                 dma_wait_map_r[mapptr] = wait;
488                 mapptr++;
489         }
490 }
491
492
493 bool TOWNS_MEMORY::set_cpu_clock_by_wait()
494 {
495         uint32_t cpu_bak = cpu_clock_val;
496         cpu_clock_val = (is_faster_wait()) ?
497                 get_cpu_clocks(d_cpu) : (16 * 1000 * 1000);
498         return ((cpu_clock_val != cpu_bak) ? true : false);
499 }
500 void TOWNS_MEMORY::set_wait_values()
501 {
502         uint32_t waitfactor = 0;
503         if(cpu_clock_val < get_cpu_clocks(d_cpu)) {
504                 waitfactor = (uint32_t)(((double)get_cpu_clocks(d_cpu) / (double)cpu_clock_val) * 65536.0);
505         }
506         d_cpu->write_signal(SIG_CPU_WAIT_FACTOR, waitfactor, 0xffffffff);
507 }
508
509 void TOWNS_MEMORY::release()
510 {
511 //      if(rd_table != NULL) free(rd_table);
512 //      if(rd_dummy != NULL) free(rd_dummy);
513 //      if(wr_table != NULL) free(wr_table);
514 //      if(wr_dummy != NULL) free(wr_dummy);
515
516         if(extra_ram != NULL) {
517                 free(extra_ram);
518                 extra_ram = NULL;
519         }
520
521 }
522 void TOWNS_MEMORY::reset()
523 {
524         // reset memory
525         // ToDo
526         update_machine_features(); // Update MISC3, MISC4 by MACHINE ID.
527         is_compatible = true;
528         reset_happened = false;
529
530         nmi_vector_protect = false;
531         ankcg_enabled = false;
532         nmi_mask = false;
533         //config_page0c_0e(false, false, true); // VRAM, DICT, FORCE
534         reset_wait_values();
535         config_page0c_0e(false, false, true); // VRAM, DICT, FORCE
536         config_page0f(true,  true); // SYSROM, FORCE
537
538
539         set_cpu_clock_by_wait();
540         set_wait_values();
541 #if 1
542         __LIKELY_IF(d_cpu != NULL) {
543                 d_cpu->set_address_mask(0xffffffff);
544         }
545         if(d_dmac != NULL) {
546                 uint8_t wrap_val = 0xff; // WRAP ON
547                 d_dmac->write_signal(SIG_TOWNS_DMAC_WRAP, wrap_val, 0xff);
548         }
549 #endif
550 }
551
552 void TOWNS_MEMORY::update_machine_features()
553 {
554         // 0024h: MISC3
555         reg_misc3 = 0xff;
556         if(machine_id >= 0x0b00) { // After MA/MX/ME
557                 reg_misc3 &= ~0x04; // DMACMD
558         }
559         if(machine_id >= 0x0700) { // After HR/HG
560                 reg_misc3 &= ~0x08; // POFFEN
561         }
562         if(machine_id >= 0x0700) { // After HR/HG
563                 reg_misc3 &= ~0x10; // Free run counter
564         }
565         if(machine_id >= 0x0700) { // After HR/HG
566                 reg_misc3 &= ~0x20; // CRTPOWOFF (0022h)
567         }
568         if(machine_id >= 0x0700) { // After HR/HG
569                 reg_misc3 &= ~0x40; // RCREN
570         }
571         if(machine_id >= 0x0700) { // After HR/HG
572                 reg_misc3 &= ~0x80; // ENPOFF
573         }
574         // 0025h: NMICNT
575         if(machine_id >= 0x0500) { // After CX
576                 reg_misc4 = 0x7f;
577         } else {
578                 reg_misc4 = 0xff;
579         }
580 }
581
582 uint8_t TOWNS_MEMORY::read_fmr_ports8(uint32_t addr)
583 {
584         uint8_t val = 0xff;
585         __UNLIKELY_IF((addr & 0xffff) < 0xff80) {
586                 return ram_pagec[addr & 0xffff];
587         }
588 #if 1
589         __LIKELY_IF((addr & 0xffff) < 0xff88) {
590                 __LIKELY_IF(d_planevram != NULL) {
591                         val = d_planevram->read_memory_mapped_io8(addr & 0xffff);
592                 }
593                 return val;
594         } else if(((addr & 0xffff) >= 0xff94) && ((addr & 0xffff) < 0xff98)) {
595                 __LIKELY_IF(d_font != NULL) {
596                         val = d_font->read_io8(addr & 0xffff);
597                 }
598                 return val;
599         }
600 #endif
601         if((machine_id >= 0x0600) && !(is_compatible)) { // After UG
602                 switch(addr & 0xffff) {
603                 case 0xff88:
604                         __LIKELY_IF(d_crtc != NULL) {
605                                 val = d_crtc->read_signal(SIG_TOWNS_CRTC_MMIO_CFF82H);
606                         }
607                         return val;
608                         break;
609                 case 0xff99:
610                         return (ankcg_enabled) ? 0x01 : 0x00;
611                         break;
612                 case 0xff9c:
613                 case 0xff9d:
614                 case 0xff9e:
615                         __LIKELY_IF(d_font != NULL) {
616                                 val = d_font->read_io8(addr & 0xffff);
617                         }
618                         return val;
619                         break;
620                 default:
621
622                         break;
623                 }
624         }
625         switch(addr & 0xffff) {
626         case 0xff88:
627                 __LIKELY_IF(d_planevram != NULL) {
628                         val = d_planevram->read_io8(addr);
629                 }
630                 break;
631         case 0xff95:
632                 val = 0x80;
633                 break;
634         case 0xff96:
635                 __LIKELY_IF(d_font != NULL) {
636                         return d_font->read_signal(SIG_TOWNS_FONT_KANJI_DATA_LOW);
637                 }
638                 break;
639         case 0xff97:
640                 __LIKELY_IF(d_font != NULL) {
641                         return d_font->read_signal(SIG_TOWNS_FONT_KANJI_DATA_HIGH);
642                 }
643                 break;
644         case 0xff98:
645                 __LIKELY_IF(d_timer != NULL) {
646                         d_timer->write_signal(SIG_TIMER_BEEP_ON, 1, 1);
647                 }
648                 break;
649         case 0xff99:
650                 __LIKELY_IF(d_planevram != NULL) {
651                         val = d_planevram->read_memory_mapped_io8(addr);
652                 }
653                 break;
654         default:
655                 __LIKELY_IF(d_planevram != NULL) {
656                         val = d_planevram->read_io8(addr & 0xffff);
657                 }
658                 break;
659         }
660         return val;
661 }
662 uint8_t TOWNS_MEMORY::read_sys_ports8(uint32_t addr)
663 {
664     uint8_t val;
665         val = 0xff;
666         switch(addr & 0xffff) {
667         case 0x0020: // Software reset ETC.
668                 // reset cause register
669                 val = ((software_reset) ? 1 : 0) | ((reset_happened) ? 2 : 0);
670                 reset_happened = false;
671                 software_reset = false;
672                 __UNLIKELY_IF(d_cpu != NULL) {
673                         d_cpu->set_shutdown_flag(0);
674                 }
675                 if((machine_id >= 0x0300) && ((machine_id & 0xff00) != 0x0400)) { // After UX
676                         val = val | ((poff_status) ? 0x04 : 0x00);
677                 }
678                 break;
679         case 0x0022:
680 //              val.b.l = 0xff;
681 //              if(d_dmac != NULL) {
682 //                      val = d_dmac->read_signal(SIG_TOWNS_DMAC_ADDR_REG);
683 //              }
684                 break;
685                 // 0024, 0025 : MISC3 + MISC4
686         case 0x0024:
687                 val = reg_misc3;
688                 break;
689         case 0x0025:
690                 val = reg_misc4;
691                 break;
692         case 0x0028:
693                 // NMI MASK
694                 if(machine_id >= 0x0500) { // After CX
695                         val = (nmi_mask) ? 0x01 : 0x00;
696                 }
697                 break;
698         case 0x0030:
699                 // 20210227 K.O
700                 // From FMTowns::MachineID()  of TSUGARU,
701                 // git 83d4ec2309ac9fcbb8c01f26061ff0d49c5321e4.
702 //              if((config.dipswitch & TOWNS_DIPSW_PRETEND_I386) != 0) {
703 //                      val = ((machine_id & 0xf8) | 1);
704 //              } else {
705                         val = ((machine_id & 0xf8) | (cpu_id & 7));
706 //              }
707                 break;
708         case 0x0031:
709                 val = ((machine_id >> 8) & 0xff);
710                 break;
711         case 0x0032:
712                 {
713                         //bool __cs = (d_serialrom->read_signal(SIG_SERIALROM_CS) == 0);
714                         bool __clk = (d_serialrom->read_signal(SIG_SERIALROM_CLK) != 0);
715                         bool __reset = (d_serialrom->read_signal(SIG_SERIALROM_RESET) != 0);
716                         bool __dat = (d_serialrom->read_signal(SIG_SERIALROM_DATA) != 0);
717                         val = ((__reset) ? 0x80 : 0x00) | ((__clk) ? 0x40 : 0x00) | /*0x3e |*/ ((__dat) ? 0x01 : 0x00);
718                 }
719                 break;
720         case 0x00c0: // Cache
721                 val = 0x00;
722                 if((cpu_id == 0x02) || (cpu_id >= 0x04)) { // i486 SX/DX or After Pentium.
723                         // ToDo: Implement around cache.
724                         // Modified by this register and (05ECh:bit0 / Wait register).
725                         // Now, cache is always disabled.
726                         // RPNH = 0 (Disabled) : Bit1
727                         // CMEN = 0 (Disabled) : Bit0
728                         val = 0x00;
729                 }
730                 break;
731         case 0x00c2: // Cache Diagnostic
732                 val = 0x00;
733                 if((cpu_id == 0x02) || (cpu_id >= 0x04)) { // i486 SX/DX or After Pentium.
734                         // ToDo: Implement cache disgnostic.
735                         // SDMOD (Not diagnostic) : Bit3
736                         val = 0x00;
737                 }
738                 break;
739         case 0x0400: // Resolution:
740                 val = 0xfe;
741                 break;
742         case 0x0404: // System Status Reg.
743                 val = (dma_is_vram) ? 0x7f : 0xff;
744 //              val = (dma_is_vram) ? 0x00 : 0x80;
745                 break;
746         case 0x0480:
747                 val  =  (select_d0_dict) ? 0x01 : 0x00;
748                 val |=  ((select_d0_rom) ? 0x00 : 0x02);
749                 break;
750         case 0x05c0:
751 //              val = (extra_nmi_mask) ? 0xf7 : 0xff;
752                 val = (extra_nmi_mask) ? 0x00 : 0x08;
753                 break;
754         case 0x05c2:
755 //              val = (extra_nmi_val) ? 0xff : 0xf7;
756                 val = (extra_nmi_val) ? 0x08 : 0x00;
757                 break;
758         case 0x05e0:
759                 if(machine_id < 0x0200) { // Towns 1/2
760                         val =  wait_register_older;
761                 }
762                 break;
763         case 0x05e2:
764                 if(machine_id >= 0x0200) { // i386
765                         val = wait_register_ram;
766                 }
767                 break;
768         case 0x05e6:
769                 if(machine_id >= 0x0200) { // i386
770                         val = wait_register_vram;
771                 }
772                 break;
773         case 0x05e8:
774                 // After Towns1F/2F/1H/2H
775                 {
776                         uint16_t nid = machine_id & 0xff00;
777                         if(nid >= 0x1000) {
778                                 val = (extram_size >> 20) & 0x7f; // MAX 128MB
779                         } else if(nid >= 0x0900) { // UR,MA,MX,ME,MF
780                                 val = (extram_size >> 20) & 0x1f; // MAX 32MB
781                         } else if(nid == 0x0800) { // HG
782                                 val = (extram_size >> 20) & 0x0f; // MAX 15MB
783                         } else if(nid == 0x0700) { // HR
784                                 val = (extram_size >> 20) & 0x1f; // MAX 32MB
785                         } else if(nid >= 0x0200) { // 2nd GEN,3rd Gen, UX/UG, CX
786                                 val = (extram_size >> 20) & 0x0f; // MAX 15MB
787                         } else {
788                                 val = 0xff; // NOT SUPPORTED
789                         }
790                 }
791                 break;
792         case 0x05ec:
793                 // 05ec, 05ed
794                 if(machine_id >= 0x0200) { // 05ec
795                         val = ((is_faster_wait()) ? 0x01 : 0x00);
796                 }
797                 break;
798         case 0x05ed:
799                 if(machine_id >= 0x0700) { // 05ed
800                         uint32_t clk = get_cpu_clocks(d_cpu);
801                         clk = clk / (1000 * 1000);
802                         __UNLIKELY_IF(clk < 16) clk = 16;
803                         __UNLIKELY_IF(clk > 127) clk = 127; // ToDo
804                         val = 0x00 | clk;
805                 }
806                 break;
807         case 0xfda4:
808                 if(machine_id >= 0x0700) { // After HR/HG
809                         val = (is_compatible) ? 0x00 : 0x01;
810                 } else {
811                         val = 0x00;
812                 }
813                 break;
814         default:
815                 break;
816         }
817         return val;
818 }
819 // Address (TOWNS BASIC):
820 // 0x0020 - 0x0022, 0x0030-0x0031,
821 // 0x0400 - 0x0404,
822 // 0x0480 - 0x0484
823 // 0x05c0 - 0x05c2
824 // 0x05ec (Wait register)
825 // 0x05ed (CPU SPEED REGISTER)
826 // Is set extra NMI (0x05c0 - 0x05c2)?
827 uint32_t TOWNS_MEMORY::read_io8(uint32_t addr)
828 {
829 //      uint32_t val = 0x00;  // MAY NOT FILL to "1" for unused bit 20200129 K.O
830         __LIKELY_IF((addr & 0xffff) >= 0xff80) {
831                 return read_fmr_ports8(addr & 0xffff);
832         }
833         return read_sys_ports8(addr);
834 }
835
836 void TOWNS_MEMORY::write_fmr_ports8(uint32_t addr, uint32_t data)
837 {
838         __UNLIKELY_IF((addr & 0xffff) < 0xff80) {
839                 ram_pagec[addr & 0xffff] = data;
840                 return;
841         }
842 #if 1
843         __LIKELY_IF((addr & 0xffff) < 0xff88) {
844                 __LIKELY_IF(d_planevram != NULL) {
845                         d_planevram->write_io8(addr & 0xffff, data);
846                 }
847                 return;
848         } else if(((addr & 0xffff) >= 0xff94) && ((addr & 0xffff) < 0xff98)) {
849                 __LIKELY_IF(d_font != NULL) {
850                         d_font->write_io8(addr & 0xffff, data);
851                 }
852                 return;
853         }
854 #endif
855         if((machine_id >= 0x0600) && !(is_compatible)) { // After UG
856                 switch(addr & 0xffff) {
857                 case 0xff9e:
858                         __LIKELY_IF(d_font != NULL) {
859                                 d_font->write_io8(addr & 0xffff, data);
860                         }
861                         return;
862                 default:
863                         break;
864                 }
865         }
866         switch(addr & 0xffff) {
867         case 0xff94:
868                 __LIKELY_IF(d_font != NULL) {
869                         d_font->write_signal(SIG_TOWNS_FONT_KANJI_HIGH, data, 0xff);
870                 }
871                 break;
872         case 0xff95:
873                 __LIKELY_IF(d_font != NULL) {
874                         d_font->write_signal(SIG_TOWNS_FONT_KANJI_LOW, data, 0xff);
875                 }
876                 break;
877         case 0xff96:
878         case 0xff97:
879                 break;
880         case 0xff98:
881                 __LIKELY_IF(d_timer != NULL) {
882                         d_timer->write_signal(SIG_TIMER_BEEP_ON, 0, 1);
883                 }
884                 break;
885         case 0xff99:
886                 {
887                         bool _b = ankcg_enabled;
888                         ankcg_enabled = ((data & 1) != 0) ? true : false;
889                 }
890                 break;
891         case 0xffa0:
892                 __LIKELY_IF(d_planevram != NULL) {
893                         d_planevram->write_io8(addr & 0xffff, data);
894                 }
895         default:
896                 __LIKELY_IF(d_planevram != NULL) {
897                         d_planevram->write_io8(addr & 0xffff, data);
898                 }
899                 break;
900         }
901 }
902 void TOWNS_MEMORY::write_sys_ports8(uint32_t addr, uint32_t data)
903 {
904         switch(addr & 0xffff) {
905         case 0x0020: // Software reset ETC.
906                 // reset cause register
907                 if((data & 0x80) != 0) {
908                         nmi_vector_protect = true;
909                 } else {
910                         nmi_vector_protect = false;
911                 }
912                 if((data & 0x01) != 0) {
913                         software_reset = true;
914                 } else {
915                         software_reset = false;
916                 }
917
918                 if((data & 0x40) != 0) {
919                         poff_status = true;
920 //                      __LIKELY_IF(d_cpu != NULL) {
921 //                              d_cpu->set_shutdown_flag(1);
922 //                      }
923                         // Todo: Implement true power off.
924 //                      emu->notify_power_off();
925 //                      emu->power_off();
926 //                      break;
927                 } else {
928                         poff_status = false;
929 //                      __LIKELY_IF(d_cpu != NULL) {
930 //                              d_cpu->set_shutdown_flag(0);
931 //                      }
932                 }
933
934                 if((software_reset) || (poff_status)){
935 //                      __LIKELY_IF(d_cpu != NULL) {
936 //                              d_cpu->reset();
937 //                      }
938                         uint8_t wrap_val = 0xff; // WRAP ON
939                         __LIKELY_IF(d_dmac != NULL) {
940                                 d_dmac->write_signal(SIG_TOWNS_DMAC_WRAP, wrap_val, 0xff);
941                         }
942                         if(poff_status) {
943                                 __LIKELY_IF(d_cpu != NULL) {
944                                         d_cpu->set_shutdown_flag(1);
945                                 }
946                                 // Todo: Implement true power off.
947                                  emu->notify_power_off();
948                                 // emu->power_off();
949                         }
950                         vm->reset();
951                 }
952                 // Towns SEEMS to not set addreess mask (a.k.a A20 mask). 20200131 K.O
953                 break;
954         case 0x0022:
955                 if((data & 0x40) != 0) {
956                         __LIKELY_IF(d_cpu != NULL) {
957                                 d_cpu->set_shutdown_flag(1);
958                         }
959                         // Todo: Implement true power off.
960                         poff_status = true;
961                         emu->notify_power_off();
962 //                      emu->power_off();
963                         vm->reset();
964                 }
965                 // Power register
966                 break;
967         case 0x0024:
968                 //if((d_dmac != NULL) && (machine_id >= 0x0b00)) { // After MA/MX/ME
969                 //      d_dmac->write_signal(SIG_TOWNS_DMAC_WRAP, data, 0xff);
970                 //}
971                 break;
972         case 0x0032:
973                 d_serialrom->write_signal(SIG_SERIALROM_CS, ~data, 0x20);
974                 d_serialrom->write_signal(SIG_SERIALROM_CLK, data, 0x40);
975                 d_serialrom->write_signal(SIG_SERIALROM_RESET, data, 0x80);
976                 break;
977         case 0x0404: // System Status Reg.
978                 {
979                         config_page0c_0e(((data & 0x80) == 0) ? true : false, select_d0_dict, false); // VRAM, DICT, FORCE
980                 }
981                 break;
982         case 0x0480:
983                 {
984                         bool is_dict, is_sysrom;
985                         is_dict = ((data & 0x01) != 0) ? true : false;
986                         is_sysrom = ((data & 0x02) == 0) ? true : false;
987                         config_page0c_0e(dma_is_vram, is_dict, false);
988                         config_page0f(is_sysrom, false);
989                 }
990                 break;
991         case 0x05c0:
992                 extra_nmi_mask = ((data & 0x08) == 0);
993                 break;
994         case 0x05e0:
995                 // From AB.COM
996                 if(machine_id < 0x0200) { // Towns 1/2
997                         uint8_t nval_bak = wait_register_older & 0x07;
998                         uint8_t nval = data & 0x07;
999                         if(nval < 1) nval = 1;
1000                         mem_wait_val = nval;
1001                         vram_wait_val = nval + 3; // OK?
1002                         if(vram_wait_val > 6) {
1003                                 vram_wait_val = 6;
1004                         }
1005                         wait_register_older = (data & 0xf8) | nval;
1006                         cpu_clock_val = 16 * 1000 * 1000;
1007                         if(nval_bak != nval) {
1008                                 set_cpu_clock_by_wait();
1009                                 set_wait_values();
1010                         }
1011                 }
1012                 break;
1013         case 0x05e2:
1014                 if(machine_id >= 0x0200) { // After Towns 1H/2F. Hidden wait register.
1015                         uint8_t vram_bak = vram_wait_val;
1016                         uint8_t mem_bak = mem_wait_val;
1017                         if(data != 0x83) {
1018                                 uint8_t nval = data & 7;
1019                                 if(machine_id <= 0x0200) { // Towns 1H/2F.
1020                                         if(nval < 1) nval = 1;
1021                                 }
1022                                 if(nval > 6) nval = 6;
1023                                 mem_wait_val = nval;
1024                                 wait_register_ram = (data & 0xf8) | nval;
1025                         } else {
1026                                 mem_wait_val = 3;
1027                                 vram_wait_val = 6;
1028                                 wait_register_ram = data;
1029                         }
1030                         if((vram_bak != vram_wait_val) || (mem_bak != mem_wait_val)) {
1031                                 set_cpu_clock_by_wait();
1032                                 set_wait_values();
1033                         }
1034                 }
1035                 break;
1036         case 0x05e6:
1037                 if(machine_id >= 0x0200) { // After Towns 1H/2F. Hidden wait register.
1038                         uint8_t mem_bak = mem_wait_val;
1039                         uint8_t vram_bak = vram_wait_val;
1040                         if(data != 0x83) {
1041                                 uint8_t nval = data & 7;
1042                                 if(machine_id <= 0x0200) { // Towns 1H/2F.
1043                                         if(nval < 1) nval = 1;
1044                                 }
1045                                 if(nval > 6) nval = 6;
1046                                 vram_wait_val = nval;
1047                                 wait_register_vram = (data & 0xf8) | nval;
1048                         } else {
1049                                 mem_wait_val = 3;
1050                                 vram_wait_val = 3;
1051                                 wait_register_vram = data;
1052                         }
1053                         if((vram_bak != vram_wait_val) || (mem_bak != mem_wait_val)) {
1054                                 set_cpu_clock_by_wait();
1055                                 set_wait_values();
1056                         }
1057                 }
1058                 break;
1059         case 0x05ec:
1060                 // ToDo: 0x05ed
1061                 if(machine_id >= 0x0500) { // Towns2 CX :
1062                         uint8_t mem_bak = mem_wait_val;
1063                         uint8_t vram_bak = vram_wait_val;
1064                         vram_wait_val = ((data & 0x01) != 0) ? 0 : 6;
1065                         mem_wait_val = ((data & 0x01) != 0) ? 0 : 6;
1066                         wait_register_ram = mem_wait_val;
1067                         wait_register_vram = vram_wait_val;
1068                         if((mem_bak != mem_wait_val) || (vram_bak != vram_wait_val)) {
1069                                 set_cpu_clock_by_wait();
1070                                 set_wait_values();
1071                         }
1072                 }
1073                 break;
1074
1075         case 0xfda4:
1076                 if(machine_id >= 0x0700) { // After HR/HG
1077                         is_compatible = ((data & 0x01) == 0x00) ? true : false;
1078                         __LIKELY_IF(d_crtc != NULL) {
1079                                 d_crtc->write_signal(SIG_TOWNS_CRTC_COMPATIBLE_MMIO, (is_compatible) ? 0xffffffff : 0x00000000, 0xffffffff);
1080                         }
1081                 }
1082                 break;
1083         default:
1084                 break;
1085         }
1086 }
1087 void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
1088 {
1089         __LIKELY_IF((addr & 0xffff) >= 0xff80) {
1090                 write_fmr_ports8(addr & 0xffff, data);
1091                 return;
1092         }
1093         write_sys_ports8(addr, data);
1094 }
1095
1096
1097 uint32_t TOWNS_MEMORY::read_data8w(uint32_t addr, int* wait)
1098 {
1099         uint8_t val = 0xff;
1100         int waitval;
1101         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1102         uint32_t offset = addr & memory_map_mask();
1103         __LIKELY_IF(mmio_memory_map_r[mapptr] != NULL) {
1104                 uint8_t* ptr = mmio_memory_map_r[mapptr];
1105                 val = ptr[offset];
1106         } else if(mmio_devices_map_r[mapptr] != NULL) {
1107                 DEVICE* dev = mmio_devices_map_r[mapptr];
1108                 __LIKELY_IF(mmio_devices_base_r[mapptr] == UINT32_MAX) {
1109                         val = dev->read_memory_mapped_io8(addr);
1110                 } else {
1111                         offset += mmio_devices_base_r[mapptr];
1112                         val = dev->read_memory_mapped_io8(offset);
1113                 }
1114         }
1115         __LIKELY_IF(wait != NULL) {
1116                 waitval = mmio_wait_map_r[mapptr];
1117                 __LIKELY_IF(waitval < 0) {
1118                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1119                 }
1120                 *wait = waitval;
1121         }
1122         return val;
1123 }
1124
1125 uint32_t TOWNS_MEMORY::read_data16w(uint32_t addr, int* wait)
1126 {
1127         uint16_t val = 0xffff;
1128         int waitval;
1129         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1130         uint32_t offset = addr & memory_map_mask();
1131         __UNLIKELY_IF(offset == memory_map_mask()) {
1132                 pair16_t w;
1133                 int wait1, wait2;
1134                 w.b.l = read_data8w(addr    , &wait1);
1135                 w.b.h = read_data8w(addr + 1, &wait2);
1136                 __LIKELY_IF(wait != NULL) {
1137                         *wait = wait1;
1138                         //*wait = wait1 + wait2;
1139                 }
1140                 return w.w;
1141         }
1142         __LIKELY_IF(mmio_memory_map_r[mapptr] != NULL) {
1143                 uint8_t* ptr = mmio_memory_map_r[mapptr];
1144                 ptr = &(ptr[offset]);
1145                 #ifdef __BIG_ENDIAN__
1146                 pair16_t w;
1147                 w.read_2bytes_le_from(ptr);
1148                 val = w.w;
1149                 #else
1150                 __LIKELY_IF((offset & 1) == 0) {
1151                         uint16_t* q = (uint16_t*)ptr;
1152                         val = *q;
1153                 } else {
1154                         pair16_t w;
1155                         w.read_2bytes_le_from(ptr);
1156                         val = w.w;
1157                 }
1158                 #endif
1159         } else if(mmio_devices_map_r[mapptr] != NULL) {
1160                 DEVICE* dev = mmio_devices_map_r[mapptr];
1161                 __LIKELY_IF(mmio_devices_base_r[mapptr] == UINT32_MAX) {
1162                         val = dev->read_memory_mapped_io16(addr);
1163                 } else {
1164                         offset += mmio_devices_base_r[mapptr];
1165                         val = dev->read_memory_mapped_io16(offset);
1166                 }
1167         }
1168         __LIKELY_IF(wait != NULL) {
1169                 waitval = mmio_wait_map_r[mapptr];
1170                 __LIKELY_IF(waitval < 0) {
1171                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1172                 }
1173                 //__LIKELY_IF((offset & 1) == 0) {
1174                         *wait = waitval;
1175                 //} else {
1176                 //      *wait = waitval * 2;
1177                 //}
1178         }
1179         return val;
1180 }
1181
1182 uint32_t TOWNS_MEMORY::read_data32w(uint32_t addr, int* wait)
1183 {
1184         uint32_t val = 0xffffffff;
1185         int waitval;
1186         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1187         uint32_t offset = addr & memory_map_mask();
1188         __UNLIKELY_IF(offset > (memory_map_mask() - 3)) {
1189                 pair32_t d;
1190                 pair16_t w;
1191                 int wait1, wait2, wait3;
1192                 switch(offset & 3) {
1193                 case 1:
1194                 case 3:
1195                         d.b.l  = read_data8w (addr    , &wait1);
1196                         w.w    = read_data16w(addr + 1, &wait2);
1197                         d.b.h3 = read_data8w (addr + 3, &wait3);
1198                         __LIKELY_IF(wait != NULL) {
1199                                 *wait = wait1;
1200                                 //*wait = wait1 + wait2 + wait3;
1201                         }
1202                         break;
1203                 case 2:
1204                         d.w.l  = read_data16w(addr    , &wait1);
1205                         d.w.h  = read_data16w(addr + 2, &wait2);
1206                         __LIKELY_IF(wait != NULL) {
1207                                 *wait = wait1;
1208                                 //*wait = wait1 + wait2;
1209                         }
1210                 default:
1211                         __LIKELY_IF(wait != NULL) {
1212                                 waitval = mmio_wait_map_r[mapptr];
1213                                 __LIKELY_IF(waitval < 0) {
1214                                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1215                                 }
1216                                 *wait = waitval;
1217                                 //*wait = wait1 + wait2;
1218                         }
1219                 }
1220                 return d.d;
1221         }
1222         __LIKELY_IF(mmio_memory_map_r[mapptr] != NULL) {
1223                 uint8_t* ptr = mmio_memory_map_r[mapptr];
1224                 ptr = &(ptr[offset]);
1225                 #ifdef __BIG_ENDIAN__
1226                 pair32_t w;
1227                 d.read_4bytes_le_from(ptr);
1228                 val = d.d;
1229                 #else
1230                 __LIKELY_IF((offset & 3) == 0) {
1231                         uint32_t* q = (uint32_t*)ptr;
1232                         val = *q;
1233                 } else {
1234                         pair32_t d;
1235                         d.read_4bytes_le_from(ptr);
1236                         val = d.d;
1237                 }
1238                 #endif
1239         } else if(mmio_devices_map_r[mapptr] != NULL) {
1240                 DEVICE* dev = mmio_devices_map_r[mapptr];
1241                 __LIKELY_IF(mmio_devices_base_r[mapptr] == UINT32_MAX) {
1242                         offset = addr;
1243                 } else {
1244                         offset += mmio_devices_base_r[mapptr];
1245                 }
1246                 val = dev->read_memory_mapped_io32(offset);
1247         }
1248         __LIKELY_IF(wait != NULL) {
1249                 waitval = mmio_wait_map_r[mapptr];
1250                 __LIKELY_IF(waitval < 0) {
1251                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1252                 }
1253                 //__LIKELY_IF((offset & 1) == 0) {
1254                         *wait = waitval;
1255                 //} else {
1256                 //      *wait = waitval * 2;
1257                 //}
1258         }
1259         return val;
1260 }
1261
1262 uint32_t TOWNS_MEMORY::read_dma_data8w(uint32_t addr, int* wait)
1263 {
1264         uint8_t val = 0xff;
1265         int waitval;
1266         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1267         uint32_t offset = addr & memory_map_mask();
1268         __LIKELY_IF((dma_memory_map_r[mapptr] == NULL) && (dma_devices_map_r[mapptr] == NULL)) {
1269                 return read_data8w(addr, wait);
1270         }
1271
1272         __LIKELY_IF(dma_memory_map_r[mapptr] != NULL) {
1273                 uint8_t* ptr = dma_memory_map_r[mapptr];
1274                 val = ptr[offset];
1275         } else if(dma_devices_map_r[mapptr] != NULL) {
1276                 DEVICE* dev = dma_devices_map_r[mapptr];
1277                 __LIKELY_IF(dma_devices_base_r[mapptr] == UINT32_MAX) {
1278                         val = dev->read_memory_mapped_io8(addr);
1279                 } else {
1280                         offset += dma_devices_base_r[mapptr];
1281                         val = dev->read_memory_mapped_io8(offset);
1282                 }
1283         }
1284         __LIKELY_IF(wait != NULL) {
1285                 waitval = dma_wait_map_r[mapptr];
1286                 __LIKELY_IF(waitval < 0) {
1287                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1288                 }
1289                 *wait = waitval;
1290         }
1291         return val;
1292 }
1293
1294 uint32_t TOWNS_MEMORY::read_dma_data16w(uint32_t addr, int* wait)
1295 {
1296         uint16_t val = 0xffff;
1297         int waitval;
1298         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1299         uint32_t offset = addr & memory_map_mask();
1300         __UNLIKELY_IF(offset == memory_map_mask()) {
1301                 pair16_t w;
1302                 int wait1, wait2;
1303                 w.b.l = read_data8w(addr    , &wait1);
1304                 w.b.h = read_data8w(addr + 1, &wait2);
1305                 __LIKELY_IF(wait != NULL) {
1306                         *wait = wait1;
1307                         //*wait = wait1 + wait2;
1308                 }
1309                 return w.w;
1310         }
1311         __LIKELY_IF((dma_memory_map_r[mapptr] == NULL) && (dma_devices_map_r[mapptr] == NULL)) {
1312                 return read_data16w(addr, wait);
1313         }
1314         __LIKELY_IF(dma_memory_map_r[mapptr] != NULL) {
1315                 uint8_t* ptr = dma_memory_map_r[mapptr];
1316                 ptr = &(ptr[offset]);
1317                 #ifdef __BIG_ENDIAN__
1318                 pair16_t w;
1319                 w.read_2bytes_le_from(ptr);
1320                 val = w.w;
1321                 #else
1322                 __LIKELY_IF((offset & 1) == 0) {
1323                         uint16_t* q = (uint16_t*)ptr;
1324                         val = *q;
1325                 } else {
1326                         pair16_t w;
1327                         w.read_2bytes_le_from(ptr);
1328                         val = w.w;
1329                 }
1330                 #endif
1331         } else if(dma_devices_map_r[mapptr] != NULL) {
1332                 DEVICE* dev = dma_devices_map_r[mapptr];
1333                 __LIKELY_IF(dma_devices_base_r[mapptr] == UINT32_MAX) {
1334                         offset = addr;
1335                 } else {
1336                         offset += dma_devices_base_r[mapptr];
1337                 }
1338                 val = dev->read_memory_mapped_io16(offset);
1339         }
1340         __LIKELY_IF(wait != NULL) {
1341                 waitval = dma_wait_map_r[mapptr];
1342                 __LIKELY_IF(waitval < 0) {
1343                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1344                 }
1345                 //__LIKELY_IF((offset & 1) == 0) {
1346                         *wait = waitval;
1347                 //} else {
1348                 //      *wait = waitval * 2;
1349                 //}
1350         }
1351         return val;
1352 }
1353
1354 uint32_t TOWNS_MEMORY::read_dma_data32w(uint32_t addr, int* wait)
1355 {
1356         uint32_t val = 0xffffffff;
1357         int waitval;
1358         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1359         uint32_t offset = addr & memory_map_mask();
1360         __UNLIKELY_IF(offset > (memory_map_mask() - 3)) {
1361                 pair32_t d;
1362                 pair16_t w;
1363                 int wait1, wait2, wait3;
1364                 switch(offset & 3) {
1365                 case 1:
1366                 case 3:
1367                         d.b.l  = read_dma_data8w (addr    , &wait1);
1368                         w.w    = read_dma_data16w(addr + 1, &wait2);
1369                         d.b.h3 = read_dma_data8w (addr + 3, &wait3);
1370                         __LIKELY_IF(wait != NULL) {
1371                                 *wait = wait1;
1372                                 //*wait = wait1 + wait2 + wait3;
1373                         }
1374                         break;
1375                 case 2:
1376                         d.w.l  = read_dma_data16w(addr    , &wait1);
1377                         d.w.h  = read_dma_data16w(addr + 2, &wait2);
1378                         __LIKELY_IF(wait != NULL) {
1379                                 *wait = wait1;
1380                                 //*wait = wait1 + wait2;
1381                         }
1382                 default:
1383                         __LIKELY_IF(wait != NULL) {
1384                                 waitval = dma_wait_map_r[mapptr];
1385                                 __LIKELY_IF(waitval < 0) {
1386                                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1387                                 }
1388                                 *wait = waitval;
1389                                 //*wait = wait1 + wait2;
1390                         }
1391                 }
1392                 return d.d;
1393         }
1394         __LIKELY_IF((dma_memory_map_r[mapptr] == NULL) && (dma_devices_map_r[mapptr] == NULL)) {
1395                 return read_data32w(addr, wait);
1396         }
1397         __LIKELY_IF(dma_memory_map_r[mapptr] != NULL) {
1398                 uint8_t* ptr = dma_memory_map_r[mapptr];
1399                 ptr = &(ptr[offset]);
1400                 #ifdef __BIG_ENDIAN__
1401                 pair32_t w;
1402                 d.read_4bytes_le_from(ptr);
1403                 val = d.d;
1404                 #else
1405                 __LIKELY_IF((offset & 3) == 0) {
1406                         uint32_t* q = (uint32_t*)ptr;
1407                         val = *q;
1408                 } else {
1409                         pair32_t d;
1410                         d.read_4bytes_le_from(ptr);
1411                         val = d.d;
1412                 }
1413                 #endif
1414         } else if(dma_devices_map_r[mapptr] != NULL) {
1415                 DEVICE* dev = dma_devices_map_r[mapptr];
1416                 __LIKELY_IF(dma_devices_base_r[mapptr] == UINT32_MAX) {
1417                         offset = addr;
1418                 } else {
1419                         offset += mmio_devices_base_r[mapptr];
1420                 }
1421                 val = dev->read_memory_mapped_io32(offset);
1422         }
1423         __LIKELY_IF(wait != NULL) {
1424                 waitval = dma_wait_map_r[mapptr];
1425                 __LIKELY_IF(waitval < 0) {
1426                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1427                 }
1428                 //__LIKELY_IF((offset & 1) == 0) {
1429                         *wait = waitval;
1430                 //} else {
1431                 //      *wait = waitval * 2;
1432                 //}
1433         }
1434         return val;
1435 }
1436
1437
1438 void TOWNS_MEMORY::write_data8w(uint32_t addr, uint32_t data, int* wait)
1439 {
1440         int waitval;
1441         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1442         uint32_t offset = addr & memory_map_mask();
1443         __LIKELY_IF(mmio_memory_map_w[mapptr] != NULL) {
1444                 uint8_t* ptr = mmio_memory_map_w[mapptr];
1445                 ptr[offset] = data;
1446         } else if(mmio_devices_map_w[mapptr] != NULL) {
1447                 DEVICE* dev = mmio_devices_map_w[mapptr];
1448                 __LIKELY_IF(mmio_devices_base_w[mapptr] == UINT32_MAX) {
1449                         dev->write_memory_mapped_io8(addr, data);
1450                 } else {
1451                         offset += mmio_devices_base_w[mapptr];
1452                         dev->write_memory_mapped_io8(offset, data);
1453                 }
1454         }
1455         __LIKELY_IF(wait != NULL) {
1456                 waitval = mmio_wait_map_w[mapptr];
1457                 __LIKELY_IF(waitval < 0) {
1458                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1459                 }
1460                 *wait = waitval;
1461         }
1462         return;
1463 }
1464
1465
1466 void TOWNS_MEMORY::write_data16w(uint32_t addr, uint32_t data, int* wait)
1467 {
1468         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1469         uint32_t offset = addr & memory_map_mask();
1470         int waitval;
1471         __UNLIKELY_IF(offset == memory_map_mask()) {
1472                 // Beyond via bound
1473                 pair16_t d;
1474                 int wait1, wait2;
1475                 d.w = data;
1476                 write_data8w(addr    , d.b.l, &wait1);
1477                 write_data8w(addr + 1, d.b.h, &wait2);
1478                 __LIKELY_IF(wait != NULL) {
1479                         *wait = wait1 + wait2;
1480                 }
1481                 return;
1482         }
1483         __LIKELY_IF(mmio_memory_map_w[mapptr] != NULL) {
1484                 uint8_t* ptr = mmio_memory_map_w[mapptr];
1485                 ptr = &(ptr[offset]);
1486                 #ifdef __BIG_ENDIAN__
1487                 pair16_t d;
1488                 d.w = data;
1489                 d.write_2bytes_le_to(ptr);
1490                 #else
1491                 __LIKELY_IF((offset & 1) == 0) { // Aligned
1492                         uint16_t* q = (uint16_t*)ptr;
1493                         *q = data;
1494                 } else {
1495                         pair16_t d;
1496                         d.w = data;
1497                         d.write_2bytes_le_to(ptr);
1498                 }
1499                 #endif
1500         } else if(mmio_devices_map_w[mapptr] != NULL) {
1501                 DEVICE* dev = mmio_devices_map_w[mapptr];
1502                 __LIKELY_IF(mmio_devices_base_w[mapptr] == UINT32_MAX) {
1503                         offset = addr;
1504                 } else {
1505                         offset += mmio_devices_base_w[mapptr];
1506                 }
1507                 dev->write_memory_mapped_io16(offset, data);
1508         }
1509         __LIKELY_IF(wait != NULL) {
1510                 waitval = mmio_wait_map_w[mapptr];
1511                 __LIKELY_IF(waitval < 0) {
1512                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1513                 }
1514                 //#if _MEMORY_BUS_WIDTH == 16
1515                 //__UNLIKELY_IF((offset & 1) != 0) { // Penalty; maybe not need to.
1516                 //      waitval *= 2;
1517                 //}
1518                 //#else
1519                 // 32bit
1520                 //__UNLIKELY_IF((offset & 3) != 0) { // Penalty; maybe not need to.
1521                 //      waitval *= 2;
1522                 //}
1523                 //#endif
1524                 *wait = waitval;
1525         }
1526         return;
1527 }
1528
1529
1530 void TOWNS_MEMORY::write_data32w(uint32_t addr, uint32_t data, int* wait)
1531 {
1532         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1533         uint32_t offset = addr & memory_map_mask();
1534         int waitval;
1535         __UNLIKELY_IF(offset > (memory_map_mask() - 3)) {
1536                 // Beyond via bound
1537                 pair32_t d;
1538                 pair16_t w;
1539                 int wait1, wait2, wait3;
1540                 d.d = data;
1541                 switch(offset & 3) {
1542                 case 1:
1543                 case 3:
1544                         write_data8w(addr    , d.b.l, &wait1);
1545                         w.b.l = d.b.h;
1546                         w.b.h = d.b.h2;
1547                         write_data16w(addr + 1, w.w, &wait2);
1548                         write_data8w(addr + 3, d.b.h3, &wait3);
1549                         __LIKELY_IF(wait != NULL) {
1550                                 *wait = wait1; // WORKAROUND
1551                                 //#if _MEMORY_BUS_WIDTH == 16
1552                                 //*wait = wait1 + wait2 + wait3; // OK?
1553                                 //#else
1554                                 //*wait = wait1 + wait3; // OK?
1555                                 //#endif
1556                         }
1557                         break;
1558                 case 2:
1559                         write_data16w(addr    , d.w.l, &wait1);
1560                         write_data16w(addr + 2, d.w.h, &wait2);
1561                         __LIKELY_IF(wait != NULL) {
1562                                 *wait = wait1; // WORKAROUND
1563                                 //#if _MEMORY_BUS_WIDTH == 16
1564                                 //*wait = wait1 + wait2 + wait3; // OK?
1565                                 //#else
1566                                 //*wait = wait1 + wait3; // OK?
1567                                 //#endif
1568                         }
1569                         break;
1570                 default:
1571                         __LIKELY_IF(wait != NULL) {
1572                                 waitval = mmio_wait_map_w[mapptr];
1573                                 __LIKELY_IF(waitval < 0) {
1574                                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1575                                 }
1576                                 *wait = waitval; // WORKAROUND
1577                                 //#if _MEMORY_BUS_WIDTH == 16
1578                                 //*wait = wait1 + wait2 + wait3; // OK?
1579                                 //#else
1580                                 //*wait = wait1 + wait3; // OK?
1581                                 //#endif
1582                         }
1583                         break;
1584                 }
1585                 return;
1586         }
1587
1588         __LIKELY_IF(mmio_memory_map_w[mapptr] != NULL) {
1589                 uint8_t* ptr = mmio_memory_map_w[mapptr];
1590                 ptr = &(ptr[offset]);
1591                 #ifdef __BIG_ENDIAN__
1592                 pair32_t d;
1593                 d.d = data;
1594                 d.write_4bytes_le_to(ptr);
1595                 #else
1596                 __LIKELY_IF((offset & 3) == 0) { // Aligned
1597                         uint32_t* q = (uint32_t*)ptr;
1598                         *q = data;
1599                 } else {
1600                         pair32_t d;
1601                         d.d = data;
1602                         d.write_4bytes_le_to(ptr);
1603                 }
1604                 #endif
1605         } else if(mmio_devices_map_w[mapptr] != NULL) {
1606                 DEVICE* dev = mmio_devices_map_w[mapptr];
1607                 __LIKELY_IF(mmio_devices_base_w[mapptr] == UINT32_MAX) {
1608                         offset = addr;
1609                 } else {
1610                         offset += mmio_devices_base_w[mapptr];
1611                 }
1612                 dev->write_memory_mapped_io32(offset, data);
1613         }
1614         __LIKELY_IF(wait != NULL) {
1615                 waitval = mmio_wait_map_w[mapptr];
1616                 __LIKELY_IF(waitval < 0) {
1617                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1618                 }
1619                 //#if _MEMORY_BUS_WIDTH == 16
1620                 //__UNLIKELY_IF((offset & 3) != 0) { // Penalty; maybe not need to.
1621                 //      waitval *= 4;
1622                 //}
1623                 //#else
1624                 // 32bit
1625                 //__UNLIKELY_IF((offset & 3) != 0) { // Penalty; maybe not need to.
1626                 //      waitval *= 4;
1627                 //}
1628                 //#endif
1629                 *wait = waitval;
1630         }
1631         return;
1632 }
1633
1634 void TOWNS_MEMORY::write_dma_data8w(uint32_t addr, uint32_t data, int* wait)
1635 {
1636         int waitval;
1637         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1638         uint32_t offset = addr & memory_map_mask();
1639         __LIKELY_IF((dma_memory_map_w[mapptr] == NULL) && (dma_devices_map_w[mapptr] == NULL)) {
1640                 write_data8w(addr, data, wait);
1641                 return;
1642         }
1643         __LIKELY_IF(dma_memory_map_w[mapptr] != NULL) {
1644                 uint8_t* ptr = dma_memory_map_w[mapptr];
1645                 ptr[offset] = data;
1646         } else if(dma_devices_map_w[mapptr] != NULL) {
1647                 DEVICE* dev = dma_devices_map_w[mapptr];
1648                 __LIKELY_IF(dma_devices_base_w[mapptr] == UINT32_MAX) {
1649                         dev->write_memory_mapped_io8(addr, data);
1650                 } else {
1651                         offset += dma_devices_base_w[mapptr];
1652                         dev->write_memory_mapped_io8(offset, data);
1653                 }
1654         }
1655         __LIKELY_IF(wait != NULL) {
1656                 waitval = dma_wait_map_w[mapptr];
1657                 __LIKELY_IF(waitval < 0) {
1658                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1659                 }
1660                 *wait = waitval;
1661         }
1662         return;
1663 }
1664
1665 void TOWNS_MEMORY::write_dma_data16w(uint32_t addr, uint32_t data, int* wait)
1666 {
1667         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1668         uint32_t offset = addr & memory_map_mask();
1669         int waitval;
1670         __UNLIKELY_IF(offset == memory_map_mask()) {
1671                 // Beyond via bound
1672                 pair16_t d;
1673                 int wait1, wait2;
1674                 d.w = data;
1675                 write_dma_data8w(addr    , d.b.l, &wait1);
1676                 write_dma_data8w(addr + 1, d.b.h, &wait2);
1677                 __LIKELY_IF(wait != NULL) {
1678                         *wait = wait1 + wait2;
1679                 }
1680                 return;
1681         }
1682         __LIKELY_IF((dma_memory_map_w[mapptr] == NULL) && (dma_devices_map_w[mapptr] == NULL)) {
1683                 // ToDO: BEYOND THE BOUNDARY.
1684                 write_data16w(addr, data, wait);
1685                 return;
1686         }
1687         __LIKELY_IF(dma_memory_map_w[mapptr] != NULL) {
1688                 uint8_t* ptr = dma_memory_map_w[mapptr];
1689                 ptr = &(ptr[offset]);
1690                 #ifdef __BIG_ENDIAN__
1691                 pair16_t d;
1692                 d.w = data;
1693                 d.write_2bytes_le_to(ptr);
1694                 #else
1695                 __LIKELY_IF((offset & 1) == 0) { // Aligned
1696                         uint16_t* q = (uint16_t*)ptr;
1697                         *q = data;
1698                 } else {
1699                         pair16_t d;
1700                         d.w = data;
1701                         d.write_2bytes_le_to(ptr);
1702                 }
1703                 #endif
1704         } else if(dma_devices_map_w[mapptr] != NULL) {
1705                 DEVICE* dev = dma_devices_map_w[mapptr];
1706                 __LIKELY_IF(dma_devices_base_w[mapptr] == UINT32_MAX) {
1707                         offset = addr;
1708                 } else {
1709                         offset += dma_devices_base_w[mapptr];
1710                 }
1711                 dev->write_memory_mapped_io16(offset, data);
1712         }
1713         __LIKELY_IF(wait != NULL) {
1714                 waitval = dma_wait_map_w[mapptr];
1715                 __LIKELY_IF(waitval < 0) {
1716                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1717                 }
1718                 //#if _MEMORY_BUS_WIDTH == 16
1719                 //__UNLIKELY_IF((offset & 1) != 0) { // Penalty; maybe not need to.
1720                 //      waitval *= 2;
1721                 //}
1722                 //#else
1723                 // 32bit
1724                 //__UNLIKELY_IF((offset & 3) != 0) { // Penalty; maybe not need to.
1725                 //      waitval *= 2;
1726                 //}
1727                 //#endif
1728                 *wait = waitval;
1729         }
1730         return;
1731 }
1732
1733
1734 void TOWNS_MEMORY::write_dma_data32w(uint32_t addr, uint32_t data, int* wait)
1735 {
1736         uint32_t mapptr = (uint32_t)(((uint64_t)addr) >> memory_map_shift());
1737         uint32_t offset = addr & memory_map_mask();
1738         int waitval;
1739         __UNLIKELY_IF(offset > (memory_map_mask() - 3)) {
1740                 // Beyond via bound
1741                 pair32_t d;
1742                 pair16_t w;
1743                 int wait1, wait2, wait3;
1744                 d.d = data;
1745                 switch(offset & 3) {
1746                 case 1:
1747                 case 3:
1748                         write_dma_data8w(addr    , d.b.l, &wait1);
1749                         w.b.l = d.b.h;
1750                         w.b.h = d.b.h2;
1751                         write_dma_data16w(addr + 1, w.w, &wait2);
1752                         write_dma_data8w(addr + 3, d.b.h3, &wait3);
1753                         __LIKELY_IF(wait != NULL) {
1754                                 *wait = wait1; // WORKAROUND
1755                                 //#if _MEMORY_BUS_WIDTH == 16
1756                                 //*wait = wait1 + wait2 + wait3; // OK?
1757                                 //#else
1758                                 //*wait = wait1 + wait3; // OK?
1759                                 //#endif
1760                         }
1761                         break;
1762                 case 2:
1763                         write_dma_data16w(addr    , d.w.l, &wait1);
1764                         write_dma_data16w(addr + 2, d.w.h, &wait2);
1765                         __LIKELY_IF(wait != NULL) {
1766                                 *wait = wait1; // WORKAROUND
1767                                 //#if _MEMORY_BUS_WIDTH == 16
1768                                 //*wait = wait1 + wait2 + wait3; // OK?
1769                                 //#else
1770                                 //*wait = wait1 + wait3; // OK?
1771                                 //#endif
1772                         }
1773                         break;
1774                 default:
1775                         __LIKELY_IF(wait != NULL) {
1776                                 waitval = dma_wait_map_w[mapptr];
1777                                 __LIKELY_IF(waitval < 0) {
1778                                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1779                                 }
1780                                 *wait = waitval; // WORKAROUND
1781                                 //#if _MEMORY_BUS_WIDTH == 16
1782                                 //*wait = wait1 + wait2 + wait3; // OK?
1783                                 //#else
1784                                 //*wait = wait1 + wait3; // OK?
1785                                 //#endif
1786                         }
1787                         break;
1788                 }
1789                 return;
1790         }
1791
1792         __LIKELY_IF((dma_memory_map_w[mapptr] == NULL) && (dma_devices_map_w[mapptr] == NULL)) {
1793                 // ToDO: BEYOND THE BOUNDARY.
1794                 write_data32w(addr, data, wait);
1795                 return;
1796         }
1797         __LIKELY_IF(dma_memory_map_w[mapptr] != NULL) {
1798                 uint8_t* ptr = dma_memory_map_w[mapptr];
1799                 ptr = &(ptr[offset]);
1800                 #ifdef __BIG_ENDIAN__
1801                 pair32_t d;
1802                 d.d = data;
1803                 d.write_4bytes_le_to(ptr);
1804                 #else
1805                 __LIKELY_IF((offset & 3) == 0) { // Aligned
1806                         uint32_t* q = (uint32_t*)ptr;
1807                         *q = data;
1808                 } else {
1809                         pair32_t d;
1810                         d.d = data;
1811                         d.write_4bytes_le_to(ptr);
1812                 }
1813                 #endif
1814         } else if(dma_devices_map_w[mapptr] != NULL) {
1815                 DEVICE* dev = dma_devices_map_w[mapptr];
1816                 __LIKELY_IF(dma_devices_base_w[mapptr] == UINT32_MAX) {
1817                         offset = addr;
1818                 } else {
1819                         offset += dma_devices_base_w[mapptr];
1820                 }
1821                 dev->write_memory_mapped_io32(offset, data);
1822         }
1823         __LIKELY_IF(wait != NULL) {
1824                 waitval = dma_wait_map_w[mapptr];
1825                 __LIKELY_IF(waitval < 0) {
1826                         waitval = (waitval == WAITVAL_VRAM) ? vram_wait_val : mem_wait_val;
1827                 }
1828                 //#if _MEMORY_BUS_WIDTH == 16
1829                 //__UNLIKELY_IF((offset & 3) != 0) { // Penalty; maybe not need to.
1830                 //      waitval *= 4;
1831                 //}
1832                 //#else
1833                 // 32bit
1834                 //__UNLIKELY_IF((offset & 3) != 0) { // Penalty; maybe not need to.
1835                 //      waitval *= 4;
1836                 //}
1837                 //#endif
1838                 *wait = waitval;
1839         }
1840         return;
1841 }
1842
1843
1844
1845 uint32_t TOWNS_MEMORY::read_memory_mapped_io8(uint32_t addr)
1846 {
1847         // This should be for VRAM MODE, with ROMs (000C8000h - 000CFFFFh)
1848         __UNLIKELY_IF((addr >= 0x000d0000) || (addr < 0x000c8000)) {
1849                 return 0xff;
1850         }
1851         __LIKELY_IF(addr >= 0x000cc000) {
1852                 // RAM: OK?
1853                 __UNLIKELY_IF(addr >= 0x000cff80) { // I/O
1854                         return read_fmr_ports8(addr);
1855                 }
1856                 return ram_pagec[addr & 0x0000ffff];
1857         }
1858         // ROMs?
1859         if(addr < 0x000ca000) { //SPRITE
1860                 __LIKELY_IF(d_sprite != NULL) {
1861                         return d_sprite->read_memory_mapped_io8(addr);
1862                 }
1863                 return 0xff;
1864         }
1865         if(ankcg_enabled) {
1866                 __LIKELY_IF(d_font != NULL) {
1867                         return d_font->read_memory_mapped_io8(addr);
1868                 }
1869         } else {
1870                 __LIKELY_IF(d_sprite != NULL) {
1871                         return d_sprite->read_memory_mapped_io8(addr);
1872                 }
1873         }
1874         return 0xff;
1875 }
1876
1877 uint32_t TOWNS_MEMORY::read_memory_mapped_io16(uint32_t addr)
1878 {
1879         // This should be for VRAM MODE, with ROMs (000C8000h - 000CFFFFh)
1880         __UNLIKELY_IF((addr >= 0x000d0000) || (addr < 0x000c8000)) {
1881                 return 0xffff;
1882         }
1883         __LIKELY_IF(addr >= 0x000cc000) {
1884                 // RAM: OK?
1885                 pair16_t w;
1886                 __UNLIKELY_IF(addr >= 0x000cff80) { // I/O
1887                         w.b.l = read_fmr_ports8(addr);
1888                         w.b.h = read_fmr_ports8(addr + 1);
1889                 } else {
1890                         w.read_2bytes_le_from(&(ram_pagec[addr & 0x0000ffff]));
1891                 }
1892                 return w.w;
1893         }
1894         // ROMs?
1895         if(addr < 0x000ca000) { //SPRITE
1896                 __LIKELY_IF(d_sprite != NULL) {
1897                         return d_sprite->read_memory_mapped_io16(addr);
1898                 }
1899                 return 0xffff;
1900         }
1901         if(ankcg_enabled) {
1902                 __LIKELY_IF(d_font != NULL) {
1903                         return d_font->read_memory_mapped_io16(addr);
1904                 }
1905         } else {
1906                 __LIKELY_IF(d_sprite != NULL) {
1907                         return d_sprite->read_memory_mapped_io16(addr);
1908                 }
1909         }
1910         return 0xffff;
1911 }
1912
1913 uint32_t TOWNS_MEMORY::read_memory_mapped_io32(uint32_t addr)
1914 {
1915         // This should be for VRAM MODE, with ROMs (000C8000h - 000CFFFFh)
1916         __UNLIKELY_IF((addr >= 0x000d0000) || (addr < 0x000c8000)) {
1917                 return 0xffffffff;
1918         }
1919         __LIKELY_IF(addr >= 0x000cc000) {
1920                 // RAM: OK?
1921                 pair32_t d;
1922                 __UNLIKELY_IF(addr >= 0x000cff80) { // I/O
1923                         d.b.l  = read_fmr_ports8(addr);
1924                         d.b.h  = read_fmr_ports8(addr + 1);
1925                         d.b.h2 = read_fmr_ports8(addr + 2);
1926                         d.b.h3 = read_fmr_ports8(addr + 3);
1927                 } else {
1928                         d.read_4bytes_le_from(&(ram_pagec[addr & 0x0000ffff]));
1929                 }
1930                 return d.d;
1931         }
1932         // ROMs?
1933         if(addr < 0x000ca000) { //SPRITE
1934                 __LIKELY_IF(d_sprite != NULL) {
1935                         return d_sprite->read_memory_mapped_io32(addr);
1936                 }
1937                 return 0xffffffff;
1938         }
1939         if(ankcg_enabled) {
1940                 __LIKELY_IF(d_font != NULL) {
1941                         return d_font->read_memory_mapped_io32(addr);
1942                 }
1943         } else {
1944                 __LIKELY_IF(d_sprite != NULL) {
1945                         return d_sprite->read_memory_mapped_io32(addr);
1946                 }
1947         }
1948         return 0xffffffff;
1949 }
1950
1951
1952 void TOWNS_MEMORY::write_memory_mapped_io8(uint32_t addr, uint32_t data)
1953 {
1954         // This should be for VRAM MODE, with ROMs (000C8000h - 000CFFFFh)
1955         __UNLIKELY_IF((addr >= 0x000d0000) || (addr < 0x000c8000)) {
1956                 return;
1957         }
1958         __LIKELY_IF(addr >= 0x000cc000) {
1959                 // RAM: OK?
1960                 __UNLIKELY_IF(addr >= 0x000cff80) { // I/O
1961                         write_fmr_ports8(addr, data);
1962                         return;
1963                 }
1964                 ram_pagec[addr & 0x0000ffff] = data;
1965                 return;
1966         }
1967         // ROMs?
1968         if(addr < 0x000ca000) { //SPRITE
1969                 __LIKELY_IF(d_sprite != NULL) {
1970                         d_sprite->write_memory_mapped_io8(addr, data);
1971                 }
1972                 return;
1973         }
1974         if(!(ankcg_enabled)) {
1975                 __LIKELY_IF(d_sprite != NULL) {
1976                         d_sprite->write_memory_mapped_io8(addr, data);
1977                 }
1978         }
1979         return;
1980 }
1981
1982 void TOWNS_MEMORY::write_memory_mapped_io16(uint32_t addr, uint32_t data)
1983 {
1984         // This should be for VRAM MODE, with ROMs (000C8000h - 000CFFFFh)
1985         __UNLIKELY_IF((addr >= 0x000d0000) || (addr < 0x000c8000)) {
1986                 return;
1987         }
1988         __LIKELY_IF(addr >= 0x000cc000) {
1989                 // RAM: OK?
1990                 pair16_t w;
1991                 w.w = data;
1992                 __UNLIKELY_IF(addr >= 0x000cff80) { // I/O
1993                         write_fmr_ports8(addr    , w.b.l);
1994                         write_fmr_ports8(addr + 1, w.b.h);
1995                         return;
1996                 }
1997                 w.write_2bytes_le_to(&(ram_pagec[addr & 0x0000ffff]));
1998                 return;
1999         }
2000         // ROMs?
2001         if(addr < 0x000ca000) { //SPRITE
2002                 __LIKELY_IF(d_sprite != NULL) {
2003                         d_sprite->write_memory_mapped_io16(addr, data);
2004                 }
2005                 return;
2006         }
2007         if(!(ankcg_enabled)) {
2008                 __LIKELY_IF(d_sprite != NULL) {
2009                         d_sprite->write_memory_mapped_io16(addr, data);
2010                 }
2011         }
2012         return;
2013 }
2014
2015 void TOWNS_MEMORY::write_memory_mapped_io32(uint32_t addr, uint32_t data)
2016 {
2017         // This should be for VRAM MODE, with ROMs (000C8000h - 000CFFFFh)
2018         __UNLIKELY_IF((addr >= 0x000d0000) || (addr < 0x000c8000)) {
2019                 return;
2020         }
2021         __LIKELY_IF(addr >= 0x000cc000) {
2022                 // RAM: OK?
2023                 pair32_t d;
2024                 d.d = data;
2025                 __UNLIKELY_IF(addr >= 0x000cff80) { // I/O
2026                         write_fmr_ports8(addr    , d.b.l);
2027                         write_fmr_ports8(addr + 1, d.b.h);
2028                         write_fmr_ports8(addr + 2, d.b.h2);
2029                         write_fmr_ports8(addr + 3, d.b.h3);
2030                         return;
2031                 }
2032                 d.write_4bytes_le_to(&(ram_pagec[addr & 0x0000ffff]));
2033                 return;
2034         }
2035         // ROMs?
2036         if(addr < 0x000ca000) { //SPRITE
2037                 __LIKELY_IF(d_sprite != NULL) {
2038                         d_sprite->write_memory_mapped_io32(addr, data);
2039                 }
2040                 return;
2041         }
2042         if(!(ankcg_enabled)) {
2043                 __LIKELY_IF(d_sprite != NULL) {
2044                         d_sprite->write_memory_mapped_io32(addr, data);
2045                 }
2046         }
2047         return;
2048 }
2049
2050
2051
2052 void TOWNS_MEMORY::write_signal(int ch, uint32_t data, uint32_t mask)
2053 {
2054         if(ch == SIG_MEMORY_EXTNMI) {
2055                 extra_nmi_val = ((data & mask) != 0);
2056                 if(!(extra_nmi_mask)) {
2057                         // Not MASK
2058                         __LIKELY_IF(d_cpu != NULL) {
2059                                 d_cpu->write_signal(SIG_CPU_NMI, data, mask);
2060                         }
2061                 }
2062         } else if(ch == SIG_CPU_NMI) {
2063                 // Check protect
2064                 if(!(nmi_mask)) {
2065                         __LIKELY_IF(d_cpu != NULL) {
2066                                 d_cpu->write_signal(SIG_CPU_NMI, data, mask);
2067                         }
2068                 }
2069         } else if(ch == SIG_CPU_IRQ) {
2070                 __LIKELY_IF(d_cpu != NULL) {
2071                         d_cpu->write_signal(SIG_CPU_IRQ, data, mask);
2072                 }
2073         } else if(ch == SIG_CPU_BUSREQ) {
2074                 __LIKELY_IF(d_cpu != NULL) {
2075                         d_cpu->write_signal(SIG_CPU_BUSREQ, data, mask);
2076                 }
2077         } else if(ch == SIG_I386_A20) {
2078                 __LIKELY_IF(d_cpu != NULL) {
2079                         d_cpu->write_signal(SIG_I386_A20, data, mask);
2080                 }
2081         } else if(ch == SIG_FMTOWNS_NOTIFY_RESET) {
2082                 out_debug_log("RESET FROM CPU!!!\n");
2083                 reset_happened = true;
2084
2085                 nmi_vector_protect = false;
2086                 ankcg_enabled = false;
2087                 nmi_mask = false;
2088                 config_page0c_0e(true, false, true);
2089                 config_page0f(true, true);
2090                 reset_wait_values();
2091                 set_wait_values();
2092
2093                 __LIKELY_IF(d_cpu != NULL) {
2094                         d_cpu->set_address_mask(0xffffffff);
2095                 }
2096                 __LIKELY_IF(d_dmac != NULL) {
2097                         uint8_t wrap_val = 0xff; // WRAP ON
2098                         d_dmac->write_signal(SIG_TOWNS_DMAC_WRAP, wrap_val, 0xff);
2099                 }
2100         } else if(ch == SIG_FMTOWNS_RAM_WAIT) {
2101                 uint8_t _bak = mem_wait_val;
2102                 mem_wait_val = (int)data;
2103                 if(_bak != mem_wait_val) {
2104                         set_wait_values();
2105                 }
2106         } else if(ch == SIG_FMTOWNS_ROM_WAIT) {
2107 //              mem_wait_val = (int)data;
2108                 set_wait_values();
2109         } else if(ch == SIG_FMTOWNS_VRAM_WAIT) {
2110                 uint8_t _bak = vram_wait_val;
2111                 vram_wait_val = (int)data;
2112                 if(_bak != vram_wait_val) {
2113                         set_wait_values();
2114                 }
2115         }
2116 }
2117
2118 uint32_t TOWNS_MEMORY::read_signal(int ch)
2119 {
2120         if(ch == SIG_FMTOWNS_MACHINE_ID) {
2121                 uint16_t d = (machine_id & 0xfff8) | ((uint16_t)(cpu_id & 0x07));
2122                 return (uint32_t)d;
2123         } else if(ch == SIG_FMTOWNS_RAM_WAIT) {
2124                 return (uint32_t)mem_wait_val;
2125         } else if(ch == SIG_FMTOWNS_ROM_WAIT) {
2126                 return 6; // OK?
2127         } else if(ch == SIG_FMTOWNS_VRAM_WAIT) {
2128                 return (uint32_t)vram_wait_val;
2129         }
2130         return 0;
2131 }
2132
2133 void TOWNS_MEMORY::set_intr_line(bool line, bool pending, uint32_t bit)
2134 {
2135         __LIKELY_IF(d_cpu != NULL) {
2136                 d_cpu->set_intr_line(line, pending, bit);
2137         }
2138 }
2139
2140 // ToDo: DMA
2141
2142 #define STATE_VERSION   6
2143
2144 bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading)
2145 {
2146         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
2147                 return false;
2148         }
2149
2150         if(!state_fio->StateCheckInt32(this_device_id)) {
2151                 return false;
2152         }
2153         state_fio->StateValue(machine_id);
2154         state_fio->StateValue(cpu_id);
2155         state_fio->StateValue(is_compatible);
2156
2157         state_fio->StateValue(mem_wait_val);
2158         state_fio->StateValue(vram_wait_val);
2159         state_fio->StateValue(wait_register_older);
2160         state_fio->StateValue(wait_register_ram);
2161         state_fio->StateValue(wait_register_vram);
2162
2163         state_fio->StateValue(dma_is_vram);
2164         state_fio->StateValue(nmi_vector_protect);
2165         state_fio->StateValue(software_reset);
2166         state_fio->StateValue(poff_status);
2167         state_fio->StateValue(reset_happened);
2168
2169         state_fio->StateValue(extra_nmi_val);
2170         state_fio->StateValue(extra_nmi_mask);
2171         state_fio->StateValue(nmi_mask);
2172
2173         state_fio->StateArray(ram_page0,  sizeof(ram_page0), 1);
2174         state_fio->StateArray(ram_pagec,  sizeof(ram_pagec), 1);
2175
2176         state_fio->StateValue(select_d0_rom);
2177         state_fio->StateValue(select_d0_dict);
2178         state_fio->StateValue(ankcg_enabled);
2179
2180         state_fio->StateValue(vram_wait_val);
2181         state_fio->StateValue(mem_wait_val);
2182         state_fio->StateValue(vram_size);
2183         state_fio->StateValue(cpu_clock_val);
2184
2185         if(loading) {
2186                 update_machine_features(); // Update MISC3, MISC4 by MACHINE ID.
2187
2188                 uint32_t length_tmp = state_fio->FgetUint32_LE();
2189                 unset_range_rw(0x00100000, 0x3fffffff);
2190                 if(extra_ram != NULL) {
2191                         free(extra_ram);
2192                         extra_ram = NULL;
2193                 }
2194                 length_tmp = length_tmp & 0x3ff00000;
2195                 extram_size = length_tmp;
2196                 if(length_tmp > 0) {
2197                         extra_ram = (uint8_t*)malloc(length_tmp);
2198                         __LIKELY_IF(extra_ram != NULL) {
2199                                 set_region_memory_rw(0x00100000, (extram_size + 0x00100000) - 1, extra_ram);
2200                                 memset(extra_ram, 0x00, extram_size);
2201                         }
2202                 }
2203
2204                 if(extra_ram == NULL) {
2205                         extram_size = 0;
2206                         return false;
2207                 } else {
2208                         state_fio->Fread(extra_ram, extram_size, 1);
2209                         //set_memory_rw(0x00100000, (extram_size + 0x00100000) - 1, extra_ram);
2210                 }
2211                 config_page0c_0e(dma_is_vram, select_d0_dict, true);
2212                 config_page0f(select_d0_rom, true);
2213                 set_wait_values();
2214                 //config_page00();
2215         } else {
2216                 // At saving
2217                 if(extra_ram == NULL) {
2218                         state_fio->FputUint32_LE(0);
2219                 } else {
2220                         state_fio->FputUint32_LE(extram_size & 0x3ff00000);
2221                         state_fio->Fwrite(extra_ram, extram_size, 1);
2222                 }
2223         }
2224
2225         // ToDo: Do save ROMs?
2226         return true;
2227 }
2228
2229 }