void MEMORY::initialize()
{
+ DEVICE::initialize();
+ _MEMORY_DISABLE_DMA_MMIO = osd->check_feature(_T("MEMORY_DISABLE_DMA_MMIO"));
// allocate tables here to support multiple instances with different address range
if(rd_table == NULL) {
int64_t bank_num = addr_max / bank_size;
+ bank_mask = BANK_MASK;
+ addr_mask = ADDR_MASK;
rd_dummy = (uint8_t *)malloc(bank_size);
wr_dummy = (uint8_t *)malloc(bank_size);
rd_table[i].wait = 0;
}
for(int i = 0;; i++) {
- if(bank_size == (int64_t)(1 << i)) {
+ if(bank_size == (uint64_t)(1 << i)) {
addr_shift = i;
break;
}
if(rd_table[bank].dev != NULL) {
return rd_table[bank].dev->read_memory_mapped_io8(addr);
} else {
- return rd_table[bank].memory[addr & BANK_MASK];
+ return rd_table[bank].memory[addr & bank_mask];
}
}
if(wr_table[bank].dev != NULL) {
wr_table[bank].dev->write_memory_mapped_io8(addr, data);
} else {
- wr_table[bank].memory[addr & BANK_MASK] = data;
+ wr_table[bank].memory[addr & bank_mask] = data;
}
}
val |= read_data8(addr + 1) << 8;
return val;
} else {
- uint8_t* p = (uint8_t*)(&(rd_table[bank].memory[addr & BANK_MASK]));
+ uint8_t* p = (uint8_t*)(&(rd_table[bank].memory[addr & bank_mask]));
uint32_t val;
#if defined(__LITTLE_ENDIAN__)
uint16_t* pp = (uint16_t*)p;
write_data8(addr, data & 0xff);
write_data8(addr + 1, (data >> 8) & 0xff);
} else {
- uint8_t* p = (uint8_t*)(&(wr_table[bank].memory[addr & BANK_MASK]));
+ uint8_t* p = (uint8_t*)(&(wr_table[bank].memory[addr & bank_mask]));
#if defined(__LITTLE_ENDIAN__)
uint16_t* pp = (uint16_t*)p;
*pp = (uint16_t)data;
val |= read_data16(addr + 2) << 16;
return val;
} else {
- uint8_t* p = (uint8_t*)(&(rd_table[bank].memory[addr & BANK_MASK]));
+ uint8_t* p = (uint8_t*)(&(rd_table[bank].memory[addr & bank_mask]));
uint32_t val;
#if defined(__LITTLE_ENDIAN__)
uint32_t* pp = (uint32_t*)p;
write_data16(addr, data & 0xffff);
write_data16(addr + 2, (data >> 16) & 0xffff);
} else {
- uint8_t* p = (uint8_t*)(&(wr_table[bank].memory[addr & BANK_MASK]));
+ uint8_t* p = (uint8_t*)(&(wr_table[bank].memory[addr & bank_mask]));
#if defined(__LITTLE_ENDIAN__)
uint32_t* pp = (uint32_t*)p;
*pp = data;
if(rd_table[bank].dev != NULL) {
return rd_table[bank].dev->read_memory_mapped_io8(addr);
} else {
- return rd_table[bank].memory[addr & BANK_MASK];
+ return rd_table[bank].memory[addr & bank_mask];
}
}
if(wr_table[bank].dev != NULL) {
wr_table[bank].dev->write_memory_mapped_io8(addr, data);
} else {
- wr_table[bank].memory[addr & BANK_MASK] = data;
+ wr_table[bank].memory[addr & bank_mask] = data;
}
}
*wait = wait_l + wait_h;
}
-#ifdef MEMORY_DISABLE_DMA_MMIO
-
uint32_t MEMORY::read_dma_data8(uint32_t addr)
{
+ if(!(_MEMORY_DISABLE_DMA_MMIO)) {
+ return read_data8(addr);
+ }
int bank = (addr & ADDR_MASK) >> addr_shift;
if(rd_table[bank].dev != NULL) {
// return rd_table[bank].dev->read_memory_mapped_io8(addr);
return 0xff;
} else {
- return rd_table[bank].memory[addr & BANK_MASK];
+ return rd_table[bank].memory[addr & bank_mask];
}
}
void MEMORY::write_dma_data8(uint32_t addr, uint32_t data)
{
+ if(!(_MEMORY_DISABLE_DMA_MMIO)) {
+ write_data8(addr, data);
+ return;
+ }
int bank = (addr & ADDR_MASK) >> addr_shift;
if(wr_table[bank].dev != NULL) {
// wr_table[bank].dev->write_memory_mapped_io8(addr, data);
} else {
- wr_table[bank].memory[addr & BANK_MASK] = data;
+ wr_table[bank].memory[addr & bank_mask] = data;
}
}
uint32_t MEMORY::read_dma_data16(uint32_t addr)
{
+ if(!(_MEMORY_DISABLE_DMA_MMIO)) {
+ return read_data16(addr);
+ }
int bank = (addr & ADDR_MASK) >> addr_shift;
if(rd_table[bank].dev != NULL) {
void MEMORY::write_dma_data16(uint32_t addr, uint32_t data)
{
+ if(!(_MEMORY_DISABLE_DMA_MMIO)) {
+ write_data16(addr, data);
+ return;
+ }
int bank = (addr & ADDR_MASK) >> addr_shift;
if(wr_table[bank].dev != NULL) {
write_dma_data16(addr + 2, (data >> 16) & 0xffff);
}
}
-#endif
// register
uint32_t start_bank = start >> addr_shift;
uint32_t end_bank = end >> addr_shift;
uint32_t to_bank = to >> addr_shift;
- int blocks = (int)(addr_max / bank_size);
+ uint64_t blocks = addr_max / bank_size;
- for(uint32_t i = start_bank; i <= end_bank; i++) {
+ for(uint64_t i = start_bank; i <= end_bank; i++) {
if(to_bank >= blocks) break;
wr_table[to_bank].dev = wr_table[i].dev;
wr_table[to_bank].memory = wr_table[i].memory;
uint32_t start_bank = start >> addr_shift;
uint32_t end_bank = end >> addr_shift;
uint32_t to_bank = to >> addr_shift;
- int blocks = (int)(addr_max / bank_size);
+ uint64_t blocks = addr_max / bank_size;
- for(uint32_t i = start_bank; i <= end_bank; i++) {
+ for(uint64_t i = start_bank; i <= end_bank; i++) {
if(to_bank >= blocks) break;
rd_table[to_bank].dev = rd_table[i].dev;
rd_table[to_bank].memory = rd_table[i].memory;
class EMU;
class MEMORY : public DEVICE
{
-private:
+protected:
typedef struct {
DEVICE* dev;
uint8_t* memory;
uint8_t *rd_dummy;
uint8_t *wr_dummy;
+ bool _MEMORY_DISABLE_DMA_MMIO;
public:
MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
{
- addr_max = MEMORY_ADDR_MAX;
- bank_size = MEMORY_BANK_SIZE;
+ // Set temporally values.
+ addr_max = 0x10000;
+ bank_size = 0x1000;
rd_table = wr_table = NULL;
rd_dummy = wr_dummy = NULL;
-
+
+ _MEMORY_DISABLE_DMA_MMIO = false;
+
set_device_name(_T("Generic Memory Bus"));
}
~MEMORY() {}
// common functions
- void initialize();
- void release();
- uint32_t __FASTCALL read_data8(uint32_t addr);
- void __FASTCALL write_data8(uint32_t addr, uint32_t data);
- uint32_t __FASTCALL read_data16(uint32_t addr);
- void __FASTCALL write_data16(uint32_t addr, uint32_t data);
- uint32_t __FASTCALL read_data32(uint32_t addr);
- void __FASTCALL write_data32(uint32_t addr, uint32_t data);
- uint32_t __FASTCALL read_data8w(uint32_t addr, int* wait);
- void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait);
- uint32_t __FASTCALL read_data16w(uint32_t addr, int* wait);
- void __FASTCALL write_data16w(uint32_t addr, uint32_t data, int* wait);
- uint32_t __FASTCALL read_data32w(uint32_t addr, int* wait);
- void __FASTCALL write_data32w(uint32_t addr, uint32_t data, int* wait);
-#ifdef MEMORY_DISABLE_DMA_MMIO
- uint32_t __FASTCALL read_dma_data8(uint32_t addr);
- void __FASTCALL write_dma_data8(uint32_t addr, uint32_t data);
- uint32_t __FASTCALL read_dma_data16(uint32_t addr);
- void __FASTCALL write_dma_data16(uint32_t addr, uint32_t data);
- uint32_t __FASTCALL read_dma_data32(uint32_t addr);
- void __FASTCALL write_dma_data32(uint32_t addr, uint32_t data);
-#endif
+ virtual void initialize();
+ virtual void release();
+ virtual uint32_t __FASTCALL read_data8(uint32_t addr);
+ virtual void __FASTCALL write_data8(uint32_t addr, uint32_t data);
+ virtual uint32_t __FASTCALL read_data16(uint32_t addr);
+ virtual void __FASTCALL write_data16(uint32_t addr, uint32_t data);
+ virtual uint32_t __FASTCALL read_data32(uint32_t addr);
+ virtual void __FASTCALL write_data32(uint32_t addr, uint32_t data);
+ virtual uint32_t __FASTCALL read_data8w(uint32_t addr, int* wait);
+ virtual void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait);
+ virtual uint32_t __FASTCALL read_data16w(uint32_t addr, int* wait);
+ virtual void __FASTCALL write_data16w(uint32_t addr, uint32_t data, int* wait);
+ virtual uint32_t __FASTCALL read_data32w(uint32_t addr, int* wait);
+ virtual void __FASTCALL write_data32w(uint32_t addr, uint32_t data, int* wait);
+
+ virtual uint32_t __FASTCALL read_dma_data8(uint32_t addr);
+ virtual void __FASTCALL write_dma_data8(uint32_t addr, uint32_t data);
+ virtual uint32_t __FASTCALL read_dma_data16(uint32_t addr);
+ virtual void __FASTCALL write_dma_data16(uint32_t addr, uint32_t data);
+ virtual uint32_t __FASTCALL read_dma_data32(uint32_t addr);
+ virtual void __FASTCALL write_dma_data32(uint32_t addr, uint32_t data);
// unique functions
- void set_memory_r(uint32_t start, uint32_t end, uint8_t *memory);
- void set_memory_w(uint32_t start, uint32_t end, uint8_t *memory);
+ virtual void set_memory_r(uint32_t start, uint32_t end, uint8_t *memory);
+ virtual void set_memory_w(uint32_t start, uint32_t end, uint8_t *memory);
void set_memory_rw(uint32_t start, uint32_t end, uint8_t *memory)
{
set_memory_r(start, end, memory);
set_memory_w(start, end, memory);
}
- void set_memory_mapped_io_r(uint32_t start, uint32_t end, DEVICE *device);
- void set_memory_mapped_io_w(uint32_t start, uint32_t end, DEVICE *device);
+ virtual void set_memory_mapped_io_r(uint32_t start, uint32_t end, DEVICE *device);
+ virtual void set_memory_mapped_io_w(uint32_t start, uint32_t end, DEVICE *device);
void set_memory_mapped_io_rw(uint32_t start, uint32_t end, DEVICE *device)
{
set_memory_mapped_io_r(start, end, device);
set_memory_mapped_io_w(start, end, device);
}
- void set_wait_r(uint32_t start, uint32_t end, int wait);
- void set_wait_w(uint32_t start, uint32_t end, int wait);
+ virtual void set_wait_r(uint32_t start, uint32_t end, int wait);
+ virtual void set_wait_w(uint32_t start, uint32_t end, int wait);
void set_wait_rw(uint32_t start, uint32_t end, int wait)
{
set_wait_r(start, end, wait);
set_wait_w(start, end, wait);
}
- void unset_memory_r(uint32_t start, uint32_t end);
- void unset_memory_w(uint32_t start, uint32_t end);
+ virtual void unset_memory_r(uint32_t start, uint32_t end);
+ virtual void unset_memory_w(uint32_t start, uint32_t end);
void unset_memory_rw(uint32_t start, uint32_t end)
{
unset_memory_r(start, end);
unset_memory_w(start, end);
}
- void copy_table_r(uint32_t to, uint32_t start, uint32_t end);
- void copy_table_w(uint32_t to, uint32_t start, uint32_t end);
+ virtual void copy_table_r(uint32_t to, uint32_t start, uint32_t end);
+ virtual void copy_table_w(uint32_t to, uint32_t start, uint32_t end);
void copy_table_rw(uint32_t to, uint32_t start, uint32_t end) {
copy_table_r(to, start, end);
copy_table_w(to, start, end);
bool write_bios(const _TCHAR *file_name, uint8_t *buffer, int size);
bool read_image(const _TCHAR *file_path, uint8_t *buffer, int size);
bool write_image(const _TCHAR *file_path, uint8_t *buffer, int size);
+
+ // Unique functions.
+ void set_addr_max(int64_t size)
+ {
+ // Allow to modify before initialize() or set_foo_r|w|rw()..
+ if(rd_table == NULL) {
+ addr_max = size;
+ }
+ }
+ void set_bank_size(int64_t size)
+ {
+ if(rd_table == NULL) {
+ bank_size = size;
+ }
+ }
+ uint64_t get_addr_max()
+ {
+ return addr_max;
+ }
+ uint64_t get_bank_size()
+ {
+ return bank_size;
+ }
- int64_t addr_max;
- int64_t bank_size;
+ uint64_t addr_max;
+ uint64_t bank_size;
+
+ uint64_t addr_mask;
+ uint64_t bank_mask;
+
};
#endif