m6502: Fixed CPU peripheral port behavior by introducing pull-up and pull-down masks to the CPU interface. [Curt Coder]

(MESS) c64: Fixed CPU port, tsuit215 CPUPORT test passes now. [Curt Coder]
This commit is contained in:
Curt Coder 2012-09-04 09:20:01 +00:00
parent 40a39cedf1
commit 3007da08e0
3 changed files with 70 additions and 31 deletions

View File

@ -80,7 +80,10 @@ struct _m6502_Regs
write8_space_func wrmem_id; /* writemem callback for indexed instructions */
UINT8 ddr;
UINT8 port;
UINT8 port;
UINT8 mask;
UINT8 pullup;
UINT8 pulldown;
devcb_resolved_read8 in_port_func;
devcb_resolved_write8 out_port_func;
@ -154,11 +157,15 @@ static void m6502_common_init(legacy_cpu_device *device, device_irq_acknowledge_
cpustate->in_port_func.resolve(intf->in_port_func, *device);
cpustate->out_port_func.resolve(intf->out_port_func, *device);
cpustate->pullup = intf->external_port_pullup;
cpustate->pulldown = intf->external_port_pulldown;
}
else
{
devcb_write8 nullcb = DEVCB_NULL;
cpustate->out_port_func.resolve(nullcb, *device);
cpustate->pullup = 0;
cpustate->pulldown = 0;
}
device->save_item(NAME(cpustate->pc.w.l));
@ -176,7 +183,10 @@ static void m6502_common_init(legacy_cpu_device *device, device_irq_acknowledge_
if (subtype == SUBTYPE_6510)
{
device->save_item(NAME(cpustate->port));
device->save_item(NAME(cpustate->mask));
device->save_item(NAME(cpustate->ddr));
device->save_item(NAME(cpustate->pullup));
device->save_item(NAME(cpustate->pulldown));
}
}
@ -355,6 +365,7 @@ static CPU_RESET( m6510 )
CPU_RESET_CALL(m6502);
cpustate->port = 0xff;
cpustate->mask = 0xff;
cpustate->ddr = 0x00;
}
@ -374,11 +385,19 @@ static READ8_HANDLER( m6510_read_0000 )
case 0x0000: /* DDR */
result = cpustate->ddr;
break;
case 0x0001: /* Data Port */
result = cpustate->in_port_func(cpustate->ddr);
result = (cpustate->ddr & cpustate->port) | (~cpustate->ddr & result);
{
UINT8 input = cpustate->in_port_func(0) & ~cpustate->ddr;
UINT8 mask = cpustate->mask & ~cpustate->ddr;
UINT8 output = cpustate->port & cpustate->ddr;
UINT8 pulldown = ~(cpustate->pulldown & ~cpustate->ddr);
result = (input | mask | output) & pulldown;
}
break;
}
return result;
}
@ -389,14 +408,24 @@ static WRITE8_HANDLER( m6510_write_0000 )
switch(offset)
{
case 0x0000: /* DDR */
cpustate->ddr = data;
if (cpustate->ddr != data)
{
cpustate->ddr = data;
cpustate->mask = cpustate->port;
}
break;
case 0x0001: /* Data Port */
cpustate->port = data;
break;
}
cpustate->out_port_func(cpustate->ddr, cpustate->port & cpustate->ddr);
UINT8 output = (cpustate->port & cpustate->ddr) | (cpustate->pullup & ~cpustate->ddr);
cpustate->out_port_func(0, output);
// TODO assert write with floating data lines
//WRMEM(offset, 0xff);
}
static ADDRESS_MAP_START(m6510_mem, AS_PROGRAM, 8, legacy_cpu_device)

View File

@ -53,6 +53,9 @@ enum
/* Optional interface to set callbacks */
#define M6510_INTERFACE(name) \
const m6502_interface (name) =
typedef struct _m6502_interface m6502_interface;
struct _m6502_interface
{
@ -60,6 +63,8 @@ struct _m6502_interface
write8_space_func write_indexed_func;
devcb_read8 in_port_func;
devcb_write8 out_port_func;
UINT8 external_port_pullup;
UINT8 external_port_pulldown;
};
DECLARE_LEGACY_CPU_DEVICE(M6502, m6502);

View File

@ -2,10 +2,9 @@
TODO:
- floating bus writes to peripheral registers in m6502.c
- sort out kernals between PAL/NTSC
- tsuit215 test failures
- CPUPORT (0=FF 1=FF 0=00 1=FF 1=FF 1=FF, AFTER 00 17, RIGHT 00 DF)
- IRQ (WRONG $DC0D)
- NMI (WRONG $DD0D)
- all CIA tests
@ -188,6 +187,12 @@ WRITE8_MEMBER( c64_state::write )
bankswitch(offset, va, rw, aec, ba, cas, &casram, &basic, &kernal, &charom, &grw, &io, &roml, &romh);
if (offset < 0x0002)
{
// write to internal CPU register
data = m_vic->bus_r();
}
if (!casram)
{
m_ram->pointer()[offset] = data;
@ -658,9 +663,9 @@ READ8_MEMBER( c64_state::cpu_r )
P0 1
P1 1
P2 1
P3
P3
P4 CASS SENS
P5
P5 0
*/
@ -686,9 +691,7 @@ WRITE8_MEMBER( c64_state::cpu_w )
*/
// HACK apply pull-up resistors
data |= (offset ^ 0x07) & 0x07;
// memory banking
m_loram = BIT(data, 0);
m_hiram = BIT(data, 1);
m_charen = BIT(data, 2);
@ -700,12 +703,14 @@ WRITE8_MEMBER( c64_state::cpu_w )
m_cassette->motor_w(BIT(data, 5));
}
static const m6502_interface cpu_intf =
static M6510_INTERFACE( cpu_intf )
{
NULL,
NULL,
DEVCB_DRIVER_MEMBER(c64_state, cpu_r),
DEVCB_DRIVER_MEMBER(c64_state, cpu_w)
DEVCB_DRIVER_MEMBER(c64_state, cpu_w),
0x17,
0x20
};
@ -722,13 +727,13 @@ READ8_MEMBER( sx64_state::cpu_r )
P0 1
P1 1
P2 1
P3 1
P4 1
P5 1
P3
P4
P5
*/
return 0x3f;
return 0x07;
}
WRITE8_MEMBER( sx64_state::cpu_w )
@ -746,20 +751,20 @@ WRITE8_MEMBER( sx64_state::cpu_w )
*/
// HACK apply pull-up resistors
data |= (offset ^ 0x07) & 0x07;
// memory banking
m_loram = BIT(data, 0);
m_hiram = BIT(data, 1);
m_charen = BIT(data, 2);
}
static const m6502_interface sx64_cpu_intf =
static M6510_INTERFACE( sx64_cpu_intf )
{
NULL,
NULL,
DEVCB_DRIVER_MEMBER(sx64_state, cpu_r),
DEVCB_DRIVER_MEMBER(sx64_state, cpu_w)
DEVCB_DRIVER_MEMBER(sx64_state, cpu_w),
0x07,
0x00
};
@ -776,13 +781,13 @@ READ8_MEMBER( c64gs_state::cpu_r )
P0 1
P1 1
P2 1
P3 1
P4 1
P5 1
P3
P4
P5
*/
return 0x3f;
return 0x07;
}
WRITE8_MEMBER( c64gs_state::cpu_w )
@ -800,9 +805,7 @@ WRITE8_MEMBER( c64gs_state::cpu_w )
*/
// HACK apply pull-up resistors
data |= (offset ^ 0x07) & 0x07;
// memory banking
m_loram = BIT(data, 0);
m_hiram = BIT(data, 1);
m_charen = BIT(data, 2);
@ -813,7 +816,9 @@ static const m6502_interface c64gs_cpu_intf =
NULL,
NULL,
DEVCB_DRIVER_MEMBER(c64gs_state, cpu_r),
DEVCB_DRIVER_MEMBER(c64gs_state, cpu_w)
DEVCB_DRIVER_MEMBER(c64gs_state, cpu_w),
0x07,
0x00
};