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(); parallel = new ParallelCard();
((AppleMMU *)mmu)->setSlot(1, parallel); ((AppleMMU *)mmu)->setSlot(1, parallel);
mockingboard = NULL;
/*
mockingboard = new Mockingboard(); mockingboard = new Mockingboard();
((AppleMMU *)mmu)->setSlot(4, mockingboard); ((AppleMMU *)mmu)->setSlot(4, mockingboard);*/
#ifdef TEENSYDUINO #ifdef TEENSYDUINO
teensyClock = new TeensyClock((AppleMMU *)mmu); teensyClock = new TeensyClock((AppleMMU *)mmu);

View File

@ -1,6 +1,8 @@
#include "sy6522.h" #include "sy6522.h"
#include <stdio.h> #include <stdio.h>
#include "globals.h"
SY6522::SY6522() SY6522::SY6522()
{ {
ORB = ORA = 0; ORB = ORA = 0;
@ -25,7 +27,7 @@ uint8_t SY6522::read(uint8_t address)
case SY_DDRA: case SY_DDRA:
return DDRA; return DDRA;
case SY_TMR1L: case SY_TMR1L:
// FIXME: also updates IFR? IFR &= ~SY_IR_TIMER1;
return (T1_CTR & 0xFF); return (T1_CTR & 0xFF);
case SY_TMR1H: case SY_TMR1H:
return (T1_CTR >> 8); return (T1_CTR >> 8);
@ -34,7 +36,7 @@ uint8_t SY6522::read(uint8_t address)
case SY_TMR1HL: case SY_TMR1HL:
return (T1_CTR_LATCH >> 8); return (T1_CTR_LATCH >> 8);
case SY_TMR2L: case SY_TMR2L:
// FIXME: alos udpates IFR? IFR &= ~SY_IR_TIMER2;
return (T2_CTR & 0xFF); return (T2_CTR & 0xFF);
case SY_TMR2H: case SY_TMR2H:
return (T2_CTR >> 8); return (T2_CTR >> 8);
@ -82,6 +84,15 @@ uint8_t SY6522::read(uint8_t address)
return; return;
case SY_TMR1H: 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 // FIXME: clear interrupt flag
T1_CTR_LATCH = (T1_CTR_LATCH & 0x00FF) | (val << 8); T1_CTR_LATCH = (T1_CTR_LATCH & 0x00FF) | (val << 8);
T1_CTR = T1_CTR_LATCH; T1_CTR = T1_CTR_LATCH;
@ -145,6 +156,26 @@ uint8_t SY6522::read(uint8_t address)
void SY6522::update(uint32_t cycles) 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); ay8910[0].update(cycles);
} }

View File

@ -25,6 +25,19 @@ enum {
SY_ORANOHS = 0x0f // ORA_NO_HS 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 { class SY6522 {
public: public:
SY6522(); SY6522();

10
cpu.cpp
View File

@ -407,6 +407,7 @@ void Cpu::Reset()
x = 0; x = 0;
y = 0; y = 0;
flags = F_Z | F_UNK; // FIXME: is that F_UNK flag right here? flags = F_Z | F_UNK; // FIXME: is that F_UNK flag right here?
irqPending = false;
if (mmu) { if (mmu) {
pc = readmem(0xFFFC) | (readmem(0xFFFD) << 8); pc = readmem(0xFFFC) | (readmem(0xFFFD) << 8);
@ -495,6 +496,11 @@ uint8_t Cpu::Run(uint8_t numSteps)
uint8_t Cpu::step() uint8_t Cpu::step()
{ {
if (irqPending) {
irqPending = false;
irq();
}
uint8_t m = readmem(pc++); uint8_t m = readmem(pc++);
optype_t opcode = opcodes[m]; optype_t opcode = opcodes[m];
@ -1050,3 +1056,7 @@ uint16_t Cpu::popS16()
return (msb << 8) | lsb; 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 SP();
uint8_t P(); uint8_t P();
void stageIRQ();
protected: protected:
// Stack manipulation // Stack manipulation
void pushS8(uint8_t b); void pushS8(uint8_t b);
@ -64,6 +66,8 @@ class Cpu {
uint8_t flags; uint8_t flags;
uint32_t cycles; uint32_t cycles;
bool irqPending;
MMU *mmu; 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 // 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 // "voices" -- 6 from the mockingboard and 2 from the built-in. 8 is
// a great number for dividing. :) // a great number for dividing. :)
mixerValue += (toggleState ? 0xFF : 0x00); mixerValue += (toggleState ? 0x1FF : 0x00);
numMixed += 2; numMixed += 2;
#if 0
if (numMixed != 8) { if (numMixed != 8) {
printf("SPEAKER FAIL - should always be 8\n"); printf("SPEAKER FAIL - should always be 8\n");
} }
mixerValue >>= 3; // divide by 8 mixerValue >>= 3; // divide by 8
#else
mixerValue /= numMixed;
#endif
// FIXME: g_volume // FIXME: g_volume