virtual void close_from_cmd();
virtual void do_dma_eot(bool by_signal);
- void __FASTCALL write_mcuint_signals(uint32_t val)
+ void __FASTCALL write_mcuint_signals()
{
- mcu_intr = (val == 0) ? false : true;
+ uint32_t val = ((dma_intr) || (mcu_intr)) ? 0xffffffff : 0;
write_signals(&outputs_mcuint, val);
}
void cdrom_debug_log(const char *fmt, ...);
// (val) ? _T("true ") : _T("false"),
// (dma_intr_mask) ? _T("ON ") : _T("OFF"),
// (stat_reply_intr) ? _T("ON ") : _T("OFF"));
- if(val) {
- // At least, DMA interrupt mask is needed (by TownsOS v.1.1) 20200511 K.O
- dma_intr = true;
- if(!(dma_intr_mask)) {
-// if(mcu_intr) write_signals(&outputs_mcuint, 0x0);
- write_mcuint_signals(0xffffffff);
- }
- } else {
- dma_intr = false;
- write_mcuint_signals(0x0);
+ // At least, DMA interrupt mask is needed (by TownsOS v.1.1) 20200511 K.O
+ dma_intr = val;
+ if(!(dma_intr_mask)) {
+ write_mcuint_signals();
}
}
mcu = (mcu) && !(mcu_intr_mask);
dma = (dma) && !(dma_intr_mask);
}
- bool val = mcu | dma;
- write_mcuint_signals((val) ? 0xffffffff : 0);
+ uint32_t val = ((dma) || (mcu)) ? 0xffffffff : 0;
+ write_signals(&outputs_mcuint, val);
}
void TOWNS_CDROM::set_mcu_intr(bool val)
// (val) ? _T("true ") : _T("false"),
// (mcu_intr_mask) ? _T("ON ") : _T("OFF"),
// (stat_reply_intr) ? _T("ON ") : _T("OFF"));
- if(stat_reply_intr) {
- mcu_intr = val;
- write_mcuint_signals((val) ? 0xffffffff : 0);
- } else {
- mcu_intr = val;
- if(!(val)) {
- write_mcuint_signals(0);
- }
+ mcu_intr = val;
+ if((stat_reply_intr) || !(mcu_intr_mask)) {
+ write_mcuint_signals();
}
// Execute next command if reserved.
// if((mcu_ready) && (command_received) && (param_ptr >= 8)) {
// By DMA/TC, EOT.
case SIG_TOWNS_CDROM_DMAINT:
if(((data & mask) != 0) && (dma_transfer_phase)) {
- //cdrom_debug_log(_T("CAUSED DMA INTERRUPT FROM DMAC"));
+ cdrom_debug_log(_T("CAUSED DMA INTERRUPT FROM DMAC"));
//clear_event(this, event_drq);
do_dma_eot(true);
}
case SIG_TOWNS_CDROM_DMAACK:
if(((data & mask) != 0) && (dma_transfer_phase)) {
//force_register_event(this, EVENT_CDROM_DRQ, 1.0 / 8.0, false, event_drq);
- #if 1
- if(/* (read_length <= 0) && */(databuffer->empty())) {
+ #if 0
+ if((read_length <= 0) && (databuffer->empty())) {
clear_event(this, event_drq);
if((read_length <= 0)) { // ToDo: With prefetch.
cdrom_debug_log(_T("MAYBE COMPLETE TO TRANSFER ALL DATA"));
);
status_queue->clear();
extra_status = 0;
-// if(_req_status) {
+ if(_req_status) {
if(extra > 0) extra_status = extra;
status_queue->write(s0);
status_queue->write(s1);
status_queue->write(s2);
status_queue->write(s3);
-// } else {
+ } else {
// set_delay_ready_eot();
-// }
+ }
set_delay_ready_eot();
}
}
mcu_ready = true;
mcu_intr = true;
- dma_intr = false;
+ //dma_intr = false;
if((_req_status) && (stat_reply_intr) && !(mcu_intr_mask)) {
- write_mcuint_signals(0xffffffff);
+ write_mcuint_signals();
}
// cdrom_debug_log(_T("SET STATUS %02x: %02x %02x %02x %02x EXTRA=%d"), latest_command, s0, s1, s2, s3, extra_status);
}
{
switch (event_id) {
case EVENT_CDROM_DELAY_INTERRUPT_ON: // DELAY INTERRUPT ON
- write_mcuint_signals(0xffffffff);
+ mcu_intr = true;
+ write_mcuint_signals();
event_delay_interrupt = -1;
break;
case EVENT_CDROM_DELAY_INTERRUPT_OFF: // DELAY INTERRUPT OFF
- write_mcuint_signals(0x0);
+ mcu_intr = false;
+ write_mcuint_signals();
event_delay_interrupt = -1;
break;
case EVENT_CDROM_DELAY_READY: // CALL READY TO ACCEPT COMMAND WITH STATUS
// if(stat_reply_intr) {
// set_mcu_intr(true);
// }
- if(req_status) {
+// if(req_status) {
mcu_intr = true;
if(!(mcu_intr_mask) && (stat_reply_intr)) {
- write_mcuint_signals(0xffffffff);
+ write_mcuint_signals();
}
- } else {
- mcu_intr = false;
- }
+// }
// set_mcu_intr(true);
+
break;
case EVENT_CDROM_READY_CDDAREPLY: // READY TO ACCEPT A COMMAND FROM CDC.
event_delay_ready = -1;
// mcu_intr = true;
// status_queue->clear();
// if(!(mcu_intr_mask)) {
-// write_mcuint_signals(0xffffffff);
+// write_mcuint_signals();
// }
// }
break;
mcu_intr = true;
// status_queue->clear();
if(!(mcu_intr_mask)) {
- write_mcuint_signals(0xffffffff);
+ write_mcuint_signals();
}
}
}
int seccount = 0;
while(sectors > 0) {
- //cdrom_debug_log(_T("TRY TO READ SECTOR:LBA=%d"), read_sector);
+ cdrom_debug_log(_T("TRY TO READ SECTOR:LBA=%d"), read_sector);
memset(&tmpbuf, 0x00, sizeof(tmpbuf));
int _trk = check_cdda_track_boundary(read_sector);
if(_trk <= 0) { // END
}
if(cdda_status != CDDA_PLAYING) {
//// Notify to release bus.
- write_mcuint_signals(0x0);
+ mcu_intr = true;
+ write_mcuint_signals();
if((cdda_status == CDDA_OFF) || (cdda_status == CDDA_ENDED)) {
//get_track_by_track_num(current_track); // Re-Play
cdda_playing_frame = cdda_start_frame;
clear_event(this, event_cdda);
if((cdda_status == CDDA_PLAYING) || (cdda_status == CDDA_ENDED)) {
// Notify to release bus.
- write_mcuint_signals(0x0);
+ mcu_intr = true;
+ write_mcuint_signals();
if(status == CDDA_OFF) {
databuffer->clear();
cdda_buffer_ptr = 0;
clear_event(this, event_time_out);
cdrom_debug_log(_T("EOT(PIO)"));
status_read_done(false);
+ dma_intr = true;
if((stat_reply_intr) || !(dma_intr_mask)) {
//if((stat_reply_intr) && !(dma_intr_mask)) {
- write_mcuint_signals(0xffffffff);
+ write_mcuint_signals();
}
} else if(databuffer->empty()) {
pio_transfer_phase = false;
mcu_ready = false;
clear_event(this, event_time_out);
cdrom_debug_log(_T("NEXT(PIO)"));
+ dma_intr = true;
if((stat_reply_intr) || !(dma_intr_mask)) {
//if((stat_reply_intr) && !(dma_intr_mask)) {
- write_mcuint_signals(0xffffffff);
+ write_mcuint_signals();
}
}
}
* 04C4h : Parameter register
* 04C6h : Transfer control register.
*/
- //cdrom_debug_log(_T("WRITE IO8: %04X %02X"), addr, data);
+ cdrom_debug_log(_T("WRITE IO8: %04X %02X"), addr, data);
*wait = 6; // temporally
w_regs[addr & 0x0f] = data;
switch(addr & 0x0f) {
case 0x00: // Master control register
// Note: Sync with TSUGARU.
// 20220127 K.O
- //cdrom_debug_log(_T("PORT 04C0h <- %02X"), data);
- if((data & 0x80) != 0) {
- mcu_intr = false;
- if(!(dma_intr)) {
- write_mcuint_signals(0); // Reset interrupt request to PIC.
- }
- }
- if((data & 0x40) != 0) {
- dma_intr = false;
- if(!(mcu_intr)) {
- write_mcuint_signals(0); // Reset interrupt request to PIC.
- }
- }
+ cdrom_debug_log(_T("PORT 04C0h <- %02X"), data);
if((data & 0x04) != 0) {
cdrom_debug_log(_T("RESET FROM CMDREG: 04C0h"));
reset_device();
+ } else {
+ if((data & 0x80) != 0) {
+ mcu_intr = false;
+ }
+ if((data & 0x40) != 0) {
+ dma_intr = false;
+ }
+ mcu_intr_mask = ((data & 0x02) == 0) ? true : false;
+ dma_intr_mask = ((data & 0x01) == 0) ? true : false;
+ if((data & 0xc0) != 0) {
+ write_mcuint_signals(); // Reset interrupt request to PIC.
+ }
}
- mcu_intr_mask = ((data & 0x02) == 0) ? true : false;
- dma_intr_mask = ((data & 0x01) == 0) ? true : false;
break;
case 0x02: // Command
//cdrom_debug_log(_T("PORT 04C2h <- %02X"), data);
uint32_t DICTIONARY::read_memory_mapped_io8w(uint32_t addr, int *wait)
{
- uint8_t n_data = 0xff;
+ uint8_t n_data = 0x00;
// 0xd0000 - 0xdffff : primary is VRAM, secondary is DICTIONARY.
if((addr < 0x000da000) && (addr >= 0x000d0000)) {
*wait = 6; // temporally.
void TOWNS_DMAC::do_dma_inc_dec_ptr_8bit(int c)
{
// Note: FM-Towns may extend to 32bit.
+#if 0
uint32_t incdec = ((dma[c].mode & 0x20) == 0) ? 1 : UINT32_MAX;
uint32_t addr = dma[c].areg & 0x00ffffff;
uint32_t high_a = dma[c].areg & 0xff000000;
addr = (addr + incdec) & 0xffffffff;
}
dma[c].areg = addr;
+#else
+ __LIKELY_IF(dma_wrap_reg != 0) {
+ uint32_t high_a = dma[c].areg & 0xff000000;
+ if(dma[c].mode & 0x20) {
+ dma[c].areg = dma[c].areg - 1;
+ } else {
+ dma[c].areg = dma[c].areg + 1;
+ }
+ dma[c].areg = ((dma[c].areg & 0x00ffffff) | high_a) & dma_addr_mask;
+ } else {
+ if(dma[c].mode & 0x20) {
+ dma[c].areg = (dma[c].areg - 1) & dma_addr_mask;
+ } else {
+ dma[c].areg = (dma[c].areg + 1) & dma_addr_mask;
+ }
+ }
+#endif
}
void TOWNS_DMAC::do_dma_inc_dec_ptr_16bit(int c)
{
// Note: FM-Towns may extend to 32bit.
+#if 0
uint32_t incdec = ((dma[c].mode & 0x20) == 0) ? 2 : (UINT32_MAX - 1);
uint32_t addr = dma[c].areg & 0x00ffffff;
uint32_t high_a = dma[c].areg & 0xff000000;
addr = (addr + incdec) & 0xffffffff;
}
dma[c].areg = addr;
+#else
+ __LIKELY_IF(dma_wrap_reg != 0) {
+ uint32_t high_a = dma[c].areg & 0xff000000;
+ if(dma[c].mode & 0x20) {
+ dma[c].areg = dma[c].areg - 2;
+ } else {
+ dma[c].areg = dma[c].areg + 2;
+ }
+ dma[c].areg = ((dma[c].areg & 0x00ffffff) | high_a) & dma_addr_mask;
+ } else {
+ if(dma[c].mode & 0x20) {
+ dma[c].areg = (dma[c].areg - 2) & dma_addr_mask;
+ } else {
+ dma[c].areg = (dma[c].areg + 2) & dma_addr_mask;
+ }
+ }
+#endif
}
#if 0 /* For Debug */
// 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()
- //dma_addr_mask = data;
+ dma_addr_mask = data;
} else {
// Fallthrough.
// if(id == SIG_UPD71071_CH1) {
pit1->set_constant_clock(0, 1229900);
pit1->set_constant_clock(1, 1229900);
pit1->set_constant_clock(2, 1229900);
- //pic->set_context_cpu(cpu);
- pic->set_context_cpu(memory);
+ pic->set_context_cpu(cpu);
+ //pic->set_context_cpu(memory);
fdc->set_context_irq(floppy, SIG_FLOPPY_IRQ, 1);
rtc->set_context_data(timer, SIG_TIMER_RTC, 0x0f, 0);
rtc->set_context_busy(timer, SIG_TIMER_RTC_BUSY, 0x80);
dma->set_context_debugger(new DEBUGGER(this, emu));
extra_dma->set_context_debugger(new DEBUGGER(this, emu));
#endif
- dma->set_context_cpu(cpu);
+ //dma->set_context_cpu(cpu);
dma->set_context_memory(memory);
dma->set_context_ch0(fdc);
dma->set_context_ch1(scsi_host);
io->set_iomap_single_r (0xff84, planevram); // MMIO
io->set_iomap_single_rw(0xff86, planevram); // MMIO
io->set_iomap_single_rw(0xff88, memory); // MMIO
- io->set_iomap_range_rw (0xff94, 0xff97, fontrom); // MMIO
- io->set_iomap_range_rw (0xff98, 0xff99, memory); // MMIO
- io->set_iomap_range_rw (0xff9c, 0xff9f, memory); // MMIO
+ //io->set_iomap_range_rw (0xff94, 0xff97, fontrom); // MMIO
+ //io->set_iomap_range_rw (0xff98, 0xff99, memory); // MMIO
+ //io->set_iomap_range_rw (0xff9c, 0xff9f, memory); // MMIO
+
+ io->set_iomap_range_rw (0xff94, 0xff99, memory); // MMIO
+ io->set_iomap_range_r (0xff9c, 0xff9d, memory); // MMIO
+ io->set_iomap_single_rw(0xff9e, memory); // MMIO
io->set_iomap_single_rw(0xffa0, planevram); // MMIO
this->out_debug_log(_T("[SCSI] out %04X %02X\n"), addr, data);
#endif
ctrl_reg = data;
- //if((data & CTRL_DMAE) != 0) dma_enabled = true;
+ if((data & CTRL_DMAE) != 0) dma_enabled = true;
if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX
ex_int_enable = ((data & 0x20) != 0) ? true : false;
// Set host to 16bit bus width. BIT3 ,= '1'.
d_host->write_signal(SIG_SCSI_RST, data, CTRL_RST);
d_host->write_signal(SIG_SCSI_SEL, data, CTRL_SEL);
d_host->write_signal(SIG_SCSI_ATN, data, CTRL_ATN);
-// d_host->write_signal(SIG_SCSI_HOST_DMAE, data, CTRL_DMAE);
+ d_host->write_signal(SIG_SCSI_HOST_DMAE, data, CTRL_DMAE);
}
break;
}
}*/
break;
case SIG_SCSI_EOT:
- //dma_enabled = ((data & mask) == 0) ? true : false;
+ dma_enabled = ((data & mask) == 0) ? true : false;
break;
}
}
set_memory_rw (0x000d0000, 0x000effff, ram_paged);
} else {
if(select_d0_dict) {
- set_memory_mapped_io_r (0x000d0000, 0x000d9fff, d_dictionary);
+ set_memory_mapped_io_r (0x000d0000, 0x000d7fff, d_dictionary);
unset_memory_w (0x000d0000, 0x000d7fff);
- set_memory_mapped_io_rw(0x000d8000, 0x000d9fff, d_dictionary);
+ set_memory_mapped_io_w (0x000d8000, 0x000d9fff, d_dictionary);
} else {
//set_memory_rw (0x000d0000, 0x000dffff, ram_paged);
unset_memory_rw (0x000d0000, 0x000d9fff);
{
uint8_t val = 0xff;
__UNLIKELY_IF((addr & 0xffff) < 0xff80) {
- return 0xff;
+ return ram_pagec[addr & 0xffff];
}
+#if 1
__LIKELY_IF((addr & 0xffff) < 0xff88) {
__LIKELY_IF(d_planevram != NULL) {
val = d_planevram->read_memory_mapped_io8(addr & 0xffff);
}
return val;
}
+#endif
if((machine_id >= 0x0600) && !(is_compatible)) { // After UG
switch(addr & 0xffff) {
case 0xff88:
}
}
switch(addr & 0xffff) {
+ case 0xff88:
+ __LIKELY_IF(d_planevram != NULL) {
+ val = d_planevram->read_io8(addr);
+ }
+ break;
+ case 0xff95:
+ val = 0x80;
+ break;
+ case 0xff96:
+ __LIKELY_IF(d_font != NULL) {
+ return d_font->read_signal(SIG_TOWNS_FONT_KANJI_DATA_LOW);
+ }
+ break;
+ case 0xff97:
+ __LIKELY_IF(d_font != NULL) {
+ return d_font->read_signal(SIG_TOWNS_FONT_KANJI_DATA_HIGH);
+ }
+ break;
case 0xff98:
__LIKELY_IF(d_timer != NULL) {
d_timer->write_signal(SIG_TIMER_BEEP_ON, 1, 1);
}
break;
+ case 0xff99:
+ __LIKELY_IF(d_planevram != NULL) {
+ val = d_planevram->read_memory_mapped_io8(addr);
+ }
+ break;
default:
__LIKELY_IF(d_planevram != NULL) {
val = d_planevram->read_io8(addr & 0xffff);
val = reg_misc3;
break;
case 0x0025:
- val = reg_misc3;
+ val = reg_misc4;
break;
case 0x0028:
// NMI MASK
void TOWNS_MEMORY::write_fmr_ports8(uint32_t addr, uint32_t data)
{
__UNLIKELY_IF((addr & 0xffff) < 0xff80) {
+ ram_pagec[addr & 0xffff] = data;
return;
}
+#if 1
__LIKELY_IF((addr & 0xffff) < 0xff88) {
__LIKELY_IF(d_planevram != NULL) {
d_planevram->write_io8(addr & 0xffff, data);
}
return;
}
+#endif
if((machine_id >= 0x0600) && !(is_compatible)) { // After UG
switch(addr & 0xffff) {
case 0xff9e:
}
}
switch(addr & 0xffff) {
+ case 0xff94:
+ __LIKELY_IF(d_font != NULL) {
+ d_font->write_signal(SIG_TOWNS_FONT_KANJI_HIGH, data, 0xff);
+ }
+ break;
+ case 0xff95:
+ __LIKELY_IF(d_font != NULL) {
+ d_font->write_signal(SIG_TOWNS_FONT_KANJI_LOW, data, 0xff);
+ }
+ break;
+ case 0xff96:
+ case 0xff97:
+ break;
case 0xff98:
__LIKELY_IF(d_timer != NULL) {
d_timer->write_signal(SIG_TIMER_BEEP_ON, 0, 1);
}
__UNLIKELY_IF(addr >= 0xd0000) {
*wait = mem_wait_val;
- return 0xff;
+ return 0xffff;
}
// OK? This may be bus width has 8bit ?
*wait = 6; // Maybe 6.
c = c & 3;
uint8_t bit = 1 << c;
-#if 0 /* SYNC TO UPSTREAM */
+#if 1 /* SYNC TO UPSTREAM */
if(dma[c].creg-- == 0) {
//if(dma[c].endreq) dma[c].end = true;
if(dma[c].mode & 0x10) {
#else
// if(dma[c].end) return true; // OK?
if((dma[c].creg == 0) || ((dma[c].endreq) && !(dma[c].end) && ((dma[c].mode & 0xc0) != 0x40))) { // OK?
- if(dma[c].endreq) dma[c].end = true;
+ //if(dma[c].endreq) dma[c].end = true;
bool is_tc = false;
dma[c].creg--;
- if(dma[c].end) is_tc = true;
+ //if(dma[c].end) is_tc = true;
// TC
if(dma[c].bcreg < dma[c].creg) {
is_tc = true;
if(cmd & 4) {
return true;
}
- if(dma[c].end) {
- if((dma[c].mode & 0xc0) != 0x40) { // Without Single
- return true;
- }
- }
+// if(dma[c].end) {
+// if((dma[c].mode & 0xc0) != 0x40) { // Without Single
+// return true;
+// }
+// }
uint8_t bit = 1 << c;
if(((req | sreq) & bit) /*&& !(mask & bit)*/) {
for(int c = 0; c < 4; c++) {
if((mask & (1 << c)) == 0) { // MASK
if((dma[c].mode & 0xc0) == 0x00) { // Demand
- if(!(dma[c].end)) {
+ //if(!(dma[c].end)) {
do_dma_per_channel(c);
- }
+ //}
} else if((dma[c].mode & 0xc0) == 0x40) { // Single
if(do_dma_per_channel(c)) break;
} else if((dma[c].mode & 0xc0) == 0xc0) { // Block (ToDo)