x68000: Compute refresh rates from CRTC parameters and known XTAL values

This commit is contained in:
AJR 2018-06-25 20:59:31 -04:00
parent 52ab45e95f
commit fefcae883f
3 changed files with 53 additions and 40 deletions

View File

@ -307,6 +307,7 @@ const double XTAL::known_xtals[] = {
35'904'000, /* 35.904_MHz_XTAL Used on HP98543 graphics board */
36'000'000, /* 36_MHz_XTAL Sega Model 1 video board */
38'769'220, /* 38.76922_MHz_XTAL Namco System 21 video board */
38'863'630, /* 38.86363_MHz_XTAL Sharp X68000 15.98kHz video */
39'321'600, /* 39.3216_MHz_XTAL Sun 2/120 */
39'710'000, /* 39.71_MHz_XTAL Wyse WY-60 132-column display clock */
40'000'000, /* 40_MHz_XTAL - */
@ -348,6 +349,7 @@ const double XTAL::known_xtals[] = {
66'666'700, /* 66.6667_MHz_XTAL Later Midway games */
67'737'600, /* 67.7376_MHz_XTAL PSX-based h/w, Sony ZN1-2-based */
68'850'000, /* 68.85_MHz_XTAL Wyse WY-50 */
69'551'990, /* 69.55199_MHz_XTAL Sharp X68000 31.5kHz video */
72'000'000, /* 72_MHz_XTAL Aristocrat MKV */
72'576'000, /* 72.576_MHz_XTAL Centipede, Millipede, Missile Command, Let's Go Bowling "Multipede" */
73'728'000, /* 73.728_MHz_XTAL Ms. Pac-Man/Galaga 20th Anniversary */

View File

@ -138,6 +138,12 @@
#include "x68000.lh"
#define LOG_FDC (1 << 1)
#define LOG_SYS (1 << 2)
#define LOG_IRQ (1 << 3)
//#define VERBOSE (LOG_FDC | LOG_SYS | LOG_IRQ)
#include "logmacro.h"
static constexpr uint32_t adpcm_clock[2] = { 8000000, 4000000 };
static constexpr uint32_t adpcm_div[4] = { 1024, 768, 512, /* Reserved */512 };
@ -244,7 +250,7 @@ int x68k_state::x68k_read_mouse()
m_mouse.bufferempty = 1;
i_val &= ~0x01;
m_scc->set_reg_b(0, i_val);
logerror("SCC: mouse buffer empty\n");
LOGMASKED(LOG_SYS, "SCC: mouse buffer empty\n");
}
return ipt;
@ -577,7 +583,7 @@ WRITE8_MEMBER(x68k_state::ppi_port_c_w)
m_adpcm.pan = data & 0x03;
m_adpcm.rate = (data & 0x0c) >> 2;
if (m_adpcm.rate == 3)
logerror("PPI: Invalid ADPCM sample rate set.\n");
LOGMASKED(LOG_SYS, "PPI: Invalid ADPCM sample rate set.\n");
x68k_set_adpcm();
m_okim6258->set_divider(m_adpcm.rate);
@ -631,7 +637,7 @@ WRITE16_MEMBER(x68k_state::x68k_fdc_w)
}
}
m_fdc.control_drives = data & 0x0f;
logerror("FDC: signal control set to %02x\n",data);
LOGMASKED(LOG_FDC, "FDC: signal control set to %02x\n",data);
break;
case 0x01: {
x = data & 3;
@ -647,7 +653,7 @@ WRITE16_MEMBER(x68k_state::x68k_fdc_w)
if(x != m_fdc.select_drive)
m_access_drv_out[m_fdc.select_drive] = 1;
m_fdc.select_drive = x;
logerror("FDC: Drive #%i: Drive selection set to %02x\n",x,data);
LOGMASKED(LOG_FDC, "FDC: Drive #%i: Drive selection set to %02x\n",x,data);
break;
}
}
@ -673,12 +679,12 @@ READ16_MEMBER(x68k_state::x68k_fdc_r)
}
// bit 7 = disk inserted
// bit 6 = disk error (in insertion, presumably)
logerror("FDC: Drive #%i Disk check - returning %02x\n",x,ret);
LOGMASKED(LOG_FDC, "FDC: Drive #%i Disk check - returning %02x\n",x,ret);
}
}
return ret;
case 0x01:
logerror("FDC: IOC selection is write-only\n");
LOGMASKED(LOG_FDC, "FDC: IOC selection is write-only\n");
return 0xff;
}
return 0xff;
@ -691,7 +697,7 @@ WRITE_LINE_MEMBER( x68k_state::fdc_irq )
m_current_vector[1] = m_ioc.fdcvector;
m_ioc.irqstatus |= 0x80;
m_current_irq_line = 1;
logerror("FDC: IRQ triggered\n");
LOGMASKED(LOG_FDC, "FDC: IRQ triggered\n");
m_maincpu->set_input_line_and_vector(1, ASSERT_LINE, m_current_vector[1]);
}
else
@ -738,26 +744,26 @@ WRITE16_MEMBER(x68k_state::x68k_ioc_w)
{
case 0x00:
m_ioc.irqstatus = data & 0x0f;
logerror("I/O: Status register write %02x\n",data);
LOGMASKED(LOG_SYS, "I/O: Status register write %02x\n",data);
break;
case 0x01:
switch(data & 0x03)
{
case 0x00:
m_ioc.fdcvector = data & 0xfc;
logerror("IOC: FDC IRQ vector = 0x%02x\n",data & 0xfc);
LOGMASKED(LOG_IRQ, "IOC: FDC IRQ vector = 0x%02x\n",data & 0xfc);
break;
case 0x01:
m_ioc.fddvector = data & 0xfc;
logerror("IOC: FDD IRQ vector = 0x%02x\n",data & 0xfc);
LOGMASKED(LOG_IRQ, "IOC: FDD IRQ vector = 0x%02x\n",data & 0xfc);
break;
case 0x02:
m_ioc.hdcvector = data & 0xfc;
logerror("IOC: HDD IRQ vector = 0x%02x\n",data & 0xfc);
LOGMASKED(LOG_IRQ, "IOC: HDD IRQ vector = 0x%02x\n",data & 0xfc);
break;
case 0x03:
m_ioc.prnvector = data & 0xfc;
logerror("IOC: Printer IRQ vector = 0x%02x\n",data & 0xfc);
LOGMASKED(LOG_IRQ, "IOC: Printer IRQ vector = 0x%02x\n",data & 0xfc);
break;
}
break;
@ -769,7 +775,7 @@ READ16_MEMBER(x68k_state::x68k_ioc_r)
switch(offset)
{
case 0x00:
logerror("I/O: Status register read\n");
LOGMASKED(LOG_SYS, "I/O: Status register read\n");
return (m_ioc.irqstatus & 0xdf) | 0x20;
default:
return 0x00;
@ -814,7 +820,7 @@ WRITE16_MEMBER(x68k_state::x68k_sysport_w)
COMBINE_DATA(&m_sysport.sram_writeprotect);
break;
default:
// logerror("SYS: [%08x] Wrote %04x to invalid or unimplemented system port %04x\n",m_maincpu->pc(),data,offset);
// LOGMASKED(LOG_SYS, "SYS: [%08x] Wrote %04x to invalid or unimplemented system port %04x\n",m_maincpu->pc(),data,offset);
break;
}
}
@ -834,7 +840,7 @@ READ16_MEMBER(x68k_state::x68k_sysport_r)
case 0x05: // CPU type and speed
return m_sysport.cputype;
default:
logerror("Read from invalid or unimplemented system port %04x\n",offset);
LOGMASKED(LOG_SYS, "Read from invalid or unimplemented system port %04x\n",offset);
return 0xff;
}
}
@ -901,7 +907,7 @@ WRITE16_MEMBER(x68k_state::x68k_vid_w)
COMBINE_DATA(m_video.reg+2);
break;
default:
logerror("VC: Invalid video controller write (offset = 0x%04x, data = %04x)\n",offset,data);
LOGMASKED(LOG_SYS, "VC: Invalid video controller write (offset = 0x%04x, data = %04x)\n",offset,data);
}
}
@ -916,7 +922,7 @@ READ16_MEMBER(x68k_state::x68k_vid_r)
case 0x100:
return m_video.reg[2];
default:
logerror("VC: Invalid video controller read (offset = 0x%04x)\n",offset);
LOGMASKED(LOG_SYS, "VC: Invalid video controller read (offset = 0x%04x)\n",offset);
}
return 0xff;
@ -931,13 +937,13 @@ READ16_MEMBER(x68k_state::x68k_areaset_r)
WRITE16_MEMBER(x68k_state::x68k_areaset_w)
{
// TODO
logerror("SYS: Supervisor area set: 0x%02x\n",data & 0xff);
LOGMASKED(LOG_SYS, "SYS: Supervisor area set: 0x%02x\n",data & 0xff);
}
WRITE16_MEMBER(x68k_state::x68k_enh_areaset_w )
{
// TODO
logerror("SYS: Enhanced Supervisor area set (from %iMB): 0x%02x\n",(offset + 1) * 2,data & 0xff);
LOGMASKED(LOG_SYS, "SYS: Enhanced Supervisor area set (from %iMB): 0x%02x\n",(offset + 1) * 2,data & 0xff);
}
TIMER_CALLBACK_MEMBER(x68k_state::x68k_bus_error)
@ -956,7 +962,7 @@ void x68k_state::set_bus_error(uint32_t address, bool write, uint16_t mem_mask)
m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
m_bus_error_timer->adjust(m_maincpu->cycles_to_attotime(16)); // let rmw cycles complete
logerror("%s: Bus error: Unused RAM access [%08x]\n", machine().describe_context(), address);
LOGMASKED(LOG_SYS, "%s: Bus error: Unused RAM access [%08x]\n", machine().describe_context(), address);
}
READ16_MEMBER(x68k_state::x68k_rom0_r)
@ -1012,7 +1018,7 @@ void x68k_state::dma_irq(int channel)
{
m_current_vector[3] = m_hd63450->get_vector(channel);
m_current_irq_line = 3;
logerror("DMA#%i: DMA End (vector 0x%02x)\n",channel,m_current_vector[3]);
LOGMASKED(LOG_SYS, "DMA#%i: DMA End (vector 0x%02x)\n",channel,m_current_vector[3]);
m_maincpu->set_input_line_and_vector(3,ASSERT_LINE,m_current_vector[3]);
}
@ -1034,7 +1040,7 @@ WRITE8_MEMBER(x68k_state::dma_error)
{
m_current_vector[3] = m_hd63450->get_error_vector(offset);
m_current_irq_line = 3;
logerror("DMA#%i: DMA Error (vector 0x%02x)\n",offset,m_current_vector[3]);
LOGMASKED(LOG_SYS, "DMA#%i: DMA Error (vector 0x%02x)\n",offset,m_current_vector[3]);
m_maincpu->set_input_line_and_vector(3,ASSERT_LINE,m_current_vector[3]);
}
}
@ -1085,7 +1091,7 @@ IRQ_CALLBACK_MEMBER(x68k_state::x68k_int_ack)
m_current_vector[6] = m_mfpdev->get_vector();
else
m_maincpu->set_input_line_and_vector(irqline,CLEAR_LINE,m_current_vector[irqline]);
logerror("SYS: IRQ acknowledged (vector=0x%02x, line = %i)\n",m_current_vector[6],irqline);
LOGMASKED(LOG_IRQ, "SYS: IRQ acknowledged (vector=0x%02x, line = %i)\n",m_current_vector[6],irqline);
return m_current_vector[6];
}
@ -1099,7 +1105,7 @@ IRQ_CALLBACK_MEMBER(x68k_state::x68k_int_ack)
m_mouse.irqactive = 0;
}
logerror("SYS: IRQ acknowledged (vector=0x%02x, line = %i)\n",m_current_vector[irqline],irqline);
LOGMASKED(LOG_IRQ, "SYS: IRQ acknowledged (vector=0x%02x, line = %i)\n",m_current_vector[irqline],irqline);
return m_current_vector[irqline];
}
@ -1427,7 +1433,7 @@ void x68k_state::floppy_load_unload(bool load, floppy_image_device *dev)
m_ioc.irqstatus |= 0x40;
m_current_irq_line = 1;
m_maincpu->set_input_line_and_vector(1,ASSERT_LINE,m_current_vector[1]); // Disk insert/eject interrupt
logerror("IOC: Disk image inserted\n");
LOGMASKED(LOG_FDC, "IOC: Disk image inserted\n");
}
}
@ -1457,7 +1463,7 @@ WRITE_LINE_MEMBER(x68k_state::x68k_irq2_line)
}
else
m_maincpu->set_input_line_and_vector(2,CLEAR_LINE,m_current_vector[2]);
logerror("EXP: IRQ2 set to %i\n",state);
LOGMASKED(LOG_IRQ, "EXP: IRQ2 set to %i\n",state);
}
@ -1465,7 +1471,7 @@ WRITE_LINE_MEMBER(x68k_state::x68k_irq4_line)
{
m_current_vector[4] = m_expansion->vector();
m_maincpu->set_input_line_and_vector(4,state,m_current_vector[4]);
logerror("EXP: IRQ4 set to %i (vector %02x)\n",state,m_current_vector[4]);
LOGMASKED(LOG_IRQ, "EXP: IRQ4 set to %i (vector %02x)\n",state,m_current_vector[4]);
}
static void x68000_exp_cards(device_slot_interface &device)
@ -1677,9 +1683,7 @@ MACHINE_CONFIG_START(x68k_state::x68000)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(55.45)
MCFG_SCREEN_SIZE(1096, 568) // initial setting
MCFG_SCREEN_VISIBLE_AREA(0, 767, 0, 511)
MCFG_SCREEN_RAW_PARAMS(69.55199_MHz_XTAL / 2, 1096, 0, 768, 568, 0, 512) // initial setting
MCFG_SCREEN_UPDATE_DRIVER(x68k_state, screen_update_x68000)
MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "pcgpalette", gfxdecode_device::empty)

View File

@ -36,6 +36,9 @@
#include "emu.h"
#include "includes/x68k.h"
//#define VERBOSE 0
#include "logmacro.h"
PALETTE_DECODER_MEMBER(x68k_state, GGGGGRRRRRBBBBBI)
{
@ -166,10 +169,14 @@ void x68k_state::x68k_crtc_refresh_mode()
if(visiblescr.max_y >= scr.max_y - 1)
visiblescr.max_y = scr.max_y - 2;
// logerror("CRTC regs - %i %i %i %i - %i %i %i %i - %i - %i\n",m_crtc.reg[0],m_crtc.reg[1],m_crtc.reg[2],m_crtc.reg[3],
// LOG("CRTC regs - %i %i %i %i - %i %i %i %i - %i - %i\n",m_crtc.reg[0],m_crtc.reg[1],m_crtc.reg[2],m_crtc.reg[3],
// m_crtc.reg[4],m_crtc.reg[5],m_crtc.reg[6],m_crtc.reg[7],m_crtc.reg[8],m_crtc.reg[9]);
logerror("m_screen->configure(%i,%i,[%i,%i,%i,%i],55.45)\n",scr.max_x,scr.max_y,visiblescr.min_x,visiblescr.min_y,visiblescr.max_x,visiblescr.max_y);
m_screen->configure(scr.max_x,scr.max_y,visiblescr,HZ_TO_ATTOSECONDS(55.45));
unsigned div = BIT(m_crtc.reg[20], 1) ? 1 : BIT(m_crtc.reg[20], 0) ? 2 : 4;
if ((m_crtc.reg[20] & 0x0c) == 0)
div *= 2;
attotime refresh = attotime::from_ticks(scr.max_x * scr.max_y, (BIT(m_crtc.reg[20], 4) ? 69.55199_MHz_XTAL : 38.86363_MHz_XTAL) / div);
LOG("m_screen->configure(%i,%i,[%i,%i,%i,%i],%f)\n", scr.max_x, scr.max_y, visiblescr.min_x, visiblescr.min_y, visiblescr.max_x, visiblescr.max_y, ATTOSECONDS_TO_HZ(refresh.as_attoseconds()));
m_screen->configure(scr.max_x, scr.max_y, visiblescr, refresh.as_attoseconds());
}
TIMER_CALLBACK_MEMBER(x68k_state::x68k_hsync)
@ -284,7 +291,7 @@ TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_raster_irq)
end_time = m_screen->time_until_pos(scan,m_crtc.hend);
m_raster_irq->adjust(irq_time, scan);
timer_set(end_time, TIMER_X68K_CRTC_RASTER_END);
logerror("GPIP6: Raster triggered at line %i (%i)\n",scan,m_screen->vpos());
LOG("GPIP6: Raster triggered at line %i (%i)\n",scan,m_screen->vpos());
}
}
@ -300,7 +307,7 @@ TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_vblank_irq)
vblank_line = m_crtc.vbegin;
irq_time = m_screen->time_until_pos(vblank_line,2);
m_vblank_irq->adjust(irq_time);
logerror("CRTC: VBlank on\n");
LOG("CRTC: VBlank on\n");
}
if(val == 0) // V-DISP off
{
@ -310,7 +317,7 @@ TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_vblank_irq)
vblank_line = m_crtc.vtotal;
irq_time = m_screen->time_until_pos(vblank_line,2);
m_vblank_irq->adjust(irq_time, 1);
logerror("CRTC: VBlank off\n");
LOG("CRTC: VBlank off\n");
}
m_mfpdev->tai_w(!m_crtc.vblank);
@ -393,7 +400,7 @@ WRITE16_MEMBER(x68k_state::x68k_crtc_w )
if(irq_time.as_double() > 0)
m_raster_irq->adjust(irq_time, (data) / m_crtc.vmultiple);
}
logerror("CRTC: Write to raster IRQ register - %i\n",data);
LOG("CRTC: Write to raster IRQ register - %i\n",data);
break;
case 20:
if(ACCESSING_BITS_0_7)
@ -446,14 +453,14 @@ WRITE16_MEMBER(x68k_state::x68k_crtc_w )
}
break;
}
// logerror("%s CRTC: Wrote %04x to CRTC register %i\n",machine().describe_context(),data,offset);
// LOG("%s CRTC: Wrote %04x to CRTC register %i\n",machine().describe_context(),data,offset);
}
READ16_MEMBER(x68k_state::x68k_crtc_r )
{
if(offset < 24)
{
// logerror("%s CRTC: Read %04x from CRTC register %i\n",machine().describe_context(),m_crtc.reg[offset],offset);
// LOG("%s CRTC: Read %04x from CRTC register %i\n",machine().describe_context(),m_crtc.reg[offset],offset);
switch(offset)
{
case 9:
@ -476,7 +483,7 @@ READ16_MEMBER(x68k_state::x68k_crtc_r )
}
if(offset == 576) // operation port, operation bits are set to 0 when operation is complete
return m_crtc.operation;
// logerror("CRTC: [%08x] Read from unknown CRTC register %i\n",activecpu_get_pc(),offset);
// LOG("CRTC: [%08x] Read from unknown CRTC register %i\n",activecpu_get_pc(),offset);
return 0xffff;
}