diff --git a/apple/sy6522.cpp b/apple/sy6522.cpp deleted file mode 100644 index 39f4022..0000000 --- a/apple/sy6522.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "sy6522.h" -#include - -#include "globals.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: - IFR &= ~SY_IR_TIMER1; - 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: - IFR &= ~SY_IR_TIMER2; - 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: - 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; - // 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) -{ - /* 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); -} - diff --git a/apple/sy6522.h b/apple/sy6522.h deleted file mode 100644 index 46107c9..0000000 --- a/apple/sy6522.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef __SY6522_H -#define __SY6522_H - -#include - -#include "ay8910.h" - -// 6522 interface registers -enum { - SY_ORB = 0x00, // ORB - SY_ORA = 0x01, // ORA - SY_DDRB = 0x02, // DDRB - SY_DDRA = 0x03, // DDRA - SY_TMR1L = 0x04, // TIMER1L_COUNTER - SY_TMR1H = 0x05, // TIMER1H_COUNTER - SY_TMR1LL = 0x06, // TIMER1L_LATCH - SY_TMR1HL = 0x07, // TIMER1H_LATCH - SY_TMR2L = 0x08, // TIMER2L - SY_TMR2H = 0x09, // TIMER2H - SY_SS = 0x0a, // SERIAL_SHIFT - SY_ACR = 0x0b, // ACR - SY_PCR = 0x0c, // PCR - SY_IFR = 0x0d, // IFR - SY_IER = 0x0e, // IER - 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(); - - uint8_t read(uint8_t address); - void write(uint8_t address, uint8_t val); - - void update(uint32_t cycles); - - private: - uint8_t ORB; // port B - uint8_t ORA; // port A - uint8_t DDRB; // data direction register - uint8_t DDRA; // - uint16_t T1_CTR; // counters - uint16_t T1_CTR_LATCH; - uint16_t T2_CTR; - uint16_t T2_CTR_LATCH; - uint8_t ACR; // Aux Control Register - uint8_t PCR; // Peripheral Control Register - uint8_t IFR; // Interrupt Flag Register - uint8_t IER; // Interrupt Enable Register - - AY8910 ay8910[1]; // FIXME: an array in case we support more than one ... ? -}; - -#endif diff --git a/teensy/sy6522.cpp b/teensy/sy6522.cpp deleted file mode 120000 index 7c598de..0000000 --- a/teensy/sy6522.cpp +++ /dev/null @@ -1 +0,0 @@ -../apple/sy6522.cpp \ No newline at end of file diff --git a/teensy/sy6522.h b/teensy/sy6522.h deleted file mode 120000 index 944e80d..0000000 --- a/teensy/sy6522.h +++ /dev/null @@ -1 +0,0 @@ -../apple/sy6522.h \ No newline at end of file diff --git a/teensy/teensy.ino b/teensy/teensy.ino index 3ec255b..50a8b26 100644 --- a/teensy/teensy.ino +++ b/teensy/teensy.ino @@ -226,7 +226,6 @@ void runCPU() ((AppleVM *)g_vm)->cpuMaintenance(g_cpu->cycles); g_speaker->maintainSpeaker(g_cpu->cycles); - // The CPU of the Apple //e ran at 1.023 MHz. Adjust when we think // the next instruction should run based on how long the execution // was ((1000/1023) * numberOfCycles) - which is about 97.8%. @@ -252,6 +251,19 @@ void loop() // Only redraw if the CPU is caught up; and then we'll suspend the // CPU to draw a full frame. + + // Note that this breaks audio, b/c it's real-time and requires the + // CPU running to change the audio line's value. So we need to EITHER + // + // - delay the audio line by at least the time it takes for one + // display update, OR + // - lock display updates so the CPU can update the memory, but we + // keep drawing what was going to be displayed + // + // The Timer1.stop()/start() is bad. Using it, the display doesn't + // tear; but the audio is also broken. Taking it out, audio is good + // but the display tears. + Timer1.stop(); g_vm->vmdisplay->needsRedraw(); AiieRect what = g_vm->vmdisplay->getDirtyRect();