mirror of
https://github.com/holub/mame
synced 2025-05-23 14:19:01 +03:00
Transparent mc6545 phi1/pi2 addressing
* implemented support for phi1/phi2 transparent addressing * added callback to communicate address back to driver Implementation is not and can not be "clock" accurate since the timing is totally up to the hardware implementation. It is the main cpu and hardware which determines phi clocking and when data is written to video ram. The only support in the 6545 is that the update address is latched out to the ma lines during phi2.
This commit is contained in:
parent
5612216269
commit
08f0fa3f6c
@ -26,7 +26,7 @@
|
|||||||
#include "mc6845.h"
|
#include "mc6845.h"
|
||||||
|
|
||||||
|
|
||||||
#define LOG (0)
|
#define LOG (1)
|
||||||
|
|
||||||
|
|
||||||
/* device types */
|
/* device types */
|
||||||
@ -43,6 +43,13 @@ enum
|
|||||||
NUM_TYPES
|
NUM_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* mode macros */
|
||||||
|
|
||||||
|
#define MODE_TRANSPARENT(d) (((d)->mode_control & 0x08) != 0)
|
||||||
|
#define MODE_TRANSPARENT_PHI2(d) (((d)->mode_control & 0x88) == 0x88)
|
||||||
|
/* FIXME: not supported yet */
|
||||||
|
#define MODE_TRANSPARENT_BLANK(d) (((d)->mode_control & 0x88) == 0x08)
|
||||||
|
#define MODE_UPDATE_STROBE(d) (((d)->mode_control & 0x40) != 0)
|
||||||
|
|
||||||
/* tags for state saving */
|
/* tags for state saving */
|
||||||
static const char * const device_tags[NUM_TYPES] = { "mc6845", "mc6845-1", "c6545-1", "r6545-1", "h46505", "hd6845", "sy6545-1" };
|
static const char * const device_tags[NUM_TYPES] = { "mc6845", "mc6845-1", "c6545-1", "r6545-1", "h46505", "hd6845", "sy6545-1" };
|
||||||
@ -53,6 +60,9 @@ static const int supports_vert_sync_width[NUM_TYPES] = { FALSE, TRUE,
|
|||||||
static const int supports_status_reg_d5[NUM_TYPES] = { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE };
|
static const int supports_status_reg_d5[NUM_TYPES] = { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE };
|
||||||
static const int supports_status_reg_d6[NUM_TYPES] = { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE };
|
static const int supports_status_reg_d6[NUM_TYPES] = { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE };
|
||||||
|
|
||||||
|
/* FIXME: check other variants */
|
||||||
|
static const int supports_transparent[NUM_TYPES] = { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE };
|
||||||
|
|
||||||
|
|
||||||
typedef struct _mc6845_t mc6845_t;
|
typedef struct _mc6845_t mc6845_t;
|
||||||
struct _mc6845_t
|
struct _mc6845_t
|
||||||
@ -77,6 +87,7 @@ struct _mc6845_t
|
|||||||
UINT16 disp_start_addr; /* 0x0c/0x0d */
|
UINT16 disp_start_addr; /* 0x0c/0x0d */
|
||||||
UINT16 cursor_addr; /* 0x0e/0x0f */
|
UINT16 cursor_addr; /* 0x0e/0x0f */
|
||||||
UINT16 light_pen_addr; /* 0x10/0x11 */
|
UINT16 light_pen_addr; /* 0x10/0x11 */
|
||||||
|
UINT16 update_addr; /* 0x12/0x13 */
|
||||||
|
|
||||||
/* other internal state */
|
/* other internal state */
|
||||||
UINT64 clock;
|
UINT64 clock;
|
||||||
@ -138,6 +149,28 @@ static STATE_POSTLOAD( mc6845_state_save_postload )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static TIMER_CALLBACK( on_update_address_cb )
|
||||||
|
{
|
||||||
|
const device_config *device = ptr;
|
||||||
|
mc6845_t *mc6845 = get_safe_token(device);
|
||||||
|
int addr = (param >> 8);
|
||||||
|
int strobe = (param & 0xff);
|
||||||
|
|
||||||
|
/* call the callback function -- we know it exists */
|
||||||
|
mc6845->intf->on_update_addr_changed(device, addr, strobe);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE void call_on_update_address(const device_config *device, int strobe)
|
||||||
|
{
|
||||||
|
mc6845_t *mc6845 = get_safe_token(device);
|
||||||
|
|
||||||
|
if (mc6845->intf->on_update_addr_changed)
|
||||||
|
timer_set(attotime_zero, (void *) device, (mc6845->update_addr << 8) | strobe, on_update_address_cb);
|
||||||
|
else
|
||||||
|
fatalerror("M6845: transparent memory mode without handler\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE8_DEVICE_HANDLER( mc6845_address_w )
|
WRITE8_DEVICE_HANDLER( mc6845_address_w )
|
||||||
{
|
{
|
||||||
mc6845_t *mc6845 = get_safe_token(device);
|
mc6845_t *mc6845 = get_safe_token(device);
|
||||||
@ -176,6 +209,14 @@ READ8_DEVICE_HANDLER( mc6845_register_r )
|
|||||||
case 0x0f: ret = (mc6845->cursor_addr >> 0) & 0xff; break;
|
case 0x0f: ret = (mc6845->cursor_addr >> 0) & 0xff; break;
|
||||||
case 0x10: ret = (mc6845->light_pen_addr >> 8) & 0xff; mc6845->light_pen_latched = FALSE; break;
|
case 0x10: ret = (mc6845->light_pen_addr >> 8) & 0xff; mc6845->light_pen_latched = FALSE; break;
|
||||||
case 0x11: ret = (mc6845->light_pen_addr >> 0) & 0xff; mc6845->light_pen_latched = FALSE; break;
|
case 0x11: ret = (mc6845->light_pen_addr >> 0) & 0xff; mc6845->light_pen_latched = FALSE; break;
|
||||||
|
case 0x1f:
|
||||||
|
if (supports_transparent[mc6845->device_type] && MODE_TRANSPARENT(mc6845))
|
||||||
|
{
|
||||||
|
mc6845->update_addr++;
|
||||||
|
mc6845->update_addr &= 0x3fff;
|
||||||
|
call_on_update_address(device, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* all other registers are write only and return 0 */
|
/* all other registers are write only and return 0 */
|
||||||
default: break;
|
default: break;
|
||||||
@ -211,12 +252,35 @@ WRITE8_DEVICE_HANDLER( mc6845_register_w )
|
|||||||
case 0x0f: mc6845->cursor_addr = ((data & 0xff) << 0) | (mc6845->cursor_addr & 0xff00); break;
|
case 0x0f: mc6845->cursor_addr = ((data & 0xff) << 0) | (mc6845->cursor_addr & 0xff00); break;
|
||||||
case 0x10: /* read-only */ break;
|
case 0x10: /* read-only */ break;
|
||||||
case 0x11: /* read-only */ break;
|
case 0x11: /* read-only */ break;
|
||||||
|
case 0x12:
|
||||||
|
if (supports_transparent[mc6845->device_type])
|
||||||
|
{
|
||||||
|
mc6845->update_addr = ((data & 0x3f) << 8) | (mc6845->update_addr & 0x00ff);
|
||||||
|
call_on_update_address(device, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x13:
|
||||||
|
if (supports_transparent[mc6845->device_type])
|
||||||
|
{
|
||||||
|
mc6845->update_addr = ((data & 0xff) << 0) | (mc6845->update_addr & 0xff00);
|
||||||
|
call_on_update_address(device, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x1f:
|
||||||
|
if (supports_transparent[mc6845->device_type] && MODE_TRANSPARENT(mc6845))
|
||||||
|
{
|
||||||
|
mc6845->update_addr++;
|
||||||
|
mc6845->update_addr &= 0x3fff;
|
||||||
|
call_on_update_address(device, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* display message if the Mode Control register is not zero */
|
/* display message if the Mode Control register is not zero */
|
||||||
if ((mc6845->register_address_latch == 0x08) && (mc6845->mode_control != 0))
|
if ((mc6845->register_address_latch == 0x08) && (mc6845->mode_control != 0))
|
||||||
popmessage("Mode Control %02X is not supported!!!", mc6845->mode_control);
|
if (!(supports_transparent[mc6845->device_type] && MODE_TRANSPARENT_PHI2(mc6845)))
|
||||||
|
popmessage("Mode Control %02X is not supported!!!", mc6845->mode_control);
|
||||||
|
|
||||||
recompute_parameters(mc6845, FALSE);
|
recompute_parameters(mc6845, FALSE);
|
||||||
}
|
}
|
||||||
@ -746,6 +810,7 @@ static device_start_err common_start(const device_config *device, int device_typ
|
|||||||
state_save_register_item(unique_tag, 0, mc6845->light_pen_latched);
|
state_save_register_item(unique_tag, 0, mc6845->light_pen_latched);
|
||||||
state_save_register_item(unique_tag, 0, mc6845->cursor_state);
|
state_save_register_item(unique_tag, 0, mc6845->cursor_state);
|
||||||
state_save_register_item(unique_tag, 0, mc6845->cursor_blink_count);
|
state_save_register_item(unique_tag, 0, mc6845->cursor_blink_count);
|
||||||
|
state_save_register_item(unique_tag, 0, mc6845->update_addr);
|
||||||
|
|
||||||
return DEVICE_START_OK;
|
return DEVICE_START_OK;
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,8 @@ typedef void (*mc6845_on_hsync_changed_func)(const device_config *device, int hs
|
|||||||
typedef void (*mc6845_on_vsync_changed_func)(const device_config *device, int vsync);
|
typedef void (*mc6845_on_vsync_changed_func)(const device_config *device, int vsync);
|
||||||
#define MC6845_ON_VSYNC_CHANGED(name) void name(const device_config *device, int vsync)
|
#define MC6845_ON_VSYNC_CHANGED(name) void name(const device_config *device, int vsync)
|
||||||
|
|
||||||
|
typedef void (*mc6845_on_update_addr_changed_func)(const device_config *device, int address, int strobe);
|
||||||
|
#define MC6845_ON_UPDATE_ADDR_CHANGED(name) void name(const device_config *device, int address, int strobe)
|
||||||
|
|
||||||
/* interface */
|
/* interface */
|
||||||
typedef struct _mc6845_interface mc6845_interface;
|
typedef struct _mc6845_interface mc6845_interface;
|
||||||
@ -74,6 +76,12 @@ struct _mc6845_interface
|
|||||||
|
|
||||||
/* if specified, this gets called for every change of the VSYNC pin (pin 40) */
|
/* if specified, this gets called for every change of the VSYNC pin (pin 40) */
|
||||||
mc6845_on_vsync_changed_func on_vsync_changed;
|
mc6845_on_vsync_changed_func on_vsync_changed;
|
||||||
|
|
||||||
|
/* Called whenenever the update address changes
|
||||||
|
* For vblank/hblank timing strobe indicates the physical update.
|
||||||
|
* vblank/hblank timing not supported yet! */
|
||||||
|
|
||||||
|
mc6845_on_update_addr_changed_func on_update_addr_changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user