From c9db970105bb45b08e8a85d116ab68a8060b92d1 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Sat, 11 Mar 2023 17:18:12 +0100 Subject: st: Bunch more fixes --- src/mame/atari/atarist.cpp | 25 ++++-- src/mame/atari/stvideo.cpp | 205 ++++++++++++++++++++++++++------------------- src/mame/atari/stvideo.h | 6 +- 3 files changed, 142 insertions(+), 94 deletions(-) diff --git a/src/mame/atari/atarist.cpp b/src/mame/atari/atarist.cpp index 3d274b69559..f7fd82f5117 100644 --- a/src/mame/atari/atarist.cpp +++ b/src/mame/atari/atarist.cpp @@ -805,23 +805,30 @@ void st_state::st_super_map(address_map &map) map(0x000000, 0x000007).rom().region(M68000_TAG, 0); map(0x000000, 0x000007).before_delay(NAME([](offs_t) { return 64; })).w(m_maincpu, FUNC(m68000_device::berr_w)); map(0x400000, 0xf9ffff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); - //map(0xfa0000, 0xfbffff) // mapped by the cartslot + map(0xfa0000, 0xfbffff).noprw(); // mapped by the cartslot map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0); map(0xfc0000, 0xfeffff).before_delay(NAME([](offs_t) { return 64; })).w(m_maincpu, FUNC(m68000_device::berr_w)); - // Do a bus error if nothing answers - map(0xff0000, 0xffffff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); map(0xff8000, 0xff8fff).m(m_mmu, FUNC(st_mmu_device::map)); map(0xff8000, 0xff8fff).m(m_video, FUNC(st_video_device::map)); - map(0xff8800, 0xff8800).rw(YM2149_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)).mirror(0xfc); - map(0xff8802, 0xff8802).rw(YM2149_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w)).mirror(0xfc); + map(0xff8800, 0xff8800).after_delay(NAME([](offs_t) { return 1; })).rw(YM2149_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)).mirror(0xfc); + map(0xff8802, 0xff8802).after_delay(NAME([](offs_t) { return 1; })).rw(YM2149_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w)).mirror(0xfc); // no blitter on original ST map(0xfffa00, 0xfffa3f).rw(m_mfp, FUNC(mc68901_device::read), FUNC(mc68901_device::write)).umask16(0x00ff); map(0xfffc00, 0xfffc03).rw(m_acia[0], FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0xff00); map(0xfffc04, 0xfffc07).rw(m_acia[1], FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0xff00); + + // Do a bus error where nothing answers in 64 cycles + map(0xff0000, 0xff7fff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); + map(0xff8100, 0xff81ff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); + map(0xff8300, 0xff85ff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); + map(0xff8700, 0xff87ff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); + map(0xff8900, 0xfff9ff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); + map(0xfffb00, 0xfffbff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); + map(0xfffd00, 0xffffff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); } void st_state::st_user_map(address_map &map) @@ -829,8 +836,10 @@ void st_state::st_user_map(address_map &map) // Ram mapped by the mmu map.unmap_value_high(); map(0x000000, 0x0007ff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); - map(0x400000, 0xfbffff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); + map(0x400000, 0xf9ffff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); + map(0xfa0000, 0xfbffff).noprw(); // mapped by the cartslot map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0).w(m_maincpu, FUNC(m68000_device::berr_w)); + map(0xfc0000, 0xfeffff).before_delay(NAME([](offs_t) { return 64; })).w(m_maincpu, FUNC(m68000_device::berr_w)); map(0xff0000, 0xffffff).before_delay(NAME([](offs_t) { return 64; })).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w)); } @@ -1432,8 +1441,8 @@ void st_state::st(machine_config &config) m_video->set_ram(m_mainram); m_video->set_mmu(m_mmu); m_video->de_cb().set(m_mfp, FUNC(mc68901_device::tbi_w)); - m_video->hsync_cb().set([this](int state) { if(state) m_maincpu->set_input_line(2, ASSERT_LINE); }); - m_video->vsync_cb().set([this](int state) { if(state) m_maincpu->set_input_line(4, ASSERT_LINE); }); + m_video->hsync_cb().set([this](int state) { if(!state) m_maincpu->set_input_line(2, ASSERT_LINE); }); + m_video->vsync_cb().set([this](int state) { if(!state) m_maincpu->set_input_line(4, ASSERT_LINE); }); // sound hardware SPEAKER(config, "mono").front_center(); diff --git a/src/mame/atari/stvideo.cpp b/src/mame/atari/stvideo.cpp index d533efdfa3b..73adbcd53f9 100644 --- a/src/mame/atari/stvideo.cpp +++ b/src/mame/atari/stvideo.cpp @@ -284,10 +284,10 @@ const u32 st_video_device::cycles_per_screen[3] = { 128*313, 127*263, 56*501 }; static INPUT_PORTS_START(stvideo) PORT_START("config") PORT_CONFNAME( 15, 4, "GLUE wake state") - PORT_CONFSETTING( 0, "1" ) - PORT_CONFSETTING( 4, "2" ) - PORT_CONFSETTING( 8, "3" ) - PORT_CONFSETTING( 12, "4" ) + PORT_CONFSETTING( 12, "DL3 / WS2" ) + PORT_CONFSETTING( 8, "DL4 / WS4" ) + PORT_CONFSETTING( 4, "DL5 / WS3" ) + PORT_CONFSETTING( 0, "DL6 / WS1" ) INPUT_PORTS_END ioport_constructor st_video_device::device_input_ports() const @@ -326,7 +326,6 @@ void st_video_device::device_start() m_de_timer = timer_alloc(FUNC(st_video_device::de_event ), this); save_item(NAME(m_start_screen_time)); - save_item(NAME(m_start_line_time)); save_item(NAME(m_shifter_base_x)); save_item(NAME(m_shifter_update_time)); save_item(NAME(m_prev_glue_tick)); @@ -384,7 +383,8 @@ void st_video_device::device_reset() m_vdec = 0; m_vsync = 1; m_hsync = 0; - m_start_screen_time = m_start_line_time = time_now() >> 4; + m_start_screen_time = time_now() >> 4; + m_hsc_base = m_hdec_base = 0; m_shifter_update_time = (time_now() | 15) + 1; m_shifter_base_x = 0; m_pixcnt = 4; @@ -402,7 +402,7 @@ void st_video_device::device_reset() m_hde = 0; m_rr[0] = m_rr[1] = m_rr[2] = m_rr[3] = 0; m_ir[0] = m_ir[1] = m_ir[2] = m_ir[3] = 0; - m_prev_glue_tick = 1; + m_prev_glue_tick = 0; m_screen_bitmap.fill(0x808080); @@ -445,9 +445,11 @@ void st_video_device::hsync_on() void st_video_device::hsync_off(u64 glue_tick) { if(m_hsync) { - m_shifter_base_x = (glue_tick << 4) | m_phase->read(); + m_shifter_base_x = (glue_tick << 3) + m_phase->read() - 32; m_shifter_y ++; + m_hdec_base = glue_tick - 1; + m_hsync = 0; m_hsync_cb(0); if(m_vsync) @@ -456,30 +458,41 @@ void st_video_device::hsync_off(u64 glue_tick) m_vdec ++; if(m_vdec == vde_start[m_mode]) m_vde = 1; - else if(m_vdec == vde_end[m_mode]) + else if(m_vdec == vde_end[m_mode]) { m_vde = 0; + if(m_de) + next_de_event((glue_tick | 1) + 1, 0); + } + + if(v) + logerror("%s hsync 0\n", context()); } } -TIMER_CALLBACK_MEMBER(st_video_device::de_event) +void st_video_device::de_set(bool level) { u64 now = time_now(); shifter_sync(now); - m_de = param; + m_de = level; m_de_cb(m_de); - if(param) { + if(level) { m_load_current = (now & ~15) + 16 + 8; m_load_end = 0; } else m_load_end = (now & ~15) + 16 + 8; if(v) - logerror("%s de %d lc=%d le=%d\n", context(now), m_de, m_load_current/4, m_load_end/4); + logerror("%s de %d lc=%d le=%d delta=%d\n", context(now), m_de, m_load_current/4, m_load_end/4, m_load_current - now); +} + +TIMER_CALLBACK_MEMBER(st_video_device::de_event) +{ + de_set(param); } void st_video_device::next_de_event(u64 glue_tick, int level) { - u64 when = (glue_tick << 4) + m_phase->read() + 8; + u64 when = (glue_tick << 3) + m_phase->read() - 32; attotime dt = attotime::from_ticks(2*when+1, 2*clock()) - machine().time(); m_de_timer->adjust(dt, level); } @@ -494,7 +507,7 @@ void st_video_device::hde_on(u64 glue_tick) m_pixcnt_en = false; m_rdelay = 0; } - next_de_event(glue_tick, 1); + next_de_event((glue_tick | 1) + 1, 1); } } @@ -504,7 +517,7 @@ void st_video_device::hde_off(u64 glue_tick) logerror("%s hde 0\n", context()); if(m_hde) { m_hde = 0; - next_de_event(glue_tick, 0); + next_de_event((glue_tick | 1) + 1, 0); } } @@ -651,25 +664,21 @@ std::string st_video_device::context(u64 now) static const char *const mt[3] = { "50Hz", "60Hz", "71Hz" }; if(!now) now = time_now(); - shifter_sync(now); - u64 phase = m_phase->read(); - u64 glue_tick = now >> 4; - if((now & 15) < phase && glue_tick) - glue_tick --; - u16 hsc = m_hsc_base + (glue_tick - m_start_line_time); - u16 hdec = m_hsync ? 0 : (hsc - m_hdec_base) & 127; + auto [glue_tick, hsc, hdec] = compute_glue_tick(now); u64 mtick = machine().root_device().subdevice("m68000")->total_cycles(); u32 pc = machine().root_device().subdevice("m68000")->pcbase(); - return util::string_format("[%s %06x %6d %6d %6d %6d %03d/%03d %03d/%03d s:%c%c de:%c%c%c %s]", + return util::string_format("[%s %06x %6d.%d %6d %6d %4d %4d %03d/%03d %03d/%03d s:%c%c de:%c%c%c %s]", util::string_format("%08d.%x", now >> 4, now & 15), pc, - now - ((m_start_screen_time << 4) | phase), - glue_tick - m_start_screen_time, - now >> 2, + (glue_tick - m_start_screen_time) >> 1, + (glue_tick - m_start_screen_time) & 1, mtick, + glue_tick, + glue_tick - m_hsc_base, + glue_tick - m_hdec_base, hsc, m_vsc, hdec, m_vdec, m_hsync ? 'h' : '-', m_vsync ? 'v' : '-', @@ -678,45 +687,55 @@ std::string st_video_device::context(u64 now) mt[m_mode]); } +std::tuple st_video_device::compute_glue_tick(u64 now) +{ + // Glue tick is doubled to count up and down edges + + u64 phase = m_phase->read(); + u64 glue_tick = (now + 32 - phase) >> 3; // Avoid negative values after adjustement, with some margin + + u16 hsc = (glue_tick - m_hsc_base) >> 1; + u16 hdec = m_hsync ? 0 : ((glue_tick - m_hdec_base) >> 1) & 127; + return std::make_tuple(glue_tick, hsc, hdec); +} + void st_video_device::glue_sync() { static const char *const mt[3] = { "50Hz", "60Hz", "71Hz" }; u64 now = time_now(); shifter_sync(now); - u64 phase = m_phase->read(); - u64 glue_tick = now >> 4; - if((now & 15) < phase && glue_tick) - glue_tick --; + auto [glue_tick, hsc, hdec] = compute_glue_tick(now); if(glue_tick == m_prev_glue_tick) return; - m_prev_glue_tick = glue_tick; - u16 hsc = m_hsc_base + (glue_tick - m_start_line_time); - u16 hdec = m_hsync ? 0 : (hsc - m_hdec_base) & 127; + bool hsc_edge = (glue_tick >= m_prev_glue_tick+2) || !(glue_tick & 1); + bool hdec_edge = (glue_tick >= m_prev_glue_tick+2) || (glue_tick & 1); + + m_prev_glue_tick = glue_tick; if(v) - logerror("%s glue sync tick=%d\n", context(), glue_tick); + logerror("%s glue sync tick=%d.%d\n", context(), glue_tick >> 1, glue_tick & 1); if(hsc >= 128) { if(m_mode == M_71) { hsync_off(glue_tick); - m_hdec_base = 127; - hdec = 1; + hdec = 0; } - m_hdec_base += base_hsc[m_mode]; m_vsc ++; if(m_vsc == 512) { m_vsync = 0; + m_adr_live = m_adr_base; m_vdec = 0; m_vsync_cb(0); u64 dt = glue_tick - m_start_screen_time; // We put the (0, 0) position at hsync off, vsync off. We // remove the blanked zone at 50 and 60Hz. - if(dt != cycles_per_screen[m_mode]) { + if(dt != 2*cycles_per_screen[m_mode]) { logerror("Video mode: %s\n", mt[m_mode]); + logerror("dt=%d cps=%d / %d\n", dt, cycles_per_screen[m_mode], 2*cycles_per_screen[m_mode]); switch(m_mode) { case 0: screen().configure(128*8, 313, rectangle(8*(121-112), 8*(128-112 + 98-0), 223-199, 506-199-1), attotime::from_ticks(16*cycles_per_screen[m_mode], clock()).as_attoseconds()); break; case 1: screen().configure(127*8, 263, rectangle(8*(121-112), 8*(128-112 + 99-1), 264-249, 506-249-1), attotime::from_ticks(16*cycles_per_screen[m_mode], clock()).as_attoseconds()); break; @@ -731,57 +750,70 @@ void st_video_device::glue_sync() m_vsync = 1; m_vsync_cb(1); m_vde = 0; + if(m_de) + next_de_event((glue_tick | 1) + 1, 0); m_adr_live = m_adr_base; } - hsc = m_hsc_base = base_hsc[m_mode]; - m_start_line_time = glue_tick; + hsc = base_hsc[m_mode]; + m_hsc_base = glue_tick - 2*hsc; } switch(m_mode) { case M_50: - if(hsc == 102) { - hsync_on(); - if(m_hde) - hde_off(glue_tick); + if(hsc_edge) { + if(hsc == 102) { + hsync_on(); + if(m_hde) + hde_off(glue_tick); + } + else if(hsc == 112) { + hsync_off(glue_tick); + hdec = 0; + m_hdec_base = glue_tick - 1; + } } - else if(hsc == 112) { - hsync_off(glue_tick); - hdec = 1; - m_hdec_base = 111; + if(hdec_edge) { + if(hdec == 17) + hde_on(glue_tick); + else if(hdec == 97) + hde_off(glue_tick); } - if(hdec == 17) - hde_on(glue_tick); - else if(hdec == 97) - hde_off(glue_tick); break; case M_60: - if(hsc == 102) { - hsync_on(); - if(m_hde) + if(hsc_edge) { + if(hsc == 102) { + hsync_on(); + if(m_hde) + hde_off(glue_tick); + } else if(hsc == 112) { + hsync_off(glue_tick); + hdec = 0; + } + } + if(hdec_edge) { + if(hdec == 16) + hde_on(glue_tick); + else if(hdec == 96) hde_off(glue_tick); - } else if(hsc == 112) { - hsync_off(glue_tick); - hdec = 1; - m_hdec_base = 111; } - if(hdec == 16) - hde_on(glue_tick); - else if(hdec == 96) - hde_off(glue_tick); break; case M_71: - if(hsc == 122) { - hsync_on(); - if(m_hde) + if(hsc_edge) { + if(hsc == 122) { + hsync_on(); + if(m_hde) + hde_off(glue_tick); + } + } + if(hdec_edge) { + if(hdec == 4) + hde_on(glue_tick); + else if(hdec == 44) hde_off(glue_tick); } - if(hdec == 4) - hde_on(glue_tick); - else if(hdec == 44) - hde_off(glue_tick); break; } } @@ -791,12 +823,7 @@ void st_video_device::glue_determine_next_event() { u64 now = time_now(); - u64 phase = m_phase->read(); - u64 glue_tick = now >> 4; - if((now & 15) < phase) - glue_tick --; - u16 hsc = m_hsc_base + (glue_tick - m_start_line_time); - u16 hdec = m_hsync ? 0 : (hsc - m_hdec_base) & 127; + auto [glue_tick, hsc, hdec] = compute_glue_tick(now); u16 hsc_next = 128; u16 hdec_next = 128; @@ -834,13 +861,18 @@ void st_video_device::glue_determine_next_event() break; } - if(v) - logerror("%s next hsc %d hdec %d\n", context(), hsc_next, hdec_next); - hsc_next -= hsc; - hdec_next -= hdec; - u16 delta = hsc_next < hdec_next || m_hsync ? hsc_next : hdec_next; - next_event(((glue_tick + delta) << 4) | phase); + u16 hsc_delta = ((hsc_next - hsc) << 1) - (glue_tick & 1); + u16 hdec_delta = ((hdec_next - hdec) << 1) - (~glue_tick & 1); + + u16 delta = hsc_delta < hdec_delta || m_hsync ? hsc_delta : hdec_delta; + + if(v) { + u64 gt = glue_tick + delta - m_start_screen_time; + logerror("%s next hsc %d hdec %d targetting %d.%d\n", context(), hsc_next, hdec_next, gt >> 1, gt & 1); + } + + next_event(((glue_tick + delta) << 3) + m_phase->read() - 32); } TIMER_CALLBACK_MEMBER(st_video_device::timer_event) @@ -884,8 +916,13 @@ u8 st_video_device::adr_live_m_r() u8 st_video_device::adr_live_l_r() { shifter_sync(); - // v = true; logerror("%s adr %06x - %06x\n", context(), m_adr_base, m_adr_live); + u32 pc = machine().root_device().subdevice("m68000")->pcbase(); + if(pc == 0x8644) + v = false; // level 16 + if(pc == 0x84f0) + v = false; // main menu + // v = true; return m_adr_live; } diff --git a/src/mame/atari/stvideo.h b/src/mame/atari/stvideo.h index d741ad17048..72e95c39888 100644 --- a/src/mame/atari/stvideo.h +++ b/src/mame/atari/stvideo.h @@ -56,12 +56,12 @@ private: emu_timer *m_event_timer; emu_timer *m_de_timer; - u64 m_start_screen_time, m_start_line_time, m_shifter_base_x, m_shifter_update_time; + u64 m_start_screen_time, m_hsc_base, m_hdec_base, m_shifter_base_x, m_shifter_update_time; u64 m_prev_glue_tick; u64 m_load_current, m_load_end; u16 m_ir[4], m_rr[4]; u32 m_adr_base, m_adr_live; - u16 m_hsc_base, m_hdec_base, m_vsc, m_vdec, m_shifter_y; + u16 m_vsc, m_vdec, m_shifter_y; u16 m_palette[16]; u8 m_sync, m_res, m_vsync, m_hsync, m_vde, m_hde, m_de; u8 m_mode; @@ -96,6 +96,8 @@ private: void update_mode(); void shifter_handle_load(); void shifter_sync(u64 now = 0); + void de_set(bool level); + std::tuple compute_glue_tick(u64 now); void glue_sync(); void glue_determine_next_event(); -- cgit v1.2.3