atarist.cpp: Split out video and blitter as separate devices

This commit is contained in:
AJR 2022-05-19 15:21:44 -04:00
parent d561b82fae
commit aa66b4a013
7 changed files with 1274 additions and 1102 deletions

View File

@ -1922,7 +1922,8 @@ files {
MAME_DIR .. "src/mame/machine/atarifdc.cpp", MAME_DIR .. "src/mame/machine/atarifdc.cpp",
MAME_DIR .. "src/mame/machine/atarifdc.h", MAME_DIR .. "src/mame/machine/atarifdc.h",
MAME_DIR .. "src/mame/drivers/atarist.cpp", MAME_DIR .. "src/mame/drivers/atarist.cpp",
MAME_DIR .. "src/mame/includes/atarist.h", MAME_DIR .. "src/mame/machine/ataristb.cpp",
MAME_DIR .. "src/mame/machine/ataristb.h",
MAME_DIR .. "src/mame/video/atarist.cpp", MAME_DIR .. "src/mame/video/atarist.cpp",
MAME_DIR .. "src/mame/video/atarist.h", MAME_DIR .. "src/mame/video/atarist.h",
MAME_DIR .. "src/mame/drivers/lynx.cpp", MAME_DIR .. "src/mame/drivers/lynx.cpp",

View File

@ -1,11 +1,29 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Curt Coder, Olivier Galibert // copyright-holders:Curt Coder, Olivier Galibert
#include "emu.h" #include "emu.h"
#include "includes/atarist.h"
#include "machine/ataristb.h"
#include "video/atarist.h"
#include "bus/centronics/ctronics.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
#include "bus/midi/midi.h"
#include "bus/rs232/rs232.h"
#include "cpu/m68000/m68000.h"
#include "cpu/m6800/m6801.h"
#include "imagedev/floppy.h"
#include "machine/6850acia.h"
#include "machine/8530scc.h"
#include "machine/clock.h" #include "machine/clock.h"
#include "machine/input_merger.h" #include "machine/input_merger.h"
#include "bus/midi/midi.h" #include "machine/mc68901.h"
#include "video/atarist.h" #include "machine/ram.h"
#include "machine/rescap.h"
#include "machine/rp5c15.h"
#include "machine/wd_fdc.h"
#include "sound/ay8910.h"
#include "sound/lmc1992.h"
#include "screen.h" #include "screen.h"
#include "softlist_dev.h" #include "softlist_dev.h"
#include "speaker.h" #include "speaker.h"
@ -42,10 +60,331 @@
#define LOG 0 #define LOG 0
namespace {
#define M68000_TAG "m68000"
#define HD6301V1_TAG "hd6301"
#define YM2149_TAG "ym2149"
#define MC6850_0_TAG "mc6850_0"
#define MC6850_1_TAG "mc6850_1"
#define Z8530_TAG "z8530"
#define COP888_TAG "u703"
#define RP5C15_TAG "rp5c15"
#define YM3439_TAG "ym3439"
#define MC68901_TAG "mc68901"
#define LMC1992_TAG "lmc1992"
#define WD1772_TAG "wd1772"
#define SCREEN_TAG "screen"
#define CENTRONICS_TAG "centronics"
#define RS232_TAG "rs232"
// Atari ST
#define Y1 XTAL(2'457'600)
// 32028400 also exists
#define Y2 32084988.0
#define Y2_NTSC 32042400.0
// STBook
#define U517 XTAL(16'000'000)
#define Y200 XTAL(2'457'600)
#define Y700 XTAL(10'000'000)
#define DMA_STATUS_DRQ 0x04
#define DMA_STATUS_SECTOR_COUNT 0x02
#define DMA_STATUS_ERROR 0x01
#define DMA_MODE_READ_WRITE 0x100
#define DMA_MODE_FDC_HDC_ACK 0x080
#define DMA_MODE_ENABLED 0x040
#define DMA_MODE_SECTOR_COUNT 0x010
#define DMA_MODE_FDC_HDC_CS 0x008
#define DMA_MODE_A1 0x004
#define DMA_MODE_A0 0x002
#define DMA_MODE_ADDRESS_MASK 0x006
#define DMA_SECTOR_SIZE 512
static const double DMASOUND_RATE[] = { Y2/640.0/8.0, Y2/640.0/4.0, Y2/640.0/2.0, Y2/640.0 };
static const int IKBD_MOUSE_XYA[3][4] = { { 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 } }; static const int IKBD_MOUSE_XYA[3][4] = { { 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 } };
static const int IKBD_MOUSE_XYB[3][4] = { { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 1, 1, 0, 0 } }; static const int IKBD_MOUSE_XYB[3][4] = { { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 1, 1, 0, 0 } };
static const double DMASOUND_RATE[] = { Y2/640.0/8.0, Y2/640.0/4.0, Y2/640.0/2.0, Y2/640.0 }; enum
{
IKBD_MOUSE_PHASE_STATIC = 0,
IKBD_MOUSE_PHASE_POSITIVE,
IKBD_MOUSE_PHASE_NEGATIVE
};
class st_state : public driver_device
{
public:
enum
{
TIMER_MOUSE_TICK
};
st_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, M68000_TAG),
m_stb(*this, "stb"),
m_ikbd(*this, HD6301V1_TAG),
m_fdc(*this, WD1772_TAG),
m_floppy(*this, WD1772_TAG ":%u", 0U),
m_mfp(*this, MC68901_TAG),
m_acia(*this, {MC6850_0_TAG, MC6850_1_TAG}),
m_centronics(*this, CENTRONICS_TAG),
m_cart(*this, "cartslot"),
m_ram(*this, RAM_TAG),
m_rs232(*this, RS232_TAG),
m_ymsnd(*this, YM2149_TAG),
m_keys(*this, "P%o", 030),
m_joy(*this, "IKBD_JOY%u", 0U),
m_mousex(*this, "IKBD_MOUSEX"),
m_mousey(*this, "IKBD_MOUSEY"),
m_config(*this, "config"),
m_ikbd_mouse_x(0),
m_ikbd_mouse_y(0),
m_ikbd_mouse_px(IKBD_MOUSE_PHASE_STATIC),
m_ikbd_mouse_py(IKBD_MOUSE_PHASE_STATIC),
m_ikbd_mouse_pc(0),
m_ikbd_joy(1),
m_monochrome(1),
m_video(*this, "video"),
m_screen(*this, "screen"),
m_led(*this, "led1")
{ }
DECLARE_WRITE_LINE_MEMBER( write_monochrome );
void st(machine_config &config);
protected:
required_device<m68000_base_device> m_maincpu;
optional_device<st_blitter_device> m_stb;
required_device<cpu_device> m_ikbd;
required_device<wd1772_device> m_fdc;
required_device_array<floppy_connector, 2> m_floppy;
required_device<mc68901_device> m_mfp;
required_device_array<acia6850_device, 2> m_acia;
required_device<centronics_device> m_centronics;
required_device<generic_slot_device> m_cart;
required_device<ram_device> m_ram;
required_device<rs232_port_device> m_rs232;
required_device<ym2149_device> m_ymsnd;
required_ioport_array<16> m_keys;
optional_ioport_array<2> m_joy;
optional_ioport m_mousex;
optional_ioport m_mousey;
optional_ioport m_config;
void mouse_tick();
// driver
uint16_t fdc_data_r(offs_t offset);
void fdc_data_w(offs_t offset, uint16_t data);
uint16_t dma_status_r();
void dma_mode_w(uint16_t data);
uint8_t dma_counter_r(offs_t offset);
void dma_base_w(offs_t offset, uint8_t data);
uint8_t mmu_r();
void mmu_w(uint8_t data);
uint16_t berr_r();
void berr_w(uint16_t data);
uint8_t ikbd_port1_r();
uint8_t ikbd_port2_r();
void ikbd_port2_w(uint8_t data);
void ikbd_port3_w(uint8_t data);
uint8_t ikbd_port4_r();
void ikbd_port4_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER( fdc_drq_w );
void psg_pa_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER( ikbd_tx_w );
DECLARE_WRITE_LINE_MEMBER( reset_w );
void toggle_dma_fifo();
void flush_dma_fifo();
void fill_dma_fifo();
void fdc_dma_transfer();
void configure_memory();
void state_save();
/* memory state */
uint8_t m_mmu = 0U;
/* keyboard state */
uint16_t m_ikbd_keylatch = 0U;
uint8_t m_ikbd_mouse = 0U;
uint8_t m_ikbd_mouse_x;
uint8_t m_ikbd_mouse_y;
uint8_t m_ikbd_mouse_px;
uint8_t m_ikbd_mouse_py;
uint8_t m_ikbd_mouse_pc;
int m_ikbd_tx = 0;
int m_ikbd_joy;
int m_midi_tx = 0;
/* floppy state */
uint32_t m_dma_base = 0U;
uint16_t m_dma_error = 0U;
uint16_t m_fdc_mode = 0U;
uint8_t m_fdc_sectors = 0U;
uint16_t m_fdc_fifo[2][8]{};
int m_fdc_fifo_sel = 0;
int m_fdc_fifo_index = 0;
int m_fdc_fifo_msb = 0;
int m_fdc_fifo_empty[2]{};
int m_fdc_dmabytes = 0;
/* timers */
emu_timer *m_mouse_timer = nullptr;
static void floppy_formats(format_registration &fr);
int m_monochrome;
required_device<st_video_device> m_video;
required_device<screen_device> m_screen;
void common(machine_config &config);
void ikbd_map(address_map &map);
void cpu_space_map(address_map &map);
void st_map(address_map &map);
void megast_map(address_map &map);
void keyboard(machine_config &config);
uint16_t fpu_r();
void fpu_w(uint16_t data);
virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
virtual void machine_start() override;
output_finder<> m_led;
};
class megast_state : public st_state
{
public:
megast_state(const machine_config &mconfig, device_type type, const char *tag)
: st_state(mconfig, type, tag)
{ }
void megast(machine_config &config);
};
class ste_state : public st_state
{
public:
enum
{
TIMER_DMASOUND_TICK,
TIMER_MICROWIRE_TICK
};
ste_state(const machine_config &mconfig, device_type type, const char *tag)
: st_state(mconfig, type, tag),
m_lmc1992(*this, LMC1992_TAG)
{ }
optional_device<lmc1992_device> m_lmc1992;
uint8_t sound_dma_control_r();
uint8_t sound_dma_base_r(offs_t offset);
uint8_t sound_dma_counter_r(offs_t offset);
uint8_t sound_dma_end_r(offs_t offset);
uint8_t sound_mode_r();
void sound_dma_control_w(uint8_t data);
void sound_dma_base_w(offs_t offset, uint8_t data);
void sound_dma_end_w(offs_t offset, uint8_t data);
void sound_mode_w(uint8_t data);
uint16_t microwire_data_r();
void microwire_data_w(uint16_t data);
uint16_t microwire_mask_r();
void microwire_mask_w(uint16_t data);
DECLARE_WRITE_LINE_MEMBER( write_monochrome );
void dmasound_set_state(int level);
void dmasound_tick();
void microwire_shift();
void microwire_tick();
void state_save();
/* microwire state */
uint16_t m_mw_data = 0U;
uint16_t m_mw_mask = 0U;
int m_mw_shift = 0;
/* DMA sound state */
uint32_t m_dmasnd_base = 0U;
uint32_t m_dmasnd_end = 0U;
uint32_t m_dmasnd_cntr = 0U;
uint32_t m_dmasnd_baselatch = 0U;
uint32_t m_dmasnd_endlatch = 0U;
uint8_t m_dmasnd_ctrl = 0U;
uint8_t m_dmasnd_mode = 0U;
uint8_t m_dmasnd_fifo[8]{};
uint8_t m_dmasnd_samples = 0U;
int m_dmasnd_active = 0;
// timers
emu_timer *m_microwire_timer = 0;
emu_timer *m_dmasound_timer = 0;
void falcon40(machine_config &config);
void tt030(machine_config &config);
void falcon(machine_config &config);
void ste(machine_config &config);
void ste_map(address_map &map);
protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
virtual void machine_start() override;
};
class megaste_state : public ste_state
{
public:
megaste_state(const machine_config &mconfig, device_type type, const char *tag)
: ste_state(mconfig, type, tag)
{ }
uint16_t cache_r();
void cache_w(uint16_t data);
uint16_t m_cache = 0;
void megaste(machine_config &config);
void megaste_map(address_map &map);
protected:
virtual void machine_start() override;
};
class stbook_state : public ste_state
{
public:
stbook_state(const machine_config &mconfig, device_type type, const char *tag)
: ste_state(mconfig, type, tag),
m_sw400(*this, "SW400")
{ }
required_ioport m_sw400;
uint16_t config_r();
void lcd_control_w(uint16_t data);
void psg_pa_w(uint8_t data);
uint8_t mfp_gpio_r();
void stbook_map(address_map &map);
protected:
virtual void machine_start() override;
};
//************************************************************************** //**************************************************************************
@ -59,15 +398,6 @@ void st_state::device_timer(emu_timer &timer, device_timer_id id, int param)
case TIMER_MOUSE_TICK: case TIMER_MOUSE_TICK:
mouse_tick(); mouse_tick();
break; break;
case TIMER_SHIFTER_TICK:
shifter_tick();
break;
case TIMER_GLUE_TICK:
glue_tick();
break;
case TIMER_BLITTER_TICK:
blitter_tick();
break;
default: default:
throw emu_fatalerror("Unknown id in st_state::device_timer"); throw emu_fatalerror("Unknown id in st_state::device_timer");
} }
@ -719,7 +1049,9 @@ WRITE_LINE_MEMBER( st_state::write_monochrome )
WRITE_LINE_MEMBER( st_state::reset_w ) WRITE_LINE_MEMBER( st_state::reset_w )
{ {
//glue_reset(); m_video->reset();
if (m_stb.found())
m_stb->reset();
m_mfp->reset(); m_mfp->reset();
m_ikbd->pulse_input_line(INPUT_LINE_RESET, attotime::zero); m_ikbd->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
m_ymsnd->reset(); m_ymsnd->reset();
@ -1243,11 +1575,11 @@ void st_state::st_map(address_map &map)
//map(0xfa0000, 0xfbffff) // mapped by the cartslot //map(0xfa0000, 0xfbffff) // mapped by the cartslot
map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0).w(FUNC(st_state::berr_w)); map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0).w(FUNC(st_state::berr_w));
map(0xff8001, 0xff8001).rw(FUNC(st_state::mmu_r), FUNC(st_state::mmu_w)); map(0xff8001, 0xff8001).rw(FUNC(st_state::mmu_r), FUNC(st_state::mmu_w));
map(0xff8200, 0xff8203).rw(FUNC(st_state::shifter_base_r), FUNC(st_state::shifter_base_w)).umask16(0x00ff); map(0xff8200, 0xff8203).rw(m_video, FUNC(st_video_device::shifter_base_r), FUNC(st_video_device::shifter_base_w)).umask16(0x00ff);
map(0xff8204, 0xff8209).r(FUNC(st_state::shifter_counter_r)).umask16(0x00ff); map(0xff8204, 0xff8209).r(m_video, FUNC(st_video_device::shifter_counter_r)).umask16(0x00ff);
map(0xff820a, 0xff820a).rw(FUNC(st_state::shifter_sync_r), FUNC(st_state::shifter_sync_w)); map(0xff820a, 0xff820a).rw(m_video, FUNC(st_video_device::shifter_sync_r), FUNC(st_video_device::shifter_sync_w));
map(0xff8240, 0xff825f).rw(FUNC(st_state::shifter_palette_r), FUNC(st_state::shifter_palette_w)); map(0xff8240, 0xff825f).rw(m_video, FUNC(st_video_device::shifter_palette_r), FUNC(st_video_device::shifter_palette_w));
map(0xff8260, 0xff8260).rw(FUNC(st_state::shifter_mode_r), FUNC(st_state::shifter_mode_w)); map(0xff8260, 0xff8260).rw(m_video, FUNC(st_video_device::shifter_mode_r), FUNC(st_video_device::shifter_mode_w));
map(0xff8604, 0xff8605).rw(FUNC(st_state::fdc_data_r), FUNC(st_state::fdc_data_w)); map(0xff8604, 0xff8605).rw(FUNC(st_state::fdc_data_r), FUNC(st_state::fdc_data_w));
map(0xff8606, 0xff8607).rw(FUNC(st_state::dma_status_r), FUNC(st_state::dma_mode_w)); map(0xff8606, 0xff8607).rw(FUNC(st_state::dma_status_r), FUNC(st_state::dma_mode_w));
map(0xff8608, 0xff860d).rw(FUNC(st_state::dma_counter_r), FUNC(st_state::dma_base_w)).umask16(0x00ff); map(0xff8608, 0xff860d).rw(FUNC(st_state::dma_counter_r), FUNC(st_state::dma_base_w)).umask16(0x00ff);
@ -1272,30 +1604,30 @@ void st_state::megast_map(address_map &map)
map(0x200000, 0x3fffff).ram(); map(0x200000, 0x3fffff).ram();
//map(0xfa0000, 0xfbffff) // mapped by the cartslot //map(0xfa0000, 0xfbffff) // mapped by the cartslot
map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0); map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0);
// map(0xff7f30, 0xff7f31).rw(FUNC(st_state::blitter_dst_inc_y_r), FUNC(st_state::blitter_dst_inc_y_w) // for TOS 1.02 // map(0xff7f30, 0xff7f31).rw(m_stb, FUNC(st_blitter_device::dst_inc_y_r), FUNC(st_blitter_device::dst_inc_y_w) // for TOS 1.02
map(0xff8001, 0xff8001).rw(FUNC(st_state::mmu_r), FUNC(st_state::mmu_w)); map(0xff8001, 0xff8001).rw(FUNC(st_state::mmu_r), FUNC(st_state::mmu_w));
map(0xff8200, 0xff8203).rw(FUNC(st_state::shifter_base_r), FUNC(st_state::shifter_base_w)).umask16(0x00ff); map(0xff8200, 0xff8203).rw(m_video, FUNC(st_video_device::shifter_base_r), FUNC(st_video_device::shifter_base_w)).umask16(0x00ff);
map(0xff8204, 0xff8209).r(FUNC(st_state::shifter_counter_r)).umask16(0x00ff); map(0xff8204, 0xff8209).r(m_video, FUNC(st_video_device::shifter_counter_r)).umask16(0x00ff);
map(0xff820a, 0xff820a).rw(FUNC(st_state::shifter_sync_r), FUNC(st_state::shifter_sync_w)); map(0xff820a, 0xff820a).rw(m_video, FUNC(st_video_device::shifter_sync_r), FUNC(st_video_device::shifter_sync_w));
map(0xff8240, 0xff825f).rw(FUNC(st_state::shifter_palette_r), FUNC(st_state::shifter_palette_w)); map(0xff8240, 0xff825f).rw(m_video, FUNC(st_video_device::shifter_palette_r), FUNC(st_video_device::shifter_palette_w));
map(0xff8260, 0xff8260).rw(FUNC(st_state::shifter_mode_r), FUNC(st_state::shifter_mode_w)); map(0xff8260, 0xff8260).rw(m_video, FUNC(st_video_device::shifter_mode_r), FUNC(st_video_device::shifter_mode_w));
map(0xff8604, 0xff8605).rw(FUNC(st_state::fdc_data_r), FUNC(st_state::fdc_data_w)); map(0xff8604, 0xff8605).rw(FUNC(st_state::fdc_data_r), FUNC(st_state::fdc_data_w));
map(0xff8606, 0xff8607).rw(FUNC(st_state::dma_status_r), FUNC(st_state::dma_mode_w)); map(0xff8606, 0xff8607).rw(FUNC(st_state::dma_status_r), FUNC(st_state::dma_mode_w));
map(0xff8608, 0xff860d).rw(FUNC(st_state::dma_counter_r), FUNC(st_state::dma_base_w)).umask16(0x00ff); map(0xff8608, 0xff860d).rw(FUNC(st_state::dma_counter_r), FUNC(st_state::dma_base_w)).umask16(0x00ff);
map(0xff8800, 0xff8800).rw(YM2149_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)); map(0xff8800, 0xff8800).rw(YM2149_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w));
map(0xff8802, 0xff8802).w(YM2149_TAG, FUNC(ay8910_device::data_w)); map(0xff8802, 0xff8802).w(YM2149_TAG, FUNC(ay8910_device::data_w));
map(0xff8a00, 0xff8a1f).rw(FUNC(st_state::blitter_halftone_r), FUNC(st_state::blitter_halftone_w)); map(0xff8a00, 0xff8a1f).rw(m_stb, FUNC(st_blitter_device::halftone_r), FUNC(st_blitter_device::halftone_w));
map(0xff8a20, 0xff8a21).rw(FUNC(st_state::blitter_src_inc_x_r), FUNC(st_state::blitter_src_inc_x_w)); map(0xff8a20, 0xff8a21).rw(m_stb, FUNC(st_blitter_device::src_inc_x_r), FUNC(st_blitter_device::src_inc_x_w));
map(0xff8a22, 0xff8a23).rw(FUNC(st_state::blitter_src_inc_y_r), FUNC(st_state::blitter_src_inc_y_w)); map(0xff8a22, 0xff8a23).rw(m_stb, FUNC(st_blitter_device::src_inc_y_r), FUNC(st_blitter_device::src_inc_y_w));
map(0xff8a24, 0xff8a27).rw(FUNC(st_state::blitter_src_r), FUNC(st_state::blitter_src_w)); map(0xff8a24, 0xff8a27).rw(m_stb, FUNC(st_blitter_device::src_r), FUNC(st_blitter_device::src_w));
map(0xff8a28, 0xff8a2d).rw(FUNC(st_state::blitter_end_mask_r), FUNC(st_state::blitter_end_mask_w)); map(0xff8a28, 0xff8a2d).rw(m_stb, FUNC(st_blitter_device::end_mask_r), FUNC(st_blitter_device::end_mask_w));
map(0xff8a2e, 0xff8a2f).rw(FUNC(st_state::blitter_dst_inc_x_r), FUNC(st_state::blitter_dst_inc_x_w)); map(0xff8a2e, 0xff8a2f).rw(m_stb, FUNC(st_blitter_device::dst_inc_x_r), FUNC(st_blitter_device::dst_inc_x_w));
map(0xff8a30, 0xff8a31).rw(FUNC(st_state::blitter_dst_inc_y_r), FUNC(st_state::blitter_dst_inc_y_w)); map(0xff8a30, 0xff8a31).rw(m_stb, FUNC(st_blitter_device::dst_inc_y_r), FUNC(st_blitter_device::dst_inc_y_w));
map(0xff8a32, 0xff8a35).rw(FUNC(st_state::blitter_dst_r), FUNC(st_state::blitter_dst_w)); map(0xff8a32, 0xff8a35).rw(m_stb, FUNC(st_blitter_device::dst_r), FUNC(st_blitter_device::dst_w));
map(0xff8a36, 0xff8a37).rw(FUNC(st_state::blitter_count_x_r), FUNC(st_state::blitter_count_x_w)); map(0xff8a36, 0xff8a37).rw(m_stb, FUNC(st_blitter_device::count_x_r), FUNC(st_blitter_device::count_x_w));
map(0xff8a38, 0xff8a39).rw(FUNC(st_state::blitter_count_y_r), FUNC(st_state::blitter_count_y_w)); map(0xff8a38, 0xff8a39).rw(m_stb, FUNC(st_blitter_device::count_y_r), FUNC(st_blitter_device::count_y_w));
map(0xff8a3a, 0xff8a3b).rw(FUNC(st_state::blitter_op_r), FUNC(st_state::blitter_op_w)); map(0xff8a3a, 0xff8a3b).rw(m_stb, FUNC(st_blitter_device::op_r), FUNC(st_blitter_device::op_w));
map(0xff8a3c, 0xff8a3d).rw(FUNC(st_state::blitter_ctrl_r), FUNC(st_state::blitter_ctrl_w)); map(0xff8a3c, 0xff8a3d).rw(m_stb, FUNC(st_blitter_device::ctrl_r), FUNC(st_blitter_device::ctrl_w));
map(0xfffa00, 0xfffa3f).rw(m_mfp, FUNC(mc68901_device::read), FUNC(mc68901_device::write)).umask16(0x00ff); map(0xfffa00, 0xfffa3f).rw(m_mfp, FUNC(mc68901_device::read), FUNC(mc68901_device::write)).umask16(0x00ff);
map(0xfffa40, 0xfffa57).rw(FUNC(st_state::fpu_r), FUNC(st_state::fpu_w)); map(0xfffa40, 0xfffa57).rw(FUNC(st_state::fpu_r), FUNC(st_state::fpu_w));
map(0xfffc00, 0xfffc03).rw(m_acia[0], FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0xff00); map(0xfffc00, 0xfffc03).rw(m_acia[0], FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0xff00);
@ -1319,18 +1651,18 @@ void ste_state::ste_map(address_map &map)
map(0xff8921, 0xff8921).rw(FUNC(ste_state::sound_mode_r), FUNC(ste_state::sound_mode_w)); map(0xff8921, 0xff8921).rw(FUNC(ste_state::sound_mode_r), FUNC(ste_state::sound_mode_w));
map(0xff8922, 0xff8923).rw(FUNC(ste_state::microwire_data_r), FUNC(ste_state::microwire_data_w)); map(0xff8922, 0xff8923).rw(FUNC(ste_state::microwire_data_r), FUNC(ste_state::microwire_data_w));
map(0xff8924, 0xff8925).rw(FUNC(ste_state::microwire_mask_r), FUNC(ste_state::microwire_mask_w)); map(0xff8924, 0xff8925).rw(FUNC(ste_state::microwire_mask_r), FUNC(ste_state::microwire_mask_w));
map(0xff8a00, 0xff8a1f).rw(FUNC(ste_state::blitter_halftone_r), FUNC(ste_state::blitter_halftone_w)); map(0xff8a00, 0xff8a1f).rw(m_stb, FUNC(st_blitter_device::halftone_r), FUNC(st_blitter_device::halftone_w));
map(0xff8a20, 0xff8a21).rw(FUNC(ste_state::blitter_src_inc_x_r), FUNC(ste_state::blitter_src_inc_x_w)); map(0xff8a20, 0xff8a21).rw(m_stb, FUNC(st_blitter_device::src_inc_x_r), FUNC(st_blitter_device::src_inc_x_w));
map(0xff8a22, 0xff8a23).rw(FUNC(ste_state::blitter_src_inc_y_r), FUNC(ste_state::blitter_src_inc_y_w)); map(0xff8a22, 0xff8a23).rw(m_stb, FUNC(st_blitter_device::src_inc_y_r), FUNC(st_blitter_device::src_inc_y_w));
map(0xff8a24, 0xff8a27).rw(FUNC(ste_state::blitter_src_r), FUNC(ste_state::blitter_src_w)); map(0xff8a24, 0xff8a27).rw(m_stb, FUNC(st_blitter_device::src_r), FUNC(st_blitter_device::src_w));
map(0xff8a28, 0xff8a2d).rw(FUNC(ste_state::blitter_end_mask_r), FUNC(ste_state::blitter_end_mask_w)); map(0xff8a28, 0xff8a2d).rw(m_stb, FUNC(st_blitter_device::end_mask_r), FUNC(st_blitter_device::end_mask_w));
map(0xff8a2e, 0xff8a2f).rw(FUNC(ste_state::blitter_dst_inc_x_r), FUNC(ste_state::blitter_dst_inc_x_w)); map(0xff8a2e, 0xff8a2f).rw(m_stb, FUNC(st_blitter_device::dst_inc_x_r), FUNC(st_blitter_device::dst_inc_x_w));
map(0xff8a30, 0xff8a31).rw(FUNC(ste_state::blitter_dst_inc_y_r), FUNC(ste_state::blitter_dst_inc_y_w)); map(0xff8a30, 0xff8a31).rw(m_stb, FUNC(st_blitter_device::dst_inc_y_r), FUNC(st_blitter_device::dst_inc_y_w));
map(0xff8a32, 0xff8a35).rw(FUNC(ste_state::blitter_dst_r), FUNC(ste_state::blitter_dst_w)); map(0xff8a32, 0xff8a35).rw(m_stb, FUNC(st_blitter_device::dst_r), FUNC(st_blitter_device::dst_w));
map(0xff8a36, 0xff8a37).rw(FUNC(ste_state::blitter_count_x_r), FUNC(ste_state::blitter_count_x_w)); map(0xff8a36, 0xff8a37).rw(m_stb, FUNC(st_blitter_device::count_x_r), FUNC(st_blitter_device::count_x_w));
map(0xff8a38, 0xff8a39).rw(FUNC(ste_state::blitter_count_y_r), FUNC(ste_state::blitter_count_y_w)); map(0xff8a38, 0xff8a39).rw(m_stb, FUNC(st_blitter_device::count_y_r), FUNC(st_blitter_device::count_y_w));
map(0xff8a3a, 0xff8a3b).rw(FUNC(ste_state::blitter_op_r), FUNC(ste_state::blitter_op_w)); map(0xff8a3a, 0xff8a3b).rw(m_stb, FUNC(st_blitter_device::op_r), FUNC(st_blitter_device::op_w));
map(0xff8a3c, 0xff8a3d).rw(FUNC(ste_state::blitter_ctrl_r), FUNC(ste_state::blitter_ctrl_w)); map(0xff8a3c, 0xff8a3d).rw(m_stb, FUNC(st_blitter_device::ctrl_r), FUNC(st_blitter_device::ctrl_w));
map(0xff9200, 0xff9201).portr("JOY0"); map(0xff9200, 0xff9201).portr("JOY0");
map(0xff9202, 0xff9203).portr("JOY1"); map(0xff9202, 0xff9203).portr("JOY1");
map(0xff9210, 0xff9211).portr("PADDLE0X"); map(0xff9210, 0xff9211).portr("PADDLE0X");
@ -1376,15 +1708,15 @@ void stbook_state::stbook_map(address_map &map)
map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0); map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0);
/* map(0xf00000, 0xf1ffff).rw(FUNC(stbook_state::stbook_ide_r), FUNC(stbook_state::stbook_ide_w)); /* map(0xf00000, 0xf1ffff).rw(FUNC(stbook_state::stbook_ide_r), FUNC(stbook_state::stbook_ide_w));
map(0xff8000, 0xff8001).rw(FUNC(stbook_state::stbook_mmu_r), FUNC(stbook_state::stbook_mmu_w)); map(0xff8000, 0xff8001).rw(FUNC(stbook_state::stbook_mmu_r), FUNC(stbook_state::stbook_mmu_w));
map(0xff8200, 0xff8203).rw(FUNC(stbook_state::stbook_shifter_base_r), FUNC(stbook_state::stbook_shifter_base_w)); map(0xff8200, 0xff8203).rw(m_video, FUNC(stbook_video_device::stbook_shifter_base_r), FUNC(stbook_video_device::stbook_shifter_base_w));
map(0xff8204, 0xff8209).rw(FUNC(stbook_state::stbook_shifter_counter_r), FUNC(stbook_state::stbook_shifter_counter_w)); map(0xff8204, 0xff8209).rw(m_video, FUNC(stbook_video_device::stbook_shifter_counter_r), FUNC(stbook_video_device::stbook_shifter_counter_w));
map(0xff820a, 0xff820a).rw(FUNC(stbook_state::stbook_shifter_sync_r), FUNC(stbook_state::stbook_shifter_sync_w)); map(0xff820a, 0xff820a).rw(m_video, FUNC(stbook_video_device::stbook_shifter_sync_r), FUNC(stbook_video_device::stbook_shifter_sync_w));
map(0xff820c, 0xff820d).rw(FUNC(stbook_state::stbook_shifter_base_low_r), FUNC(stbook_state::stbook_shifter_base_low_w)); map(0xff820c, 0xff820d).rw(m_video, FUNC(stbook_video_device::stbook_shifter_base_low_r), FUNC(stbook_video_device::stbook_shifter_base_low_w));
map(0xff820e, 0xff820f).rw(FUNC(stbook_state::stbook_shifter_lineofs_r), FUNC(stbook_state::stbook_shifter_lineofs_w)); map(0xff820e, 0xff820f).rw(m_video, FUNC(stbook_video_device::stbook_shifter_lineofs_r), FUNC(stbook_video_device::stbook_shifter_lineofs_w));
map(0xff8240, 0xff8241).rw(FUNC(stbook_state::stbook_shifter_palette_r), FUNC(stbook_state::stbook_shifter_palette_w)); map(0xff8240, 0xff8241).rw(m_video, FUNC(stbook_video_device::stbook_shifter_palette_r), FUNC(stbook_video_device::stbook_shifter_palette_w));
map(0xff8260, 0xff8260).rw(FUNC(stbook_state::stbook_shifter_mode_r), FUNC(stbook_state::stbook_shifter_mode_w)); map(0xff8260, 0xff8260).rw(m_video, FUNC(stbook_video_device::stbook_shifter_mode_r), FUNC(stbook_video_device::stbook_shifter_mode_w));
map(0xff8264, 0xff8265).rw(FUNC(stbook_state::stbook_shifter_pixelofs_r), FUNC(stbook_state::stbook_shifter_pixelofs_w)); map(0xff8264, 0xff8265).rw(m_video, FUNC(stbook_video_device::stbook_shifter_pixelofs_r), FUNC(stbook_video_device::stbook_shifter_pixelofs_w));
map(0xff827e, 0xff827f).w(FUNC(stbook_state::lcd_control_w));*/ map(0xff827e, 0xff827f).w(m_video, FUNC(stbook_video_device::lcd_control_w));*/
map(0xff8800, 0xff8800).rw(YM3439_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)); map(0xff8800, 0xff8800).rw(YM3439_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w));
map(0xff8802, 0xff8802).w(YM3439_TAG, FUNC(ay8910_device::data_w)); map(0xff8802, 0xff8802).w(YM3439_TAG, FUNC(ay8910_device::data_w));
/* map(0xff8901, 0xff8901).rw(FUNC(stbook_state::sound_dma_control_r), FUNC(stbook_state::sound_dma_control_w)); /* map(0xff8901, 0xff8901).rw(FUNC(stbook_state::sound_dma_control_r), FUNC(stbook_state::sound_dma_control_w));
@ -1394,18 +1726,18 @@ void stbook_state::stbook_map(address_map &map)
map(0xff8921, 0xff8921).rw(FUNC(stbook_state::sound_mode_r), FUNC(stbook_state::sound_mode_w)); map(0xff8921, 0xff8921).rw(FUNC(stbook_state::sound_mode_r), FUNC(stbook_state::sound_mode_w));
map(0xff8922, 0xff8923).rw(FUNC(stbook_state::microwire_data_r), FUNC(stbook_state::microwire_data_w)); map(0xff8922, 0xff8923).rw(FUNC(stbook_state::microwire_data_r), FUNC(stbook_state::microwire_data_w));
map(0xff8924, 0xff8925).rw(FUNC(stbook_state::microwire_mask_r), FUNC(stbook_state::microwire_mask_w)); map(0xff8924, 0xff8925).rw(FUNC(stbook_state::microwire_mask_r), FUNC(stbook_state::microwire_mask_w));
map(0xff8a00, 0xff8a1f).rw(FUNC(stbook_state::blitter_halftone_r), FUNC(stbook_state::blitter_halftone_w)); map(0xff8a00, 0xff8a1f).rw(m_stb, FUNC(st_blitter_device::halftone_r), FUNC(st_blitter_device::halftone_w));
map(0xff8a20, 0xff8a21).rw(FUNC(stbook_state::blitter_src_inc_x_r), FUNC(stbook_state::blitter_src_inc_x_w)); map(0xff8a20, 0xff8a21).rw(m_stb, FUNC(st_blitter_device::src_inc_x_r), FUNC(st_blitter_device::src_inc_x_w));
map(0xff8a22, 0xff8a23).rw(FUNC(stbook_state::blitter_src_inc_y_r), FUNC(stbook_state::blitter_src_inc_y_w)); map(0xff8a22, 0xff8a23).rw(m_stb, FUNC(st_blitter_device::src_inc_y_r), FUNC(st_blitter_device::src_inc_y_w));
map(0xff8a24, 0xff8a27).rw(FUNC(stbook_state::blitter_src_r), FUNC(stbook_state::blitter_src_w)); map(0xff8a24, 0xff8a27).rw(m_stb, FUNC(st_blitter_device::src_r), FUNC(st_blitter_device::src_w));
map(0xff8a28, 0xff8a2d).rw(FUNC(stbook_state::blitter_end_mask_r), FUNC(stbook_state::blitter_end_mask_w)); map(0xff8a28, 0xff8a2d).rw(m_stb, FUNC(st_blitter_device::end_mask_r), FUNC(st_blitter_device::end_mask_w));
map(0xff8a2e, 0xff8a2f).rw(FUNC(stbook_state::blitter_dst_inc_x_r), FUNC(stbook_state::blitter_dst_inc_x_w)); map(0xff8a2e, 0xff8a2f).rw(m_stb, FUNC(st_blitter_device::dst_inc_x_r), FUNC(st_blitter_device::dst_inc_x_w));
map(0xff8a30, 0xff8a31).rw(FUNC(stbook_state::blitter_dst_inc_y_r), FUNC(stbook_state::blitter_dst_inc_y_w)); map(0xff8a30, 0xff8a31).rw(m_stb, FUNC(st_blitter_device::dst_inc_y_r), FUNC(st_blitter_device::dst_inc_y_w));
map(0xff8a32, 0xff8a35).rw(FUNC(stbook_state::blitter_dst_r), FUNC(stbook_state::blitter_dst_w)); map(0xff8a32, 0xff8a35).rw(m_stb, FUNC(st_blitter_device::dst_r), FUNC(st_blitter_device::dst_w));
map(0xff8a36, 0xff8a37).rw(FUNC(stbook_state::blitter_count_x_r), FUNC(stbook_state::blitter_count_x_w)); map(0xff8a36, 0xff8a37).rw(m_stb, FUNC(st_blitter_device::count_x_r), FUNC(st_blitter_device::count_x_w));
map(0xff8a38, 0xff8a39).rw(FUNC(stbook_state::blitter_count_y_r), FUNC(stbook_state::blitter_count_y_w)); map(0xff8a38, 0xff8a39).rw(m_stb, FUNC(st_blitter_device::count_y_r), FUNC(st_blitter_device::count_y_w));
map(0xff8a3a, 0xff8a3b).rw(FUNC(stbook_state::blitter_op_r), FUNC(stbook_state::blitter_op_w)); map(0xff8a3a, 0xff8a3b).rw(m_stb, FUNC(st_blitter_device::op_r), FUNC(st_blitter_device::op_w));
map(0xff8a3c, 0xff8a3d).rw(FUNC(stbook_state::blitter_ctrl_r), FUNC(stbook_state::blitter_ctrl_w)); map(0xff8a3c, 0xff8a3d).rw(m_stb, FUNC(st_blitter_device::ctrl_r), FUNC(st_blitter_device::ctrl_w));
map(0xff9200, 0xff9201).r(FUNC(stbook_state::config_r)); map(0xff9200, 0xff9201).r(FUNC(stbook_state::config_r));
map(0xff9202, 0xff9203).rw(FUNC(stbook_state::lcd_contrast_r), FUNC(stbook_state::lcd_contrast_w)); map(0xff9202, 0xff9203).rw(FUNC(stbook_state::lcd_contrast_r), FUNC(stbook_state::lcd_contrast_w));
map(0xff9210, 0xff9211).rw(FUNC(stbook_state::power_r), FUNC(stbook_state::power_w)); map(0xff9210, 0xff9211).rw(FUNC(stbook_state::power_r), FUNC(stbook_state::power_w));
@ -1890,10 +2222,6 @@ void st_state::machine_start()
m_mfp->i4_w(1); m_mfp->i4_w(1);
m_mfp->i5_w(1); m_mfp->i5_w(1);
m_mfp->i7_w(1); m_mfp->i7_w(1);
m_shifter_base = 0;
m_shifter_ofs = 0;
m_shifter_mode = 0;
} }
@ -1947,10 +2275,6 @@ void ste_state::machine_start()
m_mfp->i4_w(1); m_mfp->i4_w(1);
m_mfp->i5_w(1); m_mfp->i5_w(1);
m_mfp->i7_w(1); m_mfp->i7_w(1);
m_shifter_base = 0;
m_shifter_ofs = 0;
m_shifter_mode = 0;
} }
@ -2117,10 +2441,13 @@ void st_state::st(machine_config &config)
// video hardware // video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_screen_update(FUNC(st_state::screen_update)); m_screen->set_screen_update(m_video, FUNC(st_video_device::screen_update));
m_screen->set_raw(Y2/2, ATARIST_HTOT_PAL*2, ATARIST_HBEND_PAL*2, ATARIST_HBSTART_PAL*2, ATARIST_VTOT_PAL, ATARIST_VBEND_PAL, ATARIST_VBSTART_PAL); m_screen->set_raw(Y2/2, ATARIST_HTOT_PAL*2, ATARIST_HBEND_PAL*2, ATARIST_HBSTART_PAL*2, ATARIST_VTOT_PAL, ATARIST_VBEND_PAL, ATARIST_VBSTART_PAL);
PALETTE(config, m_palette).set_entries(16); ST_VIDEO(config, m_video, Y2);
m_video->set_screen(m_screen);
m_video->set_ram_space(m_maincpu, AS_PROGRAM);
m_video->de_callback().set(m_mfp, FUNC(mc68901_device::tbi_w));
// sound hardware // sound hardware
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
@ -2144,12 +2471,19 @@ void megast_state::megast(machine_config &config)
// basic machine hardware // basic machine hardware
m_maincpu->set_addrmap(AS_PROGRAM, &megast_state::megast_map); m_maincpu->set_addrmap(AS_PROGRAM, &megast_state::megast_map);
ST_BLITTER(config, m_stb, Y2/4);
m_stb->set_space(m_maincpu, AS_PROGRAM);
m_stb->int_callback().set(m_mfp, FUNC(mc68901_device::i3_w));
// video hardware // video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_screen_update(FUNC(megast_state::screen_update)); m_screen->set_screen_update(m_video, FUNC(st_video_device::screen_update));
m_screen->set_raw(Y2/4, ATARIST_HTOT_PAL, ATARIST_HBEND_PAL, ATARIST_HBSTART_PAL, ATARIST_VTOT_PAL, ATARIST_VBEND_PAL, ATARIST_VBSTART_PAL); m_screen->set_raw(Y2/4, ATARIST_HTOT_PAL, ATARIST_HBEND_PAL, ATARIST_HBSTART_PAL, ATARIST_VTOT_PAL, ATARIST_VBEND_PAL, ATARIST_VBSTART_PAL);
PALETTE(config, m_palette).set_entries(16); ST_VIDEO(config, m_video, Y2);
m_video->set_screen(m_screen);
m_video->set_ram_space(m_maincpu, AS_PROGRAM);
m_video->de_callback().set(m_mfp, FUNC(mc68901_device::tbi_w));
// sound hardware // sound hardware
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
@ -2176,12 +2510,19 @@ void ste_state::ste(machine_config &config)
// basic machine hardware // basic machine hardware
m_maincpu->set_addrmap(AS_PROGRAM, &ste_state::ste_map); m_maincpu->set_addrmap(AS_PROGRAM, &ste_state::ste_map);
ST_BLITTER(config, m_stb, Y2/4);
m_stb->set_space(m_maincpu, AS_PROGRAM);
m_stb->int_callback().set(m_mfp, FUNC(mc68901_device::i3_w));
// video hardware // video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_screen_update(FUNC(ste_state::screen_update)); m_screen->set_screen_update(m_video, FUNC(ste_video_device::screen_update));
m_screen->set_raw(Y2/4, ATARIST_HTOT_PAL, ATARIST_HBEND_PAL, ATARIST_HBSTART_PAL, ATARIST_VTOT_PAL, ATARIST_VBEND_PAL, ATARIST_VBSTART_PAL); m_screen->set_raw(Y2/4, ATARIST_HTOT_PAL, ATARIST_HBEND_PAL, ATARIST_HBSTART_PAL, ATARIST_VTOT_PAL, ATARIST_VBEND_PAL, ATARIST_VBSTART_PAL);
PALETTE(config, m_palette).set_entries(512); STE_VIDEO(config, m_video, Y2);
m_video->set_screen(m_screen);
m_video->set_ram_space(m_maincpu, AS_PROGRAM);
m_video->de_callback().set(m_mfp, FUNC(mc68901_device::tbi_w));
// sound hardware // sound hardware
SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "lspeaker").front_left();
@ -2232,14 +2573,21 @@ void stbook_state::stbook(machine_config &config)
//COP888(config, COP888_TAG, Y700); //COP888(config, COP888_TAG, Y700);
ST_BLITTER(config, m_stb, U517/2);
m_stb->set_space(m_maincpu, AS_PROGRAM);
m_stb->int_callback().set(m_mfp, FUNC(mc68901_device::i3_w));
// video hardware // video hardware
SCREEN(config, m_screen, SCREEN_TYPE_LCD); SCREEN(config, m_screen, SCREEN_TYPE_LCD);
m_screen->set_screen_update(FUNC(stbook_state::screen_update)); m_screen->set_screen_update(m_video, FUNC(stbook_video_device::screen_update));
m_screen->set_refresh_hz(60); m_screen->set_refresh_hz(60);
m_screen->set_size(640, 400); m_screen->set_size(640, 400);
m_screen->set_visarea(0, 639, 0, 399); m_screen->set_visarea(0, 639, 0, 399);
PALETTE(config, "palette", palette_device::MONOCHROME); STBOOK_VIDEO(config, m_video, Y2);
m_video->set_screen(m_screen);
m_video->set_ram_space(m_maincpu, AS_PROGRAM);
m_video->de_callback().set(m_mfp, FUNC(mc68901_device::tbi_w));
// sound hardware // sound hardware
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
@ -2275,13 +2623,13 @@ void stbook_state::stbook(machine_config &config)
m_rs232->cts_handler().set(m_mfp, FUNC(mc68901_device::i2_w)); m_rs232->cts_handler().set(m_mfp, FUNC(mc68901_device::i2_w));
m_rs232->ri_handler().set(m_mfp, FUNC(mc68901_device::i6_w)); m_rs232->ri_handler().set(m_mfp, FUNC(mc68901_device::i6_w));
ACIA6850(config, m_acia[0], 0); ACIA6850(config, m_acia[0]);
m_acia[0]->txd_handler().set(FUNC(st_state::ikbd_tx_w)); m_acia[0]->txd_handler().set(FUNC(st_state::ikbd_tx_w));
m_acia[0]->irq_handler().set("aciairq", FUNC(input_merger_device::in_w<0>)); m_acia[0]->irq_handler().set("aciairq", FUNC(input_merger_device::in_w<0>));
m_acia[0]->write_cts(0); m_acia[0]->write_cts(0);
m_acia[0]->write_dcd(0); m_acia[0]->write_dcd(0);
ACIA6850(config, m_acia[1], 0); ACIA6850(config, m_acia[1]);
m_acia[1]->txd_handler().set("mdout", FUNC(midi_port_device::write_txd)); m_acia[1]->txd_handler().set("mdout", FUNC(midi_port_device::write_txd));
m_acia[1]->irq_handler().set("aciairq", FUNC(input_merger_device::in_w<1>)); m_acia[1]->irq_handler().set("aciairq", FUNC(input_merger_device::in_w<1>));
m_acia[1]->write_cts(0); m_acia[1]->write_cts(0);
@ -3068,6 +3416,8 @@ ROM_START( falcon40 )
ROM_LOAD( "keyboard.u1", 0x0000, 0x1000, CRC(0296915d) SHA1(1102f20d38f333234041c13687d82528b7cde2e1) ) ROM_LOAD( "keyboard.u1", 0x0000, 0x1000, CRC(0296915d) SHA1(1102f20d38f333234041c13687d82528b7cde2e1) )
ROM_END ROM_END
} // anonymous namespace
//************************************************************************** //**************************************************************************

View File

@ -1,456 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder, Olivier Galibert
#ifndef MAME_INCLUDES_ATARI_ST_H
#define MAME_INCLUDES_ATARI_ST_H
#pragma once
#include "bus/rs232/rs232.h"
#include "cpu/m68000/m68000.h"
#include "cpu/m6800/m6801.h"
#include "machine/6850acia.h"
#include "machine/8530scc.h"
#include "bus/centronics/ctronics.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
#include "imagedev/floppy.h"
#include "machine/mc68901.h"
#include "machine/ram.h"
#include "machine/rescap.h"
#include "machine/rp5c15.h"
#include "machine/wd_fdc.h"
#include "sound/ay8910.h"
#include "sound/lmc1992.h"
#include "emupal.h"
#include "screen.h"
#define M68000_TAG "m68000"
#define HD6301V1_TAG "hd6301"
#define YM2149_TAG "ym2149"
#define MC6850_0_TAG "mc6850_0"
#define MC6850_1_TAG "mc6850_1"
#define Z8530_TAG "z8530"
#define COP888_TAG "u703"
#define RP5C15_TAG "rp5c15"
#define YM3439_TAG "ym3439"
#define MC68901_TAG "mc68901"
#define LMC1992_TAG "lmc1992"
#define WD1772_TAG "wd1772"
#define SCREEN_TAG "screen"
#define CENTRONICS_TAG "centronics"
#define RS232_TAG "rs232"
// Atari ST
#define Y1 XTAL(2'457'600)
// STBook
#define U517 XTAL(16'000'000)
#define Y200 XTAL(2'457'600)
#define Y700 XTAL(10'000'000)
#define DMA_STATUS_DRQ 0x04
#define DMA_STATUS_SECTOR_COUNT 0x02
#define DMA_STATUS_ERROR 0x01
#define DMA_MODE_READ_WRITE 0x100
#define DMA_MODE_FDC_HDC_ACK 0x080
#define DMA_MODE_ENABLED 0x040
#define DMA_MODE_SECTOR_COUNT 0x010
#define DMA_MODE_FDC_HDC_CS 0x008
#define DMA_MODE_A1 0x004
#define DMA_MODE_A0 0x002
#define DMA_MODE_ADDRESS_MASK 0x006
#define DMA_SECTOR_SIZE 512
enum
{
IKBD_MOUSE_PHASE_STATIC = 0,
IKBD_MOUSE_PHASE_POSITIVE,
IKBD_MOUSE_PHASE_NEGATIVE
};
class st_state : public driver_device
{
public:
enum
{
TIMER_MOUSE_TICK,
TIMER_SHIFTER_TICK,
TIMER_GLUE_TICK,
TIMER_BLITTER_TICK
};
st_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, M68000_TAG),
m_ikbd(*this, HD6301V1_TAG),
m_fdc(*this, WD1772_TAG),
m_floppy(*this, WD1772_TAG ":%u", 0U),
m_mfp(*this, MC68901_TAG),
m_acia(*this, {MC6850_0_TAG, MC6850_1_TAG}),
m_centronics(*this, CENTRONICS_TAG),
m_cart(*this, "cartslot"),
m_ram(*this, RAM_TAG),
m_rs232(*this, RS232_TAG),
m_ymsnd(*this, YM2149_TAG),
m_keys(*this, "P%o", 030),
m_joy(*this, "IKBD_JOY%u", 0U),
m_mousex(*this, "IKBD_MOUSEX"),
m_mousey(*this, "IKBD_MOUSEY"),
m_config(*this, "config"),
m_ikbd_mouse_x(0),
m_ikbd_mouse_y(0),
m_ikbd_mouse_px(IKBD_MOUSE_PHASE_STATIC),
m_ikbd_mouse_py(IKBD_MOUSE_PHASE_STATIC),
m_ikbd_mouse_pc(0),
m_ikbd_joy(1),
m_monochrome(1),
m_palette(*this, "palette"),
m_screen(*this, "screen"),
m_led(*this, "led1")
{ }
DECLARE_WRITE_LINE_MEMBER( write_monochrome );
void st(machine_config &config);
protected:
required_device<m68000_base_device> m_maincpu;
required_device<cpu_device> m_ikbd;
required_device<wd1772_device> m_fdc;
required_device_array<floppy_connector, 2> m_floppy;
required_device<mc68901_device> m_mfp;
required_device_array<acia6850_device, 2> m_acia;
required_device<centronics_device> m_centronics;
required_device<generic_slot_device> m_cart;
required_device<ram_device> m_ram;
required_device<rs232_port_device> m_rs232;
required_device<ym2149_device> m_ymsnd;
required_ioport_array<16> m_keys;
optional_ioport_array<2> m_joy;
optional_ioport m_mousex;
optional_ioport m_mousey;
optional_ioport m_config;
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
// video
uint8_t shifter_base_r(offs_t offset);
uint8_t shifter_counter_r(offs_t offset);
uint8_t shifter_sync_r();
uint16_t shifter_palette_r(offs_t offset);
uint8_t shifter_mode_r();
void shifter_base_w(offs_t offset, uint8_t data);
void shifter_sync_w(uint8_t data);
void shifter_palette_w(offs_t offset, uint16_t data);
void shifter_mode_w(uint8_t data);
uint16_t blitter_halftone_r(offs_t offset);
uint16_t blitter_src_inc_x_r();
uint16_t blitter_src_inc_y_r();
uint16_t blitter_src_r(offs_t offset);
uint16_t blitter_end_mask_r(offs_t offset);
uint16_t blitter_dst_inc_x_r();
uint16_t blitter_dst_inc_y_r();
uint16_t blitter_dst_r(offs_t offset);
uint16_t blitter_count_x_r();
uint16_t blitter_count_y_r();
uint16_t blitter_op_r(offs_t offset, uint16_t mem_mask = ~0);
uint16_t blitter_ctrl_r(offs_t offset, uint16_t mem_mask = ~0);
void blitter_halftone_w(offs_t offset, uint16_t data);
void blitter_src_inc_x_w(uint16_t data);
void blitter_src_inc_y_w(uint16_t data);
void blitter_src_w(offs_t offset, uint16_t data);
void blitter_end_mask_w(offs_t offset, uint16_t data);
void blitter_dst_inc_x_w(uint16_t data);
void blitter_dst_inc_y_w(uint16_t data);
void blitter_dst_w(offs_t offset, uint16_t data);
void blitter_count_x_w(uint16_t data);
void blitter_count_y_w(uint16_t data);
void blitter_op_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void blitter_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void mouse_tick();
inline pen_t shift_mode_0();
inline pen_t shift_mode_1();
inline pen_t shift_mode_2();
void shifter_tick();
inline void shifter_load();
inline void draw_pixel(int x, int y, u32 pen);
void glue_tick();
void set_screen_parameters();
void blitter_source();
uint16_t blitter_hop();
void blitter_op(uint16_t s, uint32_t dstaddr, uint16_t mask);
void blitter_tick();
// driver
uint16_t fdc_data_r(offs_t offset);
void fdc_data_w(offs_t offset, uint16_t data);
uint16_t dma_status_r();
void dma_mode_w(uint16_t data);
uint8_t dma_counter_r(offs_t offset);
void dma_base_w(offs_t offset, uint8_t data);
uint8_t mmu_r();
void mmu_w(uint8_t data);
uint16_t berr_r();
void berr_w(uint16_t data);
uint8_t ikbd_port1_r();
uint8_t ikbd_port2_r();
void ikbd_port2_w(uint8_t data);
void ikbd_port3_w(uint8_t data);
uint8_t ikbd_port4_r();
void ikbd_port4_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER( fdc_drq_w );
void psg_pa_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER( ikbd_tx_w );
DECLARE_WRITE_LINE_MEMBER( reset_w );
void toggle_dma_fifo();
void flush_dma_fifo();
void fill_dma_fifo();
void fdc_dma_transfer();
void configure_memory();
void state_save();
/* memory state */
uint8_t m_mmu = 0U;
/* keyboard state */
uint16_t m_ikbd_keylatch = 0U;
uint8_t m_ikbd_mouse = 0U;
uint8_t m_ikbd_mouse_x;
uint8_t m_ikbd_mouse_y;
uint8_t m_ikbd_mouse_px;
uint8_t m_ikbd_mouse_py;
uint8_t m_ikbd_mouse_pc;
int m_ikbd_tx = 0;
int m_ikbd_joy;
int m_midi_tx = 0;
/* floppy state */
uint32_t m_dma_base = 0U;
uint16_t m_dma_error = 0U;
uint16_t m_fdc_mode = 0U;
uint8_t m_fdc_sectors = 0U;
uint16_t m_fdc_fifo[2][8]{};
int m_fdc_fifo_sel = 0;
int m_fdc_fifo_index = 0;
int m_fdc_fifo_msb = 0;
int m_fdc_fifo_empty[2]{};
int m_fdc_dmabytes = 0;
/* shifter state */
uint32_t m_shifter_base = 0U;
uint32_t m_shifter_ofs = 0U;
uint8_t m_shifter_sync = 0U;
uint8_t m_shifter_mode = 0U;
uint16_t m_shifter_palette[16]{};
uint16_t m_shifter_rr[4]{};
uint16_t m_shifter_ir[4]{};
int m_shifter_bitplane = 0;
int m_shifter_shift = 0;
int m_shifter_h = 0;
int m_shifter_v = 0;
int m_shifter_de = 0;
int m_shifter_x_start = 0;
int m_shifter_x_end = 0;
int m_shifter_y_start = 0;
int m_shifter_y_end = 0;
int m_shifter_hblank_start = 0;
int m_shifter_vblank_start = 0;
/* blitter state */
uint16_t m_blitter_halftone[16]{};
int16_t m_blitter_src_inc_x = 0;
int16_t m_blitter_src_inc_y = 0;
int16_t m_blitter_dst_inc_x = 0;
int16_t m_blitter_dst_inc_y = 0;
uint32_t m_blitter_src = 0U;
uint32_t m_blitter_dst = 0U;
uint16_t m_blitter_endmask1 = 0U;
uint16_t m_blitter_endmask2 = 0U;
uint16_t m_blitter_endmask3 = 0U;
uint16_t m_blitter_xcount = 0U;
uint16_t m_blitter_ycount = 0U;
uint16_t m_blitter_xcountl = 0U;
uint8_t m_blitter_hop = 0U;
uint8_t m_blitter_op = 0U;
uint8_t m_blitter_ctrl = 0U;
uint8_t m_blitter_skew = 0U;
uint32_t m_blitter_srcbuf = 0U;
/* timers */
emu_timer *m_mouse_timer = nullptr;
emu_timer *m_glue_timer = nullptr;
emu_timer *m_shifter_timer = nullptr;
bitmap_rgb32 m_bitmap = 0;
static void floppy_formats(format_registration &fr);
int m_monochrome;
required_device<palette_device> m_palette;
required_device<screen_device> m_screen;
void common(machine_config &config);
void ikbd_map(address_map &map);
void cpu_space_map(address_map &map);
void st_map(address_map &map);
void megast_map(address_map &map);
void keyboard(machine_config &config);
uint16_t fpu_r();
void fpu_w(uint16_t data);
virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
virtual void machine_start() override;
virtual void video_start() override;
output_finder<> m_led;
};
class megast_state : public st_state
{
public:
megast_state(const machine_config &mconfig, device_type type, const char *tag)
: st_state(mconfig, type, tag)
{ }
void megast(machine_config &config);
};
class ste_state : public st_state
{
public:
enum
{
TIMER_DMASOUND_TICK,
TIMER_MICROWIRE_TICK
};
ste_state(const machine_config &mconfig, device_type type, const char *tag)
: st_state(mconfig, type, tag),
m_lmc1992(*this, LMC1992_TAG)
{ }
optional_device<lmc1992_device> m_lmc1992;
uint8_t shifter_base_low_r();
void shifter_base_low_w(uint8_t data);
uint8_t shifter_counter_r(offs_t offset);
void shifter_counter_w(offs_t offset, uint8_t data);
void shifter_palette_w(offs_t offset, uint16_t data);
uint8_t shifter_lineofs_r();
void shifter_lineofs_w(uint8_t data);
uint8_t shifter_pixelofs_r();
void shifter_pixelofs_w(uint8_t data);
uint8_t sound_dma_control_r();
uint8_t sound_dma_base_r(offs_t offset);
uint8_t sound_dma_counter_r(offs_t offset);
uint8_t sound_dma_end_r(offs_t offset);
uint8_t sound_mode_r();
void sound_dma_control_w(uint8_t data);
void sound_dma_base_w(offs_t offset, uint8_t data);
void sound_dma_end_w(offs_t offset, uint8_t data);
void sound_mode_w(uint8_t data);
uint16_t microwire_data_r();
void microwire_data_w(uint16_t data);
uint16_t microwire_mask_r();
void microwire_mask_w(uint16_t data);
DECLARE_WRITE_LINE_MEMBER( write_monochrome );
void dmasound_set_state(int level);
void dmasound_tick();
void microwire_shift();
void microwire_tick();
void state_save();
// shifter state
uint8_t m_shifter_lineofs = 0U;
uint8_t m_shifter_pixelofs = 0U;
/* microwire state */
uint16_t m_mw_data = 0U;
uint16_t m_mw_mask = 0U;
int m_mw_shift = 0;
/* DMA sound state */
uint32_t m_dmasnd_base = 0U;
uint32_t m_dmasnd_end = 0U;
uint32_t m_dmasnd_cntr = 0U;
uint32_t m_dmasnd_baselatch = 0U;
uint32_t m_dmasnd_endlatch = 0U;
uint8_t m_dmasnd_ctrl = 0U;
uint8_t m_dmasnd_mode = 0U;
uint8_t m_dmasnd_fifo[8]{};
uint8_t m_dmasnd_samples = 0U;
int m_dmasnd_active = 0;
// timers
emu_timer *m_microwire_timer = 0;
emu_timer *m_dmasound_timer = 0;
void falcon40(machine_config &config);
void tt030(machine_config &config);
void falcon(machine_config &config);
void ste(machine_config &config);
void ste_map(address_map &map);
protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
virtual void machine_start() override;
virtual void video_start() override;
};
class megaste_state : public ste_state
{
public:
megaste_state(const machine_config &mconfig, device_type type, const char *tag)
: ste_state(mconfig, type, tag)
{ }
uint16_t cache_r();
void cache_w(uint16_t data);
uint16_t m_cache = 0;
void megaste(machine_config &config);
void megaste_map(address_map &map);
protected:
virtual void machine_start() override;
};
class stbook_state : public ste_state
{
public:
stbook_state(const machine_config &mconfig, device_type type, const char *tag)
: ste_state(mconfig, type, tag),
m_sw400(*this, "SW400")
{ }
required_ioport m_sw400;
uint16_t config_r();
void lcd_control_w(uint16_t data);
void psg_pa_w(uint8_t data);
uint8_t mfp_gpio_r();
void stbook_map(address_map &map);
protected:
virtual void machine_start() override;
virtual void video_start() override;
};
#endif // MAME_INCLUDES_ATARI_ST_H

View File

@ -0,0 +1,554 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder, Olivier Galibert
#include "emu.h"
#include "machine/ataristb.h"
//**************************************************************************
// CONSTANTS / MACROS
//**************************************************************************
DEFINE_DEVICE_TYPE(ST_BLITTER, st_blitter_device, "st_blitter", "Atari ST Blitter")
static const int BLITTER_NOPS[16][4] =
{
{ 1, 1, 1, 1 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 1, 1, 2, 2 },
{ 2, 2, 3, 3 },
{ 2, 2, 2, 2 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 2, 2, 2, 2 },
{ 2, 2, 3, 3 },
{ 1, 1, 2, 2 },
{ 2, 2, 3, 3 },
{ 2, 2, 3, 3 },
{ 1, 1, 1, 1 }
};
//**************************************************************************
// BLITTER
//**************************************************************************
//-------------------------------------------------
// blitter_source -
//-------------------------------------------------
void st_blitter_device::blitter_source()
{
uint16_t data = m_space->read_word(m_src);
if (m_src_inc_x < 0)
{
m_srcbuf = (data << 16) | (m_srcbuf >> 16);
}
else
{
m_srcbuf = (m_srcbuf << 16) | data;
}
}
//-------------------------------------------------
// blitter_hop -
//-------------------------------------------------
uint16_t st_blitter_device::blitter_hop()
{
uint16_t source = m_srcbuf >> (m_skew & 0x0f);
uint16_t halftone = m_halftone[m_ctrl & 0x0f];
if (m_ctrl & CTRL_SMUDGE)
{
halftone = m_halftone[source & 0x0f];
}
switch (m_hop)
{
case 0:
return 0xffff;
case 1:
return halftone;
case 2:
return source;
case 3:
return source & halftone;
}
return 0;
}
//-------------------------------------------------
// blitter_op -
//-------------------------------------------------
void st_blitter_device::blitter_op(uint16_t s, uint32_t dstaddr, uint16_t mask)
{
uint16_t d = m_space->read_word(dstaddr);
uint16_t result = 0;
if (m_op & 0x08) result = (~s & ~d);
if (m_op & 0x04) result |= (~s & d);
if (m_op & 0x02) result |= (s & ~d);
if (m_op & 0x01) result |= (s & d);
m_space->write_word(dstaddr, result);
}
//-------------------------------------------------
// blitter_tick -
//-------------------------------------------------
TIMER_CALLBACK_MEMBER(st_blitter_device::blitter_tick)
{
do
{
if (m_skew & SKEW_FXSR)
{
blitter_source();
m_src += m_src_inc_x;
}
blitter_source();
blitter_op(blitter_hop(), m_dst, m_endmask1);
m_xcount--;
while (m_xcount > 0)
{
m_src += m_src_inc_x;
m_dst += m_dst_inc_x;
if (m_xcount == 1)
{
if (!(m_skew & SKEW_NFSR))
{
blitter_source();
}
blitter_op(blitter_hop(), m_dst, m_endmask3);
}
else
{
blitter_source();
blitter_op(blitter_hop(), m_dst, m_endmask2);
}
m_xcount--;
}
m_src += m_src_inc_y;
m_dst += m_dst_inc_y;
if (m_dst_inc_y < 0)
{
m_ctrl = (m_ctrl & 0xf0) | (((m_ctrl & 0x0f) - 1) & 0x0f);
}
else
{
m_ctrl = (m_ctrl & 0xf0) | (((m_ctrl & 0x0f) + 1) & 0x0f);
}
m_xcount = m_xcountl;
m_ycount--;
}
while (m_ycount > 0);
m_ctrl &= 0x7f;
m_int_callback(0); // active low
}
//-------------------------------------------------
// halftone_r -
//-------------------------------------------------
uint16_t st_blitter_device::halftone_r(offs_t offset)
{
return m_halftone[offset];
}
//-------------------------------------------------
// src_inc_x_r -
//-------------------------------------------------
uint16_t st_blitter_device::src_inc_x_r()
{
return m_src_inc_x;
}
//-------------------------------------------------
// src_inc_y_r -
//-------------------------------------------------
uint16_t st_blitter_device::src_inc_y_r()
{
return m_src_inc_y;
}
//-------------------------------------------------
// src_r -
//-------------------------------------------------
uint16_t st_blitter_device::src_r(offs_t offset)
{
switch (offset)
{
case 0:
return (m_src >> 16) & 0xff;
case 1:
return m_src & 0xfffe;
}
return 0;
}
//-------------------------------------------------
// end_mask_r -
//-------------------------------------------------
uint16_t st_blitter_device::end_mask_r(offs_t offset)
{
switch (offset)
{
case 0:
return m_endmask1;
case 1:
return m_endmask2;
case 2:
return m_endmask3;
}
return 0;
}
//-------------------------------------------------
// dst_inc_x_r -
//-------------------------------------------------
uint16_t st_blitter_device::dst_inc_x_r()
{
return m_dst_inc_x;
}
//-------------------------------------------------
// dst_inc_y_r -
//-------------------------------------------------
uint16_t st_blitter_device::dst_inc_y_r()
{
return m_dst_inc_y;
}
//-------------------------------------------------
// blitter_dst_r -
//-------------------------------------------------
uint16_t st_blitter_device::dst_r(offs_t offset)
{
switch (offset)
{
case 0:
return (m_dst >> 16) & 0xff;
case 1:
return m_dst & 0xfffe;
}
return 0;
}
//-------------------------------------------------
// count_x_r -
//-------------------------------------------------
uint16_t st_blitter_device::count_x_r()
{
return m_xcount;
}
//-------------------------------------------------
// count_y_r -
//-------------------------------------------------
uint16_t st_blitter_device::count_y_r()
{
return m_ycount;
}
//-------------------------------------------------
// op_r -
//-------------------------------------------------
uint16_t st_blitter_device::op_r(offs_t offset, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
{
return m_hop;
}
else
{
return m_op;
}
}
//-------------------------------------------------
// ctrl_r -
//-------------------------------------------------
uint16_t st_blitter_device::ctrl_r(offs_t offset, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
{
return m_ctrl;
}
else
{
return m_skew;
}
}
//-------------------------------------------------
// halftone_w -
//-------------------------------------------------
void st_blitter_device::halftone_w(offs_t offset, uint16_t data)
{
m_halftone[offset] = data;
}
//-------------------------------------------------
// src_inc_x_w -
//-------------------------------------------------
void st_blitter_device::src_inc_x_w(uint16_t data)
{
m_src_inc_x = data & 0xfffe;
}
//-------------------------------------------------
// src_inc_y_w -
//-------------------------------------------------
void st_blitter_device::src_inc_y_w(uint16_t data)
{
m_src_inc_y = data & 0xfffe;
}
//-------------------------------------------------
// src_w -
//-------------------------------------------------
void st_blitter_device::src_w(offs_t offset, uint16_t data)
{
switch (offset)
{
case 0:
m_src = (data & 0xff) | (m_src & 0xfffe);
break;
case 1:
m_src = (m_src & 0xff0000) | (data & 0xfffe);
break;
}
}
//-------------------------------------------------
// end_mask_w -
//-------------------------------------------------
void st_blitter_device::end_mask_w(offs_t offset, uint16_t data)
{
switch (offset)
{
case 0:
m_endmask1 = data;
break;
case 1:
m_endmask2 = data;
break;
case 2:
m_endmask3 = data;
break;
}
}
//-------------------------------------------------
// dst_inc_x_w -
//-------------------------------------------------
void st_blitter_device::dst_inc_x_w(uint16_t data)
{
m_dst_inc_x = data & 0xfffe;
}
//-------------------------------------------------
// dst_inc_y_w -
//-------------------------------------------------
void st_blitter_device::dst_inc_y_w(uint16_t data)
{
m_dst_inc_y = data & 0xfffe;
}
//-------------------------------------------------
// dst_w -
//-------------------------------------------------
void st_blitter_device::dst_w(offs_t offset, uint16_t data)
{
switch (offset)
{
case 0:
m_dst = (data & 0xff) | (m_dst & 0xfffe);
break;
case 1:
m_dst = (m_dst & 0xff0000) | (data & 0xfffe);
break;
}
}
//-------------------------------------------------
// count_x_w -
//-------------------------------------------------
void st_blitter_device::count_x_w(uint16_t data)
{
m_xcount = data;
}
//-------------------------------------------------
// count_y_w -
//-------------------------------------------------
void st_blitter_device::count_y_w(uint16_t data)
{
m_ycount = data;
}
//-------------------------------------------------
// op_w -
//-------------------------------------------------
void st_blitter_device::op_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
{
m_hop = (data >> 8) & 0x03;
}
else
{
m_op = data & 0x0f;
}
}
//-------------------------------------------------
// ctrl_w -
//-------------------------------------------------
void st_blitter_device::ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
{
m_ctrl = (data >> 8) & 0xef;
if (!(m_ctrl & CTRL_BUSY))
{
if ((data >> 8) & CTRL_BUSY)
{
m_int_callback(1);
int nops = BLITTER_NOPS[m_op][m_hop]; // each NOP takes 4 cycles
m_blitter_timer->adjust(clocks_to_attotime(4*nops));
}
}
}
else
{
m_skew = data & 0xcf;
}
}
//**************************************************************************
// VIDEO
//**************************************************************************
st_blitter_device::st_blitter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, ST_BLITTER, tag, owner, clock)
, m_space(*this, finder_base::DUMMY_TAG, 0)
, m_int_callback(*this)
, m_blitter_timer(nullptr)
{
}
void st_blitter_device::device_resolve_objects()
{
m_int_callback.resolve_safe();
}
void st_blitter_device::device_start()
{
m_blitter_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st_blitter_device::blitter_tick), this));
// register for state saving
save_item(NAME(m_halftone));
save_item(NAME(m_src_inc_x));
save_item(NAME(m_src_inc_y));
save_item(NAME(m_dst_inc_x));
save_item(NAME(m_dst_inc_y));
save_item(NAME(m_src));
save_item(NAME(m_dst));
save_item(NAME(m_endmask1));
save_item(NAME(m_endmask2));
save_item(NAME(m_endmask3));
save_item(NAME(m_xcount));
save_item(NAME(m_ycount));
save_item(NAME(m_xcountl));
save_item(NAME(m_hop));
save_item(NAME(m_op));
save_item(NAME(m_ctrl));
save_item(NAME(m_skew));
}
void st_blitter_device::device_reset()
{
}

View File

@ -0,0 +1,90 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder, Olivier Galibert
#ifndef MAME_MACHINE_ATARISTB_H
#define MAME_MACHINE_ATARISTB_H
#pragma once
class st_blitter_device : public device_t
{
static constexpr uint8_t SKEW_NFSR = 0x40;
static constexpr uint8_t SKEW_FXSR = 0x80;
static constexpr uint8_t CTRL_SMUDGE = 0x20;
static constexpr uint8_t CTRL_HOG = 0x40;
static constexpr uint8_t CTRL_BUSY = 0x80;
public:
st_blitter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <typename T> void set_space(T &&tag, int spacenum) { m_space.set_tag(tag, spacenum); }
auto int_callback() { return m_int_callback.bind(); }
uint16_t halftone_r(offs_t offset);
uint16_t src_inc_x_r();
uint16_t src_inc_y_r();
uint16_t src_r(offs_t offset);
uint16_t end_mask_r(offs_t offset);
uint16_t dst_inc_x_r();
uint16_t dst_inc_y_r();
uint16_t dst_r(offs_t offset);
uint16_t count_x_r();
uint16_t count_y_r();
uint16_t op_r(offs_t offset, uint16_t mem_mask = ~0);
uint16_t ctrl_r(offs_t offset, uint16_t mem_mask = ~0);
void halftone_w(offs_t offset, uint16_t data);
void src_inc_x_w(uint16_t data);
void src_inc_y_w(uint16_t data);
void src_w(offs_t offset, uint16_t data);
void end_mask_w(offs_t offset, uint16_t data);
void dst_inc_x_w(uint16_t data);
void dst_inc_y_w(uint16_t data);
void dst_w(offs_t offset, uint16_t data);
void count_x_w(uint16_t data);
void count_y_w(uint16_t data);
void op_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
protected:
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual void device_reset() override;
private:
void blitter_source();
uint16_t blitter_hop();
void blitter_op(uint16_t s, uint32_t dstaddr, uint16_t mask);
TIMER_CALLBACK_MEMBER(blitter_tick);
required_address_space m_space;
devcb_write_line m_int_callback;
// timers
emu_timer *m_blitter_timer;
// blitter state
uint16_t m_halftone[16]{};
int16_t m_src_inc_x = 0;
int16_t m_src_inc_y = 0;
int16_t m_dst_inc_x = 0;
int16_t m_dst_inc_y = 0;
uint32_t m_src = 0U;
uint32_t m_dst = 0U;
uint16_t m_endmask1 = 0U;
uint16_t m_endmask2 = 0U;
uint16_t m_endmask3 = 0U;
uint16_t m_xcount = 0U;
uint16_t m_ycount = 0U;
uint16_t m_xcountl = 0U;
uint8_t m_hop = 0U;
uint8_t m_op = 0U;
uint8_t m_ctrl = 0U;
uint8_t m_skew = 0U;
uint32_t m_srcbuf = 0U;
};
// device type declaration
DECLARE_DEVICE_TYPE(ST_BLITTER, st_blitter_device)
#endif // MAME_MACHINE_ATARISTB_H

View File

@ -13,7 +13,8 @@
#include "emu.h" #include "emu.h"
#include "video/atarist.h" #include "video/atarist.h"
#include "includes/atarist.h" #include "cpu/m68000/m68000.h"
#include "screen.h"
@ -21,7 +22,10 @@
// CONSTANTS / MACROS // CONSTANTS / MACROS
//************************************************************************** //**************************************************************************
#define LOG 0 DEFINE_DEVICE_TYPE(ST_VIDEO, st_video_device, "st_video", "Atari ST Video ASICs")
DEFINE_DEVICE_TYPE(STE_VIDEO, ste_video_device, "ste_video", "Atari STe Video ASICs")
//DEFINE_DEVICE_TYPE(STBOOK_VIDEO, stbook_video_device, "stbook_video", "Atari STbook Video ASICs")
//DEFINE_DEVICE_TYPE(TT_VIDEO, tt_video_device, "tt_video", "Atari TT Video ASICs")
static const int BLITTER_NOPS[16][4] = static const int BLITTER_NOPS[16][4] =
{ {
@ -52,7 +56,7 @@ static const int BLITTER_NOPS[16][4] =
// shift_mode_0 - // shift_mode_0 -
//------------------------------------------------- //-------------------------------------------------
inline pen_t st_state::shift_mode_0() inline pen_t st_video_device::shift_mode_0()
{ {
int color = (BIT(m_shifter_rr[3], 15) << 3) | (BIT(m_shifter_rr[2], 15) << 2) | (BIT(m_shifter_rr[1], 15) << 1) | BIT(m_shifter_rr[0], 15); int color = (BIT(m_shifter_rr[3], 15) << 3) | (BIT(m_shifter_rr[2], 15) << 2) | (BIT(m_shifter_rr[1], 15) << 1) | BIT(m_shifter_rr[0], 15);
@ -61,7 +65,7 @@ inline pen_t st_state::shift_mode_0()
m_shifter_rr[2] <<= 1; m_shifter_rr[2] <<= 1;
m_shifter_rr[3] <<= 1; m_shifter_rr[3] <<= 1;
return m_palette->pen(color); return pen(color);
} }
@ -69,7 +73,7 @@ inline pen_t st_state::shift_mode_0()
// shift_mode_1 - // shift_mode_1 -
//------------------------------------------------- //-------------------------------------------------
inline pen_t st_state::shift_mode_1() inline pen_t st_video_device::shift_mode_1()
{ {
int color = (BIT(m_shifter_rr[1], 15) << 1) | BIT(m_shifter_rr[0], 15); int color = (BIT(m_shifter_rr[1], 15) << 1) | BIT(m_shifter_rr[0], 15);
@ -85,7 +89,7 @@ inline pen_t st_state::shift_mode_1()
m_shifter_shift = 0; m_shifter_shift = 0;
} }
return m_palette->pen(color); return pen(color);
} }
@ -93,7 +97,7 @@ inline pen_t st_state::shift_mode_1()
// shift_mode_2 - // shift_mode_2 -
//------------------------------------------------- //-------------------------------------------------
inline pen_t st_state::shift_mode_2() inline pen_t st_video_device::shift_mode_2()
{ {
int color = BIT(m_shifter_rr[0], 15); int color = BIT(m_shifter_rr[0], 15);
@ -122,7 +126,7 @@ inline pen_t st_state::shift_mode_2()
break; break;
} }
return m_palette->pen(color); return pen(color);
} }
@ -130,10 +134,10 @@ inline pen_t st_state::shift_mode_2()
// shifter_tick - // shifter_tick -
//------------------------------------------------- //-------------------------------------------------
void st_state::shifter_tick() TIMER_CALLBACK_MEMBER(st_video_device::shifter_tick)
{ {
int y = m_screen->vpos(); int y = screen().vpos();
int x = m_screen->hpos(); int x = screen().hpos();
pen_t pen; pen_t pen;
@ -152,7 +156,7 @@ void st_state::shifter_tick()
break; break;
default: default:
pen = m_palette->black_pen(); pen = black_pen();
break; break;
} }
@ -164,10 +168,9 @@ void st_state::shifter_tick()
// shifter_load - // shifter_load -
//------------------------------------------------- //-------------------------------------------------
inline void st_state::shifter_load() inline void st_video_device::shifter_load()
{ {
address_space &program = m_maincpu->space(AS_PROGRAM); uint16_t data = m_ram_space->read_word(m_shifter_ofs);
uint16_t data = program.read_word(m_shifter_ofs);
m_shifter_ir[m_shifter_bitplane] = data; m_shifter_ir[m_shifter_bitplane] = data;
m_shifter_bitplane++; m_shifter_bitplane++;
@ -189,16 +192,16 @@ inline void st_state::shifter_load()
// glue_tick - // glue_tick -
//------------------------------------------------- //-------------------------------------------------
void st_state::draw_pixel(int x, int y, u32 pen) void st_video_device::draw_pixel(int x, int y, u32 pen)
{ {
if(x < m_bitmap.width() && y < m_bitmap.height()) if(x < m_bitmap.width() && y < m_bitmap.height())
m_bitmap.pix(y, x) = pen; m_bitmap.pix(y, x) = pen;
} }
void st_state::glue_tick() TIMER_CALLBACK_MEMBER(st_video_device::glue_tick)
{ {
int y = m_screen->vpos(); int y = screen().vpos();
int x = m_screen->hpos(); int x = screen().hpos();
int v = (y >= m_shifter_y_start) && (y < m_shifter_y_end); int v = (y >= m_shifter_y_start) && (y < m_shifter_y_end);
int h = (x >= m_shifter_x_start) && (x < m_shifter_x_end); int h = (x >= m_shifter_x_start) && (x < m_shifter_x_end);
@ -212,7 +215,7 @@ void st_state::glue_tick()
if (de != m_shifter_de) if (de != m_shifter_de)
{ {
m_mfp->tbi_w(de); m_de_callback(de);
m_shifter_de = de; m_shifter_de = de;
} }
@ -223,13 +226,13 @@ void st_state::glue_tick()
if ((y == m_shifter_vblank_start) && (x == 0)) if ((y == m_shifter_vblank_start) && (x == 0))
{ {
m_maincpu->set_input_line(M68K_IRQ_4, HOLD_LINE); m_maincpu->set_input_line(M68K_IRQ_4, HOLD_LINE); // FIXME: make this a callback instead
m_shifter_ofs = m_shifter_base; m_shifter_ofs = m_shifter_base;
} }
if (x == m_shifter_hblank_start) if (x == m_shifter_hblank_start)
{ {
m_maincpu->set_input_line(M68K_IRQ_2, HOLD_LINE); m_maincpu->set_input_line(M68K_IRQ_2, HOLD_LINE); // FIXME: make this a callback instead
// m_shifter_ofs += (m_shifter_lineofs * 2); // STe // m_shifter_ofs += (m_shifter_lineofs * 2); // STe
} }
@ -276,7 +279,7 @@ void st_state::glue_tick()
break; break;
default: default:
pen = m_palette->black_pen(); pen = black_pen();
break; break;
} }
} }
@ -286,7 +289,7 @@ void st_state::glue_tick()
// set_screen_parameters - // set_screen_parameters -
//------------------------------------------------- //-------------------------------------------------
void st_state::set_screen_parameters() void st_video_device::set_screen_parameters()
{ {
if (m_shifter_sync & 0x02) if (m_shifter_sync & 0x02)
{ {
@ -313,7 +316,7 @@ void st_state::set_screen_parameters()
// shifter_base_r - // shifter_base_r -
//------------------------------------------------- //-------------------------------------------------
uint8_t st_state::shifter_base_r(offs_t offset) uint8_t st_video_device::shifter_base_r(offs_t offset)
{ {
uint8_t data = 0; uint8_t data = 0;
@ -336,7 +339,7 @@ uint8_t st_state::shifter_base_r(offs_t offset)
// shifter_base_w - // shifter_base_w -
//------------------------------------------------- //-------------------------------------------------
void st_state::shifter_base_w(offs_t offset, uint8_t data) void st_video_device::shifter_base_w(offs_t offset, uint8_t data)
{ {
switch (offset) switch (offset)
{ {
@ -357,7 +360,7 @@ void st_state::shifter_base_w(offs_t offset, uint8_t data)
// shifter_counter_r - // shifter_counter_r -
//------------------------------------------------- //-------------------------------------------------
uint8_t st_state::shifter_counter_r(offs_t offset) uint8_t st_video_device::shifter_counter_r(offs_t offset)
{ {
uint8_t data = 0; uint8_t data = 0;
@ -384,7 +387,7 @@ uint8_t st_state::shifter_counter_r(offs_t offset)
// shifter_sync_r - // shifter_sync_r -
//------------------------------------------------- //-------------------------------------------------
uint8_t st_state::shifter_sync_r() uint8_t st_video_device::shifter_sync_r()
{ {
return m_shifter_sync; return m_shifter_sync;
} }
@ -394,7 +397,7 @@ uint8_t st_state::shifter_sync_r()
// shifter_sync_w - // shifter_sync_w -
//------------------------------------------------- //-------------------------------------------------
void st_state::shifter_sync_w(uint8_t data) void st_video_device::shifter_sync_w(uint8_t data)
{ {
m_shifter_sync = data; m_shifter_sync = data;
logerror("SHIFTER Sync %x\n", m_shifter_sync); logerror("SHIFTER Sync %x\n", m_shifter_sync);
@ -406,7 +409,7 @@ void st_state::shifter_sync_w(uint8_t data)
// shifter_mode_r - // shifter_mode_r -
//------------------------------------------------- //-------------------------------------------------
uint8_t st_state::shifter_mode_r() uint8_t st_video_device::shifter_mode_r()
{ {
return m_shifter_mode; return m_shifter_mode;
} }
@ -416,7 +419,7 @@ uint8_t st_state::shifter_mode_r()
// shifter_mode_w - // shifter_mode_w -
//------------------------------------------------- //-------------------------------------------------
void st_state::shifter_mode_w(uint8_t data) void st_video_device::shifter_mode_w(uint8_t data)
{ {
m_shifter_mode = data; m_shifter_mode = data;
logerror("SHIFTER Mode %x\n", m_shifter_mode); logerror("SHIFTER Mode %x\n", m_shifter_mode);
@ -427,7 +430,7 @@ void st_state::shifter_mode_w(uint8_t data)
// shifter_palette_r - // shifter_palette_r -
//------------------------------------------------- //-------------------------------------------------
uint16_t st_state::shifter_palette_r(offs_t offset) uint16_t st_video_device::shifter_palette_r(offs_t offset)
{ {
return m_shifter_palette[offset] | 0xf888; return m_shifter_palette[offset] | 0xf888;
} }
@ -437,12 +440,12 @@ uint16_t st_state::shifter_palette_r(offs_t offset)
// shifter_palette_w - // shifter_palette_w -
//------------------------------------------------- //-------------------------------------------------
void st_state::shifter_palette_w(offs_t offset, uint16_t data) void st_video_device::shifter_palette_w(offs_t offset, uint16_t data)
{ {
m_shifter_palette[offset] = data; m_shifter_palette[offset] = data;
// logerror("SHIFTER Palette[%x] = %x\n", offset, data); // logerror("SHIFTER Palette[%x] = %x\n", offset, data);
m_palette->set_pen_color(offset, pal3bit(data >> 8), pal3bit(data >> 4), pal3bit(data)); set_pen_color(offset, pal3bit(data >> 8), pal3bit(data >> 4), pal3bit(data));
} }
@ -455,7 +458,7 @@ void st_state::shifter_palette_w(offs_t offset, uint16_t data)
// shifter_base_low_r - // shifter_base_low_r -
//------------------------------------------------- //-------------------------------------------------
uint8_t ste_state::shifter_base_low_r() uint8_t ste_video_device::shifter_base_low_r()
{ {
return m_shifter_base & 0xfe; return m_shifter_base & 0xfe;
} }
@ -465,7 +468,7 @@ uint8_t ste_state::shifter_base_low_r()
// shifter_base_low_w - // shifter_base_low_w -
//------------------------------------------------- //-------------------------------------------------
void ste_state::shifter_base_low_w(uint8_t data) void ste_video_device::shifter_base_low_w(uint8_t data)
{ {
m_shifter_base = (m_shifter_base & 0x3fff00) | (data & 0xfe); m_shifter_base = (m_shifter_base & 0x3fff00) | (data & 0xfe);
logerror("SHIFTER Video Base Address %06x\n", m_shifter_base); logerror("SHIFTER Video Base Address %06x\n", m_shifter_base);
@ -476,7 +479,7 @@ void ste_state::shifter_base_low_w(uint8_t data)
// shifter_counter_r - // shifter_counter_r -
//------------------------------------------------- //-------------------------------------------------
uint8_t ste_state::shifter_counter_r(offs_t offset) uint8_t ste_video_device::shifter_counter_r(offs_t offset)
{ {
uint8_t data = 0; uint8_t data = 0;
@ -503,7 +506,7 @@ uint8_t ste_state::shifter_counter_r(offs_t offset)
// shifter_counter_w - // shifter_counter_w -
//------------------------------------------------- //-------------------------------------------------
void ste_state::shifter_counter_w(offs_t offset, uint8_t data) void ste_video_device::shifter_counter_w(offs_t offset, uint8_t data)
{ {
switch (offset) switch (offset)
{ {
@ -529,7 +532,7 @@ void ste_state::shifter_counter_w(offs_t offset, uint8_t data)
// shifter_palette_w - // shifter_palette_w -
//------------------------------------------------- //-------------------------------------------------
void ste_state::shifter_palette_w(offs_t offset, uint16_t data) void ste_video_device::shifter_palette_w(offs_t offset, uint16_t data)
{ {
int r = ((data >> 7) & 0x0e) | BIT(data, 11); int r = ((data >> 7) & 0x0e) | BIT(data, 11);
int g = ((data >> 3) & 0x0e) | BIT(data, 7); int g = ((data >> 3) & 0x0e) | BIT(data, 7);
@ -538,7 +541,7 @@ void ste_state::shifter_palette_w(offs_t offset, uint16_t data)
m_shifter_palette[offset] = data; m_shifter_palette[offset] = data;
logerror("SHIFTER palette %x = %x\n", offset, data); logerror("SHIFTER palette %x = %x\n", offset, data);
m_palette->set_pen_color(offset, r, g, b); set_pen_color(offset, r, g, b);
} }
@ -546,7 +549,7 @@ void ste_state::shifter_palette_w(offs_t offset, uint16_t data)
// shifter_lineofs_r - // shifter_lineofs_r -
//------------------------------------------------- //-------------------------------------------------
uint8_t ste_state::shifter_lineofs_r() uint8_t ste_video_device::shifter_lineofs_r()
{ {
return m_shifter_lineofs; return m_shifter_lineofs;
} }
@ -556,7 +559,7 @@ uint8_t ste_state::shifter_lineofs_r()
// shifter_lineofs_w - // shifter_lineofs_w -
//------------------------------------------------- //-------------------------------------------------
void ste_state::shifter_lineofs_w(uint8_t data) void ste_video_device::shifter_lineofs_w(uint8_t data)
{ {
m_shifter_lineofs = data; m_shifter_lineofs = data;
logerror("SHIFTER Line Offset %x\n", m_shifter_lineofs); logerror("SHIFTER Line Offset %x\n", m_shifter_lineofs);
@ -567,7 +570,7 @@ void ste_state::shifter_lineofs_w(uint8_t data)
// shifter_pixelofs_r - // shifter_pixelofs_r -
//------------------------------------------------- //-------------------------------------------------
uint8_t ste_state::shifter_pixelofs_r() uint8_t ste_video_device::shifter_pixelofs_r()
{ {
return m_shifter_pixelofs; return m_shifter_pixelofs;
} }
@ -577,7 +580,7 @@ uint8_t ste_state::shifter_pixelofs_r()
// shifter_pixelofs_w - // shifter_pixelofs_w -
//------------------------------------------------- //-------------------------------------------------
void ste_state::shifter_pixelofs_w(uint8_t data) void ste_video_device::shifter_pixelofs_w(uint8_t data)
{ {
m_shifter_pixelofs = data & 0x0f; m_shifter_pixelofs = data & 0x0f;
logerror("SHIFTER Pixel Offset %x\n", m_shifter_pixelofs); logerror("SHIFTER Pixel Offset %x\n", m_shifter_pixelofs);
@ -585,496 +588,48 @@ void ste_state::shifter_pixelofs_w(uint8_t data)
//**************************************************************************
// BLITTER
//**************************************************************************
//-------------------------------------------------
// blitter_source -
//-------------------------------------------------
void st_state::blitter_source()
{
address_space &program = m_maincpu->space(AS_PROGRAM);
uint16_t data = program.read_word(m_blitter_src);
if (m_blitter_src_inc_x < 0)
{
m_blitter_srcbuf = (data << 16) | (m_blitter_srcbuf >> 16);
}
else
{
m_blitter_srcbuf = (m_blitter_srcbuf << 16) | data;
}
}
//-------------------------------------------------
// blitter_hop -
//-------------------------------------------------
uint16_t st_state::blitter_hop()
{
uint16_t source = m_blitter_srcbuf >> (m_blitter_skew & 0x0f);
uint16_t halftone = m_blitter_halftone[m_blitter_ctrl & 0x0f];
if (m_blitter_ctrl & ATARIST_BLITTER_CTRL_SMUDGE)
{
halftone = m_blitter_halftone[source & 0x0f];
}
switch (m_blitter_hop)
{
case 0:
return 0xffff;
case 1:
return halftone;
case 2:
return source;
case 3:
return source & halftone;
}
return 0;
}
//-------------------------------------------------
// blitter_op -
//-------------------------------------------------
void st_state::blitter_op(uint16_t s, uint32_t dstaddr, uint16_t mask)
{
address_space &program = m_maincpu->space(AS_PROGRAM);
uint16_t d = program.read_word(dstaddr);
uint16_t result = 0;
if (m_blitter_op & 0x08) result = (~s & ~d);
if (m_blitter_op & 0x04) result |= (~s & d);
if (m_blitter_op & 0x02) result |= (s & ~d);
if (m_blitter_op & 0x01) result |= (s & d);
program.write_word(dstaddr, result);
}
//-------------------------------------------------
// blitter_tick -
//-------------------------------------------------
void st_state::blitter_tick()
{
do
{
if (m_blitter_skew & ATARIST_BLITTER_SKEW_FXSR)
{
blitter_source();
m_blitter_src += m_blitter_src_inc_x;
}
blitter_source();
blitter_op(blitter_hop(), m_blitter_dst, m_blitter_endmask1);
m_blitter_xcount--;
while (m_blitter_xcount > 0)
{
m_blitter_src += m_blitter_src_inc_x;
m_blitter_dst += m_blitter_dst_inc_x;
if (m_blitter_xcount == 1)
{
if (!(m_blitter_skew & ATARIST_BLITTER_SKEW_NFSR))
{
blitter_source();
}
blitter_op(blitter_hop(), m_blitter_dst, m_blitter_endmask3);
}
else
{
blitter_source();
blitter_op(blitter_hop(), m_blitter_dst, m_blitter_endmask2);
}
m_blitter_xcount--;
}
m_blitter_src += m_blitter_src_inc_y;
m_blitter_dst += m_blitter_dst_inc_y;
if (m_blitter_dst_inc_y < 0)
{
m_blitter_ctrl = (m_blitter_ctrl & 0xf0) | (((m_blitter_ctrl & 0x0f) - 1) & 0x0f);
}
else
{
m_blitter_ctrl = (m_blitter_ctrl & 0xf0) | (((m_blitter_ctrl & 0x0f) + 1) & 0x0f);
}
m_blitter_xcount = m_blitter_xcountl;
m_blitter_ycount--;
}
while (m_blitter_ycount > 0);
m_blitter_ctrl &= 0x7f;
m_mfp->i3_w(0);
}
//-------------------------------------------------
// blitter_halftone_r -
//-------------------------------------------------
uint16_t st_state::blitter_halftone_r(offs_t offset)
{
return m_blitter_halftone[offset];
}
//-------------------------------------------------
// blitter_src_inc_x_r -
//-------------------------------------------------
uint16_t st_state::blitter_src_inc_x_r()
{
return m_blitter_src_inc_x;
}
//-------------------------------------------------
// blitter_src_inc_y_r -
//-------------------------------------------------
uint16_t st_state::blitter_src_inc_y_r()
{
return m_blitter_src_inc_y;
}
//-------------------------------------------------
// blitter_src_r -
//-------------------------------------------------
uint16_t st_state::blitter_src_r(offs_t offset)
{
switch (offset)
{
case 0:
return (m_blitter_src >> 16) & 0xff;
case 1:
return m_blitter_src & 0xfffe;
}
return 0;
}
//-------------------------------------------------
// blitter_end_mask_r -
//-------------------------------------------------
uint16_t st_state::blitter_end_mask_r(offs_t offset)
{
switch (offset)
{
case 0:
return m_blitter_endmask1;
case 1:
return m_blitter_endmask2;
case 2:
return m_blitter_endmask3;
}
return 0;
}
//-------------------------------------------------
// blitter_dst_inc_x_r -
//-------------------------------------------------
uint16_t st_state::blitter_dst_inc_x_r()
{
return m_blitter_dst_inc_x;
}
//-------------------------------------------------
// blitter_dst_inc_y_r -
//-------------------------------------------------
uint16_t st_state::blitter_dst_inc_y_r()
{
return m_blitter_dst_inc_y;
}
//-------------------------------------------------
// blitter_dst_r -
//-------------------------------------------------
uint16_t st_state::blitter_dst_r(offs_t offset)
{
switch (offset)
{
case 0:
return (m_blitter_dst >> 16) & 0xff;
case 1:
return m_blitter_dst & 0xfffe;
}
return 0;
}
//-------------------------------------------------
// blitter_count_x_r -
//-------------------------------------------------
uint16_t st_state::blitter_count_x_r()
{
return m_blitter_xcount;
}
//-------------------------------------------------
// blitter_count_y_r -
//-------------------------------------------------
uint16_t st_state::blitter_count_y_r()
{
return m_blitter_ycount;
}
//-------------------------------------------------
// blitter_op_r -
//-------------------------------------------------
uint16_t st_state::blitter_op_r(offs_t offset, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
{
return m_blitter_hop;
}
else
{
return m_blitter_op;
}
}
//-------------------------------------------------
// blitter_ctrl_r -
//-------------------------------------------------
uint16_t st_state::blitter_ctrl_r(offs_t offset, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
{
return m_blitter_ctrl;
}
else
{
return m_blitter_skew;
}
}
//-------------------------------------------------
// blitter_halftone_w -
//-------------------------------------------------
void st_state::blitter_halftone_w(offs_t offset, uint16_t data)
{
m_blitter_halftone[offset] = data;
}
//-------------------------------------------------
// blitter_src_inc_x_w -
//-------------------------------------------------
void st_state::blitter_src_inc_x_w(uint16_t data)
{
m_blitter_src_inc_x = data & 0xfffe;
}
//-------------------------------------------------
// blitter_src_inc_y_w -
//-------------------------------------------------
void st_state::blitter_src_inc_y_w(uint16_t data)
{
m_blitter_src_inc_y = data & 0xfffe;
}
//-------------------------------------------------
// blitter_src_w -
//-------------------------------------------------
void st_state::blitter_src_w(offs_t offset, uint16_t data)
{
switch (offset)
{
case 0:
m_blitter_src = (data & 0xff) | (m_blitter_src & 0xfffe);
break;
case 1:
m_blitter_src = (m_blitter_src & 0xff0000) | (data & 0xfffe);
break;
}
}
//-------------------------------------------------
// blitter_end_mask_w -
//-------------------------------------------------
void st_state::blitter_end_mask_w(offs_t offset, uint16_t data)
{
switch (offset)
{
case 0:
m_blitter_endmask1 = data;
break;
case 1:
m_blitter_endmask2 = data;
break;
case 2:
m_blitter_endmask3 = data;
break;
}
}
//-------------------------------------------------
// blitter_dst_inc_x_w -
//-------------------------------------------------
void st_state::blitter_dst_inc_x_w(uint16_t data)
{
m_blitter_dst_inc_x = data & 0xfffe;
}
//-------------------------------------------------
// blitter_dst_inc_y_w -
//-------------------------------------------------
void st_state::blitter_dst_inc_y_w(uint16_t data)
{
m_blitter_dst_inc_y = data & 0xfffe;
}
//-------------------------------------------------
// blitter_dst_w -
//-------------------------------------------------
void st_state::blitter_dst_w(offs_t offset, uint16_t data)
{
switch (offset)
{
case 0:
m_blitter_dst = (data & 0xff) | (m_blitter_dst & 0xfffe);
break;
case 1:
m_blitter_dst = (m_blitter_dst & 0xff0000) | (data & 0xfffe);
break;
}
}
//-------------------------------------------------
// blitter_count_x_w -
//-------------------------------------------------
void st_state::blitter_count_x_w(uint16_t data)
{
m_blitter_xcount = data;
}
//-------------------------------------------------
// blitter_count_y_w -
//-------------------------------------------------
void st_state::blitter_count_y_w(uint16_t data)
{
m_blitter_ycount = data;
}
//-------------------------------------------------
// blitter_op_w -
//-------------------------------------------------
void st_state::blitter_op_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
{
m_blitter_hop = (data >> 8) & 0x03;
}
else
{
m_blitter_op = data & 0x0f;
}
}
//-------------------------------------------------
// blitter_ctrl_w -
//-------------------------------------------------
void st_state::blitter_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
{
m_blitter_ctrl = (data >> 8) & 0xef;
if (!(m_blitter_ctrl & ATARIST_BLITTER_CTRL_BUSY))
{
if ((data >> 8) & ATARIST_BLITTER_CTRL_BUSY)
{
m_mfp->i3_w(1);
int nops = BLITTER_NOPS[m_blitter_op][m_blitter_hop]; // each NOP takes 4 cycles
timer_set(attotime::from_hz((Y2/4)/(4*nops)), TIMER_BLITTER_TICK);
}
}
}
else
{
m_blitter_skew = data & 0xcf;
}
}
//************************************************************************** //**************************************************************************
// VIDEO // VIDEO
//************************************************************************** //**************************************************************************
void st_state::video_start() st_video_device::st_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, device_palette_interface(mconfig, *this)
, device_video_interface(mconfig, *this, true)
, m_ram_space(*this, finder_base::DUMMY_TAG, 0)
, m_maincpu(*this, "^m68000") // FIXME: use callbacks instead
, m_de_callback(*this)
{ {
m_shifter_timer = timer_alloc(TIMER_SHIFTER_TICK); }
m_glue_timer = timer_alloc(TIMER_GLUE_TICK);
// m_shifter_timer->adjust(m_screen->time_until_pos(0), 0, attotime::from_hz(Y2/4)); // 125 ns st_video_device::st_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
m_glue_timer->adjust(m_screen->time_until_pos(0), 0, attotime::from_hz(Y2/16)); // 500 ns : st_video_device(mconfig, ST_VIDEO, tag, owner, clock)
{
}
m_screen->register_screen_bitmap(m_bitmap); ste_video_device::ste_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: st_video_device(mconfig, STE_VIDEO, tag, owner, clock)
{
}
/* register for state saving */
void st_video_device::device_resolve_objects()
{
m_de_callback.resolve_safe();
}
void st_video_device::device_start()
{
m_shifter_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st_video_device::shifter_tick), this));
m_glue_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st_video_device::glue_tick), this));
// m_shifter_timer->adjust(screen().time_until_pos(0), 0, clocks_to_attotime(4)); // 125 ns
m_glue_timer->adjust(screen().time_until_pos(0), 0, clocks_to_attotime(16)); // 500 ns
screen().register_screen_bitmap(m_bitmap);
// register for state saving
save_item(NAME(m_shifter_base)); save_item(NAME(m_shifter_base));
save_item(NAME(m_shifter_ofs)); save_item(NAME(m_shifter_ofs));
save_item(NAME(m_shifter_sync)); save_item(NAME(m_shifter_sync));
@ -1088,43 +643,30 @@ void st_state::video_start()
save_item(NAME(m_shifter_v)); save_item(NAME(m_shifter_v));
save_item(NAME(m_shifter_de)); save_item(NAME(m_shifter_de));
save_item(NAME(m_blitter_halftone)); m_shifter_base = 0;
save_item(NAME(m_blitter_src_inc_x)); m_shifter_ofs = 0;
save_item(NAME(m_blitter_src_inc_y)); m_shifter_mode = 0;
save_item(NAME(m_blitter_dst_inc_x));
save_item(NAME(m_blitter_dst_inc_y));
save_item(NAME(m_blitter_src));
save_item(NAME(m_blitter_dst));
save_item(NAME(m_blitter_endmask1));
save_item(NAME(m_blitter_endmask2));
save_item(NAME(m_blitter_endmask3));
save_item(NAME(m_blitter_xcount));
save_item(NAME(m_blitter_ycount));
save_item(NAME(m_blitter_xcountl));
save_item(NAME(m_blitter_hop));
save_item(NAME(m_blitter_op));
save_item(NAME(m_blitter_ctrl));
save_item(NAME(m_blitter_skew));
set_screen_parameters(); set_screen_parameters();
} }
void ste_video_device::device_start()
void ste_state::video_start()
{ {
st_state::video_start(); st_video_device::device_start();
// register for state saving // register for state saving
save_item(NAME(m_shifter_lineofs)); save_item(NAME(m_shifter_lineofs));
save_item(NAME(m_shifter_pixelofs)); save_item(NAME(m_shifter_pixelofs));
} }
void stbook_state::video_start()
void st_video_device::device_reset()
{ {
// TODO: reset glue chip
} }
uint32_t st_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) uint32_t st_video_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{ {
copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
return 0; return 0;

View File

@ -5,10 +5,6 @@
#pragma once #pragma once
// 32028400 also exists
#define Y2 32084988.0
#define Y2_NTSC 32042400.0
#define ATARIST_HBSTART_PAL 128*4 #define ATARIST_HBSTART_PAL 128*4
#define ATARIST_HBEND_PAL 0 #define ATARIST_HBEND_PAL 0
#define ATARIST_HBSTART_NTSC 127*4 #define ATARIST_HBSTART_NTSC 127*4
@ -33,11 +29,106 @@
#define ATARIST_VBDEND_NTSC 34 #define ATARIST_VBDEND_NTSC 34
#define ATARIST_VBDSTART_NTSC 234 #define ATARIST_VBDSTART_NTSC 234
#define ATARIST_BLITTER_SKEW_NFSR 0x40 class st_video_device : public device_t, public device_palette_interface, public device_video_interface
#define ATARIST_BLITTER_SKEW_FXSR 0x80 {
public:
st_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
#define ATARIST_BLITTER_CTRL_SMUDGE 0x20 template <typename T> void set_ram_space(T &&tag, int spacenum) { m_ram_space.set_tag(tag, spacenum); }
#define ATARIST_BLITTER_CTRL_HOG 0x40 auto de_callback() { return m_de_callback.bind(); }
#define ATARIST_BLITTER_CTRL_BUSY 0x80
uint8_t shifter_base_r(offs_t offset);
uint8_t shifter_counter_r(offs_t offset);
uint8_t shifter_sync_r();
uint16_t shifter_palette_r(offs_t offset);
uint8_t shifter_mode_r();
void shifter_base_w(offs_t offset, uint8_t data);
void shifter_sync_w(uint8_t data);
void shifter_palette_w(offs_t offset, uint16_t data);
void shifter_mode_w(uint8_t data);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
protected:
st_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual void device_reset() override;
virtual uint32_t palette_entries() const override { return 16; }
private:
inline pen_t shift_mode_0();
inline pen_t shift_mode_1();
inline pen_t shift_mode_2();
TIMER_CALLBACK_MEMBER(shifter_tick);
inline void shifter_load();
inline void draw_pixel(int x, int y, u32 pen);
TIMER_CALLBACK_MEMBER(glue_tick);
void set_screen_parameters();
required_address_space m_ram_space;
required_device<cpu_device> m_maincpu; // HACK
devcb_write_line m_de_callback;
bitmap_rgb32 m_bitmap;
// timers
emu_timer *m_glue_timer = nullptr;
emu_timer *m_shifter_timer = nullptr;
protected:
// shifter state
uint32_t m_shifter_base = 0U;
uint32_t m_shifter_ofs = 0U;
uint8_t m_shifter_sync = 0U;
uint8_t m_shifter_mode = 0U;
uint16_t m_shifter_palette[16]{};
uint16_t m_shifter_rr[4]{};
uint16_t m_shifter_ir[4]{};
int m_shifter_bitplane = 0;
int m_shifter_shift = 0;
int m_shifter_h = 0;
int m_shifter_v = 0;
int m_shifter_de = 0;
int m_shifter_x_start = 0;
int m_shifter_x_end = 0;
int m_shifter_y_start = 0;
int m_shifter_y_end = 0;
int m_shifter_hblank_start = 0;
int m_shifter_vblank_start = 0;
};
class ste_video_device : public st_video_device
{
public:
ste_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
uint8_t shifter_base_low_r();
void shifter_base_low_w(uint8_t data);
uint8_t shifter_counter_r(offs_t offset);
void shifter_counter_w(offs_t offset, uint8_t data);
void shifter_palette_w(offs_t offset, uint16_t data);
uint8_t shifter_lineofs_r();
void shifter_lineofs_w(uint8_t data);
uint8_t shifter_pixelofs_r();
void shifter_pixelofs_w(uint8_t data);
protected:
virtual void device_start() override;
virtual uint32_t palette_entries() const override { return 512; }
private:
// shifter state
uint8_t m_shifter_lineofs = 0U;
uint8_t m_shifter_pixelofs = 0U;
};
DECLARE_DEVICE_TYPE(ST_VIDEO, st_video_device)
DECLARE_DEVICE_TYPE(STE_VIDEO, ste_video_device)
//DECLARE_DEVICE_TYPE(STBOOK_VIDEO, stbook_video_device)
//DECLARE_DEVICE_TYPE(TT_VIDEO, tt_video_device)
#endif // MAME_VIDEO_ATARIST_H #endif // MAME_VIDEO_ATARIST_H