Cidelsa changes:

- Combined CDP1869 video and sound parts to one device
- Refactored CDP1852 to use devcb
This commit is contained in:
Curt Coder 2009-02-16 07:45:00 +00:00
parent b3e1fbd1fb
commit 6fc10ff553
11 changed files with 1262 additions and 1511 deletions

2
.gitattributes vendored
View File

@ -957,8 +957,6 @@ src/emu/uismall.png -text svneol=unset#image/png
src/emu/validity.c svneol=native#text/plain
src/emu/video.c svneol=native#text/plain
src/emu/video.h svneol=native#text/plain
src/emu/video/cdp1869.c svneol=native#text/plain
src/emu/video/cdp1869.h svneol=native#text/plain
src/emu/video/generic.c svneol=native#text/plain
src/emu/video/generic.h svneol=native#text/plain
src/emu/video/mc6845.c svneol=native#text/plain

View File

@ -176,7 +176,6 @@ EMUMACHINEOBJS = \
$(EMUMACHINE)/z80sio.o \
EMUVIDEOOBJS = \
$(EMUVIDEO)/cdp1869.o \
$(EMUVIDEO)/generic.o \
$(EMUVIDEO)/mc6845.o \
$(EMUVIDEO)/poly.o \

View File

@ -10,11 +10,18 @@
#include "driver.h"
#include "cdp1852.h"
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
typedef struct _cdp1852_t cdp1852_t;
struct _cdp1852_t
{
const cdp1852_interface *intf; /* interface */
devcb_resolved_write_line out_sr_func;
devcb_resolved_read8 in_data_func;
devcb_resolved_write8 out_data_func;
cdp1852_mode mode; /* operation mode */
int new_data; /* new data written */
UINT8 data; /* data latch */
UINT8 next_data; /* next data*/
@ -26,41 +33,59 @@ struct _cdp1852_t
emu_timer *scan_timer; /* scan timer */
};
/***************************************************************************
INLINE FUNCTIONS
***************************************************************************/
INLINE cdp1852_t *get_safe_token(const device_config *device)
{
assert(device != NULL);
assert(device->token != NULL);
return (cdp1852_t *)device->token;
}
static void set_sr_line(const device_config *device, int level)
INLINE const cdp1852_interface *get_interface(const device_config *device)
{
cdp1852_t *cdp1852 = get_safe_token(device);
assert(device != NULL);
assert((device->type == CDP1852));
return (const cdp1852_interface *) device->static_config;
}
if (cdp1852->intf->on_sr_changed)
{
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
/*-------------------------------------------------
set_sr_line - service request out
-------------------------------------------------*/
static void set_sr_line(cdp1852_t *cdp1852, int level)
{
if (cdp1852->sr != level)
{
cdp1852->intf->on_sr_changed(device, level);
cdp1852->sr = level;
}
devcb_call_write_line(&cdp1852->out_sr_func, cdp1852->sr);
}
}
/*-------------------------------------------------
TIMER_CALLBACK( cdp1852_scan_tick )
-------------------------------------------------*/
static TIMER_CALLBACK( cdp1852_scan_tick )
{
const device_config *device = ptr;
cdp1852_t *cdp1852 = get_safe_token(device);
switch (cdp1852->intf->mode)
switch (cdp1852->mode)
{
case CDP1852_MODE_INPUT:
// input data into register
cdp1852->data = cdp1852->intf->data_r(device);
/* input data into register */
cdp1852->data = devcb_call_read8(&cdp1852->in_data_func, 0);
// signal processor
set_sr_line(device, 0);
/* signal processor */
set_sr_line(cdp1852, 0);
break;
case CDP1852_MODE_OUTPUT:
@ -68,80 +93,79 @@ static TIMER_CALLBACK( cdp1852_scan_tick )
{
cdp1852->new_data = 0;
// latch data into register
/* latch data into register */
cdp1852->data = cdp1852->next_data;
// output data
cdp1852->intf->data_w(device, cdp1852->data);
/* output data */
devcb_call_write8(&cdp1852->out_data_func, 0, cdp1852->data);
// signal peripheral device
set_sr_line(device, 1);
/* signal peripheral device */
set_sr_line(cdp1852, 1);
cdp1852->next_sr = 0;
}
else
{
set_sr_line(device, cdp1852->next_sr);
set_sr_line(cdp1852, cdp1852->next_sr);
}
break;
}
}
/* Data Access */
/*-------------------------------------------------
cdp1852_data_r - data register read
-------------------------------------------------*/
READ8_DEVICE_HANDLER( cdp1852_data_r )
{
cdp1852_t *cdp1852 = get_safe_token(device);
if (cdp1852->intf->mode == CDP1852_MODE_INPUT && device->clock == 0)
if (cdp1852->mode == CDP1852_MODE_INPUT && device->clock == 0)
{
// input data into register
cdp1852->data = cdp1852->intf->data_r(device);
cdp1852->data = devcb_call_read8(&cdp1852->in_data_func, 0);
}
set_sr_line(device, 1);
set_sr_line(cdp1852, 1);
return cdp1852->data;
}
/*-------------------------------------------------
cdp1852_data_r - data register write
-------------------------------------------------*/
WRITE8_DEVICE_HANDLER( cdp1852_data_w )
{
cdp1852_t *cdp1852 = get_safe_token(device);
if (cdp1852->intf->mode == CDP1852_MODE_OUTPUT)
if (cdp1852->mode == CDP1852_MODE_OUTPUT)
{
cdp1852->next_data = data;
cdp1852->new_data = 1;
}
}
/* Device Interface */
/*-------------------------------------------------
DEVICE_START( cdp1852 )
-------------------------------------------------*/
static DEVICE_START( cdp1852 )
{
cdp1852_t *cdp1852 = get_safe_token(device);
const cdp1852_interface *intf = get_interface(device);
/* validate arguments */
assert(device != NULL);
assert(device->tag != NULL);
/* resolve callbacks */
devcb_resolve_read8(&cdp1852->in_data_func, &intf->in_data_func, device);
devcb_resolve_write8(&cdp1852->out_data_func, &intf->out_data_func, device);
devcb_resolve_write_line(&cdp1852->out_sr_func, &intf->out_sr_func, device);
cdp1852->intf = device->static_config;
/* set initial values */
cdp1852->mode = intf->mode;
assert(cdp1852->intf != NULL);
if (cdp1852->intf->mode == CDP1852_MODE_INPUT)
{
assert(cdp1852->intf->data_r != NULL);
}
else
{
assert(device->clock > 0);
assert(cdp1852->intf->data_w != NULL);
}
/* create the timers */
if (device->clock > 0)
{
/* create the scan timer */
cdp1852->scan_timer = timer_alloc(device->machine, cdp1852_scan_tick, (void *)device);
timer_adjust_periodic(cdp1852->scan_timer, attotime_zero, 0, ATTOTIME_IN_HZ(device->clock));
}
@ -154,35 +178,35 @@ static DEVICE_START( cdp1852 )
state_save_register_device_item(device, 0, cdp1852->next_sr);
}
/*-------------------------------------------------
DEVICE_RESET( cdp1852 )
-------------------------------------------------*/
static DEVICE_RESET( cdp1852 )
{
cdp1852_t *cdp1852 = get_safe_token(device);
// reset data register
/* reset data register */
cdp1852->data = 0;
if (cdp1852->intf->mode == CDP1852_MODE_INPUT)
if (cdp1852->mode == CDP1852_MODE_INPUT)
{
// reset service request flip-flop
set_sr_line(device, 1);
/* reset service request flip-flop */
set_sr_line(cdp1852, 1);
}
else
{
// output data
cdp1852->intf->data_w(device, 0);
/* output data */
devcb_call_write8(&cdp1852->out_data_func, 0, cdp1852->data);
// reset service request flip-flop
set_sr_line(device, 0);
/* reset service request flip-flop */
set_sr_line(cdp1852, 0);
}
}
static DEVICE_SET_INFO( cdp1852 )
{
switch (state)
{
/* no parameters to set */
}
}
/*-------------------------------------------------
DEVICE_GET_INFO( cdp1852 )
-------------------------------------------------*/
DEVICE_GET_INFO( cdp1852 )
{
@ -194,7 +218,7 @@ DEVICE_GET_INFO( cdp1852 )
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(cdp1852); break;
case DEVINFO_FCT_SET_INFO: /* Nothing */ break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(cdp1852); break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(cdp1852); break;

View File

@ -25,17 +25,14 @@
#ifndef __CDP1852__
#define __CDP1852__
#include "devcb.h"
/***************************************************************************
MACROS / CONSTANTS
***************************************************************************/
#define CDP1852_CLOCK_HIGH 0
typedef UINT8 (*cdp1852_data_read_func) (const device_config *device);
#define CDP1852_DATA_READ(name) UINT8 name(const device_config *device)
typedef void (*cdp1852_data_write_func) (const device_config *device, UINT8 data);
#define CDP1852_DATA_WRITE(name) void name(const device_config *device, UINT8 data)
typedef void (*cdp1852_on_sr_changed_func) (const device_config *device, int level);
#define CDP1852_ON_SR_CHANGED(name) void name(const device_config *device, int level)
#define CDP1852 DEVICE_GET_INFO_NAME(cdp1852)
#define MDRV_CDP1852_ADD(_tag, _clock, _config) \
@ -45,6 +42,12 @@ typedef void (*cdp1852_on_sr_changed_func) (const device_config *device, int lev
#define MDRV_CDP1852_REMOVE(_tag) \
MDRV_DEVICE_REMOVE(_tag, CDP1852)
#define CDP1852_INTERFACE(_name) \
const cdp1852_interface (_name)=
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
typedef enum _cdp1852_mode cdp1852_mode;
enum _cdp1852_mode {
@ -52,22 +55,24 @@ enum _cdp1852_mode {
CDP1852_MODE_OUTPUT
};
/* interface */
typedef struct _cdp1852_interface cdp1852_interface;
struct _cdp1852_interface
{
int mode; /* operation mode */
/* this gets called for every external data read */
cdp1852_data_read_func data_r;
devcb_read8 in_data_func;
/* this gets called for every external data write */
cdp1852_data_write_func data_w;
devcb_write8 out_data_func;
/* this gets called for every change of the SR pin (pin 23) */
cdp1852_on_sr_changed_func on_sr_changed;
devcb_write_line out_sr_func;
};
#define CDP1852_INTERFACE(name) const cdp1852_interface (name)=
/***************************************************************************
PROTOTYPES
***************************************************************************/
/* device interface */
DEVICE_GET_INFO( cdp1852 );

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,9 @@
/*
RCA CDP1869/70/76 Video Interface System (VIS)
http://homepage.mac.com/ruske/cosmacelf/cdp1869.pdf
________________ ________________
TPA 1 ---| \/ |--- 40 Vdd PREDISPLAY_ 1 ---| \/ |--- 40 Vdd
TPB 2 ---| |--- 39 PMSEL *DISPLAY_ 2 ---| |--- 39 PAL/NTSC_
@ -27,20 +31,152 @@
*/
#pragma once
#ifndef __CDP1869__
#define __CDP1869__
#ifndef __CDP1869_H__
#define __CDP1869_H__
#include "devcb.h"
void cdp1869_set_toneamp(const device_config *device, int value);
void cdp1869_set_tonefreq(const device_config *device, int value);
void cdp1869_set_toneoff(const device_config *device, int value);
void cdp1869_set_tonediv(const device_config *device, int value);
void cdp1869_set_wnamp(const device_config *device, int value);
void cdp1869_set_wnfreq(const device_config *device, int value);
void cdp1869_set_wnoff(const device_config *device, int value);
/***************************************************************************
MACROS / CONSTANTS
***************************************************************************/
#define CDP1869_DOT_CLK_PAL 5626000.0
#define CDP1869_DOT_CLK_NTSC 5670000.0
#define CDP1869_COLOR_CLK_PAL 8867236.0
#define CDP1869_COLOR_CLK_NTSC 7159090.0
#define CDP1869_CPU_CLK_PAL (CDP1869_DOT_CLK_PAL / 2)
#define CDP1869_CPU_CLK_NTSC (CDP1869_DOT_CLK_NTSC / 2)
#define CDP1869_CHAR_WIDTH 6
#define CDP1869_HSYNC_START (56 * CDP1869_CHAR_WIDTH)
#define CDP1869_HSYNC_END (60 * CDP1869_CHAR_WIDTH)
#define CDP1869_HBLANK_START (54 * CDP1869_CHAR_WIDTH)
#define CDP1869_HBLANK_END ( 5 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_START_PAL ( 9 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_START_NTSC (10 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_START (10 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_END (50 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_WIDTH (60 * CDP1869_CHAR_WIDTH)
#define CDP1869_TOTAL_SCANLINES_PAL 312
#define CDP1869_SCANLINE_VBLANK_START_PAL 304
#define CDP1869_SCANLINE_VBLANK_END_PAL 10
#define CDP1869_SCANLINE_VSYNC_START_PAL 308
#define CDP1869_SCANLINE_VSYNC_END_PAL 312
#define CDP1869_SCANLINE_DISPLAY_START_PAL 44
#define CDP1869_SCANLINE_DISPLAY_END_PAL 260
#define CDP1869_SCANLINE_PREDISPLAY_START_PAL 43
#define CDP1869_SCANLINE_PREDISPLAY_END_PAL 260
#define CDP1869_VISIBLE_SCANLINES_PAL (CDP1869_SCANLINE_DISPLAY_END_PAL - CDP1869_SCANLINE_DISPLAY_START_PAL)
#define CDP1869_TOTAL_SCANLINES_NTSC 262
#define CDP1869_SCANLINE_VBLANK_START_NTSC 252
#define CDP1869_SCANLINE_VBLANK_END_NTSC 10
#define CDP1869_SCANLINE_VSYNC_START_NTSC 258
#define CDP1869_SCANLINE_VSYNC_END_NTSC 262
#define CDP1869_SCANLINE_DISPLAY_START_NTSC 36
#define CDP1869_SCANLINE_DISPLAY_END_NTSC 228
#define CDP1869_SCANLINE_PREDISPLAY_START_NTSC 35
#define CDP1869_SCANLINE_PREDISPLAY_END_NTSC 228
#define CDP1869_VISIBLE_SCANLINES_NTSC (CDP1869_SCANLINE_DISPLAY_END_NTSC - CDP1869_SCANLINE_DISPLAY_START_NTSC)
#define CDP1869_PALETTE_LENGTH 8+64
#define CDP1869 DEVICE_GET_INFO_NAME(cdp1869)
#define SOUND_CDP1869 CDP1869
#define MDRV_CDP1869_ADD(_tag, _pixclock, _config) \
MDRV_DEVICE_ADD(_tag, SOUND, _pixclock) \
MDRV_DEVICE_CONFIG_DATAPTR(sound_config, type, SOUND_CDP1869) \
MDRV_DEVICE_CONFIG(_config)
#define MDRV_CDP1869_REMOVE(_tag) \
MDRV_DEVICE_REMOVE(_tag, SOUND)
#define CDP1869_INTERFACE(_name) const cdp1869_interface (_name) =
#define CDP1869_CHAR_RAM_READ(name) UINT8 name(const device_config *device, UINT16 pma, UINT8 cma)
#define CDP1869_CHAR_RAM_WRITE(name) void name(const device_config *device, UINT16 pma, UINT8 cma, UINT8 data)
#define CDP1869_PAGE_RAM_READ(name) UINT8 name(const device_config *device, UINT16 pma)
#define CDP1869_PAGE_RAM_WRITE(name) void name(const device_config *device, UINT16 pma, UINT8 data)
#define CDP1869_PCB_READ(name) int name(const device_config *device, UINT16 pma, UINT8 cma)
#define CDP1869_ON_PRD_CHANGED(name) void name(const device_config *device, int prd)
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
typedef UINT8 (*cdp1869_char_ram_read_func)(const device_config *device, UINT16 pma, UINT8 cma);
typedef void (*cdp1869_char_ram_write_func)(const device_config *device, UINT16 pma, UINT8 cma, UINT8 data);
typedef UINT8 (*cdp1869_page_ram_read_func)(const device_config *device, UINT16 pma);
typedef void (*cdp1869_page_ram_write_func)(const device_config *device, UINT16 pma, UINT8 data);
typedef int (*cdp1869_pcb_read_func)(const device_config *device, UINT16 pma, UINT8 cma);
typedef enum _cdp1869_format cdp1869_format;
enum _cdp1869_format {
CDP1869_NTSC = 0,
CDP1869_PAL
};
/* interface */
typedef struct _cdp1869_interface cdp1869_interface;
struct _cdp1869_interface
{
const char *cpu_tag; /* CPU we work together with */
const char *screen_tag; /* screen we are acting on */
/* pixel clock of the chip is the device clock */
int color_clock; /* the chroma clock of the chip */
cdp1869_format pal_ntsc; /* screen format */
/* page memory read function */
cdp1869_page_ram_read_func page_ram_r;
/* page memory write function */
cdp1869_page_ram_write_func page_ram_w;
/* page memory color bit read function */
cdp1869_pcb_read_func pcb_r;
/* character memory read function */
cdp1869_char_ram_read_func char_ram_r;
/* character memory write function */
cdp1869_char_ram_write_func char_ram_w;
/* if specified, this gets called for every change of the predisplay pin (CDP1870/76 pin 1) */
devcb_write_line out_prd_func;
};
/***************************************************************************
PROTOTYPES
***************************************************************************/
/* device interface */
DEVICE_GET_INFO( cdp1869 );
#define SOUND_CDP1869 DEVICE_GET_INFO_NAME( cdp1869 )
#endif /* __CDP1869_H__ */
/* palette initialization */
PALETTE_INIT( cdp1869 );
/* register access */
WRITE8_DEVICE_HANDLER( cdp1869_out3_w );
WRITE8_DEVICE_HANDLER( cdp1869_out4_w );
WRITE8_DEVICE_HANDLER( cdp1869_out5_w );
WRITE8_DEVICE_HANDLER( cdp1869_out6_w );
WRITE8_DEVICE_HANDLER( cdp1869_out7_w );
/* character memory access */
READ8_DEVICE_HANDLER ( cdp1869_charram_r );
WRITE8_DEVICE_HANDLER ( cdp1869_charram_w );
/* page memory access */
READ8_DEVICE_HANDLER ( cdp1869_pageram_r );
WRITE8_DEVICE_HANDLER ( cdp1869_pageram_w );
/* screen update */
void cdp1869_update(const device_config *device, bitmap_t *bitmap, const rectangle *cliprect);
#endif

View File

@ -1,881 +0,0 @@
#include "driver.h"
#include "sndintrf.h"
#include "streams.h"
#include "cpu/cdp1802/cdp1802.h"
#include "sound/cdp1869.h"
#include "video/cdp1869.h"
/*
TODO:
- connect to sound system when possible
- white noise
- scanline based update
- separate to CDP1869 and CDP1870/6
*/
#define CDP1869_WEIGHT_RED 30 /* % of max luminance */
#define CDP1869_WEIGHT_GREEN 59
#define CDP1869_WEIGHT_BLUE 11
#define CDP1869_COLUMNS_HALF 20
#define CDP1869_COLUMNS_FULL 40
#define CDP1869_ROWS_HALF 12
#define CDP1869_ROWS_FULL_PAL 25
#define CDP1869_ROWS_FULL_NTSC 24
enum
{
CDB0 = 0,
CDB1,
CDB2,
CDB3,
CDB4,
CDB5,
CCB0,
CCB1
};
typedef struct _cdp1869_t cdp1869_t;
struct _cdp1869_t
{
const cdp1869_interface *intf; /* interface */
const device_config *screen; /* screen */
const device_config *cpu; /* CPU */
sound_stream *stream; /* sound output */
int color_clock;
/* video state */
int dispoff; /* display off */
int fresvert; /* full resolution vertical */
int freshorz; /* full resolution horizontal */
int cmem; /* character memory access mode */
int dblpage; /* double page mode */
int line16; /* 16-line hi-res mode */
int line9; /* 9 line mode */
int cfc; /* color format control */
UINT8 col; /* character color control */
UINT8 bkg; /* background color */
UINT16 pma; /* page memory address */
UINT16 hma; /* home memory address */
/* video timer */
emu_timer *prd_changed_timer; /* predisplay changed timer */
/* sound state */
INT16 signal; /* current signal */
int incr; /* initial wave state */
int toneoff; /* tone off */
int wnoff; /* white noise off */
UINT8 tonediv; /* tone divisor */
UINT8 tonefreq; /* tone range select */
UINT8 toneamp; /* tone output amplitude */
UINT8 wnfreq; /* white noise range select */
UINT8 wnamp; /* white noise output amplitude */
};
INLINE cdp1869_t *get_safe_token(const device_config *device)
{
assert(device != NULL);
assert(device->token != NULL);
return (cdp1869_t *)device->token;
}
/* Predisplay Timer */
static void update_prd_changed_timer(cdp1869_t *cdp1869)
{
if (cdp1869->prd_changed_timer != NULL)
{
attotime duration;
int start, end, level;
int scanline = video_screen_get_vpos(cdp1869->screen);
int next_scanline;
if (cdp1869->intf->pal_ntsc == CDP1869_NTSC)
{
start = CDP1869_SCANLINE_PREDISPLAY_START_NTSC;
end = CDP1869_SCANLINE_PREDISPLAY_END_NTSC;
}
else
{
start = CDP1869_SCANLINE_PREDISPLAY_START_PAL;
end = CDP1869_SCANLINE_PREDISPLAY_END_PAL;
}
if (scanline < start)
{
next_scanline = start;
level = 0;
}
else if (scanline < end)
{
next_scanline = end;
level = 1;
}
else
{
next_scanline = start;
level = 0;
}
if (cdp1869->dispoff)
{
level = 1;
}
duration = video_screen_get_time_until_pos(cdp1869->screen, next_scanline, 0);
timer_adjust_oneshot(cdp1869->prd_changed_timer, duration, level);
}
}
static TIMER_CALLBACK( prd_changed_tick )
{
const device_config *device = ptr;
cdp1869_t *cdp1869 = get_safe_token(device);
/* call the callback function -- we know it exists */
cdp1869->intf->on_prd_changed(device, param);
update_prd_changed_timer(cdp1869);
}
/* State Save Postload */
static STATE_POSTLOAD( cdp1869_state_save_postload )
{
update_prd_changed_timer(param);
}
/* CDP1802 X Register */
static UINT16 cdp1802_get_r_x(cdp1869_t *cdp1869)
{
return cpu_get_reg(cdp1869->cpu, CDP1802_R0 + cpu_get_reg(cdp1869->cpu, CDP1802_X));
}
/* Palette Initialization */
static rgb_t cdp1869_get_rgb(int i, int c, int l)
{
int luma = 0, r, g, b;
luma += (l & 4) ? CDP1869_WEIGHT_RED : 0;
luma += (l & 1) ? CDP1869_WEIGHT_GREEN : 0;
luma += (l & 2) ? CDP1869_WEIGHT_BLUE : 0;
luma = (luma * 0xff) / 100;
r = (c & 4) ? luma : 0;
g = (c & 1) ? luma : 0;
b = (c & 2) ? luma : 0;
return MAKE_RGB(r, g, b);
}
/* Screen Update */
static int cdp1869_get_lines(const device_config *device)
{
cdp1869_t *cdp1869 = get_safe_token(device);
if (cdp1869->line16 && !cdp1869->dblpage)
{
return 16;
}
else if (!cdp1869->line9)
{
return 9;
}
else
{
return 8;
}
}
static UINT16 cdp1869_get_pmemsize(const device_config *device, int cols, int rows)
{
cdp1869_t *cdp1869 = get_safe_token(device);
int pmemsize = cols * rows;
if (cdp1869->dblpage) pmemsize *= 2;
if (cdp1869->line16) pmemsize *= 2;
return pmemsize;
}
static UINT16 cdp1869_get_pma(const device_config *device)
{
cdp1869_t *cdp1869 = get_safe_token(device);
if (cdp1869->dblpage)
{
return cdp1869->pma;
}
else
{
return cdp1869->pma & 0x3ff;
}
}
static int cdp1869_get_pen(const device_config *device, int ccb0, int ccb1, int pcb)
{
cdp1869_t *cdp1869 = get_safe_token(device);
int r = 0, g = 0, b = 0, color;
switch (cdp1869->col)
{
case 0:
r = ccb0;
b = ccb1;
g = pcb;
break;
case 1:
r = ccb0;
b = pcb;
g = ccb1;
break;
case 2:
case 3:
r = pcb;
b = ccb0;
g = ccb1;
break;
}
color = (r << 2) + (b << 1) + g;
if (cdp1869->cfc)
{
return color + ((cdp1869->bkg + 1) * 8);
}
else
{
return color;
}
}
static void cdp1869_draw_line(const device_config *device, bitmap_t *bitmap, int x, int y, int data, int color)
{
cdp1869_t *cdp1869 = get_safe_token(device);
int i;
data <<= 2;
for (i = 0; i < CDP1869_CHAR_WIDTH; i++)
{
if (data & 0x80)
{
*BITMAP_ADDR16(bitmap, y, x) = color;
if (!cdp1869->fresvert)
{
*BITMAP_ADDR16(bitmap, y + 1, x) = color;
}
if (!cdp1869->freshorz)
{
*BITMAP_ADDR16(bitmap, y, x + 1) = color;
if (!cdp1869->fresvert)
{
*BITMAP_ADDR16(bitmap, y + 1, x + 1) = color;
}
}
}
if (!cdp1869->freshorz)
{
x++;
}
x++;
data <<= 1;
}
}
static void cdp1869_draw_char(const device_config *device, bitmap_t *bitmap, int x, int y, UINT16 pma, const rectangle *screenrect)
{
cdp1869_t *cdp1869 = get_safe_token(device);
UINT8 cma = 0;
for (cma = 0; cma < cdp1869_get_lines(device); cma++)
{
UINT8 data = cdp1869->intf->char_ram_r(device, pma, cma);
int ccb0 = BIT(data, CCB0);
int ccb1 = BIT(data, CCB1);
int pcb = BIT(cdp1869->intf->pcb_r(device, pma, cma), 0);
int color = cdp1869_get_pen(device, ccb0, ccb1, pcb);
cdp1869_draw_line(device, bitmap, screenrect->min_x + x, screenrect->min_y + y, data, color);
y++;
if (!cdp1869->fresvert)
{
y++;
}
}
}
/* Palette Initialization */
PALETTE_INIT( cdp1869 )
{
int i, c, l;
// color-on-color display (CFC=0)
for (i = 0; i < 8; i++)
{
palette_set_color(machine, i, cdp1869_get_rgb(i, i, 15));
}
// tone-on-tone display (CFC=1)
for (c = 0; c < 8; c++)
{
for (l = 0; l < 8; l++)
{
palette_set_color(machine, i, cdp1869_get_rgb(i, c, l));
i++;
}
}
}
/* Register Access */
WRITE8_DEVICE_HANDLER( cdp1869_out3_w )
{
cdp1869_t *cdp1869 = get_safe_token(device);
/*
bit description
0 bkg green
1 bkg blue
2 bkg red
3 cfc
4 disp off
5 colb0
6 colb1
7 fres horz
*/
cdp1869->bkg = data & 0x07;
cdp1869->cfc = BIT(data, 3);
cdp1869->dispoff = BIT(data, 4);
cdp1869->col = (data & 0x60) >> 5;
cdp1869->freshorz = BIT(data, 7);
}
WRITE8_DEVICE_HANDLER( cdp1869_out4_w )
{
cdp1869_t *cdp1869 = get_safe_token(device);
const device_config *cdp = devtag_get_device(device->machine, SOUND, "cdp");
UINT16 word = cdp1802_get_r_x(cdp1869);
/*
bit description
0 tone amp 2^0
1 tone amp 2^1
2 tone amp 2^2
3 tone amp 2^3
4 tone freq sel0
5 tone freq sel1
6 tone freq sel2
7 tone off
8 tone / 2^0
9 tone / 2^1
10 tone / 2^2
11 tone / 2^3
12 tone / 2^4
13 tone / 2^5
14 tone / 2^6
15 always 0
*/
cdp1869->toneamp = word & 0x0f;
cdp1869->tonefreq = (word & 0x70) >> 4;
cdp1869->toneoff = BIT(word, 7);
cdp1869->tonediv = (word & 0x7f00) >> 8;
// fork out to CDP1869 sound core
cdp1869_set_toneamp(cdp, cdp1869->toneamp);
cdp1869_set_tonefreq(cdp, cdp1869->tonefreq);
cdp1869_set_toneoff(cdp, cdp1869->toneoff);
cdp1869_set_tonediv(cdp, cdp1869->tonediv);
}
WRITE8_DEVICE_HANDLER( cdp1869_out5_w )
{
cdp1869_t *cdp1869 = get_safe_token(device);
const device_config *cdp = devtag_get_device(device->machine, SOUND, "cdp");
UINT16 word = cdp1802_get_r_x(cdp1869);
/*
bit description
0 cmem access mode
1 x
2 x
3 9-line
4 x
5 16 line hi-res
6 double page
7 fres vert
8 wn amp 2^0
9 wn amp 2^1
10 wn amp 2^2
11 wn amp 2^3
12 wn freq sel0
13 wn freq sel1
14 wn freq sel2
15 wn off
*/
cdp1869->cmem = BIT(word, 0);
cdp1869->line9 = BIT(word, 3);
if (cdp1869->intf->pal_ntsc == CDP1869_NTSC)
{
cdp1869->line16 = BIT(word, 5);
}
cdp1869->dblpage = BIT(word, 6);
cdp1869->fresvert = BIT(word, 7);
cdp1869->wnamp = (word & 0x0f00) >> 8;
cdp1869->wnfreq = (word & 0x7000) >> 12;
cdp1869->wnoff = BIT(word, 15);
// fork out to CDP1869 sound core
cdp1869_set_wnamp(cdp, cdp1869->wnamp);
cdp1869_set_wnfreq(cdp, cdp1869->wnfreq);
cdp1869_set_wnoff(cdp, cdp1869->wnoff);
if (cdp1869->cmem)
{
cdp1869->pma = word;
}
else
{
cdp1869->pma = 0;
}
}
WRITE8_DEVICE_HANDLER( cdp1869_out6_w )
{
cdp1869_t *cdp1869 = get_safe_token(device);
UINT16 word = cdp1802_get_r_x(cdp1869);
/*
bit description
0 pma0 reg
1 pma1 reg
2 pma2 reg
3 pma3 reg
4 pma4 reg
5 pma5 reg
6 pma6 reg
7 pma7 reg
8 pma8 reg
9 pma9 reg
10 pma10 reg
11 x
12 x
13 x
14 x
15 x
*/
cdp1869->pma = word & 0x7ff;
}
WRITE8_DEVICE_HANDLER( cdp1869_out7_w )
{
cdp1869_t *cdp1869 = get_safe_token(device);
UINT16 word = cdp1802_get_r_x(cdp1869);
/*
bit description
0 x
1 x
2 hma2 reg
3 hma3 reg
4 hma4 reg
5 hma5 reg
6 hma6 reg
7 hma7 reg
8 hma8 reg
9 hma9 reg
10 hma10 reg
11 x
12 x
13 x
14 x
15 x
*/
cdp1869->hma = word & 0x7fc;
}
/* Page RAM Access */
READ8_DEVICE_HANDLER( cdp1869_pageram_r )
{
cdp1869_t *cdp1869 = get_safe_token(device);
UINT16 pma;
if (cdp1869->cmem)
{
pma = cdp1869_get_pma(device);
}
else
{
pma = offset;
}
return cdp1869->intf->page_ram_r(device, pma);
}
WRITE8_DEVICE_HANDLER( cdp1869_pageram_w )
{
cdp1869_t *cdp1869 = get_safe_token(device);
UINT16 pma;
if (cdp1869->cmem)
{
pma = cdp1869_get_pma(device);
}
else
{
pma = offset;
}
if (cdp1869->intf->page_ram_w)
{
cdp1869->intf->page_ram_w(device, pma, data);
}
}
/* Character RAM Access */
READ8_DEVICE_HANDLER( cdp1869_charram_r )
{
cdp1869_t *cdp1869 = get_safe_token(device);
UINT8 cma = offset & 0x0f;
UINT16 pma;
if (cdp1869->cmem)
{
pma = cdp1869_get_pma(device);
}
else
{
pma = offset;
}
if (cdp1869->dblpage)
{
cma &= 0x07;
}
return cdp1869->intf->char_ram_r(device, pma, cma);
}
WRITE8_DEVICE_HANDLER( cdp1869_charram_w )
{
cdp1869_t *cdp1869 = get_safe_token(device);
UINT8 cma = offset & 0x0f;
UINT16 pma;
if (cdp1869->cmem)
{
pma = cdp1869_get_pma(device);
}
else
{
pma = offset;
}
if (cdp1869->dblpage)
{
cma &= 0x07;
}
if (cdp1869->intf->char_ram_w)
{
cdp1869->intf->char_ram_w(device, pma, cma, data);
}
}
/* Screen Update */
void cdp1869_update(const device_config *device, bitmap_t *bitmap, const rectangle *cliprect)
{
cdp1869_t *cdp1869 = get_safe_token(device);
rectangle screen_rect, outer;
switch (cdp1869->intf->pal_ntsc)
{
case CDP1869_NTSC:
outer.min_x = CDP1869_HBLANK_END;
outer.max_x = CDP1869_HBLANK_START - 1;
outer.min_y = CDP1869_SCANLINE_VBLANK_END_NTSC;
outer.max_y = CDP1869_SCANLINE_VBLANK_START_NTSC - 1;
screen_rect.min_x = CDP1869_SCREEN_START_NTSC;
screen_rect.max_x = CDP1869_SCREEN_END - 1;
screen_rect.min_y = CDP1869_SCANLINE_DISPLAY_START_NTSC;
screen_rect.max_y = CDP1869_SCANLINE_DISPLAY_END_NTSC - 1;
break;
default:
case CDP1869_PAL:
outer.min_x = CDP1869_HBLANK_END;
outer.max_x = CDP1869_HBLANK_START - 1;
outer.min_y = CDP1869_SCANLINE_VBLANK_END_PAL;
outer.max_y = CDP1869_SCANLINE_VBLANK_START_PAL - 1;
screen_rect.min_x = CDP1869_SCREEN_START_PAL;
screen_rect.max_x = CDP1869_SCREEN_END - 1;
screen_rect.min_y = CDP1869_SCANLINE_DISPLAY_START_PAL;
screen_rect.max_y = CDP1869_SCANLINE_DISPLAY_END_PAL - 1;
break;
}
sect_rect(&outer, cliprect);
bitmap_fill(bitmap, &outer, device->machine->pens[cdp1869->bkg]);
if (!cdp1869->dispoff)
{
int sx, sy, rows, cols, width, height;
UINT16 addr, pmemsize;
width = CDP1869_CHAR_WIDTH;
height = cdp1869_get_lines(device);
if (!cdp1869->freshorz)
{
width *= 2;
}
if (!cdp1869->fresvert)
{
height *= 2;
}
cols = cdp1869->freshorz ? CDP1869_COLUMNS_FULL : CDP1869_COLUMNS_HALF;
rows = (screen_rect.max_y - screen_rect.min_y + 1) / height;
pmemsize = cdp1869_get_pmemsize(device, cols, rows);
addr = cdp1869->hma;
for (sy = 0; sy < rows; sy++)
{
for (sx = 0; sx < cols; sx++)
{
int x = sx * width;
int y = sy * height;
cdp1869_draw_char(device, bitmap, x, y, addr, &screen_rect);
addr++;
if (addr == pmemsize) addr = 0;
}
}
}
}
/* Sound Update */
#ifdef UNUSED_FUNCTION
static void cdp1869_sum_square_wave(stream_sample_t *buffer, double frequency, double amplitude)
{
// do a fast fourier transform on all the waves in the white noise range
}
static void cdp1869_sound_update(const device_config *device, stream_sample_t **inputs, stream_sample_t **_buffer, int length)
{
cdp1869_t *cdp1869 = get_safe_token(device);
INT16 signal = cdp1869->signal;
stream_sample_t *buffer = _buffer[0];
memset(buffer, 0, length * sizeof(*buffer));
if (!cdp1869->toneoff && cdp1869->toneamp)
{
double frequency = (device->clock / 2) / (512 >> cdp1869->tonefreq) / (cdp1869->tonediv + 1);
int rate = device->machine->sample_rate / 2;
/* get progress through wave */
int incr = cdp1869->incr;
if (signal < 0)
{
signal = -(cdp1869->toneamp * (0x07fff / 15));
}
else
{
signal = cdp1869->toneamp * (0x07fff / 15);
}
while( length-- > 0 )
{
*buffer++ = signal;
incr -= frequency;
while( incr < 0 )
{
incr += rate;
signal = -signal;
}
}
/* store progress through wave */
cdp1869->incr = incr;
cdp1869->signal = signal;
}
if (!cdp1869->wnoff)
{
int wndiv;
double amplitude = cdp1869->wnamp * ((0.78*5) / 15);
for (wndiv = 0; wndiv < 128; wndiv++)
{
double frequency = (device->clock / 2) / (4096 >> cdp1869->wnfreq) / (wndiv + 1);
cdp1869_sum_square_wave(buffer, frequency, amplitude);
}
}
}
#endif
/* Device Interface */
static DEVICE_START( cdp1869 )
{
const cdp1869_inline *inline_config = device->inline_config;
cdp1869_t *cdp1869 = get_safe_token(device);
// validate arguments
assert(device != NULL);
assert(device->tag != NULL);
assert(device->static_config != NULL);
assert(inline_config != NULL);
cdp1869->intf = device->static_config;
assert(cdp1869->intf->page_ram_r != NULL);
assert(cdp1869->intf->pcb_r != NULL);
assert(cdp1869->intf->char_ram_r != NULL);
// set initial values
cdp1869->toneoff = 1;
cdp1869->wnoff = 1;
// get the screen device
cdp1869->screen = devtag_get_device(device->machine, VIDEO_SCREEN, inline_config->screen_tag);
assert(cdp1869->screen != NULL);
// get the CPU device
cdp1869->cpu = cputag_get_cpu(device->machine, inline_config->cpu_tag);
assert(cdp1869->cpu != NULL);
// allocate timers
if (cdp1869->intf->on_prd_changed != NULL)
{
cdp1869->prd_changed_timer = timer_alloc(device->machine, prd_changed_tick, (void *)device);
update_prd_changed_timer(cdp1869);
}
// register for state saving
state_save_register_postload(device->machine, cdp1869_state_save_postload, cdp1869);
state_save_register_device_item(device, 0, cdp1869->dispoff);
state_save_register_device_item(device, 0, cdp1869->fresvert);
state_save_register_device_item(device, 0, cdp1869->freshorz);
state_save_register_device_item(device, 0, cdp1869->cmem);
state_save_register_device_item(device, 0, cdp1869->dblpage);
state_save_register_device_item(device, 0, cdp1869->line16);
state_save_register_device_item(device, 0, cdp1869->line9);
state_save_register_device_item(device, 0, cdp1869->cfc);
state_save_register_device_item(device, 0, cdp1869->col);
state_save_register_device_item(device, 0, cdp1869->bkg);
state_save_register_device_item(device, 0, cdp1869->pma);
state_save_register_device_item(device, 0, cdp1869->hma);
state_save_register_device_item(device, 0, cdp1869->signal);
state_save_register_device_item(device, 0, cdp1869->incr);
state_save_register_device_item(device, 0, cdp1869->toneoff);
state_save_register_device_item(device, 0, cdp1869->wnoff);
state_save_register_device_item(device, 0, cdp1869->tonediv);
state_save_register_device_item(device, 0, cdp1869->tonefreq);
state_save_register_device_item(device, 0, cdp1869->toneamp);
state_save_register_device_item(device, 0, cdp1869->wnfreq);
state_save_register_device_item(device, 0, cdp1869->wnamp);
}
static DEVICE_SET_INFO( cdp1869 )
{
switch (state)
{
/* no parameters to set */
}
}
DEVICE_GET_INFO( cdp1869_video )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(cdp1869_t); break;
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(cdp1869_inline); break;
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(cdp1869); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(cdp1869); break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: /* Nothing */ break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "RCA CDP1869"); break;
case DEVINFO_STR_FAMILY: strcpy(info->s, "RCA CDP1800"); break;
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
}
}

View File

@ -1,178 +0,0 @@
/*
RCA CDP1869/70/76 Video Interface System (VIS)
http://homepage.mac.com/ruske/cosmacelf/cdp1869.pdf
________________ ________________
TPA 1 ---| \/ |--- 40 Vdd PREDISPLAY_ 1 ---| \/ |--- 40 Vdd
TPB 2 ---| |--- 39 PMSEL *DISPLAY_ 2 ---| |--- 39 PAL/NTSC_
MRD_ 3 ---| |--- 38 PMWR_ PCB 3 ---| |--- 38 CPUCLK
MWR_ 4 ---| |--- 37 *CMSEL CCB1 4 ---| |--- 37 XTAL (DOT)
MA0/8 5 ---| |--- 36 CMWR_ BUS7 5 ---| |--- 36 XTAL (DOT)_
MA1/9 6 ---| |--- 35 PMA0 CCB0 6 ---| |--- 35 *ADDRSTB_
MA2/10 7 ---| |--- 34 PMA1 BUS6 7 ---| |--- 34 MRD_
MA3/11 8 ---| |--- 33 PMA2 CDB5 8 ---| |--- 33 TPB
MA4/12 9 ---| |--- 32 PMA3 BUS5 9 ---| |--- 32 *CMSEL
MA5/13 10 ---| CDP1869C |--- 31 PMA4 CDB4 10 ---| CDP1870/76C |--- 31 BURST
MA6/14 11 ---| top view |--- 30 PMA5 BUS4 11 ---| top view |--- 30 *H SYNC_
MA7/15 12 ---| |--- 29 PMA6 CDB3 12 ---| |--- 29 COMPSYNC_
N0 13 ---| |--- 28 PMA7 BUS3 13 ---| |--- 28 LUM / (RED)^
N1 14 ---| |--- 27 PMA8 CDB2 14 ---| |--- 27 PAL CHROM / (BLUE)^
N2 15 ---| |--- 26 PMA9 BUS2 15 ---| |--- 26 NTSC CHROM / (GREEN)^
*H SYNC_ 16 ---| |--- 25 CMA3/PMA10 CDB1 16 ---| |--- 25 XTAL_ (CHROM)
*DISPLAY_ 17 ---| |--- 24 CMA2 BUS1 17 ---| |--- 24 XTAL (CHROM)
*ADDRSTB_ 18 ---| |--- 23 CMA1 CDB0 18 ---| |--- 23 EMS_
SOUND 19 ---| |--- 22 CMA0 BUS0 19 ---| |--- 22 EVS_
VSS 20 ---|________________|--- 21 *N=3_ Vss 20 ---|________________|--- 21 *N=3_
* = INTERCHIP CONNECTIONS ^ = FOR THE RGB BOND-OUT OPTION (CDP1876C) _ = ACTIVE LOW
*/
#ifndef __CDP1869_VIDEO__
#define __CDP1869_VIDEO__
#define CDP1869_DOT_CLK_PAL 5626000.0
#define CDP1869_DOT_CLK_NTSC 5670000.0
#define CDP1869_COLOR_CLK_PAL 8867236.0
#define CDP1869_COLOR_CLK_NTSC 7159090.0
#define CDP1869_CPU_CLK_PAL (CDP1869_DOT_CLK_PAL / 2)
#define CDP1869_CPU_CLK_NTSC (CDP1869_DOT_CLK_NTSC / 2)
#define CDP1869_CHAR_WIDTH 6
#define CDP1869_HSYNC_START (56 * CDP1869_CHAR_WIDTH)
#define CDP1869_HSYNC_END (60 * CDP1869_CHAR_WIDTH)
#define CDP1869_HBLANK_START (54 * CDP1869_CHAR_WIDTH)
#define CDP1869_HBLANK_END ( 5 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_START_PAL ( 9 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_START_NTSC (10 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_START (10 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_END (50 * CDP1869_CHAR_WIDTH)
#define CDP1869_SCREEN_WIDTH (60 * CDP1869_CHAR_WIDTH)
#define CDP1869_TOTAL_SCANLINES_PAL 312
#define CDP1869_SCANLINE_VBLANK_START_PAL 304
#define CDP1869_SCANLINE_VBLANK_END_PAL 10
#define CDP1869_SCANLINE_VSYNC_START_PAL 308
#define CDP1869_SCANLINE_VSYNC_END_PAL 312
#define CDP1869_SCANLINE_DISPLAY_START_PAL 44
#define CDP1869_SCANLINE_DISPLAY_END_PAL 260
#define CDP1869_SCANLINE_PREDISPLAY_START_PAL 43
#define CDP1869_SCANLINE_PREDISPLAY_END_PAL 260
#define CDP1869_VISIBLE_SCANLINES_PAL (CDP1869_SCANLINE_DISPLAY_END_PAL - CDP1869_SCANLINE_DISPLAY_START_PAL)
#define CDP1869_TOTAL_SCANLINES_NTSC 262
#define CDP1869_SCANLINE_VBLANK_START_NTSC 252
#define CDP1869_SCANLINE_VBLANK_END_NTSC 10
#define CDP1869_SCANLINE_VSYNC_START_NTSC 258
#define CDP1869_SCANLINE_VSYNC_END_NTSC 262
#define CDP1869_SCANLINE_DISPLAY_START_NTSC 36
#define CDP1869_SCANLINE_DISPLAY_END_NTSC 228
#define CDP1869_SCANLINE_PREDISPLAY_START_NTSC 35
#define CDP1869_SCANLINE_PREDISPLAY_END_NTSC 228
#define CDP1869_VISIBLE_SCANLINES_NTSC (CDP1869_SCANLINE_DISPLAY_END_NTSC - CDP1869_SCANLINE_DISPLAY_START_NTSC)
#define CDP1869_PALETTE_LENGTH 8+64
#define CDP1869_VIDEO DEVICE_GET_INFO_NAME(cdp1869_video)
#define MDRV_CDP1869_ADD(_tag, _screen, _pixclock, _chrclock, _cpu, _config) \
MDRV_DEVICE_ADD(_tag, CDP1869_VIDEO, _pixclock) \
MDRV_DEVICE_CONFIG_DATA32(cdp1869_inline, color_clock, _chrclock) \
MDRV_DEVICE_CONFIG_DATAPTR(cdp1869_inline, screen_tag, _screen) \
MDRV_DEVICE_CONFIG_DATAPTR(cdp1869_inline, cpu_tag, _cpu) \
MDRV_DEVICE_CONFIG(_config)
#define MDRV_CDP1869_REMOVE(_tag) \
MDRV_DEVICE_REMOVE(_tag, CDP1869_VIDEO)
typedef UINT8 (*cdp1869_char_ram_read_func)(const device_config *device, UINT16 pma, UINT8 cma);
#define CDP1869_CHAR_RAM_READ(name) UINT8 name(const device_config *device, UINT16 pma, UINT8 cma)
typedef void (*cdp1869_char_ram_write_func)(const device_config *device, UINT16 pma, UINT8 cma, UINT8 data);
#define CDP1869_CHAR_RAM_WRITE(name) void name(const device_config *device, UINT16 pma, UINT8 cma, UINT8 data)
typedef UINT8 (*cdp1869_page_ram_read_func)(const device_config *device, UINT16 pma);
#define CDP1869_PAGE_RAM_READ(name) UINT8 name(const device_config *device, UINT16 pma)
typedef void (*cdp1869_page_ram_write_func)(const device_config *device, UINT16 pma, UINT8 data);
#define CDP1869_PAGE_RAM_WRITE(name) void name(const device_config *device, UINT16 pma, UINT8 data)
typedef int (*cdp1869_pcb_read_func)(const device_config *device, UINT16 pma, UINT8 cma);
#define CDP1869_PCB_READ(name) int name(const device_config *device, UINT16 pma, UINT8 cma)
typedef void (*cdp1869_on_prd_changed_func) (const device_config *device, int prd);
#define CDP1869_ON_PRD_CHANGED(name) void name(const device_config *device, int prd)
typedef enum _cdp1869_format cdp1869_format;
enum _cdp1869_format {
CDP1869_NTSC = 0,
CDP1869_PAL
};
typedef struct _cdp1869_inline cdp1869_inline;
struct _cdp1869_inline
{
const char *screen_tag; /* screen we are acting on */
const char *cpu_tag; /* CPU we work together with */
/* pixel clock of the chip is the device clock */
int color_clock; /* the chroma clock of the chip */
};
/* interface */
typedef struct _cdp1869_interface cdp1869_interface;
struct _cdp1869_interface
{
cdp1869_format pal_ntsc; /* screen format */
/* page memory read function */
cdp1869_page_ram_read_func page_ram_r;
/* page memory write function */
cdp1869_page_ram_write_func page_ram_w;
/* page memory color bit read function */
cdp1869_pcb_read_func pcb_r;
/* character memory read function */
cdp1869_char_ram_read_func char_ram_r;
/* character memory write function */
cdp1869_char_ram_write_func char_ram_w;
/* if specified, this gets called for every change of the predisplay pin (CDP1870/76 pin 1) */
cdp1869_on_prd_changed_func on_prd_changed;
};
#define CDP1869_INTERFACE(name) const cdp1869_interface (name) =
/* device interface */
DEVICE_GET_INFO( cdp1869_video );
/* palette initialization */
PALETTE_INIT( cdp1869 );
/* register access */
WRITE8_DEVICE_HANDLER( cdp1869_out3_w );
WRITE8_DEVICE_HANDLER( cdp1869_out4_w );
WRITE8_DEVICE_HANDLER( cdp1869_out5_w );
WRITE8_DEVICE_HANDLER( cdp1869_out6_w );
WRITE8_DEVICE_HANDLER( cdp1869_out7_w );
/* character memory access */
READ8_DEVICE_HANDLER ( cdp1869_charram_r );
WRITE8_DEVICE_HANDLER ( cdp1869_charram_w );
/* page memory access */
READ8_DEVICE_HANDLER ( cdp1869_pageram_r );
WRITE8_DEVICE_HANDLER ( cdp1869_pageram_w );
/* screen update */
void cdp1869_update(const device_config *device, bitmap_t *bitmap, const rectangle *cliprect);
#endif

View File

@ -1,22 +1,11 @@
#include "driver.h"
#include "cpu/cdp1802/cdp1802.h"
#include "cpu/cop400/cop400.h"
#include "video/cdp1869.h"
#include "sound/cdp1869.h"
#include "sound/ay8910.h"
#include "machine/cdp1852.h"
#include "cidelsa.h"
/*
TODO:
- move set_cpu_mode timer call to MDRV
*/
#define CDP1869_TAG "cdp1869"
/* CDP1802 Interface */
static CDP1802_MODE_READ( cidelsa_mode_r )
@ -127,48 +116,6 @@ static WRITE8_HANDLER( draco_sound_ay8910_w )
state->draco_ay_latch = data;
}
static WRITE8_DEVICE_HANDLER( draco_ay8910_port_a_w )
{
/*
bit description
0 not connected
1 not connected
2 not connected
3 not connected
4 not connected
5 not connected
6 not connected
7 not connected
*/
}
static WRITE8_DEVICE_HANDLER( draco_ay8910_port_b_w )
{
/*
bit description
0 RELE0
1 RELE1
2 sound output -> * -> 22K capacitor -> GND
3 sound output -> * -> 220K capacitor -> GND
4 5V -> 1K resistor -> * -> 10uF capacitor -> GND (volume pot voltage adjustment)
5 not connected
6 not connected
7 not connected
*/
}
static const ay8910_interface ay8910_config =
{
AY8910_SINGLE_OUTPUT,
AY8910_DEFAULT_LOADS,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_HANDLER(draco_ay8910_port_a_w),
DEVCB_HANDLER(draco_ay8910_port_b_w)
};
/* Read/Write Handlers */
static WRITE8_HANDLER( destryer_out1_w )
@ -189,22 +136,7 @@ static WRITE8_HANDLER( destryer_out1_w )
/* CDP1852 Interfaces */
static CDP1852_DATA_READ( cidelsa_in0_r )
{
return input_port_read(device->machine, "IN0");
}
static CDP1852_DATA_READ( cidelsa_in1_r )
{
return input_port_read(device->machine, "IN1");
}
static CDP1852_DATA_READ( cidelsa_in2_r )
{
return input_port_read(device->machine, "IN2");
}
static CDP1852_DATA_WRITE( altair_out1_w )
static WRITE8_HANDLER( altair_out1_w )
{
/*
bit description
@ -224,7 +156,7 @@ static CDP1852_DATA_WRITE( altair_out1_w )
set_led_status(2, data & 0x20); // FIRE
}
static CDP1852_DATA_WRITE( draco_out1_w )
static WRITE8_HANDLER( draco_out1_w )
{
/*
bit description
@ -239,7 +171,7 @@ static CDP1852_DATA_WRITE( draco_out1_w )
7 SONIDO C -> COP402 IN2
*/
cidelsa_state *state = device->machine->driver_data;
cidelsa_state *state = space->machine->driver_data;
state->draco_sound = (data & 0xe0) >> 5;
}
@ -247,41 +179,41 @@ static CDP1852_DATA_WRITE( draco_out1_w )
static CDP1852_INTERFACE( cidelsa_cdp1852_in0_intf )
{
CDP1852_MODE_INPUT,
cidelsa_in0_r,
NULL,
NULL
DEVCB_INPUT_PORT("IN0"),
DEVCB_NULL,
DEVCB_NULL
};
static CDP1852_INTERFACE( cidelsa_cdp1852_in1_intf )
{
CDP1852_MODE_INPUT,
cidelsa_in1_r,
NULL,
NULL
DEVCB_INPUT_PORT("IN1"),
DEVCB_NULL,
DEVCB_NULL
};
static CDP1852_INTERFACE( cidelsa_cdp1852_in2_intf )
{
CDP1852_MODE_INPUT,
cidelsa_in2_r,
NULL,
NULL
DEVCB_INPUT_PORT("IN2"),
DEVCB_NULL,
DEVCB_NULL
};
static CDP1852_INTERFACE( altair_cdp1852_out1_intf )
{
CDP1852_MODE_OUTPUT,
NULL,
altair_out1_w,
NULL
DEVCB_NULL,
DEVCB_MEMORY_HANDLER(CDP1802_TAG, PROGRAM, altair_out1_w),
DEVCB_NULL
};
static CDP1852_INTERFACE( draco_cdp1852_out1_intf )
{
CDP1852_MODE_OUTPUT,
NULL,
draco_out1_w,
NULL
DEVCB_NULL,
DEVCB_MEMORY_HANDLER(CDP1802_TAG, PROGRAM, draco_out1_w),
DEVCB_NULL
};
/* COP400 Interface */
@ -300,25 +232,25 @@ static COP400_INTERFACE( draco_cop_intf )
static ADDRESS_MAP_START( destryer_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x1fff) AM_ROM
AM_RANGE(0x2000, 0x20ff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w)
AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w)
AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(SOUND, CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w)
AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(SOUND, CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( destryea_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x1fff) AM_ROM
AM_RANGE(0x3000, 0x30ff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w)
AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w)
AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(SOUND, CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w)
AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(SOUND, CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( destryer_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x01, 0x01) AM_READ_PORT("IN0") AM_WRITE(destryer_out1_w)
AM_RANGE(0x02, 0x02) AM_READ_PORT("IN1")
AM_RANGE(0x03, 0x03) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out3_w)
AM_RANGE(0x04, 0x04) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out4_w)
AM_RANGE(0x05, 0x05) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out5_w)
AM_RANGE(0x06, 0x06) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out6_w)
AM_RANGE(0x07, 0x07) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out7_w)
AM_RANGE(0x03, 0x03) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out3_w)
AM_RANGE(0x04, 0x04) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out4_w)
AM_RANGE(0x05, 0x05) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out5_w)
AM_RANGE(0x06, 0x06) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out6_w)
AM_RANGE(0x07, 0x07) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out7_w)
ADDRESS_MAP_END
// Altair
@ -326,18 +258,18 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( altair_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x2fff) AM_ROM
AM_RANGE(0x3000, 0x30ff) AM_RAM
AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w)
AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w)
AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(SOUND, CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w)
AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(SOUND, CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( altair_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x01, 0x01) AM_DEVREAD(CDP1852, "ic23", cdp1852_data_r) AM_DEVWRITE(CDP1852, "ic26", cdp1852_data_w)
AM_RANGE(0x02, 0x02) AM_DEVREAD(CDP1852, "ic24", cdp1852_data_r)
AM_RANGE(0x03, 0x03) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out3_w)
AM_RANGE(0x04, 0x04) AM_DEVREAD(CDP1852, "ic25", cdp1852_data_r) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out4_w)
AM_RANGE(0x05, 0x05) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out5_w)
AM_RANGE(0x06, 0x06) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out6_w)
AM_RANGE(0x07, 0x07) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out7_w)
AM_RANGE(0x03, 0x03) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out3_w)
AM_RANGE(0x04, 0x04) AM_DEVREAD(CDP1852, "ic25", cdp1852_data_r) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out4_w)
AM_RANGE(0x05, 0x05) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out5_w)
AM_RANGE(0x06, 0x06) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out6_w)
AM_RANGE(0x07, 0x07) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out7_w)
ADDRESS_MAP_END
// Draco
@ -345,18 +277,18 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( draco_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x3fff) AM_ROM
AM_RANGE(0x8000, 0x83ff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w)
AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w)
AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(SOUND, CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w)
AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(SOUND, CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( draco_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x01, 0x01) AM_DEVREAD(CDP1852, "ic29", cdp1852_data_r) AM_DEVWRITE(CDP1852, "ic32", cdp1852_data_w)
AM_RANGE(0x02, 0x02) AM_DEVREAD(CDP1852, "ic30", cdp1852_data_r)
AM_RANGE(0x03, 0x03) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out3_w)
AM_RANGE(0x04, 0x04) AM_DEVREAD(CDP1852, "ic31", cdp1852_data_r) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out4_w)
AM_RANGE(0x05, 0x05) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out5_w)
AM_RANGE(0x06, 0x06) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out6_w)
AM_RANGE(0x07, 0x07) AM_DEVWRITE(CDP1869_VIDEO, CDP1869_TAG, cdp1869_out7_w)
AM_RANGE(0x03, 0x03) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out3_w)
AM_RANGE(0x04, 0x04) AM_DEVREAD(CDP1852, "ic31", cdp1852_data_r) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out4_w)
AM_RANGE(0x05, 0x05) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out5_w)
AM_RANGE(0x06, 0x06) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out6_w)
AM_RANGE(0x07, 0x07) AM_DEVWRITE(SOUND, CDP1869_TAG, cdp1869_out7_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( draco_sound_map, ADDRESS_SPACE_PROGRAM, 8 )
@ -365,7 +297,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( draco_sound_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(COP400_PORT_D, COP400_PORT_D) AM_WRITE(draco_sound_bankswitch_w)
AM_RANGE(COP400_PORT_G, COP400_PORT_G) AM_DEVWRITE(SOUND, "ay", draco_sound_g_w)
AM_RANGE(COP400_PORT_G, COP400_PORT_G) AM_DEVWRITE(SOUND, AY8910_TAG, draco_sound_g_w)
AM_RANGE(COP400_PORT_L, COP400_PORT_L) AM_READWRITE(draco_sound_ay8910_r, draco_sound_ay8910_w)
AM_RANGE(COP400_PORT_IN, COP400_PORT_IN) AM_READ(draco_sound_in_r)
AM_RANGE(COP400_PORT_SIO, COP400_PORT_SIO) AM_NOP
@ -544,12 +476,10 @@ static MACHINE_START( cidelsa )
cidelsa_state *state = machine->driver_data;
/* reset the CPU */
state->cdp1802_mode = CDP1802_MODE_RESET;
timer_set(machine, ATTOTIME_IN_MSEC(200), NULL, 0, set_cpu_mode);
/* register for state saving */
state_save_register_global(machine, state->cdp1802_mode);
}
@ -560,12 +490,10 @@ static MACHINE_START( draco )
MACHINE_START_CALL( cidelsa );
/* setup COP402 memory banking */
memory_configure_bank(machine, 1, 0, 2, memory_region(machine, "audio"), 0x400);
memory_set_bank(machine, 1, 0);
/* register for state saving */
state_save_register_global(machine, state->draco_sound);
state_save_register_global(machine, state->draco_ay_latch);
}
@ -574,7 +502,7 @@ static MACHINE_START( draco )
static MACHINE_RESET( cidelsa )
{
cputag_set_input_line(machine, MAIN_CPU_TAG, INPUT_LINE_RESET, PULSE_LINE);
cputag_set_input_line(machine, CDP1802_TAG, INPUT_LINE_RESET, PULSE_LINE);
}
/* Machine Drivers */
@ -582,9 +510,8 @@ static MACHINE_RESET( cidelsa )
static MACHINE_DRIVER_START( destryer )
MDRV_DRIVER_DATA(cidelsa_state)
// basic system hardware
MDRV_CPU_ADD(MAIN_CPU_TAG, CDP1802, DESTRYER_CHR1)
/* basic system hardware */
MDRV_CPU_ADD(CDP1802_TAG, CDP1802, DESTRYER_CHR1)
MDRV_CPU_PROGRAM_MAP(destryer_map, 0)
MDRV_CPU_IO_MAP(destryer_io_map, 0)
MDRV_CPU_CONFIG(cidelsa_cdp1802_config)
@ -593,24 +520,15 @@ static MACHINE_DRIVER_START( destryer )
MDRV_MACHINE_START(cidelsa)
MDRV_MACHINE_RESET(cidelsa)
// video hardware
/* sound and video hardware */
MDRV_IMPORT_FROM(destryer_video)
// sound hardware
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_SOUND_ADD("cdp", CDP1869, DESTRYER_CHR2)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MACHINE_DRIVER_END
static MACHINE_DRIVER_START( destryea )
MDRV_DRIVER_DATA(cidelsa_state)
// basic system hardware
MDRV_CPU_ADD(MAIN_CPU_TAG, CDP1802, DESTRYER_CHR1)
/* basic system hardware */
MDRV_CPU_ADD(CDP1802_TAG, CDP1802, DESTRYER_CHR1)
MDRV_CPU_PROGRAM_MAP(destryea_map, 0)
MDRV_CPU_IO_MAP(destryer_io_map, 0)
MDRV_CPU_CONFIG(cidelsa_cdp1802_config)
@ -619,24 +537,16 @@ static MACHINE_DRIVER_START( destryea )
MDRV_MACHINE_START(cidelsa)
MDRV_MACHINE_RESET(cidelsa)
// video hardware
/* sound and video hardware */
MDRV_IMPORT_FROM(destryer_video)
// sound hardware
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_SOUND_ADD("cdp", CDP1869, DESTRYER_CHR2)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MACHINE_DRIVER_END
static MACHINE_DRIVER_START( altair )
MDRV_DRIVER_DATA(cidelsa_state)
// basic system hardware
/* basic system hardware */
MDRV_CPU_ADD(MAIN_CPU_TAG, CDP1802, ALTAIR_CHR1)
MDRV_CPU_ADD(CDP1802_TAG, CDP1802, ALTAIR_CHR1)
MDRV_CPU_PROGRAM_MAP(altair_map, 0)
MDRV_CPU_IO_MAP(altair_io_map, 0)
MDRV_CPU_CONFIG(cidelsa_cdp1802_config)
@ -644,31 +554,21 @@ static MACHINE_DRIVER_START( altair )
MDRV_MACHINE_START(cidelsa)
MDRV_MACHINE_RESET(cidelsa)
// input/output hardware
/* input/output hardware */
MDRV_CDP1852_ADD("ic23", CDP1852_CLOCK_HIGH, cidelsa_cdp1852_in0_intf) /* clock is really tied to CDP1876 CMSEL (pin 32) */
MDRV_CDP1852_ADD("ic24", CDP1852_CLOCK_HIGH, cidelsa_cdp1852_in1_intf)
MDRV_CDP1852_ADD("ic25", CDP1852_CLOCK_HIGH, cidelsa_cdp1852_in2_intf)
MDRV_CDP1852_ADD("ic26", ALTAIR_CHR1 / 8, altair_cdp1852_out1_intf) /* clock is CDP1802 TPB */
// video hardware
/* sound and video hardware */
MDRV_IMPORT_FROM(altair_video)
// sound hardware
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_SOUND_ADD("cdp", CDP1869, ALTAIR_CHR2)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MACHINE_DRIVER_END
static MACHINE_DRIVER_START( draco )
MDRV_DRIVER_DATA(cidelsa_state)
// basic system hardware
MDRV_CPU_ADD(MAIN_CPU_TAG, CDP1802, DRACO_CHR1)
/* basic system hardware */
MDRV_CPU_ADD(CDP1802_TAG, CDP1802, DRACO_CHR1)
MDRV_CPU_PROGRAM_MAP(draco_map, 0)
MDRV_CPU_IO_MAP(draco_io_map, 0)
MDRV_CPU_CONFIG(cidelsa_cdp1802_config)
@ -682,32 +582,20 @@ static MACHINE_DRIVER_START( draco )
MDRV_CPU_IO_MAP(draco_sound_io_map, 0)
MDRV_CPU_CONFIG(draco_cop_intf)
// input/output hardware
/* input/output hardware */
MDRV_CDP1852_ADD("ic29", CDP1852_CLOCK_HIGH, cidelsa_cdp1852_in0_intf) /* clock is really tied to CDP1876 CMSEL (pin 32) */
MDRV_CDP1852_ADD("ic30", CDP1852_CLOCK_HIGH, cidelsa_cdp1852_in1_intf)
MDRV_CDP1852_ADD("ic31", CDP1852_CLOCK_HIGH, cidelsa_cdp1852_in2_intf)
MDRV_CDP1852_ADD("ic32", DRACO_CHR1 / 8, draco_cdp1852_out1_intf) /* clock is CDP1802 TPB */
// video hardware
/* sound and video hardware */
MDRV_IMPORT_FROM(draco_video)
// sound hardware
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_SOUND_ADD("cdp", CDP1869, DRACO_CHR2)
MDRV_SOUND_ADD("ay", AY8910, DRACO_SND_CHR1)
MDRV_SOUND_CONFIG(ay8910_config)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MACHINE_DRIVER_END
/* ROMs */
ROM_START( destryer )
ROM_REGION( 0x10000, MAIN_CPU_TAG, 0 )
ROM_REGION( 0x10000, CDP1802_TAG, 0 )
ROM_LOAD( "des a 2.ic4", 0x0000, 0x0800, CRC(63749870) SHA1(a8eee4509d7a52dcf33049de221d928da3632174) )
ROM_LOAD( "des b 2.ic5", 0x0800, 0x0800, CRC(60604f40) SHA1(32ca95c5b38b0f4992e04d77123d217f143ae084) )
ROM_LOAD( "des c 2.ic6", 0x1000, 0x0800, CRC(a7cdeb7b) SHA1(a5a7748967d4ca89fb09632e1f0130ef050dbd68) )
@ -716,7 +604,7 @@ ROM_END
// this was destroyer2.rom in standalone emu..
ROM_START( destryea )
ROM_REGION( 0x10000, MAIN_CPU_TAG, 0 )
ROM_REGION( 0x10000, CDP1802_TAG, 0 )
ROM_LOAD( "destryea_1", 0x0000, 0x0800, CRC(421428e9) SHA1(0ac3a1e7f61125a1cd82145fa28cbc4b93505dc9) )
ROM_LOAD( "destryea_2", 0x0800, 0x0800, CRC(55dc8145) SHA1(a0066d3f3ac0ae56273485b74af90eeffea5e64e) )
ROM_LOAD( "destryea_3", 0x1000, 0x0800, CRC(5557bdf8) SHA1(37a9cbc5d25051d3bed7535c58aac937cd7c64e1) )
@ -724,7 +612,7 @@ ROM_START( destryea )
ROM_END
ROM_START( altair )
ROM_REGION( 0x10000, MAIN_CPU_TAG, 0 )
ROM_REGION( 0x10000, CDP1802_TAG, 0 )
ROM_LOAD( "alt a 1.ic7", 0x0000, 0x0800, CRC(37c26c4e) SHA1(30df7efcf5bd12dafc1cb6e894fc18e7b76d3e61) )
ROM_LOAD( "alt b 1.ic8", 0x0800, 0x0800, CRC(76b814a4) SHA1(e8ab1d1cbcef974d929ef8edd10008f60052a607) )
ROM_LOAD( "alt c 1.ic9", 0x1000, 0x0800, CRC(2569ce44) SHA1(a09597d2f8f50fab9a09ed9a59c50a2bdcba47bb) )
@ -734,7 +622,7 @@ ROM_START( altair )
ROM_END
ROM_START( draco )
ROM_REGION( 0x10000, MAIN_CPU_TAG, 0 )
ROM_REGION( 0x10000, CDP1802_TAG, 0 )
ROM_LOAD( "dra a 1.ic10", 0x0000, 0x0800, CRC(ca127984) SHA1(46721cf42b1c891f7c88bc063a2149dd3cefea74) )
ROM_LOAD( "dra b 1.ic11", 0x0800, 0x0800, CRC(e4936e28) SHA1(ddbbf769994d32a6bce75312306468a89033f0aa) )
ROM_LOAD( "dra c 1.ic12", 0x1000, 0x0800, CRC(94480f5d) SHA1(8f49ce0f086259371e999d097a502482c83c6e9e) )

View File

@ -2,9 +2,12 @@
#define __CIDELSA__
#include "cpu/cdp1802/cdp1802.h"
#include "video/cdp1869.h"
#define MAIN_CPU_TAG "main"
#define SCREEN_TAG "main"
#define CDP1802_TAG "cpd1802"
#define CDP1869_TAG "cdp1869"
#define AY8910_TAG "ay8910"
#define DESTRYER_CHR1 3579000.0 // unverified
#define DESTRYER_CHR2 XTAL_5_7143MHz
#define ALTAIR_CHR1 3579000.0 // unverified
@ -13,6 +16,14 @@
#define DRACO_CHR2 CDP1869_DOT_CLK_PAL // unverified
#define DRACO_SND_CHR1 XTAL_2_01216MHz
#define CIDELSA_PAGERAM_SIZE 0x400
#define DRACO_PAGERAM_SIZE 0x800
#define CIDELSA_CHARRAM_SIZE 0x800
#define CIDELSA_PAGERAM_MASK 0x3ff
#define DRACO_PAGERAM_MASK 0x7ff
#define CIDELSA_CHARRAM_MASK 0x7ff
typedef struct _cidelsa_state cidelsa_state;
struct _cidelsa_state

View File

@ -1,21 +1,11 @@
#include "driver.h"
#include "video/cdp1869.h"
#include "sound/cdp1869.h"
#include "sound/ay8910.h"
#include "cidelsa.h"
#define CIDELSA_PAGERAM_SIZE 0x400
#define DRACO_PAGERAM_SIZE 0x800
#define CIDELSA_CHARRAM_SIZE 0x800
#define CIDELSA_PAGERAM_MASK 0x3ff
#define DRACO_PAGERAM_MASK 0x7ff
#define CIDELSA_CHARRAM_MASK 0x7ff
#define SCREEN_TAG "main"
#define CDP1869_TAG "cdp1869"
/* Page RAM Access */
static CDP1869_PAGE_RAM_READ(cidelsa_pageram_r)
static CDP1869_PAGE_RAM_READ( cidelsa_pageram_r )
{
cidelsa_state *state = device->machine->driver_data;
@ -29,7 +19,7 @@ static CDP1869_PAGE_RAM_READ(cidelsa_pageram_r)
return state->pageram[addr];
}
static CDP1869_PAGE_RAM_WRITE(cidelsa_pageram_w)
static CDP1869_PAGE_RAM_WRITE( cidelsa_pageram_w )
{
cidelsa_state *state = device->machine->driver_data;
@ -43,7 +33,7 @@ static CDP1869_PAGE_RAM_WRITE(cidelsa_pageram_w)
state->pageram[addr] = data;
}
static CDP1869_PAGE_RAM_READ(draco_pageram_r)
static CDP1869_PAGE_RAM_READ( draco_pageram_r )
{
cidelsa_state *state = device->machine->driver_data;
@ -52,7 +42,7 @@ static CDP1869_PAGE_RAM_READ(draco_pageram_r)
return state->pageram[addr];
}
static CDP1869_PAGE_RAM_WRITE(draco_pageram_w)
static CDP1869_PAGE_RAM_WRITE( draco_pageram_w )
{
cidelsa_state *state = device->machine->driver_data;
@ -63,7 +53,7 @@ static CDP1869_PAGE_RAM_WRITE(draco_pageram_w)
/* Character RAM Access */
static CDP1869_CHAR_RAM_READ(cidelsa_charram_r)
static CDP1869_CHAR_RAM_READ( cidelsa_charram_r )
{
cidelsa_state *state = device->machine->driver_data;
@ -76,7 +66,7 @@ static CDP1869_CHAR_RAM_READ(cidelsa_charram_r)
return data;
}
static CDP1869_CHAR_RAM_WRITE(cidelsa_charram_w)
static CDP1869_CHAR_RAM_WRITE( cidelsa_charram_w )
{
cidelsa_state *state = device->machine->driver_data;
@ -87,7 +77,7 @@ static CDP1869_CHAR_RAM_WRITE(cidelsa_charram_w)
state->pcbram[addr] = state->cdp1802_q;
}
static CDP1869_CHAR_RAM_READ(draco_charram_r)
static CDP1869_CHAR_RAM_READ( draco_charram_r )
{
cidelsa_state *state = device->machine->driver_data;
@ -100,7 +90,7 @@ static CDP1869_CHAR_RAM_READ(draco_charram_r)
return data;
}
static CDP1869_CHAR_RAM_WRITE(draco_charram_w)
static CDP1869_CHAR_RAM_WRITE( draco_charram_w )
{
cidelsa_state *state = device->machine->driver_data;
@ -113,7 +103,7 @@ static CDP1869_CHAR_RAM_WRITE(draco_charram_w)
/* Page Color Bit Access */
static CDP1869_PCB_READ(cidelsa_pcb_r)
static CDP1869_PCB_READ( cidelsa_pcb_r )
{
cidelsa_state *state = device->machine->driver_data;
@ -123,7 +113,7 @@ static CDP1869_PCB_READ(cidelsa_pcb_r)
return state->pcbram[addr];
}
static CDP1869_PCB_READ(draco_pcb_r)
static CDP1869_PCB_READ( draco_pcb_r )
{
cidelsa_state *state = device->machine->driver_data;
@ -135,104 +125,96 @@ static CDP1869_PCB_READ(draco_pcb_r)
/* Predisplay Changed Handler */
static CDP1869_ON_PRD_CHANGED(cidelsa_prd_changed)
static WRITE_LINE_DEVICE_HANDLER( cidelsa_prd_w )
{
cidelsa_state *state = device->machine->driver_data;
cidelsa_state *driver_state = device->machine->driver_data;
// PRD is inverted
cputag_set_input_line(device->machine, MAIN_CPU_TAG, INPUT_LINE_IRQ0, !prd);
state->cdp1869_prd = !prd;
/* invert PRD signal */
cputag_set_input_line(device->machine, CDP1802_TAG, INPUT_LINE_IRQ0, !state);
driver_state->cdp1869_prd = !state;
}
static CDP1869_ON_PRD_CHANGED(draco_prd_changed)
static WRITE_LINE_DEVICE_HANDLER( draco_prd_w )
{
cidelsa_state *state = device->machine->driver_data;
cidelsa_state *driver_state = device->machine->driver_data;
state->cdp1869_prd = prd;
driver_state->cdp1869_prd = state;
}
/* CDP1869 Interface */
static CDP1869_INTERFACE( destryer_cdp1869_intf )
{
CDP1802_TAG,
SCREEN_TAG,
0,
CDP1869_PAL,
cidelsa_pageram_r,
cidelsa_pageram_w,
cidelsa_pcb_r,
cidelsa_charram_r,
cidelsa_charram_w,
cidelsa_prd_changed,
DEVCB_LINE(cidelsa_prd_w)
};
static CDP1869_INTERFACE( altair_cdp1869_intf )
{
CDP1802_TAG,
SCREEN_TAG,
0,
CDP1869_PAL,
cidelsa_pageram_r,
cidelsa_pageram_w,
cidelsa_pcb_r,
cidelsa_charram_r,
cidelsa_charram_w,
cidelsa_prd_changed,
DEVCB_LINE(cidelsa_prd_w)
};
static CDP1869_INTERFACE( draco_cdp1869_intf )
{
CDP1802_TAG,
SCREEN_TAG,
0,
CDP1869_PAL,
draco_pageram_r,
draco_pageram_w,
draco_pcb_r,
draco_charram_r,
draco_charram_w,
draco_prd_changed,
DEVCB_LINE(draco_prd_w)
};
/* Video Start */
static VIDEO_START(cidelsa)
static void video_start(running_machine *machine, UINT16 pageram_size)
{
cidelsa_state *state = machine->driver_data;
/* allocate memory */
state->pageram = auto_malloc(CIDELSA_PAGERAM_SIZE);
state->pageram = auto_malloc(pageram_size);
state->pcbram = auto_malloc(CIDELSA_CHARRAM_SIZE);
state->charram = auto_malloc(CIDELSA_CHARRAM_SIZE);
/* find devices */
state->cdp1869 = devtag_get_device(machine, CDP1869_VIDEO, CDP1869_TAG);
state->cdp1869 = devtag_get_device(machine, SOUND, CDP1869_TAG);
/* register for state saving */
state_save_register_global(machine, state->cdp1869_prd);
state_save_register_global(machine, state->cdp1869_pcb);
state_save_register_global_pointer(machine, state->pageram, CIDELSA_PAGERAM_SIZE);
state_save_register_global_pointer(machine, state->pageram, pageram_size);
state_save_register_global_pointer(machine, state->pcbram, CIDELSA_CHARRAM_SIZE);
state_save_register_global_pointer(machine, state->charram, CIDELSA_CHARRAM_SIZE);
}
static VIDEO_START(cidelsa)
{
video_start(machine, CIDELSA_PAGERAM_SIZE);
}
static VIDEO_START(draco)
{
cidelsa_state *state = machine->driver_data;
/* allocate memory */
state->pageram = auto_malloc(DRACO_PAGERAM_SIZE);
state->pcbram = auto_malloc(CIDELSA_CHARRAM_SIZE);
state->charram = auto_malloc(CIDELSA_CHARRAM_SIZE);
/* find devices */
state->cdp1869 = devtag_get_device(machine, CDP1869_VIDEO, CDP1869_TAG);
/* register for state saving */
state_save_register_global(machine, state->cdp1869_prd);
state_save_register_global(machine, state->cdp1869_pcb);
state_save_register_global_pointer(machine, state->pageram, DRACO_PAGERAM_SIZE);
state_save_register_global_pointer(machine, state->pcbram, CIDELSA_CHARRAM_SIZE);
state_save_register_global_pointer(machine, state->charram, CIDELSA_CHARRAM_SIZE);
video_start(machine, DRACO_PAGERAM_SIZE);
}
/* Video Update */
@ -246,6 +228,36 @@ static VIDEO_UPDATE( cidelsa )
return 0;
}
/* AY-3-8910 */
static WRITE8_DEVICE_HANDLER( draco_ay8910_port_b_w )
{
/*
bit description
0 RELE0
1 RELE1
2 sound output -> * -> 22K capacitor -> GND
3 sound output -> * -> 220K capacitor -> GND
4 5V -> 1K resistor -> * -> 10uF capacitor -> GND (volume pot voltage adjustment)
5 not connected
6 not connected
7 not connected
*/
}
static const ay8910_interface ay8910_config =
{
AY8910_SINGLE_OUTPUT,
AY8910_DEFAULT_LOADS,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_HANDLER(draco_ay8910_port_b_w)
};
/* Machine Drivers */
MACHINE_DRIVER_START( destryer_video )
@ -260,7 +272,9 @@ MACHINE_DRIVER_START( destryer_video )
MDRV_SCREEN_RAW_PARAMS(DESTRYER_CHR2, CDP1869_SCREEN_WIDTH, CDP1869_HBLANK_END, CDP1869_HBLANK_START, CDP1869_TOTAL_SCANLINES_PAL, CDP1869_SCANLINE_VBLANK_END_PAL, CDP1869_SCANLINE_VBLANK_START_PAL)
MDRV_SCREEN_DEFAULT_POSITION(1.226, 0.012, 1.4, 0.044)
MDRV_CDP1869_ADD(CDP1869_TAG, SCREEN_TAG, DESTRYER_CHR2, 0, MAIN_CPU_TAG, destryer_cdp1869_intf)
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_CDP1869_ADD(CDP1869_TAG, DESTRYER_CHR2, destryer_cdp1869_intf)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MACHINE_DRIVER_END
MACHINE_DRIVER_START( altair_video )
@ -275,7 +289,9 @@ MACHINE_DRIVER_START( altair_video )
MDRV_SCREEN_RAW_PARAMS(ALTAIR_CHR2, CDP1869_SCREEN_WIDTH, CDP1869_HBLANK_END, CDP1869_HBLANK_START, CDP1869_TOTAL_SCANLINES_PAL, CDP1869_SCANLINE_VBLANK_END_PAL, CDP1869_SCANLINE_VBLANK_START_PAL)
MDRV_SCREEN_DEFAULT_POSITION(1.226, 0.012, 1.4, 0.044)
MDRV_CDP1869_ADD(CDP1869_TAG, SCREEN_TAG, ALTAIR_CHR2, 0, MAIN_CPU_TAG, altair_cdp1869_intf)
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_CDP1869_ADD(CDP1869_TAG, ALTAIR_CHR2, altair_cdp1869_intf)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MACHINE_DRIVER_END
MACHINE_DRIVER_START( draco_video )
@ -290,5 +306,9 @@ MACHINE_DRIVER_START( draco_video )
MDRV_SCREEN_RAW_PARAMS(DRACO_CHR2, CDP1869_SCREEN_WIDTH, CDP1869_HBLANK_END, CDP1869_HBLANK_START, CDP1869_TOTAL_SCANLINES_PAL, CDP1869_SCANLINE_VBLANK_END_PAL, CDP1869_SCANLINE_VBLANK_START_PAL)
MDRV_SCREEN_DEFAULT_POSITION(1.226, 0.012, 1.360, 0.024)
MDRV_CDP1869_ADD(CDP1869_TAG, SCREEN_TAG, DRACO_CHR2, 0, MAIN_CPU_TAG, draco_cdp1869_intf)
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_CDP1869_ADD(CDP1869_TAG, DRACO_CHR2, draco_cdp1869_intf)
MDRV_SOUND_ADD(AY8910_TAG, AY8910, DRACO_SND_CHR1)
MDRV_SOUND_CONFIG(ay8910_config)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MACHINE_DRIVER_END