(MESS) mm1: Fixed floppy. [Curt Coder]

Added a new implementation of the Intel 8275 with accurate DMA timing. [Curt Coder]
This commit is contained in:
Curt Coder 2013-01-10 15:32:07 +00:00
parent b8d6e154db
commit 45319730ae
7 changed files with 820 additions and 9 deletions

2
.gitattributes vendored
View File

@ -1717,6 +1717,8 @@ src/emu/video/huc6272.c svneol=native#text/plain
src/emu/video/huc6272.h svneol=native#text/plain
src/emu/video/i8275.c svneol=native#text/plain
src/emu/video/i8275.h svneol=native#text/plain
src/emu/video/i8275x.c svneol=native#text/plain
src/emu/video/i8275x.h svneol=native#text/plain
src/emu/video/k053250.c svneol=native#text/plain
src/emu/video/k053250.h svneol=native#text/plain
src/emu/video/m50458.c svneol=native#text/plain

View File

@ -309,6 +309,7 @@ EMUVIDEOOBJS = \
$(EMUVIDEO)/huc6270.o \
$(EMUVIDEO)/huc6272.o \
$(EMUVIDEO)/i8275.o \
$(EMUVIDEO)/i8275x.o \
$(EMUVIDEO)/k053250.o \
$(EMUVIDEO)/m50458.o \
$(EMUVIDEO)/mb90082.o \

585
src/emu/video/i8275x.c Normal file
View File

@ -0,0 +1,585 @@
/**********************************************************************
Intel 8275 Programmable CRT Controller emulation
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
**********************************************************************/
/*
TODO:
- double spaced rows
*/
#include "i8275x.h"
//**************************************************************************
// MACROS / CONSTANTS
//**************************************************************************
const int DMA_BURST_SPACING[] = { 0, 7, 15, 23, 31, 39, 47, 55 };
#define DOUBLE_SPACED_ROWS \
BIT(m_param[REG_SCN1], 7)
#define CHARACTERS_PER_ROW \
((m_param[REG_SCN1] & 0x7f) + 1)
#define VRTC_ROW_COUNT \
((m_param[REG_SCN2] >> 5) + 1)
#define CHARACTER_ROWS_PER_FRAME \
((m_param[REG_SCN2] & 0x3f) + 1)
#define UNDERLINE \
(m_param[REG_SCN3] >> 4)
#define SCANLINES_PER_ROW \
((m_param[REG_SCN3] & 0x0f) + 1)
#define OFFSET_LINE_COUNTER \
BIT(m_param[REG_SCN4], 7)
#define VISIBLE_FIELD_ATTRIBUTE \
BIT(m_param[REG_SCN4], 6)
#define CURSOR_FORMAT \
((m_param[REG_SCN4] >> 4) & 0x03)
#define HRTC_COUNT \
(((m_param[REG_SCN4] & 0x0f) + 1) * 2)
#define DMA_BURST_COUNT \
(1 << (m_param[REG_DMA] & 0x03))
#define DMA_BURST_SPACE \
DMA_BURST_SPACING[(m_param[REG_DMA] >> 2) & 0x07]
//**************************************************************************
// somethign
//**************************************************************************
// device type definition
const device_type I8275x = &device_creator<i8275x_device>;
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// i8275x_device - constructor
//-------------------------------------------------
i8275x_device::i8275x_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, I8275x, "I8275", tag, owner, clock),
m_status(0),
m_param_idx(0),
m_param_end(0),
m_buffer_idx(0),
m_fifo_next(false),
m_buffer_dma(0),
m_lpen(0),
m_hlgt(0),
m_vsp(0),
m_gpa(0),
m_rvv(0),
m_lten(0),
m_scanline(0),
m_du(false),
m_cursor_blink(0),
m_char_blink(0)
{
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void i8275x_device::device_config_complete()
{
// inherit a copy of the static data
const i8275_interface *intf = reinterpret_cast<const i8275_interface *>(static_config());
if (intf != NULL)
*static_cast<i8275_interface *>(this) = *intf;
// or initialize to defaults if none provided
else
{
memset(&m_out_drq_cb, 0, sizeof(m_out_drq_cb));
memset(&m_out_irq_cb, 0, sizeof(m_out_irq_cb));
memset(&m_out_hrtc_cb, 0, sizeof(m_out_hrtc_cb));
memset(&m_out_vrtc_cb, 0, sizeof(m_out_vrtc_cb));
}
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void i8275x_device::device_start()
{
// get the screen device
m_screen = machine().device<screen_device>(m_screen_tag);
assert(m_screen != NULL);
m_screen->register_screen_bitmap(m_bitmap);
// resolve callbacks
m_out_drq_func.resolve(m_out_drq_cb, *this);
m_out_irq_func.resolve(m_out_irq_cb, *this);
m_out_hrtc_func.resolve(m_out_hrtc_cb, *this);
m_out_vrtc_func.resolve(m_out_vrtc_cb, *this);
// allocate timers
m_hrtc_on_timer = timer_alloc(TIMER_HRTC_ON);
m_drq_on_timer = timer_alloc(TIMER_DRQ_ON);
m_drq_off_timer = timer_alloc(TIMER_DRQ_OFF);
m_scanline_timer = timer_alloc(TIMER_SCANLINE);
// state saving
save_item(NAME(m_status));
save_item(NAME(m_param));
save_item(NAME(m_param_idx));
save_item(NAME(m_param_end));
save_item(NAME(m_buffer[0]));
save_item(NAME(m_buffer[1]));
save_item(NAME(m_buffer_idx));
save_item(NAME(m_fifo_idx));
save_item(NAME(m_fifo_next));
save_item(NAME(m_buffer_dma));
save_item(NAME(m_lpen));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void i8275x_device::device_reset()
{
m_status &= ~ST_IE;
m_out_irq_func(CLEAR_LINE);
}
//-------------------------------------------------
// device_timer - handle timer events
//-------------------------------------------------
void i8275x_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
int y = m_screen->vpos();
int x = m_screen->hpos();
int rc = m_scanline / SCANLINES_PER_ROW;
int lc = m_scanline % SCANLINES_PER_ROW;
switch (id)
{
case TIMER_HRTC_ON:
//logerror("I8275 '%s' y %u x %u HRTC 1\n", tag(), y, x);
m_out_hrtc_func(1);
break;
case TIMER_DRQ_ON:
logerror("I8275 '%s' y %u x %u DRQ 1\n", tag(), y, x);
m_out_drq_func(1);
m_drq_off_timer->adjust(clocks_to_attotime(DMA_BURST_COUNT));
break;
case TIMER_DRQ_OFF:
if (m_buffer_idx == 0)
{
m_status |= ST_DU;
m_du = true;
logerror("I8275 '%s' y %u x %u DRQ 0\n", tag(), y, x);
m_out_drq_func(0);
}
else if (m_buffer_idx == CHARACTERS_PER_ROW)
{
logerror("I8275 '%s' y %u x %u DRQ 0\n", tag(), y, x);
m_out_drq_func(0);
}
else if (DMA_BURST_SPACE > 0)
{
logerror("I8275 '%s' y %u x %u DRQ 0\n", tag(), y, x);
m_out_drq_func(0);
m_drq_on_timer->adjust(clocks_to_attotime(DMA_BURST_SPACE));
}
break;
case TIMER_SCANLINE:
if (!(m_status & ST_VE)) break;
//logerror("I8275 '%s' y %u x %u HRTC 0\n", tag(), y, x);
m_out_hrtc_func(0);
if (m_scanline == 0)
{
//logerror("I8275 '%s' y %u x %u VRTC 0\n", tag(), y, x);
m_out_vrtc_func(0);
}
else if (m_scanline == m_irq_scanline)
{
if (m_status & ST_IE)
{
//logerror("I8275 '%s' y %u x %u IRQ 1\n", tag(), y, x);
m_status |= ST_IR;
m_out_irq_func(ASSERT_LINE);
}
}
else if (m_scanline == m_vrtc_scanline)
{
//logerror("I8275 '%s' y %u x %u VRTC 1\n", tag(), y, x);
m_out_vrtc_func(1);
// reset field attributes
m_hlgt = 0;
m_vsp = 0;
m_gpa = 0;
m_rvv = 0,
m_lten = 0;
m_du = false;
m_cursor_blink++;
m_cursor_blink &= 0x1f;
m_char_blink++;
m_char_blink &= 0x3f;
}
if (lc == 0)
{
// swap line buffers
m_buffer_dma = !m_buffer_dma;
m_buffer_idx = 0;
m_fifo_idx = 0;
if (!m_du && ((m_scanline < m_vrtc_scanline - SCANLINES_PER_ROW) || (m_scanline == m_vrtc_drq_scanline)))
{
// start DMA burst
m_drq_on_timer->adjust(clocks_to_attotime(DMA_BURST_SPACE));
}
}
if (m_scanline < m_vrtc_scanline)
{
for (int sx = 0; sx < CHARACTERS_PER_ROW; sx++)
{
int m_lineattr = 0;
int lten = 0;
int vsp = 0;
UINT8 data = m_buffer[!m_buffer_dma][sx];
if (data & 0x80)
{
if ((data & 0xc0) == 0x80)
{
// field attribute code
m_hlgt = (data & FAC_H) ? 1 : 0;
m_vsp = (data & FAC_B) ? 1 : 0;
m_gpa = (data & FAC_GG) >> 2;
m_rvv = (data & FAC_R) ? 1 : 0;
m_lten = (data & FAC_U) ? 1 : 0;
if (!VISIBLE_FIELD_ATTRIBUTE)
{
int fifo_idx = 0;
data = m_fifo[!m_buffer_dma][fifo_idx];
fifo_idx++;
fifo_idx &= 0xf;
}
else
{
vsp = 1;
}
}
else
{
// character attribute code
}
}
if (!vsp && m_vsp)
{
vsp = (m_char_blink < 32) ? 1 : 0;
}
if ((rc == m_param[REG_CUR_ROW]) && (sx == m_param[REG_CUR_COL]))
{
int vis = 1;
if (!(CURSOR_FORMAT & 0x02))
{
vis = (m_cursor_blink < 16) ? 1 : 0;
}
if (CURSOR_FORMAT & 0x01)
{
lten = (lc == UNDERLINE) ? vis : 0;
}
else
{
lten = vis;
}
}
if (OFFSET_LINE_COUNTER)
{
lc = (lc - 1) & 0x0f;
}
m_display_pixels_func(this, m_bitmap,
sx * m_hpixels_per_column, // x position on screen of starting point
m_scanline, // y position on screen
lc, // current line of char
(data & 0x7f), // char code to be displayed
m_lineattr, // line attribute code
lten | m_lten, // light enable signal
m_rvv, // reverse video signal
vsp, // video suppression
m_gpa, // general purpose attribute code
m_hlgt // highlight
);
}
}
m_scanline++;
m_scanline %= ((CHARACTER_ROWS_PER_FRAME + VRTC_ROW_COUNT) * SCANLINES_PER_ROW);
break;
}
}
//-------------------------------------------------
// read -
//-------------------------------------------------
READ8_MEMBER( i8275x_device::read )
{
UINT8 data = 0;
if (offset & 0x01)
{
data = m_status;
if (m_status & ST_IR)
{
//logerror("I8275 '%s' IRQ 0\n", tag());
m_out_irq_func(CLEAR_LINE);
}
m_status &= ~(ST_IR | ST_LP | ST_IC | ST_DU | ST_FO);
}
else
{
data = m_param[m_param_idx];
m_param_idx++;
if (m_param_idx > m_param_end)
{
m_status |= ST_IC;
}
}
return data;
}
//-------------------------------------------------
// write -
//-------------------------------------------------
WRITE8_MEMBER( i8275x_device::write )
{
if (offset & 0x01)
{
logerror("I8275 '%s' Command %02x\n", tag(), data);
switch (data >> 5)
{
case CMD_RESET:
logerror("I8275 '%s' Reset\n", tag());
m_status &= ~ST_IE;
logerror("I8275 '%s' IRQ 0\n", tag());
m_out_irq_func(CLEAR_LINE);
m_param_idx = REG_SCN1;
m_param_end = REG_SCN4;
break;
case CMD_START_DISPLAY:
{
m_param[REG_DMA] = data;
logerror("I8275 '%s' Start Display %u %u\n", tag(), DMA_BURST_COUNT, DMA_BURST_SPACE);
m_status |= (ST_IE | ST_VE);
}
break;
case CMD_STOP_DISPLAY:
logerror("I8275 '%s' Stop Display\n", tag());
m_status &= ~ST_VE;
break;
case CMD_READ_LIGHT_PEN:
logerror("I8275 '%s' Read Light Pen\n", tag());
m_param_idx = REG_LPEN_COL;
m_param_end = REG_LPEN_ROW;
break;
case CMD_LOAD_CURSOR:
logerror("I8275 '%s' Load Cursor\n", tag());
m_param_idx = REG_CUR_COL;
m_param_end = REG_CUR_ROW;
break;
case CMD_ENABLE_INTERRUPT:
logerror("I8275 '%s' Enable Interrupt\n", tag());
m_status |= ST_IE;
break;
case CMD_DISABLE_INTERRUPT:
logerror("I8275 '%s' Disable Interrupt\n", tag());
m_status &= ~ST_IE;
break;
case CMD_PRESET_COUNTERS:
logerror("I8275 '%s' Preset Counters\n", tag());
m_scanline = 0;
break;
}
}
else
{
logerror("I8275 '%s' Parameter %02x\n", tag(), data);
m_param[m_param_idx] = data;
if (m_param_idx == REG_SCN4)
{
recompute_parameters();
}
m_param_idx++;
}
}
//-------------------------------------------------
// dack_w -
//-------------------------------------------------
WRITE8_MEMBER( i8275x_device::dack_w )
{
logerror("DACK write %02x %u\n", data, m_buffer_idx);
if (m_fifo_next)
{
if (m_fifo_idx == 16)
{
m_fifo_idx = 0;
m_status |= ST_FO;
}
m_fifo[m_buffer_dma][m_fifo_idx++] = data;
m_fifo_next = false;
}
else
{
m_buffer[m_buffer_dma][m_buffer_idx++] = data;
if (!VISIBLE_FIELD_ATTRIBUTE && ((data & 0xc0) == 0x80))
{
m_fifo_next = true;
}
if (m_buffer_idx == CHARACTERS_PER_ROW)
{
m_drq_off_timer->adjust(attotime::zero);
}
}
}
//-------------------------------------------------
// lpen_w -
//-------------------------------------------------
WRITE_LINE_MEMBER( i8275x_device::lpen_w )
{
if (!m_lpen && state)
{
m_param[REG_LPEN_COL] = m_screen->hpos() / m_hpixels_per_column;
m_param[REG_LPEN_ROW] = m_screen->vpos() / SCANLINES_PER_ROW;
m_status |= ST_LP;
}
m_lpen = state;
}
//-------------------------------------------------
// screen_update -
//-------------------------------------------------
UINT32 i8275x_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
if (!(m_status & ST_VE))
{
m_bitmap.fill(RGB_BLACK);
}
copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
return 0;
}
//-------------------------------------------------
// recompute_parameters -
//-------------------------------------------------
void i8275x_device::recompute_parameters()
{
int y = m_screen->vpos();
int horiz_pix_total = (CHARACTERS_PER_ROW + HRTC_COUNT) * m_hpixels_per_column;
int vert_pix_total = (CHARACTER_ROWS_PER_FRAME + VRTC_ROW_COUNT) * SCANLINES_PER_ROW;
attoseconds_t refresh = m_screen->frame_period().attoseconds;
int max_visible_x = (CHARACTERS_PER_ROW * m_hpixels_per_column) - 1;
int max_visible_y = (CHARACTER_ROWS_PER_FRAME * SCANLINES_PER_ROW) - 1;
logerror("width %u height %u max_x %u max_y %u refresh %f\n", horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, 1 / ATTOSECONDS_TO_DOUBLE(refresh));
rectangle visarea;
visarea.set(0, max_visible_x, 0, max_visible_y);
m_screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh);
int hrtc_on_pos = CHARACTERS_PER_ROW * m_hpixels_per_column;
m_hrtc_on_timer->adjust(m_screen->time_until_pos(y, hrtc_on_pos), 0, m_screen->scan_period());
m_irq_scanline = (CHARACTER_ROWS_PER_FRAME - 1) * SCANLINES_PER_ROW;
m_vrtc_scanline = CHARACTER_ROWS_PER_FRAME * SCANLINES_PER_ROW;
m_vrtc_drq_scanline = vert_pix_total - SCANLINES_PER_ROW;
m_scanline_timer->adjust(m_screen->time_until_pos(0, 0), 0, m_screen->scan_period());
}

225
src/emu/video/i8275x.h Normal file
View File

@ -0,0 +1,225 @@
/**********************************************************************
Intel 8275 Programmable CRT Controller emulation
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
**********************************************************************
_____ _____
LC3 1 |* \_/ | 40 Vcc
LC2 2 | | 39 LA0
LC1 3 | | 38 LA1
LC0 4 | | 37 LTEN
DRQ 5 | | 36 RVV
_DACK 6 | | 35 VSP
HRTC 7 | | 34 GPA1
VRTC 8 | | 33 GPA0
_RD 9 | | 32 HLGT
_WR 10 | 8275 | 31 IRQ
LPEN 11 | | 30 CCLK
DB0 12 | | 29 CC6
DB1 13 | | 28 CC5
DB2 14 | | 27 CC4
DB3 15 | | 26 CC3
DB4 16 | | 25 CC2
DB5 17 | | 24 CC1
DB6 18 | | 23 CC0
DB7 19 | | 22 _CS
GND 20 |_____________| 21 A0
**********************************************************************/
#pragma once
#ifndef __I8275x__
#define __I8275x__
#include "emu.h"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_I8275_ADD(_tag, _clock, _config) \
MCFG_DEVICE_ADD(_tag, I8275x, _clock) \
MCFG_DEVICE_CONFIG(_config)
#define I8275_INTERFACE(name) \
const i8275_interface (name) =
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class i8275x_device;
// ======================> i8275_display_pixels_func
typedef void (*i8275_display_pixels_func)(i8275x_device *device, bitmap_rgb32 &bitmap, int x, int y, UINT8 linecount, UINT8 charcode, UINT8 lineattr, UINT8 lten, UINT8 rvv, UINT8 vsp, UINT8 gpa, UINT8 hlgt);
#define I8275_DISPLAY_PIXELS(name) void name(i8275x_device *device, bitmap_rgb32 &bitmap, int x, int y, UINT8 linecount, UINT8 charcode, UINT8 lineattr, UINT8 lten, UINT8 rvv, UINT8 vsp, UINT8 gpa, UINT8 hlgt)
// ======================> i8275_interface
struct i8275_interface
{
const char *m_screen_tag;
int m_hpixels_per_column;
int m_dummy;
devcb_write_line m_out_drq_cb;
devcb_write_line m_out_irq_cb;
devcb_write_line m_out_hrtc_cb;
devcb_write_line m_out_vrtc_cb;
i8275_display_pixels_func m_display_pixels_func;
};
// ======================> i8275x_device
class i8275x_device : public device_t,
public i8275_interface
{
public:
// construction/destruction
i8275x_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
DECLARE_WRITE8_MEMBER( dack_w );
DECLARE_WRITE_LINE_MEMBER( lpen_w );
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
void recompute_parameters();
enum
{
TIMER_HRTC_ON,
TIMER_DRQ_ON,
TIMER_DRQ_OFF,
TIMER_SCANLINE
};
enum
{
ST_IE = 0x40,
ST_IR = 0x20,
ST_LP = 0x10,
ST_IC = 0x08,
ST_VE = 0x04,
ST_DU = 0x02,
ST_FO = 0x01
};
enum
{
CMD_RESET = 0,
CMD_START_DISPLAY,
CMD_STOP_DISPLAY,
CMD_READ_LIGHT_PEN,
CMD_LOAD_CURSOR,
CMD_ENABLE_INTERRUPT,
CMD_DISABLE_INTERRUPT,
CMD_PRESET_COUNTERS
};
enum
{
REG_SCN1 = 0,
REG_SCN2,
REG_SCN3,
REG_SCN4,
REG_CUR_COL,
REG_CUR_ROW,
REG_LPEN_COL,
REG_LPEN_ROW,
REG_DMA
};
enum
{
CA_H = 0x01,
CA_B = 0x02,
CA_CCCC = 0x3c
};
enum
{
FAC_H = 0x01,
FAC_B = 0x02,
FAC_GG = 0x0c,
FAC_R = 0x10,
FAC_U = 0x20
};
devcb_resolved_write_line m_out_drq_func;
devcb_resolved_write_line m_out_irq_func;
devcb_resolved_write_line m_out_hrtc_func;
devcb_resolved_write_line m_out_vrtc_func;
screen_device *m_screen;
bitmap_rgb32 m_bitmap;
UINT8 m_status;
UINT8 m_param[REG_DMA + 1];
int m_param_idx;
int m_param_end;
UINT8 m_buffer[2][80];
UINT8 m_fifo[2][16];
int m_buffer_idx;
int m_fifo_idx;
bool m_fifo_next;
int m_buffer_dma;
int m_lpen;
int m_hlgt;
int m_vsp;
int m_gpa;
int m_rvv;
int m_lten;
int m_scanline;
int m_irq_scanline;
int m_vrtc_scanline;
int m_vrtc_drq_scanline;
bool m_du;
int m_cursor_blink;
int m_char_blink;
// timers
emu_timer *m_hrtc_on_timer;
emu_timer *m_drq_on_timer;
emu_timer *m_drq_off_timer;
emu_timer *m_scanline_timer;
};
// device type definition
extern const device_type I8275x;
#endif

View File

@ -41,8 +41,6 @@
TODO:
- fix i8275 DMA timing (full screen is transferred in 1 burst, which kills floppy sector DMA)
- add HRTC/VRTC output to i8275
- NEC uPD7220 GDC
- accurate video timing
- floppy DRQ during RECALL = 0
@ -59,7 +57,7 @@
// MACROS / CONSTANTS
//**************************************************************************
#define LOG 1
#define LOG 0
#define MMU_IOEN 0x01
#define MMU_RAMEN 0x02
@ -540,7 +538,7 @@ static I8237_INTERFACE( dmac_intf )
DEVCB_DRIVER_MEMBER(mm1_state, read),
DEVCB_DRIVER_MEMBER(mm1_state, write),
{ DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(mm1_state, mpsc_dack_r), DEVCB_DEVICE_MEMBER(UPD765_TAG, upd765_family_device, mdma_r) },
{ DEVCB_DEVICE_MEMBER(I8275_TAG, i8275_device, dack_w), DEVCB_DRIVER_MEMBER(mm1_state, mpsc_dack_w), DEVCB_NULL, DEVCB_DEVICE_MEMBER(UPD765_TAG, upd765_family_device, mdma_w) },
{ DEVCB_DEVICE_MEMBER(I8275_TAG, i8275x_device, dack_w), DEVCB_DRIVER_MEMBER(mm1_state, mpsc_dack_w), DEVCB_NULL, DEVCB_DEVICE_MEMBER(UPD765_TAG, upd765_family_device, mdma_w) },
{ DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_LINE_MEMBER(mm1_state, dack3_w) }
};
@ -841,5 +839,5 @@ ROM_END
//**************************************************************************
// YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS
COMP( 1981, mm1m6, 0, 0, mm1m6, mm1, driver_device, 0, "Nokia Data", "MikroMikko 1 M6", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
COMP( 1981, mm1m7, mm1m6, 0, mm1m7, mm1, driver_device, 0, "Nokia Data", "MikroMikko 1 M7", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
COMP( 1981, mm1m6, 0, 0, mm1m6, mm1, driver_device, 0, "Nokia Data", "MikroMikko 1 M6", GAME_SUPPORTS_SAVE )
COMP( 1981, mm1m7, mm1m6, 0, mm1m7, mm1, driver_device, 0, "Nokia Data", "MikroMikko 1 M7", GAME_SUPPORTS_SAVE )

View File

@ -13,7 +13,7 @@
#include "machine/upd7201.h"
#include "machine/upd765.h"
#include "sound/speaker.h"
#include "video/i8275.h"
#include "video/i8275x.h"
#include "video/upd7220.h"
#define SCREEN_TAG "screen"
@ -55,7 +55,7 @@ public:
required_device<i8212_device> m_iop;
required_device<am9517a_device> m_dmac;
required_device<pit8253_device> m_pit;
required_device<i8275_device> m_crtc;
required_device<i8275x_device> m_crtc;
required_device<upd765a_device> m_fdc;
required_device<upd7201_device> m_mpsc;
required_device<upd7220_device> m_hgdc;

View File

@ -150,6 +150,6 @@ MACHINE_CONFIG_FRAGMENT( mm1m6_video )
MCFG_GFXDECODE(mm1)
MCFG_I8275_ADD(I8275_TAG, crtc_intf) // XTAL_18_720MHz/8
MCFG_I8275_ADD(I8275_TAG, XTAL_18_720MHz/8, crtc_intf)
MCFG_UPD7220_ADD(UPD7220_TAG, XTAL_18_720MHz/8, hgdc_intf, mm1_upd7220_map)
MACHINE_CONFIG_END