aiie/apple/sy6522.cpp

151 lines
2.7 KiB
C++

#include "sy6522.h"
#include <stdio.h>
SY6522::SY6522()
{
ORB = ORA = 0;
DDRB = DDRA = 0x00;
T1_CTR = T2_CTR = 0;
T1_CTR_LATCH = T2_CTR_LATCH = 0;
ACR = 0x20; // free-running; FIXME: constant?
PCR = 0xB0; // FIXME: ?
IFR = 0x00; // FIXME: ?
IER = 0x90; // FIXME: ?
}
uint8_t SY6522::read(uint8_t address)
{
switch (address) {
case SY_ORB:
return ORB;
case SY_ORA:
return ORA;
case SY_DDRB:
return DDRB;
case SY_DDRA:
return DDRA;
case SY_TMR1L:
// FIXME: also updates IFR?
return (T1_CTR & 0xFF);
case SY_TMR1H:
return (T1_CTR >> 8);
case SY_TMR1LL:
return (T1_CTR_LATCH & 0xFF);
case SY_TMR1HL:
return (T1_CTR_LATCH >> 8);
case SY_TMR2L:
// FIXME: alos udpates IFR?
return (T2_CTR & 0xFF);
case SY_TMR2H:
return (T2_CTR >> 8);
case SY_SS:
// FIXME: floating
return 0xFF;
case SY_ACR:
return ACR;
case SY_PCR:
return PCR;
case SY_IFR:
return IFR;
case SY_IER:
return 0x80 | IER;
case SY_ORANOHS:
return ORA;
}
return 0xFF;
}
void SY6522::write(uint8_t address, uint8_t val)
{
switch (address) {
case SY_ORB:
val &= DDRB;
ORB = val;
ay8910[0].write(val, ORA & DDRA);
return;
case SY_ORA:
ORA = val & DDRA;
return;
case SY_DDRB:
DDRB = val;
return;
case SY_DDRA:
DDRA = val;
return;
case SY_TMR1L:
case SY_TMR1LL:
T1_CTR_LATCH = (T1_CTR_LATCH & 0xFF00) | val;
return;
case SY_TMR1H:
// FIXME: clear interrupt flag
T1_CTR_LATCH = (T1_CTR_LATCH & 0x00FF) | (val << 8);
T1_CTR = T1_CTR_LATCH;
// FIXME: start timer?
return;
case SY_TMR1HL:
T1_CTR_LATCH = (T1_CTR_LATCH & 0x00FF) | (val << 8);
// FIXME: clear interrupt flag
return;
case SY_TMR2L:
T2_CTR_LATCH = (T2_CTR_LATCH & 0xFF00) | val;
return;
case SY_TMR2H:
// FIXME: clear timer2 interrupt flag
T2_CTR_LATCH = (T2_CTR_LATCH & 0x00FF) | (val << 8);
T2_CTR = T2_CTR_LATCH;
return;
case SY_SS:
// FIXME: what is this for?
return;
case SY_ACR:
ACR = val;
break;
case SY_PCR:
PCR = val;
break;
case SY_IFR:
// Clear whatever low bits are set in IFR.
val |= 0x80;
val ^= 0x7F;
IFR &= val;
break;
case SY_IER:
if (val & 0x80) {
// Set bits based on val
val &= 0x7F;
IER |= val;
// FIXME: start timer if necessary?
} else {
// Clear whatever low bits are set in IER.
val |= 0x80;
val ^= 0x7F;
IER &= val;
// FIXME: stop timer if it's running?
}
return;
case SY_ORANOHS:
// FIXME: what is this for?
return;
}
}
void SY6522::update(uint32_t cycles)
{
ay8910[0].update(cycles);
}