working on mockingboard interrupts

This commit is contained in:
Jorj Bauer 2017-05-31 18:17:25 -04:00
parent 8c7a97ee54
commit ccc649bfc1
6 changed files with 69 additions and 4 deletions

View File

@ -23,8 +23,10 @@ AppleVM::AppleVM()
parallel = new ParallelCard();
((AppleMMU *)mmu)->setSlot(1, parallel);
mockingboard = NULL;
/*
mockingboard = new Mockingboard();
((AppleMMU *)mmu)->setSlot(4, mockingboard);
((AppleMMU *)mmu)->setSlot(4, mockingboard);*/
#ifdef TEENSYDUINO
teensyClock = new TeensyClock((AppleMMU *)mmu);

View File

@ -1,6 +1,8 @@
#include "sy6522.h"
#include <stdio.h>
#include "globals.h"
SY6522::SY6522()
{
ORB = ORA = 0;
@ -25,7 +27,7 @@ uint8_t SY6522::read(uint8_t address)
case SY_DDRA:
return DDRA;
case SY_TMR1L:
// FIXME: also updates IFR?
IFR &= ~SY_IR_TIMER1;
return (T1_CTR & 0xFF);
case SY_TMR1H:
return (T1_CTR >> 8);
@ -34,7 +36,7 @@ uint8_t SY6522::read(uint8_t address)
case SY_TMR1HL:
return (T1_CTR_LATCH >> 8);
case SY_TMR2L:
// FIXME: alos udpates IFR?
IFR &= ~SY_IR_TIMER2;
return (T2_CTR & 0xFF);
case SY_TMR2H:
return (T2_CTR >> 8);
@ -82,6 +84,15 @@ uint8_t SY6522::read(uint8_t address)
return;
case SY_TMR1H:
IFR &= SY_IR_TIMER1;
// Update IFR?
IFR &= 0x7F;
if (IFR & IER) {
// an interrupt is happening; keep the IE flag on
IFR |= 0x80;
}
// FIXME: clear interrupt flag
T1_CTR_LATCH = (T1_CTR_LATCH & 0x00FF) | (val << 8);
T1_CTR = T1_CTR_LATCH;
@ -145,6 +156,26 @@ uint8_t SY6522::read(uint8_t address)
void SY6522::update(uint32_t cycles)
{
/* Update 6522 timers */
// ...
/*
SY_IR_CA2 = 1,
SY_IR_CA1 = 2,
SY_IR_SHIFTREG = 4,
SY_IR_CB2 = 8,
SY_IR_CB1 = 16,
SY_IR_TIMER2 = 32,
SY_IR_TIMER1 = 64,
SY_IER_SETCLEAR = 128,
SY_IFR_IRQ = 128
*/
/* Check for 6522 interrupts */
if (IFR & 0x80) {
g_cpu->stageIRQ();
}
/* Update the attached 8910 chip(s) */
ay8910[0].update(cycles);
}

View File

@ -25,6 +25,19 @@ enum {
SY_ORANOHS = 0x0f // ORA_NO_HS
};
// IFR and IER share the names of all but the high bit
enum {
SY_IR_CA2 = 1,
SY_IR_CA1 = 2,
SY_IR_SHIFTREG = 4,
SY_IR_CB2 = 8,
SY_IR_CB1 = 16,
SY_IR_TIMER2 = 32,
SY_IR_TIMER1 = 64,
SY_IER_SETCLEAR = 128,
SY_IFR_IRQ = 128
};
class SY6522 {
public:
SY6522();

10
cpu.cpp
View File

@ -407,6 +407,7 @@ void Cpu::Reset()
x = 0;
y = 0;
flags = F_Z | F_UNK; // FIXME: is that F_UNK flag right here?
irqPending = false;
if (mmu) {
pc = readmem(0xFFFC) | (readmem(0xFFFD) << 8);
@ -495,6 +496,11 @@ uint8_t Cpu::Run(uint8_t numSteps)
uint8_t Cpu::step()
{
if (irqPending) {
irqPending = false;
irq();
}
uint8_t m = readmem(pc++);
optype_t opcode = opcodes[m];
@ -1050,3 +1056,7 @@ uint16_t Cpu::popS16()
return (msb << 8) | lsb;
}
void Cpu::stageIRQ()
{
irqPending = true;
}

4
cpu.h
View File

@ -45,6 +45,8 @@ class Cpu {
uint8_t SP();
uint8_t P();
void stageIRQ();
protected:
// Stack manipulation
void pushS8(uint8_t b);
@ -64,6 +66,8 @@ class Cpu {
uint8_t flags;
uint32_t cycles;
bool irqPending;
MMU *mmu;
};

View File

@ -133,14 +133,19 @@ void SDLSpeaker::maintainSpeaker(uint32_t c)
// The "terribad" audio gets two shares. THis means we've got 8 total
// "voices" -- 6 from the mockingboard and 2 from the built-in. 8 is
// a great number for dividing. :)
mixerValue += (toggleState ? 0xFF : 0x00);
mixerValue += (toggleState ? 0x1FF : 0x00);
numMixed += 2;
#if 0
if (numMixed != 8) {
printf("SPEAKER FAIL - should always be 8\n");
}
mixerValue >>= 3; // divide by 8
#else
mixerValue /= numMixed;
#endif
// FIXME: g_volume