OSDN Git Service

[VM][STATE][WIP] Apply process_state() to some devices.
[csp-qt/common_source_project-fm7.git] / source / src / vm / memory.cpp
index 1d08401..d01e1a8 100644 (file)
@@ -9,23 +9,56 @@
 
 #include "memory.h"
 
-#define ADDR_MASK (MEMORY_ADDR_MAX - 1)
-#define BANK_MASK (MEMORY_BANK_SIZE - 1)
+#define ADDR_MASK (addr_max - 1)
+#define BANK_MASK (bank_size - 1)
+
+void MEMORY::initialize()
+{
+       // allocate tables here to support multiple instances with different address range
+       if(rd_table == NULL) {
+               int bank_num = addr_max / bank_size;
+               
+               rd_dummy = (uint8_t *)malloc(bank_size);
+               wr_dummy = (uint8_t *)malloc(bank_size);
+               
+               rd_table = (bank_t *)calloc(bank_num, sizeof(bank_t));
+               wr_table = (bank_t *)calloc(bank_num, sizeof(bank_t));
+               
+               for(int i = 0; i < bank_num; i++) {
+                       rd_table[i].dev = NULL;
+                       rd_table[i].memory = rd_dummy;
+                       rd_table[i].wait = 0;
+                       
+                       wr_table[i].dev = NULL;
+                       wr_table[i].memory = wr_dummy;
+                       rd_table[i].wait = 0;
+               }
+               for(int i = 0;; i++) {
+                       if(bank_size == (1 << i)) {
+                               addr_shift = i;
+                               break;
+                       }
+               }
+               memset(rd_dummy, 0xff, bank_size);
+       }
+}
 
 void MEMORY::release()
 {
-       free(read_table);
-       free(write_table);
+       free(rd_table);
+       free(wr_table);
+       free(rd_dummy);
+       free(wr_dummy);
 }
 
 uint32_t MEMORY::read_data8(uint32_t addr)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(read_table[bank].dev != NULL) {
-               return read_table[bank].dev->read_memory_mapped_io8(addr);
+       if(rd_table[bank].dev != NULL) {
+               return rd_table[bank].dev->read_memory_mapped_io8(addr);
        } else {
-               return read_table[bank].memory[addr & BANK_MASK];
+               return rd_table[bank].memory[addr & BANK_MASK];
        }
 }
 
@@ -33,10 +66,10 @@ void MEMORY::write_data8(uint32_t addr, uint32_t data)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(write_table[bank].dev != NULL) {
-               write_table[bank].dev->write_memory_mapped_io8(addr, data);
+       if(wr_table[bank].dev != NULL) {
+               wr_table[bank].dev->write_memory_mapped_io8(addr, data);
        } else {
-               write_table[bank].memory[addr & BANK_MASK] = data;
+               wr_table[bank].memory[addr & BANK_MASK] = data;
        }
 }
 
@@ -44,8 +77,8 @@ uint32_t MEMORY::read_data16(uint32_t addr)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(read_table[bank].dev != NULL) {
-               return read_table[bank].dev->read_memory_mapped_io16(addr);
+       if(rd_table[bank].dev != NULL) {
+               return rd_table[bank].dev->read_memory_mapped_io16(addr);
        } else {
                uint32_t val = read_data8(addr);
                val |= read_data8(addr + 1) << 8;
@@ -57,8 +90,8 @@ void MEMORY::write_data16(uint32_t addr, uint32_t data)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(write_table[bank].dev != NULL) {
-               write_table[bank].dev->write_memory_mapped_io16(addr, data);
+       if(wr_table[bank].dev != NULL) {
+               wr_table[bank].dev->write_memory_mapped_io16(addr, data);
        } else {
                write_data8(addr, data & 0xff);
                write_data8(addr + 1, (data >> 8) & 0xff);
@@ -69,8 +102,8 @@ uint32_t MEMORY::read_data32(uint32_t addr)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(read_table[bank].dev != NULL) {
-               return read_table[bank].dev->read_memory_mapped_io32(addr);
+       if(rd_table[bank].dev != NULL) {
+               return rd_table[bank].dev->read_memory_mapped_io32(addr);
        } else {
                uint32_t val = read_data16(addr);
                val |= read_data16(addr + 2) << 16;
@@ -82,8 +115,8 @@ void MEMORY::write_data32(uint32_t addr, uint32_t data)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(write_table[bank].dev != NULL) {
-               write_table[bank].dev->write_memory_mapped_io32(addr, data);
+       if(wr_table[bank].dev != NULL) {
+               wr_table[bank].dev->write_memory_mapped_io32(addr, data);
        } else {
                write_data16(addr, data & 0xffff);
                write_data16(addr + 2, (data >> 16) & 0xffff);
@@ -94,11 +127,11 @@ uint32_t MEMORY::read_data8w(uint32_t addr, int* wait)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       *wait = read_table[bank].wait;
-       if(read_table[bank].dev != NULL) {
-               return read_table[bank].dev->read_memory_mapped_io8(addr);
+       *wait = rd_table[bank].wait;
+       if(rd_table[bank].dev != NULL) {
+               return rd_table[bank].dev->read_memory_mapped_io8(addr);
        } else {
-               return read_table[bank].memory[addr & BANK_MASK];
+               return rd_table[bank].memory[addr & BANK_MASK];
        }
 }
 
@@ -106,11 +139,11 @@ void MEMORY::write_data8w(uint32_t addr, uint32_t data, int* wait)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       *wait = write_table[bank].wait;
-       if(write_table[bank].dev != NULL) {
-               write_table[bank].dev->write_memory_mapped_io8(addr, data);
+       *wait = wr_table[bank].wait;
+       if(wr_table[bank].dev != NULL) {
+               wr_table[bank].dev->write_memory_mapped_io8(addr, data);
        } else {
-               write_table[bank].memory[addr & BANK_MASK] = data;
+               wr_table[bank].memory[addr & BANK_MASK] = data;
        }
 }
 
@@ -153,11 +186,11 @@ uint32_t MEMORY::read_dma_data8(uint32_t addr)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(read_table[bank].dev != NULL) {
-//             return read_table[bank].dev->read_memory_mapped_io8(addr);
+       if(rd_table[bank].dev != NULL) {
+//             return rd_table[bank].dev->read_memory_mapped_io8(addr);
                return 0xff;
        } else {
-               return read_table[bank].memory[addr & BANK_MASK];
+               return rd_table[bank].memory[addr & BANK_MASK];
        }
 }
 
@@ -165,10 +198,10 @@ void MEMORY::write_dma_data8(uint32_t addr, uint32_t data)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(write_table[bank].dev != NULL) {
-//             write_table[bank].dev->write_memory_mapped_io8(addr, data);
+       if(wr_table[bank].dev != NULL) {
+//             wr_table[bank].dev->write_memory_mapped_io8(addr, data);
        } else {
-               write_table[bank].memory[addr & BANK_MASK] = data;
+               wr_table[bank].memory[addr & BANK_MASK] = data;
        }
 }
 
@@ -176,8 +209,8 @@ uint32_t MEMORY::read_dma_data16(uint32_t addr)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(read_table[bank].dev != NULL) {
-//             return read_table[bank].dev->read_memory_mapped_io16(addr);
+       if(rd_table[bank].dev != NULL) {
+//             return rd_table[bank].dev->read_memory_mapped_io16(addr);
                return 0xffff;
        } else {
                uint32_t val = read_dma_data8(addr);
@@ -190,8 +223,8 @@ void MEMORY::write_dma_data16(uint32_t addr, uint32_t data)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(write_table[bank].dev != NULL) {
-//             write_table[bank].dev->write_memory_mapped_io16(addr, data);
+       if(wr_table[bank].dev != NULL) {
+//             wr_table[bank].dev->write_memory_mapped_io16(addr, data);
        } else {
                write_dma_data8(addr, data & 0xff);
                write_dma_data8(addr + 1, (data >> 8) & 0xff);
@@ -202,8 +235,8 @@ uint32_t MEMORY::read_dma_data32(uint32_t addr)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(read_table[bank].dev != NULL) {
-//             return read_table[bank].dev->read_memory_mapped_io32(addr);
+       if(rd_table[bank].dev != NULL) {
+//             return rd_table[bank].dev->read_memory_mapped_io32(addr);
                return 0xffffffff;
        } else {
                uint32_t val = read_dma_data16(addr);
@@ -216,8 +249,8 @@ void MEMORY::write_dma_data32(uint32_t addr, uint32_t data)
 {
        int bank = (addr & ADDR_MASK) >> addr_shift;
        
-       if(write_table[bank].dev != NULL) {
-//             write_table[bank].dev->write_memory_mapped_io32(addr, data);
+       if(wr_table[bank].dev != NULL) {
+//             wr_table[bank].dev->write_memory_mapped_io32(addr, data);
        } else {
                write_dma_data16(addr, data & 0xffff);
                write_dma_data16(addr + 2, (data >> 16) & 0xffff);
@@ -229,85 +262,101 @@ void MEMORY::write_dma_data32(uint32_t addr, uint32_t data)
 
 void MEMORY::set_memory_r(uint32_t start, uint32_t end, uint8_t *memory)
 {
+       MEMORY::initialize(); // subclass may overload initialize()
+       
        uint32_t start_bank = start >> addr_shift;
        uint32_t end_bank = end >> addr_shift;
        
        for(uint32_t i = start_bank; i <= end_bank; i++) {
-               read_table[i].dev = NULL;
-               read_table[i].memory = memory + MEMORY_BANK_SIZE * (i - start_bank);
+               rd_table[i].dev = NULL;
+               rd_table[i].memory = memory + bank_size * (i - start_bank);
        }
 }
 
 void MEMORY::set_memory_w(uint32_t start, uint32_t end, uint8_t *memory)
 {
+       MEMORY::initialize();
+       
        uint32_t start_bank = start >> addr_shift;
        uint32_t end_bank = end >> addr_shift;
        
        for(uint32_t i = start_bank; i <= end_bank; i++) {
-               write_table[i].dev = NULL;
-               write_table[i].memory = memory + MEMORY_BANK_SIZE * (i - start_bank);
+               wr_table[i].dev = NULL;
+               wr_table[i].memory = memory + bank_size * (i - start_bank);
        }
 }
 
 void MEMORY::set_memory_mapped_io_r(uint32_t start, uint32_t end, DEVICE *device)
 {
+       MEMORY::initialize();
+       
        uint32_t start_bank = start >> addr_shift;
        uint32_t end_bank = end >> addr_shift;
        
        for(uint32_t i = start_bank; i <= end_bank; i++) {
-               read_table[i].dev = device;
+               rd_table[i].dev = device;
        }
 }
 
 void MEMORY::set_memory_mapped_io_w(uint32_t start, uint32_t end, DEVICE *device)
 {
+       MEMORY::initialize();
+       
        uint32_t start_bank = start >> addr_shift;
        uint32_t end_bank = end >> addr_shift;
        
        for(uint32_t i = start_bank; i <= end_bank; i++) {
-               write_table[i].dev = device;
+               wr_table[i].dev = device;
        }
 }
 
 void MEMORY::set_wait_r(uint32_t start, uint32_t end, int wait)
 {
+       MEMORY::initialize();
+       
        uint32_t start_bank = start >> addr_shift;
        uint32_t end_bank = end >> addr_shift;
        
        for(uint32_t i = start_bank; i <= end_bank; i++) {
-               read_table[i].wait = wait;
+               rd_table[i].wait = wait;
        }
 }
 
 void MEMORY::set_wait_w(uint32_t start, uint32_t end, int wait)
 {
+       MEMORY::initialize();
+       
        uint32_t start_bank = start >> addr_shift;
        uint32_t end_bank = end >> addr_shift;
        
        for(uint32_t i = start_bank; i <= end_bank; i++) {
-               write_table[i].wait = wait;
+               wr_table[i].wait = wait;
        }
 }
 
 void MEMORY::unset_memory_r(uint32_t start, uint32_t end)
 {
+       MEMORY::initialize();
+       
        uint32_t start_bank = start >> addr_shift;
        uint32_t end_bank = end >> addr_shift;
        
        for(uint32_t i = start_bank; i <= end_bank; i++) {
-               read_table[i].dev = NULL;
-               read_table[i].memory = read_dummy;
+               rd_table[i].dev = NULL;
+               rd_table[i].memory = rd_dummy;
        }
 }
 
 void MEMORY::unset_memory_w(uint32_t start, uint32_t end)
 {
+       MEMORY::initialize();
+       
        uint32_t start_bank = start >> addr_shift;
        uint32_t end_bank = end >> addr_shift;
        
        for(uint32_t i = start_bank; i <= end_bank; i++) {
-               write_table[i].dev = NULL;
-               write_table[i].memory = write_dummy;
+               wr_table[i].dev = NULL;
+               wr_table[i].memory = wr_dummy;
        }
 }