mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
i8089: fix odd byte count and mismatched bus size (nw)
altos8600: hdd support (nw)
This commit is contained in:
parent
3603b85686
commit
f8118baec7
@ -105,6 +105,8 @@ void i8089_channel_device::device_reset()
|
||||
elem.t = 0;
|
||||
}
|
||||
m_prio = PRIO_IDLE;
|
||||
m_load_hi = false;
|
||||
m_store_hi = false;
|
||||
}
|
||||
|
||||
|
||||
@ -230,6 +232,8 @@ int i8089_channel_device::execute_run()
|
||||
// we are no longer executing task blocks
|
||||
m_r[PSW].w &= ~(1 << 2);
|
||||
m_xfer_pending = false;
|
||||
m_load_hi = false;
|
||||
m_store_hi = false;
|
||||
|
||||
if (VERBOSE)
|
||||
{
|
||||
@ -269,21 +273,23 @@ int i8089_channel_device::execute_run()
|
||||
m_r[GA + CC_SOURCE].w += 2;
|
||||
m_r[BC].w -= 2;
|
||||
}
|
||||
// destination is 16-bit, byte count is even
|
||||
else if (BIT(m_r[PSW].w, 0) && !(m_r[BC].w & 1))
|
||||
// destination is 16-bit, low byte
|
||||
else if (BIT(m_r[PSW].w, 0) && !m_load_hi)
|
||||
{
|
||||
m_dma_value = m_iop->read_byte(m_r[GA + CC_SOURCE].t, m_r[GA + CC_SOURCE].w);
|
||||
if(CC_FUNC & 1)
|
||||
m_r[GA + CC_SOURCE].w++;
|
||||
m_r[BC].w--;
|
||||
if(--m_r[BC].w)
|
||||
m_load_hi = true;
|
||||
}
|
||||
// destination is 16-bit, byte count is odd
|
||||
else if (BIT(m_r[PSW].w, 0) && (m_r[BC].w & 1))
|
||||
// destination is 16-bit, high byte
|
||||
else if (BIT(m_r[PSW].w, 0) && m_load_hi)
|
||||
{
|
||||
m_dma_value |= m_iop->read_byte(m_r[GA + CC_SOURCE].t, m_r[GA + CC_SOURCE].w) << 8;
|
||||
if(CC_FUNC & 1)
|
||||
m_r[GA + CC_SOURCE].w++;
|
||||
m_r[BC].w--;
|
||||
m_load_hi = false;
|
||||
}
|
||||
// 8-bit transfer
|
||||
else
|
||||
@ -300,7 +306,7 @@ int i8089_channel_device::execute_run()
|
||||
if (VERBOSE_DMA)
|
||||
logerror("[ %04x ]\n", m_dma_value);
|
||||
|
||||
if (BIT(m_r[PSW].w, 0) && (m_r[BC].w & 1))
|
||||
if (BIT(m_r[PSW].w, 0) && m_load_hi)
|
||||
m_dma_state = DMA_FETCH;
|
||||
else if (CC_TRANS)
|
||||
m_dma_state = DMA_TRANSLATE;
|
||||
@ -316,7 +322,12 @@ int i8089_channel_device::execute_run()
|
||||
|
||||
case DMA_WAIT_FOR_DEST_DRQ:
|
||||
if (m_drq)
|
||||
m_dma_state = DMA_STORE;
|
||||
{
|
||||
if(m_store_hi)
|
||||
m_dma_state = DMA_STORE_BYTE_HIGH;
|
||||
else
|
||||
m_dma_state = DMA_STORE;
|
||||
}
|
||||
break;
|
||||
|
||||
case DMA_STORE:
|
||||
@ -360,8 +371,20 @@ int i8089_channel_device::execute_run()
|
||||
if (VERBOSE_DMA)
|
||||
logerror("%s('%s'): entering state: DMA_TERMINATE\n", shortname(), tag());
|
||||
|
||||
// do we need to read another byte?
|
||||
if (BIT(m_r[PSW].w, 1) && !BIT(m_r[PSW].w, 0) && !m_store_hi)
|
||||
{
|
||||
if (CC_SYNC == 0x02)
|
||||
{
|
||||
m_store_hi = true;
|
||||
m_dma_state = DMA_WAIT_FOR_DEST_DRQ;
|
||||
}
|
||||
else
|
||||
m_dma_state = DMA_STORE_BYTE_HIGH;
|
||||
}
|
||||
|
||||
// terminate on masked compare?
|
||||
if (CC_TMC & 0x03)
|
||||
else if (CC_TMC & 0x03)
|
||||
fatalerror("%s('%s'): terminate on masked compare not supported\n", shortname(), tag());
|
||||
|
||||
// terminate on byte count?
|
||||
@ -372,18 +395,11 @@ int i8089_channel_device::execute_run()
|
||||
else if (CC_TS)
|
||||
fatalerror("%s('%s'): terminate on single transfer not supported\n", shortname(), tag());
|
||||
|
||||
// not terminated, continue transfer
|
||||
else
|
||||
// do we need to read another byte?
|
||||
if (BIT(m_r[PSW].w, 1) && !BIT(m_r[PSW].w, 0))
|
||||
if (CC_SYNC == 0x02)
|
||||
m_dma_state = DMA_WAIT_FOR_DEST_DRQ;
|
||||
else
|
||||
m_dma_state = DMA_STORE_BYTE_HIGH;
|
||||
|
||||
// transfer done
|
||||
else
|
||||
m_dma_state = DMA_IDLE;
|
||||
{
|
||||
m_store_hi = false;
|
||||
m_dma_state = DMA_IDLE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -391,8 +407,9 @@ int i8089_channel_device::execute_run()
|
||||
if (VERBOSE_DMA)
|
||||
logerror("%s('%s'): entering state: DMA_STORE_BYTE_HIGH[ %02x ]\n", shortname(), tag(), (m_dma_value >> 8) & 0xff);
|
||||
|
||||
m_iop->write_byte(m_r[GA - CC_SOURCE].t, m_r[GB - CC_SOURCE].w, (m_dma_value >> 8) & 0xff);
|
||||
m_r[GB - CC_SOURCE].w++;
|
||||
m_iop->write_byte(m_r[GB - CC_SOURCE].t, m_r[GB - CC_SOURCE].w, (m_dma_value >> 8) & 0xff);
|
||||
if(CC_FUNC & 2)
|
||||
m_r[GB - CC_SOURCE].w++;
|
||||
m_dma_state = DMA_TERMINATE;
|
||||
|
||||
break;
|
||||
|
@ -183,7 +183,7 @@ private:
|
||||
bool m_xfer_pending;
|
||||
uint16_t m_dma_value;
|
||||
int m_dma_state;
|
||||
bool m_drq;
|
||||
bool m_drq, m_store_hi, m_load_hi;
|
||||
|
||||
// dma state
|
||||
enum
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "machine/z80sio.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "machine/acs8600_ics.h"
|
||||
#include "imagedev/harddriv.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
|
||||
class altos8600_state : public driver_device
|
||||
@ -27,6 +28,7 @@ public:
|
||||
m_fdc(*this, "fd1797"),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_ics(*this, "ics"),
|
||||
m_hdd(*this, "hdd"),
|
||||
m_bios(*this, "bios")
|
||||
{}
|
||||
DECLARE_READ16_MEMBER(cpuram_r);
|
||||
@ -53,6 +55,8 @@ public:
|
||||
DECLARE_READ16_MEMBER(errhi_r);
|
||||
DECLARE_WRITE16_MEMBER(clear_w);
|
||||
DECLARE_WRITE8_MEMBER(cattn_w);
|
||||
DECLARE_READ8_MEMBER(hd_r);
|
||||
DECLARE_WRITE8_MEMBER(hd_w);
|
||||
DECLARE_READ8_MEMBER(romport_r);
|
||||
DECLARE_WRITE8_MEMBER(romport_w);
|
||||
DECLARE_WRITE8_MEMBER(clrsys_w);
|
||||
@ -69,6 +73,10 @@ private:
|
||||
u16 xlate_r(address_space &space, offs_t offset, u16 mem_mask, int permbit);
|
||||
void xlate_w(address_space &space, offs_t offset, u16 data, u16 mem_mask, int permbit);
|
||||
void seterr(offs_t offset, u16 mem_mask, u16 err_mask);
|
||||
bool find_sector();
|
||||
bool write_sector(u8 data);
|
||||
u8 read_sector();
|
||||
void format_sector();
|
||||
required_device<i8086_cpu_device> m_maincpu;
|
||||
required_device<i8089_device> m_dmac;
|
||||
required_device<pic8259_device> m_pic1;
|
||||
@ -78,10 +86,18 @@ private:
|
||||
required_device<fd1797_device> m_fdc;
|
||||
required_device<ram_device> m_ram;
|
||||
required_device<acs8600_ics_device> m_ics;
|
||||
required_device<harddisk_image_device> m_hdd;
|
||||
required_memory_region m_bios;
|
||||
u8 m_mmuaddr[256], m_romport[4], m_dmamplex;
|
||||
u16 m_mmuflags[256], m_mmuerr, m_mode, m_mmueaddr[2];
|
||||
bool m_cpuif, m_user, m_nmiinh, m_nmistat;
|
||||
u32 m_lba;
|
||||
u16 m_head, m_sect, m_cyl, m_curcyl;
|
||||
int m_secoff;
|
||||
u8 m_cmd, m_stat;
|
||||
bool m_cylhi, m_sechi;
|
||||
const struct hard_disk_info* m_geom;
|
||||
u8 m_sector[512];
|
||||
};
|
||||
|
||||
void altos8600_state::machine_start()
|
||||
@ -96,6 +112,184 @@ void altos8600_state::machine_reset()
|
||||
m_user = false;
|
||||
m_nmiinh = true;
|
||||
m_nmistat = false;
|
||||
m_cylhi = m_sechi = false;
|
||||
m_stat = 0;
|
||||
if(m_hdd->get_hard_disk_file())
|
||||
m_geom = hard_disk_get_info(m_hdd->get_hard_disk_file());
|
||||
else
|
||||
m_geom = nullptr;
|
||||
}
|
||||
|
||||
bool altos8600_state::find_sector()
|
||||
{
|
||||
u8 head = m_head >> 4;
|
||||
logerror("head %d cyl %d curcyl %d sect %d", head, m_cyl, m_curcyl, m_sect);
|
||||
|
||||
if(!m_geom)
|
||||
return false;
|
||||
|
||||
if(m_cyl != m_curcyl)
|
||||
return false;
|
||||
|
||||
if(m_curcyl > m_geom->cylinders)
|
||||
return false;
|
||||
|
||||
if(head > m_geom->heads)
|
||||
return false;
|
||||
|
||||
if(m_sect > m_geom->sectors)
|
||||
return false;
|
||||
|
||||
m_lba = (m_cyl * m_geom->heads + head) * m_geom->sectors + m_sect;
|
||||
return true;
|
||||
}
|
||||
|
||||
u8 altos8600_state::read_sector()
|
||||
{
|
||||
int secoff = m_secoff;
|
||||
m_secoff++;
|
||||
if(m_cmd == 1)
|
||||
{
|
||||
switch(secoff)
|
||||
{
|
||||
case 0:
|
||||
return m_curcyl;
|
||||
case 1:
|
||||
return (m_head & 0xf0) | (m_curcyl >> 8);
|
||||
case 2:
|
||||
return m_sect;
|
||||
}
|
||||
secoff -= 3;
|
||||
}
|
||||
if(!secoff)
|
||||
hard_disk_read(m_hdd->get_hard_disk_file(), m_lba, m_sector);
|
||||
if(secoff >= 511)
|
||||
{
|
||||
m_dmac->drq1_w(CLEAR_LINE);
|
||||
m_stat &= ~1;
|
||||
m_stat |= 2;
|
||||
}
|
||||
if(secoff >= 512)
|
||||
return 0;
|
||||
return m_sector[secoff];
|
||||
}
|
||||
|
||||
bool altos8600_state::write_sector(u8 data)
|
||||
{
|
||||
if(m_secoff >= 512)
|
||||
return true;
|
||||
m_sector[m_secoff++] = data;
|
||||
logerror("secoff %d", m_secoff);
|
||||
if(m_secoff == 512)
|
||||
{
|
||||
m_stat &= ~1;
|
||||
m_stat |= 2;
|
||||
hard_disk_write(m_hdd->get_hard_disk_file(), m_lba, m_sector);
|
||||
m_dmac->drq1_w(CLEAR_LINE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
READ8_MEMBER(altos8600_state::hd_r)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 1:
|
||||
if(BIT(m_stat, 0) && (m_cmd & 1))
|
||||
return read_sector();
|
||||
break;
|
||||
case 3:
|
||||
m_pic1->ir3_w(CLEAR_LINE);
|
||||
return m_stat;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(altos8600_state::hd_w)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 0:
|
||||
m_head = data;
|
||||
if((m_head & 3) == 1)
|
||||
m_stat |= 0x80;
|
||||
else
|
||||
m_stat &= ~0x80;
|
||||
break;
|
||||
case 1:
|
||||
if(BIT(m_stat, 0))
|
||||
{
|
||||
switch(m_cmd)
|
||||
{
|
||||
case 2:
|
||||
write_sector(data);
|
||||
break;
|
||||
case 4:
|
||||
m_secoff++;
|
||||
if(m_secoff == 4)
|
||||
{
|
||||
m_dmac->drq1_w(CLEAR_LINE);
|
||||
m_stat &= ~1;
|
||||
m_stat |= 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(m_sechi)
|
||||
m_sect |= (data & 7) << 8;
|
||||
else
|
||||
{
|
||||
m_sechi = true;
|
||||
m_sect = data;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(m_cylhi)
|
||||
m_cyl |= (data & 7) << 8;
|
||||
else
|
||||
{
|
||||
m_cylhi = true;
|
||||
m_cyl = data;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
logerror("cmd %02x stat %04x\n", data, m_stat);
|
||||
m_cmd = data;
|
||||
m_cylhi = false;
|
||||
m_sechi = false;
|
||||
m_dmac->drq1_w(CLEAR_LINE);
|
||||
if(!BIT(m_stat, 7))
|
||||
break;
|
||||
m_stat &= 0x80;
|
||||
switch(m_cmd)
|
||||
{
|
||||
case 0x10:
|
||||
m_curcyl = m_cyl;
|
||||
m_stat |= 2;
|
||||
break;
|
||||
case 0x11:
|
||||
m_curcyl = 0;
|
||||
m_stat |= 2;
|
||||
break;
|
||||
case 0x1:
|
||||
case 0x2:
|
||||
case 0x9:
|
||||
if(!find_sector())
|
||||
{
|
||||
m_stat |= 0xa;
|
||||
break;
|
||||
}
|
||||
case 0x4:
|
||||
m_secoff = 0;
|
||||
m_stat |= 1;
|
||||
m_dmac->drq1_w(ASSERT_LINE);
|
||||
break;
|
||||
}
|
||||
m_pic2->ir0_w(ASSERT_LINE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(altos8600_state::cpuif_w)
|
||||
@ -440,6 +634,7 @@ static ADDRESS_MAP_START(dmac_io, AS_IO, 16, altos8600_state)
|
||||
AM_RANGE(0x0008, 0x000f) AM_WRITE(clear_w)
|
||||
AM_RANGE(0x0010, 0x0017) AM_READ(errlo_r)
|
||||
AM_RANGE(0x0018, 0x001f) AM_READ(errhi_r)
|
||||
AM_RANGE(0x0020, 0x0027) AM_READWRITE8(hd_r, hd_w, 0x00ff)
|
||||
AM_RANGE(0x0030, 0x0037) AM_WRITE(mode_w)
|
||||
AM_RANGE(0x0038, 0x003f) AM_WRITE8(cattn_w, 0xffff)
|
||||
AM_RANGE(0x0040, 0x0047) AM_DEVREADWRITE8("ppi", i8255_device, read, write, 0x00ff)
|
||||
@ -536,9 +731,11 @@ static MACHINE_CONFIG_START(altos8600)
|
||||
MCFG_FLOPPY_DRIVE_ADD("fd1797:3", altos8600_floppies, "8dd", floppy_image_device::default_floppy_formats)
|
||||
|
||||
MCFG_DEVICE_ADD("ics", ACS8600_ICS, 0)
|
||||
MCFG_ACS8600_ICS_MAINCPU(":maincpu")
|
||||
MCFG_ACS8600_ICS_MAINCPU(":dmac") // TODO: fixme
|
||||
MCFG_ACS8600_ICS_IRQ1(DEVWRITELINE("pic8259_1", pic8259_device, ir5_w))
|
||||
MCFG_ACS8600_ICS_IRQ2(DEVWRITELINE("pic8259_1", pic8259_device, ir6_w))
|
||||
|
||||
MCFG_HARDDISK_ADD("hdd")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
ROM_START(altos8600)
|
||||
|
Loading…
Reference in New Issue
Block a user