diff options
author | Juergen Buchmueller <pullmoll@t-online.de> | 2016-08-19 22:05:12 +0200 |
---|---|---|
committer | Juergen Buchmueller <pullmoll@t-online.de> | 2016-08-19 22:09:27 +0200 |
commit | 0b89614f16eca16406262ac728a4033761bf0523 (patch) | |
tree | 0bd6fd6ccc54b94df5cdc375b1cf5445f52cbe10 | |
parent | fe29ea1c765f6fd60b9c20b7ba3f9ee114d3f987 (diff) |
alto2: Refactor videotiming + use attoseconds_t
Use MAME's type attoseconds_t and handle the timing accus in
attoseconds instead of nanoseconds.
Try to solve the video timing issues by using an emu_timer running
at the field rate of 60Hz, which the video state machine synchronizes to.
-rw-r--r-- | src/devices/cpu/alto2/a2disk.cpp | 8 | ||||
-rw-r--r-- | src/devices/cpu/alto2/a2disk.h | 2 | ||||
-rw-r--r-- | src/devices/cpu/alto2/a2disp.cpp | 68 | ||||
-rw-r--r-- | src/devices/cpu/alto2/a2disp.h | 38 | ||||
-rw-r--r-- | src/devices/cpu/alto2/a2dwt.cpp | 10 | ||||
-rw-r--r-- | src/devices/cpu/alto2/alto2cpu.cpp | 80 | ||||
-rw-r--r-- | src/devices/cpu/alto2/alto2cpu.h | 9 | ||||
-rw-r--r-- | src/mame/drivers/alto2.cpp | 35 |
8 files changed, 135 insertions, 115 deletions
diff --git a/src/devices/cpu/alto2/a2disk.cpp b/src/devices/cpu/alto2/a2disk.cpp index c4658726492..0d0d43c0ceb 100644 --- a/src/devices/cpu/alto2/a2disk.cpp +++ b/src/devices/cpu/alto2/a2disk.cpp @@ -1638,8 +1638,8 @@ void alto2_cpu_device::next_sector(int unit) { diablo_hd_device* dhd = m_drive[unit]; LOG((this,LOG_DISK,0,"%s dhd=%p\n", __FUNCTION__, dhd)); - // get bit time in pico seconds - m_dsk.bitclk_time[unit] = static_cast<int>(dhd->bit_time().as_attoseconds() / 1000000); + // get bit time in attoseconds + m_dsk.bitclk_time[unit] = dhd->bit_time().as_attoseconds(); if (m_bitclk_time >= 0) { LOG((this,LOG_DISK,0," unit #%d stop bitclk\n", unit)); m_bitclk_time = -1; @@ -1796,8 +1796,8 @@ void alto2_cpu_device::reset_disk() m_dsk.strobe = 0; m_dsk.strobon_timer->reset(); m_dsk.bitclk = 0; - m_dsk.bitclk_time[0] = static_cast<int>(attotime::from_nsec(300).as_attoseconds() / 1000000); - m_dsk.bitclk_time[1] = static_cast<int>(attotime::from_nsec(300).as_attoseconds() / 1000000); + m_dsk.bitclk_time[0] = attotime::from_nsec(300).as_attoseconds(); + m_dsk.bitclk_time[1] = attotime::from_nsec(300).as_attoseconds(); m_dsk.datin = 0; m_dsk.bitcount = 0; m_dsk.seclate = 0; diff --git a/src/devices/cpu/alto2/a2disk.h b/src/devices/cpu/alto2/a2disk.h index a3f8c7755fc..e000ad7cfc4 100644 --- a/src/devices/cpu/alto2/a2disk.h +++ b/src/devices/cpu/alto2/a2disk.h @@ -37,7 +37,7 @@ struct { UINT8 strobe; //!< strobe (still) active emu_timer* strobon_timer; //!< set strobe on timer UINT8 bitclk; //!< current bitclk state (either crystal clock, or rdclk from the drive) - int bitclk_time[2]; //!< per drive time in clocks per bit + attoseconds_t bitclk_time[2]; //!< per drive time in attoseconds per bit UINT8 datin; //!< current datin from the drive UINT8 bitcount; //!< bit counter UINT8 carry; //!< carry output of the bitcounter diff --git a/src/devices/cpu/alto2/a2disp.cpp b/src/devices/cpu/alto2/a2disp.cpp index f2c5b06a77f..df8ac15f3a5 100644 --- a/src/devices/cpu/alto2/a2disp.cpp +++ b/src/devices/cpu/alto2/a2disp.cpp @@ -245,11 +245,13 @@ static const UINT16 double_bits[256] = { //! update the internal frame buffer and draw the scanline segment if changed void alto2_cpu_device::update_framebuf_word(UINT16* framebuf, int x, int y, UINT16 word) { + if (y >= A2_DISP_TOTAL_HEIGHT) + return; int xpword = (m_dsp.xpreg ^ 01777) / 16; // mixing with the cursor if (x == xpword++) word ^= (m_dsp.csr << (m_dsp.xpreg % 16)) >> 16; - if (x == xpword) + if (x == xpword) word ^= (m_dsp.csr << (m_dsp.xpreg % 16)) & 0xffff; // no change? if (word == framebuf[x]) @@ -266,12 +268,11 @@ void alto2_cpu_device::unload_word() int x = m_unload_word; int y = m_dsp.scanline; - if (y < 0 || y >= ALTO2_DISPLAY_TOTAL_HEIGHT || x >= ALTO2_DISPLAY_VISIBLE_WORDS) - { + if (x >= A2_DISP_VISIBLE_WORDS) { m_unload_time = -1; return; } - UINT16* framebuf = m_dsp.framebuf.get() + y * ALTO2_DISPLAY_SCANLINE_WORDS; + UINT16* framebuf = m_dsp.framebuf.get() + y * A2_DISP_SCANLINE_WORDS; UINT16 word = m_dsp.inverse; UINT8 a38 = m_disp_a38[m_dsp.ra * 16 + m_dsp.wa]; if (FIFO_MBEMPTY(a38)) @@ -281,9 +282,9 @@ void alto2_cpu_device::unload_word() else { word ^= m_dsp.fifo[m_dsp.ra]; - m_dsp.ra = (m_dsp.ra + 1) % ALTO2_DISPLAY_FIFO; + m_dsp.ra = (m_dsp.ra + 1) % A2_DISP_FIFO; LOG((this,LOG_DISPL,3, " DSP pull %04x from FIFO[%02o] y:%d x:%d\n", - word, (m_dsp.ra - 1) & (ALTO2_DISPLAY_FIFO - 1), y, x)); + word, (m_dsp.ra - 1) & (A2_DISP_FIFO - 1), y, x)); } if (m_dsp.halfclock) @@ -291,21 +292,21 @@ void alto2_cpu_device::unload_word() const UINT16 word1 = double_bits[word / 256]; update_framebuf_word(framebuf, x, y, word1); x++; - if (x < ALTO2_DISPLAY_VISIBLE_WORDS) + if (x < A2_DISP_VISIBLE_WORDS) { const UINT16 word2 = double_bits[word % 256]; update_framebuf_word(framebuf, x, y, word2); x++; } - m_unload_time += ALTO2_DISPLAY_BITTIME(32); + m_unload_time += A2_DISP_BITTIME(32); } else { update_framebuf_word(framebuf, x, y, word); x++; - m_unload_time += ALTO2_DISPLAY_BITTIME(16); + m_unload_time += A2_DISP_BITTIME(16); } - if (x < ALTO2_DISPLAY_VISIBLE_WORDS) + if (x < A2_DISP_VISIBLE_WORDS) m_unload_word = x; else m_unload_time = -1; @@ -330,13 +331,11 @@ void alto2_cpu_device::display_state_machine() { // count horizontal line counters and wrap m_dsp.hlc += 1; - if (m_dsp.hlc > ALTO2_DISPLAY_HLC_END) { - m_dsp.hlc = ALTO2_DISPLAY_HLC_START; - m_dsp.scanline = 30; - m_dsp.vsync = true; + if (m_dsp.hlc > A2_DISP_HLC_END) { + m_dsp.hlc = A2_DISP_HLC_START; + m_dsp.scanline = 0; } else if (m_dsp.hlc == 1024) { - m_dsp.vsync = true; - m_dsp.scanline = 31; + m_dsp.scanline = 1; } // wake up the memory refresh task _twice_ on each scanline m_task_wakeup |= 1 << task_mrt; @@ -350,6 +349,15 @@ void alto2_cpu_device::display_state_machine() if (A66_VBLANK(a66)) { LOG((this,LOG_DISPL,1, " VBLANK")); + // Rising edge of VBLANK? + if (!A66_VBLANK(m_dsp.a66)) { + // synchronize on MAME video timing + if (!m_dsp.vblank) { + m_display_time += A2_DISP_BITTIME(1); + return; + } + m_dsp.vblank = false; + } // VSYNC is always within VBLANK, thus we handle it only here if (A66_VSYNC(a66) && !A66_VSYNC(m_dsp.a66)) @@ -393,7 +401,7 @@ void alto2_cpu_device::display_state_machine() m_dsp.scanline += 2; // Falling edge of a63 HBLANK starts unloading of FIFO words LOG((this,LOG_DISPL,1, " HBLANK\\ UNLOAD")); - m_unload_time = ALTO2_DISPLAY_BITTIME(m_dsp.halfclock ? 40+32 : 40+16); + m_unload_time = A2_DISP_BITTIME(m_dsp.halfclock ? 40+32 : 40+16); m_unload_word = 0; } } @@ -466,7 +474,7 @@ void alto2_cpu_device::display_state_machine() m_dsp.a63 = a63; m_dsp.a66 = a66; m_dsp.state = next; - m_dsp_time += ALTO2_DISPLAY_BITTIME(32); + m_display_time += A2_DISP_BITTIME(32); } /** @@ -476,7 +484,7 @@ void alto2_cpu_device::display_state_machine() */ void alto2_cpu_device::f2_late_evenfield() { - UINT16 r = m_dsp.odd ? 0 : 1; + UINT16 r = HLC1024 ^ 1; LOG((this,LOG_DISPL,2," EVENFIELD branch (%#o | %#o)\n", m_next2, r)); m_next2 |= r; } @@ -512,9 +520,9 @@ void alto2_cpu_device::init_disp() m_disp_a63 = prom_load(machine(), &pl_displ_a63, memregion("displ_a63")->base()); m_disp_a66 = prom_load(machine(), &pl_displ_a66, memregion("displ_a66")->base()); - m_dsp.hlc = ALTO2_DISPLAY_HLC_START; + m_dsp.hlc = A2_DISP_HLC_START; - m_dsp.framebuf = std::make_unique<UINT16[]>(ALTO2_DISPLAY_TOTAL_HEIGHT * ALTO2_DISPLAY_SCANLINE_WORDS); + m_dsp.framebuf = std::make_unique<UINT16[]>(A2_DISP_TOTAL_HEIGHT * A2_DISP_SCANLINE_WORDS); m_dsp.patterns = auto_alloc_array(machine(), UINT8, 65536 * 16); for (int y = 0; y < 65536; y++) { UINT8* dst = m_dsp.patterns + y * 16; @@ -523,7 +531,7 @@ void alto2_cpu_device::init_disp() } // Allocate a bitmap including the V/H blank areas - m_dsp.bitmap = std::make_unique<bitmap_ind16>(ALTO2_DISPLAY_TOTAL_WIDTH, ALTO2_DISPLAY_TOTAL_HEIGHT); + m_dsp.bitmap = std::make_unique<bitmap_ind16>(A2_DISP_TOTAL_WIDTH, A2_DISP_TOTAL_HEIGHT); m_dsp.state = 0; } @@ -535,12 +543,12 @@ void alto2_cpu_device::exit_disp() void alto2_cpu_device::reset_disp() { m_dsp.state = 0; - m_dsp.hlc = ALTO2_DISPLAY_HLC_START; + m_dsp.hlc = A2_DISP_HLC_START; m_dsp.a63 = 0; m_dsp.a66 = 0; m_dsp.setmode = 0; m_dsp.inverse = 0; - m_dsp.scanline = 30; + m_dsp.scanline = 0; m_dsp.halfclock = false; m_dsp.wa = 0; m_dsp.ra = 0; @@ -548,18 +556,20 @@ void alto2_cpu_device::reset_disp() m_dsp.dwt_blocks = false; m_dsp.curt_blocks = false; m_dsp.curt_wakeup = false; - m_dsp.vsync = false; - m_dsp.odd = false; + m_dsp.vblank = false; m_dsp.xpreg = 0; m_dsp.csr = 0; - memset(m_dsp.framebuf.get(), 1, sizeof(UINT16) * ALTO2_DISPLAY_HEIGHT * ALTO2_DISPLAY_SCANLINE_WORDS); + memset(m_dsp.framebuf.get(), 1, sizeof(UINT16) * A2_DISP_HEIGHT * A2_DISP_SCANLINE_WORDS); } /* Video update */ UINT32 alto2_cpu_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { copybitmap(bitmap, *m_dsp.bitmap, 0, 0, 0, 0, cliprect); - m_dsp.vsync = false; - m_dsp.odd = !m_dsp.odd; return 0; } + +void alto2_cpu_device::screen_vblank() +{ + m_dsp.vblank = true; +} diff --git a/src/devices/cpu/alto2/a2disp.h b/src/devices/cpu/alto2/a2disp.h index 823114e3066..c2c321583e6 100644 --- a/src/devices/cpu/alto2/a2disp.h +++ b/src/devices/cpu/alto2/a2disp.h @@ -18,7 +18,7 @@ * * The value is 2+4+16+128 = 150 */ -#define ALTO2_DISPLAY_HLC_START (2+4+16+128) +#define A2_DISP_HLC_START (2+4+16+128) /** * @brief End value for the horizontal line counter. @@ -30,7 +30,7 @@ * Note: The horizontal line counts 150 ... 1023 for the even field, * and 1024 ... 1899 for the odd field. */ -#define ALTO2_DISPLAY_HLC_END (1+2+8+32+64+256+512+1024) +#define A2_DISP_HLC_END (1+2+8+32+64+256+512+1024) /** * @brief display total height, including overscan (vertical blanking and synch) @@ -39,7 +39,7 @@ * scanlines to the monitor. The frame rate is 60Hz, which is actually the rate * of the half-frames. The rate for full frames is thus 30Hz. */ -#define ALTO2_DISPLAY_TOTAL_HEIGHT ((ALTO2_DISPLAY_HLC_END + 1 - ALTO2_DISPLAY_HLC_START) / 2) +#define A2_DISP_TOTAL_HEIGHT (static_cast<double>(A2_DISP_HLC_END - A2_DISP_HLC_START) / 2) /** * @brief display total width, including horizontal blanking @@ -68,40 +68,39 @@ * as its own next address A0-A3! * */ -#define ALTO2_DISPLAY_TOTAL_WIDTH 768 +#define A2_DISP_TOTAL_WIDTH 768 //! The display fifo has 16 words. -#define ALTO2_DISPLAY_FIFO 16 +#define A2_DISP_FIFO 16 //! Words per scanline. -#define ALTO2_DISPLAY_SCANLINE_WORDS (ALTO2_DISPLAY_TOTAL_WIDTH/16) +#define A2_DISP_SCANLINE_WORDS (A2_DISP_TOTAL_WIDTH/16) -//! Number of visible scanlines per frame; 808 really, but there are some empty lines? -#define ALTO2_DISPLAY_HEIGHT 808 +//! Number of visible scanlines per frame +#define A2_DISP_HEIGHT 808 //! Visible width of the display; 38 x 16 bit words - 2 pixels. -//#define ALTO2_DISPLAY_WIDTH 606 -#define ALTO2_DISPLAY_WIDTH 608 +#define A2_DISP_WIDTH 606 //! Visible words per scanline. -#define ALTO2_DISPLAY_VISIBLE_WORDS ((ALTO2_DISPLAY_WIDTH+15)/16) +#define A2_DISP_VISIBLE_WORDS ((A2_DISP_WIDTH+15)/16) //! Display bit clock in Hertz (20.16MHz). -#define ALTO2_DISPLAY_BITCLOCK 20160000ll +#define A2_DISP_BITCLOCK 20160000ll //! Display bit time in pico seconds (~= 49.6031ns). -#define ALTO2_DISPLAY_BITTIME(n) (U64(1000000000000)*(n)/ALTO2_DISPLAY_BITCLOCK) +#define A2_DISP_BITTIME(n) DOUBLE_TO_ATTOSECONDS(static_cast<double>(n)/A2_DISP_BITCLOCK) //! Time for a scanline in pico seconds (768 * 49.6031ns ~= 38095.1808ns). -#define ALTO2_DISPLAY_SCANLINE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_TOTAL_WIDTH) +#define A2_DISP_SCANLINE_TIME A2_DISP_BITTIME(A2_DISP_TOTAL_WIDTH) //!< Time of the visible part of a scanline in pico seconds (606 * 49.6031ns ~= 30059.4786ns). -#define ALTO2_DISPLAY_VISIBLE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_WIDTH) +#define A2_DISP_VISIBLE_TIME A2_DISP_BITTIME(A2_DISP_WIDTH) //!< Time for a word in pico seconds (16 pixels * 49.6031ns ~= 793.6496ns). -#define ALTO2_DISPLAY_WORD_TIME ALTO2_DISPLAY_BITTIME(16) +#define A2_DISP_WORD_TIME A2_DISP_BITTIME(16) -#define ALTO2_DISPLAY_VBLANK_TIME ((ALTO2_DISPLAY_TOTAL_HEIGHT-ALTO2_DISPLAY_HEIGHT)*HZ_TO_ATTOSECONDS(26250)) +#define A2_DISP_VBLANK_TIME (static_cast<double>(-A2_DISP_HEIGHT)*HZ_TO_ATTOSECONDS(26250)) #else // ALTO2_DEFINE_CONSTANTS /** @@ -200,9 +199,8 @@ struct { UINT32 inverse; //!< set to 0xffff if line is inverse, 0x0000 otherwise UINT32 scanline; //!< current scanline bool halfclock; //!< false for normal pixel clock, true for half pixel clock - bool vsync; //!< true after vsync, false when end_of_frame was called - bool odd; //!< true if odd field - UINT16 fifo[ALTO2_DISPLAY_FIFO]; //!< display word fifo + bool vblank; //!< true during vblank, false otherwise + UINT16 fifo[A2_DISP_FIFO]; //!< display word fifo UINT32 wa; //!< fifo input pointer (write address; 4-bit) UINT32 ra; //!< fifo output pointer (read address; 4-bit) UINT32 a63; //!< most recent value read from the PROM a63 diff --git a/src/devices/cpu/alto2/a2dwt.cpp b/src/devices/cpu/alto2/a2dwt.cpp index c3ac954b432..81601138e91 100644 --- a/src/devices/cpu/alto2/a2dwt.cpp +++ b/src/devices/cpu/alto2/a2dwt.cpp @@ -11,15 +11,15 @@ * Copied from ALTOCODE24.MU * * ;Display Word Task - * + * * DWT: T← DWA; * T←-3+T+1; * L← AECL+T,BUS=0,TASK; AECL CONTAINS NWRDS AT THIS TIME * AECL←L, :DWTZ; - * + * * DWTY: BLOCK; * TASK, :DWTF; - * + * * DWTZ: L←HTAB-1, BUS=0,TASK; * HTAB←L, :DOTAB; * @@ -66,12 +66,12 @@ void alto2_cpu_device::f2_late_load_ddr() { LOG((this,LOG_DWT,2," DDR<- BUS (%#o)\n", m_bus)); m_dsp.fifo[m_dsp.wa] = m_bus; - m_dsp.wa = (m_dsp.wa + 1) % ALTO2_DISPLAY_FIFO; + m_dsp.wa = (m_dsp.wa + 1) % A2_DISP_FIFO; UINT8 a38 = m_disp_a38[m_dsp.ra * 16 + m_dsp.wa]; if (FIFO_STOPWAKE(a38)) m_task_wakeup &= ~(1 << task_dwt); LOG((this,LOG_DWT,2, " DWT push %04x into FIFO[%02o]%s\n", - m_bus, (m_dsp.wa - 1) & (ALTO2_DISPLAY_FIFO - 1), + m_bus, (m_dsp.wa - 1) & (A2_DISP_FIFO - 1), FIFO_STOPWAKE(a38) ? " STOPWAKE" : "")); } diff --git a/src/devices/cpu/alto2/alto2cpu.cpp b/src/devices/cpu/alto2/alto2cpu.cpp index 6a4438c973c..4361539af97 100644 --- a/src/devices/cpu/alto2/alto2cpu.cpp +++ b/src/devices/cpu/alto2/alto2cpu.cpp @@ -157,7 +157,7 @@ alto2_cpu_device::alto2_cpu_device(const machine_config& mconfig, const char* ta m_wrtram_flag(false), m_ether_enable(false), m_ewfct(false), - m_dsp_time(0), + m_display_time(0), m_unload_time(0), m_unload_word(0), m_bitclk_time(0), @@ -872,7 +872,7 @@ void alto2_cpu_device::device_start() save_item(NAME(m_bank_reg)); save_item(NAME(m_ether_enable)); save_item(NAME(m_ewfct)); - save_item(NAME(m_dsp_time)); + save_item(NAME(m_display_time)); save_item(NAME(m_unload_time)); save_item(NAME(m_unload_word)); save_item(NAME(m_bitclk_time)); @@ -2275,11 +2275,42 @@ void alto2_cpu_device::execute_run() { m_next = m_task_mpc[m_task]; // get current task's next mpc and address modifier m_next2 = m_task_next2[m_task]; + attoseconds_t ucycle = DOUBLE_TO_ATTOSECONDS(1.0/m_clock); do { - if (m_dsp.vsync) { - // synchronizing to the vsync signal - continue; + if (m_display_time >= 0) { + /** + * Subtract the microcycle time from the display time accu. + * If it underflows, call the display state machine which + * adds the time for 32 pixel clocks to the accu. + * This is very close to every seventh CPU cycle + */ + m_display_time -= ucycle; + if (m_display_time < 0) + display_state_machine(); + } + + if (m_unload_time >= 0) { + /** + * Subtract the microcycle time from the unload time accu. + * If it underflows, call the unload word function which adds + * the time for 16 or 32 pixel clocks to the accu, or ends + * the FIFO unloading by leaving m_unload_time at -1. + */ + m_unload_time -= ucycle; + if (m_unload_time < 0) + unload_word(); + } + + if (m_bitclk_time >= 0) { + /** + * Subtract the microcycle time from the bitclk time accu. + * If it underflows, call the disk bitclk function which adds + * the time for one bit as clock cycles to the accu, or ends + * the bitclk sequence by leaving m_bitclk_time at -1. + */ + m_bitclk_time -= ucycle; + disk_bitclk(nullptr, m_bitclk_index); } m_mpc = m_next; // next instruction's micro program counter @@ -2859,41 +2890,6 @@ void alto2_cpu_device::execute_run() } } } - - if (m_dsp_time >= 0) { - /** - * Subtract the microcycle time from the display time accu. - * If it underflows, call the display state machine which - * adds the time for 32 pixel clocks to the accu. - * This is very close to every seventh CPU cycle - */ - m_dsp_time -= ALTO2_UCYCLE; - if (m_dsp_time < 0) - display_state_machine(); - } - - if (m_unload_time >= 0) { - /** - * Subtract the microcycle time from the unload time accu. - * If it underflows, call the unload word function which adds - * the time for 16 or 32 pixel clocks to the accu, or ends - * the FIFO unloading by leaving m_unload_time at -1. - */ - m_unload_time -= ALTO2_UCYCLE; - if (m_unload_time < 0) - unload_word(); - } - - if (m_bitclk_time >= 0) { - /** - * Subtract the microcycle time from the bitclk time accu. - * If it underflows, call the disk bitclk function which adds - * the time for one bit as clock cycles to the accu, or ends - * the bitclk sequence by leaving m_bitclk_time at -1. - */ - m_bitclk_time -= ALTO2_UCYCLE; - disk_bitclk(nullptr, m_bitclk_index); - } } while (m_icount-- > 0); // Save this task's mpc and address modifier @@ -2935,7 +2931,7 @@ void alto2_cpu_device::hard_reset() init_part(); init_kwd(); - m_dsp_time = 0; // reset the display state timing + m_display_time = 0; // reset the display state timing m_unload_time = 0; // reset the word unload timing accu m_bitclk_time = 0; // reset the bitclk timing accu m_task = task_emu; // start with task 0 (emulator) @@ -2981,7 +2977,7 @@ void alto2_cpu_device::soft_reset() m_task = task_emu; // set current task to emulator m_task_wakeup = 1 << task_emu; // set only the emulator task wakeup flag - m_dsp_time = 0; // reset the display state machine timing accu + m_display_time = 0; // reset the display state machine timing accu m_unload_time = 0; // reset the word unload timing accu m_bitclk_time = 0; // reset the bitclk timing accu } diff --git a/src/devices/cpu/alto2/alto2cpu.h b/src/devices/cpu/alto2/alto2cpu.h index 3993e79d816..036f709dae0 100644 --- a/src/devices/cpu/alto2/alto2cpu.h +++ b/src/devices/cpu/alto2/alto2cpu.h @@ -195,6 +195,9 @@ public: //! update the screen bitmap UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + //! set the vblank bit for the display to synch upon + void screen_vblank(); + DECLARE_ADDRESS_MAP( ucode_map, 32 ); DECLARE_ADDRESS_MAP( const_map, 16 ); DECLARE_ADDRESS_MAP( iomem_map, 16 ); @@ -584,10 +587,10 @@ private: UINT8 m_bank_reg[ALTO2_TASKS]; //!< normal and extended RAM banks per task bool m_ether_enable; //!< set to true, if the ethernet should be simulated bool m_ewfct; //!< set by Ether task when it want's a wakeup at switch to task_mrt - int m_dsp_time; //!< display_state_machine() time accu - int m_unload_time; //!< unload word time accu + attoseconds_t m_display_time; //!< display time accu (display state machine) + attoseconds_t m_unload_time; //!< unload word time accu (display FIFO) int m_unload_word; //!< unload word number - int m_bitclk_time; //!< bitclk call time accu + attoseconds_t m_bitclk_time; //!< bitclk call time accu (disk shift register) int m_bitclk_index; //!< bitclk index (bit number in sector) static const char *task_name(int task); //!< human readable task names diff --git a/src/mame/drivers/alto2.cpp b/src/mame/drivers/alto2.cpp index 809303922ca..11669bceb2a 100644 --- a/src/mame/drivers/alto2.cpp +++ b/src/mame/drivers/alto2.cpp @@ -44,6 +44,9 @@ protected: required_ioport m_io_row6; required_ioport m_io_row7; optional_ioport m_io_config; + static const device_timer_id TIMER_VBLANK = 0; + emu_timer* m_vblank_timer; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; }; /* Input Ports */ @@ -269,7 +272,7 @@ ADDRESS_MAP_START( alto2_iomem_map, AS_2, 16, alto2_state ) ADDRESS_MAP_END static MACHINE_CONFIG_START( alto2, alto2_state ) - /* basic machine hardware */ + // Basic machine hardware // SYSCLK is Display Control part A51 (tagged 29.4MHz) divided by 5(?) // 5.8MHz according to de.wikipedia.org/wiki/Xerox_Alto MCFG_CPU_ADD("maincpu", ALTO2, XTAL_29_4912MHz/5) @@ -277,16 +280,13 @@ static MACHINE_CONFIG_START( alto2, alto2_state ) MCFG_CPU_DATA_MAP(alto2_const_map) MCFG_CPU_IO_MAP(alto2_iomem_map) - /* video hardware */ + // Video hardware MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::white) MCFG_SCREEN_RAW_PARAMS(XTAL_20_16MHz, - ALTO2_DISPLAY_TOTAL_WIDTH, - 0, - ALTO2_DISPLAY_WIDTH, - ALTO2_DISPLAY_TOTAL_HEIGHT, - 16, // some scalines of vblank period before - 16+ALTO2_DISPLAY_HEIGHT+8) // and after the usual range - MCFG_SCREEN_REFRESH_RATE(30) // two interlaced fields at 60Hz + A2_DISP_TOTAL_WIDTH, 0, A2_DISP_WIDTH, + A2_DISP_TOTAL_HEIGHT, 0, A2_DISP_HEIGHT) + // Two interlaced fields at 60Hz => 30Hz frame rate + MCFG_SCREEN_REFRESH_RATE(30) MCFG_SCREEN_UPDATE_DEVICE("maincpu", alto2_cpu_device, screen_update) MCFG_SCREEN_PALETTE("palette") @@ -294,7 +294,7 @@ static MACHINE_CONFIG_START( alto2, alto2_state ) MCFG_PALETTE_ADD_MONOCHROME("palette") - /* sound hardware */ + // Sound hardware MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) @@ -306,11 +306,24 @@ MACHINE_CONFIG_END DRIVER_INIT_MEMBER( alto2_state, alto2 ) { - // make the diablo drives known to the CPU core + // Make the diablo drives known to the CPU core alto2_cpu_device* cpu = downcast<alto2_cpu_device *>(m_maincpu.target()); cpu->set_diablo(0, downcast<diablo_hd_device *>(machine().device(DIABLO_HD_0))); cpu->set_diablo(1, downcast<diablo_hd_device *>(machine().device(DIABLO_HD_1))); cpu->set_speaker(m_speaker); + // Create a timer which fires twice per frame, once for each field + m_vblank_timer = timer_alloc(TIMER_VBLANK); + m_vblank_timer->adjust(attotime::from_hz(30),0,attotime::from_hz(30*2)); +} + +void alto2_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + alto2_cpu_device* cpu = downcast<alto2_cpu_device *>(m_maincpu.target()); + switch (id) { + case TIMER_VBLANK: + cpu->screen_vblank(); + break; + } } /* Game Drivers */ |