OSDN Git Service

[VM][FMTOWNS] Add FONT ROMS, MSDOS ROM, SYSTEM ROM and SERIAL ROM.
[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 "../i386.h"
13
14 namespace FMTOWNS {
15         
16 void TOWNS_MEMORY::initialize()
17 {
18
19         extra_nmi_mask = true;
20         extra_nmi_val = false;
21         
22         vram_wait_val = 6;
23         mem_wait_val = 3;
24
25         
26         memset(ram_page0, 0x00, sizeof(ram_page0));
27
28         // load rom image
29 #if 0
30         if(fio->Fopen(create_local_path(_T("FMT_F20.ROM")), FILEIO_READ_BINARY)) { // 20 pixels FONT : Optional
31                 fio->Fread(rom_font20, sizeof(rom_font20), 1);
32                 fio->Fclose();
33         }
34 #endif
35         // ToDo: Will move to config.
36         extram_size = TOWNS_EXTRAM_PAGES * 0x100000;
37         // ToDo: Limit extram_size per VM.
38         extram = (uint8_t *)malloc(extram_size);
39         // ToDo: More smart.
40         vram_size = 0x80000; // OK?
41         
42         //dma_addr_reg = dma_wrap_reg = 0;
43         dma_addr_mask = 0x00ffffff; // ToDo
44         
45         initialize_tables();
46 }
47
48 void TOWNS_MEMORY::reset()
49 {
50         // reset memory
51         protect = rst = 0;
52         // ToDo
53         dma_addr_reg = dma_wrap_reg = 0;
54         dma_addr_mask = 0x00ffffff;
55         d_cpu->set_address_mask(0xffffffff);
56 }
57
58 bool TOWNS_MEMORY::check_bank(uint32_t addr, uint32_t *mask, uint32_t *offset, void** readfn, void** writefn, void** readp, void** writep)
59 {
60         uint8_t __type = (uint8_t)(type_bank_adrs_cx[banknum] >> 24);
61         uint32_t __offset = type_bank_adrs_cx[banknum] & 0x00ffffff;
62         if(offset == NULL) return false;
63         if(mask == NULL) return false;
64         if(readfn == NULL) return false;
65         if(writefn == NULL) return false;
66         if(readp == NULL) return false;
67         if(writep == NULL) return false;
68
69         *readfn = NULL;
70         *writefn = NULL;
71         *readp = NULL;
72         *writep = NULL;
73         *mask = 0x00;
74         *offset = 0;
75         switch(__type) {
76         case TOWNS_MEMORY_FMR_VRAM:
77                 if(!mainmem_enabled) {
78                         *readfn = (void *)d_vram;
79                         *writefn = (void *)d_vram;
80                         *offset = FMTOWNS_VRAM_PLANE_ACCESS;
81                         *mask = 0x7fff;
82                 } else {
83                         *readp = (void *)(&(ram_0c0[addr & 0x7fff]));
84                         *writep = (void *)(&(ram_0c0[addr & 0x7fff]));
85                         *mask = 0x7fff;
86                 }
87                 break;
88         case TOWNS_MEMORY_FMR_TEXT:
89                 if(!mainmem_enabled) {
90                         if((addr & 0x1000) == 0) {
91                                 *readfn = (void *)d_vram;
92                                 *writefn = (void *)d_vram;
93                                 *offset = FMTOWNS_VRAM_TEXT_VRAM;
94                                 *mask = 0x0fff;
95                         } else {
96                                 *mask = 0x1fff;
97                                 *readp = (void*)(&(ram_0c8[addr & 0x1fff]));
98                                 *writedp = (void*)(&(ram_0c8[addr & 0x1fff]));
99                         }                                               
100                 } else {
101                         *mask = 0x1fff;
102                         *readp = (void*)(&(ram_0c8[addr & 0x1fff]));
103                         *writedp = (void*)(&(ram_0c8[addr & 0x1fff]));
104                 }
105                 break;
106         case TOWNS_MEMORY_MMIO_0CC:
107                 if(!mainmem_enabled) {
108                         if((addr & 0xfffff) < 0xcff80) {
109                                 *mask = 0x3fff;
110                                 *readp = (void*)(&(ram_0cc[addr & 0x3fff]));
111                                 *writedp = (void*)(&(ram_0cc[addr & 0x3fff]));
112                         }
113                 } else {
114                         *mask = 0x3fff;
115                         *readp = (void*)(&(ram_0cc[addr & 0x3fff]));
116                         *writedp = (void*)(&(ram_0cc[addr & 0x3fff]));
117                 }
118                 break;
119         case TOWNS_MEMORY_SPRITE_ANKCG1:
120                 if(!mainmem_enabled) {
121                         if(ankcg_enabled) {
122                                 *offset = 0x000ca000;
123                                 *mask = 0x0fff;
124                                 *readfn = (void *)d_fonts;
125                                 *writefn = (void *)d_fonts;
126                         } else {
127                                 *offset = 0x2000 + FMTOWNS_VRAM_TEXT_VRAM;
128                                 *mask = 0x0fff;
129                                 *readfn = (void *)d_vram;
130                                 *writefn = (void *)d_vram;
131                         }
132                 } else {
133                         *readp = (void*)(&(ram_0ca[addr & 0xfff]));
134                         *writep = (void*)(&(ram_0ca[addr & 0xfff]));
135                 }
136                 break;
137         case TOWNS_MEMORY_SPRITE_ANKCG2:
138                 if(!(mainmem_enabled) && (ankcg_enabled)) {
139                         *offset = 0x000cb000;
140                         *mask = 0x0fff;
141                         *readfn = (void *)d_fonts;
142                         *writefn = (void *)d_fonts;
143                 } else {
144                         *readp = (void*)(&(ram_0cb[addr & 0xfff]));
145                         *writep = (void*)(&(ram_0cb[addr & 0xfff]));
146                         *mask = 0xfff;
147                         *offset = 0;
148                 }
149                 break;
150         default:
151                 return false;
152                 break;
153         }
154         return true;
155         
156 }
157
158
159 uint32_t TOWNS_MEMORY::read_data_base(uint32_t addr, int* wait, int wordsize)
160 {
161         uint8_t *maddr;
162         DEVICE *daddr;
163         uint32_t banknum = addr >> 12;
164         uint32_t _naddr;
165         switch(wordsize) {
166         case 2:
167                 _naddr = addr & 0xfffffffe;
168                 break;
169         case 4:
170                 _naddr = addr & 0xfffffffc;
171                 break;
172         dafault:
173                 _naddr = addr;
174                 break;
175         }
176                 
177         maddr = read_bank_adrs_cx[banknum];
178         if(maddr != NULL)  {
179                 // Memory found.
180                 if(wait != NULL) *wait = mem_wait_val;
181                 uint8_t *p;
182                 switch(wordsize) {
183                 case 1:
184                         p = &maddr[addr & 0x00000fff];
185                         return (uint32_t)(*p);
186                         break;
187                 case 2:
188                         {
189                                 pair16_t _d;
190                                 p = &maddr[addr & 0x00000ffe];
191 #if defined(__LITTLE_ENDIAN__)
192                                 uint16_t* pp = (uint16_t*)p;
193                                 _d.u16 = *pp;
194 #else
195                                 _d.l = p[0];
196                                 _d.h = p[1];
197 #endif
198                                 return _d.u16;
199                         }
200                         break;
201                 case 4:
202                         {
203                                 pair32_t _d;
204                                 p = &maddr[addr & 0x00000ffc];
205 #if defined(__LITTLE_ENDIAN__)
206                                 uint32_t* pp = (uint32_t*)p;
207                                 _d.u32 = *pp;
208 #else
209                                 _d.l  = p[0];
210                                 _d.h  = p[1];
211                                 _d.h2 = p[2];
212                                 _d.h3 = p[3];
213 #endif
214                                 return _d.u32;
215                         }
216                         break;
217                 default:
218                         return 0xffffffff; // Word size error
219                         break;
220                 }
221         } else {
222                 daddr = device_bank_adrs_cx[banknum];
223                 if(daddr != NULL) {
224                         // Device chained.
225                         switch(wordsize) {
226                         case 1:
227                                 return daddr->read_data8w(addr, wait);
228                                 break;
229                         case 2:
230                                 return daddr->read_data16w(addr, wait);
231                                 break;
232                         case 4:
233                                 return daddr->read_data32w(addr, wait);
234                                 break;
235                         default:
236                                 return 0xffffffff;
237                                 break;
238                         }
239                 } else {
240                         uint32_t _mask;
241                         uint32_t _offset;
242                         DEVICE* readfn;
243                         DEVICE* writefn;
244                         uint8_t* readp;
245                         uint8_t* writep;
246                         if(check_bank(_naddr, &_mask, &_offset, (void**)(&readfn), (void**)(&writefn), (void**)(&readp), (void**)(&writep))) {
247                                 switch(wordsize)
248                                 {
249                                 case 1:
250                                         if(readp != NULL) {
251                                                 if(wait != NULL) *wait = mem_wait_val;
252                                                 return (uint32_t)(*readp);
253                                         } else if(readfn != NULL) {
254                                                 return readfn->read_data8w(_naddr, wait);
255                                         } else {
256                                                 return 0xff;
257                                         }
258                                         break;
259                                 case 2:
260                                         if(readp != NULL) {
261                                                 
262                                                 if(wait != NULL) *wait = mem_wait_val;
263 #if defined(__LITTLE_ENDIAN__)
264                                                 uint16_t *pp = (uint16_t*)readp;
265                                                 return (uint32_t)(*pp);
266 #else
267                                                 pair16_t _d;
268                                                 pair16_t *pp = (pair16_t*)readp;
269                                                 _d.l = pp[0];
270                                                 _d.h = pp[1];
271                                                 return _d.u16;
272 #endif
273                                         } else if(readfn != NULL) {
274                                                 return readfn->read_data16w(_naddr, wait);
275                                         } else {
276                                                 return 0xffff;
277                                         }
278                                         break;
279                                 case 2:
280                                         if(readp != NULL) {
281                                                 
282                                                 if(wait != NULL) *wait = mem_wait_val;
283 #if defined(__LITTLE_ENDIAN__)
284                                                 uint32_t *pp = (uint32_t*)readp;
285                                                 return (uint32_t)(*pp);
286 #else
287                                                 pair32_t _d;
288                                                 _d.l  = readp[0];
289                                                 _d.h  = readp[1];
290                                                 _d.h2 = readp[2];
291                                                 _d.h3 = readp[3];
292                                                 return _d.u32;
293 #endif
294                                         } else if(readfn != NULL) {
295                                                 return readfn->read_data32w(_naddr, wait);
296                                         } else {
297                                                 return 0xffffffff;
298                                         }
299                                         break;
300                                 default:
301                                         return 0xffffffff;
302                                         break;
303                                 }                                       
304                                 // Function or memory don't exist this bank.
305                         } else {
306                                 // Bank not registered.
307                                 if((addr >= 0x000cff80) && (addr <= 0x000cffff)) {
308                                         bool _hit;
309                                         uint32_t val;
310                                         val = read_mmio(addr, wait, &_hit);
311                                         if(!_hit) {
312                                                 ///
313                                         } else {
314                                                 return val;
315                                         }
316                                 }
317                         }
318                 }
319                 // Neither memory nor device nor bank.
320         }
321         return 0xffffffff;
322 }               
323
324 uint32_t TOWNS_MEMORY::read_data8w(uint32_t addr, int *wait)
325 {
326         return read_data_base(addr, wait, 1);
327 }
328 uint32_t TOWNS_MEMORY::read_data16w(uint32_t addr, int *wait)
329 {
330         return read_data_base(addr, wait, 2);
331 }
332
333 uint32_t TOWNS_MEMORY::read_data32w(uint32_t addr, int *wait)
334 {
335         return read_data_base(addr, wait, 4);
336 }
337
338 void TOWNS_MEMORY::write_data_base(uint32_t addr, uint32_t data, int* wait, int wordsize)
339 {
340         uint8_t *maddr;
341         DEVICE *daddr;
342         uint32_t banknum = addr >> 12;
343         uint32_t _naddr;
344         switch(wordsize) {
345         case 2:
346                 _naddr = addr & 0xfffffffe;
347                 break;
348         case 4:
349                 _naddr = addr & 0xfffffffc;
350                 break;
351         dafault:
352                 _naddr = addr;
353                 break;
354         }
355                 
356         maddr = write_bank_adrs_cx[banknum];
357         if(maddr != NULL)  {
358                 // Memory found.
359                 if(wait != NULL) *wait = mem_wait_val;
360                 uint8_t *p;
361                 switch(wordsize) {
362                 case 1:
363                         p = &maddr[addr & 0x00000fff];
364                         *p = (uint8_t)data;
365                         return;
366                         break;
367                 case 2:
368                         {
369                                 pair16_t _d;
370                                 _d.u16 = (uint16_t)data;
371                                 p = &maddr[addr & 0x00000ffe];
372 #if defined(__LITTLE_ENDIAN__)
373                                 uint16_t* pp = (uint16_t*)p;
374                                 *pp = _d.u16;
375 #else
376                                 p[0] = _d.l;
377                                 p[1] = _d.h;
378 #endif
379                                 return;
380                         }
381                         break;
382                 case 4:
383                         {
384                                 pair32_t _d;
385                                 _d.u32 = data;
386                                 p = &maddr[addr & 0x00000ffc];
387 #if defined(__LITTLE_ENDIAN__)
388                                 uint32_t* pp = (uint32_t*)p;
389                                 *pp = data;
390 #else
391                                 p[0] = _d.l;
392                                 p[1] = _d.h;
393                                 p[2] = _d.h2;
394                                 p[3] = _d.h3;
395 #endif
396                                 return;
397                         }
398                         break;
399                 default:
400                         return; // Word size error
401                         break;
402                 }
403         } else {
404                 daddr = device_bank_adrs_cx[banknum];
405                 if(daddr != NULL) {
406                         // Device chained.
407                         switch(wordsize) {
408                         case 1:
409                                 daddr->write_data8w(addr, data, wait);
410                                 break;
411                         case 2:
412                                 daddr->write_data16w(addr, data, wait);
413                                 break;
414                         case 4:
415                                 daddr->write_data32w(addr, data, wait);
416                                 break;
417                         default:
418                                 break;
419                         }
420                         return;
421                 } else {
422                         uint32_t _mask;
423                         uint32_t _offset;
424                         DEVICE* readfn;
425                         DEVICE* writefn;
426                         uint8_t* readp;
427                         uint8_t* writep;
428                         if(check_bank(_naddr, &_mask, &_offset, (void**)(&readfn), (void**)(&writefn), (void**)(&readp), (void**)(&writep))) {
429                                 switch(wordsize)
430                                 {
431                                 case 1:
432                                         if(writep != NULL) {
433                                                 if(wait != NULL) *wait = mem_wait_val;
434                                                 *writep = (uint8_t)data;
435                                         } else if(writefn != NULL) {
436                                                 writefn->write_data8w(_naddr, data, wait);
437                                         }
438                                         break;
439                                 case 2:
440                                         if(writep != NULL) {
441                                                 
442                                                 if(wait != NULL) *wait = mem_wait_val;
443 #if defined(__LITTLE_ENDIAN__)
444                                                 uint16_t *pp = (uint16_t*)writep;
445                                                 *pp = (uint16_t)data;
446 #else
447                                                 pair16_t _d;
448                                                 _d.u16 = (uint16_t)data;
449                                                 writep[0] = _d.l;
450                                                 writep[1] = _d.h;
451 #endif
452                                         } else if(writefn != NULL) {
453                                                 writefn->write_data16w(_naddr, data, wait);
454                                         }
455                                         break;
456                                 case 4:
457                                         if(writep != NULL) {
458                                                 
459                                                 if(wait != NULL) *wait = mem_wait_val;
460 #if defined(__LITTLE_ENDIAN__)
461                                                 uint32_t *pp = (uint32_t*)writep;
462                                                 *pp = (uint32_t)data;
463 #else
464                                                 pair32_t _d;
465                                                 _d.u32 = data;
466                                             writep[0] = _d.l;
467                                             writep[1] = _d.h;
468                                             writep[2] = _d.h2;
469                                             writep[3] = _d.h3;
470 #endif
471                                         } else if(writefn != NULL) {
472                                                 writefn->write_data32w(_naddr, data, wait);
473                                         }
474                                         break;
475                                 default:
476                                         break;
477                                 }                                       
478                                 return;
479                                 // Function or memory don't exist this bank.
480                         } else {
481                                 // Bank not registered.
482                                 if((addr >= 0x000cff80) && (addr <= 0x000cffff)) {
483                                         bool _hit;
484                                         write_mmio(addr, data, wait, &_hit); // ToDo: Not Hit
485                                 }
486                         }
487                 }
488                 // Neither memory nor device nor bank.
489         }
490         return;
491 }               
492
493 void TOWNS_MEMORY::write_data8w(uint32_t addr, uint32_t data, int *wait)
494 {
495         write_data_base(addr, data, wait, 1);
496 }
497
498 void TOWNS_MEMORY::write_data16w(uint32_t addr, uint32_t data, int *wait)
499 {
500         write_data_base(addr, data, wait, 2);
501 }
502
503 void TOWNS_MEMORY::write_data32w(uint32_t addr, uint32_t data, int *wait)
504 {
505         write_data_base(addr, data, wait, 4);
506 }
507
508
509
510 uint32_t TOWNS_MEMORY::read_data8(uint32_t addr)
511 {
512         return read_data_base(addr, NULL, 1);
513 }
514
515 uint32_t TOWNS_MEMORY::read_data16(uint32_t addr)
516 {
517         return read_data_base(addr, NULL, 2);
518 }
519
520 uint32_t TOWNS_MEMORY::read_data32(uint32_t addr)
521 {
522         return read_data_base(addr, NULL, 4);
523 }
524
525 void TOWNS_MEMORY::write_data8(uint32_t addr, uint32_t data)
526 {
527         write_data_base(addr, data, NULL, 1);
528 }
529
530 void TOWNS_MEMORY::write_data16(uint32_t addr, uint32_t data)
531 {
532         write_data_base(addr, data, NULL, 2);
533 }
534
535 void TOWNS_MEMORY::write_data32(uint32_t addr, uint32_t data)
536 {
537         write_data_base(addr, data, NULL, 4);
538 }
539
540 // Address (TOWNS BASIC):
541 // 0x0020 - 0x0022, 0x0030-0x0031,
542 // 0x0400 - 0x0404,
543 // 0x0480 - 0x0484
544 // 0x05c0 - 0x05c2
545 // 0x05ec (Wait register)
546 // Is set extra NMI (0x05c0 - 0x05c2)?
547 uint32_t TOWNS_MEMORY::read_io8(uint32_t addr)
548 {
549         uint32_t val = 0xff;
550         switch(addr & 0xffff) {
551         case 0x0020: // Software reset ETC.
552                 // reset cause register
553                 val = ((software_reset) ? 1 : 0) | ((d_cpu->get_shutdown_flag() != 0) ? 2 : 0);
554                 software_reset = false;
555                 d_cpu->set_shutdown_flag(0);
556                 val =  val | 0x7c;
557                 break;
558         case 0x0022:
559                 // Power register
560                 val = 0xff;
561                 break;
562         case 0x0030:
563                 val = (((machine_id & 0x1f) << 3) | (cpu_id & 7));
564                 // SPEED: bit0/Write
565                 break;
566         case 0x0031:
567                 val = ((machine_id >> 5) & 0xff);
568                 break;
569         case 0x0032:
570                 {
571                         //bool __cs = (d_serialrom->read_data8(SIG_SERIALROM_CS) == 0);
572                         bool __clk = (d_serialrom->read_data8(SIG_SERIALROM_CLK) != 0);
573                         bool __reset = (d_serialrom->read_data8(SIG_SERIALROM_RESET) != 0);
574                         bool __dat = (d_serialrom->read_data8(SIG_SERIALROM_DATA) != 0);
575                         val = ((__reset) ? 0x80 : 0x00) | ((__clk) ? 0x40 : 0x00) | 0x3e | ((__dat) ? 0x01 : 0x00);
576                 }
577                 break;
578         case 0x006c: // Wait register.
579                 if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
580                         val = 0x7f;
581                 }
582                 break;
583         case 0x0400: // Resolution:
584                 val = 0xfe;
585                 break;
586         case 0x0404: // System Status Reg.
587                 val = (bankc0_vram) ? 0x7f : 0xff;
588                 break;
589         case 0x05c0:
590                 val = (extra_nmi_mask) ? 0xf7 : 0xff;
591                 break;
592         case 0x05c2:
593                 val = (extra_nmi_val) ? 0xff : 0xf7;
594                 break;
595         case 0x05e8:
596                 // After Towns1F/2F/1H/2H
597                 {
598                         switch(machine_id & 0xff00) {
599                         case 0x0000:
600                         case 0x0100:
601                                 val = 0xff;
602                                 break;
603                         case 0x0200:
604                         case 0x0300:
605                         case 0x0400:
606                         case 0x0500:
607                         case 0x0600:
608                         case 0x0700:
609                         case 0x0800:
610                         case 0x0a00:
611                                 val = ((extram_size >> 20) & 0x1f);
612                                 break;
613                         case 0x0b00:
614                         case 0x0c00:
615                         case 0x0d00:
616                         case 0x0f00:
617                                 val = ((extram_size >> 20) & 0x7f);
618                                 break;
619                         default:
620                                 val = 0xff; // ???
621                                 break;
622                         }
623                 }
624                 break;
625            
626         case 0x05ec:
627                 if(machine_id >= 0x0500) { // Towns2 CX : Is this hidden register after Towns 1F/2F/1H/2H?
628                    val = 0x00 | ((mem_wait_val > 0) ? 0x01 : 0x00); 
629                 }
630                 break;
631         default:
632                 break;
633         }
634         return val;
635 }
636
637 void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
638 {
639
640         switch(addr & 0xffff) {
641         case 0x0020: // Software reset ETC.
642                 // reset cause register
643                 if((data & 0x80) != 0) {
644                         nmi_vector_protect = true;
645                 } else {
646                         nmi_vector_protect = false;
647                 }
648                 if((data & 0x01) != 0) {
649                         software_reset = true;
650                 } else {
651                         software_reset = false;
652                 }
653                 if((data & 0x40) != 0) {
654                         d_cpu->set_shutdown_flag(1);
655                         emu->power_off();
656                 }
657                 if(software_reset) {
658                         d_cpu->reset();
659                 }
660                 break;
661         case 0x0022:
662                 if((data & 0x40) != 0) {
663                         d_cpu->set_shutdown_flag(1);
664                         emu->power_off();
665                 }
666                 // Power register
667                 break;
668         case 0x0032:
669                 {
670                         d_serialrom->write_data8(SIG_SERIALROM_CS, ~data, 0x20);
671                         d_serialrom->write_data8(SIG_SERIALROM_CLK, data, 0x40);
672                         d_serialrom->write_data8(SIG_SERIALROM_RESET, data, 0x80);
673                 }
674                 break;
675         case 0x006c: // Wait register.
676                 if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
677                         if(event_wait_1us != -1) cancel_event(this, event_wait_1us);
678                         register_event(this, EVENT_1US_WAIT, 1.0, false, &event_wait_1us);
679                         d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
680                 }
681                 break;
682         case 0x0404: // System Status Reg.
683                 bankc0_vram = ((data & 0x80) != 0);
684                 break;
685         case 0x05c0:
686                 extra_nmi_mask = ((data & 0x08) == 0);
687                 break;
688         case 0x05ec:
689                 if(machine_id >= 0x0500) { // Towns2 CX : Is this hidden register after Towns 1F/2F/1H/2H?
690                         vram_wait_val = ((data & 0x01) != 0) ? 3 : 6;
691                         mem_wait_val = ((data & 0x01) != 0) ? 0 : 3;
692                         this->write_signal(SIG_FMTOWNS_SET_VRAMWAIT, vram_wait_val, 0xff);
693                         this->write_signal(SIG_FMTOWNS_SET_MEMWAIT, mem_wait_val, 0xff);
694                 }
695                 break;
696         default:
697                 break;
698         }
699         return;
700 }
701
702 void TOWNS_MEMORY::event_callback(int id, int err)
703 {
704         switch(id) {
705         case EVENT_1US_WAIT:
706                 cvent_wait_1us = -1;
707                 if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
708                         d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
709                 }
710                 break;
711         default:
712                 break;
713         }
714         
715 }
716
717 uint32_t TOWNS_MEMORY::read_mmio(uint32_t addr, int *wait, bool *hit)
718 {
719         if(hit != NULL) *hit = false;
720         if(wait != NULL) *wait = 0; // OK?
721         if(addr >= 0x000d0000) return 0xffffffff;
722         if(addr <  0x000cff80) return 0xffffffff;
723         uint32_t val = 0xff;
724         bool found = false;
725         switch(addr & 0x7f) {
726         case 0x00:
727                 if(d_vram != NULL) {
728                         val = d_vram->read_io8(FMTOWNS_VRAM_IO_CURSOR);
729                         found = true;
730                 }
731                 break;
732         case 0x01:
733                 if(d_vram != NULL) {
734                         val = d_vram->read_io8(FMTOWNS_VRAM_IO_FMR_RAMSELECT);
735                         found = true;
736                 }
737                 break;
738         case 0x02:
739                 if(d_vram != NULL) {
740                         val = d_vram->read_io8(FMTOWNS_VRAM_IO_FMR_DISPMODE);
741                         found = true;
742                 }
743                 break;
744         case 0x03:
745                 if(d_vram != NULL) {
746                         val = d_vram->read_io8(FMTOWNS_VRAM_IO_FMR_PAGESEL);
747                         found = true;
748                 }
749                 break;
750         case 0x04:
751                 val = 0x7f; // Reserve.FIRQ
752                 found = true;
753                 break;
754         case 0x06:
755                 if(d_vram != NULL) {
756                         val = d_vram->read_io8(FMTOWNS_VRAM_IO_SYNC_STATUS);
757                         found = true;
758                 }
759                 break;
760         //case 0x14:
761         //case 0x15:
762         case 0x16:
763         case 0x17:
764                 if(d_vram != NULL) {
765                         val = d_vram->read_io8(FMTOWNS_VRAM_KANJICG + (addr & 3));
766                         found = true;
767                 }
768                 break;
769         case 0x18:
770                 if(d_beep != NULL) {
771                         d_beep->write_signal(SIG_BEEP_ON, 1, 1);
772                         found = true;
773                 }
774                 break;
775         case 0x19:
776                 val = val & ((ankcg_enabled) ? 0x00 : 0x01);
777                 found = true;
778                 break;
779         case 0x20:
780                 val = 0xff;
781                 val = val & 0x7f;
782                 found = true;
783                 break;
784         default:
785                 break;
786         }
787         if(hit != NULL) *hit = found;
788         return (uint32_t)val;
789 }
790
791 void TOWNS_MEMORY::write_mmio(uint32_t addr, uint32_t data, int *wait, bool *hit)
792 {
793         if(hit != NULL) *hit = false;
794         if(wait != NULL) *wait = 0; // OK?
795         if(addr >= 0x000d0000) return;
796         if(addr <  0x000cff80) return;
797         bool found = false;
798         switch(addr & 0x7f) {
799         case 0x00:
800                 if(d_vram != NULL) {
801                         d_vram->write_io8(FMTOWNS_VRAM_IO_CURSOR, data);
802                         found = true;
803                 }
804                 break;
805         case 0x01:
806                 if(d_vram != NULL) {
807                         d_vram->write_io8(FMTOWNS_VRAM_IO_FMR_RAMSELECT, data);
808                         found = true;
809                 }
810                 break;
811         case 0x02:
812                 if(d_vram != NULL) {
813                         d_vram->write_io8(FMTOWNS_VRAM_IO_FMR_DISPMODE, data);
814                         found = true;
815                 }
816                 break;
817         case 0x03:
818                 if(d_vram != NULL) {
819                         d_vram->write_io8(FMTOWNS_VRAM_IO_FMR_PAGESEL, data);
820                         found = true;
821                 }
822                 break;
823         case 0x04:
824                 found = true;
825                 break;
826         case 0x06:
827                 found = true;
828                 break;
829         case 0x14:
830         case 0x15:
831         case 0x16:
832         case 0x17:
833                 if(d_vram != NULL) {
834                         d_vram->write_io8(FMTOWNS_VRAM_KANJICG + (addr & 3), data);
835                         found = true;
836                 }
837                 break;
838         case 0x18:
839                 if(d_beep != NULL) {
840                         d_beep->write_signal(SIG_BEEP_ON, 0, 1);
841                         found = true;
842                 }
843                 break;
844         case 0x19:
845             ankcg_enabled = ((data & 1) == 0);
846                 found = true;
847                 break;
848         case 0x20:
849                 found = true;
850                 break;
851         default:
852                 break;
853         }
854         if(hit != NULL) *hit = found;
855         return;
856 }
857
858 void TOWNS_MEMORY::initialize_tables(void)
859 {
860         // Address Cx000000
861         memset(write_bank_adrs_cx, 0x00, sizeof(write_bank_adrs_cx));
862         memset(read_bank_adrs_cx, 0x00, sizeof(read_bank_adrs_cx));
863         memset(device_bank_adrs_cx, 0x00, sizeof(device_bank_adrs_cx));
864         memset(type_bank_adrs_cx, 0x00, sizeof(type_bank_adrs_cx));
865
866         // PAGE0
867         for(uint32_t ui = 0x00000; ui < 0x000c0; ui++) {  // $00000000 - $000bffff
868                 read_bank_adrs_cx[ui] = &(ram_page0[ui << 12]);
869                 write_bank_adrs_cx[ui] = &(ram_page0[ui << 12]);
870         }
871         
872         for(uint32_t ui = 0x000c0; ui < 0x000c8; ui++) { // $000c0000 - $000effff
873                         type_bank_adrs_cx[ui] = (TOWNS_MEMORY_FMR_VRAM << 24) | ((ui - 0xc0) << 12);    
874         }
875         for(uint32_t ui = 0x000c8; ui < 0x000c9; ui++) { // $000c0000 - $000effff
876                         type_bank_adrs_cx[ui] = (TOWNS_MEMORY_FMR_TEXT << 24) | ((ui - 0xc8) << 12);    
877         }
878         for(uint32_t ui = 0x000c9; ui < 0x000ca; ui++) { // $000c0000 - $000effff
879                         type_bank_adrs_cx[ui] = (TOWNS_MEMORY_FMR_VRAM_RESERVE << 24) | ((ui - 0xc8) << 12);    
880         }
881         for(uint32_t ui = 0x000ca; ui < 0x000cb; ui++) { // $000c0000 - $000effff
882                         type_bank_adrs_cx[ui] = (TOWNS_MEMORY_SPRITE_ANKCG1 << 24) | ((ui - 0xca) << 12);       
883         }
884         for(uint32_t ui = 0x000cb; ui < 0x000cc; ui++) { // $000c0000 - $000effff
885                         type_bank_adrs_cx[ui] = (TOWNS_MEMORY_ANKCG2 << 24) | ((ui - 0xcb) << 12);      
886         }
887         for(uint32_t ui = 0x000cc; ui < 0x000d0; ui++) { // $000c0000 - $000effff
888                         type_bank_adrs_cx[ui] = (TOWNS_MEMORY_MMIO_0CC << 24) | ((ui - 0xcc) << 12);    
889         }
890         for(uint32_t ui = 0x000d0; ui < 0x000f0; ui++) { // $000c0000 - $000effff
891                 device_bank_adrs_cx[ui] = d_dictionary;
892         }
893         for(uint32_t ui = 0x000f0; ui < 0x00100; ui++) { // $000f0000 - $000fffff
894                 device_bank_adrs_cx[ui] = d_sysrom;
895         }
896         // Extra RAM
897         for(uint32_t ui = 0x00100; ui < (0x00100 + (extram_size >> 12)); ui++) {
898                 read_bank_adrs_cx[ui] = &(extram[(ui - 0x100)  << 12]);
899                 write_bank_adrs_cx[ui] = &(extram[(ui - 0x100) << 12]);
900         }
901         // ToDo: EXTRA IO(0x40000000 - 0x80000000)
902         
903         // VRAM
904         /*
905         for(uint32_t ui = 0x000c0; ui < 0x000ca; ui++) {
906                 device_bank_adrs_cx[ui] = d_vram;
907         }
908         for(uint32_t ui = 0x000ca; ui < 0x000cb; ui++) {
909                 device_bank_adrs_cx[ui] = d_sprite;
910         }
911         */
912         for(uint32_t ui = 0x80000; ui < (0x80000 + (vram_size >> 12)); ui++) {
913                 device_bank_adrs_cx[ui] = d_vram;
914         }
915         for(uint32_t ui = 0x80100; ui < (0x80100 + (vram_size >> 12)); ui++) {
916                 device_bank_adrs_cx[ui] = d_vram;
917         }
918         for(uint32_t ui = 0x81000; ui < 0x81020; ui++) {
919                 device_bank_adrs_cx[ui] = d_sprite;
920         }
921
922         // ROM CARD
923         for(uint32_t ui = 0xc0000; ui < 0xc1000; ui++) {
924                 device_bank_adrs_cx[ui] = d_romcard[0];
925         }
926         // ROM CARD2
927         for(uint32_t ui = 0xc1000; ui < 0xc2000; ui++) {
928                 device_bank_adrs_cx[ui] = d_romcard[1];
929         }
930         for(uint32_t ui = 0xc2140; ui < 0xc2142; ui++) { 
931                 device_bank_adrs_cx[ui] = d_dictionary;
932         }
933         for(uint32_t ui = 0xc2200; ui < 0xc2201; ui++) { 
934                 device_bank_adrs_cx[ui] = d_pcm;
935         }
936         // ROMs
937         for(uint32_t ui = 0xc2000; ui < 0xc2080; ui++) {
938                 device_bank_adrs_cx[ui] = d_msdos;
939         }
940         for(uint32_t ui = 0xc2080; ui < 0xc2100; ui++) {
941                 device_bank_adrs_cx[ui] = d_dictionary;
942         }
943         for(uint32_t ui = 0xc2100; ui < 0xc2140; ui++) {
944                 device_bank_adrs_cx[ui] = d_fonts;
945         }
946         for(uint32_t ui = 0xc2180; ui < 0xc2200; ui++) { // 20pixs fonts.
947                 device_bank_adrs_cx[ui] = d_fonts;
948         }
949
950         // SYSTEM CODE ROM
951         for(uint32_t ui = 0xfffc0; ui < 0x100000; ui++) { 
952                 device_bank_adrs_cx[ui] = d_sysrom;
953         }
954 }
955
956
957 uint32_t TOWNS_MEMORY::read_data8(uint32_t addr)
958 {
959         int wait;
960         return read_data8w(addr, &wait);
961 }
962
963 uint32_t TOWNS_MEMORY::read_data16(uint32_t addr)
964 {
965         int wait;
966         return read_data16w(addr, &wait);
967 }
968
969 uint32_t TOWNS_MEMORY::read_data32(uint32_t addr)
970 {
971         int wait;
972         return read_data32w(addr, &wait);
973 }
974
975 void TOWNS_MEMORY::write_dma_data8(uint32_t addr, uint32_t data)
976 {
977         int wait;
978         write_data8w(addr & dma_addr_mask, data, &wait);
979 }
980
981 uint32_t TOWNS_MEMORY::read_dma_data8(uint32_t addr)
982 {
983         int wait;
984         return read_data8w(addr & dma_addr_mask, &wait);
985 }
986 void TOWNS_MEMORY::write_dma_data16(uint32_t addr, uint32_t data)
987 {
988         int wait;
989         write_data16w(addr & dma_addr_mask, data, &wait);
990 }
991
992 uint32_t TOWNS_MEMORY::read_dma_data16(uint32_t addr)
993 {
994         int wait;
995         return read_data16w(addr & dma_addr_mask, &wait);
996 }
997
998
999 void TOWNS_MEMORY::write_signal(int ch, uint32_t data, uint32_t mask)
1000 {
1001         if(ch == SIG_MEMORY_EXTNMI) {
1002                 extra_nmi_val = ((data & mask) != 0);
1003         } else if(ch == SIG_CPU_NMI) {
1004                 // Check protect
1005                 d_cpu->write_signal(SIG_CPU_NMI, data, mask);
1006         } else if(ch == SIG_CPU_IRQ) {
1007                 d_cpu->write_signal(SIG_CPU_IRQ, data, mask);
1008         } else if(ch == SIG_CPU_BUSREQ) {
1009                 d_cpu->write_signal(SIG_CPU_BUSREQ, data, mask);
1010         } else if(ch == SIG_I386_A20) {
1011                 d_cpu->write_signal(SIG_I386_A20, data, mask);
1012         } else if(ch == SIG_FMTOWNS_SET_MEMWAIT) {
1013                 mem_wait_val = (int)data;
1014                 d_sysrom->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1015                 d_dictionary->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1016                 d_msdos->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1017                 d_fonts->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1018         } else if(ch == SIG_FMTOWNS_SET_VRAMWAIT) {
1019                 vram_wait_val = (int)data;
1020                 d_vram->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1021         }
1022 }
1023
1024 uint32_t TOWNS_MEMORY::read_signal(int ch)
1025 {
1026         if(ch == SIG_FMTOWNS_MACHINE_ID) {
1027                 uint16_t d = (machine_id & 0xfff8) | ((uint16_t)(cpu_id & 0x07));
1028                 return (uint32_t)d;
1029         } else if(ch == SIG_FMTOWNS_SET_MEMWAIT) {
1030                 return (uint32_t)mem_wait_val;
1031         } else if(ch == SIG_FMTOWNS_SET_VRAMWAIT) {
1032                 return (uint32_t)vram_wait_val;
1033         } 
1034         return 0;
1035 }
1036 // ToDo: DMA
1037
1038 #define STATE_VERSION   1
1039
1040 bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading)
1041 {
1042         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1043                 return false;
1044         }
1045         if(!state_fio->StateCheckInt32(this_device_id)) {
1046                 return false;
1047         }
1048         state_fio->StateValue(bankc0_vram);
1049         state_fio->StateValue(ankcg_enabled);
1050         state_fio->StateValue(machine_id);
1051         state_fio->StateValue(cpu_id);
1052
1053         state_fio->StateValue(dma_addr_mask);
1054         //state_fio->StateValue(dma_addr_reg);
1055         //state_fio->StateValue(dma_wrap_reg);
1056         
1057         state_fio->StateArray(ram_page0, sizeof(ram_page0), 1);
1058         state_fio->StateArray(ram_0c0, sizeof(ram_0c0), 1);
1059         state_fio->StateArray(ram_0c8, sizeof(ram_0c8), 1);
1060         state_fio->StateArray(ram_0ca, sizeof(ram_0ca), 1);
1061         state_fio->StateArray(ram_0cb, sizeof(ram_0cb), 1);
1062         state_fio->StateArray(ram_0cc, sizeof(ram_0cc), 1);
1063         
1064
1065         if(loading) {
1066                 uint32_t length_tmp = state_fio->FgetUint32_LE();
1067                 if(extram != NULL) {
1068                         free(extram);
1069                         extram = NULL;
1070                 }
1071                 length_tmp = length_tmp & 0x3ff00000;
1072                 extram_size = length_tmp;
1073                 if(length_tmp > 0) {
1074                         extram = (uint8_t*)malloc(length_tmp);
1075                 }
1076                 if(extram == NULL) {
1077                         extram_size = 0;
1078                         return false;
1079                 } else {
1080                         state_fio->Fread(extram, extram_size, 1);
1081                 }
1082         } else {
1083                 if(extram == NULL) {
1084                         state_fio->FputUint32_LE(0);
1085                 } else {
1086                         state_fio->FputUint32_LE(extram_size & 0x3ff00000);
1087                         state_fio->Fwrite(extram, extram_size, 1);
1088                 }
1089         }
1090                         
1091         state_fio->StateValue(vram_wait_val);
1092         state_fio->StateValue(mem_wait_val);
1093         state_fio->StateValue(vram_size);
1094
1095         // ToDo: Do save ROMs?
1096
1097         if(loading) {
1098                 initialize_tables();
1099         }
1100         return true;
1101 }
1102
1103 }