(MESS) apple3: Implement correct (zp),y extended addressing. [R. Belmont]

This commit is contained in:
R. Belmont 2014-02-02 05:31:09 +00:00
parent 6e5462526a
commit c397fcbe4b
4 changed files with 280 additions and 137 deletions

View File

@ -23,29 +23,9 @@
#include "machine/appldriv.h"
static ADDRESS_MAP_START( apple3_map, AS_PROGRAM, 8, apple3_state )
AM_RANGE(0x0000, 0x00FF) AM_READWRITE(apple3_00xx_r, apple3_00xx_w)
AM_RANGE(0x0100, 0x01FF) AM_RAMBANK("bank2")
AM_RANGE(0x0200, 0x1FFF) AM_RAMBANK("bank3")
AM_RANGE(0x2000, 0x9FFF) AM_RAMBANK("bank4")
AM_RANGE(0xA000, 0xBFFF) AM_RAMBANK("bank5")
AM_RANGE(0x0000, 0xffff) AM_READWRITE(apple3_memory_r, apple3_memory_w)
ADDRESS_MAP_END
/* the Apple /// does some weird tricks whereby it monitors the SYNC pin
* on the CPU to check for indexed instructions and directs them to
* different memory locations */
#if 0
static const m6502_interface apple3_m6502_interface =
{
DEVCB_DRIVER_MEMBER(apple3_state, apple3_indexed_read), /* read_indexed_func */
DEVCB_DRIVER_MEMBER(apple3_state, apple3_indexed_write), /* write_indexed_func */
DEVCB_NULL, /* port_read_func */
DEVCB_NULL, /* port_write_func */
0x00,
0x00
};
#endif
static const floppy_interface apple3_floppy_interface =
{
DEVCB_NULL,
@ -71,9 +51,9 @@ static const struct a2bus_interface a2bus_intf =
static MACHINE_CONFIG_START( apple3, apple3_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", M6502, 2000000) /* 2 MHz */
MCFG_M6502_SYNC_CALLBACK(WRITELINE(apple3_state, apple3_sync_w))
MCFG_CPU_PROGRAM_MAP(apple3_map)
// MCFG_CPU_CONFIG( apple3_m6502_interface )
MCFG_CPU_PERIODIC_INT_DRIVER(apple3_state, apple3_interrupt, 192)
MCFG_CPU_PERIODIC_INT_DRIVER(apple3_state, apple3_interrupt, 192)
MCFG_QUANTUM_TIME(attotime::from_hz(60))
MCFG_MACHINE_RESET_OVERRIDE(apple3_state, apple3 )

View File

@ -54,6 +54,9 @@ public:
UINT8 m_last_n;
UINT8 *m_char_mem;
UINT32 *m_hgr_map;
DECLARE_READ8_MEMBER(apple3_memory_r);
DECLARE_WRITE8_MEMBER(apple3_memory_w);
DECLARE_WRITE_LINE_MEMBER(apple3_sync_w);
DECLARE_READ8_MEMBER(apple3_c0xx_r);
DECLARE_WRITE8_MEMBER(apple3_c0xx_w);
DECLARE_READ8_MEMBER(apple3_00xx_r);
@ -84,11 +87,18 @@ public:
void apple3_profile_init(void);
void apple3_profile_statemachine(void);
UINT8 *apple3_bankaddr(UINT16 bank, offs_t offset);
void apple3_setbank(const char *mame_bank, UINT16 bank, offs_t offset);
UINT8 *apple3_get_zpa_addr(offs_t offset);
void apple3_update_memory();
void apple3_via_out(UINT8 *var, UINT8 data);
UINT8 *apple3_get_indexed_addr(offs_t offset);
bool m_sync;
UINT8 m_indir_opcode;
int m_indir_count;
UINT8 *m_bank2, *m_bank3, *m_bank4, *m_bank5, *m_bank8, *m_bank9;
UINT8 *m_bank10, *m_bank11;
UINT8 *m_bank6, *m_bank7;
};

View File

@ -10,7 +10,17 @@
VIA #1 (E VIA)
CA2: 1 if key pressed, 0 otherwise
m_via_0_a: Environment register
bit 7: 1 for 1 MHz, 0 for 2 MHz
bit 6: 1 for I/O at C000-CFFF
bit 5: 1 to enable video
bit 4: 1 to enable NMI/Reset
bit 3: 1 to write-protect RAM in system bank C000-FFFF
bit 2: 1 to force primary stack at 0100-01FF
bit 1: 1 for primary ROM, 0 for secondary (Apple III doesn't have a secondary ROM, so this should always be '1' when bit 0 is)
bit 0: 1 to enable ROM in F000-FFFF
***************************************************************************/
#include "emu.h"
@ -269,28 +279,6 @@ UINT8 *apple3_state::apple3_bankaddr(UINT16 bank, offs_t offset)
return &m_ram->pointer()[offset];
}
void apple3_state::apple3_setbank(const char *mame_bank, UINT16 bank, offs_t offset)
{
UINT8 *ptr;
ptr = apple3_bankaddr(bank, offset);
membank(mame_bank)->set_base(ptr);
#if 0
if (LOG_MEMORY)
{
#ifdef PTR64
//logerror("\tbank %s --> %02x/%04x [0x%08lx]\n", mame_bank, (unsigned) bank, (unsigned)offset, ptr - m_ram->pointer());
#else
logerror("\tbank %s --> %02x/%04x [0x%08lx]\n", mame_bank, (unsigned) bank, (unsigned)offset, ptr - m_ram->pointer());
#endif
}
#endif
}
UINT8 *apple3_state::apple3_get_zpa_addr(offs_t offset)
{
m_zpa = (((offs_t) m_via_0_b) * 0x100) + offset;
@ -303,27 +291,11 @@ UINT8 *apple3_state::apple3_get_zpa_addr(offs_t offset)
return apple3_bankaddr(m_via_1_a, m_zpa - 0x2000);
}
READ8_MEMBER(apple3_state::apple3_00xx_r)
{
return *apple3_get_zpa_addr(offset);
}
WRITE8_MEMBER(apple3_state::apple3_00xx_w)
{
*apple3_get_zpa_addr(offset) = data;
}
void apple3_state::apple3_update_memory()
{
UINT16 bank;
UINT8 page;
address_space& space = m_maincpu->space(AS_PROGRAM);
UINT8 *ptr;
if (LOG_MEMORY)
{
@ -356,95 +328,46 @@ void apple3_state::apple3_update_memory()
bank = ~0;
page = 0x01;
}
apple3_setbank("bank2", bank, ((offs_t) page) * 0x100);
m_bank2 = apple3_bankaddr(bank, ((offs_t) page) * 0x100);
/* bank 3 (0200-1FFF) */
apple3_setbank("bank3", ~0, 0x0200);
m_bank3 = apple3_bankaddr(~0, 0x0200);
/* bank 4 (2000-9FFF) */
apple3_setbank("bank4", m_via_1_a, 0x0000);
m_bank4 = apple3_bankaddr(m_via_1_a, 0x0000);
/* bank 5 (A000-BFFF) */
apple3_setbank("bank5", ~0, 0x2000);
m_bank5 = apple3_bankaddr(~0, 0x2000);
/* install bank 8 (C000-CFFF) */
if (m_via_0_a & 0x40)
/* bank 8 (C000-C0FF) */
if (!(m_via_0_a & 0x40))
{
space.install_read_handler(0xC000, 0xC0FF, read8_delegate(FUNC(apple3_state::apple3_c0xx_r),this));
space.install_write_handler(0xC000, 0xC0FF, write8_delegate(FUNC(apple3_state::apple3_c0xx_w),this));
}
else
{
space.install_read_bank(0xC000, 0xC0FF, "bank8");
if (m_via_0_a & 0x08)
space.unmap_write(0xC000, 0xC0FF);
else
space.install_write_bank(0xC000, 0xC0FF, "bank8");
apple3_setbank("bank8", ~0, 0x4000);
m_bank8 = apple3_bankaddr(~0, 0x4000);
}
/* install bank 9 (C100-C4FF) */
if (m_via_0_a & 0x40)
/* bank 9 (C100-C4FF) */
if (!(m_via_0_a & 0x40))
{
space.nop_readwrite(0xC100, 0xC4FF);
}
else
{
space.install_read_bank(0xC100, 0xC4FF, "bank9");
if (m_via_0_a & 0x08)
space.unmap_write(0xC100, 0xC4FF);
else
space.install_write_bank(0xC100, 0xC4FF, "bank9");
apple3_setbank("bank9", ~0, 0x4100);
m_bank9 = apple3_bankaddr(~0, 0x4100);
}
/* install bank 10 (C500-C7FF) */
space.install_read_bank(0xC500, 0xC7FF, "bank10");
if (m_via_0_a & 0x08)
space.unmap_write(0xC500, 0xC7FF);
else
space.install_write_bank(0xC500, 0xC7FF, "bank10");
apple3_setbank("bank10", ~0, 0x4500);
/* bank 10 (C500-C7FF) */
m_bank10 = apple3_bankaddr(~0, 0x4500);
/* install bank 11 (C800-CFFF) */
if (m_via_0_a & 0x40)
/* bank 11 (C800-CFFF) */
if (!(m_via_0_a & 0x40))
{
space.nop_readwrite(0xC800, 0xCFFF);
}
else
{
space.install_read_bank(0xC800, 0xCFFF, "bank11");
if (m_via_0_a & 0x08)
space.unmap_write(0xC800, 0xCFFF);
else
space.install_write_bank(0xC800, 0xCFFF, "bank11");
apple3_setbank("bank11", ~0, 0x4800);
m_bank11 = apple3_bankaddr(~0, 0x4800);
}
/* install bank 6 (D000-EFFF) */
space.install_read_bank(0xD000, 0xEFFF, "bank6");
if (m_via_0_a & 0x08)
space.unmap_write(0xD000, 0xEFFF);
else
space.install_write_bank(0xD000, 0xEFFF, "bank6");
apple3_setbank("bank6", ~0, 0x5000);
m_bank6 = apple3_bankaddr(~0, 0x5000);
/* install bank 7 (F000-FFFF) */
space.install_read_bank(0xF000, 0xFFFF, "bank7");
if (m_via_0_a & 0x09)
space.unmap_write(0xF000, 0xFFFF);
else
space.install_write_bank(0xF000, 0xFFFF, "bank7");
if (m_via_0_a & 0x01)
membank("bank7")->set_base(memregion("maincpu")->base());
m_bank7 = memregion("maincpu")->base();
else
apple3_setbank("bank7", ~0, 0x7000);
/* reinstall VIA handlers */
{
space.install_readwrite_handler(0xFFD0, 0xFFDF, 0, 0, read8_delegate(FUNC(via6522_device::read),m_via_0.target()), write8_delegate(FUNC(via6522_device::write),m_via_0.target()));
space.install_readwrite_handler(0xFFE0, 0xFFEF, 0, 0, read8_delegate(FUNC(via6522_device::read),m_via_1.target()), write8_delegate(FUNC(via6522_device::write),m_via_1.target()));
}
m_bank7 = apple3_bankaddr(~0, 0x7000);
}
@ -493,6 +416,8 @@ WRITE_LINE_MEMBER(apple3_state::apple2_via_1_irq_func)
MACHINE_RESET_MEMBER(apple3_state,apple3)
{
m_indir_count = 0;
m_sync = false;
}
@ -556,15 +481,11 @@ UINT8 *apple3_state::apple3_get_indexed_addr(offs_t offset)
}
else if ((offset >= 0xF000) && (m_via_0_a & 0x01))
{
#if 0
/* The Apple /// Diagnostics seems to expect that indexed writes
* always write to RAM. That image jumps to an address that is
* undefined unless this code is enabled. However, the Sara
* emulator does not have corresponding code here, though Chris
* Smolinski does not rule out the possibility
*/
* undefined unless this code is enabled.
*/
result = apple3_bankaddr(~0, offset - 0x8000);
#endif
}
return result;
@ -705,3 +626,232 @@ DRIVER_INIT_MEMBER(apple3_state,apple3)
m_maincpu->space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(apple3_state::apple3_opbase), this));
}
READ8_MEMBER(apple3_state::apple3_memory_r)
{
UINT8 rv = 0xff;
// (zp), y read
if (!space.debugger_access())
{
if (m_indir_count == 4)
{
UINT8 *test;
// printf("doing redirect on (zp),y, offset %x\n", offset);
test = apple3_get_indexed_addr(offset);
if (test)
{
return *test;
}
}
}
if (offset < 0x100)
{
rv = *apple3_get_zpa_addr(offset);
}
else if (offset < 0x200)
{
rv = m_bank2[offset-0x100];
}
else if (offset < 0x2000)
{
rv = m_bank3[offset-0x200];
}
else if (offset < 0xa000)
{
rv = m_bank4[offset-0x2000];
}
else if (offset < 0xc000)
{
rv = m_bank5[offset-0xa000];
}
else if (offset < 0xc100)
{
if (m_via_0_a & 0x40)
{
rv = apple3_c0xx_r(space, offset-0xc000);
}
else
{
rv = m_bank8[offset - 0xc000];
}
}
else if (offset < 0xc500)
{
if (!(m_via_0_a & 0x40))
{
rv = m_bank9[offset - 0xc100];
}
}
else if (offset < 0xc800)
{
rv = m_bank10[offset - 0xc500];
}
else if (offset < 0xd000)
{
if (!(m_via_0_a & 0x40))
{
rv = m_bank11[offset - 0xc800];
}
}
else if (offset < 0xf000)
{
rv = m_bank6[offset - 0xd000];
}
else
{
if (offset >= 0xffd0 && offset <= 0xffdf)
{
rv = m_via_0->read(space, offset);
}
else if (offset >= 0xffe0 && offset <= 0xffef)
{
rv = m_via_1->read(space, offset);
}
else
{
rv = m_bank7[offset - 0xf000];
}
}
if (!space.debugger_access())
{
if (m_indir_count > 0)
{
m_indir_count++;
}
// capture last opcode for indirect mode shenanigans
if (m_sync)
{
// 0xN1 with bit 4 set is a (zp),y opcode
if (((rv & 0x0f) == 0x1) && (rv & 0x10))
{
// printf("(zp),y %02x at %x\n", rv, offset);
m_indir_count = 1;
m_indir_opcode = rv;
}
}
}
return rv;
}
WRITE8_MEMBER(apple3_state::apple3_memory_w)
{
if ((!space.debugger_access()) && (m_indir_count > 0))
{
UINT8 *test;
// printf("store (zp),y %02x at %x\n", data, offset);
test = apple3_get_indexed_addr(offset);
if (test)
{
*test = data;
return;
}
}
if (offset < 0x100)
{
*apple3_get_zpa_addr(offset) = data;
return;
}
else if (offset < 0x200)
{
m_bank2[offset-0x100] = data;
}
else if (offset < 0x2000)
{
m_bank3[offset-0x200] = data;
}
else if (offset < 0xa000)
{
m_bank4[offset-0x2000] = data;
}
else if (offset < 0xc000)
{
m_bank5[offset-0xa000] = data;
}
else if (offset < 0xc100)
{
if (m_via_0_a & 0x40)
{
apple3_c0xx_w(space, offset-0xc000, data);
}
else
{
// is this page write protected?
if (!(m_via_0_a & 0x08))
{
m_bank8[offset - 0xc000] = data;
}
}
}
else if (offset < 0xc500)
{
if (!(m_via_0_a & 0x40))
{
if (!(m_via_0_a & 0x08))
{
m_bank9[offset - 0xc100] = data;
}
}
}
else if (offset < 0xc800)
{
if (!(m_via_0_a & 0x08))
{
m_bank10[offset - 0xc500] = data;
}
}
else if (offset < 0xd000)
{
if (!(m_via_0_a & 0x40))
{
if (!(m_via_0_a & 0x08))
{
m_bank11[offset - 0xc800] = data;
}
}
}
else if (offset < 0xf000)
{
if (!(m_via_0_a & 0x08))
{
m_bank6[offset - 0xd000] = data;
}
}
else
{
if (offset >= 0xffd0 && offset <= 0xffdf)
{
m_via_0->write(space, offset, data);
}
else if (offset >= 0xffe0 && offset <= 0xffef)
{
m_via_1->write(space, offset, data);
}
else
{
if (!(m_via_0_a & 0x09))
{
m_bank7[offset - 0xf000] = data;
}
}
}
}
WRITE_LINE_MEMBER(apple3_state::apple3_sync_w)
{
// printf("sync: %d\n", state);
m_sync = (state == ASSERT_LINE) ? true : false;
if (m_sync)
{
m_indir_count = 0;
}
}

View File

@ -2333,6 +2333,9 @@ $(MESS_VIDEO)/apple2.o: $(MESSSRC)/includes/apple2.h
$(MESS_DRIVERS)/apple2gs.o: $(MESSSRC)/includes/apple2.h $(MESSSRC)/includes/apple2gs.h
$(MESS_MACHINE)/apple2gs.o: $(MESSSRC)/includes/apple2.h $(MESSSRC)/includes/apple2gs.h
$(MESS_VIDEO)/apple2gs.o: $(MESSSRC)/includes/apple2.h $(MESSSRC)/includes/apple2gs.h
$(MESS_DRIVERS)/apple3.o: $(MESSSRC)/includes/apple3.h
$(MESS_MACHINE)/apple3.o: $(MESSSRC)/includes/apple3.h
$(MESS_VIDEO)/apple3.o: $(MESSSRC)/includes/apple3.h
# $(MESSSRC)/drivers/apollo.c includes m68kcpu.h and m68kcpu.h now includes m68kops.h