//e_volume[1]->set_context_ch2(mic, MB87878_VOLUME_LEFT | MB87878_VOLUME_RIGHT);
//e_volume[1]->set_context_ch3(modem, MB87878_VOLUME_LEFT | MB87878_VOLUME_RIGHT);
+ memory->set_context_dmac(dma);
memory->set_context_vram(vram);
memory->set_context_system_rom(sysrom);
memory->set_context_msdos(msdosrom);
void TOWNS_DMAC::reset()
{
UPD71071::reset();
+ dma_wrap_reg = 0;
+ dma_addr_reg = 0;
+ dma_addr_mask = 0xffffffff; // OK?
}
void TOWNS_DMAC::write_io8(uint32_t addr, uint32_t data)
{
// Note: FM-Towns may extend to 32bit.
if(dma[c].mode & 0x20) {
- dma[c].areg = (dma[c].areg - 1) & 0xffffffff;
+ dma[c].areg = (dma[c].areg - 1) & dma_addr_mask;
} else {
- dma[c].areg = (dma[c].areg + 1) & 0xffffffff;
+ dma[c].areg = (dma[c].areg + 1) & dma_addr_mask;
}
}
{
// Note: FM-Towns may extend to 32bit.
if(dma[c].mode & 0x20) {
- dma[c].areg = (dma[c].areg - 2) & 0xffffffff;
+ dma[c].areg = (dma[c].areg - 2) & dma_addr_mask;
} else {
- dma[c].areg = (dma[c].areg + 2) & 0xffffffff;
+ dma[c].areg = (dma[c].areg + 2) & dma_addr_mask;
}
}
-
+uint32_t TOWNS_DMAC::read_signal(int id)
+{
+ if(id == SIG_TOWNS_DMAC_ADDR_REG) {
+ return dma_addr_reg;
+ } else if(SIG_TOWNS_DMAC_WRAP_REG) {
+ return dma_wrap_reg;
+ } else if(id == SIG_TOWNS_DMAC_ADDR_MASK) {
+ return dma_addr_mask;
+ }
+ return UPD71071::read_signal(id);
+}
+
+void TOWNS_DMAC::write_signal(int id, uint32_t data, uint32_t mask)
+{
+ if(id == SIG_TOWNS_DMAC_ADDR_REG) {
+ dma_addr_reg = data & 3;
+ this->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, data, mask);
+ } else if(id == SIG_TOWNS_DMAC_WRAP_REG) {
+ dma_wrap_reg = data;
+ this->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, data, mask);
+ } else if(id == SIG_TOWNS_DMAC_ADDR_MASK) {
+ // From eFMR50 / memory.cpp / update_dma_addr_mask()
+ switch(dma_addr_reg & 3) {
+ case 0:
+ dma_addr_mask = data;
+ break;
+ case 1:
+ if(!(dma_wrap_reg & 1) && (data == 0x000fffff)) {
+ dma_addr_mask = 0x000fffff;
+ } else {
+ dma_addr_mask = 0x00ffffff;
+ }
+ break;
+ default:
+ if(!(dma_wrap_reg & 1) && (data == 0x000fffff)) {
+ dma_addr_mask = 0x000fffff;
+ } else {
+ dma_addr_mask = 0xffffffff;
+ }
+ break;
+ }
+ } else {
+ // Fallthrough.
+ UPD71071::write_signal(id, data, mask);
+ }
}
+
+
+void TOWNS_DMAC::write_via_debugger_data8(uint32_t addr, uint32_t data)
+{
+ d_mem->write_dma_data8(addr & dma_addr_mask, data);
+}
+
+uint32_t TOWNS_DMAC::read_via_debugger_data8(uint32_t addr)
+{
+ return d_mem->read_dma_data8(addr & dma_addr_mask);
+}
+
+void TOWNS_DMAC::write_via_debugger_data16(uint32_t addr, uint32_t data)
+{
+ d_mem->write_dma_data16(addr & dma_addr_mask, data);
+}
+
+uint32_t TOWNS_DMAC::read_via_debugger_data16(uint32_t addr)
+{
+ return d_mem->read_dma_data16(addr & dma_addr_mask);
+}
+
+// note: if SINGLE_MODE_DMA is defined, do_dma() is called in every machine cycle
+bool TOWNS_DMAC::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
+{
+ if(buffer == NULL) return false;
+ _TCHAR sbuf[4096] = {0};
+ if(UPD71071::get_debug_regs_info(sbuf, 4096)) {
+ my_stprintf_s(buffer, buffer_len,
+ _T("%s\n")
+ _T("ADDR_MASK=%08X ADDR_REG=%02X ADDR_WRAP=%02X\n")
+ , sbuf, dma_addr_mask, dma_addr_reg, dma_wrap_reg);
+ return true;
+ }
+ return false;
+}
+
+#define STATE_VERSION 1
+
+bool TOWNS_DMAC::process_state(FILEIO *state_fio, bool loading)
+{
+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+ return false;
+ }
+ if(!state_fio->StateCheckInt32(this_device_id)) {
+ return false;
+ }
+ if(!(UPD71071::process_state(state_fio, loading))) {
+ return false;
+ }
+ state_fio->StateValue(dma_addr_reg);
+ state_fio->StateValue(dma_wrap_reg);
+ state_fio->StateValue(dma_addr_mask);
+
+ return true;
+}
+}
#include "../vm.h"
#include "../upd71071.h"
+// Using original signal using after 1 << 12.
+#define SIG_TOWNS_DMAC_ADDR_REG 4096
+#define SIG_TOWNS_DMAC_WRAP_REG 4100
+#define SIG_TOWNS_DMAC_ADDR_MASK 4104
+
namespace FMTOWNS {
class TOWNS_DMAC : public UPD71071
{
protected:
+ uint8_t dma_addr_reg;
+ uint8_t dma_wrap_reg;
+ uint32_t dma_addr_mask;
+
virtual void __FASTCALL do_dma_inc_dec_ptr_8bit(int c);
virtual void __FASTCALL do_dma_inc_dec_ptr_16bit(int c);
public:
// common functions
virtual void initialize();
virtual void reset();
+// virtual void __FASTCALL do_dma();
+
virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data);
virtual uint32_t __FASTCALL read_io8(uint32_t addr);
-// virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask);
-// virtual uint32_t __FASTCALL read_signal(int id);
-// virtual void __FASTCALL do_dma();
+
+ virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask);
+ virtual uint32_t __FASTCALL read_signal(int id);
+ virtual bool process_state(FILEIO* state_fio, bool loading);
-// virtual bool process_state(FILEIO* state_fio, bool loading);
+ // for debug
+ virtual void __FASTCALL write_via_debugger_data8(uint32_t addr, uint32_t data);
+ virtual uint32_t __FASTCALL read_via_debugger_data8(uint32_t addr);
+ virtual void __FASTCALL write_via_debugger_data16(uint32_t addr, uint32_t data);
+ virtual uint32_t __FASTCALL read_via_debugger_data16(uint32_t addr);
+ virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
+
};
}
#include "../../fileio.h"
#include "./towns_memory.h"
+#include "./towns_dmac.h"
#include "./towns_vram.h"
#include "./towns_sprite.h"
#include "./fontroms.h"
}
rd_table[bank].dev->read_memory_mapped_io8(addr);
// return rd_table[bank].dev->read_dma_data8w(addr, wait);
- } else if(dma_is_vram) {
- if(wait != NULL) {
- *wait = mem_wait_val;
- }
- if(d_vram != NULL) {
- return d_vram->read_memory_mapped_io8(addr);
- }
} else if(rd_table[bank].memory != NULL) {
if(wait != NULL) {
*wait = mem_wait_val;
*wait = rd_table[bank].wait;
}
rd_table[bank].dev->read_memory_mapped_io16(addr);
- } else if(dma_is_vram) {
- if(wait != NULL) {
- *wait = mem_wait_val;
- }
- if(d_vram != NULL) {
- return d_vram->read_memory_mapped_io16(addr);
- }
} else if(rd_table[bank].memory != NULL) {
if(wait != NULL) {
*wait = mem_wait_val;
}
wr_table[bank].dev->write_memory_mapped_io8(addr, data);
return;
- } else if(dma_is_vram) {
- if(wait != NULL) {
- *wait = mem_wait_val;
- }
- if(d_vram != NULL) {
- d_vram->write_memory_mapped_io8(addr, data);
- }
} else if(wr_table[bank].memory != NULL) {
if(wait != NULL) {
*wait = mem_wait_val;
}
wr_table[bank].dev->write_memory_mapped_io16(addr, data);
return;
- } else if(dma_is_vram) {
- if(wait != NULL) {
- *wait = wr_table[bank].wait;
- }
- if(d_vram != NULL) {
- d_vram->write_memory_mapped_io16(addr, data);
- return;
- }
} else if(wr_table[bank].memory != NULL) {
if(wait != NULL) {
*wait = mem_wait_val;
case 0x0022:
// Power register
val = 0xff;
+// if(d_dmac != NULL) {
+// val = d_dmac->read_signal(SIG_TOWNS_DMAC_ADDR_REG);
+// }
+ break;
+ case 0x0024:
+ // Power register
+ val = 0xff;
+ if(d_dmac != NULL) {
+ val = d_dmac->read_signal(SIG_TOWNS_DMAC_WRAP_REG);
+ }
break;
case 0x0030:
val = (((machine_id & 0x1f) << 3) | (cpu_id & 7));
}
}
if(d_cpu != NULL) {
- switch(data & 0x08) {
+// switch(data & 0x08) {
+ switch(data & 0x30) { // From eFMR50
case 0x00: // 20bit
- d_cpu->set_address_mask(0xffffffff);
+ d_cpu->set_address_mask(0x000fffff);
+ break;
+ case 0x20: // 24bit
+ d_cpu->set_address_mask(0x00ffffff);
break;
default: // 32bit
- d_cpu->set_address_mask(0x000fffff);
+ d_cpu->set_address_mask(0xffffffff);
break;
}
+ if(d_dmac != NULL) {
+ uint32_t maskval = d_cpu->get_address_mask();
+ d_dmac->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, maskval, 0xff);
+ }
}
break;
case 0x0022:
}
emu->power_off();
}
+ if(d_dmac != NULL) {
+ d_dmac->write_signal(SIG_TOWNS_DMAC_ADDR_REG, data, 0xff);
+ }
+ // Power register
+ break;
+ case 0x0024:
+ if(d_dmac != NULL) {
+ d_dmac->write_signal(SIG_TOWNS_DMAC_WRAP_REG, data, 0xff);
+ }
// Power register
break;
case 0x0032:
DEVICE* d_romcard[2]; // 0xc0000000 - 0xc0ffffff / 0xc1000000 - 0xc1ffffff
DEVICE* d_pcm; // 0xc2200000 - 0xc2200fff
DEVICE* d_beep;
+ DEVICE* d_dmac;
I386* d_cpu;
DEVICE* d_dictionary;
d_cpu = NULL;
d_vram = NULL;
+ d_dmac = NULL;
d_pcm = NULL;
d_sprite = NULL;
d_romcard[0] = d_romcard[1] = NULL;
{
d_cpu = device;
}
+ void set_context_dmac(DEVICE* device)
+ {
+ d_dmac = device;
+ }
void set_context_vram(DEVICE* device)
{
d_vram = device;