# else
psg = new YM2203(this, emu);
# endif
+# ifdef USE_DEBUGGER
+ psg->set_context_debugger(new DEBUGGER(this, emu));
+# endif
#else
opn[0] = new YM2203(this, emu); // OPN
opn[1] = new YM2203(this, emu); // WHG
opn[2] = new YM2203(this, emu); // THG
+# ifdef USE_DEBUGGER
+ opn[0]->set_context_debugger(new DEBUGGER(this, emu));
+ opn[1]->set_context_debugger(new DEBUGGER(this, emu));
+ opn[2]->set_context_debugger(new DEBUGGER(this, emu));
+# endif
# if !defined(_FM77AV_VARIANTS)
# if defined(USE_AY_3_8910_AS_PSG)
psg = new AY_3_891X(this, emu);
# else
psg = new YM2203(this, emu);
# endif
+# ifdef USE_DEBUGGER
+ psg->set_context_debugger(new DEBUGGER(this, emu));
+# endif
# endif
#endif
#define WINDOW_HEIGHT_ASPECT 480
#define HAS_MC6809
#define MB8877_MAX_CHIPS 1
+#define MB8877_DELAY_AFTER_SEEK 60000
//#define IO_ADDR_MAX 0x10000
// device informations for win32
void DISPLAY::draw_screen()
{
+ if(emu->now_waiting_in_debugger) {
+ // draw lines
+#ifdef _X1TURBO_FEATURE
+ for(int v = 0; v < (hireso ? 400 : 200); v++) {
+#else
+ for(int v = 0; v < 200; v++) {
+#endif
+ draw_line(v);
+ }
+ }
+
// copy to real screen
#ifdef _X1TURBOZ
dr_zpalette_pc[8 + 0] = dr_zpalette_pc[16 + 0x000];
pattern_r = pcg_r[code];
pattern_g = pcg_g[code];
#ifdef _X1TURBO_FEATURE
- shift = hireso ? 1 : 0;
+ shift = (mode1 & 1) ? 1 : 0;
}
#endif
#ifdef _X1TURBO_FEATURE
ofs += 16; // right
}
pattern_b = pattern_r = pattern_g = &kanji[ofs];
- shift = hireso ? ((ch_height >= 32) ? 1 : 0) : ((ch_height >= 16) ? 0 : -1);
max_line = 16;
- } else if(hireso || (mode1 & 4)) {
+ } else if((mode1 & 5) != 0) {
// ank 8x16 or kanji
pattern_b = pattern_r = pattern_g = &kanji[code << 4];
- shift = hireso ? ((ch_height >= 32) ? 1 : 0) : ((ch_height >= 16) ? 0 : -1);
max_line = 16;
#endif
} else {
// ank 8x8
pattern_b = pattern_r = pattern_g = &font[code << 3];
}
+#ifdef _X1TURBO_FEATURE
+ if(max_line == 16) {
+ shift = ((mode1 & 5) == 5) ? 1 : ((mode1 & 5) != 0) ? 0 : -1;
+ }
+#endif
// check vertical doubled char
if(!(attr & 0x40)) {
b = prev_pattern_b[line] << 4;
r = prev_pattern_r[line] << 4;
g = prev_pattern_g[line] << 4;
- } else if(line >= max_line) {
- b = prev_pattern_b[line] = 0;
- r = prev_pattern_r[line] = 0;
- g = prev_pattern_g[line] = 0;
} else {
- b = prev_pattern_b[line] = pattern_b[line];
- r = prev_pattern_r[line] = pattern_r[line];
- g = prev_pattern_g[line] = pattern_g[line];
+ b = prev_pattern_b[line] = pattern_b[line % max_line];
+ r = prev_pattern_r[line] = pattern_r[line % max_line];
+ g = prev_pattern_g[line] = pattern_g[line % max_line];
}
if(reverse) {
b = (!(col & 1)) ? 0xff : ~b;
void reset();
void write_io8(uint32_t addr, uint32_t data);
uint32_t read_io8(uint32_t addr);
+#ifdef USE_DEBUGGER
+ bool is_debugger_available()
+ {
+ return true;
+ }
+ uint64_t get_debug_data_addr_space()
+ {
+ return EMM_BUFFER_SIZE;
+ }
+ void write_debug_data8(uint32_t addr, uint32_t data)
+ {
+ if(addr < EMM_BUFFER_SIZE) {
+ data_buffer[addr] = data;
+ }
+ }
+ uint32_t read_debug_data8(uint32_t addr)
+ {
+ if(addr < EMM_BUFFER_SIZE) {
+ return data_buffer[addr];
+ }
+ return 0;
+ }
+#endif
bool process_state(FILEIO* state_fio, bool loading);
};
#include "io_wait_hireso.h"
#endif
#include "display.h"
+#ifdef USE_DEBUGGER
+#include "../debugger.h"
+#endif
namespace X1 {
{
prev_clock = vram_wait_index = 0;
column40 = true;
+#ifdef USE_DEBUGGER
+ d_debugger->set_device_name(_T("Debugger (I/O Bus)"));
+ d_debugger->set_context_mem(this);
+ d_debugger->set_context_io(vm->dummy);
+#endif
}
void IOBUS::reset()
{
memset(vram, 0, sizeof(vram));
- vram_b = vram + 0x0000;
- vram_r = vram + 0x4000;
- vram_g = vram + 0x8000;
+ vram_ofs_b = 0x0000;
+ vram_ofs_r = 0x4000;
+ vram_ofs_g = 0x8000;
vram_mode = signal = false;
vdisp = 0;
#ifdef _X1TURBO_FEATURE
return read_port8(addr, true, wait);
}
+void IOBUS::write_via_debugger_data8(uint32_t addr, uint32_t data)
+{
+ vram[addr] = data;
+}
+
+uint32_t IOBUS::read_via_debugger_data8(uint32_t addr)
+{
+ return vram[addr];
+}
+
void IOBUS::write_port8(uint32_t addr, uint32_t data, bool is_dma, int* wait)
{
// vram access
switch(addr & 0xc000) {
case 0x0000:
if(vram_mode) {
- vram_b[addr & 0x3fff] = data;
- vram_r[addr & 0x3fff] = data;
- vram_g[addr & 0x3fff] = data;
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ d_debugger->write_via_debugger_data8(vram_ofs_b + (addr & 0x3fff), data);
+ d_debugger->write_via_debugger_data8(vram_ofs_r + (addr & 0x3fff), data);
+ d_debugger->write_via_debugger_data8(vram_ofs_g + (addr & 0x3fff), data);
+ } else
+#endif
+ {
+ this->write_via_debugger_data8(vram_ofs_b + (addr & 0x3fff), data);
+ this->write_via_debugger_data8(vram_ofs_r + (addr & 0x3fff), data);
+ this->write_via_debugger_data8(vram_ofs_g + (addr & 0x3fff), data);
+ }
*wait = get_vram_wait();
return;
}
break;
case 0x4000:
if(vram_mode) {
- vram_r[addr & 0x3fff] = data;
- vram_g[addr & 0x3fff] = data;
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ d_debugger->write_via_debugger_data8(vram_ofs_r + (addr & 0x3fff), data);
+ d_debugger->write_via_debugger_data8(vram_ofs_g + (addr & 0x3fff), data);
+ } else
+#endif
+ {
+ this->write_via_debugger_data8(vram_ofs_r + (addr & 0x3fff), data);
+ this->write_via_debugger_data8(vram_ofs_g + (addr & 0x3fff), data);
+ }
} else {
- vram_b[addr & 0x3fff] = data;
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ d_debugger->write_via_debugger_data8(vram_ofs_b + (addr & 0x3fff), data);
+ } else
+#endif
+ {
+ this->write_via_debugger_data8(vram_ofs_b + (addr & 0x3fff), data);
+ }
}
*wait = get_vram_wait();
return;
case 0x8000:
if(vram_mode) {
- vram_b[addr & 0x3fff] = data;
- vram_g[addr & 0x3fff] = data;
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ d_debugger->write_via_debugger_data8(vram_ofs_b + (addr & 0x3fff), data);
+ d_debugger->write_via_debugger_data8(vram_ofs_g + (addr & 0x3fff), data);
+ } else
+#endif
+ {
+ this->write_via_debugger_data8(vram_ofs_b + (addr & 0x3fff), data);
+ this->write_via_debugger_data8(vram_ofs_g + (addr & 0x3fff), data);
+ }
} else {
- vram_r[addr & 0x3fff] = data;
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ d_debugger->write_via_debugger_data8(vram_ofs_r + (addr & 0x3fff), data);
+ } else
+#endif
+ {
+ this->write_via_debugger_data8(vram_ofs_r + (addr & 0x3fff), data);
+ }
}
*wait = get_vram_wait();
return;
case 0xc000:
if(vram_mode) {
- vram_b[addr & 0x3fff] = data;
- vram_r[addr & 0x3fff] = data;
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ d_debugger->write_via_debugger_data8(vram_ofs_b + (addr & 0x3fff), data);
+ d_debugger->write_via_debugger_data8(vram_ofs_r + (addr & 0x3fff), data);
+ } else
+#endif
+ {
+ this->write_via_debugger_data8(vram_ofs_b + (addr & 0x3fff), data);
+ this->write_via_debugger_data8(vram_ofs_r + (addr & 0x3fff), data);
+ }
} else {
- vram_g[addr & 0x3fff] = data;
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ d_debugger->write_via_debugger_data8(vram_ofs_g + (addr & 0x3fff), data);
+ } else
+#endif
+ {
+ this->write_via_debugger_data8(vram_ofs_g + (addr & 0x3fff), data);
+ }
}
*wait = get_vram_wait();
return;
#ifdef _X1TURBO_FEATURE
if(addr == 0x1fd0) {
int ofs = (data & 0x10) ? 0xc000 : 0;
- vram_b = vram + 0x0000 + ofs;
- vram_r = vram + 0x4000 + ofs;
- vram_g = vram + 0x8000 + ofs;
+ vram_ofs_b = 0x0000 + ofs;
+ vram_ofs_r = 0x4000 + ofs;
+ vram_ofs_g = 0x8000 + ofs;
} else if((addr & 0xff0f) == 0x1800) {
crtc_ch = data;
} else if((addr & 0xff0f) == 0x1801 && crtc_ch < 18) {
switch(addr & 0xc000) {
case 0x4000:
*wait = get_vram_wait();
- return vram_b[addr & 0x3fff];
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ return d_debugger->read_via_debugger_data8(vram_ofs_b + (addr & 0x3fff));
+ }
+#endif
+ return this->read_via_debugger_data8(vram_ofs_b + (addr & 0x3fff));
case 0x8000:
*wait = get_vram_wait();
- return vram_r[addr & 0x3fff];
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ return d_debugger->read_via_debugger_data8(vram_ofs_r + (addr & 0x3fff));
+ }
+#endif
+ return this->read_via_debugger_data8(vram_ofs_r + (addr & 0x3fff));
case 0xc000:
*wait = get_vram_wait();
- return vram_g[addr & 0x3fff];
+#ifdef USE_DEBUGGER
+ if(d_debugger->now_device_debugging) {
+ return d_debugger->read_via_debugger_data8(vram_ofs_g + (addr & 0x3fff));
+ }
+#endif
+ return this->read_via_debugger_data8(vram_ofs_g + (addr & 0x3fff));
}
uint32_t val = is_dma ? d_io->read_dma_io8(addr) : d_io->read_io8(addr);;
if((addr & 0xff0f) == 0x1a01) {
state_fio->StateArray(vram, sizeof(vram), 1);
state_fio->StateValue(vram_mode);
state_fio->StateValue(signal);
- if(loading) {
- intptr_t _v = (intptr_t)vram;
- vram_b = (uint8_t*)(_v + state_fio->FgetInt32_LE());
- vram_r = (uint8_t*)(_v + state_fio->FgetInt32_LE());
- vram_g = (uint8_t*)(_v + state_fio->FgetInt32_LE());
- } else {
- intptr_t _v = (intptr_t)vram;
- intptr_t _b = (intptr_t)vram_b;
- intptr_t _r = (intptr_t)vram_r;
- intptr_t _g = (intptr_t)vram_g;
-
- state_fio->FputInt32_LE((int)(_b - _v));
- state_fio->FputInt32_LE((int)(_r - _v));
- state_fio->FputInt32_LE((int)(_g - _v));
- }
+ state_fio->StateValue(vram_ofs_b);
+ state_fio->StateValue(vram_ofs_r);
+ state_fio->StateValue(vram_ofs_g);
state_fio->StateValue(vdisp);
state_fio->StateValue(prev_clock);
state_fio->StateValue(vram_wait_index);
#define SIG_IOBUS_MODE 0
+#ifdef USE_DEBUGGER
+class DEBUGGER;
+#endif
+
namespace X1 {
class IOBUS : public DEVICE
{
private:
DEVICE *d_cpu, *d_display, *d_io;
+#ifdef USE_DEBUGGER
+ DEBUGGER *d_debugger;
+#endif
// vram
#ifdef _X1TURBO_FEATURE
#endif
bool vram_mode, signal;
- uint8_t* vram_b;
- uint8_t* vram_r;
- uint8_t* vram_g;
- int vramptr_b;
- int vramptr_r;
- int vramptr_g;
+ int vram_ofs_b;
+ int vram_ofs_r;
+ int vram_ofs_g;
+
uint8_t vdisp;
uint32_t prev_clock, vram_wait_index;
public:
IOBUS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
{
- set_device_name(_T("I/O Bus"));
+ set_device_name(_T("I/O Bus (VRAM)"));
}
~IOBUS() {}
uint32_t read_io8w(uint32_t addr, int* wait);
void write_dma_io8w(uint32_t addr, uint32_t data, int* wait);
uint32_t read_dma_io8w(uint32_t addr, int* wait);
+ // for debugging vram
+ void write_via_debugger_data8(uint32_t addr, uint32_t data);
+ uint32_t read_via_debugger_data8(uint32_t addr);
+#ifdef USE_DEBUGGER
+ bool is_debugger_available()
+ {
+ return true;
+ }
+ void *get_debugger()
+ {
+ return d_debugger;
+ }
+ uint64_t get_debug_data_addr_space()
+ {
+ return sizeof(vram);
+ }
+ void write_debug_data8(uint32_t addr, uint32_t data)
+ {
+ if(addr < sizeof(vram)) {
+ write_via_debugger_data8(addr, data);
+ }
+ }
+ uint32_t read_debug_data8(uint32_t addr)
+ {
+ if(addr < sizeof(vram)) {
+ return read_via_debugger_data8(addr);
+ }
+ return 0;
+ }
+#endif
bool process_state(FILEIO* state_fio, bool loading);
// unique functions
{
return vram;
}
+#ifdef USE_DEBUGGER
+ void set_context_debugger(DEBUGGER* device)
+ {
+ d_debugger = device;
+ }
+#endif
};
}
for(int drv = 0; drv < USE_HARD_DISK; drv++) {
sasi_hdd[drv >> 1]->set_disk_handler(drv & 1, new HARDDISK(emu));
}
-// psg = new YM2203(this, emu);
psg = new AY_3_891X(this, emu);
+#ifdef USE_DEBUGGER
+ psg->set_context_debugger(new DEBUGGER(this, emu));
+#endif
cpu = new Z80(this, emu);
ctc = new Z80CTC(this, emu);
sio = new Z80SIO(this, emu);
if(sound_type >= 1) {
opm1 = new YM2151(this, emu);
opm1->set_device_name(_T("YM2151 OPM (CZ-8BS1 #1)"));
+#ifdef USE_DEBUGGER
+ opm1->set_context_debugger(new DEBUGGER(this, emu));
+#endif
ctc1 = new Z80CTC(this, emu);
ctc1->set_device_name(_T("Z80 CTC (CZ-8BS1 #1)"));
}
if(sound_type == 2) {
opm2 = new YM2151(this, emu);
opm2->set_device_name(_T("YM2151 OPM (CZ-8BS1 #2)"));
+#ifdef USE_DEBUGGER
+ opm2->set_context_debugger(new DEBUGGER(this, emu));
+#endif
ctc2 = new Z80CTC(this, emu);
ctc2->set_device_name(_T("Z80 CTC (CZ-8BS1 #2)"));
}
}
#ifdef _X1TURBO_FEATURE
dma = new Z80DMA(this, emu);
+#ifdef USE_DEBUGGER
+ dma->set_context_debugger(new DEBUGGER(this, emu));
+#endif
#endif
display = new DISPLAY(this, emu);
iobus->set_context_cpu(cpu);
iobus->set_context_display(display);
iobus->set_context_io(io);
+#ifdef USE_DEBUGGER
+ iobus->set_context_debugger(new DEBUGGER(this, emu));
+#endif
joy->set_context_psg(psg);
#ifdef _X1TURBO_FEATURE
memory->set_context_pio(pio);
for(DEVICE* device = first_device; device; device = device->next_device) {
device->reset();
}
+
+ // hack to force reset iei/oei
+#if 1
+ for(DEVICE* device = cpu; device; device = device->get_context_child()) {
+ device->reset();
+ }
+#else
+ cpu->get_context_child()->notify_intr_reti();
+ cpu->reset();
+#endif
+
pio->write_signal(SIG_I8255_PORT_B, 0x00, 0x08); // busy = low
psg->set_reg(0x2e, 0); // set prescaler
}
}
#endif
-#define STATE_VERSION 11
+#define STATE_VERSION 12
bool VM::process_state(FILEIO* state_fio, bool loading)
{