#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];
}
}
{
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;
}
}
{
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;
{
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);
{
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;
{
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);
{
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];
}
}
{
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;
}
}
{
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];
}
}
{
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;
}
}
{
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);
{
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);
{
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);
{
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);
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;
}
}