diff options
Diffstat (limited to 'src/mess/drivers/abc1600.c')
-rw-r--r-- | src/mess/drivers/abc1600.c | 1995 |
1 files changed, 1995 insertions, 0 deletions
diff --git a/src/mess/drivers/abc1600.c b/src/mess/drivers/abc1600.c new file mode 100644 index 00000000000..846a4744a0c --- /dev/null +++ b/src/mess/drivers/abc1600.c @@ -0,0 +1,1995 @@ +/* + + Luxor ABC 1600 + + Skeleton driver +*/ + +/* + + How to create HDD image: + ------------------------ + chdman -createblankhd necd5126a.chd 615 4 17 512 + + How to format HDD: + ------------------ + mf(2,0) + mf(2,0) + abcenix + sas/format/format + sa(40,0) + y + 5 + necd5126a + + How to install OS: + ------------------ + mf(2,0) + mf(2,0) + abcenix + loadsys1 + <enter> + <enter> + +*/ + +/* + + TODO: + + - segment/page RAM addresses are not correctly decoded, "sas/format/format" can't find the SASI interface because of this + forcetask0 1 t0 0 t1 0 t2 0 t3 0 + sega19 0 task 0 + sega 000 segd 00 pga 008 pgd 4058 virtual 02c730 (should be 004730) + + - floppy + - internal floppy is really drive 2, but wd17xx.c doesn't like having NULL drives + - short/long reset (RSTBUT) + - CIO + - optimize timers! + - port C, open drain output bit PC1 (RTC/NVRAM data) + - hard disk + - 4105 SASI interface card + - SASI interface (scsibus.c) + +*/ + +#include "includes/abc1600.h" + + + +//************************************************************************** +// CONSTANTS / MACROS +//************************************************************************** + +#define LOG 0 + + +// MAC +#define A0 BIT(offset, 0) +#define A1 BIT(offset, 1) +#define A2 BIT(offset, 2) +#define A4 BIT(offset, 4) +#define A7 BIT(offset, 7) +#define A8 BIT(offset, 8) +#define X11 BIT(offset, 11) +#define X12 BIT(offset, 12) +#define A17 BIT(offset, 17) +#define A18 BIT(offset, 18) +#define A19 BIT(offset, 19) + +#define A10_A9_A8 ((offset >> 8) & 0x07) +#define A2_A1_A0 (offset & 0x07) +#define A1_A2 ((A1 << 1) | A2) +#define A2_A1 ((offset >> 1) & 0x03) + +#define FC0 BIT(fc, 0) +#define FC1 BIT(fc, 1) +#define FC2 BIT(fc, 2) + +#define PAGE_WP BIT(page_data, 14) +#define PAGE_NONX BIT(page_data, 15) + + +// task register +#define BOOTE BIT(m_task, 6) +#define MAGIC BIT(m_task, 7) +#define READ_MAGIC !MAGIC + + +// DMA map +enum +{ + DMAMAP_R2_LO = 0, + DMAMAP_R2_HI, + DMAMAP_R1_LO = 4, + DMAMAP_R1_HI, + DMAMAP_R0_LO, + DMAMAP_R0_HI +}; + + +// internal I/O registers +enum +{ + FLP = 0, + CRT, + DRT, + DMA0, + DMA1, + DMA2, + SCC, + CIO +}; + + +// internal I/O registers +enum +{ + IORD0 = 0 +}; + + +// internal I/O registers +enum +{ + IOWR0 = 0, + IOWR1, + IOWR2, + FW, + DMAMAP = 5, + SPEC_CONTR_REG +}; + + +// external I/O +enum +{ + INP = 0, + STAT, + OPS +}; + +enum +{ + OUT = 0, + C1 = 2, + C2, + C3, + C4 +}; + + + +//************************************************************************** +// MEMORY ACCESS CONTROLLER +//************************************************************************** + +//------------------------------------------------- +// read_ram - +//------------------------------------------------- + +UINT8 abc1600_state::read_ram(offs_t offset) +{ + UINT8 data = 0; + + if (offset < 0x100000) + { + // main RAM + UINT8 *ram = m_ram->pointer(); + data = ram[offset]; + } + else if (offset < 0x180000) + { + // video RAM + address_space *program = m_maincpu->memory().space(AS_PROGRAM); + data = video_ram_r(*program, offset); + } + else + { + logerror("%s Unmapped read from virtual memory %06x\n", machine().describe_context(), offset); + } + + return data; +} + + +//------------------------------------------------- +// write_ram - +//------------------------------------------------- + +void abc1600_state::write_ram(offs_t offset, UINT8 data) +{ + if (offset < 0x100000) + { + // main RAM + UINT8 *ram = m_ram->pointer(); + ram[offset] = data; + } + else if (offset < 0x180000) + { + // video RAM + address_space *program = m_maincpu->memory().space(AS_PROGRAM); + video_ram_w(*program, offset, data); + } + else + { + logerror("%s Unmapped write to virtual memory %06x : %02x\n", machine().describe_context(), offset, data); + } +} + + +//------------------------------------------------- +// read_io - +//------------------------------------------------- + +UINT8 abc1600_state::read_io(offs_t offset) +{ + if (X12) + { + return read_internal_io(offset); + } + else + { + return read_external_io(offset); + } +} + + +//------------------------------------------------- +// read_internal_io - +//------------------------------------------------- + +UINT8 abc1600_state::read_internal_io(offs_t offset) +{ + address_space *program = m_maincpu->memory().space(AS_PROGRAM); + UINT8 data = 0; + + if (X11) + { + switch (A10_A9_A8) + { + case IORD0: + data = iord0_r(*program, offset); + break; + + default: + logerror("%s Unmapped read from virtual I/O %06x\n", machine().describe_context(), offset); + } + } + else + { + switch (A10_A9_A8) + { + case FLP: + data = wd17xx_r(m_fdc, A2_A1); + break; + + case CRT: + if (A0) + data = m_crtc->register_r(*program, offset); + else + data = m_crtc->status_r(*program, offset); + break; + + case DRT: + data = z80dart_ba_cd_r(m_dart, A2_A1 ^ 0x03); + break; + + case DMA0: + data = m_dma0->read(); + break; + + case DMA1: + data = m_dma1->read(); + break; + + case DMA2: + data = m_dma2->read(); + break; + + case SCC: + data = m_scc->reg_r(*program, A1_A2); + break; + + case CIO: + data = m_cio->read(*program, A2_A1); + break; + } + } + + return data; +} + + +//------------------------------------------------- +// read_external_io - +//------------------------------------------------- + +UINT8 abc1600_state::read_external_io(offs_t offset) +{ + UINT8 data = 0; + + // card select pulse + UINT8 cs = (m_cs7 << 7) | ((offset >> 5) & 0x3f); + + m_bus0i->cs_w(cs); + m_bus0x->cs_w(cs); + m_bus1->cs_w(cs); + m_bus2->cs_w(cs); + + // card select b? + m_csb = m_bus2->csb_r(); + m_csb |= m_bus1->csb_r() << 1; + m_csb |= m_bus0x->xcsb2_r() << 2; + m_csb |= m_bus0x->xcsb3_r() << 3; + m_csb |= m_bus0x->xcsb4_r() << 4; + m_csb |= m_bus0x->xcsb5_r() << 5; + m_csb |= m_bus0x->csb_r() << 6; + m_csb |= m_bus0i->csb_r() << 7; + + m_bus0 = !((m_csb & 0xfc) == 0xfc); + + if (X11) + { + if (A4) + { + // EXP + data = m_bus0x->exp_r(); + + logerror("%s EXP %02x: %02x\n", machine().describe_context(), cs, data); + } + else + { + // RCSB + if (m_bus0) + { + /* + + bit description + + 0 1 + 1 1 + 2 LXCSB2* + 3 LXCSB3* + 4 LXCSB4* + 5 LXCSB5* + 6 LCSB*-0 + 7 LCSB*-0I + + */ + + data = (m_csb & 0xfc) | 0x03; + } + else + { + /* + + bit description + + 0 LCSB*-2 + 1 LCSB*-1 + 2 1 + 3 1 + 4 1 + 5 1 + 6 1 + 7 1 + + */ + + data = 0xfc | (m_csb & 0x03); + } + + logerror("%s RCSB %02x\n", machine().describe_context(), data); + } + } + else + { + data = 0xff; + + switch ((offset >> 1) & 0x07) + { + case INP: + if (m_bus0) + { + data &= m_bus0i->inp_r(); + data &= m_bus0x->inp_r(); + } + else + { + data &= m_bus1->inp_r(); + data &= m_bus2->inp_r(); + } + + logerror("%s INP %02x: %02x\n", machine().describe_context(), cs, data); + break; + + case STAT: + if (m_bus0) + { + data &= m_bus0i->stat_r(); + data &= m_bus0x->stat_r(); + } + else + { + data &= m_bus1->stat_r(); + data &= m_bus2->stat_r(); + } + + logerror("%s STAT %02x: %02x\n", machine().describe_context(), cs, data); + break; + + case OPS: + if (m_bus0) + { + data &= m_bus0i->ops_r(); + data &= m_bus0x->ops_r(); + } + else + { + data &= m_bus1->ops_r(); + data &= m_bus2->ops_r(); + } + + logerror("%s OPS %02x: %02x\n", machine().describe_context(), cs, data); + break; + + default: + logerror("%s Unmapped read from virtual I/O %06x\n", machine().describe_context(), offset); + } + } + + return data; +} + + +//------------------------------------------------- +// write_io - +//------------------------------------------------- + +void abc1600_state::write_io(offs_t offset, UINT8 data) +{ + if (X12) + { + write_internal_io(offset, data); + } + else + { + write_external_io(offset, data); + } +} + + +//------------------------------------------------- +// write_internal_io - +//------------------------------------------------- + +void abc1600_state::write_internal_io(offs_t offset, UINT8 data) +{ + address_space *program = m_maincpu->memory().space(AS_PROGRAM); + + if (X11) + { + switch (A10_A9_A8) + { + case IOWR0: + iowr0_w(*program, offset, data); + break; + + case IOWR1: + iowr1_w(*program, offset, data); + break; + + case IOWR2: + iowr2_w(*program, offset, data); + break; + + case FW: + if (!A7) + { + if (A0) + fw1_w(*program, offset, data); + else + fw0_w(*program, offset, data); + } + else + { + logerror("%s Unmapped write to virtual I/O %06x : %02x\n", machine().describe_context(), offset, data); + } + break; + + case DMAMAP: + dmamap_w(*program, offset, data); + break; + + case SPEC_CONTR_REG: + spec_contr_reg_w(*program, offset, data); + break; + + default: + logerror("%s Unmapped write to virtual I/O %06x : %02x\n", machine().describe_context(), offset, data); + } + } + else + { + switch (A10_A9_A8) + { + case FLP: + wd17xx_w(m_fdc, A2_A1, data); + break; + + case CRT: + if (A0) + m_crtc->register_w(*program, offset, data); + else + m_crtc->address_w(*program, offset, data); + break; + + case DRT: + z80dart_ba_cd_w(m_dart, A2_A1 ^ 0x03, data); + break; + + case DMA0: + m_dma0->write(data); + break; + + case DMA1: + m_dma1->write(data); + break; + + case DMA2: + m_dma2->write(data); + break; + + case SCC: + m_scc->reg_w(*program, A1_A2, data); + break; + + case CIO: + m_cio->write(*program, A2_A1, data); + break; + } + } +} + + +//------------------------------------------------- +// write_external_io - +//------------------------------------------------- + +void abc1600_state::write_external_io(offs_t offset, UINT8 data) +{ + UINT8 cs = (m_cs7 << 7) | ((offset >> 5) & 0x3f); + + m_bus0i->cs_w(cs); + m_bus0x->cs_w(cs); + m_bus1->cs_w(cs); + m_bus2->cs_w(cs); + + switch ((offset >> 1) & 0x07) + { + case OUT: + logerror("%s OUT %02x: %02x\n", machine().describe_context(), cs, data); + + if (m_bus0) + { + m_bus0i->out_w(data); + m_bus0x->out_w(data); + } + else + { + m_bus1->out_w(data); + m_bus2->out_w(data); + } + break; + + case C1: + logerror("%s C1 %02x: %02x\n", machine().describe_context(), cs, data); + + if (m_bus0) + { + m_bus0i->c1_w(data); + m_bus0x->c1_w(data); + } + else + { + m_bus1->c1_w(data); + m_bus2->c1_w(data); + } + break; + + case C2: + logerror("%s C2 %02x: %02x\n", machine().describe_context(), cs, data); + + if (m_bus0) + { + m_bus0i->c2_w(data); + m_bus0x->c2_w(data); + } + else + { + m_bus1->c2_w(data); + m_bus2->c2_w(data); + } + break; + + case C3: + logerror("%s C3 %02x: %02x\n", machine().describe_context(), cs, data); + + if (m_bus0) + { + m_bus0i->c3_w(data); + m_bus0x->c3_w(data); + } + else + { + m_bus1->c3_w(data); + m_bus2->c3_w(data); + } + break; + + case C4: + logerror("%s C4 %02x: %02x\n", machine().describe_context(), cs, data); + + if (m_bus0) + { + m_bus0i->c4_w(data); + m_bus0x->c4_w(data); + } + else + { + m_bus1->c4_w(data); + m_bus2->c4_w(data); + } + break; + + default: + logerror("%s Unmapped write %02x to virtual I/O %06x\n", machine().describe_context(), data, offset); + } +} + + +//------------------------------------------------- +// get_current_task - +//------------------------------------------------- + +int abc1600_state::get_current_task(offs_t offset) +{ + int force_task0 = !(m_ifc2 || A19); + int t0 = !(BIT(m_task, 0) || force_task0); + int t1 = !(BIT(m_task, 1) || force_task0); + int t2 = !(BIT(m_task, 2) || force_task0); + int t3 = !(BIT(m_task, 3) || force_task0); + + return (t3 << 3) | (t2 << 2) | (t1 << 1) | t0; +} + + +//------------------------------------------------- +// get_segment_address - +//------------------------------------------------- + +offs_t abc1600_state::get_segment_address(offs_t offset) +{ + int sega19 = !(!(A8 || m_ifc2) || !A19); + int task = get_current_task(offset); + + return (task << 5) | (sega19 << 4) | ((offset >> 15) & 0x0f); +} + + +//------------------------------------------------- +// get_page_address - +//------------------------------------------------- + +offs_t abc1600_state::get_page_address(offs_t offset, UINT8 segd) +{ + return ((segd & 0x3f) << 4) | ((offset >> 11) & 0x0f); +} + + +//------------------------------------------------- +// translate_address - +//------------------------------------------------- + +offs_t abc1600_state::translate_address(offs_t offset, int *nonx, int *wp) +{ + // segment + offs_t sega = get_segment_address(offset); + UINT8 segd = m_segment_ram[sega]; + + // page + offs_t pga = get_page_address(offset, segd); + UINT16 page_data = m_page_ram[pga]; + + offs_t virtual_offset = ((page_data & 0x3ff) << 11) | (offset & 0x7ff); + + if (PAGE_NONX) + { + //logerror("Bus error %06x : %06x\n", offset, virtual_offset); + //m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); + //m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); + } + + *nonx = PAGE_NONX; + *wp = PAGE_WP; + + return virtual_offset; +} + + +//------------------------------------------------- +// read_user_memory - +//------------------------------------------------- + +UINT8 abc1600_state::read_user_memory(offs_t offset) +{ + int nonx = 0, wp = 0; + offs_t virtual_offset = translate_address(offset, &nonx, &wp); + UINT8 data = 0; + + if (virtual_offset < 0x1fe000) + { + data = read_ram(virtual_offset); + } + else + { + data = read_io(virtual_offset); + } + + return data; +} + + +//------------------------------------------------- +// write_user_memory - +//------------------------------------------------- + +void abc1600_state::write_user_memory(offs_t offset, UINT8 data) +{ + int nonx = 0, wp = 0; + offs_t virtual_offset = translate_address(offset, &nonx, &wp); + + //if (nonx || !wp) return; + + if (virtual_offset < 0x1fe000) + { + write_ram(virtual_offset, data); + } + else + { + write_io(virtual_offset, data); + } +} + + +//------------------------------------------------- +// read_supervisor_memory - +//------------------------------------------------- + +UINT8 abc1600_state::read_supervisor_memory(offs_t offset) +{ + address_space *program = m_maincpu->memory().space(AS_PROGRAM); + UINT8 data = 0; + + if (!A2 && !A1) + { + // _EP + data = page_r(*program, offset); + } + else if (!A2 && A1 && A0) + { + // _ES + data = segment_r(*program, offset); + } + else if (A2 && A1 && A0) + { + // _CAUSE + data = cause_r(*program, offset); + } + + return data; +} + + +//------------------------------------------------- +// write_supervisor_memory - +//------------------------------------------------- + +void abc1600_state::write_supervisor_memory(offs_t offset, UINT8 data) +{ + address_space *program = m_maincpu->memory().space(AS_PROGRAM); + + if (!A2 && !A1) + { + // _WEP + page_w(*program, offset, data); + } + else if (!A2 && A1 && A0) + { + // _WES + segment_w(*program, offset, data); + } + else if (A2 && !A1 && A0) + { + // W(C) + task_w(*program, offset, data); + } +} + + +//------------------------------------------------- +// get_fc - +//------------------------------------------------- + +int abc1600_state::get_fc() +{ + UINT16 fc = m68k_get_fc(m_maincpu); + + m_ifc2 = !(!(MAGIC || FC0) || FC2); + + return fc; +} + + +//------------------------------------------------- +// mac_r - +//------------------------------------------------- + +READ8_MEMBER( abc1600_state::mac_r ) +{ + int fc = get_fc(); + + UINT8 data = 0; + + if (!BOOTE && !A19 && !A18 && !A17) + { + // _BOOTCE + UINT8 *rom = memregion(MC68008P8_TAG)->base(); + data = rom[offset & 0x3fff]; + } + else if (A19 && !m_ifc2 && !FC1) + { + data = read_supervisor_memory(offset); + } + else + { + data = read_user_memory(offset); + } + + return data; +} + + +//------------------------------------------------- +// mac_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc1600_state::mac_w ) +{ + int fc = get_fc(); + + if (A19 && !m_ifc2 && !FC1) + { + write_supervisor_memory(offset, data); + } + else + { + write_user_memory(offset, data); + } +} + + +//------------------------------------------------- +// cause_r - +//------------------------------------------------- + +READ8_MEMBER( abc1600_state::cause_r ) +{ + /* + + bit description + + 0 RSTBUT + 1 1 + 2 DMAOK + 3 X16 + 4 X17 + 5 X18 + 6 X19 + 7 X20 + + */ + + UINT8 data = 0x02; + + // DMA status + data |= m_cause; + + machine().watchdog_reset(); + + return data; +} + + +//------------------------------------------------- +// task_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc1600_state::task_w ) +{ + /* + + bit description + + 0 TASKD0* (inverted SEGA5) + 1 TASKD1* (inverted SEGA6) + 2 TASKD2* (inverted SEGA7) + 3 TASKD3* (inverted SEGA8) + 4 + 5 + 6 BOOTE* + 7 MAGIC* + + */ + + m_task = data ^ 0xff; + + if (LOG) logerror("%s: %06x Task %u BOOTE %u MAGIC %u\n", machine().describe_context(), offset, get_current_task(offset), BOOTE, MAGIC); +} + + +//------------------------------------------------- +// segment_r - +//------------------------------------------------- + +READ8_MEMBER( abc1600_state::segment_r ) +{ + /* + + bit description + + 0 SEGD0 + 1 SEGD1 + 2 SEGD2 + 3 SEGD3 + 4 SEGD4 + 5 SEGD5 + 6 SEGD6 + 7 READ_MAGIC + + */ + + offs_t sega = get_segment_address(offset); + UINT8 segd = m_segment_ram[sega]; + + return (READ_MAGIC << 7) | (segd & 0x7f); +} + + +//------------------------------------------------- +// segment_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc1600_state::segment_w ) +{ + /* + + bit description + + 0 SEGD0 + 1 SEGD1 + 2 SEGD2 + 3 SEGD3 + 4 SEGD4 + 5 SEGD5 + 6 SEGD6 + 7 0 + + */ + + offs_t sega = get_segment_address(offset); + + m_segment_ram[sega] = data & 0x7f; + + if (LOG) logerror("%s: %06x Task %u Segment %03x : %02x\n", machine().describe_context(), offset, get_current_task(offset), sega, data); +} + + +//------------------------------------------------- +// page_r - +//------------------------------------------------- + +READ8_MEMBER( abc1600_state::page_r ) +{ + /* + + bit description + + 0 X11 + 1 X12 + 2 X13 + 3 X14 + 4 X15 + 5 X16 + 6 X17 + 7 X18 + + 8 X19 + 9 X20 + 10 X20 + 11 X20 + 12 X20 + 13 X20 + 14 _WP + 15 NONX + + */ + + // segment + offs_t sega = get_segment_address(offset); + UINT8 segd = m_segment_ram[sega]; + + // page + offs_t pga = get_page_address(offset, segd); + UINT16 pgd = m_page_ram[pga]; + + UINT8 data = 0; + + if (A0) + { + data = pgd & 0xff; + } + else + { + int x20 = BIT(pgd, 9); + + data = (pgd >> 8) | (x20 << 2) | (x20 << 3) | (x20 << 4) | (x20 << 5); + } + + return data; +} + + +//------------------------------------------------- +// page_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc1600_state::page_w ) +{ + /* + + bit description + + 0 X11 + 1 X12 + 2 X13 + 3 X14 + 4 X15 + 5 X16 + 6 X17 + 7 X18 + + 8 X19 + 9 X20 + 10 + 11 + 12 + 13 + 14 _WP + 15 NONX + + */ + + // segment + offs_t sega = get_segment_address(offset); + UINT8 segd = m_segment_ram[sega]; + + // page + offs_t pga = get_page_address(offset, segd); + + if (A0) + { + m_page_ram[pga] = (m_page_ram[pga] & 0xff00) | data; + } + else + { + m_page_ram[pga] = ((data & 0xc3) << 8) | (m_page_ram[pga] & 0xff); + } + + if (LOG) logerror("%s: %06x Task %u Segment %03x Page %03x : %02x -> %04x\n", machine().describe_context(), offset, get_current_task(offset), sega, pga, data, m_page_ram[pga]); +} + + + +//************************************************************************** +// DMA +//************************************************************************** + +//------------------------------------------------- +// update_drdy0 - +//------------------------------------------------- + +inline void abc1600_state::update_drdy0() +{ + if (m_sysfs) + { + // floppy + m_dma0->rdy_w(!wd17xx_drq_r(m_fdc)); + } + else + { + // BUS0I/BUS0X + int trrq0 = m_bus0i->trrq_r() && m_bus0x->trrq_r(); + + m_dma0->rdy_w(trrq0); + } +} + + +//------------------------------------------------- +// update_drdy1 - +//------------------------------------------------- + +inline void abc1600_state::update_drdy1() +{ + if (m_sysscc) + { + // SCC + m_dma1->rdy_w(1); + } + else + { + // BUS1 + m_dma1->rdy_w(m_bus1->trrq_r()); + } +} + + +//------------------------------------------------- +// update_drdy2 - +//------------------------------------------------- + +inline void abc1600_state::update_drdy2() +{ + // Winchester + m_dma2->rdy_w(1); +} + + +//------------------------------------------------- +// get_dma_address - +//------------------------------------------------- + +inline offs_t abc1600_state::get_dma_address(int index, UINT16 offset) +{ + // A0 = DMA15, A1 = BA1, A2 = BA2 + UINT8 dmamap_addr = index | BIT(offset, 15); + UINT8 dmamap = m_dmamap[dmamap_addr]; + + m_cause = (dmamap & 0x1f) << 3; + + return ((dmamap & 0x1f) << 16) | offset; +} + + +//------------------------------------------------- +// dma_mreq_r - DMA memory read +//------------------------------------------------- + +inline UINT8 abc1600_state::dma_mreq_r(int index, UINT16 offset) +{ + offs_t virtual_offset = get_dma_address(index, offset); + + return read_ram(virtual_offset); +} + + +//------------------------------------------------- +// dma_mreq_w - DMA memory write +//------------------------------------------------- + +inline void abc1600_state::dma_mreq_w(int index, UINT16 offset, UINT8 data) +{ + offs_t virtual_offset = get_dma_address(index, offset); + + write_ram(virtual_offset, data); +} + + +//------------------------------------------------- +// dma_iorq_r - DMA I/O read +//------------------------------------------------- + +inline UINT8 abc1600_state::dma_iorq_r(int index, UINT16 offset) +{ + offs_t virtual_offset = get_dma_address(index, offset); + + return read_io(virtual_offset); +} + + +//------------------------------------------------- +// dma_iorq_w - DMA I/O write +//------------------------------------------------- + +inline void abc1600_state::dma_iorq_w(int index, UINT16 offset, UINT8 data) +{ + offs_t virtual_offset = get_dma_address(index, offset); + + write_io(virtual_offset, data); +} + + +//------------------------------------------------- +// dmamap_w - DMA map write +//------------------------------------------------- + +WRITE8_MEMBER( abc1600_state::dmamap_w ) +{ + /* + + bit description + + 0 X16 + 1 X17 + 2 X18 + 3 X19 + 4 X20 + 5 + 6 + 7 _R/W + + */ + + if (LOG) logerror("DMAMAP %u %02x\n", offset & 7, data); + + m_dmamap[offset & 7] = data; +} + + + +//************************************************************************** +// READ/WRITE HANDLERS +//************************************************************************** + +//------------------------------------------------- +// fw0_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc1600_state::fw0_w ) +{ + /* + + bit description + + 0 SEL1 + 1 SEL2 + 2 SEL3 + 3 MOTOR + 4 LC/PC + 5 LC/PC + 6 + 7 + + */ + + if (LOG) logerror("FW0 %02x\n", data); + + // drive select + if (BIT(data, 0)) wd17xx_set_drive(m_fdc, 0); + if (BIT(data, 1)) wd17xx_set_drive(m_fdc, 1); + if (BIT(data, 2)) wd17xx_set_drive(m_fdc, 2); + + // floppy motor + floppy_mon_w(m_floppy, !BIT(data, 3)); +} + + +//------------------------------------------------- +// fw1_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc1600_state::fw1_w ) +{ + /* + + bit description + + 0 MR + 1 DDEN + 2 HLT + 3 MINI + 4 HLD + 5 P0 + 6 P1 + 7 P2 + + */ + + if (LOG) logerror("FW1 %02x\n", data); + + // FDC master reset + wd17xx_mr_w(m_fdc, BIT(data, 0)); + + // density select + wd17xx_dden_w(m_fdc, BIT(data, 1)); +} + + +//------------------------------------------------- +// spec_contr_reg_w - +//------------------------------------------------- + +WRITE8_MEMBER( abc1600_state::spec_contr_reg_w ) +{ + int state = BIT(data, 3); + + switch (data & 0x07) + { + case 0: // CS7 + m_cs7 = state; + break; + + case 1: + break; + + case 2: // _BTCE + m_btce = state; + break; + + case 3: // _ATCE + m_atce = state; + break; + + case 4: // PARTST + m_partst = state; + break; + + case 5: // _DMADIS + m_dmadis = state; + break; + + case 6: // SYSSCC + m_sysscc = state; + + m_cio->pb5_w(!state); + m_bus1->pren_w(!state); + + update_drdy1(); + break; + + case 7: // SYSFS + m_sysfs = state; + + m_cio->pb6_w(!state); + m_bus0i->pren_w(!state); + m_bus0x->pren_w(!state); + + update_drdy0(); + break; + } +} + + + +//************************************************************************** +// ADDRESS MAPS +//************************************************************************** + +//------------------------------------------------- +// ADDRESS_MAP( abc1600_mem ) +//------------------------------------------------- + +static ADDRESS_MAP_START( abc1600_mem, AS_PROGRAM, 8, abc1600_state ) + AM_RANGE(0x00000, 0xfffff) AM_READWRITE(mac_r, mac_w) +ADDRESS_MAP_END + + + +//************************************************************************** +// INPUT PORTS +//************************************************************************** + +//------------------------------------------------- +// INPUT_PORTS( abc1600 ) +//------------------------------------------------- + +static INPUT_PORTS_START( abc1600 ) + // inputs defined in machine/abc99.c +INPUT_PORTS_END + + + +//************************************************************************** +// DEVICE CONFIGURATION +//************************************************************************** + +//------------------------------------------------- +// Z80DMA_INTERFACE( dma0_intf ) +//------------------------------------------------- + +WRITE_LINE_MEMBER( abc1600_state::dbrq_w ) +{ + m_maincpu->set_input_line(INPUT_LINE_HALT, state && m_dmadis); +} + +READ8_MEMBER( abc1600_state::dma0_mreq_r ) +{ + return dma_mreq_r(DMAMAP_R0_LO, offset); +} + +WRITE8_MEMBER( abc1600_state::dma0_mreq_w ) +{ + dma_mreq_w(DMAMAP_R0_LO, offset, data); +} + +READ8_MEMBER( abc1600_state::dma0_iorq_r ) +{ + return dma_iorq_r(DMAMAP_R0_LO, offset); +} + +WRITE8_MEMBER( abc1600_state::dma0_iorq_w ) +{ + dma_iorq_w(DMAMAP_R0_LO, offset, data); +} + +static Z80DMA_INTERFACE( dma0_intf ) +{ + DEVCB_DRIVER_LINE_MEMBER(abc1600_state, dbrq_w), + DEVCB_NULL, + DEVCB_DEVICE_LINE(Z8410AB1_1_TAG, z80dma_bai_w), + DEVCB_DRIVER_MEMBER(abc1600_state, dma0_mreq_r), + DEVCB_DRIVER_MEMBER(abc1600_state, dma0_mreq_w), + DEVCB_DRIVER_MEMBER(abc1600_state, dma0_iorq_r), + DEVCB_DRIVER_MEMBER(abc1600_state, dma0_iorq_w) +}; + + +//------------------------------------------------- +// Z80DMA_INTERFACE( dma1_intf ) +//------------------------------------------------- + +READ8_MEMBER( abc1600_state::dma1_mreq_r ) +{ + return dma_mreq_r(DMAMAP_R1_LO, offset); +} + +WRITE8_MEMBER( abc1600_state::dma1_mreq_w ) +{ + dma_mreq_w(DMAMAP_R1_LO, offset, data); +} + +READ8_MEMBER( abc1600_state::dma1_iorq_r ) +{ + return dma_iorq_r(DMAMAP_R1_LO, offset); +} + +WRITE8_MEMBER( abc1600_state::dma1_iorq_w ) +{ + dma_iorq_w(DMAMAP_R1_LO, offset, data); +} + +static Z80DMA_INTERFACE( dma1_intf ) +{ + DEVCB_DRIVER_LINE_MEMBER(abc1600_state, dbrq_w), + DEVCB_NULL, + DEVCB_DEVICE_LINE(Z8410AB1_2_TAG, z80dma_bai_w), + DEVCB_DRIVER_MEMBER(abc1600_state, dma1_mreq_r), + DEVCB_DRIVER_MEMBER(abc1600_state, dma1_mreq_w), + DEVCB_DRIVER_MEMBER(abc1600_state, dma1_iorq_r), + DEVCB_DRIVER_MEMBER(abc1600_state, dma1_iorq_w) +}; + + +//------------------------------------------------- +// Z80DMA_INTERFACE( dma2_intf ) +//------------------------------------------------- + +READ8_MEMBER( abc1600_state::dma2_mreq_r ) +{ + return dma_mreq_r(DMAMAP_R2_LO, offset); +} + +WRITE8_MEMBER( abc1600_state::dma2_mreq_w ) +{ + dma_mreq_w(DMAMAP_R2_LO, offset, data); +} + +READ8_MEMBER( abc1600_state::dma2_iorq_r ) +{ + return dma_iorq_r(DMAMAP_R2_LO, offset); +} + +WRITE8_MEMBER( abc1600_state::dma2_iorq_w ) +{ + dma_iorq_w(DMAMAP_R2_LO, offset, data); +} + +static Z80DMA_INTERFACE( dma2_intf ) +{ + DEVCB_DRIVER_LINE_MEMBER(abc1600_state, dbrq_w), + DEVCB_NULL, + DEVCB_NULL, + DEVCB_DRIVER_MEMBER(abc1600_state, dma2_mreq_r), + DEVCB_DRIVER_MEMBER(abc1600_state, dma2_mreq_w), + DEVCB_DRIVER_MEMBER(abc1600_state, dma2_iorq_r), + DEVCB_DRIVER_MEMBER(abc1600_state, dma2_iorq_w) +}; + + +//------------------------------------------------- +// Z80DART_INTERFACE( dart_intf ) +//------------------------------------------------- + +static Z80DART_INTERFACE( dart_intf ) +{ + 0, 0, 0, 0, + + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + + DEVCB_DEVICE_LINE_MEMBER(ABC99_TAG, abc99_device, txd_r), + DEVCB_DEVICE_LINE_MEMBER(ABC99_TAG, abc99_device, rxd_w), + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + + DEVCB_CPU_INPUT_LINE(MC68008P8_TAG, M68K_IRQ_5) // shared with SCC +}; + + +//------------------------------------------------- +// SCC8530_INTERFACE( sc_intf ) +//------------------------------------------------- + +void abc1600_state::scc_irq(bool status) +{ + m_maincpu->set_input_line(M68K_IRQ_5, status ? ASSERT_LINE : CLEAR_LINE); +} + + +//------------------------------------------------- +// Z8536_INTERFACE( cio_intf ) +//------------------------------------------------- + +READ8_MEMBER( abc1600_state::cio_pa_r ) +{ + /* + + bit description + + PA0 BUS2 + PA1 BUS1 + PA2 BUS0X*2 + PA3 BUS0X*3 + PA4 BUS0X*4 + PA5 BUS0X*5 + PA6 BUS0X + PA7 BUS0I + + */ + + UINT8 data = 0; + + data |= m_bus2->int_r(); + data |= m_bus1->int_r() << 1; + data |= m_bus0x->xint2_r() << 2; + data |= m_bus0x->xint3_r() << 3; + data |= m_bus0x->xint4_r() << 4; + data |= m_bus0x->xint5_r() << 5; + data |= m_bus0x->int_r() << 6; + data |= m_bus0i->int_r() << 7; + + return data; +} + +READ8_MEMBER( abc1600_state::cio_pb_r ) +{ + /* + + bit description + + PB0 + PB1 POWERFAIL + PB2 + PB3 + PB4 MINT + PB5 _PREN-1 + PB6 _PREN-0 + PB7 FINT + + */ + + UINT8 data = 0; + + data |= !m_sysscc << 5; + data |= !m_sysfs << 6; + + // floppy interrupt + data |= wd17xx_intrq_r(m_fdc) << 7; + + return data; +} + +WRITE8_MEMBER( abc1600_state::cio_pb_w ) +{ + /* + + bit description + + PB0 PRBR + PB1 + PB2 + PB3 + PB4 + PB5 + PB6 + PB7 + + */ + + // printer baudrate + int prbr = BIT(data, 0); + + z80dart_txca_w(m_dart, prbr); + z80dart_rxca_w(m_dart, prbr); +} + +READ8_MEMBER( abc1600_state::cio_pc_r ) +{ + /* + + bit description + + PC0 1 + PC1 DATA IN + PC2 1 + PC3 1 + + */ + + UINT8 data = 0x0d; + + // data in + data |= (m_rtc->dio_r() || m_nvram->do_r()) << 1; + + return data; +} + +WRITE8_MEMBER( abc1600_state::cio_pc_w ) +{ + /* + + bit description + + PC0 CLOCK + PC1 DATA OUT + PC2 RTC CS + PC3 NVRAM CS + + */ + + int clock = BIT(data, 0); + int data_out = BIT(data, 1); + int rtc_cs = BIT(data, 2); + int nvram_cs = BIT(data, 3); + + if (LOG) logerror("CLK %u DATA %u RTC %u NVRAM %u\n", clock, data_out, rtc_cs, nvram_cs); + + m_rtc->cs_w(rtc_cs); + m_rtc->dio_w(data_out); + m_rtc->clk_w(clock); + + m_nvram->cs_w(nvram_cs); + m_nvram->di_w(data_out); + m_nvram->sk_w(clock); +} + +static Z8536_INTERFACE( cio_intf ) +{ + DEVCB_CPU_INPUT_LINE(MC68008P8_TAG, M68K_IRQ_2), + DEVCB_DRIVER_MEMBER(abc1600_state, cio_pa_r), + DEVCB_NULL, + DEVCB_DRIVER_MEMBER(abc1600_state, cio_pb_r), + DEVCB_DRIVER_MEMBER(abc1600_state, cio_pb_w), + DEVCB_DRIVER_MEMBER(abc1600_state, cio_pc_r), + DEVCB_DRIVER_MEMBER(abc1600_state, cio_pc_w) +}; + + +//------------------------------------------------- +// wd17xx_interface fdc_intf +//------------------------------------------------- + +static LEGACY_FLOPPY_OPTIONS_START( abc1600 ) + LEGACY_FLOPPY_OPTION(abc1600, "dsk", "Luxor ABC 1600", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([2]) + TRACKS([80]) + SECTORS([16]) + SECTOR_LENGTH([256]) + FIRST_SECTOR_ID([1])) +LEGACY_FLOPPY_OPTIONS_END + +static const floppy_interface abc1600_floppy_interface = +{ + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + FLOPPY_STANDARD_5_25_DSQD, + LEGACY_FLOPPY_OPTIONS_NAME(abc1600), + "floppy_5_25", + NULL +}; + +WRITE_LINE_MEMBER( abc1600_state::drq_w ) +{ + update_drdy0(); +} + +static const wd17xx_interface fdc_intf = +{ + DEVCB_NULL, + DEVCB_DEVICE_LINE_MEMBER(Z8536B1_TAG, z8536_device, pb7_w), + DEVCB_DRIVER_LINE_MEMBER(abc1600_state, drq_w), + { FLOPPY_0, NULL, NULL, NULL } // TODO should be { NULL, NULL, FLOPPY_2, NULL } +}; + + +//------------------------------------------------- +// ABC99_INTERFACE( abc99_intf ) +//------------------------------------------------- + +static ABC99_INTERFACE( abc99_intf ) +{ + DEVCB_DEVICE_LINE(Z8470AB1_TAG, z80dart_rxtxcb_w), + DEVCB_DEVICE_LINE(Z8470AB1_TAG, z80dart_dcdb_w) +}; + + +//------------------------------------------------- +// ABC1600BUS_INTERFACE( abcbus_intf ) +//------------------------------------------------- + +static SLOT_INTERFACE_START( abc1600bus_cards ) + SLOT_INTERFACE("4105", LUXOR_4105) // SASI interface +// SLOT_INTERFACE("4077", LUXOR_4077) // Winchester controller +// SLOT_INTERFACE("4004", LUXOR_4004) // ICOM I/O (Z80, Z80PIO, Z80SIO/2, Z80CTC, 2 Z80DMAs, 2 PROMs, 64KB RAM) +SLOT_INTERFACE_END + +static ABC1600BUS_INTERFACE( bus0i_intf ) +{ + DEVCB_DEVICE_LINE_MEMBER(Z8536B1_TAG, z8536_device, pa7_w), // really inverted but ASSERT_LINE takes care of that + DEVCB_NULL, + DEVCB_NULL +}; + +WRITE_LINE_MEMBER( abc1600_state::nmi_w ) +{ + if (state == ASSERT_LINE) + { + m_maincpu->set_input_line(M68K_IRQ_7, ASSERT_LINE); + } +} + +static ABC1600BUS_INTERFACE( bus0x_intf ) +{ + DEVCB_DEVICE_LINE_MEMBER(Z8536B1_TAG, z8536_device, pa6_w), // really inverted but ASSERT_LINE takes care of that + DEVCB_NULL, + DEVCB_NULL, + DEVCB_DRIVER_LINE_MEMBER(abc1600_state, nmi_w), + DEVCB_DEVICE_LINE_MEMBER(Z8536B1_TAG, z8536_device, pa2_w), // really inverted but ASSERT_LINE takes care of that + DEVCB_DEVICE_LINE_MEMBER(Z8536B1_TAG, z8536_device, pa3_w), // really inverted but ASSERT_LINE takes care of that + DEVCB_DEVICE_LINE_MEMBER(Z8536B1_TAG, z8536_device, pa4_w), // really inverted but ASSERT_LINE takes care of that + DEVCB_DEVICE_LINE_MEMBER(Z8536B1_TAG, z8536_device, pa5_w) // really inverted but ASSERT_LINE takes care of that +}; + +static ABC1600BUS_INTERFACE( bus1_intf ) +{ + DEVCB_DEVICE_LINE_MEMBER(Z8536B1_TAG, z8536_device, pa1_w), // really inverted but ASSERT_LINE takes care of that + DEVCB_NULL, + DEVCB_NULL +}; + +static ABC1600BUS_INTERFACE( bus2_intf ) +{ + DEVCB_DEVICE_LINE_MEMBER(Z8536B1_TAG, z8536_device, pa0_w), // really inverted but ASSERT_LINE takes care of that + DEVCB_NULL, // DEVCB_DEVICE_LINE_MEMBER(Z8410AB1_2_TAG, z80dma_device, iei_w) inverted + DEVCB_DEVICE_LINE_MEMBER(Z8410AB1_2_TAG, z80dma_device, rdy_w) +}; + + + +//************************************************************************** +// MACHINE INITIALIZATION +//************************************************************************** + +//------------------------------------------------- +// IRQ_CALLBACK( abc1600_int_ack ) +//------------------------------------------------- + +static IRQ_CALLBACK( abc1600_int_ack ) +{ + abc1600_state *state = device->machine().driver_data<abc1600_state>(); + int data = 0; + + switch (irqline) + { + case M68K_IRQ_2: + data = state->m_cio->intack_r(); + break; + + case M68K_IRQ_5: + data = state->m_dart->m1_r(); + break; + + case M68K_IRQ_7: + state->m_maincpu->set_input_line(M68K_IRQ_7, CLEAR_LINE); + + data = M68K_INT_ACK_AUTOVECTOR; + break; + } + + return data; +} + + +//------------------------------------------------- +// MACHINE_START( abc1600 ) +//------------------------------------------------- + +void abc1600_state::machine_start() +{ + // interrupt callback + device_set_irq_callback(m_maincpu, abc1600_int_ack); + + // HACK fill segment RAM with non-zero values or no boot + memset(m_segment_ram, 0xcd, 0x400); + + // state saving + save_item(NAME(m_ifc2)); + save_item(NAME(m_task)); + save_item(NAME(m_segment_ram)); + save_item(NAME(m_page_ram)); + save_item(NAME(m_dmamap)); + save_item(NAME(m_dmadis)); + save_item(NAME(m_sysscc)); + save_item(NAME(m_sysfs)); + save_item(NAME(m_cause)); + save_item(NAME(m_partst)); + save_item(NAME(m_cs7)); + save_item(NAME(m_bus0)); + save_item(NAME(m_csb)); + save_item(NAME(m_atce)); + save_item(NAME(m_btce)); +} + + +//------------------------------------------------- +// MACHINE_RESET( abc1600 ) +//------------------------------------------------- + +void abc1600_state::machine_reset() +{ + address_space *program = m_maincpu->memory().space(AS_PROGRAM); + + // clear special control register + for (int i = 0; i < 8; i++) + { + spec_contr_reg_w(*program, 0, i); + } + + // clear floppy registers + fw0_w(*program, 0, 0); + fw1_w(*program, 0, 0); + + // clear task register + m_task = 0; + + // disable display + m_clocks_disabled = 1; + m_endisp = 0; + + // clear NMI + m_maincpu->set_input_line(M68K_IRQ_7, CLEAR_LINE); +} + + + +//************************************************************************** +// MACHINE CONFIGURATION +//************************************************************************** + +//------------------------------------------------- +// MACHINE_CONFIG( abc1600 ) +//------------------------------------------------- + +static MACHINE_CONFIG_START( abc1600, abc1600_state ) + // basic machine hardware + MCFG_CPU_ADD(MC68008P8_TAG, M68008, XTAL_64MHz/8) + MCFG_CPU_PROGRAM_MAP(abc1600_mem) + MCFG_WATCHDOG_TIME_INIT(attotime::from_msec(1600)) // XTAL_64MHz/8/10/20000/8/8 + + // video hardware + MCFG_FRAGMENT_ADD(abc1600_video) + + // devices + MCFG_Z80DMA_ADD(Z8410AB1_0_TAG, XTAL_64MHz/16, dma0_intf) + MCFG_Z80DMA_ADD(Z8410AB1_1_TAG, XTAL_64MHz/16, dma1_intf) + MCFG_Z80DMA_ADD(Z8410AB1_2_TAG, XTAL_64MHz/16, dma2_intf) + MCFG_Z80DART_ADD(Z8470AB1_TAG, XTAL_64MHz/16, dart_intf) + MCFG_SCC8530_ADD(Z8530B1_TAG, XTAL_64MHz/16, line_cb_t(FUNC(abc1600_state::scc_irq), static_cast<abc1600_state *>(owner))) + MCFG_Z8536_ADD(Z8536B1_TAG, XTAL_64MHz/16, cio_intf) + MCFG_NMC9306_ADD(NMC9306_TAG) + MCFG_E0516_ADD(E050_C16PC_TAG, XTAL_32_768kHz) + MCFG_FD1797_ADD(SAB1797_02P_TAG, fdc_intf) + MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, abc1600_floppy_interface) + MCFG_DEVICE_ADD("harddisk0", SCSIHD, 0) + MCFG_ABC99_ADD(abc99_intf) + MCFG_S1410_ADD() + + MCFG_ABC1600BUS_SLOT_ADD("bus0i", bus0i_intf, abc1600bus_cards, NULL, NULL) + MCFG_ABC1600BUS_SLOT_ADD("bus0x", bus0x_intf, abc1600bus_cards, NULL, NULL) + MCFG_ABC1600BUS_SLOT_ADD("bus1", bus1_intf, abc1600bus_cards, NULL, NULL) + MCFG_ABC1600BUS_SLOT_ADD("bus2", bus2_intf, abc1600bus_cards, "4105", NULL) + + // internal ram + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("1M") + + // software list + MCFG_SOFTWARE_LIST_ADD("flop_list", "abc1600") +MACHINE_CONFIG_END + + + +//************************************************************************** +// ROMS +//************************************************************************** + +//------------------------------------------------- +// ROM( abc1600 ) +//------------------------------------------------- + +ROM_START( abc1600 ) + ROM_REGION( 0x4000, MC68008P8_TAG, 0 ) + ROM_LOAD( "boot 6490356-04.1f", 0x0000, 0x4000, CRC(9372f6f2) SHA1(86f0681f7ef8dd190b49eda5e781881582e0c2a4) ) + + ROM_REGION( 0x2000, "wrmsk", 0 ) + ROM_LOAD( "wrmskl 6490362-01.1g", 0x0000, 0x1000, CRC(bc737538) SHA1(80e2c3757eb7f713018808d6e41ebef612425028) ) + ROM_LOAD( "wrmskh 6490363-01.1j", 0x1000, 0x1000, CRC(6b7c9f0b) SHA1(7155a993adcf08a5a8a2f22becf9fd66fda698be) ) + + ROM_REGION( 0x200, "shinf", 0 ) + ROM_LOAD( "shinf 6490361-01.1f", 0x000, 0x200, CRC(20260f8f) SHA1(29bf49c64e7cc7592e88cde2768ac57c7ce5e085) ) + + ROM_REGION( 0x40, "drmsk", 0 ) + ROM_LOAD( "drmskl 6490359-01.1k", 0x00, 0x20, CRC(6e71087c) SHA1(0acf67700d6227f4b315cf8fb0fb31c0e7fb9496) ) + ROM_LOAD( "drmskh 6490358-01.1l", 0x20, 0x20, CRC(a4a9a9dc) SHA1(d8575c0335d6021cbb5f7bcd298b41c35294a80a) ) + + ROM_REGION( 0x71c, "plds", 0 ) + ROM_LOAD( "drmsk 6490360-01.1m", 0x000, 0x104, CRC(5f7143c1) SHA1(1129917845f8e505998b15288f02bf907487e4ac) ) // mover word mixer @ 1m,1n,1t,2t + ROM_LOAD( "1020 6490349-01.8b", 0x104, 0x104, CRC(1fa065eb) SHA1(20a95940e39fa98e97e59ea1e548ac2e0c9a3444) ) // expansion bus strobes + ROM_LOAD( "1021 6490350-01.5d", 0x208, 0x104, CRC(96f6f44b) SHA1(12d1cd153dcc99d1c4a6c834122f370d49723674) ) // interrupt encoder and ROM/RAM control + ROM_LOAD( "1022 6490351-01.17e", 0x30c, 0x104, CRC(5dd00d43) SHA1(a3871f0d796bea9df8f25d41b3169dd4b8ef65ab) ) // MAC register address decoder + ROM_LOAD( "1023 6490352-01.11e", 0x410, 0x104, CRC(a2f350ac) SHA1(77e08654a197080fa2111bc3031cd2c7699bf82b) ) // interrupt acknowledge + ROM_LOAD( "1024 6490353-01.12e", 0x514, 0x104, CRC(67f1328a) SHA1(b585495fe14a7ae2fbb29f722dca106d59325002) ) // expansion bus timing and control + ROM_LOAD( "1025 6490354-01.6e", 0x618, 0x104, CRC(9bda0468) SHA1(ad373995dcc18532274efad76fa80bd13c23df25) ) // DMA transfer + //ROM_LOAD( "pal16r4.10c", 0x71c, 0x104, NO_DUMP ) // SCC read/write, mentioned in the preliminary service manual, but not present on the PCB +ROM_END + + + +//************************************************************************** +// SYSTEM DRIVERS +//************************************************************************** + +// YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS +COMP( 1985, abc1600, 0, 0, abc1600, abc1600, driver_device, 0, "Luxor", "ABC 1600", GAME_NOT_WORKING ) |