event->set_context_sound(seek_sound);
event->set_context_sound(head_down_sound);
event->set_context_sound(head_up_sound);
-
-
-/* pic 0 timer
- 1 keyboard
- 2 rs-232c
- 3 ex rs-232c
- 4 (option)
- 5 (option)
- 6 floppy drive or dma ???
- 7 (slave)
- 8 scsi
- 9 cd-rom controller
- 10 (option)
- 11 crtc vsync
- 12 printer
- 13 sound (OPN2 + ADPCM)
- 14 (option)
- 15 (reserve)
- nmi 0 keyboard (RAS)
- 1 extend slot
- dma 0 floppy drive
- 1 hard drive
- 2 printer
- 3 cd-rom controller
- dma 4 extend slot
- 5 (reserve)
- 6 (reserve)
- 7 (reserve)
-
-
-*/
-
-
pit0->set_context_ch0(timer, SIG_TIMER_CH0, 1);
pit0->set_context_ch1(timer, SIG_TIMER_CH1, 1);
pit0->set_constant_clock(1, 307200);
pit0->set_constant_clock(2, 307200);
pit1->set_constant_clock(1, 1228800);
- pic->set_context_cpu(cpu);
- fdc->set_context_drq(dma, SIG_UPD71071_CH0, 1);
+// 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, 0x80);
dma->set_context_child_dma(extra_dma);
floppy->set_context_fdc(fdc);
- floppy->set_context_pic(pic);
- keyboard->set_context_pic(pic);
sprite->set_context_vram(vram);
vram->set_context_sprite(sprite);
cdc->set_context_cdrom(cdrom);
cdc->set_context_scsi_host(cdc_scsi);
- cdc->set_context_dmareq_line(dma, SIG_UPD71071_CH3, 0xff);
-// cdc->set_context_pic(pic, SIG_I8259_CHIP1 | SIG_I8259_IR1);
+// cdc->set_context_dmaint_line(dma, SIG_UPD71071_CH3, 0xff);
- crtc->set_context_vsync(pic, SIG_I8259_CHIP1 | SIG_I8259_IR3, 0xffffffff); // VSYNC
adpcm->set_context_opn2(opn2);
adpcm->set_context_rf5c68(rf5c68);
adpcm->set_context_adc(adc);
- adpcm->set_context_pic(pic);
- adpcm->set_context_intr_line(pic, SIG_I8259_CHIP1 | SIG_I8259_IR5, 0xffffffff); // ADPCM AND OPN2
rf5c68->set_context_interrupt_boundary(adpcm, SIG_ADPCM_WRITE_INTERRUPT, 0xffffffff);
opn2->set_context_irq(adpcm, SIG_ADPCM_OPX_INTR, 0xffffffff);
adc->set_context_interrupt(adpcm, SIG_ADPCM_ADC_INTR, 0xffffffff);
scsi->set_context_dma(dma);
- scsi->set_context_pic(pic);
scsi->set_context_host(scsi_host);
+ scsi->set_context_pic(pic);
timer->set_context_pcm(beep);
- timer->set_context_pic(pic);
timer->set_context_rtc(rtc);
// cpu bus
#ifdef USE_DEBUGGER
cpu->set_context_debugger(new DEBUGGER(this, emu));
#endif
+ // Interrupts
+ // IRQ0 : TIMER
+ // IRQ1 : KEYBOARD
+ // IRQ2 : USART (ToDo)
+ // IRQ3 : EXTRA USART (ToDo)
+ // IRQ4 : EXTRA I/O (Maybe not implement)
+ // IRQ5 : EXTRA I/O (Maybe not implement)
+ // IRQ6 : FDC
+ // IRQ7 : Deisy chain (to IRQ8 - 15)
+ timer->set_context_intr_line(pic, SIG_I8259_CHIP0 | SIG_I8259_IR0, 0xffffffff);
+ keyboard->set_context_intr_line(pic, SIG_I8259_CHIP0 | SIG_I8259_IR1, 0xffffffff);
+ floppy->set_context_intr_line(pic, SIG_I8259_CHIP0 | SIG_I8259_IR6, 0xffffffff);
+
+ // IRQ8 : SCSI (-> scsi.cpp)
+ // IRQ9 : CDC
+ // IRQ10 : EXTRA I/O (Maybe not implement)
+ // IRQ11 : VSYNC
+ // IRQ12 : PRINTER (ToDo)
+ // IRQ13 : ADPCM AND OPN2 (Route to adpcm.cpp)
+ // IRQ14 : EXTRA I/O (Maybe not implement)
+ // IRQ15 : RESERVED.
+ cdc->set_context_dmaint_line(pic, SIG_I8259_CHIP1 | SIG_I8259_IR1, 0xffffffff);
+ cdc->set_context_mpuint_line(pic, SIG_I8259_CHIP1 | SIG_I8259_IR1, 0xffffffff);
+ crtc->set_context_vsync(pic, SIG_I8259_CHIP1 | SIG_I8259_IR3, 0xffffffff);
+ adpcm->set_context_intr_line(pic, SIG_I8259_CHIP1 | SIG_I8259_IR5, 0xffffffff);
+
+ // DMA0 : FDC/DRQ
+ // DMA1 : SCSI (-> scsi.cpp)
+ // DMA2 : PRINTER (ToDo)
+ // DMA3 : CDC
+ // EXTRA DMA0 : EXTRA SLOT (Maybe not implement)
+ // EXTRA DMA1 : Reserved
+ // EXTRA DMA2 : Reserved
+ // EXTRA DMA3 : Reserved
+ fdc->set_context_drq(dma, SIG_UPD71071_CH0, 1);
+ cdc->set_context_dmareq_line(dma, SIG_UPD71071_CH3, 0xff);
+
+ // NMI0 : KEYBOARD (RAS)
+ // NMI1 : Extra SLOT (Maybe not implement)
+ keyboard->set_context_nmi_line(memory, SIG_CPU_NMI, 0xffffffff);
// i/o bus
- io->set_iomap_alias_rw(0x00, pic, I8259_ADDR_CHIP0 | 0);
- io->set_iomap_alias_rw(0x02, pic, I8259_ADDR_CHIP0 | 1);
- io->set_iomap_alias_rw(0x10, pic, I8259_ADDR_CHIP1 | 0);
- io->set_iomap_alias_rw(0x12, pic, I8259_ADDR_CHIP1 | 1);
- io->set_iomap_single_rw(0x20, memory); // reset
- io->set_iomap_single_r(0x21, memory); // cpu misc
- io->set_iomap_single_w(0x22, memory); // power
- io->set_iomap_single_rw(0x24, memory); // dma
- io->set_iomap_single_r(0x25, memory); // cpu_misc4 (after Towns2)
- io->set_iomap_single_r(0x26, timer);
- io->set_iomap_single_r(0x27, timer);
- io->set_iomap_single_r(0x28, memory); // NMI MASK (after Towns2)
- io->set_iomap_single_r(0x30, memory); // cpu id
- io->set_iomap_single_r(0x31, memory); // cpu id
-
- io->set_iomap_single_rw(0x32, serialrom); // serial rom
-
- io->set_iomap_alias_rw(0x40, pit0, 0);
- io->set_iomap_alias_rw(0x42, pit0, 1);
- io->set_iomap_alias_rw(0x44, pit0, 2);
- io->set_iomap_alias_rw(0x46, pit0, 3);
- io->set_iomap_alias_rw(0x50, pit1, 0);
- io->set_iomap_alias_rw(0x52, pit1, 1);
- io->set_iomap_alias_rw(0x54, pit1, 2);
- io->set_iomap_alias_rw(0x56, pit1, 3);
-
- io->set_iomap_single_rw(0x60, timer);
- io->set_iomap_single_rw(0x68, timer); // Interval timer register2 (after Towns 10F).
- io->set_iomap_single_rw(0x6a, timer); // Interval timer register2 (after Towns 10F).
- io->set_iomap_single_rw(0x6b, timer); // Interval timer register2 (after Towns 10F).
- io->set_iomap_single_rw(0x6c, memory); // 1uS wait register (after Towns 10F).
-
- io->set_iomap_single_rw(0x70, timer);
- io->set_iomap_single_w(0x80, timer);
-
- io->set_iomap_range_rw(0xa0, 0xaf, dma);
- io->set_iomap_range_rw(0xb0, 0xbf, extra_dma);
-
- io->set_iomap_alias_rw(0x200, fdc, 0);
- io->set_iomap_alias_rw(0x202, fdc, 1);
- io->set_iomap_alias_rw(0x204, fdc, 2);
- io->set_iomap_alias_rw(0x206, fdc, 3);
- io->set_iomap_single_rw(0x208, floppy);
- io->set_iomap_single_rw(0x20c, floppy);
- io->set_iomap_single_rw(0x20e, floppy); // Towns drive SW
-
- io->set_iomap_single_rw(0x400, memory); // System Status
- io->set_iomap_single_rw(0x402, memory);
- io->set_iomap_single_rw(0x404, memory); // System status
- io->set_iomap_range_rw(0x406, 0x43f, memory);
-
- io->set_iomap_range_rw(0x440, 0x443, crtc); // CRTC
- io->set_iomap_range_rw(0x448, 0x44f, crtc); //
- io->set_iomap_single_rw(0x450, sprite); //
- io->set_iomap_single_rw(0x452, sprite); //
-
- io->set_iomap_range_rw(0x458, 0x45f, vram); // CRTC
-
- io->set_iomap_single_rw(0x480, memory); //
- io->set_iomap_single_rw(0x484, dictionary); // Dictionary
+ io->set_iomap_alias_rw (0x0000, pic, I8259_ADDR_CHIP0 | 0);
+ io->set_iomap_alias_rw (0x0002, pic, I8259_ADDR_CHIP0 | 1);
+ io->set_iomap_alias_rw (0x0010, pic, I8259_ADDR_CHIP1 | 0);
+ io->set_iomap_alias_rw (0x0012, pic, I8259_ADDR_CHIP1 | 1);
+
+ io->set_iomap_range_rw (0x0020, 0x0028, memory);
+ io->set_iomap_range_r (0x0030, 0x0031, memory); // cpu id / machine id
+ io->set_iomap_single_rw(0x0032, memory); // serial rom (routed from memory)
+
+ io->set_iomap_alias_rw(0x0040, pit0, 0);
+ io->set_iomap_alias_rw(0x0042, pit0, 1);
+ io->set_iomap_alias_rw(0x0044, pit0, 2);
+ io->set_iomap_alias_rw(0x0046, pit0, 3);
+ io->set_iomap_alias_rw(0x0050, pit1, 0);
+ io->set_iomap_alias_rw(0x0052, pit1, 1);
+ io->set_iomap_alias_rw(0x0054, pit1, 2);
+ io->set_iomap_alias_rw(0x0056, pit1, 3);
+
+ io->set_iomap_single_rw(0x0060, timer);
+ io->set_iomap_single_rw(0x0068, timer); // Interval timer register2 (after Towns 10F).
+ io->set_iomap_single_rw(0x006a, timer); // Interval timer register2 (after Towns 10F).
+ io->set_iomap_single_rw(0x006b, timer); // Interval timer register2 (after Towns 10F).
+ io->set_iomap_single_rw(0x006c, memory); // 1uS wait register (after Towns 10F).
+
+ io->set_iomap_single_rw(0x0070, timer); // RTC DATA
+ io->set_iomap_single_w (0x0080, timer); // RTC COMMAND
+
+ io->set_iomap_range_rw (0x00a0, 0x00af, dma);
+ io->set_iomap_range_rw (0x00b0, 0x00bf, extra_dma);
+
+ io->set_iomap_alias_rw (0x0200, fdc, 0); // STATUS/COMMAND
+ io->set_iomap_alias_rw (0x0202, fdc, 1); // TRACK
+ io->set_iomap_alias_rw (0x0204, fdc, 2); // SECTOR
+ io->set_iomap_alias_rw (0x0206, fdc, 3); // DATA
+ io->set_iomap_single_rw(0x0208, floppy); // DRIVE STATUS / DRIVE CONTROL
+ io->set_iomap_single_rw(0x020c, floppy); // DRIVE SELECT
+ io->set_iomap_single_rw(0x020e, floppy); // Towns drive SW
+
+ io->set_iomap_range_rw (0x0400, 0x0404, memory); // System Status
+ io->set_iomap_range_rw (0x0406, 0x403f, memory); // Reserved
+
+ io->set_iomap_range_rw(0x0440, 0x0443, crtc); // CRTC
+ io->set_iomap_range_rw(0x0448, 0x044f, crtc); // VIDEO OUT (CRTC)
+
+ io->set_iomap_range_rw(0x0450, 0x0452, sprite); // SPRITE
+
+ io->set_iomap_single_rw(0x0458, vram); // VRAM ACCESS CONTROLLER (ADDRESS)
+ io->set_iomap_range_rw (0x045a, 0x045f, vram); // VRAM ACCESS CONTROLLER (DATA)
+
+ io->set_iomap_single_rw(0x0480, sysrom); // MEMORY REGISTER
+ io->set_iomap_single_rw(0x0484, dictionary); // Dictionary
+
//io->set_iomap_alias_r(0x48a, memory_card, 0); //
//io->set_iomap_alias_rw(0x490, memory_card); // After Towns2
//io->set_iomap_alias_rw(0x491, memory_card); // After Towns2
- io->set_iomap_range_rw(0x4c0, 0x4cf, cdc); // CDROM
+ io->set_iomap_range_rw(0x04c0, 0x04cf, cdc); // CDROM
// PAD, Sound
#if 0
- io->set_iomap_alias_r(0x4d0, pad, 0); // Pad1
- io->set_iomap_alias_r(0x4d2, pad, 1); // Pad 2
- io->set_iomap_alias_rw(0x4d5, adpcm, 0); // mute
- io->set_iomap_alias_w(0x4d6, pad, 3); // Pad out
-#else
- io->set_iomap_alias_rw(0x4d5, adpcm, 0); // mute
+ io->set_iomap_single_r(0x04d0, pad); // Pad1
+ io->set_iomap_single_r(0x04d2, pad); // Pad 2
+ io->set_iomap_single_w(0x04d6, pad); // Pad out
#endif
+ io->set_iomap_single_rw(0x04d5, adpcm); // mute
// OPN2(YM2612)
- io->set_iomap_alias_rw(0x4d8, opn2, 0); // STATUS(R)/Addrreg 0(W)
- io->set_iomap_alias_w(0x4da, opn2, 1); // Datareg 0(W)
- io->set_iomap_alias_w(0x4dc, opn2, 2); // Addrreg 1(W)
- io->set_iomap_alias_w(0x4de, opn2, 3); // Datareg 1(W)
+ io->set_iomap_alias_rw(0x04d8, opn2, 0); // STATUS(R)/Addrreg 0(W)
+ io->set_iomap_alias_w (0x04da, opn2, 1); // Datareg 0(W)
+ io->set_iomap_alias_w (0x04dc, opn2, 2); // Addrreg 1(W)
+ io->set_iomap_alias_w (0x04de, opn2, 3); // Datareg 1(W)
// Electrical volume
-// io->set_iomap_alias_rw(0x4e0, e_volume[0], 0);
-// io->set_iomap_alias_rw(0x4e1, e_volume[0], 1);
-// io->set_iomap_alias_rw(0x4e2, e_volume[1], 0);
-// io->set_iomap_alias_rw(0x4e3, e_volume[1], 1);
+// io->set_iomap_alias_rw(0x04e0, e_volume[0], 0);
+// io->set_iomap_alias_rw(0x04e1, e_volume[0], 1);
+// io->set_iomap_alias_rw(0x04e2, e_volume[1], 0);
+// io->set_iomap_alias_rw(0x04e3, e_volume[1], 1);
// ADPCM
- io->set_iomap_range_w(0x4e7, 0x4ff, adpcm); //
-
- io->set_iomap_single_rw(0x5c0, memory); // NMI MASK
- io->set_iomap_single_r(0x5c2, memory); // NMI STATUS
- io->set_iomap_single_r(0x5c8, vram); // TVRAM EMULATION
- io->set_iomap_single_w(0x5ca, vram); // VSYNC INTERRUPT
-
- io->set_iomap_single_r(0x5e8, memory); // RAM capacity register.(later Towns1H/2H/1F/2F).
- io->set_iomap_single_r(0x5ec, memory); // RAM Wait register , ofcially after Towns2, but exists after Towns1H.
-
- io->set_iomap_single_rw(0x600, keyboard);
- io->set_iomap_single_rw(0x602, keyboard);
- io->set_iomap_single_rw(0x604, keyboard);
- //io->set_iomap_single_r(0x606, keyboard); // BufFul (After Towns2)
-
- //io->set_iomap_single_rw(0x800, printer);
- //io->set_iomap_single_rw(0x802, printer);
- //io->set_iomap_single_rw(0x804, printer);
-
- io->set_iomap_alias_rw(0xa00, sio, 0);
- io->set_iomap_alias_rw(0xa02, sio, 1);
-// io->set_iomap_single_r(0xa04, serial);
-// io->set_iomap_single_r(0xa06, serial);
-// io->set_iomap_single_w(0xa08, serial);
-// io->set_iomap_single_rw(0xa0a, modem);
-
- io->set_iomap_single_rw(0xc30, scsi);
- io->set_iomap_single_rw(0xc32, scsi);
+ io->set_iomap_range_rw(0x04e7, 0x04ef, adpcm); // A/D SAMPLING DATA REG
+ io->set_iomap_range_rw(0x04f0, 0x04ff, adpcm); // A/D SAMPLING DATA REG
+
+ io->set_iomap_single_rw(0x05c0, memory); // NMI MASK
+ io->set_iomap_single_r (0x05c2, memory); // NMI STATUS
+ io->set_iomap_single_r (0x05c8, vram); // TVRAM EMULATION
+ io->set_iomap_single_w (0x05ca, vram); // VSYNC INTERRUPT
+
+ io->set_iomap_single_rw(0x05e8, memory); // RAM capacity register.(later Towns1H/2H/1F/2F).
+ io->set_iomap_single_rw(0x05ec, memory); // RAM Wait register , ofcially after Towns2, but exists after Towns1H.
+
+ io->set_iomap_single_rw(0x0600, keyboard);
+ io->set_iomap_single_rw(0x0602, keyboard);
+ io->set_iomap_single_rw(0x0604, keyboard);
+ io->set_iomap_single_r (0x0606, keyboard); // BufFul (After Towns2)
+
+ //io->set_iomap_single_rw(0x0800, printer);
+ //io->set_iomap_single_rw(0x0802, printer);
+ //io->set_iomap_single_rw(0x0804, printer);
+
+ io->set_iomap_alias_rw (0x0a00, sio, 0);
+ io->set_iomap_alias_rw (0x0a02, sio, 1);
+// io->set_iomap_single_r (0x0a04, serial);
+// io->set_iomap_single_r (0x0a06, serial);
+// io->set_iomap_single_w (0x0a08, serial);
+// io->set_iomap_single_rw(0x0a0a, modem);
+
+ io->set_iomap_single_rw(0x0c30, scsi);
+ io->set_iomap_single_rw(0x0c32, scsi);
io->set_iomap_range_rw(0x3000, 0x3fff, dictionary); // CMOS
set_lines_per_frame(512);
//set_pixels_per_line(640);
+ set_vsync(vsync, true);
+
force_recalc_crtc_param();
// register_event(this, EVENT_CRTC_VSTART, vstart_us, false, &event_id_vstart);
}
+void TOWNS_CRTC::set_vsync(bool val, bool force)
+{
+ if((vsync != val) || (force)) {
+ write_signals(&outputs_int_vsync, (val) ? 0xffffffff : 0x00000000);
+ vsync = val;
+ }
+}
void TOWNS_CRTC::restart_display()
{
// ToDo
horiz_start_us[layer] = ((double)(regs[(layer << 1) + 9] & 0x07ff)) * crtc_clock ; // HDSx
horiz_end_us[layer] = ((double)(regs[(layer << 1) + 9 + 1] & 0x07ff)) * crtc_clock ; // HDEx
}
+#if 1
+ out_debug_log(_T("RECALC: CRTC_CLOCK=%f MHz FPS=%f"), 1.0 / crtc_clock, 1.0e6 / frame_us);
+ _TCHAR sdata[32 * 5];
+ _TCHAR sdata2[8];
+ for(int q = 0; q < 4; q++) {
+ memset(sdata, 0x00, sizeof(sdata));
+ for(int r = 0; r < 8; r++) {
+ my_sprintf_s(sdata2, 8, "%04X ", regs[r + q * 8]);
+ my_tcscat_s(sdata, sizeof(sdata) / sizeof(_TCHAR), sdata2);
+ }
+ out_debug_log(_T("RECALC: regs[%02d..%02d]= %s"), q * 8, q * 8 + 7, sdata);
+ }
+ out_debug_log(_T("RECALC: HORIZ_us=%f HORIZ_WIDTH_P_us=%f HORIZ_WIDTH_N_us=%f"), horiz_us, horiz_width_posi_us, horiz_width_nega_us);
+ out_debug_log(_T("RECALC: VERT_SYNC_PRE_us=%f VST2_us=%f EET_us=%f frame_us=%f"), vert_sync_pre_us, vst2_us, eet_us, frame_us);
+ for(int q = 0; q < 2; q++) {
+ out_debug_log(_T("RECALC: LAYER%d: VERT_START_us=%f VERT_END_us=%f HORIZ_START_us=%f HORIZ_END_us=%f"), q, vert_start_us[q], vert_end_us[q], horiz_start_us[q], horiz_end_us[q]);
+ }
+#endif
req_recalc = false;
}
}
break;
case 0x0448:
+ voutreg_num = data & 0x01;
+ break;
case 0x044a:
+ if(voutreg_num == 0) {
+ voutreg_ctrl = data & 0x10;
+ } else if(voutreg_num == 1) {
+ voutreg_prio = data & 0x10;
+ }
+ break;
case 0x044c:
+ break;
case 0xfd98:
case 0xfd99:
case 0xfd9a:
case 0xfd9d:
case 0xfd9e:
case 0xfd9f:
+ {
+ pair32_t n;
+ n.d = data;
+ if(addr == 0xfd9f) {
+ dpalette_regs[7] = n.b.l & 0x0f;
+ } else {
+ dpalette_regs[addr & 7] = n.b.l & 0x0f;
+ dpalette_regs[(addr + 1) & 7] = n.b.h & 0x0f;
+ }
+ dpalette_changed = true;
+ }
+ break;
case 0xfda0:
- write_io16(addr, data);
+ crtout[0] = ((data & 0x0c) != 0) ? true : false;
+ crtout[1] = ((data & 0x03) != 0) ? true : false;
break;
}
}
void TOWNS_CRTC::write_io16(uint32_t addr, uint32_t data)
{
// out_debug_log(_T("WRITE16 ADDR=%04x DATA=%04x"), addr, data);
- switch(addr) {
- case 0x0440:
- case 0x0441:
- crtc_ch = data & 0x1f;
- break;
+ switch(addr & 0xfffe) {
case 0x0442:
- case 0x0443:
{
if(crtc_ch < 32) {
if((crtc_ch < 0x09) && ((crtc_ch >= 0x04) || (crtc_ch <= 0x01))) { // HSW1..VST
}
}
break;
- case 0x0448:
- case 0x0449:
- voutreg_num = data & 0x01;
- break;
- case 0x044a:
- case 0x044b:
- if(voutreg_num == 0) {
- voutreg_ctrl = data & 0x10;
- } else if(voutreg_num == 1) {
- voutreg_prio = data & 0x10;
- }
- break;
- case 0x044c:
- break;
- case 0xfd98:
- case 0xfd99:
- case 0xfd9a:
- case 0xfd9b:
- case 0xfd9c:
- case 0xfd9d:
- case 0xfd9e:
- case 0xfd9f:
- {
- pair32_t n;
- n.d = data;
- if(addr == 0xfd9f) {
- dpalette_regs[7] = n.b.l & 0x0f;
- } else {
- dpalette_regs[addr & 7] = n.b.l & 0x0f;
- dpalette_regs[(addr + 1) & 7] = n.b.h & 0x0f;
- }
- dpalette_changed = true;
- }
- break;
- case 0xfda0:
- crtout[0] = ((data & 0x0c) != 0) ? true : false;
- crtout[1] = ((data & 0x03) != 0) ? true : false;
- break;
+ default:
+ write_io8(addr & 0xfffe, data);
}
}
uint32_t TOWNS_CRTC::read_io16(uint32_t addr)
{
// out_debug_log(_T("READ16 ADDR=%04x"), addr);
- switch(addr) {
- case 0x0440:
- case 0x0441:
- return (uint32_t)crtc_ch;
- break;
+ switch(addr & 0xfffe) {
case 0x0442:
- case 0x0443:
if(crtc_ch == 30) {
return (uint32_t)read_reg30();
} else {
return regs[crtc_ch];
}
break;
- case 0x044c:
- case 0x044d:
- {
- uint16_t d = 0xff7c;
- d = d | ((dpalette_changed) ? 0x80 : 0x00);
- if(d_sprite != NULL) {
- d = d | ((d_sprite->read_signal(SIG_TOWNS_SPRITE_BUSY) != 0) ? 0x02 : 0x00);
- }
- d = d | ((sprite_disp_page != 0) ? 0x01 : 0x00);
- dpalette_changed = false;
- return d;
- }
- break;
- case 0xfd98:
- case 0xfd99:
- case 0xfd9a:
- case 0xfd9b:
- case 0xfd9c:
- case 0xfd9d:
- case 0xfd9e:
- case 0xfd9f:
- {
- pair16_t n;
- if(addr == 0xfd9f) {
- n.b.l = dpalette_regs[7];
- n.b.h = 0xff;
- } else {
- n.b.l = dpalette_regs[addr & 0x07];
- n.b.h = dpalette_regs[(addr + 1) & 0x07];
- }
- return n.w;
- }
- break;
- case 0xfda0:
- {
- uint16_t d = 0xfffc;
- d = d | ((vsync) ? 0x01 : 0);
- d = d | ((hsync) ? 0x02 : 0);
- return d;
- }
+ default:
+ return read_io8(addr & 0xfffe);
break;
}
return 0xffff;
return (uint32_t)(d.b.h);
}
break;
+ case 0x044c:
+ {
+ uint16_t d = 0x7c;
+ d = d | ((dpalette_changed) ? 0x80 : 0x00);
+ if(d_sprite != NULL) {
+ d = d | ((d_sprite->read_signal(SIG_TOWNS_SPRITE_BUSY) != 0) ? 0x02 : 0x00);
+ }
+ d = d | ((sprite_disp_page != 0) ? 0x01 : 0x00);
+ dpalette_changed = false;
+ return d;
+ }
+ break;
case 0xfd98:
case 0xfd99:
case 0xfd9a:
int xx = pwidth & ~15;
int w = pwidth & 15;
for(int i = 0; i < w; i++) {
- pbuf[i] = p++;
+ pbuf[i] = *p++;
}
for(int i = 0; i < w; i++) {
lbuffer1[xx++] = apal256[pbuf[i]];
event_id_vst2 = -1;
}
if(vert_sync_pre_us > 0.0) {
- vsync = false;
+ set_vsync(false, true);
register_event(this, EVENT_CRTC_VST1, vert_sync_pre_us, false, &event_id_vst1); // VST1
} else {
- vsync = true;
+ set_vsync(true, true);
}
if(vst2_us > 0.0) {
register_event(this, EVENT_CRTC_VST2, vst2_us, false, &event_id_vst2);
int eid2 = (event_id / 2) * 2;
// EVENT_VSTART MOVED TO event_frame().
if(event_id == EVENT_CRTC_VST1) { // VSYNC
- vsync = true;
+ set_vsync(true, false);
event_id_vst1 = -1;
} else if (event_id == EVENT_CRTC_VST2) {
- vsync = false;
+ set_vsync(false, false);
event_id_vst2 = -1;
} else if(eid2 == EVENT_CRTC_VDS) { // Display start
int layer = event_id & 1;
if(loading) {
for(int i = 0; i < 4; i++) {
if(linebuffers[i] == NULL) {
- linebuffers[i] = malloc(sizeof(linebuffer_t ) * TOWNS_CRTC_MAX_LINES);
+ linebuffers[i] = (linebuffer_t*)malloc(sizeof(linebuffer_t ) * TOWNS_CRTC_MAX_LINES);
}
for(int l = 0; l < TOWNS_CRTC_MAX_LINES; l++) {
memset(&(linebuffers[i][l]), 0x00, sizeof(linebuffer_t));
#include "../pcm1bit.h"
namespace FMTOWNS {
-#define EVENT_1US_WAIT 1
+#define EVENT_1US_WAIT 1
+#define EVENT_1US_FREERUN 2
void TOWNS_MEMORY::config_page00()
{
// load rom image
// ToDo: More smart.
vram_size = 0x80000; // OK?
+ event_freerun = -1;
}
void TOWNS_MEMORY::set_wait_values()
{
// reset memory
// ToDo
- d_cpu->set_address_mask(0xffffffff);
+ if(d_cpu != NULL) {
+ d_cpu->set_address_mask(0xffffffff);
+ }
dma_is_vram = true;
nmi_vector_protect = false;
config_page00();
set_wait_values();
+ freerun_counter = 0;
+ if(event_freerun > -1) cancel_event(this, event_freerun);
+ register_event(this, EVENT_1US_FREERUN, 1.0, true, &event_freerun);
+
}
uint32_t TOWNS_MEMORY::read_data8(uint32_t addr)
switch(addr & 0xffff) {
case 0x0020: // Software reset ETC.
// reset cause register
- val = ((software_reset) ? 1 : 0) | ((d_cpu->get_shutdown_flag() != 0) ? 2 : 0);
+ if(d_cpu != NULL) {
+ val = ((software_reset) ? 1 : 0) | ((d_cpu->get_shutdown_flag() != 0) ? 2 : 0);
+ }
software_reset = false;
- d_cpu->set_shutdown_flag(0);
+ if(d_cpu != NULL) {
+ d_cpu->set_shutdown_flag(0);
+ }
val = val | 0x7c;
break;
case 0x0022:
// Power register
val = 0xff;
break;
+ case 0x0026:
+ {
+ pair16_t n;
+ n.w = freerun_counter;
+ val = n.b.l;
+ }
+ break;
+ case 0x0027:
+ {
+ pair16_t n;
+ n.w = freerun_counter;
+ val = n.b.l;
+ }
+ break;
case 0x0030:
val = (((machine_id & 0x1f) << 3) | (cpu_id & 7));
// SPEED: bit0/Write
return val;
}
+uint32_t TOWNS_MEMORY::read_io16(uint32_t addr)
+{
+ switch(addr & 0xfffe) {
+ case 0x0026:
+ return freerun_counter;
+ break;
+ default:
+ {
+ // OK?
+ pair16_t n;
+ n.b.l = read_io8((addr & 0xfffe) + 0);
+ n.b.h = read_io8((addr & 0xfffe) + 1);
+ return n.w;
+ }
+ break;
+ }
+ return 0xffff;
+}
+
void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
{
software_reset = false;
}
if((data & 0x40) != 0) {
- d_cpu->set_shutdown_flag(1);
+ if(d_cpu != NULL) {
+ d_cpu->set_shutdown_flag(1);
+ }
emu->power_off();
}
if(software_reset) {
- d_cpu->reset();
+ if(d_cpu != NULL) {
+ d_cpu->reset();
+ }
}
- switch(data & 0x08) {
- case 0x00: // 20bit
- d_cpu->set_address_mask(0xffffffff);
- break;
- default: // 32bit
- d_cpu->set_address_mask(0x000fffff);
- break;
+ if(d_cpu != NULL) {
+ switch(data & 0x08) {
+ case 0x00: // 20bit
+ d_cpu->set_address_mask(0xffffffff);
+ break;
+ default: // 32bit
+ d_cpu->set_address_mask(0x000fffff);
+ break;
+ }
}
break;
case 0x0022:
if((data & 0x40) != 0) {
- d_cpu->set_shutdown_flag(1);
+ if(d_cpu != NULL) {
+ d_cpu->set_shutdown_flag(1);
+ }
emu->power_off();
}
// Power register
if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
if(event_wait_1us != -1) cancel_event(this, event_wait_1us);
register_event(this, EVENT_1US_WAIT, 1.0, false, &event_wait_1us);
- d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
+ if(d_cpu != NULL) {
+ d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
+ }
}
break;
case 0x0404: // System Status Reg.
void TOWNS_MEMORY::event_callback(int id, int err)
{
switch(id) {
+ case EVENT_1US_FREERUN:
+ freerun_counter++;
+ break;
case EVENT_1US_WAIT:
event_wait_1us = -1;
if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
- d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
+ if(d_cpu != NULL) {
+ d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
+ }
}
break;
default:
break;
case 0x18:
if(d_beep != NULL) {
- //d_beep->write_signal(SIG_BEEP_ON, 1, 1);
+ d_beep->write_signal(SIG_PCM1BIT_ON, 1, 1);
}
break;
case 0x19:
break;
case 0x18:
if(d_beep != NULL) {
- //d_beep->write_signal(SIG_BEEP_ON, 0, 1);
+ d_beep->write_signal(SIG_PCM1BIT_ON, 0, 1);
}
break;
case 0x19:
{
if(ch == SIG_MEMORY_EXTNMI) {
extra_nmi_val = ((data & mask) != 0);
+ if(!(extra_nmi_mask)) {
+ // Not MASK
+ if(d_cpu != NULL) {
+ d_cpu->write_signal(SIG_CPU_NMI, data, mask);
+ }
+ }
} else if(ch == SIG_CPU_NMI) {
// Check protect
- d_cpu->write_signal(SIG_CPU_NMI, data, mask);
+ if(d_cpu != NULL) {
+ d_cpu->write_signal(SIG_CPU_NMI, data, mask);
+ }
} else if(ch == SIG_CPU_IRQ) {
- d_cpu->write_signal(SIG_CPU_IRQ, data, mask);
+ if(d_cpu != NULL) {
+ d_cpu->write_signal(SIG_CPU_IRQ, data, mask);
+ }
} else if(ch == SIG_CPU_BUSREQ) {
- d_cpu->write_signal(SIG_CPU_BUSREQ, data, mask);
+ if(d_cpu != NULL) {
+ d_cpu->write_signal(SIG_CPU_BUSREQ, data, mask);
+ }
} else if(ch == SIG_I386_A20) {
- d_cpu->write_signal(SIG_I386_A20, data, mask);
+ if(d_cpu != NULL) {
+ d_cpu->write_signal(SIG_I386_A20, data, mask);
+ }
} else if(ch == SIG_FMTOWNS_RAM_WAIT) {
mem_wait_val = (int)data;
set_wait_values();
}
return 0;
}
+
+void TOWNS_MEMORY::set_intr_line(bool line, bool pending, uint32_t bit)
+{
+ if(d_cpu != NULL) {
+ d_cpu->set_intr_line(line, pending, bit);
+ }
+}
+
// ToDo: DMA
#define STATE_VERSION 1
state_fio->StateValue(software_reset);
state_fio->StateValue(event_wait_1us);
+ state_fio->StateValue(event_freerun);
+ state_fio->StateValue(freerun_counter);
+
state_fio->StateValue(extra_nmi_val);
state_fio->StateValue(extra_nmi_mask);