antic.c: converted to be a device. [Fabio Priuli]

This commit is contained in:
Fabio Priuli 2014-09-09 18:03:05 +00:00
parent 7ae39e007c
commit 7696f22483
8 changed files with 825 additions and 798 deletions

View File

@ -30,7 +30,6 @@ public:
: atari_common_state(mconfig, type, tag),
m_maincpu(*this, "maincpu") { }
virtual void machine_start();
virtual void machine_reset();
required_device<cpu_device> m_maincpu;
};
@ -40,7 +39,7 @@ static ADDRESS_MAP_START(a5200_mem, AS_PROGRAM, 8, bartop52_state )
AM_RANGE(0x0000, 0x3fff) AM_RAM
AM_RANGE(0x4000, 0xbfff) AM_ROM
AM_RANGE(0xc000, 0xc0ff) AM_DEVREADWRITE("gtia", gtia_device, read, write)
AM_RANGE(0xd400, 0xd5ff) AM_READWRITE(atari_antic_r, atari_antic_w)
AM_RANGE(0xd400, 0xd5ff) AM_DEVREADWRITE("antic", antic_device, read, write)
AM_RANGE(0xe800, 0xe8ff) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0xf800, 0xffff) AM_ROM
ADDRESS_MAP_END
@ -102,17 +101,10 @@ static INPUT_PORTS_START(bartop52)
INPUT_PORTS_END
void bartop52_state::machine_start()
{
/* ANTIC */
antic_start(machine());
}
void bartop52_state::machine_reset()
{
pokey_device *pokey = machine().device<pokey_device>("pokey");
pokey->write(15,0);
antic_reset();
}
@ -124,13 +116,16 @@ static MACHINE_CONFIG_START( a5200, bartop52_state )
MCFG_DEVICE_ADD("gtia", ATARI_GTIA, 0)
MCFG_DEVICE_ADD("antic", ATARI_ANTIC, 0)
MCFG_ANTIC_GTIA("gtia")
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1))
MCFG_SCREEN_VISIBLE_AREA(MIN_X, MAX_X, MIN_Y, MAX_Y)
MCFG_SCREEN_REFRESH_RATE(FRAME_RATE_60HZ)
MCFG_SCREEN_SIZE(HWIDTH*8, TOTAL_LINES_60HZ)
MCFG_SCREEN_UPDATE_DRIVER(atari_common_state, screen_update_atari)
MCFG_SCREEN_UPDATE_DEVICE("antic", antic_device, screen_update)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", 256)

View File

@ -65,7 +65,6 @@ public:
WRITE_LINE_MEMBER(pia_cb2_w) { } // This is used by Floppy drive on Atari 8bits Home Computers
TIMER_DEVICE_CALLBACK_MEMBER(mcu_timer_proc);
int atari_input_disabled();
virtual void machine_start();
virtual void machine_reset();
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_mcu;
@ -289,7 +288,7 @@ static ADDRESS_MAP_START(a600xl_mem, AS_PROGRAM, 8, maxaflex_state )
AM_RANGE(0xd100, 0xd1ff) AM_NOP
AM_RANGE(0xd200, 0xd2ff) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0xd300, 0xd3ff) AM_DEVREADWRITE("pia", pia6821_device, read_alt, write_alt)
AM_RANGE(0xd400, 0xd4ff) AM_READWRITE(atari_antic_r, atari_antic_w)
AM_RANGE(0xd400, 0xd4ff) AM_DEVREADWRITE("antic", antic_device, read, write)
AM_RANGE(0xd500, 0xd7ff) AM_NOP
AM_RANGE(0xd800, 0xffff) AM_ROM /* OS */
ADDRESS_MAP_END
@ -385,17 +384,10 @@ READ8_MEMBER(maxaflex_state::pia_pb_r)
}
void maxaflex_state::machine_start()
{
/* ANTIC */
antic_start(machine());
}
void maxaflex_state::machine_reset()
{
pokey_device *pokey = machine().device<pokey_device>("pokey");
pokey->write(15,0);
antic_reset();
// Supervisor board reset
m_portA_in = m_portA_out = m_ddrA = 0;
@ -426,6 +418,9 @@ static MACHINE_CONFIG_START( maxaflex, maxaflex_state )
MCFG_DEVICE_ADD("gtia", ATARI_GTIA, 0)
MCFG_GTIA_READ_CB(IOPORT("console"))
MCFG_DEVICE_ADD("antic", ATARI_ANTIC, 0)
MCFG_ANTIC_GTIA("gtia")
MCFG_DEVICE_ADD("pia", PIA6821, 0)
MCFG_PIA_READPA_HANDLER(READ8(maxaflex_state, pia_pa_r))
MCFG_PIA_READPB_HANDLER(READ8(maxaflex_state, pia_pb_r))
@ -440,7 +435,7 @@ static MACHINE_CONFIG_START( maxaflex, maxaflex_state )
MCFG_SCREEN_VISIBLE_AREA(MIN_X, MAX_X, MIN_Y, MAX_Y)
MCFG_SCREEN_REFRESH_RATE(FRAME_RATE_60HZ)
MCFG_SCREEN_SIZE(HWIDTH*8, TOTAL_LINES_60HZ)
MCFG_SCREEN_UPDATE_DRIVER(atari_common_state, screen_update_atari)
MCFG_SCREEN_UPDATE_DEVICE("antic", antic_device, screen_update)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", 256)

View File

@ -24,12 +24,10 @@ public:
atari_common_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_gtia(*this, "gtia"),
tv_artifacts(0) { }
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
m_antic(*this, "antic")
{ }
virtual void video_start();
UINT32 screen_update_atari(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_DEVICE_CALLBACK_MEMBER( a400_interrupt );
TIMER_DEVICE_CALLBACK_MEMBER( a800_interrupt );
@ -38,59 +36,13 @@ public:
DECLARE_PALETTE_INIT(atari);
DECLARE_READ8_MEMBER ( atari_antic_r );
DECLARE_WRITE8_MEMBER ( atari_antic_w );
POKEY_INTERRUPT_CB_MEMBER(interrupt_cb);
POKEY_KEYBOARD_CB_MEMBER(a5200_keypads);
POKEY_KEYBOARD_CB_MEMBER(a800_keyboard);
private:
static const device_timer_id TIMER_CYCLE_STEAL = 0;
static const device_timer_id TIMER_ISSUE_DLI = 1;
static const device_timer_id TIMER_LINE_REND = 2;
static const device_timer_id TIMER_LINE_DONE = 3;
required_device<gtia_device> m_gtia;
UINT32 tv_artifacts;
void prio_init();
void cclk_init();
void artifacts_gfx(UINT8 *src, UINT8 *dst, int width);
void artifacts_txt(UINT8 * src, UINT8 * dst, int width);
void antic_linerefresh();
int cycle();
void after(int cycles, timer_expired_delegate function);
TIMER_CALLBACK_MEMBER( antic_issue_dli );
TIMER_CALLBACK_MEMBER( antic_line_done );
TIMER_CALLBACK_MEMBER( antic_steal_cycles );
TIMER_CALLBACK_MEMBER( antic_scanline_render );
inline void LMS(int new_cmd);
void antic_scanline_dma(int param);
void generic_atari_interrupt(int button_count);
int m_antic_render1, m_antic_render2, m_antic_render3;
required_device<antic_device> m_antic;
};
/* video */
#define CYCLES_PER_LINE 114 /* total number of cpu cycles per scanline (incl. hblank) */
#define CYCLES_REFRESH 9 /* number of cycles lost for ANTICs RAM refresh using DMA */
#define CYCLES_HSTART 32 /* where does the ANTIC DMA fetch start */
#define CYCLES_DLI_NMI 7 /* number of cycles until the CPU recognizes a DLI */
#define CYCLES_HSYNC 104 /* where does the HSYNC position of a scanline start */
#define VBL_END 8 /* vblank ends in this scanline */
#define VDATA_START 11 /* video display begins in this scanline */
#define VDATA_END 244 /* video display ends in this scanline */
#define VBL_START 248 /* vblank starts in this scanline */
/* total number of lines per frame (incl. vblank) */
#define TOTAL_LINES_60HZ 262
#define TOTAL_LINES_50HZ 312
/* frame rates */
#define FRAME_RATE_50HZ (double)1789790/114/TOTAL_LINES_50HZ
#define FRAME_RATE_60HZ (double)1789790/114/TOTAL_LINES_60HZ
#endif /* ATARI_H */

View File

@ -9,10 +9,8 @@
***************************************************************************/
#include "emu.h"
#include "cpu/m6502/m6502.h"
#include "includes/atari.h"
#include "sound/pokey.h"
#include "sound/dac.h"
#define VERBOSE_POKEY 1
#define VERBOSE_SERIAL 1

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,27 @@
#define __ANTIC_H__
#include "emu.h"
#include "video/gtia.h"
#define CYCLES_PER_LINE 114 /* total number of cpu cycles per scanline (incl. hblank) */
#define CYCLES_REFRESH 9 /* number of cycles lost for ANTICs RAM refresh using DMA */
#define CYCLES_HSTART 32 /* where does the ANTIC DMA fetch start */
#define CYCLES_DLI_NMI 7 /* number of cycles until the CPU recognizes a DLI */
#define CYCLES_HSYNC 104 /* where does the HSYNC position of a scanline start */
#define VBL_END 8 /* vblank ends in this scanline */
#define VDATA_START 11 /* video display begins in this scanline */
#define VDATA_END 244 /* video display ends in this scanline */
#define VBL_START 248 /* vblank starts in this scanline */
/* total number of lines per frame (incl. vblank) */
#define TOTAL_LINES_60HZ 262
#define TOTAL_LINES_50HZ 312
/* frame rates */
#define FRAME_RATE_50HZ (double)1789790/114/TOTAL_LINES_50HZ
#define FRAME_RATE_60HZ (double)1789790/114/TOTAL_LINES_60HZ
#define HWIDTH 48 /* total characters per line */
#define HCHARS 44 /* visible characters per line */
@ -122,6 +143,179 @@
#define COPY8(dst,s1,s2) *dst++ = s1; *dst++ = s2
#define COPY16(dst,s1,s2,s3,s4) *dst++ = s1; *dst++ = s2; *dst++ = s3; *dst++ = s4
#define RDANTIC(space) space.read_byte(m_dpage+m_doffs)
#define RDVIDEO(space,o) space.read_byte(m_vpage+((m_voffs+(o))&VOFFS))
#define RDCHGEN(space,o) space.read_byte(m_chbase+(o))
#define RDPMGFXS(space,o) space.read_byte(m_pmbase_s+(o)+(m_scanline>>1))
#define RDPMGFXD(space,o) space.read_byte(m_pmbase_d+(o)+m_scanline)
#define PREPARE() \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]
#define PREPARE_TXT2(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
{ \
UINT16 ch = RDVIDEO(space,i) << 3; \
if (ch & 0x400) \
{ \
ch = RDCHGEN(space,(ch & 0x3f8) + m_w.chbasl); \
ch = (ch ^ m_chxor) & m_chand; \
} \
else \
{ \
ch = RDCHGEN(space,ch + m_w.chbasl); \
} \
video->data[i] = ch; \
}
#define PREPARE_TXT3(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
{ \
UINT16 ch = RDVIDEO(space,i) << 3; \
if (ch & 0x400) \
{ \
ch &= 0x3f8; \
if ((ch & 0x300) == 0x300) \
{ \
if (m_w.chbasl < 2) /* first two lines empty */ \
ch = 0x00; \
else /* lines 2..7 are standard, 8&9 are 0&1 */ \
ch = RDCHGEN(space,ch + (m_w.chbasl & 7));\
} \
else \
{ \
if (m_w.chbasl > 7) /* last two lines empty */ \
ch = 0x00; \
else /* lines 0..7 are standard */ \
ch = RDCHGEN(space,ch + m_w.chbasl); \
} \
ch = (ch ^ m_chxor) & m_chand; \
} \
else \
{ \
if ((ch & 0x300) == 0x300) \
{ \
if (m_w.chbasl < 2) /* first two lines empty */ \
ch = 0x00; \
else /* lines 2..7 are standard, 8&9 are 0&1 */ \
ch = RDCHGEN(space,ch + (m_w.chbasl & 7));\
} \
else \
{ \
if (m_w.chbasl > 7) /* last two lines empty */ \
ch = 0x00; \
else /* lines 0..7 are standard */ \
ch = RDCHGEN(space,ch + m_w.chbasl); \
} \
} \
video->data[i] = ch; \
}
#define PREPARE_TXT45(space,width,shift) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
{ \
UINT16 ch = RDVIDEO(space,i) << 3; \
ch = ((ch>>2)&0x100)|RDCHGEN(space,(ch&0x3f8)+(m_w.chbasl>>shift)); \
video->data[i] = ch; \
}
#define PREPARE_TXT67(space,width,shift) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
{ \
UINT16 ch = RDVIDEO(space,i) << 3; \
ch = (ch&0x600)|(RDCHGEN(space,(ch&0x1f8)+(m_w.chbasl>>shift))<<1); \
video->data[i] = ch; \
}
#define PREPARE_GFX8(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i) << 2
#define PREPARE_GFX9BC(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i) << 1
#define PREPARE_GFXA(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i) << 1
#define PREPARE_GFXDE(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
#define PREPARE_GFXF(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
#define PREPARE_GFXG1(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
#define PREPARE_GFXG2(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
#define PREPARE_GFXG3(space,width) \
UINT32 *dst = (UINT32 *)&m_cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
/******************************************************************
* common end of a single antic/gtia mode emulation function
******************************************************************/
#define POST() \
--m_modelines
#define POST_GFX(width) \
m_steal_cycles += width; \
if (--m_modelines == 0) \
m_voffs = (m_voffs + width) & VOFFS
#define POST_TXT(width) \
m_steal_cycles += width; \
if (--m_modelines == 0) \
m_voffs = (m_voffs + width) & VOFFS; \
else if (m_w.chactl & 4) \
m_w.chbasl--; \
else \
m_w.chbasl++
/* erase a number of color clocks to background color PBK */
#define ERASE(size) \
for (int i = 0; i < size; i++) \
{ \
*dst++ = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
} \
#define ZAP48() \
dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
dst[ 0] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[ 1] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[ 2] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[45] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[46] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[47] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK
#define REP(FUNC, size) \
for (int i = 0; i < size; i++) \
{ \
FUNC(i); \
} \
struct ANTIC_R {
UINT8 antic00; /* 00 nothing */
UINT8 antic01; /* 01 nothing */
@ -166,233 +360,129 @@ struct VIDEO {
UINT16 data[HWIDTH]; /* graphics data buffer (text through chargen) */
};
typedef void (*atari_renderer_func)(address_space &space, VIDEO *video);
struct ANTIC {
atari_renderer_func renderer; /* current renderer */
UINT32 cmd; /* currently executed display list command */
UINT32 steal_cycles; /* steal how many cpu cycles for this line ? */
UINT32 vscrol_old; /* old vscrol value */
UINT32 hscrol_old; /* old hscrol value */
INT32 modelines; /* number of lines for current ANTIC mode */
UINT32 chbase; /* character mode source base */
UINT32 chand; /* character and mask (chactl) */
UINT32 chxor; /* character xor mask (chactl) */
UINT32 scanline; /* current scan line */
UINT32 pfwidth; /* playfield width */
UINT32 dpage; /* display list address page */
UINT32 doffs; /* display list offset into page */
UINT32 vpage; /* video data source page */
UINT32 voffs; /* video data offset into page */
UINT32 pmbase_s; /* p/m graphics single line source base */
UINT32 pmbase_d; /* p/m graphics double line source base */
ANTIC_R r; /* ANTIC read registers */
ANTIC_W w; /* ANTIC write registers */
UINT8 cclock[256+32]; /* color clock buffer filled by ANTIC */
UINT8 pmbits[256+32]; /* player missile buffer filled by GTIA */
UINT8 *prio_table[64]; /* player/missile priority tables */
VIDEO *video[312]; /* video buffer */
UINT32 *cclk_expand; /* shared buffer for the following: */
UINT32 *pf_21; /* 1cclk 2 color txt 2,3 */
UINT32 *pf_x10b; /* 1cclk 4 color txt 4,5, gfx D,E */
UINT32 *pf_3210b2; /* 1cclk 5 color txt 6,7, gfx 9,B,C */
UINT32 *pf_210b4; /* 4cclk 4 color gfx 8 */
UINT32 *pf_210b2; /* 2cclk 4 color gfx A */
UINT32 *pf_1b; /* 1cclk hires gfx F */
UINT32 *pf_gtia1; /* 1cclk gtia mode 1 */
UINT32 *pf_gtia2; /* 1cclk gtia mode 2 */
UINT32 *pf_gtia3; /* 1cclk gtia mode 3 */
UINT8 *used_colors; /* shared buffer for the following: */
UINT8 *uc_21; /* used colors for txt (2,3) */
UINT8 *uc_x10b; /* used colors for txt 4,5, gfx D,E */
UINT8 *uc_3210b2; /* used colors for txt 6,7, gfx 9,B,C */
UINT8 *uc_210b4; /* used colors for gfx 8 */
UINT8 *uc_210b2; /* used colors for gfx A */
UINT8 *uc_1b; /* used colors for gfx F */
UINT8 *uc_g1; /* used colors for gfx GTIA 1 */
UINT8 *uc_g2; /* used colors for gfx GTIA 2 */
UINT8 *uc_g3; /* used colors for gfx GTIA 3 */
bitmap_ind16 *bitmap;
class antic_device : public device_t
{
public:
// construction/destruction
antic_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// device-level overrides
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
static void set_gtia_tag(device_t &device, const char *tag) { downcast<antic_device &>(device).m_gtia_tag = tag; }
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void generic_interrupt(int button_count);
private:
static const device_timer_id TIMER_CYCLE_STEAL = 0;
static const device_timer_id TIMER_ISSUE_DLI = 1;
static const device_timer_id TIMER_LINE_REND = 2;
static const device_timer_id TIMER_LINE_DONE = 3;
const char *m_gtia_tag;
gtia_device *m_gtia;
UINT32 m_tv_artifacts;
int m_render1, m_render2, m_render3;
inline void mode_0(address_space &space, VIDEO *video);
inline void mode_2(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_3(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_4(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_5(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_6(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_7(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_8(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_9(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_a(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_b(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_c(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_d(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_e(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_f(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_gtia1(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_gtia2(address_space &space, VIDEO *video, int bytes, int erase);
inline void mode_gtia3(address_space &space, VIDEO *video, int bytes, int erase);
UINT32 m_cmd; /* currently executed display list command */
UINT32 m_steal_cycles; /* steal how many cpu cycles for this line ? */
UINT32 m_vscrol_old; /* old vscrol value */
UINT32 m_hscrol_old; /* old hscrol value */
INT32 m_modelines; /* number of lines for current ANTIC mode */
UINT32 m_chbase; /* character mode source base */
UINT32 m_chand; /* character and mask (chactl) */
UINT32 m_chxor; /* character xor mask (chactl) */
UINT32 m_scanline; /* current scan line */
UINT32 m_pfwidth; /* playfield width */
UINT32 m_dpage; /* display list address page */
UINT32 m_doffs; /* display list offset into page */
UINT32 m_vpage; /* video data source page */
UINT32 m_voffs; /* video data offset into page */
UINT32 m_pmbase_s; /* p/m graphics single line source base */
UINT32 m_pmbase_d; /* p/m graphics double line source base */
ANTIC_R m_r; /* ANTIC read registers */
ANTIC_W m_w; /* ANTIC write registers */
UINT8 m_cclock[256+32]; /* color clock buffer filled by ANTIC */
UINT8 m_pmbits[256+32]; /* player missile buffer filled by GTIA */
UINT8 *m_prio_table[64]; /* player/missile priority tables */
VIDEO *m_video[312]; /* video buffer */
UINT32 *m_cclk_expand; /* shared buffer for the following: */
UINT32 *m_pf_21; /* 1cclk 2 color txt 2,3 */
UINT32 *m_pf_x10b; /* 1cclk 4 color txt 4,5, gfx D,E */
UINT32 *m_pf_3210b2; /* 1cclk 5 color txt 6,7, gfx 9,B,C */
UINT32 *m_pf_210b4; /* 4cclk 4 color gfx 8 */
UINT32 *m_pf_210b2; /* 2cclk 4 color gfx A */
UINT32 *m_pf_1b; /* 1cclk hires gfx F */
UINT32 *m_pf_gtia1; /* 1cclk gtia mode 1 */
UINT32 *m_pf_gtia2; /* 1cclk gtia mode 2 */
UINT32 *m_pf_gtia3; /* 1cclk gtia mode 3 */
UINT8 *m_used_colors; /* shared buffer for the following: */
UINT8 *m_uc_21; /* used colors for txt (2,3) */
UINT8 *m_uc_x10b; /* used colors for txt 4,5, gfx D,E */
UINT8 *m_uc_3210b2; /* used colors for txt 6,7, gfx 9,B,C */
UINT8 *m_uc_210b4; /* used colors for gfx 8 */
UINT8 *m_uc_210b2; /* used colors for gfx A */
UINT8 *m_uc_1b; /* used colors for gfx F */
UINT8 *m_uc_g1; /* used colors for gfx GTIA 1 */
UINT8 *m_uc_g2; /* used colors for gfx GTIA 2 */
UINT8 *m_uc_g3; /* used colors for gfx GTIA 3 */
bitmap_ind16 *m_bitmap;
void prio_init();
void cclk_init();
void artifacts_gfx(UINT8 *src, UINT8 *dst, int width);
void artifacts_txt(UINT8 *src, UINT8 *dst, int width);
void linerefresh();
int cycle();
TIMER_CALLBACK_MEMBER( issue_dli );
TIMER_CALLBACK_MEMBER( line_done );
TIMER_CALLBACK_MEMBER( steal_cycles );
TIMER_CALLBACK_MEMBER( scanline_render );
void render(address_space &space, int param1, int param2, int param3);
inline void LMS(int new_cmd);
void scanline_dma(int param);
};
#define RDANTIC(space) space.read_byte(antic.dpage+antic.doffs)
#define RDVIDEO(space,o) space.read_byte(antic.vpage+((antic.voffs+(o))&VOFFS))
#define RDCHGEN(space,o) space.read_byte(antic.chbase+(o))
#define RDPMGFXS(space,o) space.read_byte(antic.pmbase_s+(o)+(antic.scanline>>1))
#define RDPMGFXD(space,o) space.read_byte(antic.pmbase_d+(o)+antic.scanline)
#define PREPARE() \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]
#define PREPARE_TXT2(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
{ \
UINT16 ch = RDVIDEO(space,i) << 3; \
if (ch & 0x400) \
{ \
ch = RDCHGEN(space,(ch & 0x3f8) + antic.w.chbasl); \
ch = (ch ^ antic.chxor) & antic.chand; \
} \
else \
{ \
ch = RDCHGEN(space,ch + antic.w.chbasl); \
} \
video->data[i] = ch; \
}
#define PREPARE_TXT3(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
{ \
UINT16 ch = RDVIDEO(space,i) << 3; \
if (ch & 0x400) \
{ \
ch &= 0x3f8; \
if ((ch & 0x300) == 0x300) \
{ \
if (antic.w.chbasl < 2) /* first two lines empty */ \
ch = 0x00; \
else /* lines 2..7 are standard, 8&9 are 0&1 */ \
ch = RDCHGEN(space,ch + (antic.w.chbasl & 7));\
} \
else \
{ \
if (antic.w.chbasl > 7) /* last two lines empty */ \
ch = 0x00; \
else /* lines 0..7 are standard */ \
ch = RDCHGEN(space,ch + antic.w.chbasl); \
} \
ch = (ch ^ antic.chxor) & antic.chand; \
} \
else \
{ \
if ((ch & 0x300) == 0x300) \
{ \
if (antic.w.chbasl < 2) /* first two lines empty */ \
ch = 0x00; \
else /* lines 2..7 are standard, 8&9 are 0&1 */ \
ch = RDCHGEN(space,ch + (antic.w.chbasl & 7));\
} \
else \
{ \
if (antic.w.chbasl > 7) /* last two lines empty */ \
ch = 0x00; \
else /* lines 0..7 are standard */ \
ch = RDCHGEN(space,ch + antic.w.chbasl); \
} \
} \
video->data[i] = ch; \
}
#define PREPARE_TXT45(space,width,shift) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
{ \
UINT16 ch = RDVIDEO(space,i) << 3; \
ch = ((ch>>2)&0x100)|RDCHGEN(space,(ch&0x3f8)+(antic.w.chbasl>>shift)); \
video->data[i] = ch; \
}
// device type definition
extern const device_type ATARI_ANTIC;
#define PREPARE_TXT67(space,width,shift) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
{ \
UINT16 ch = RDVIDEO(space,i) << 3; \
ch = (ch&0x600)|(RDCHGEN(space,(ch&0x1f8)+(antic.w.chbasl>>shift))<<1); \
video->data[i] = ch; \
}
#define PREPARE_GFX8(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i) << 2
#define MCFG_ANTIC_GTIA(_tag) \
antic_device::set_gtia_tag(*device, _tag);
#define PREPARE_GFX9BC(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i) << 1
#define PREPARE_GFXA(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i) << 1
#define PREPARE_GFXDE(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
#define PREPARE_GFXF(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
#define PREPARE_GFXG1(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
#define PREPARE_GFXG2(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
#define PREPARE_GFXG3(space,width) \
UINT32 *dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
for (int i = 0; i < width; i++) \
video->data[i] = RDVIDEO(space,i)
/******************************************************************
* common end of a single antic/gtia mode emulation function
******************************************************************/
#define POST() \
--antic.modelines
#define POST_GFX(width) \
antic.steal_cycles += width; \
if (--antic.modelines == 0) \
antic.voffs = (antic.voffs + width) & VOFFS
#define POST_TXT(width) \
antic.steal_cycles += width; \
if (--antic.modelines == 0) \
antic.voffs = (antic.voffs + width) & VOFFS; \
else if (antic.w.chactl & 4) \
antic.w.chbasl--; \
else \
antic.w.chbasl++
/* erase a number of color clocks to background color PBK */
#define ERASE(size) \
for (int i = 0; i < size; i++) \
{ \
*dst++ = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
} \
#define ZAP48() \
dst = (UINT32 *)&antic.cclock[PMOFFSET]; \
dst[ 0] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[ 1] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[ 2] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[45] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[46] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK; \
dst[47] = (PBK << 24) | (PBK << 16) | (PBK << 8) | PBK
#define REP(FUNC, size) \
for (int i = 0; i < size; i++) \
{ \
FUNC(i); \
} \
void antic_start(running_machine &machine);
void antic_vstart(running_machine &machine);
void antic_reset(void);
void antic_render(address_space &space, int param1, int param2, int param3);
extern ANTIC antic;
#endif /* __GTIA_H__ */

View File

@ -8,7 +8,6 @@
#include "emu.h"
#include "includes/atari.h"
#include "video/gtia.h"
#define VERBOSE 0
@ -16,7 +15,7 @@
/************************************************************************
* atari_vh_start
* video_start
* Initialize the ATARI800 video emulation
************************************************************************/
@ -24,81 +23,35 @@ void atari_common_state::video_start()
{
palette_device *m_palette = machine().first_screen()->palette();
m_antic_render1 = 0;
m_antic_render2 = 0;
m_antic_render3 = 0;
for (int i = 0; i < 256; i++)
m_gtia->set_color_lookup(i, (m_palette->pen(0) << 8) + m_palette->pen(0));
antic_vstart(machine());
}
/*****************************************************************************
/**************************************************************
*
* Generic Atari Interrupt Dispatcher
* This is called once per scanline and handles:
* vertical blank interrupt
* ANTIC DMA to possibly access the next display list command
* Interrupts
*
*****************************************************************************/
void atari_common_state::generic_atari_interrupt(int button_count)
{
LOG(("ANTIC #%3d @cycle #%d scanline interrupt\n", antic.scanline, cycle()));
if( antic.scanline < VBL_START )
{
antic_scanline_dma(0);
return;
}
if( antic.scanline == VBL_START )
{
/* specify buttons relevant to this Atari variant */
m_gtia->button_interrupt(button_count, machine().root_device().ioport("djoy_b")->read_safe(0));
/* do nothing new for the rest of the frame */
antic.modelines = machine().first_screen()->height() - VBL_START;
m_antic_render1 = 0;
m_antic_render2 = 0;
m_antic_render3 = 0;
/* if the CPU want's to be interrupted at vertical blank... */
if( antic.w.nmien & VBL_NMI )
{
LOG((" cause VBL NMI\n"));
/* set the VBL NMI status bit */
antic.r.nmist |= VBL_NMI;
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
}
}
/* refresh the display (translate color clocks to pixels) */
antic_linerefresh();
}
**************************************************************/
TIMER_DEVICE_CALLBACK_MEMBER( atari_common_state::a400_interrupt )
{
generic_atari_interrupt(4);
m_antic->generic_interrupt(4);
}
TIMER_DEVICE_CALLBACK_MEMBER( atari_common_state::a800_interrupt )
{
generic_atari_interrupt(4);
m_antic->generic_interrupt(4);
}
TIMER_DEVICE_CALLBACK_MEMBER( atari_common_state::a800xl_interrupt )
{
generic_atari_interrupt(2);
m_antic->generic_interrupt(2);
}
TIMER_DEVICE_CALLBACK_MEMBER( atari_common_state::a5200_interrupt )
{
generic_atari_interrupt(4);
m_antic->generic_interrupt(4);
}
/**************************************************************

View File

@ -263,7 +263,7 @@ public:
DECLARE_MACHINE_RESET(a400);
DECLARE_WRITE8_MEMBER(gtia_write);
DECLARE_WRITE8_MEMBER(gtia_cb);
DECLARE_WRITE8_MEMBER(a600xl_pia_pb_w);
DECLARE_WRITE8_MEMBER(a800xl_pia_pb_w);
@ -304,10 +304,6 @@ protected:
void setup_ram(int bank,UINT32 size);
void setup_cart(a800_cart_slot_device *slot);
// start helper (until GTIA & ANTIC are device-fied)
void common_start();
void a5200_start();
};
@ -535,7 +531,7 @@ static ADDRESS_MAP_START(a400_mem, AS_PROGRAM, 8, a400_state)
AM_RANGE(0xd100, 0xd1ff) AM_NOP
AM_RANGE(0xd200, 0xd2ff) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0xd300, 0xd3ff) AM_DEVREADWRITE("pia", pia6821_device, read_alt, write_alt)
AM_RANGE(0xd400, 0xd4ff) AM_READWRITE(atari_antic_r, atari_antic_w)
AM_RANGE(0xd400, 0xd4ff) AM_DEVREADWRITE("antic", antic_device, read, write)
AM_RANGE(0xd500, 0xd7ff) AM_NOP
AM_RANGE(0xd800, 0xffff) AM_ROM
ADDRESS_MAP_END
@ -550,7 +546,7 @@ static ADDRESS_MAP_START(a600xl_mem, AS_PROGRAM, 8, a400_state)
AM_RANGE(0xd100, 0xd1ff) AM_NOP
AM_RANGE(0xd200, 0xd2ff) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0xd300, 0xd3ff) AM_DEVREADWRITE("pia", pia6821_device, read_alt, write_alt)
AM_RANGE(0xd400, 0xd4ff) AM_READWRITE(atari_antic_r, atari_antic_w)
AM_RANGE(0xd400, 0xd4ff) AM_DEVREADWRITE("antic", antic_device, read, write)
AM_RANGE(0xd500, 0xd7ff) AM_NOP
AM_RANGE(0xd800, 0xffff) AM_ROM // OS
ADDRESS_MAP_END
@ -562,7 +558,7 @@ static ADDRESS_MAP_START(a1200xl_mem, AS_PROGRAM, 8, a400_state)
AM_RANGE(0xd100, 0xd1ff) AM_NOP
AM_RANGE(0xd200, 0xd2ff) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0xd300, 0xd3ff) AM_DEVREADWRITE("pia", pia6821_device, read_alt, write_alt)
AM_RANGE(0xd400, 0xd4ff) AM_READWRITE(atari_antic_r, atari_antic_w)
AM_RANGE(0xd400, 0xd4ff) AM_DEVREADWRITE("antic", antic_device, read, write)
AM_RANGE(0xd500, 0xd7ff) AM_NOP
AM_RANGE(0xd800, 0xffff) AM_READWRITE(a800xl_high_r, a800xl_high_w)
ADDRESS_MAP_END
@ -574,7 +570,7 @@ static ADDRESS_MAP_START(a800xl_mem, AS_PROGRAM, 8, a400_state)
AM_RANGE(0xd100, 0xd1ff) AM_NOP
AM_RANGE(0xd200, 0xd2ff) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0xd300, 0xd3ff) AM_DEVREADWRITE("pia", pia6821_device, read_alt, write_alt)
AM_RANGE(0xd400, 0xd4ff) AM_READWRITE(atari_antic_r, atari_antic_w)
AM_RANGE(0xd400, 0xd4ff) AM_DEVREADWRITE("antic", antic_device, read, write)
AM_RANGE(0xd500, 0xd7ff) AM_NOP
AM_RANGE(0xd800, 0xffff) AM_READWRITE(a800xl_high_r, a800xl_high_w)
ADDRESS_MAP_END
@ -586,7 +582,7 @@ static ADDRESS_MAP_START(a130xe_mem, AS_PROGRAM, 8, a400_state)
AM_RANGE(0xd100, 0xd1ff) AM_NOP
AM_RANGE(0xd200, 0xd2ff) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0xd300, 0xd3ff) AM_DEVREADWRITE("pia", pia6821_device, read_alt, write_alt)
AM_RANGE(0xd400, 0xd4ff) AM_READWRITE(atari_antic_r, atari_antic_w)
AM_RANGE(0xd400, 0xd4ff) AM_DEVREADWRITE("antic", antic_device, read, write)
AM_RANGE(0xd500, 0xd7ff) AM_NOP
AM_RANGE(0xd800, 0xffff) AM_READWRITE(a800xl_high_r, a800xl_high_w)
ADDRESS_MAP_END
@ -598,7 +594,7 @@ static ADDRESS_MAP_START(xegs_mem, AS_PROGRAM, 8, a400_state)
AM_RANGE(0xd100, 0xd1ff) AM_NOP
AM_RANGE(0xd200, 0xd2ff) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0xd300, 0xd3ff) AM_DEVREADWRITE("pia", pia6821_device, read_alt, write_alt)
AM_RANGE(0xd400, 0xd4ff) AM_READWRITE(atari_antic_r, atari_antic_w)
AM_RANGE(0xd400, 0xd4ff) AM_DEVREADWRITE("antic", antic_device, read, write)
AM_RANGE(0xd500, 0xd7ff) AM_NOP
AM_RANGE(0xd800, 0xffff) AM_READWRITE(a800xl_high_r, a800xl_high_w)
ADDRESS_MAP_END
@ -608,7 +604,7 @@ static ADDRESS_MAP_START(a5200_mem, AS_PROGRAM, 8, a400_state)
AM_RANGE(0x0000, 0x3fff) AM_RAM
AM_RANGE(0x4000, 0xbfff) AM_NOP // ROM installed at machine start
AM_RANGE(0xc000, 0xcfff) AM_DEVREADWRITE("gtia", gtia_device, read, write)
AM_RANGE(0xd400, 0xdfff) AM_READWRITE(atari_antic_r, atari_antic_w)
AM_RANGE(0xd400, 0xdfff) AM_DEVREADWRITE("antic", antic_device, read, write)
// 0xe000-0xe7ff - Expansion?
AM_RANGE(0xe800, 0xefff) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0xf000, 0xffff) AM_ROM
@ -1931,29 +1927,15 @@ void a400_state::setup_cart(a800_cart_slot_device *slot)
}
void a400_state::common_start()
{
/* ANTIC */
antic_start(machine());
}
void a400_state::a5200_start()
{
/* ANTIC */
antic_start(machine());
}
MACHINE_RESET_MEMBER( a400_state, a400 )
{
pokey_device *pokey = machine().device<pokey_device>("pokey");
pokey->write(15,0);
antic_reset();
}
MACHINE_START_MEMBER( a400_state, a400 )
{
common_start();
setup_ram(0, m_ram->size());
setup_ram(1, m_ram->size());
setup_ram(2, m_ram->size());
@ -1966,7 +1948,6 @@ MACHINE_START_MEMBER( a400_state, a400 )
MACHINE_START_MEMBER( a400_state, a800 )
{
common_start();
setup_ram(0, m_ram->size());
setup_ram(1, m_ram->size());
setup_ram(2, m_ram->size());
@ -1981,7 +1962,6 @@ MACHINE_START_MEMBER( a400_state, a800xl )
{
m_mmu = 0xfd;
m_ext_bank = 0x03; // only used by a130xe
common_start();
setup_cart(m_cartslot);
save_item(NAME(m_cart_disabled));
@ -1993,7 +1973,6 @@ MACHINE_START_MEMBER( a400_state, a800xl )
MACHINE_START_MEMBER( a400_state, a5200 )
{
a5200_start();
setup_cart(m_cartslot);
save_item(NAME(m_cart_disabled));
@ -2007,7 +1986,7 @@ MACHINE_START_MEMBER( a400_state, a5200 )
*
**************************************************************/
WRITE8_MEMBER(a400_state::gtia_write)
WRITE8_MEMBER(a400_state::gtia_cb)
{
dac_device *dac = machine().device<dac_device>("dac");
if (data & 0x08)
@ -2062,7 +2041,7 @@ static MACHINE_CONFIG_START( atari_common_nodac, a400_state )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1))
MCFG_SCREEN_VISIBLE_AREA(MIN_X, MAX_X, MIN_Y, MAX_Y)
MCFG_SCREEN_UPDATE_DRIVER(atari_common_state, screen_update_atari)
MCFG_SCREEN_UPDATE_DEVICE("antic", antic_device, screen_update)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", sizeof(atari_palette) / 3)
@ -2102,7 +2081,10 @@ static MACHINE_CONFIG_DERIVED( atari_common, atari_common_nodac )
MCFG_DEVICE_ADD("gtia", ATARI_GTIA, 0)
MCFG_GTIA_READ_CB(IOPORT("console"))
MCFG_GTIA_WRITE_CB(WRITE8(a400_state, gtia_write))
MCFG_GTIA_WRITE_CB(WRITE8(a400_state, gtia_cb))
MCFG_DEVICE_ADD("antic", ATARI_ANTIC, 0)
MCFG_ANTIC_GTIA("gtia")
/* devices */
MCFG_DEVICE_ADD("fdc", ATARI_FDC, 0)
@ -2290,6 +2272,9 @@ static MACHINE_CONFIG_DERIVED( a5200, atari_common_nodac )
MCFG_DEVICE_ADD("gtia", ATARI_GTIA, 0)
MCFG_DEVICE_ADD("antic", ATARI_ANTIC, 0)
MCFG_ANTIC_GTIA("gtia")
MCFG_DEVICE_MODIFY("pia")
MCFG_PIA_READPA_HANDLER(NULL) // FIXME: is there anything connected here
MCFG_PIA_READPB_HANDLER(NULL) // FIXME: is there anything connected here