OSDN Git Service

[VM][FMTOWNS][MEMORY][DONOTBUILD] Re-Implementing memory faster.DON't build.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 27 Aug 2023 17:17:32 +0000 (02:17 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 27 Aug 2023 17:17:32 +0000 (02:17 +0900)
- This is work-in-progress. DO NOT BUILD.
- This expects to fix some issues of CDROM booting, i.e) DOUKYUSEI 1.
- Reduce usage of memory mapping table.
- Change inherits from MEMORY:: to DEVICE:: .
- Now modifying read_dataFOO() and write_dataFOO(). Still be
  imcompletely.
- Will change around banking.
- Will re-implent around bank detection.
- Will re-implement config around page 000C0000h .

source/src/vm/fmtowns/towns_memory.cpp
source/src/vm/fmtowns/towns_memory.h

index 44fbc4c..f1e10d6 100644 (file)
 namespace FMTOWNS {
 
 // Note: Bank width will be 0x2000 bytes.
+void TOWNS_MEMORY::set_device_range_r(DEVICE* dev, uint32_t begin_addr, uint32_t end_addr)
+{
+       if(begin_addr >= 0xc40000000) return;
+       if(begin_addr < 0xc0000000) {
+               if(begin_addr >= 0x80000000) {
+                       if(begin_addr < 0x84000000) {
+                               if(end_addr >= 0x84000000) {
+                                       end_addr = 0x84000000;
+                               }
+                               for(uint32_t addr = begin_addr, uint32_t i = 0; addr < end_addr; addr += 0x00020000, i++) {
+                                       devmap_80000000h[i] = dev;
+                                       //offsetmap_80000000h[i] = addr - begin_addr;
+                               }
+                               return;
+                       }
+                       return;
+               } else if(begin_addr < 0x000f0000) {
+                       if(begin_addr >= 0x000c0000) {
+                               if(end_addr >= 0x000f0000) {
+                                       end_addr = 0x000f0000;
+                               }
+                               for(uint32_t addr = begin_addr, uint32_t i = 0; addr < end_addr; addr += 0x00001000, i++) {
+                                       devmap_c0000h_read[i] = dev;
+                                       //offsetmap_c0000h_read[i] = addr - begin_addr;
+                               }
+                               return;
+                       }
+               }
+               return;
+       }
+       // C0000000h - C3ffffffh
+       if(end_addr >= 0xc4000000) {
+               end_addr = 0xc4000000;
+       }
+       for(uint32_t addr = begin_addr, uint32_t i = 0; addr < end_addr; addr += 0x00001000, i++) {
+               devmap_c0000000h_read[i] = dev;
+               //offsetmap_c0000000h_read[i] = addr - begin_addr;
+       }
+}
+
+void TOWNS_MEMORY::set_device_range_w(DEVICE* dev, uint32_t begin_addr, uint32_t end_addr)
+{
+       if(begin_addr >= 0xc40000000) return;
+       if(begin_addr < 0xc0000000) {
+               if(begin_addr >= 0x80000000) {
+                       if(begin_addr < 0x84000000) {
+                               if(end_addr >= 0x84000000) {
+                                       end_addr = 0x84000000;
+                               }
+                               for(uint32_t addr = begin_addr, uint32_t i = 0; addr < end_addr; addr += 0x00020000, i++) {
+                                       devmap_80000000h[i] = dev;
+                                       //offsetmap_80000000h[i] = addr - begin_addr;
+                               }
+                               return;
+                       }
+                       return;
+               } else if(begin_addr < 0x000f0000) {
+                       if(begin_addr >= 0x000c0000) {
+                               if(end_addr >= 0x000f0000) {
+                                       end_addr = 0x000f0000;
+                               }
+                               for(uint32_t addr = begin_addr, uint32_t i = 0; addr < end_addr; addr += 0x00001000, i++) {
+                                       devmap_c0000h_write[i] = dev;
+                                       //offsetmap_c0000h_write[i] = addr - begin_addr;
+                               }
+                               return;
+                       }
+               }
+               return;
+       }
+       // C0000000h - C3ffffffh
+       if(end_addr >= 0xc4000000) {
+               end_addr = 0xc4000000;
+       }
+       for(uint32_t addr = begin_addr, uint32_t i = 0; addr < end_addr; addr += 0x00001000, i++) {
+               devmap_c0000000h_write[i] = dev;
+               //offsetmap_c0000000h_write[i] = addr - begin_addr;
+       }
+}
+
+
 void TOWNS_MEMORY::config_page_c0()
 {
        if(dma_is_vram) {
@@ -82,7 +163,7 @@ void TOWNS_MEMORY::config_page_f8_rom()
                set_memory_mapped_io_r (0x000f8000, 0x000fffff, d_sysrom);
                unset_memory_w         (0x000f8000, 0x000fffff);
        } else {
-               set_memory_rw          (0x000f8000, 0x000fffff, &(ram_pagef[0x8000]));
+               set_memory_rw          (0x000f8000, 0x000fffff, &(ram_paged[0x28000]));
        }
 }
 
@@ -133,7 +214,6 @@ void TOWNS_MEMORY::initialize()
        memset(ram_page0, 0x00, sizeof(ram_page0));
        memset(ram_pagec, 0x00, sizeof(ram_pagec));
        memset(ram_paged, 0x00, sizeof(ram_paged));
-       memset(ram_pagef, 0x00, sizeof(ram_pagef));
 
        select_d0_dict = false;
        select_d0_rom = true;
@@ -143,7 +223,7 @@ void TOWNS_MEMORY::initialize()
 
        // Lower 100000h
        set_memory_rw          (0x00000000, 0x000bffff, ram_page0);
-       set_memory_rw          (0x000f0000, 0x000f7fff, ram_pagef);
+       set_memory_rw          (0x000f0000, 0x000f7fff, &(ram_paged[0x20000]));
        config_page00();
 
        set_memory_mapped_io_rw(0x80000000, 0x8007ffff, d_vram);
@@ -835,6 +915,251 @@ void TOWNS_MEMORY::write_io8w(uint32_t addr, uint32_t data, int *wait)
        return;
 }
 
+uint32_t TOWNS_MEMORY::read_data8w(uint32_t addr, int* wait)
+{
+       int waitval;
+       bool is_exists;
+       uintptr_t memptr;
+       uint32_t offset;
+
+       DEVICE* dev = select_bank_memory_mpu(addr, false, true, is_exists, memptr, offset, waitval);
+
+       __UNLIKELY_IF(!(is_exists)) {
+               __LIKELY_IF(wait != NULL) {
+                       *wait = mem_wait_val;
+               }
+               return 0xff;
+       }
+       __LIKELY_IF(dev == NULL) {
+               __LIKELY_IF(wait != NULL) {
+                       *wait = mem_wait_val;
+               }
+               __LIKELY_IF(memptr != UINTPTR_MAX) {
+                       uint8_t* p = (uint8_t*)memptr;
+                       return memptr[offset];
+               }
+               return 0xff; // OK?
+       } else { // DEVICE
+               __LIKELY_IF(wait != NULL) {
+                       *wait = waitval;
+               }
+               __LIKELY_IF(offset == UINT32_MAX) {
+                       // THROUGH ADDRESS
+                       return dev->read_memory_mapped_io8(addr);
+               } else {
+                       return dev->read_memory_mapped_io8(offset);
+               }
+       }
+       return 0xff;
+}
+
+uint32_t TOWNS_MEMORY::read_data16w(uint32_t addr, int* wait)
+{
+       int waitval;
+       bool is_exists;
+       uintptr_t memptr;
+       uint32_t offset;
+
+       int waitval2;
+       bool is_exists2;
+       uintptr_t memptr2;
+       uint32_t offset2;
+
+       DEVICE* dev = select_bank_memory_mpu(addr, false, true, is_exists, memptr, offset, waitval);
+       DEVICE* dev2 = select_bank_memory_mpu(((addr & 0x0ffe) + 1) + (addr & 0xfffff000)), false, true, is_exists2, memptr2, offset2, waitval2);
+
+       __UNLIKELY_IF(!(is_exists) && !(is_exists2)) {
+               __LIKELY_IF(wait != NULL) {
+                       *wait = mem_wait_val;
+               }
+               return 0xffff;
+       }
+       // ToDO: Implement correctness.
+       __LIKELY_IF(dev == NULL) {
+               __LIKELY_IF(wait != NULL) {
+                       *wait = mem_wait_val;
+               }
+               bool is_boundary = ((addr & 0x7fff) == 0x7fff) ? true : false;
+               __UNLIKELY_IF(addr == 0x000cff7f) {
+                       is_boundary = true;
+               }
+               __LIKELY_IF(memptr != UINTPTR_MAX) {
+                       uint8_t* p = (uint8_t*)memptr;
+                       pair16_t nd;
+                       __LIKELY_IF(!(is_boundary)) {
+                               nd.read_2bytes_le_from(p);
+                       } else {
+                               nd.b.l = p[0];
+                               int waitval2;
+                               DEVICE* dev2 = select_bank_memory_mpu(addr + 1, false, true, is_exists, memptr, offset, waitval2);
+                               __LIKELY_IF(dev2 == NULL) {
+                                       // UNCHANGED WAIT
+                                       nd.b.h = p[1];
+                               } else {
+                                       __LIKELY_IF(offset == UINT32_MAX) {
+                                               nd.b.h = dev2->read_memory_mapped_io8(addr + 1);
+                                       } else {
+                                               nd.b.h = dev2->read_memory_mapped_io8(offset);
+                                       }
+                                       __LIKELY_IF(wait != NULL) {
+                                               *wait += waitval2;
+                                       }
+                               }
+                       }
+                       return nd.w;
+               }
+               return 0xffff; // OK?
+       } else { // DEVICE
+               __LIKELY_IF(wait != NULL) {
+                       *wait = waitval;
+               }
+               __LIKELY_IF(offset == UINT32_MAX) {
+                       // THROUGH ADDRESS
+                       return dev->read_memory_mapped_io16(addr);
+               } else {
+                       return dev->read_memory_mapped_io16(offset);
+               }
+       }
+       return 0xffff;
+}
+
+uint32_t TOWNS_MEMORY::read_data32w(uint32_t addr, int* wait)
+{
+       int waitval;
+       bool is_exists;
+       uintptr_t memptr;
+       uint32_t offset;
+
+       int waitval2;
+       bool is_exists2;
+       uintptr_t memptr2;
+       uint32_t offset2;
+
+       pair32_t dat;
+
+       DEVICE* dev = select_bank_memory_mpu(addr, false, true, is_exists, memptr, offset, waitval);
+       DEVICE* dev2 = select_bank_memory_mpu(((addr & 0x0ffc) + 3) + (addr & 0xfffff000)), false, true, is_exists2, memptr2, offset2, waitval2);
+       if(!(is_exists) && !(is_exists2)) {
+               __LIKELY_IF(wait != NULL) {
+                       *wait = mem_wait_val;
+               }
+               return 0xffffffff; // OK?
+       }
+
+       dat.d = 0xffffffff; // OK?
+
+       uint32_t bytes1 = 4 - (addr & 3);
+       uint32_t bytes2 = 4 - bytes1;
+       uint32_t addr1 = (offset == UINT32_MAX) ? addr : offset;
+       uint32_t addr2 = (offset2 == UINT32_MAX) ? (addr + bytes1) : offset2;
+       __LIKELY_IF((dev == NULL) && (dev2 == NULL)) {
+               __LIKELY_IF((is_exists) && (memptr != UINTPTR_MAX)) {
+                       uint8_t *ptr1 = (uint8_t*)(memptr + (uintptr_t)((offset == UINT32_MAX) ? 0 : offset));
+                       dat.read_4bytes_le_from(p);
+               }
+               waitval = ((addr & 3) == 0) ? mem_wait_val : (mem_wait_val * 2); // OK?
+               __LIKELY_IF(wait != NULL) {
+                       *wait = waitval;
+               }
+               return dat.d;
+       }
+       __LIKELY_IF(dev != NULL) {
+               __LIKELY_IF(bytes1 > 1) {
+                       dat.w.l = dev->read_memory_mapped_io16(addr1);
+               }
+               __UNLIKELY_IF(bytes1 == 3) {
+                       dat.b.h = dev->read_memory_mapped_io8(addr1 + 2);
+               } else if(bytes1 > 3) {
+                       dat.w.h = dev->read_memory_mapped_io16(addr1 + 2);
+               } else if(bytes1 == 1) {
+                       dat.b.l = dev->read_memory_mapped_io8(addr1);
+               }
+               if((bytes1 & 3) != 0) {
+                       waitval = waitval * 2;
+               }
+       } else if(memptr != UINTPTR_MAX) {
+               uint8_t *ptr1 = (uint8_t*)(memptr + (uintptr_t)((offset == UINT32_MAX) ? 0 : offset));
+               switch(bytes1) {
+               case 0:
+                       break;
+               case 1:
+                       dat.b.l = ptr1[0];
+                       waitval = mem_wait_val * 2;
+                       break;
+               case 2:
+                       dat.b.l = ptr1[0];
+                       dat.b.h = ptr1[1];
+                       waitval = mem_wait_val * 2;
+                       break;
+               case 3:
+                       dat.b.l  = ptr1[0];
+                       dat.b.h  = ptr1[1];
+                       dat.b.h2 = ptr1[2];
+                       waitval = mem_wait_val * 2;
+                       break;
+               default:
+                       dat.read_4bytes_le_from(ptr1);
+                       waitval = mem_wait_val;
+                       break;
+               }
+       }
+       __LIKELY_IF(dev2 != NULL) {
+               switch(bytes2) {
+               case 0:
+                       break;
+               case 1:
+                       dat.b.h3 = dev2->read_memory_mapped_io8(addr2);
+                       waitval += waitval2
+                       break;
+               case 2:
+                       dat.w.h = dev2->read_memory_mapped_io16(addr2);
+                       waitval += waitval2
+                       break;
+               case 3:
+                       w.w = dev2->read_memory_mapped_io16(addr2);
+                       dat.b.h  = w.b.l;
+                       dat.b.h2 = w.b.h;
+                       dat.b.h3 = dev2->read_memory_mapped_io8(addr2);
+                       waitval += waitval2
+                       break;
+               default:
+                       dat.d = dev2->read_memory_mapped_io32(addr2);
+                       waitval = waitval2;
+                       break;
+               }
+       } else if(memptr2 != UINTPTR_MAX) {
+               uint8_t *ptr2 = (uint8_t*)(memptr2 + (uintptr_t)((offset2 == UINT32_MAX) ? 0 : offset2));
+               switch(bytes2) {
+               case 0:
+                       break;
+               case 1:
+                       dat.b.h3 = ptr2[0];
+                       waitval = waitval + mem_wait_val;
+                       break;
+               case 2:
+                       dat.b.h2 = ptr2[0];
+                       dat.b.h3 = ptr2[1];
+                       waitval = waitval + mem_wait_val;
+                       break;
+               case 3:
+                       dat.b.h  = ptr2[0];
+                       dat.b.h2 = ptr2[1];
+                       dat.b.h3 = ptr2[2];
+                       waitval = waitval + mem_wait_val;
+                       break;
+               default:
+                       dat.read_4bytes_le_from(ptr2);
+                       waitval = mem_wait_val;
+                       break;
+               }
+       }
+       __LIKELY_IF(wait != NULL) {
+               *wait = waitval;
+       }
+       return dat.d;
+}
+
+
 uint32_t TOWNS_MEMORY::read_memory_mapped_io8(uint32_t addr)
 {
        int wait = 0;
@@ -1066,7 +1391,6 @@ bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateArray(ram_page0,  sizeof(ram_page0), 1);
        state_fio->StateArray(ram_pagec,  sizeof(ram_pagec), 1);
        state_fio->StateArray(ram_paged,  sizeof(ram_paged), 1);
-       state_fio->StateArray(ram_pagef,  sizeof(ram_pagef), 1);
 
        state_fio->StateValue(select_d0_rom);
        state_fio->StateValue(select_d0_dict);
index 6e1d895..54cf2ce 100644 (file)
@@ -57,12 +57,11 @@ namespace FMTOWNS {
 }
 
 namespace FMTOWNS {
-class TOWNS_MEMORY : public MEMORY
+class TOWNS_MEMORY : public DEVICE
 {
 protected:
        DEVICE* d_vram;
        DEVICE* d_sprite;       // 0x81000000 - 0x8101ffff ?
-       DEVICE* d_romcard[2]; // 0xc0000000 - 0xc0ffffff / 0xc1000000 - 0xc1ffffff
        DEVICE* d_pcm;             // 0xc2200000 - 0xc2200fff
        DEVICE* d_timer;
        DEVICE* d_dmac;
@@ -79,7 +78,102 @@ protected:
 
        DEVICE* d_iccard[2];
 
-       outputs_t outputs_ram_wait;
+       // Add memory MAP
+       DEVICE*  devmap_c0000h_read[0x00030000 >> 12]; // Per 1000h bytes
+       uint32_t offsetmap_c0000h_read[0x00030000 >> 12];
+       DEVICE*  devmap_c0000h_write[0x00030000 >> 12]; // Per 1000h bytes
+       uint32_t offsetmap_c0000h_write[0x00030000 >> 12];
+
+       DEVICE*  devmap_80000000h[0x04000000 >> 17];
+       uint32_t offsetmap_80000000h[0x04000000 >> 17];
+
+       DEVICE*  devmap_c0000000h_read[0x04000000 >> 12];
+       uint32_t offsetmap_c0000000h_read[0x04000000 >> 12];
+       DEVICE*  devmap_c0000000h_write[0x04000000 >> 12];
+       uint32_t offsetmap_c0000000h_write[0x04000000 >> 12];
+
+       virtual inline __FASTCALL DEVICE* select_bank_memory_mpu(uint32_t addr, constexpr bool is_dma, constexpr bool is_read, bool& is_exists, uintptr_t& memptr, uint32_t& offset, int& waitval)
+       {
+               memptr = UINTPTR_MAX;
+               offset = UINT32_MAX;
+               waitval = mem_wait_val;
+               is_exists = false;
+               __LIKELY_IF(addr < (extram_size + 0x00100000)) {
+                       __LIKELY_IF(addr >= 0x00100000) { // Extra RAM
+                               is_exists = (extra_ram != NULL) ? true : false;
+                               offset = addr - 0x00100000;
+                               memptr = (uintptr_t)extra_ram;
+                               return NULL;
+                       }
+                       __LIKELY_IF(addr < 0x000c0000) { // 1st RAM
+                               is_exists = true;
+                               offset = addr;
+                               memptr = (uintptr_t)ram_page0;
+                               return NULL;
+                       }
+                       __LIKELY_IF((dma_is_vram) && (addr < 0x000f0000)) {
+                               uint32_t map_ptr = (addr - 0x000c0000) >> 12; // Per 4KBytes
+                               DEVICE* p = (is_read) ? devmap_c0000h_read[map_ptr] : devmap_c0000h_write[map_ptr];
+                               __LIKELY_IF(p != NULL) {
+                                       is_exists = true;
+                                       offset = (is_read) ? offsetmap_c0000h_read[map_ptr] : offsetmap_c0000h_write[map_ptr];
+                                       __UNLIKELY_IF(addr < 0x000d0000) {
+                                               waitval = vram_wait_val;
+                                       }
+                               }
+                               return p;
+                       }
+                       __UNLIKELY_IF((addr >= 0x000cff80) && (addr < 0x000d0000)) { // MMIO
+                               is_exists = true;
+                               return this;
+                       }
+                       // 0x000f8000 - 0x000fffff
+                       __LIKELY_IF((select_d0_rom) && (addr >= 0x000f8000)) {
+                               is_exists = (is_read) ? true : false;
+                               offset = (addr - 0x000f8000) + 0x38000;
+                               return (is_read) ? d_sysrom : NULL;
+                       }
+                       is_exists = true;
+                       offset = addr - 0x0000c0000;
+                       memptr = (uintptr_t)ram_pagec;
+                       return NULL;
+               }
+               __LIKELY_IF(addr >= 0x80000000) {
+                       __LIKELY_IF(addr >= 0xfffc0000) { // SYSROM
+                               is_exists = true;
+                               offset = addr - 0xfffc0000;
+                               return d_sysrom;
+                       }
+                       __LIKELY_IF(addr < 0x84000000) { // VRAM
+                               uint32_t map_ptr = (addr - 0x80000000) >> 17; // Per 128KBytes
+                               DEVICE* p = devmap_80000000h[map_ptr];
+                               waitval = vram_wait_val; // ToDo.
+                               __LIKELY_IF(p != NULL) {
+                                       offset = offsetmap_80000000h[map_ptr];
+                                       is_exists = true;
+                               }
+                               return p;
+                       }
+                       __LIKELY_IF(addr >= 0xc0000000) {
+                               __LIKELY_IF(addr < 0xc2400000) { // MISC DEVICES
+                                       uint32_t map_ptr = (addr - 0xc0000000) >> 12; // Per 4KBytes
+                                       DEVICE* p = (is_read) ? devmap_c0000000h_read[map_ptr] : devmap_c0000000h_write[map_ptr];
+                                       __LIKELY_IF(p != NULL) {
+                                               offset = (is_read) ? offsetmap_c0000000h_read[map_ptr] : offsetmap_c0000000h_write[map_ptr];
+                                               is_exists = true;
+                                       }
+                                       return p;
+                               }
+                               return NULL;
+                       }
+                       return NULL;
+               }
+               // ToDo: I/O SLOTS (40000000h)
+               return NULL;
+       }
+       virtual void __FASTCALL set_device_range_r(DEVICE* dev, uint32_t begin_addr, uint32_t end_addr);
+       virtual void __FASTCALL set_device_range_w(DEVICE* dev, uint32_t begin_addr, uint32_t end_addr);
+       outputs_t outputs_ram_wait;
        outputs_t outputs_rom_wait;
 
        bool bankc0_vram;
@@ -94,9 +188,7 @@ protected:
 
        // RAM
        uint8_t ram_page0[0xc0000];       // 0x00000000 - 0x000bffff : RAM
-       uint8_t ram_pagec[0x10000];       // 0x000c0000 - 0x000cffff : URA? RAM
-       uint8_t ram_paged[0x20000];       // 0x000d0000 - 0x000effff : RAM
-       uint8_t ram_pagef[0x10000];       // 0x000f0000 - 0x000fffff : RAM
+       uint8_t ram_pagec[0x40000];       // 0x000c0000 - 0x000fffff : URA? RAM
 
        uint8_t *extra_ram;                  // 0x00100000 - (0x3fffffff) : Size is defined by extram_size;
        uint32_t extram_size;
@@ -149,7 +241,6 @@ public:
 
                d_vram = NULL;
                d_sprite = NULL;
-               d_romcard[0] = d_romcard[1] = NULL;
                d_pcm = NULL;
                d_timer = NULL;
                d_dmac = NULL;
@@ -168,6 +259,22 @@ public:
 
                initialize_output_signals(&outputs_ram_wait);
                initialize_output_signals(&outputs_rom_wait);
+               for(int i = 0; i < (sizeof(devmap_c0000h_read) / sizeof(DEVICE*)); i++) {
+                       devmap_c0000h_read[i] = NULL;
+                       devmap_c0000h_write[i] = NULL;
+                       offsetmap_c0000h_read[i] = UINT32_MAX;
+                       offsetmap_c0000h_write[i] = UINT32_MAX;
+               }
+               for(int i = 0; i < (sizeof(devmap_80000000h) / sizeof(DEVICE*)); i++) {
+                       devmap_80000000h[i] = NULL;
+                       offsetmap_80000000h[i] = UINT32_MAX;
+               }
+               for(int i = 0; i < (sizeof(devmap_c0000000h_read) / sizeof(DEVICE*)); i++) {
+                       devmap_c0000000h_read[i] = NULL;
+                       devmap_c00000000h_write[i] = NULL;
+                       offsetmap_c00000000h_read[i] = UINT32_MAX;
+                       offsetmap_c00000000h_write[i] = UINT32_MAX;
+               }
                // Note: machine id must set before initialize() from set_context_machine_id() by VM::VM().
                // machine_id = 0x0100;   // FM-Towns 1,2
                // machine_id = 0x0200 // FM-Towns  1F/2F/1H/2H
@@ -265,9 +372,10 @@ public:
        {
                d_dmac = device;
        }
-       void set_context_vram(DEVICE* device)
+       virtual void set_context_vram(DEVICE* device)
        {
                d_vram = device;
+
        }
        void set_context_system_rom(DEVICE* device)
        {
@@ -276,18 +384,25 @@ public:
        void set_context_font_rom(DEVICE* device)
        {
                d_font = device;
+               set_device_range_r(device, 0xc2100000, 0xc2140000);
        }
        void set_context_font_20pix_rom(DEVICE* device)
        {
                d_font_20pix = device;
+               set_device_range_r(device, 0xc2180000, 0xc2200000);
        }
        void set_context_dictionary(DEVICE* device)
        {
                d_dictionary = device;
+               set_device_range_r(device, 0xc2080000, 0xc2100000);
+               set_device_range_r(device, 0xc2140000, 0xc2142000);
+               // CMOS
+               set_device_range_w(device, 0xc2140000, 0xc2142000);
        }
        void set_context_msdos(DEVICE* device)
        {
                d_msdos = device;
+               set_device_range_r(device, 0xc2000000, 0xc2080000);
        }
        void set_context_timer(DEVICE* device)
        {
@@ -296,18 +411,25 @@ public:
        void set_context_sprite(DEVICE* device)
        {
                d_sprite = device;
+               set_device_range_r(device, 0x81000000, 0x81020000);
+               set_device_range_w(device, 0x81000000, 0x81020000);
        }
        void set_context_crtc(DEVICE* device)
        {
                d_crtc = device;
        }
-       void set_context_romcard(DEVICE* device, int num)
+       void set_context_iccard(DEVICE* device, int num)
        {
-               d_romcard[num & 1] = device;
+               d_iccard[num & 1] = device;
+               uint32_t begin_addr = ((num & 1) == 0) ? 0xc0000000 : 0xc1000000;
+               set_device_range_r(device, begin_addr, begin_addr + 0x01000000);
+               set_device_range_w(device, begin_addr, begin_addr + 0x01000000);
        }
        void set_context_pcm(DEVICE* device)
        {
                d_pcm = device;
+               set_device_range_r(device, 0xc2200000, 0xc2200fff);
+               set_device_range_w(device, 0xc2200000, 0xc2200fff);
        }
        void set_context_serial_rom(DEVICE* device)
        {
@@ -317,12 +439,6 @@ public:
        {
                d_planevram = dev;
        }
-       void set_context_iccard(DEVICE* device, int num)
-       {
-               if((num >= 0) && (num < 2)) {
-                       d_iccard[num] = device;
-               }
-       }
        void set_machine_id(uint16_t val)
        {
                machine_id = val & 0xfff8;