mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
atarist: Extract the MMU, will need STE memory map specialization
This commit is contained in:
parent
aebf6eddd8
commit
82814d3b50
@ -301,7 +301,7 @@ void m68000_device::device_reset()
|
||||
|
||||
void m68000_device::update_user_super()
|
||||
{
|
||||
if(m_sr & 0x2000) {
|
||||
if(m_sr & SR_S) {
|
||||
m_sp = 16;
|
||||
m_program = m_r_program;
|
||||
m_opcodes = m_r_opcodes;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "ataristb.h"
|
||||
#include "atarist_v.h"
|
||||
#include "stkbd.h"
|
||||
#include "stmmu.h"
|
||||
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "bus/generic/slot.h"
|
||||
@ -93,21 +94,6 @@ namespace {
|
||||
#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 };
|
||||
|
||||
class st_state : public driver_device
|
||||
@ -116,7 +102,9 @@ public:
|
||||
st_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, M68000_TAG),
|
||||
m_mainram(*this, "mainram", 0x400000, ENDIANNESS_BIG),
|
||||
m_ikbd(*this, "ikbd"),
|
||||
m_mmu(*this, "mmu"),
|
||||
m_stb(*this, "stb"),
|
||||
m_fdc(*this, WD1772_TAG),
|
||||
m_floppy(*this, WD1772_TAG ":%u", 0U),
|
||||
@ -124,7 +112,7 @@ public:
|
||||
m_acia(*this, {MC6850_0_TAG, MC6850_1_TAG}),
|
||||
m_centronics(*this, CENTRONICS_TAG),
|
||||
m_cart(*this, "cartslot"),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_ramcfg(*this, RAM_TAG),
|
||||
m_rs232(*this, RS232_TAG),
|
||||
m_ymsnd(*this, YM2149_TAG),
|
||||
m_config(*this, "config"),
|
||||
@ -139,7 +127,9 @@ public:
|
||||
|
||||
protected:
|
||||
required_device<m68000_device> m_maincpu;
|
||||
memory_share_creator<u16> m_mainram;
|
||||
required_device<st_kbd_device> m_ikbd;
|
||||
required_device<st_mmu_device> m_mmu;
|
||||
optional_device<st_blitter_device> m_stb;
|
||||
required_device<wd1772_device> m_fdc;
|
||||
required_device_array<floppy_connector, 2> m_floppy;
|
||||
@ -147,55 +137,17 @@ protected:
|
||||
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<ram_device> m_ramcfg;
|
||||
required_device<rs232_port_device> m_rs232;
|
||||
required_device<ym2149_device> m_ymsnd;
|
||||
optional_ioport m_config;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(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);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( fdc_drq_w );
|
||||
|
||||
void psg_pa_w(uint8_t data);
|
||||
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
@ -204,8 +156,9 @@ protected:
|
||||
|
||||
void common(machine_config &config);
|
||||
void cpu_space_map(address_map &map);
|
||||
void st_map(address_map &map);
|
||||
void megast_map(address_map &map);
|
||||
void st_super_map(address_map &map);
|
||||
void st_user_map(address_map &map);
|
||||
void megast_super_map(address_map &map);
|
||||
|
||||
uint16_t fpu_r();
|
||||
void fpu_w(uint16_t data);
|
||||
@ -280,7 +233,7 @@ public:
|
||||
void tt030(machine_config &config);
|
||||
void falcon(machine_config &config);
|
||||
void ste(machine_config &config);
|
||||
void ste_map(address_map &map);
|
||||
void ste_super_map(address_map &map);
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
};
|
||||
@ -297,7 +250,7 @@ public:
|
||||
|
||||
uint16_t m_cache = 0;
|
||||
void megaste(machine_config &config);
|
||||
void megaste_map(address_map &map);
|
||||
void megaste_super_map(address_map &map);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
@ -324,365 +277,6 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// FLOPPY
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// toggle_dma_fifo -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::toggle_dma_fifo()
|
||||
{
|
||||
if (LOG) logerror("Toggling DMA FIFO\n");
|
||||
|
||||
m_fdc_fifo_sel = !m_fdc_fifo_sel;
|
||||
m_fdc_fifo_index = 0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// flush_dma_fifo -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::flush_dma_fifo()
|
||||
{
|
||||
if (m_fdc_fifo_empty[m_fdc_fifo_sel]) return;
|
||||
|
||||
if (m_fdc_dmabytes)
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
uint16_t data = m_fdc_fifo[m_fdc_fifo_sel][i];
|
||||
|
||||
if (LOG) logerror("Flushing DMA FIFO %u data %04x to address %06x\n", m_fdc_fifo_sel, data, m_dma_base);
|
||||
|
||||
if (m_dma_base >= 8)
|
||||
program.write_word(m_dma_base, data);
|
||||
m_dma_base += 2;
|
||||
}
|
||||
m_fdc_dmabytes -= 16;
|
||||
if (!m_fdc_dmabytes)
|
||||
{
|
||||
m_fdc_sectors--;
|
||||
|
||||
if (m_fdc_sectors)
|
||||
m_fdc_dmabytes = DMA_SECTOR_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_dma_error = 0;
|
||||
|
||||
m_fdc_fifo_empty[m_fdc_fifo_sel] = 1;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// fill_dma_fifo -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::fill_dma_fifo()
|
||||
{
|
||||
if (m_fdc_dmabytes)
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
uint16_t data = program.read_word(m_dma_base);
|
||||
|
||||
if (LOG) logerror("Filling DMA FIFO %u with data %04x from memory address %06x\n", m_fdc_fifo_sel, data, m_dma_base);
|
||||
|
||||
m_fdc_fifo[m_fdc_fifo_sel][i] = data;
|
||||
m_dma_base += 2;
|
||||
}
|
||||
m_fdc_dmabytes -= 16;
|
||||
if (!m_fdc_dmabytes)
|
||||
{
|
||||
m_fdc_sectors--;
|
||||
|
||||
if (m_fdc_sectors)
|
||||
m_fdc_dmabytes = DMA_SECTOR_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_dma_error = 0;
|
||||
|
||||
m_fdc_fifo_empty[m_fdc_fifo_sel] = 0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// fdc_dma_transfer -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::fdc_dma_transfer()
|
||||
{
|
||||
if (m_fdc_mode & DMA_MODE_READ_WRITE)
|
||||
{
|
||||
uint16_t data = m_fdc_fifo[m_fdc_fifo_sel][m_fdc_fifo_index];
|
||||
|
||||
if (m_fdc_fifo_msb)
|
||||
{
|
||||
// write LSB to disk
|
||||
m_fdc->data_w(data & 0xff);
|
||||
|
||||
if (LOG) logerror("DMA Write to FDC %02x\n", data & 0xff);
|
||||
|
||||
m_fdc_fifo_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// write MSB to disk
|
||||
m_fdc->data_w(data >> 8);
|
||||
|
||||
if (LOG) logerror("DMA Write to FDC %02x\n", data >> 8);
|
||||
}
|
||||
|
||||
// toggle MSB/LSB
|
||||
m_fdc_fifo_msb = !m_fdc_fifo_msb;
|
||||
|
||||
if (m_fdc_fifo_index == 8)
|
||||
{
|
||||
m_fdc_fifo_index--;
|
||||
m_fdc_fifo_empty[m_fdc_fifo_sel] = 1;
|
||||
|
||||
toggle_dma_fifo();
|
||||
|
||||
if (m_fdc_fifo_empty[m_fdc_fifo_sel])
|
||||
{
|
||||
fill_dma_fifo();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// read from controller to FIFO
|
||||
uint8_t data = m_fdc->data_r();
|
||||
|
||||
m_fdc_fifo_empty[m_fdc_fifo_sel] = 0;
|
||||
|
||||
if (LOG) logerror("DMA Read from FDC %02x\n", data);
|
||||
|
||||
if (m_fdc_fifo_msb)
|
||||
{
|
||||
// write MSB to FIFO
|
||||
m_fdc_fifo[m_fdc_fifo_sel][m_fdc_fifo_index] |= data;
|
||||
m_fdc_fifo_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// write LSB to FIFO
|
||||
m_fdc_fifo[m_fdc_fifo_sel][m_fdc_fifo_index] = data << 8;
|
||||
}
|
||||
|
||||
// toggle MSB/LSB
|
||||
m_fdc_fifo_msb = !m_fdc_fifo_msb;
|
||||
|
||||
if (m_fdc_fifo_index == 8)
|
||||
{
|
||||
flush_dma_fifo();
|
||||
toggle_dma_fifo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// fdc_data_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
uint16_t st_state::fdc_data_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
if (m_fdc_mode & DMA_MODE_SECTOR_COUNT)
|
||||
{
|
||||
if (LOG) logerror("Indeterminate DMA Sector Count Read!\n");
|
||||
|
||||
// sector count register is write only, reading it returns unpredictable values
|
||||
data = machine().rand() & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(m_fdc_mode & DMA_MODE_FDC_HDC_CS))
|
||||
{
|
||||
// floppy controller
|
||||
offs_t offset = (m_fdc_mode & DMA_MODE_ADDRESS_MASK) >> 1;
|
||||
|
||||
data = m_fdc->read(offset);
|
||||
|
||||
if (LOG) logerror("FDC Register %u Read %02x\n", offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// fdc_data_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::fdc_data_w(offs_t offset, uint16_t data)
|
||||
{
|
||||
if (m_fdc_mode & DMA_MODE_SECTOR_COUNT)
|
||||
{
|
||||
if (LOG) logerror("DMA Sector Count %u\n", data);
|
||||
|
||||
// sector count register
|
||||
m_fdc_sectors = data;
|
||||
|
||||
if (m_fdc_sectors)
|
||||
{
|
||||
m_fdc_dmabytes = DMA_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
if (m_fdc_mode & DMA_MODE_READ_WRITE)
|
||||
{
|
||||
// fill both FIFOs with data
|
||||
fill_dma_fifo();
|
||||
toggle_dma_fifo();
|
||||
fill_dma_fifo();
|
||||
toggle_dma_fifo();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(m_fdc_mode & DMA_MODE_FDC_HDC_CS))
|
||||
{
|
||||
// floppy controller
|
||||
offs_t offset = (m_fdc_mode & DMA_MODE_ADDRESS_MASK) >> 1;
|
||||
|
||||
if (LOG) logerror("FDC Register %u Write %02x\n", offset, data);
|
||||
|
||||
m_fdc->write(offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// dma_status_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
uint16_t st_state::dma_status_r()
|
||||
{
|
||||
uint16_t data = 0;
|
||||
|
||||
// DMA error
|
||||
data |= m_dma_error;
|
||||
|
||||
// sector count null
|
||||
data |= !(m_fdc_sectors == 0) << 1;
|
||||
|
||||
// DRQ state
|
||||
data |= m_fdc->drq_r() << 2;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// dma_mode_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::dma_mode_w(uint16_t data)
|
||||
{
|
||||
if (LOG) logerror("DMA Mode %04x\n", data);
|
||||
|
||||
if ((data & DMA_MODE_READ_WRITE) != (m_fdc_mode & DMA_MODE_READ_WRITE))
|
||||
{
|
||||
if (LOG) logerror("DMA reset\n");
|
||||
|
||||
m_dma_error = 1;
|
||||
m_fdc_sectors = 0;
|
||||
m_fdc_fifo_sel = 0;
|
||||
m_fdc_fifo_msb = 0;
|
||||
m_fdc_fifo_index = 0;
|
||||
}
|
||||
|
||||
m_fdc_mode = data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// dma_counter_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
uint8_t st_state::dma_counter_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
data = (m_dma_base >> 16) & 0xff;
|
||||
break;
|
||||
case 1:
|
||||
data = (m_dma_base >> 8) & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
data = m_dma_base & 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// dma_base_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::dma_base_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
m_dma_base = (m_dma_base & 0x00ffff) | (data << 16);
|
||||
if (LOG) logerror("DMA Address High %02x (%06x)\n", data & 0xff, m_dma_base);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_dma_base = (m_dma_base & 0xff00ff) | (data << 8);
|
||||
if (LOG) logerror("DMA Address Mid %02x (%06x)\n", data & 0xff, m_dma_base);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_dma_base = (m_dma_base & 0xffff00) | data;
|
||||
if (LOG) logerror("DMA Address Low %02x (%06x)\n", data & 0xff, m_dma_base);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MMU
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// mmu_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
uint8_t st_state::mmu_r()
|
||||
{
|
||||
return m_mmu;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mmu_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::mmu_w(uint8_t data)
|
||||
{
|
||||
if (LOG) logerror("Memory Configuration Register: %02x\n", data);
|
||||
|
||||
m_mmu = data;
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// FPU
|
||||
//**************************************************************************
|
||||
@ -762,11 +356,9 @@ TIMER_CALLBACK_MEMBER(ste_state::dmasound_tick)
|
||||
{
|
||||
if (m_dmasnd_samples == 0)
|
||||
{
|
||||
uint8_t *RAM = m_ram->pointer();
|
||||
|
||||
for (auto & elem : m_dmasnd_fifo)
|
||||
{
|
||||
elem = RAM[m_dmasnd_cntr];
|
||||
elem = m_mainram[m_dmasnd_cntr];
|
||||
m_dmasnd_cntr++;
|
||||
m_dmasnd_samples++;
|
||||
|
||||
@ -1198,55 +790,61 @@ void st_state::cpu_space_map(address_map &map)
|
||||
// ADDRESS_MAP( st_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::st_map(address_map &map)
|
||||
void st_state::st_super_map(address_map &map)
|
||||
{
|
||||
// Ram mapped by the mmu
|
||||
map.unmap_value_high();
|
||||
map(0x000000, 0x000007).rom().region(M68000_TAG, 0).w(m_maincpu, FUNC(m68000_device::berr_w));
|
||||
map(0x000008, 0x1fffff).ram();
|
||||
map(0x200000, 0x3fffff).ram();
|
||||
map(0x400000, 0xf9ffff).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w));
|
||||
//map(0xfa0000, 0xfbffff) // mapped by the cartslot
|
||||
map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0).w(m_maincpu, FUNC(m68000_device::berr_w));
|
||||
map(0xff8001, 0xff8001).rw(FUNC(st_state::mmu_r), FUNC(st_state::mmu_w));
|
||||
map(0xff8000, 0xff8fff).m(m_mmu, FUNC(st_mmu_device::map));
|
||||
|
||||
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(m_video, FUNC(st_video_device::shifter_counter_r)).umask16(0x00ff);
|
||||
map(0xff820a, 0xff820a).rw(m_video, FUNC(st_video_device::shifter_sync_r), FUNC(st_video_device::shifter_sync_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(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(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(0xff8800, 0xff8800).rw(YM2149_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)).mirror(0xfc);
|
||||
map(0xff8802, 0xff8802).rw(YM2149_TAG, FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w)).mirror(0xfc);
|
||||
|
||||
// no blitter on original ST
|
||||
|
||||
map(0xfffa00, 0xfffa3f).rw(m_mfp, FUNC(mc68901_device::read), FUNC(mc68901_device::write)).umask16(0x00ff);
|
||||
map(0xfffc00, 0xfffc03).rw(m_acia[0], FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0xff00);
|
||||
map(0xfffc04, 0xfffc07).rw(m_acia[1], FUNC(acia6850_device::read), FUNC(acia6850_device::write)).umask16(0xff00);
|
||||
}
|
||||
|
||||
void st_state::st_user_map(address_map &map)
|
||||
{
|
||||
// Ram mapped by the mmu
|
||||
map.unmap_value_high();
|
||||
map(0x000000, 0x0007ff).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w));
|
||||
map(0x400000, 0xfbffff).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w));
|
||||
map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0).w(m_maincpu, FUNC(m68000_device::berr_w));
|
||||
map(0xff0000, 0xffffff).rw(m_maincpu, FUNC(m68000_device::berr_r), FUNC(m68000_device::berr_w));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ADDRESS_MAP( megast_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::megast_map(address_map &map)
|
||||
void st_state::megast_super_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x000000, 0x3fffff).ram().share(m_mainram);
|
||||
map(0x000000, 0x000007).rom().region(M68000_TAG, 0);
|
||||
map(0x000008, 0x1fffff).ram();
|
||||
map(0x200000, 0x3fffff).ram();
|
||||
//map(0xfa0000, 0xfbffff) // mapped by the cartslot
|
||||
map(0xfc0000, 0xfeffff).rom().region(M68000_TAG, 0);
|
||||
// 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(0xff8000, 0xff8fff).m(m_mmu, FUNC(st_mmu_device::map));
|
||||
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(m_video, FUNC(st_video_device::shifter_counter_r)).umask16(0x00ff);
|
||||
map(0xff820a, 0xff820a).rw(m_video, FUNC(st_video_device::shifter_sync_r), FUNC(st_video_device::shifter_sync_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(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(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(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(0xff8a00, 0xff8a1f).rw(m_stb, FUNC(st_blitter_device::halftone_r), FUNC(st_blitter_device::halftone_w));
|
||||
@ -1273,9 +871,9 @@ void st_state::megast_map(address_map &map)
|
||||
// ADDRESS_MAP( ste_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
void ste_state::ste_map(address_map &map)
|
||||
void ste_state::ste_super_map(address_map &map)
|
||||
{
|
||||
st_map(map);
|
||||
st_super_map(map);
|
||||
map(0xe00000, 0xe3ffff).rom().region(M68000_TAG, 0);
|
||||
map(0xff8901, 0xff8901).rw(FUNC(ste_state::sound_dma_control_r), FUNC(ste_state::sound_dma_control_w));
|
||||
map(0xff8902, 0xff8907).rw(FUNC(ste_state::sound_dma_base_r), FUNC(ste_state::sound_dma_base_w)).umask16(0x00ff);
|
||||
@ -1311,9 +909,9 @@ void ste_state::ste_map(address_map &map)
|
||||
// ADDRESS_MAP( megaste_map )
|
||||
//-------------------------------------------------
|
||||
|
||||
void megaste_state::megaste_map(address_map &map)
|
||||
void megaste_state::megaste_super_map(address_map &map)
|
||||
{
|
||||
megast_map(map);
|
||||
megast_super_map(map);
|
||||
map(0xe00000, 0xe3ffff).rom().region(M68000_TAG, 0);
|
||||
map(0xff8c80, 0xff8c87).rw(Z8530_TAG, FUNC(scc8530_legacy_device::reg_r), FUNC(scc8530_legacy_device::reg_w)).umask16(0x00ff);
|
||||
map(0xff8901, 0xff8901).rw(FUNC(megaste_state::sound_dma_control_r), FUNC(megaste_state::sound_dma_control_w));
|
||||
@ -1332,8 +930,7 @@ void megaste_state::megaste_map(address_map &map)
|
||||
#if 0
|
||||
void stbook_state::stbook_map(address_map &map)
|
||||
{
|
||||
map(0x000000, 0x1fffff).ram();
|
||||
map(0x200000, 0x3fffff).ram();
|
||||
map(0x000000, 0x3fffff).ram().share(m_mainram);
|
||||
// map(0xd40000, 0xd7ffff).rom();
|
||||
map(0xe00000, 0xe3ffff).rom().region(M68000_TAG, 0);
|
||||
// map(0xe80000, 0xebffff).rom();
|
||||
@ -1586,76 +1183,21 @@ void stbook_state::psg_pa_w(uint8_t data)
|
||||
m_fdc->dden_w(BIT(data, 7));
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( st_state::fdc_drq_w )
|
||||
{
|
||||
if (state && (!(m_fdc_mode & DMA_MODE_ENABLED)) && (m_fdc_mode & DMA_MODE_FDC_HDC_ACK))
|
||||
fdc_dma_transfer();
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACHINE INITIALIZATION
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// configure_memory -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::configure_memory()
|
||||
{
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
|
||||
switch (m_ram->size())
|
||||
{
|
||||
case 256 * 1024:
|
||||
program.unmap_readwrite(0x040000, 0x3fffff);
|
||||
break;
|
||||
|
||||
case 512 * 1024:
|
||||
program.unmap_readwrite(0x080000, 0x3fffff);
|
||||
break;
|
||||
|
||||
case 1024 * 1024:
|
||||
program.unmap_readwrite(0x100000, 0x3fffff);
|
||||
break;
|
||||
|
||||
case 2048 * 1024:
|
||||
program.unmap_readwrite(0x200000, 0x3fffff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_save -
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::state_save()
|
||||
{
|
||||
m_dma_error = 1;
|
||||
|
||||
save_item(NAME(m_mmu));
|
||||
save_item(NAME(m_dma_base));
|
||||
save_item(NAME(m_dma_error));
|
||||
save_item(NAME(m_fdc_mode));
|
||||
save_item(NAME(m_fdc_sectors));
|
||||
save_item(NAME(m_fdc_dmabytes));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// MACHINE_START( st )
|
||||
//-------------------------------------------------
|
||||
|
||||
void st_state::machine_start()
|
||||
{
|
||||
// configure RAM banking
|
||||
configure_memory();
|
||||
m_mmu->set_ram_size(m_ramcfg->size());
|
||||
|
||||
if (m_cart->exists())
|
||||
m_maincpu->space(AS_PROGRAM).install_read_handler(0xfa0000, 0xfbffff, read16s_delegate(*m_cart, FUNC(generic_slot_device::read16_rom)));
|
||||
|
||||
// register for state saving
|
||||
state_save();
|
||||
|
||||
/// TODO: get callbacks to trigger these.
|
||||
m_mfp->i0_w(1);
|
||||
m_mfp->i4_w(1);
|
||||
@ -1670,8 +1212,6 @@ void st_state::machine_start()
|
||||
|
||||
void ste_state::state_save()
|
||||
{
|
||||
st_state::state_save();
|
||||
|
||||
save_item(NAME(m_dmasnd_base));
|
||||
save_item(NAME(m_dmasnd_end));
|
||||
save_item(NAME(m_dmasnd_cntr));
|
||||
@ -1694,8 +1234,7 @@ void ste_state::state_save()
|
||||
|
||||
void ste_state::machine_start()
|
||||
{
|
||||
/* configure RAM banking */
|
||||
configure_memory();
|
||||
m_mmu->set_ram_size(m_ramcfg->size());
|
||||
|
||||
if (m_cart->exists())
|
||||
m_maincpu->space(AS_PROGRAM).install_read_handler(0xfa0000, 0xfbffff, read16s_delegate(*m_cart, FUNC(generic_slot_device::read16_rom)));
|
||||
@ -1733,10 +1272,10 @@ void megaste_state::machine_start()
|
||||
|
||||
void stbook_state::machine_start()
|
||||
{
|
||||
/* configure RAM banking */
|
||||
/* configure RAM size */
|
||||
address_space &program = m_maincpu->space(AS_PROGRAM);
|
||||
|
||||
switch (m_ram->size())
|
||||
switch (m_ramcfg->size())
|
||||
{
|
||||
case 1024 * 1024:
|
||||
program.unmap_readwrite(0x100000, 0x3fffff);
|
||||
@ -1780,8 +1319,14 @@ void st_state::common(machine_config &config)
|
||||
// basic machine hardware
|
||||
M68000(config, m_maincpu, Y2/4);
|
||||
m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &st_state::cpu_space_map);
|
||||
m_maincpu->set_addrmap(m68000_base_device::AS_USER_PROGRAM, &st_state::st_user_map);
|
||||
m_maincpu->reset_cb().set(FUNC(st_state::reset_w));
|
||||
|
||||
ST_MMU(config, m_mmu);
|
||||
m_mmu->set_ram(m_mainram);
|
||||
m_mmu->set_cpu(m_maincpu);
|
||||
m_mmu->set_fdc(m_fdc);
|
||||
|
||||
// sound
|
||||
YM2149(config, m_ymsnd, Y2/16);
|
||||
m_ymsnd->set_flags(AY8910_SINGLE_OUTPUT);
|
||||
@ -1792,7 +1337,7 @@ void st_state::common(machine_config &config)
|
||||
// devices
|
||||
WD1772(config, m_fdc, Y2/4);
|
||||
m_fdc->intrq_wr_callback().set(m_mfp, FUNC(mc68901_device::i5_w)).invert();
|
||||
m_fdc->drq_wr_callback().set(FUNC(st_state::fdc_drq_w));
|
||||
m_fdc->drq_wr_callback().set(m_mmu, FUNC(st_mmu_device::fdc_drq_w));
|
||||
FLOPPY_CONNECTOR(config, WD1772_TAG ":0", atari_floppies, "35dd", st_state::floppy_formats);
|
||||
FLOPPY_CONNECTOR(config, WD1772_TAG ":1", atari_floppies, nullptr, st_state::floppy_formats);
|
||||
|
||||
@ -1861,7 +1406,7 @@ void st_state::st(machine_config &config)
|
||||
common(config);
|
||||
|
||||
// basic machine hardware
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &st_state::st_map);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &st_state::st_super_map);
|
||||
|
||||
// video hardware
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
@ -1878,9 +1423,9 @@ void st_state::st(machine_config &config)
|
||||
m_ymsnd->add_route(ALL_OUTPUTS, "mono", 1.00);
|
||||
|
||||
// internal ram
|
||||
RAM(config, m_ram);
|
||||
m_ram->set_default_size("1M"); // 1040ST
|
||||
m_ram->set_extra_options("512K,256K"); // 520ST, 260ST
|
||||
RAM(config, m_ramcfg);
|
||||
m_ramcfg->set_default_size("1M"); // 1040ST
|
||||
m_ramcfg->set_extra_options("512K,256K"); // 520ST, 260ST
|
||||
}
|
||||
|
||||
|
||||
@ -1893,7 +1438,7 @@ void megast_state::megast(machine_config &config)
|
||||
common(config);
|
||||
|
||||
// basic machine hardware
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &megast_state::megast_map);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &megast_state::megast_super_map);
|
||||
|
||||
ST_BLITTER(config, m_stb, Y2/4);
|
||||
m_stb->set_space(m_maincpu, AS_PROGRAM);
|
||||
@ -1917,9 +1462,9 @@ void megast_state::megast(machine_config &config)
|
||||
RP5C15(config, RP5C15_TAG, XTAL(32'768));
|
||||
|
||||
// internal ram
|
||||
RAM(config, m_ram);
|
||||
m_ram->set_default_size("4M"); // Mega ST 4
|
||||
m_ram->set_extra_options("2M,1M"); // Mega ST 2, Mega ST 1
|
||||
RAM(config, m_ramcfg);
|
||||
m_ramcfg->set_default_size("4M"); // Mega ST 4
|
||||
m_ramcfg->set_extra_options("2M,1M"); // Mega ST 2, Mega ST 1
|
||||
}
|
||||
|
||||
|
||||
@ -1932,7 +1477,7 @@ void ste_state::ste(machine_config &config)
|
||||
common(config);
|
||||
|
||||
// basic machine hardware
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &ste_state::ste_map);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &ste_state::ste_super_map);
|
||||
|
||||
ST_BLITTER(config, m_stb, Y2/4);
|
||||
m_stb->set_space(m_maincpu, AS_PROGRAM);
|
||||
@ -1961,9 +1506,9 @@ void ste_state::ste(machine_config &config)
|
||||
LMC1992(config, LMC1992_TAG);
|
||||
|
||||
// internal ram
|
||||
RAM(config, m_ram);
|
||||
m_ram->set_default_size("1M"); // 1040STe
|
||||
m_ram->set_extra_options("512K"); // 520STe
|
||||
RAM(config, m_ramcfg);
|
||||
m_ramcfg->set_default_size("1M"); // 1040STe
|
||||
m_ramcfg->set_extra_options("512K"); // 520STe
|
||||
}
|
||||
|
||||
|
||||
@ -1974,13 +1519,13 @@ void ste_state::ste(machine_config &config)
|
||||
void megaste_state::megaste(machine_config &config)
|
||||
{
|
||||
ste(config);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &megaste_state::megaste_map);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &megaste_state::megaste_super_map);
|
||||
RP5C15(config, RP5C15_TAG, XTAL(32'768));
|
||||
SCC8530(config, Z8530_TAG, Y2/4);
|
||||
|
||||
/* internal ram */
|
||||
m_ram->set_default_size("4M"); // Mega STe 4
|
||||
m_ram->set_extra_options("2M,1M"); // Mega STe 2, Mega STe 1
|
||||
m_ramcfg->set_default_size("4M"); // Mega STe 4
|
||||
m_ramcfg->set_extra_options("2M,1M"); // Mega STe 2, Mega STe 1
|
||||
}
|
||||
|
||||
|
||||
@ -2081,7 +1626,7 @@ void stbook_state::stbook(machine_config &config)
|
||||
SOFTWARE_LIST(config, "cart_list").set_original("st_cart");
|
||||
|
||||
/* internal ram */
|
||||
RAM(config, m_ram).set_default_size("4M").set_extra_options("1M");
|
||||
RAM(config, m_ramcfg).set_default_size("4M").set_extra_options("1M");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
501
src/mame/atari/stmmu.cpp
Normal file
501
src/mame/atari/stmmu.cpp
Normal file
@ -0,0 +1,501 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Curt Coder, Olivier Galibert
|
||||
|
||||
#include "emu.h"
|
||||
#include "stmmu.h"
|
||||
|
||||
#define LOG_MODE (1U << 1) // Shows mode
|
||||
#define LOG_PORT (1U << 2) // Shows direct data read/write
|
||||
#define LOG_DMA (1U << 3) // Shows dma address and sector count setup
|
||||
#define LOG_DATA (1U << 4) // Shows dma-ed data
|
||||
#define LOG_RAM (1U << 5) // Shows ram configuration
|
||||
|
||||
#define VERBOSE (LOG_RAM)
|
||||
|
||||
//#define VERBOSE (LOG_DESC | LOG_COMMAND | LOG_MATCH | LOG_WRITE | LOG_STATE | LOG_LINES | LOG_COMP | LOG_CRC )
|
||||
//#define LOG_OUTPUT_STREAM std::cout
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
#define LOGMODE(...) LOGMASKED(LOG_MODE, __VA_ARGS__)
|
||||
#define LOGPORT(...) LOGMASKED(LOG_PORT, __VA_ARGS__)
|
||||
#define LOGDMA(...) LOGMASKED(LOG_DMA, __VA_ARGS__)
|
||||
#define LOGDATA(...) LOGMASKED(LOG_DATA, __VA_ARGS__)
|
||||
#define LOGRAM(...) LOGMASKED(LOG_RAM, __VA_ARGS__)
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(ST_MMU, st_mmu_device, "st_mmu", "Atari ST MMU")
|
||||
|
||||
void st_mmu_device::map(address_map &map)
|
||||
{
|
||||
map(0x001, 0x001).rw(FUNC(st_mmu_device::memcfg_r), FUNC(st_mmu_device::memcfg_w));
|
||||
map(0x604, 0x605).rw(FUNC(st_mmu_device::data_r), FUNC(st_mmu_device::data_w));
|
||||
map(0x606, 0x607).rw(FUNC(st_mmu_device::dma_status_r), FUNC(st_mmu_device::dma_mode_w));
|
||||
map(0x609, 0x609).rw(FUNC(st_mmu_device::dma_address_h_r), FUNC(st_mmu_device::dma_address_h_w));
|
||||
map(0x60b, 0x60b).rw(FUNC(st_mmu_device::dma_address_m_r), FUNC(st_mmu_device::dma_address_m_w));
|
||||
map(0x60d, 0x60d).rw(FUNC(st_mmu_device::dma_address_l_r), FUNC(st_mmu_device::dma_address_l_w));
|
||||
}
|
||||
|
||||
st_mmu_device::st_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, ST_MMU, tag, owner, clock),
|
||||
m_ram(*this, finder_base::DUMMY_TAG),
|
||||
m_cpu(*this, finder_base::DUMMY_TAG),
|
||||
m_fdc(*this, finder_base::DUMMY_TAG)
|
||||
{
|
||||
m_ram_size = 0;
|
||||
}
|
||||
|
||||
void st_mmu_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_ram_size));
|
||||
save_item(NAME(m_dma_address));
|
||||
save_item(NAME(m_dma_mode));
|
||||
save_item(NAME(m_fifo));
|
||||
save_item(NAME(m_block_count));
|
||||
save_item(NAME(m_sector_count));
|
||||
save_item(NAME(m_fifo_index));
|
||||
save_item(NAME(m_memcfg));
|
||||
save_item(NAME(m_fdc_drq));
|
||||
save_item(NAME(m_hdc_drq));
|
||||
save_item(NAME(m_dma_no_error));
|
||||
}
|
||||
|
||||
void st_mmu_device::device_reset()
|
||||
{
|
||||
m_dma_address = 0;
|
||||
m_dma_mode = 0;
|
||||
memset(m_fifo, 0, sizeof(m_fifo));
|
||||
m_sector_count = 0;
|
||||
m_block_count = 0;
|
||||
m_fifo_index = 0;
|
||||
m_memcfg = 0;
|
||||
m_fdc_drq = false;
|
||||
m_hdc_drq = false;
|
||||
m_dma_no_error = true;
|
||||
configure_ram();
|
||||
}
|
||||
|
||||
void st_mmu_device::fdc_transfer()
|
||||
{
|
||||
if(m_dma_mode & MODE_READ_WRITE)
|
||||
m_fdc->data_w(fifo_pop());
|
||||
else
|
||||
fifo_push(m_fdc->data_r());
|
||||
}
|
||||
|
||||
void st_mmu_device::hdc_transfer()
|
||||
{
|
||||
logerror("hdc transfer unimplemented\n");
|
||||
}
|
||||
|
||||
void st_mmu_device::fdc_drq_w(int state)
|
||||
{
|
||||
if(state == m_fdc_drq)
|
||||
return;
|
||||
m_fdc_drq = state;
|
||||
while(m_fdc_drq && (m_dma_mode & MODE_FDC_HDC_ACK))
|
||||
fdc_transfer();
|
||||
}
|
||||
|
||||
void st_mmu_device::hdc_drq_w(int state)
|
||||
{
|
||||
if(state == m_hdc_drq)
|
||||
return;
|
||||
m_hdc_drq = state;
|
||||
while(m_hdc_drq && !(m_dma_mode & MODE_FDC_HDC_ACK))
|
||||
hdc_transfer();
|
||||
}
|
||||
|
||||
uint16_t st_mmu_device::data_r()
|
||||
{
|
||||
if(m_dma_mode & MODE_SECTOR_COUNT)
|
||||
// Sector count is not readable
|
||||
return 0x55;
|
||||
|
||||
else if(m_dma_mode & MODE_FDC_HDC_CS) {
|
||||
u8 r = 0x00;
|
||||
LOGPORT("hdc_r %02x\n", r);
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
u8 r = m_fdc->read((m_dma_mode >> 1) & 3);
|
||||
LOGPORT("fdc_r %02x\n", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
void st_mmu_device::data_w(uint16_t data)
|
||||
{
|
||||
data &= 0xff;
|
||||
if(m_dma_mode & MODE_SECTOR_COUNT) {
|
||||
LOGDMA("sector_count_w %02x\n", data);
|
||||
m_sector_count = data;
|
||||
if(data == 0)
|
||||
m_dma_no_error = false;
|
||||
else if(m_dma_mode & MODE_READ_WRITE)
|
||||
fifo_schedule_block_transfer_from_ram();
|
||||
|
||||
} else if(m_dma_mode & MODE_FDC_HDC_CS) {
|
||||
LOGPORT("hdc_w %02x\n", data);
|
||||
|
||||
} else {
|
||||
LOGPORT("fdc_w %d, %02x\n", (m_dma_mode >> 1) & 3, data);
|
||||
m_fdc->write((m_dma_mode >> 1) & 3, data);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t st_mmu_device::dma_status_r()
|
||||
{
|
||||
return (m_dma_no_error ? 1 : 0) | (m_sector_count ? 2 : 0) | (m_fdc_drq ? 4 : 0);
|
||||
}
|
||||
|
||||
void st_mmu_device::dma_mode_w(uint16_t data)
|
||||
{
|
||||
if((m_dma_mode ^ data) & MODE_READ_WRITE)
|
||||
fifo_flush();
|
||||
|
||||
m_dma_mode = data;
|
||||
LOGMODE("mode %04x %c%c%c%c%c%d\n", m_dma_mode,
|
||||
m_dma_mode & MODE_READ_WRITE ? 'w' : 'r',
|
||||
m_dma_mode & MODE_FDC_HDC_ACK ? 'f' : 'h',
|
||||
m_dma_mode & MODE_ENABLED ? '+' : '-',
|
||||
m_dma_mode & MODE_SECTOR_COUNT ? 'C' : '.',
|
||||
m_dma_mode & MODE_FDC_HDC_CS ? 'h' : 'f',
|
||||
(m_dma_mode >> 1) & 3);
|
||||
|
||||
while(m_fdc_drq && (m_dma_mode & MODE_FDC_HDC_ACK))
|
||||
fdc_transfer();
|
||||
while(m_hdc_drq && !(m_dma_mode & MODE_FDC_HDC_ACK))
|
||||
hdc_transfer();
|
||||
}
|
||||
|
||||
uint8_t st_mmu_device::dma_address_h_r()
|
||||
{
|
||||
return m_dma_address >> 16;
|
||||
}
|
||||
|
||||
uint8_t st_mmu_device::dma_address_m_r()
|
||||
{
|
||||
return m_dma_address >> 8;
|
||||
}
|
||||
|
||||
uint8_t st_mmu_device::dma_address_l_r()
|
||||
{
|
||||
return m_dma_address;
|
||||
}
|
||||
|
||||
void st_mmu_device::dma_address_h_w(uint8_t data)
|
||||
{
|
||||
m_dma_address = (m_dma_address & 0x00ffff) | (data << 16);
|
||||
LOGDMA("dma address %06x\n", m_dma_address);
|
||||
}
|
||||
|
||||
void st_mmu_device::dma_address_m_w(uint8_t data)
|
||||
{
|
||||
m_dma_address = (m_dma_address & 0xff00ff) | (data << 8);
|
||||
}
|
||||
|
||||
void st_mmu_device::dma_address_l_w(uint8_t data)
|
||||
{
|
||||
m_dma_address = (m_dma_address & 0xffff00) | data;
|
||||
}
|
||||
|
||||
|
||||
void st_mmu_device::fifo_flush()
|
||||
{
|
||||
m_fifo_index = 0;
|
||||
m_sector_count = 0;
|
||||
m_block_count = 0;
|
||||
m_dma_no_error = true;
|
||||
}
|
||||
|
||||
void st_mmu_device::fifo_push(u8 data)
|
||||
{
|
||||
if(m_fifo_index == 32 || !m_sector_count) {
|
||||
m_dma_no_error = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = m_fifo_index >> 1;
|
||||
if(m_fifo_index & 1)
|
||||
m_fifo[idx] = data | (m_fifo[idx] & 0xff00);
|
||||
else
|
||||
m_fifo[idx] = (data << 8) | (m_fifo[idx] & 0x00ff);
|
||||
m_fifo_index ++;
|
||||
if(m_fifo_index == 16)
|
||||
fifo_schedule_block_transfer_to_ram();
|
||||
}
|
||||
|
||||
u8 st_mmu_device::fifo_pop()
|
||||
{
|
||||
if(m_fifo_index == 32) {
|
||||
m_dma_no_error = false;
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
int idx = m_fifo_index >> 1;
|
||||
u8 r;
|
||||
if(m_fifo_index & 1)
|
||||
r = m_fifo[idx];
|
||||
else
|
||||
r = m_fifo[idx] >> 8;
|
||||
m_fifo_index ++;
|
||||
if(m_fifo_index == 16)
|
||||
fifo_schedule_block_transfer_from_ram();
|
||||
return r;
|
||||
}
|
||||
|
||||
void st_mmu_device::fifo_schedule_block_transfer_to_ram()
|
||||
{
|
||||
if(VERBOSE & LOG_DATA) {
|
||||
std::string l = util::string_format("r %06x =", m_dma_address);
|
||||
for(int i = 0; i != 8; i++)
|
||||
l += util::string_format(" %04x", m_fifo[i]);
|
||||
logerror("%s\n", l);
|
||||
}
|
||||
|
||||
// Synchronous for now
|
||||
for(int i=0; i != 8; i++) {
|
||||
m_ram[(m_dma_address & 0x3ffffe) >> 1] = m_fifo[i];
|
||||
m_dma_address += 2;
|
||||
}
|
||||
memcpy(m_fifo, m_fifo + 8, 8*2);
|
||||
m_fifo_index -= 16;
|
||||
m_block_count ++;
|
||||
if(m_block_count == 32) {
|
||||
m_block_count = 0;
|
||||
m_sector_count --;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void st_mmu_device::fifo_schedule_block_transfer_from_ram()
|
||||
{
|
||||
if(!m_sector_count)
|
||||
return;
|
||||
|
||||
// Synchronous for now
|
||||
if(m_fifo_index == 0) {
|
||||
int limit = m_sector_count > 1 || m_block_count != 31 ? 16 : 8;
|
||||
for(int i=0; i != limit; i++) {
|
||||
m_fifo[i] = m_ram[(m_dma_address & 0x3ffffe) >> 1];
|
||||
m_dma_address += 2;
|
||||
}
|
||||
m_block_count += limit == 16 ? 2 : 1;
|
||||
if(VERBOSE & LOG_DATA) {
|
||||
std::string l = util::string_format("w %06x =", m_dma_address-2*limit);
|
||||
for(int i = 0; i != 8; i++)
|
||||
l += util::string_format(" %04x", m_fifo[i]);
|
||||
logerror("%s\n", l);
|
||||
if(limit == 16) {
|
||||
std::string l = util::string_format("w %06x =", m_dma_address-16);
|
||||
for(int i = 0; i != 8; i++)
|
||||
l += util::string_format(" %04x", m_fifo[i+8]);
|
||||
logerror("%s\n", l);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
memcpy(m_fifo, m_fifo + 8, 8*2);
|
||||
for(int i=0; i != 8; i++) {
|
||||
m_fifo[8 + i] = m_ram[(m_dma_address & 0x3ffffe) >> 1];
|
||||
m_dma_address += 2;
|
||||
}
|
||||
m_block_count ++;
|
||||
m_fifo_index -= 16;
|
||||
if(VERBOSE & LOG_DATA) {
|
||||
std::string l = util::string_format("w %06x =", m_dma_address-16);
|
||||
for(int i = 0; i != 8; i++)
|
||||
l += util::string_format(" %04x", m_fifo[i+8]);
|
||||
logerror("%s\n", l);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_block_count == 32) {
|
||||
m_block_count = 0;
|
||||
m_sector_count --;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t st_mmu_device::memcfg_r()
|
||||
{
|
||||
return m_memcfg;
|
||||
}
|
||||
|
||||
void st_mmu_device::memcfg_w(uint8_t data)
|
||||
{
|
||||
m_memcfg = data;
|
||||
configure_ram();
|
||||
}
|
||||
|
||||
void st_mmu_device::set_ram_size(u32 size)
|
||||
{
|
||||
m_ram_size = size;
|
||||
}
|
||||
|
||||
// Install a bank of real size (in K) actual and configured size
|
||||
// config, in memory map at address adr, in memory block at offset
|
||||
// radr, skipping off_s bytes at the start in supervisor mode and
|
||||
// off_u in user mode.
|
||||
|
||||
// In the ST (non-e), the address is split into a column and row of 7
|
||||
// to 9 bits (128K to 2M). Smaller chips just do not have the top
|
||||
// column and row bits. The address is split in the middle, with
|
||||
// column in the high bits and row in the low. As a result a mismatch
|
||||
// between configuration and actual chip size requires breaking up and
|
||||
// rebuilding the address.
|
||||
|
||||
// In the STE it's the same but the column and row bits are
|
||||
// interleaved, ensuring a linear behaviour at all times.
|
||||
|
||||
offs_t st_mmu_device::remap_128_512(offs_t offset)
|
||||
{
|
||||
return (offset & 0xff) | ((offset & 0xff00) << 1);
|
||||
}
|
||||
|
||||
offs_t st_mmu_device::remap_128_2048(offs_t offset)
|
||||
{
|
||||
return (offset & 0xff) | ((offset & 0xff00) << 2);
|
||||
}
|
||||
|
||||
offs_t st_mmu_device::remap_512_128(offs_t offset)
|
||||
{
|
||||
return (offset & 0xff) | ((offset & 0x1fe00) >> 1);
|
||||
}
|
||||
|
||||
offs_t st_mmu_device::remap_512_2048(offs_t offset)
|
||||
{
|
||||
return (offset & 0x1ff) | ((offset & 0x3fe00) << 1);
|
||||
}
|
||||
|
||||
offs_t st_mmu_device::remap_2048_128(offs_t offset)
|
||||
{
|
||||
return (offset & 0xff) | ((offset & 0x1fc00) >> 2);
|
||||
}
|
||||
|
||||
offs_t st_mmu_device::remap_2048_512(offs_t offset)
|
||||
{
|
||||
return (offset & 0x1ff) | ((offset & 0x7fc00) >> 1);
|
||||
}
|
||||
|
||||
void st_mmu_device::ram_mapping(u32 actual, u32 config, u32 adr, u32 radr, u32 off_s, u32 off_u)
|
||||
{
|
||||
auto &ss = m_cpu->space(AS_PROGRAM);
|
||||
auto &su = m_cpu->space(m68000_device::AS_USER_PROGRAM);
|
||||
switch(config) {
|
||||
case 128:
|
||||
switch(actual) {
|
||||
case 0: {
|
||||
ss.unmap_readwrite(adr + off_s, adr + 0x1ffff);
|
||||
su.unmap_readwrite(adr + off_u, adr + 0x1ffff);
|
||||
break;
|
||||
}
|
||||
case 128: {
|
||||
ss.install_ram(adr + off_s, adr + 0x1ffff, m_ram + radr/2 + off_s/2);
|
||||
su.install_ram(adr + off_u, adr + 0x1ffff, m_ram + radr/2 + off_u/2);
|
||||
break;
|
||||
}
|
||||
case 512: {
|
||||
ss.install_read_handler (adr + off_s, adr + 0x1ffff, read16sm_delegate(*this, [this, off_s, radr](offs_t offset) { return m_ram[remap_128_512(offset + off_s/2) + radr/2]; }, "128-512"));
|
||||
ss.install_write_handler(adr + off_s, adr + 0x1ffff, write16s_delegate(*this, [this, off_s, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_128_512(offset + off_s/2) + radr/2]); }, "128-512"));
|
||||
su.install_read_handler (adr + off_u, adr + 0x1ffff, read16sm_delegate(*this, [this, off_u, radr](offs_t offset) { return m_ram[remap_128_512(offset + off_u/2) + radr/2]; }, "128-512"));
|
||||
su.install_write_handler(adr + off_u, adr + 0x1ffff, write16s_delegate(*this, [this, off_u, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_128_512(offset + off_u/2) + radr/2]); }, "128-512"));
|
||||
break;
|
||||
}
|
||||
case 2048: {
|
||||
ss.install_read_handler (adr + off_s, adr + 0x1ffff, read16sm_delegate(*this, [this, off_s, radr](offs_t offset) { return m_ram[remap_128_2048(offset + off_s/2) + radr/2]; }, "128-2048"));
|
||||
ss.install_write_handler(adr + off_s, adr + 0x1ffff, write16s_delegate(*this, [this, off_s, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_512_128(offset + off_s/2) + radr/2]); }, "128-2048"));
|
||||
su.install_read_handler (adr + off_u, adr + 0x1ffff, read16sm_delegate(*this, [this, off_u, radr](offs_t offset) { return m_ram[remap_128_2048(offset + off_u/2) + radr/2]; }, "128-2048"));
|
||||
su.install_write_handler(adr + off_u, adr + 0x1ffff, write16s_delegate(*this, [this, off_u, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_512_128(offset + off_u/2) + radr/2]); }, "128-2048"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 512:
|
||||
switch(actual) {
|
||||
case 0: {
|
||||
ss.unmap_readwrite(adr + off_s, adr + 0x7ffff);
|
||||
su.unmap_readwrite(adr + off_u, adr + 0x7ffff);
|
||||
break;
|
||||
}
|
||||
case 128: {
|
||||
ss.install_read_handler (adr + off_s, adr + 0x7ffff, read16sm_delegate(*this, [this, off_s, radr](offs_t offset) { return m_ram[remap_512_128(offset + off_s/2) + radr/2]; }, "512-128"));
|
||||
ss.install_write_handler(adr + off_s, adr + 0x7ffff, write16s_delegate(*this, [this, off_s, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_512_128(offset + off_s/2) + radr/2]); }, "512-128"));
|
||||
su.install_read_handler (adr + off_u, adr + 0x7ffff, read16sm_delegate(*this, [this, off_u, radr](offs_t offset) { return m_ram[remap_512_128(offset + off_u/2) + radr/2]; }, "512-128"));
|
||||
su.install_write_handler(adr + off_u, adr + 0x7ffff, write16s_delegate(*this, [this, off_u, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_512_128(offset + off_u/2) + radr/2]); }, "512-128"));
|
||||
break;
|
||||
}
|
||||
case 512: {
|
||||
ss.install_ram(adr + off_s, adr + 0x7ffff, m_ram + radr/2 + off_s/2);
|
||||
su.install_ram(adr + off_u, adr + 0x7ffff, m_ram + radr/2 + off_u/2);
|
||||
break;
|
||||
}
|
||||
case 2048: {
|
||||
ss.install_read_handler (adr + off_s, adr + 0x7ffff, read16sm_delegate(*this, [this, off_s, radr](offs_t offset) { return m_ram[remap_512_2048(offset + off_s/2) + radr/2]; }, "512-2048"));
|
||||
ss.install_write_handler(adr + off_s, adr + 0x7ffff, write16s_delegate(*this, [this, off_s, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_512_128(offset + off_s/2) + radr/2]); }, "512-2048"));
|
||||
su.install_read_handler (adr + off_u, adr + 0x7ffff, read16sm_delegate(*this, [this, off_u, radr](offs_t offset) { return m_ram[remap_512_2048(offset + off_u/2) + radr/2]; }, "512-2048"));
|
||||
su.install_write_handler(adr + off_u, adr + 0x7ffff, write16s_delegate(*this, [this, off_u, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_512_128(offset + off_u/2) + radr/2]); }, "512-2048"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2048:
|
||||
switch(actual) {
|
||||
case 0: {
|
||||
ss.unmap_readwrite(adr + off_s, adr + 0x1fffff);
|
||||
su.unmap_readwrite(adr + off_u, adr + 0x1fffff);
|
||||
break;
|
||||
}
|
||||
case 128: {
|
||||
ss.install_read_handler (adr + off_s, adr + 0x1fffff, read16sm_delegate(*this, [this, off_s, radr](offs_t offset) { return m_ram[remap_2048_128(offset + off_s/2) + radr/2]; }, "2048-128"));
|
||||
ss.install_write_handler(adr + off_s, adr + 0x1fffff, write16s_delegate(*this, [this, off_s, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_2048_128(offset + off_s/2) + radr/2]); }, "2048-128"));
|
||||
su.install_read_handler (adr + off_u, adr + 0x1fffff, read16sm_delegate(*this, [this, off_u, radr](offs_t offset) { return m_ram[remap_2048_128(offset + off_u/2) + radr/2]; }, "2048-128"));
|
||||
su.install_write_handler(adr + off_u, adr + 0x1fffff, write16s_delegate(*this, [this, off_u, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_2048_128(offset + off_u/2) + radr/2]); }, "2048-128"));
|
||||
break;
|
||||
}
|
||||
case 512: {
|
||||
ss.install_read_handler (adr + off_s, adr + 0x1fffff, read16sm_delegate(*this, [this, off_s, radr](offs_t offset) { return m_ram[remap_2048_512(offset + off_s/2) + radr/2]; }, "2048-512"));
|
||||
ss.install_write_handler(adr + off_s, adr + 0x1fffff, write16s_delegate(*this, [this, off_s, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_2048_512(offset + off_s/2) + radr/2]); }, "2048-512"));
|
||||
su.install_read_handler (adr + off_u, adr + 0x1fffff, read16sm_delegate(*this, [this, off_u, radr](offs_t offset) { return m_ram[remap_2048_512(offset + off_u/2) + radr/2]; }, "2048-512"));
|
||||
su.install_write_handler(adr + off_u, adr + 0x1fffff, write16s_delegate(*this, [this, off_u, radr](offs_t offset, offs_t data, offs_t mem_mask) { COMBINE_DATA(&m_ram[remap_2048_512(offset + off_u/2) + radr/2]); }, "2048-512"));
|
||||
break;
|
||||
}
|
||||
case 2048: {
|
||||
ss.install_ram(adr + off_s, adr + 0x1fffff, m_ram + radr/2 + off_s/2);
|
||||
su.install_ram(adr + off_u, adr + 0x1fffff, m_ram + radr/2 + off_u/2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void st_mmu_device::configure_ram()
|
||||
{
|
||||
u32 b0 = 0, b1 = 0;
|
||||
switch(m_ram_size) {
|
||||
case 256*1024: b0 = 128; b1 = 128; break;
|
||||
case 512*1024: b0 = 512; b1 = 0; break;
|
||||
case 1024*1024: b0 = 512; b1 = 512; break;
|
||||
case 2048*1024: b0 = 2048; b1 = 0; break;
|
||||
case 4096*1024: b0 = 2048; b1 = 2048; break;
|
||||
}
|
||||
|
||||
const u32 bank_sizes[4] = { 128, 512, 2048, 0 };
|
||||
u32 c0 = bank_sizes[(m_memcfg >> 2) & 3];
|
||||
u32 c1 = bank_sizes[m_memcfg & 3];
|
||||
|
||||
logerror("ram banks %d/%d configured %d/%d\n", b0, b1, c0, c1);
|
||||
|
||||
constexpr u32 st_s = 0x000008;
|
||||
constexpr u32 st_u = 0x000800;
|
||||
|
||||
ram_mapping(b0, c0, 0, 0, st_s, st_u);
|
||||
ram_mapping(b1, c1, 1024*c0, 1024*b0, 0, 0);
|
||||
|
||||
u32 ub = 1024*(c0+c1);
|
||||
if(ub < 0x400000) {
|
||||
m_cpu->space(AS_PROGRAM).nop_readwrite(ub, 0x3fffff);
|
||||
m_cpu->space(m68000_device::AS_USER_PROGRAM).nop_readwrite(ub, 0x3fffff);
|
||||
}
|
||||
}
|
105
src/mame/atari/stmmu.h
Normal file
105
src/mame/atari/stmmu.h
Normal file
@ -0,0 +1,105 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Curt Coder, Olivier Galibert
|
||||
|
||||
#ifndef MAME_ATARI_STMMU_H
|
||||
#define MAME_ATARI_STMMU_H
|
||||
|
||||
#include <machine/wd_fdc.h>
|
||||
#include <cpu/m68000/m68000.h>
|
||||
|
||||
// Atari ST family MMU implementation. Handles things from the GLUE
|
||||
// too, because the concerns are difficult to separate
|
||||
|
||||
// Manages dma and communications with fdc and hd in general.
|
||||
|
||||
class st_mmu_device : public device_t {
|
||||
public:
|
||||
st_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
|
||||
template <typename T> void set_ram(T &&tag) { m_ram.set_tag(std::forward<T>(tag)); }
|
||||
template <typename T> void set_cpu(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); }
|
||||
template <typename T> void set_fdc(T &&tag) { m_fdc.set_tag(std::forward<T>(tag)); }
|
||||
|
||||
void map(address_map &map);
|
||||
void set_ram_size(u32 size);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(fdc_drq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(hdc_drq_w);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
enum {
|
||||
STATUS_DRQ = 0x04,
|
||||
STATUS_SECTOR_COUNT = 0x02,
|
||||
STATUS_ERROR = 0x01,
|
||||
};
|
||||
|
||||
enum {
|
||||
MODE_READ_WRITE = 0x100,
|
||||
MODE_FDC_HDC_ACK = 0x080,
|
||||
MODE_ENABLED = 0x040,
|
||||
MODE_SECTOR_COUNT = 0x010,
|
||||
MODE_FDC_HDC_CS = 0x008,
|
||||
MODE_A1 = 0x004,
|
||||
MODE_A0 = 0x002,
|
||||
MODE_ADDRESS_MASK = 0x006,
|
||||
};
|
||||
|
||||
enum {
|
||||
SECTOR_SIZE = 512
|
||||
};
|
||||
|
||||
required_shared_ptr<u16> m_ram;
|
||||
required_device<m68000_device> m_cpu;
|
||||
required_device<wd1772_device> m_fdc;
|
||||
|
||||
uint32_t m_ram_size;
|
||||
|
||||
uint32_t m_dma_address;
|
||||
uint16_t m_dma_mode;
|
||||
uint16_t m_fifo[16];
|
||||
uint8_t m_sector_count, m_block_count;
|
||||
uint8_t m_fifo_index;
|
||||
uint8_t m_memcfg;
|
||||
bool m_fdc_drq, m_hdc_drq;
|
||||
bool m_dma_no_error;
|
||||
|
||||
uint16_t data_r();
|
||||
void data_w(uint16_t data);
|
||||
uint16_t dma_status_r();
|
||||
void dma_mode_w(uint16_t data);
|
||||
uint8_t dma_address_h_r();
|
||||
uint8_t dma_address_m_r();
|
||||
uint8_t dma_address_l_r();
|
||||
void dma_address_h_w(uint8_t data);
|
||||
void dma_address_m_w(uint8_t data);
|
||||
void dma_address_l_w(uint8_t data);
|
||||
|
||||
uint8_t memcfg_r();
|
||||
void memcfg_w(uint8_t data);
|
||||
void configure_ram();
|
||||
static offs_t remap_128_512(offs_t offset);
|
||||
static offs_t remap_128_2048(offs_t offset);
|
||||
static offs_t remap_512_128(offs_t offset);
|
||||
static offs_t remap_512_2048(offs_t offset);
|
||||
static offs_t remap_2048_128(offs_t offset);
|
||||
static offs_t remap_2048_512(offs_t offset);
|
||||
void ram_mapping(u32 actual, u32 config, u32 adr, u32 radr, u32 off_s, u32 off_u);
|
||||
|
||||
void fdc_transfer();
|
||||
void hdc_transfer();
|
||||
|
||||
void fifo_flush();
|
||||
u8 fifo_pop();
|
||||
void fifo_push(u8 data);
|
||||
|
||||
void fifo_schedule_block_transfer_to_ram();
|
||||
void fifo_schedule_block_transfer_from_ram();
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(ST_MMU, st_mmu_device)
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user