From 342b391b4aac32911d01deb50b1eeb29198e75cb Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Sun, 5 Mar 2023 20:22:26 +0100 Subject: st: lots of fixes, with much help by Ijor (Jorge Cwik) --- src/mame/atari/atarist.cpp | 11 ++- src/mame/atari/stkbd.cpp | 20 ++--- src/mame/atari/stmmu.cpp | 4 +- src/mame/atari/stvideo.cpp | 205 +++++++++++++++++++++++++++++++++------------ src/mame/atari/stvideo.h | 3 + 5 files changed, 177 insertions(+), 66 deletions(-) diff --git a/src/mame/atari/atarist.cpp b/src/mame/atari/atarist.cpp index 9acb5b97b14..3d274b69559 100644 --- a/src/mame/atari/atarist.cpp +++ b/src/mame/atari/atarist.cpp @@ -785,8 +785,13 @@ void stbook_state::lcd_control_w(uint16_t data) void st_state::cpu_space_map(address_map &map) { - map(0xfffff0, 0xffffff).m(m_maincpu, FUNC(m68000_base_device::autovectors_map)); + map(0xfffff3, 0xfffff3).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 25; })); + map(0xfffff5, 0xfffff5).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([this] () -> u8 { m_maincpu->set_input_line(2, CLEAR_LINE); return 26; })); + map(0xfffff7, 0xfffff7).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 27; })); + map(0xfffff9, 0xfffff9).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([this] () -> u8 { m_maincpu->set_input_line(4, CLEAR_LINE); return 28; })); + map(0xfffffb, 0xfffffb).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 29; })); map(0xfffffd, 0xfffffd).r(m_mfp, FUNC(mc68901_device::get_vector)); + map(0xffffff, 0xffffff).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 31; })); } //------------------------------------------------- @@ -1427,8 +1432,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_inputline(m_maincpu, 2); - m_video->vsync_cb().set_inputline(m_maincpu, 4); + 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/stkbd.cpp b/src/mame/atari/stkbd.cpp index a43ebb5575f..d1b9988c9a3 100644 --- a/src/mame/atari/stkbd.cpp +++ b/src/mame/atari/stkbd.cpp @@ -339,19 +339,19 @@ static INPUT_PORTS_START(stkbd) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad Enter") PORT_CODE(KEYCODE_ENTER_PAD) PORT_START("JOY0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_8WAY + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_8WAY + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_8WAY + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_8WAY + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_8WAY + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY PORT_START("JOY1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_START("MOUSEX") PORT_BIT( 0xff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1) diff --git a/src/mame/atari/stmmu.cpp b/src/mame/atari/stmmu.cpp index 291e8b66b14..046a7a27cc8 100644 --- a/src/mame/atari/stmmu.cpp +++ b/src/mame/atari/stmmu.cpp @@ -58,6 +58,9 @@ void st_mmu_device::device_start() save_item(NAME(m_fdc_drq)); save_item(NAME(m_hdc_drq)); save_item(NAME(m_dma_no_error)); + + // Electra demo shows reset does not reconfigure ram + m_memcfg = 0; } void st_mmu_device::device_reset() @@ -68,7 +71,6 @@ void st_mmu_device::device_reset() m_sector_count = 0; m_block_count = 0; m_fifo_index = 0; - m_memcfg = 0; m_fdc_drq = false; m_hdc_drq = false; m_dma_no_error = true; diff --git a/src/mame/atari/stvideo.cpp b/src/mame/atari/stvideo.cpp index 228a7273486..d533efdfa3b 100644 --- a/src/mame/atari/stvideo.cpp +++ b/src/mame/atari/stvideo.cpp @@ -141,7 +141,9 @@ bool v = false; // DE is on whole cycles of the GLUE clock as vde & hde. Which means, // given that hde is on the inverted phase, that there is a delay of // 0.5 cycles between a hde change and the corresponding de change. - +// +// hde/vde are dropped by the associated sync if they were still 1 at +// that point. // load_d1 = 0 if !de, 1 if load // load_d2 = load_d1 on pixclk @@ -180,6 +182,25 @@ bool v = false; /* +bp a3fe +phase 4 +[:video] [13329804.0 00a420 130820 8176 53319216 53319216 112/262 001/064 s:-- de:-v- 71Hz] res = 2 (2) (ste only) +[:video] [13329806.0 00a422 130852 8178 53319224 53319224 114/262 003/064 s:-- de:-v- 50Hz] res = 0 (0) +[:video] [13329815.0 00a42c 130996 8187 53319260 53319260 123/262 012/064 s:-- de:-v- 60Hz] sync = 0 (1) (+2 on 1/3) +[:video] [13329818.8 00a430 131052 8190 53319274 53319274 126/262 015/064 s:-- de:-v- 50Hz] sync = 2 (0) +[:video] [13329819.c 00a430 131072 8192 53319279 53319279 000/263 017/064 s:-- de:-v- 50Hz] hde 1 +[:video] [13329820.4 00a430 131080 8192 53319281 53319281 000/263 017/064 s:-- de:hvd 50Hz] de 1 lc=53319286 le=0 +[:video] [13329847.0 00a438 131508 8219 53319388 53319388 027/263 044/064 s:-- de:hvd 71Hz] res = 2 (2) +[:video] [13329849.0 00a43a 131540 8221 53319396 53319396 029/263 046/064 s:-- de:hvd 50Hz] res = 0 (0) (stop on ws2) +[:video] [13329899.8 00a444 132348 8271 53319598 53319598 079/263 096/064 s:-- de:hvd 71Hz] res = 2 (2) +[:video] [13329902.0 00a446 132388 8274 53319608 53319608 082/263 099/064 s:-- de:hvd 50Hz] res = 0 (0) (right border 2/3/4, avoids 97) +delta = cc + +phase 3 + + + + phase 1: left border on ste? @@ -303,10 +324,50 @@ void st_video_device::device_start() m_event_timer = timer_alloc(FUNC(st_video_device::timer_event), this); 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)); + save_item(NAME(m_load_current)); + save_item(NAME(m_load_end)); + save_item(NAME(m_ir)); + save_item(NAME(m_rr)); + save_item(NAME(m_adr_base)); + save_item(NAME(m_adr_live)); + save_item(NAME(m_hsc_base)); + save_item(NAME(m_hdec_base)); + save_item(NAME(m_vsc)); + save_item(NAME(m_vdec)); + save_item(NAME(m_shifter_y)); + save_item(NAME(m_palette)); + save_item(NAME(m_sync)); + save_item(NAME(m_res)); + save_item(NAME(m_vsync)); + save_item(NAME(m_hsync)); + save_item(NAME(m_vde)); + save_item(NAME(m_hde)); + save_item(NAME(m_de)); + save_item(NAME(m_mode)); + save_item(NAME(m_pixcnt)); + save_item(NAME(m_rdelay)); + save_item(NAME(m_load_1)); + save_item(NAME(m_load_2)); + save_item(NAME(m_pixcnt_en)); + save_item(NAME(m_reload)); +} + +u64 st_video_device::time_now() +{ + // as_ticks is not clean, so round up + return (machine().time().as_ticks(2*clock()) + 1) >> 1; } void st_video_device::next_event(u64 when) { + if(v) + logerror("%s next event at %d.%x\n", context(), when >> 4, when & 15); // from_ticks/as_ticks is not stable, need target in the middle of the cycle attotime dt = attotime::from_ticks(2*when+1, 2*clock()) - machine().time(); m_event_timer->adjust(dt); @@ -323,8 +384,8 @@ void st_video_device::device_reset() m_vdec = 0; m_vsync = 1; m_hsync = 0; - m_start_screen_time = m_start_line_time = machine().time().as_ticks(clock()) >> 4; - m_shifter_update_time = (machine().time().as_ticks(clock()) | 15) + 1; + m_start_screen_time = m_start_line_time = time_now() >> 4; + m_shifter_update_time = (time_now() | 15) + 1; m_shifter_base_x = 0; m_pixcnt = 4; m_pixcnt_en = false; @@ -341,6 +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_screen_bitmap.fill(0x808080); @@ -401,7 +463,7 @@ void st_video_device::hsync_off(u64 glue_tick) TIMER_CALLBACK_MEMBER(st_video_device::de_event) { - u64 now = machine().time().as_ticks(clock()); + u64 now = time_now(); shifter_sync(now); m_de = param; m_de_cb(m_de); @@ -428,10 +490,9 @@ void st_video_device::hde_on(u64 glue_tick) logerror("%s hde 1\n", context()); if(m_vde && !m_hde) { m_hde = 1; - if(m_mode == 0 && !v) { + if(m_mode == 0) { m_pixcnt_en = false; m_rdelay = 0; - v = false; } next_de_event(glue_tick, 1); } @@ -493,7 +554,7 @@ void st_video_device::shifter_handle_load() void st_video_device::shifter_sync(u64 now) { if(!now) - now = machine().time().as_ticks(clock()); + now = time_now(); switch(m_res & 3) { case 0: { if(m_shifter_update_time & 3) { @@ -589,20 +650,22 @@ std::string st_video_device::context(u64 now) { static const char *const mt[3] = { "50Hz", "60Hz", "71Hz" }; if(!now) - now = machine().time().as_ticks(clock()); + now = time_now(); shifter_sync(now); u64 phase = m_phase->read(); u64 glue_tick = now >> 4; - if((now & 15) < phase) + 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; u64 mtick = machine().root_device().subdevice("m68000")->total_cycles(); + u32 pc = machine().root_device().subdevice("m68000")->pcbase(); - return util::string_format("[%s %6d %6d %6d %6d %03d/%03d %03d/%03d s:%c%c de:%c%c%c %s]", - machine().time().to_string(), + return util::string_format("[%s %06x %6d %6d %6d %6d %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, @@ -615,22 +678,26 @@ std::string st_video_device::context(u64 now) mt[m_mode]); } -void st_video_device::glue_determine_next_event() +void st_video_device::glue_sync() { static const char *const mt[3] = { "50Hz", "60Hz", "71Hz" }; - u64 now = machine().time().as_ticks(clock()); + u64 now = time_now(); shifter_sync(now); u64 phase = m_phase->read(); - // logerror("now %d time %s\n", now, machine().time().to_string()); u64 glue_tick = now >> 4; - if((now & 15) < phase) + if((now & 15) < phase && glue_tick) glue_tick --; + + 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; if(v) - logerror("%s glue sync\n", context()); + logerror("%s glue sync tick=%d\n", context(), glue_tick); if(hsc >= 128) { if(m_mode == M_71) { @@ -656,8 +723,6 @@ void st_video_device::glue_determine_next_event() case 2: screen().configure(56*16, 501, rectangle(0, 16*(122-72), 0, 511-11-1), attotime::from_ticks(16*cycles_per_screen[m_mode], clock()).as_attoseconds()); break; } } - if(m_mode == 2) - v = false; m_vsc = base_vsc[m_mode]; m_start_screen_time = glue_tick; m_shifter_y = 0; @@ -665,6 +730,7 @@ void st_video_device::glue_determine_next_event() } else if(m_vsc == vsync_start[m_mode]) { m_vsync = 1; m_vsync_cb(1); + m_vde = 0; m_adr_live = m_adr_base; } @@ -672,6 +738,66 @@ void st_video_device::glue_determine_next_event() m_start_line_time = glue_tick; } + switch(m_mode) { + case M_50: + if(hsc == 102) { + hsync_on(); + if(m_hde) + hde_off(glue_tick); + } + else if(hsc == 112) { + hsync_off(glue_tick); + hdec = 1; + m_hdec_base = 111; + } + 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) + 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) + hde_off(glue_tick); + } + if(hdec == 4) + hde_on(glue_tick); + else if(hdec == 44) + hde_off(glue_tick); + break; + } +} + + +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; + u16 hsc_next = 128; u16 hdec_next = 128; @@ -679,63 +805,37 @@ void st_video_device::glue_determine_next_event() case M_50: if(hsc < 102) hsc_next = 102; - else if(hsc < 112) { - if(hsc == 102) - hsync_on(); + else if(hsc < 112) hsc_next = 112; - } else if(hsc == 112) { - hsync_off(glue_tick); - hdec = 1; - m_hdec_base = 111; - } if(hdec < 17) hdec_next = 17; - else if(hdec < 97) { - if(hdec == 17) - hde_on(glue_tick); + else if(hdec < 97) hdec_next = 97; - } else if(hdec == 97) - hde_off(glue_tick); break; case M_60: if(hsc < 102) hsc_next = 102; - else if(hsc < 112) { - if(hsc == 102) - hsync_on(); + else if(hsc < 112) hsc_next = 112; - } else if(hsc == 112) { - hsync_off(glue_tick); - hdec = 1; - m_hdec_base = 111; - } if(hdec < 16) hdec_next = 16; - else if(hdec < 96) { - if(hdec == 16) - hde_on(glue_tick); + else if(hdec < 96) hdec_next = 96; - } else if(hdec == 96) - hde_off(glue_tick); break; case M_71: if(hsc < 122) hsc_next = 122; - else if(hsc == 122) - hsync_on(); if(hdec < 4) hdec_next = 4; - else if(hdec < 44) { - if(hdec == 4) - hde_on(glue_tick); + else if(hdec < 44) hdec_next = 44; - } else if(hdec == 44) - hde_off(glue_tick); break; } + if(v) + logerror("%s next hsc %d hdec %d\n", context(), hsc_next, hdec_next); hsc_next -= hsc; hdec_next -= hdec; @@ -745,6 +845,7 @@ void st_video_device::glue_determine_next_event() TIMER_CALLBACK_MEMBER(st_video_device::timer_event) { + glue_sync(); glue_determine_next_event(); } @@ -783,7 +884,7 @@ u8 st_video_device::adr_live_m_r() u8 st_video_device::adr_live_l_r() { shifter_sync(); - v = false; + // v = true; logerror("%s adr %06x - %06x\n", context(), m_adr_base, m_adr_live); return m_adr_live; } diff --git a/src/mame/atari/stvideo.h b/src/mame/atari/stvideo.h index 4a129807e89..d741ad17048 100644 --- a/src/mame/atari/stvideo.h +++ b/src/mame/atari/stvideo.h @@ -57,6 +57,7 @@ private: emu_timer *m_de_timer; u64 m_start_screen_time, m_start_line_time, 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; @@ -95,8 +96,10 @@ private: void update_mode(); void shifter_handle_load(); void shifter_sync(u64 now = 0); + void glue_sync(); void glue_determine_next_event(); + u64 time_now(); void next_event(u64 when); void next_de_event(u64 glue_tick, int level); -- cgit v1.2.3