// license:BSD-3-Clause // copyright-holders:Aaron Giles /*************************************************************************** atarigen.h General functions for Atari games. ***************************************************************************/ #ifndef __MACHINE_ATARIGEN__ #define __MACHINE_ATARIGEN__ #include "machine/nvram.h" #include "machine/er2055.h" #include "machine/eeprompar.h" #include "video/atarimo.h" #include "cpu/m6502/m6502.h" #include "sound/okim6295.h" #include "includes/slapstic.h" /*************************************************************************** CONSTANTS ***************************************************************************/ #define ATARI_CLOCK_14MHz XTAL_14_31818MHz #define ATARI_CLOCK_20MHz XTAL_20MHz #define ATARI_CLOCK_32MHz XTAL_32MHz #define ATARI_CLOCK_50MHz XTAL_50MHz //************************************************************************** // DEVICE CONFIGURATION MACROS //************************************************************************** #define MCFG_ATARI_SOUND_COMM_ADD(_tag, _soundcpu, _intcb) \ MCFG_DEVICE_ADD(_tag, ATARI_SOUND_COMM, 0) \ atari_sound_comm_device::static_set_sound_cpu(*device, _soundcpu); \ devcb = &atari_sound_comm_device::static_set_main_int_cb(*device, DEVCB_##_intcb); #define MCFG_ATARI_VAD_ADD(_tag, _screen, _intcb) \ MCFG_DEVICE_ADD(_tag, ATARI_VAD, 0) \ MCFG_VIDEO_SET_SCREEN(_screen) \ devcb = &atari_vad_device::static_set_scanline_int_cb(*device, DEVCB_##_intcb); #define MCFG_ATARI_VAD_PLAYFIELD(_class, _gfxtag, _getinfo) \ { std::string fulltag(device->tag()); fulltag.append(":playfield"); device_t *device; \ MCFG_TILEMAP_ADD(fulltag.c_str()) \ MCFG_TILEMAP_GFXDECODE("^" _gfxtag) \ MCFG_TILEMAP_BYTES_PER_ENTRY(2) \ MCFG_TILEMAP_INFO_CB_DEVICE(DEVICE_SELF_OWNER, _class, _getinfo) \ MCFG_TILEMAP_TILE_SIZE(8,8) \ MCFG_TILEMAP_LAYOUT_STANDARD(SCAN_COLS, 64,64) } #define MCFG_ATARI_VAD_PLAYFIELD2(_class, _gfxtag, _getinfo) \ { std::string fulltag(device->tag()); fulltag.append(":playfield2"); device_t *device; \ MCFG_TILEMAP_ADD(fulltag.c_str()) \ MCFG_TILEMAP_GFXDECODE("^" _gfxtag) \ MCFG_TILEMAP_BYTES_PER_ENTRY(2) \ MCFG_TILEMAP_INFO_CB_DEVICE(DEVICE_SELF_OWNER, _class, _getinfo) \ MCFG_TILEMAP_TILE_SIZE(8,8) \ MCFG_TILEMAP_LAYOUT_STANDARD(SCAN_COLS, 64,64) \ MCFG_TILEMAP_TRANSPARENT_PEN(0) } #define MCFG_ATARI_VAD_ALPHA(_class, _gfxtag, _getinfo) \ { std::string fulltag(device->tag()); fulltag.append(":alpha"); device_t *device; \ MCFG_TILEMAP_ADD(fulltag.c_str()) \ MCFG_TILEMAP_GFXDECODE("^" _gfxtag) \ MCFG_TILEMAP_BYTES_PER_ENTRY(2) \ MCFG_TILEMAP_INFO_CB_DEVICE(DEVICE_SELF_OWNER, _class, _getinfo) \ MCFG_TILEMAP_TILE_SIZE(8,8) \ MCFG_TILEMAP_LAYOUT_STANDARD(SCAN_ROWS, 64,32) \ MCFG_TILEMAP_TRANSPARENT_PEN(0) } #define MCFG_ATARI_VAD_MOB(_config, _gfxtag) \ { std::string fulltag(device->tag()); fulltag.append(":mob"); device_t *device; \ MCFG_ATARI_MOTION_OBJECTS_ADD(fulltag.c_str(), "^^screen", _config) \ MCFG_ATARI_MOTION_OBJECTS_GFXDECODE("^" _gfxtag) } #define MCFG_ATARI_EEPROM_2804_ADD(_tag) \ MCFG_DEVICE_ADD(_tag, ATARI_EEPROM_2804, 0) #define MCFG_ATARI_EEPROM_2816_ADD(_tag) \ MCFG_DEVICE_ADD(_tag, ATARI_EEPROM_2816, 0) /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ #define PORT_ATARI_COMM_SOUND_TO_MAIN_READY(_tag) \ PORT_READ_LINE_DEVICE_MEMBER(_tag, atari_sound_comm_device, sound_to_main_ready) #define PORT_ATARI_COMM_MAIN_TO_SOUND_READY(_tag) \ PORT_READ_LINE_DEVICE_MEMBER(_tag, atari_sound_comm_device, main_to_sound_ready) // ======================> atari_sound_comm_device // device type definition extern const device_type ATARI_SOUND_COMM; class atari_sound_comm_device : public device_t { public: // construction/destruction atari_sound_comm_device(const machine_config &mconfig, std::string tag, device_t *owner, UINT32 clock); // static configuration helpers static void static_set_sound_cpu(device_t &device, const char *cputag); template static devcb_base &static_set_main_int_cb(device_t &device, _Object object) { return downcast(device).m_main_int_cb.set_callback(object); } // getters DECLARE_READ_LINE_MEMBER(main_to_sound_ready) { return m_main_to_sound_ready ? ASSERT_LINE : CLEAR_LINE; } DECLARE_READ_LINE_MEMBER(sound_to_main_ready) { return m_sound_to_main_ready ? ASSERT_LINE : CLEAR_LINE; } // main cpu accessors (forward internally to the atari_sound_comm_device) DECLARE_WRITE8_MEMBER(main_command_w); DECLARE_READ8_MEMBER(main_response_r); DECLARE_WRITE16_MEMBER(sound_reset_w); // sound cpu accessors void sound_cpu_reset() { synchronize(TID_SOUND_RESET, 1); } DECLARE_WRITE8_MEMBER(sound_response_w); DECLARE_READ8_MEMBER(sound_command_r); DECLARE_WRITE8_MEMBER(sound_irq_ack_w); DECLARE_READ8_MEMBER(sound_irq_ack_r); INTERRUPT_GEN_MEMBER(sound_irq_gen); // additional helpers DECLARE_WRITE_LINE_MEMBER(ym2151_irq_gen); protected: // sound I/O helpers void update_sound_irq(); void delayed_sound_reset(int param); void delayed_sound_write(int data); void delayed_6502_write(int data); // device-level overrides virtual void device_start() override; virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; private: // timer IDs enum { TID_SOUND_RESET, TID_SOUND_WRITE, TID_6502_WRITE }; // configuration state const char * m_sound_cpu_tag; devcb_write_line m_main_int_cb; // internal state m6502_device * m_sound_cpu; bool m_main_to_sound_ready; bool m_sound_to_main_ready; UINT8 m_main_to_sound_data; UINT8 m_sound_to_main_data; UINT8 m_timed_int; UINT8 m_ym2151_int; }; // ======================> atari_vad_device // device type definition extern const device_type ATARI_VAD; class atari_vad_device : public device_t, public device_video_interface { public: // construction/destruction atari_vad_device(const machine_config &mconfig, std::string tag, device_t *owner, UINT32 clock); // static configuration helpers template static devcb_base &static_set_scanline_int_cb(device_t &device, _Object object) { return downcast(device).m_scanline_int_cb.set_callback(object); } // getters tilemap_device *alpha() const { return m_alpha_tilemap; } tilemap_device *playfield() const { return m_playfield_tilemap; } tilemap_device *playfield2() const { return m_playfield2_tilemap; } atari_motion_objects_device *mob() const { return m_mob; } // read/write handlers DECLARE_READ16_MEMBER(control_read); DECLARE_WRITE16_MEMBER(control_write); // playfield/alpha tilemap helpers DECLARE_WRITE16_MEMBER(alpha_w); DECLARE_WRITE16_MEMBER(playfield_upper_w); DECLARE_WRITE16_MEMBER(playfield_latched_lsb_w); DECLARE_WRITE16_MEMBER(playfield_latched_msb_w); DECLARE_WRITE16_MEMBER(playfield2_latched_msb_w); protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; private: // timer IDs enum { TID_SCANLINE_INT, TID_TILEROW_UPDATE, TID_EOF }; // internal helpers void internal_control_write(offs_t offset, UINT16 newword); void update_pf_xscrolls(); void update_parameter(UINT16 newword); void update_tilerow(emu_timer &timer, int scanline); void eof_update(emu_timer &timer); // configuration state devcb_write_line m_scanline_int_cb; // internal state optional_device m_alpha_tilemap; required_device m_playfield_tilemap; optional_device m_playfield2_tilemap; optional_device m_mob; optional_shared_ptr m_eof_data; emu_timer * m_scanline_int_timer; emu_timer * m_tilerow_update_timer; emu_timer * m_eof_timer; UINT32 m_palette_bank; // which palette bank is enabled //UINT32 m_pf0_xscroll; // playfield 1 xscroll UINT32 m_pf0_xscroll_raw; // playfield 1 xscroll raw value UINT32 m_pf0_yscroll; // playfield 1 yscroll UINT32 m_pf1_xscroll_raw; // playfield 2 xscroll raw value UINT32 m_pf1_yscroll; // playfield 2 yscroll UINT32 m_mo_xscroll; // sprite xscroll UINT32 m_mo_yscroll; // sprite xscroll UINT16 m_control[0x40/2]; // control data }; // ======================> atari_eeprom_device // device type definition extern const device_type ATARI_EEPROM_2804; extern const device_type ATARI_EEPROM_2816; class atari_eeprom_device : public device_t { protected: // construction/destruction atari_eeprom_device(const machine_config &mconfig, device_type devtype, const char *name, std::string tag, device_t *owner, const char *shortname, const char *file); public: // unlock controls DECLARE_READ8_MEMBER(unlock_read); DECLARE_WRITE8_MEMBER(unlock_write); DECLARE_READ16_MEMBER(unlock_read); DECLARE_WRITE16_MEMBER(unlock_write); DECLARE_READ32_MEMBER(unlock_read); DECLARE_WRITE32_MEMBER(unlock_write); // EEPROM read/write DECLARE_READ8_MEMBER(read); DECLARE_WRITE8_MEMBER(write); protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; // internal state required_device m_eeprom; // live state bool m_unlocked; }; class atari_eeprom_2804_device : public atari_eeprom_device { public: // construction/destruction atari_eeprom_2804_device(const machine_config &mconfig, std::string tag, device_t *owner, UINT32 clock); protected: // device-level overrides virtual machine_config_constructor device_mconfig_additions() const override; }; class atari_eeprom_2816_device : public atari_eeprom_device { public: // construction/destruction atari_eeprom_2816_device(const machine_config &mconfig, std::string tag, device_t *owner, UINT32 clock); protected: // device-level overrides virtual machine_config_constructor device_mconfig_additions() const override; }; /*************************************************************************** TYPES & STRUCTURES ***************************************************************************/ struct atarigen_screen_timer { screen_device *screen; emu_timer * scanline_interrupt_timer; emu_timer * scanline_timer; }; class atarigen_state : public driver_device { public: // construction/destruction atarigen_state(const machine_config &mconfig, device_type type, std::string tag); // users must call through to these virtual void machine_start() override; virtual void machine_reset() override; virtual void device_post_load() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // callbacks provided by the derived class virtual void update_interrupts() = 0; virtual void scanline_update(screen_device &screen, int scanline); // interrupt handling void scanline_int_set(screen_device &screen, int scanline); DECLARE_WRITE_LINE_MEMBER(scanline_int_write_line); INTERRUPT_GEN_MEMBER(scanline_int_gen); DECLARE_WRITE16_MEMBER(scanline_int_ack_w); DECLARE_WRITE_LINE_MEMBER(sound_int_write_line); INTERRUPT_GEN_MEMBER(sound_int_gen); DECLARE_WRITE16_MEMBER(sound_int_ack_w); INTERRUPT_GEN_MEMBER(video_int_gen); DECLARE_WRITE16_MEMBER(video_int_ack_w); // slapstic helpers void slapstic_configure(cpu_device &device, offs_t base, offs_t mirror, int chipnum); void slapstic_update_bank(int bank); DECLARE_DIRECT_UPDATE_MEMBER(slapstic_setdirect); DECLARE_WRITE16_MEMBER(slapstic_w); DECLARE_READ16_MEMBER(slapstic_r); // sound helpers void set_volume_by_type(int volume, device_type type); void set_ym2151_volume(int volume); void set_ym2413_volume(int volume); void set_pokey_volume(int volume); void set_tms5220_volume(int volume); void set_oki6295_volume(int volume); // scanline timing void scanline_timer_reset(screen_device &screen, int frequency); void scanline_timer(emu_timer &timer, screen_device &screen, int scanline); // video helpers int get_hblank(screen_device &screen) const { return (screen.hpos() > (screen.width() * 9 / 10)); } void halt_until_hblank_0(device_t &device, screen_device &screen); // misc helpers void blend_gfx(int gfx0, int gfx1, int mask0, int mask1); // vector and early raster EAROM interface DECLARE_READ8_MEMBER( earom_r ); DECLARE_WRITE8_MEMBER( earom_w ); DECLARE_WRITE8_MEMBER( earom_control_w ); // timer IDs enum { TID_SCANLINE_INTERRUPT, TID_SCANLINE_TIMER, TID_UNHALT_CPU, TID_ATARIGEN_LAST }; // vector and early raster EAROM interface optional_device m_earom; UINT8 m_earom_data; UINT8 m_earom_control; UINT8 m_scanline_int_state; UINT8 m_sound_int_state; UINT8 m_video_int_state; optional_shared_ptr m_xscroll; optional_shared_ptr m_yscroll; /* internal state */ UINT8 m_slapstic_num; UINT16 * m_slapstic; UINT8 m_slapstic_bank; dynamic_buffer m_slapstic_bank0; offs_t m_slapstic_last_pc; offs_t m_slapstic_last_address; offs_t m_slapstic_base; offs_t m_slapstic_mirror; UINT32 m_scanlines_per_callback; atarigen_screen_timer m_screen_timer[2]; required_device m_maincpu; optional_device m_audiocpu; optional_device m_oki; optional_device m_soundcomm; optional_device m_gfxdecode; optional_device m_screen; optional_device m_palette; optional_shared_ptr m_generic_paletteram_16; optional_device m_slapstic_device; }; /*************************************************************************** GENERAL ATARI NOTES **************************************************************************## Atari 68000 list: Driver Pr? Up? VC? PF? P2? MO? AL? BM? PH? ---------- --- --- --- --- --- --- --- --- --- arcadecl.c * * * atarig1.c * * rle * atarig42.c * * rle * atarigt.c * rle * atarigx2.c * rle * atarisy1.c * * * * * 270->260 atarisy2.c * * * * * 150->120 badlands.c * * * 250->260 batman.c * * * * * * * * 200->160 ? blstroid.c * * * 240->230 cyberbal.c * * * * 125->105 ? eprom.c * * * * 170->170 gauntlet.c * * * * * * 220->250 klax.c * * * * 480->440 ? offtwall.c * * * * 260->260 rampart.c * * * 280->280 relief.c * * * * * * 240->240 shuuz.c * * * * 410->290 fix! skullxbo.c * * * * 150->145 thunderj.c * * * * * * * 180->180 toobin.c * * * * 140->115 fix! vindictr.c * * * * * * 200->210 xybots.c * * * * * 235->238 ---------- --- --- --- --- --- --- --- --- --- Pr? - do we have verifiable proof on priorities? Up? - have we updated to use new MO's & tilemaps? VC? - does it use the video controller? PF? - does it have a playfield? P2? - does it have a dual playfield? MO? - does it have MO's? AL? - does it have an alpha layer? BM? - does it have a bitmap layer? PH? - does it use the palette hack? ***************************************************************************/ #endif