diff --git a/io.cpp b/io.cpp index b36d605..34518d7 100644 --- a/io.cpp +++ b/io.cpp @@ -12,11 +12,6 @@ #include "hardware.h" #include "config.h" -#define ROWS 24 -#define COLS 40 -static unsigned r, c; -static char screen[ROWS][COLS]; - void io::reset() { Display::begin(BG_COLOUR, FG_COLOUR, ORIENT); clear(); @@ -78,7 +73,6 @@ static const uint8_t shiftmap[] PROGMEM = { }; void io::down(uint8_t scan) { - PIA::write_porta(0); if (isshift(scan)) _shift = true; } diff --git a/io.h b/io.h index e11a40e..d640bd2 100644 --- a/io.h +++ b/io.h @@ -6,8 +6,8 @@ public: io(filer &files): Memory::Device(Memory::page_size), files(files) {} virtual void reset(); - virtual void down(uint8_t scan); - virtual void up(uint8_t scan); + virtual void down(uint8_t); + virtual void up(uint8_t); virtual void operator=(uint8_t b) { PIA::write(_acc, b); } virtual operator uint8_t() { return PIA::read(_acc); } @@ -20,13 +20,18 @@ public: void load(); filer &files; + + static const uint8_t ROWS = 24; + static const uint8_t COLS = 40; + private: void display(uint8_t); void draw(char, int, int); void enter(uint8_t); - bool _shift; - bool _loading; + bool _shift, _loading; + uint8_t r, c; + char screen[ROWS][COLS]; }; #endif diff --git a/pia.cpp b/pia.cpp index 2d0b473..6f4eb8e 100644 --- a/pia.cpp +++ b/pia.cpp @@ -9,6 +9,14 @@ inline bool c1_low_to_high(uint8_t cr) { return cr & 0x02; } inline bool c1_high_to_low(uint8_t cr) { return !c1_low_to_high(cr); } +inline bool c2_output(uint8_t cr) { return cr & 0x20; } + +inline bool c2_input(uint8_t cr) { return !c2_input(cr); } + +inline bool c2_low_to_high(uint8_t cr) { return cr & 0x10; } + +inline bool c2_high_to_low(uint8_t cr) { return !c2_low_to_high(cr); } + void PIA::write(Memory::address a, uint8_t b) { #if defined(DEBUGGING) Serial.print(millis()); @@ -58,9 +66,13 @@ void PIA::checkpoint(Stream &s) { s.write(porta_cr); s.write(porta); s.write(irq_b1); + s.write(irq_b2); s.write(irq_a1); + s.write(irq_a2); s.write(cb1); + s.write(cb2); s.write(ca1); + s.write(ca2); } void PIA::restore(Stream &s) { @@ -69,9 +81,13 @@ void PIA::restore(Stream &s) { porta_cr = s.read(); porta = s.read(); irq_b1 = s.read(); + irq_b2 = s.read(); irq_a1 = s.read(); + irq_a2 = s.read(); cb1 = s.read(); + cb2 = s.read(); ca1 = s.read(); + ca2 = s.read(); } void PIA::write_ca1(bool state) { @@ -85,6 +101,17 @@ void PIA::write_ca1(bool state) { ca1 = state; } +void PIA::write_ca2(bool state) { + + if (ca2 == state || !c2_input(porta_cr)) + return; + + if ((state && c2_low_to_high(porta_cr)) || (!state && c2_high_to_low(porta_cr))) + irq_a2 = true; + + ca2 = state; +} + void PIA::write_cb1(bool state) { if (cb1 == state) @@ -96,14 +123,37 @@ void PIA::write_cb1(bool state) { cb1 = state; } +void PIA::write_cb2(bool state) { + + if (cb2 == state || !c2_input(portb_cr)) + return; + + if ((state && c2_low_to_high(portb_cr)) || (!state && c2_high_to_low(portb_cr))) + irq_b2 = true; + + cb2 = state; +} + uint8_t PIA::read_porta_cr() { + byte b = porta_cr; + if (irq_a1) - return porta_cr | IRQ1; - return porta_cr; + b |= IRQ1; + + if (irq_a2 && c2_input(porta_cr)) + b |= IRQ2; + + return b; } uint8_t PIA::read_portb_cr() { + byte b = portb_cr; + if (irq_b1) - return portb_cr | IRQ1; - return portb_cr; + b |= IRQ1; + + if (irq_b2 && c2_input(portb_cr)) + b |= IRQ2; + + return b; } diff --git a/pia.h b/pia.h index efd30b8..0916194 100644 --- a/pia.h +++ b/pia.h @@ -4,11 +4,13 @@ // https://en.wikipedia.org/wiki/Peripheral_Interface_Adapter class PIA { public: - PIA(): portb(0), portb_cr(0), porta(0), porta_cr(0), irq_a1(false), irq_b1(false) {} + PIA(): portb(0), portb_cr(0), porta(0), porta_cr(0), + ca1(false), ca2(false), cb1(false), cb2(false), + irq_a1(false), irq_a2(false), irq_b1(false), irq_b2(false) {} virtual void reset() { portb = portb_cr = porta = porta_cr = 0; - irq_a1 = irq_b1 = ca1 = cb1 = false; + irq_a1 = irq_a2 = irq_b1 = irq_b2 = ca1 = ca2 = cb1 = cb2 = false; } void write(Memory::address, uint8_t); @@ -18,15 +20,18 @@ public: void restore(Stream &); void write_ca1(bool); + void write_ca2(bool); void write_cb1(bool); + void write_cb2(bool); static const uint8_t IRQ1 = 0x80; + static const uint8_t IRQ2 = 0x40; protected: // "device-side" operations (called from memory interface) - virtual uint8_t read_porta() { irq_a1 = false; return porta; } + virtual uint8_t read_porta() { irq_a1 = irq_a2 = false; return porta; } virtual uint8_t read_porta_cr(); - virtual uint8_t read_portb() { irq_b1 = false; return portb; } + virtual uint8_t read_portb() { irq_b1 = irq_b2 = false; return portb; } virtual uint8_t read_portb_cr(); virtual void write_porta(uint8_t b) { porta = b; } @@ -36,7 +41,7 @@ protected: private: uint8_t portb_cr, portb, porta_cr, porta; - bool ca1, irq_a1; - bool cb1, irq_b1; + bool ca1, ca2, irq_a1, irq_a2; + bool cb1, cb2, irq_b1, irq_b2; }; #endif