From b955dd106f754dc1f20ec94a9b7b04e25c05c756 Mon Sep 17 00:00:00 2001 From: Jorj Bauer Date: Sun, 26 Feb 2017 20:25:47 -0500 Subject: [PATCH] draw the drive status indicators from outside the CPU thread/ISR --- apple/diskii.cpp | 15 ++++++++------- apple/diskii.h | 1 - physicaldisplay.h | 2 +- sdl/sdl-display.cpp | 35 +++++++++++++++++----------------- sdl/sdl-display.h | 5 ++++- teensy/teensy-display.cpp | 40 ++++++++++++++++++++++----------------- teensy/teensy-display.h | 6 ++++-- teensy/teensy.ino | 2 +- 8 files changed, 58 insertions(+), 48 deletions(-) diff --git a/apple/diskii.cpp b/apple/diskii.cpp index 2c1a4e2..6b665d3 100644 --- a/apple/diskii.cpp +++ b/apple/diskii.cpp @@ -35,8 +35,6 @@ DiskII::DiskII(AppleMMU *mmu) indicatorIsOn[0] = indicatorIsOn[1] = 0; selectedDisk = 0; diskType[0] = diskType[1] = dosDisk; - - indicatorNeedsDrawing = true; // set to true whenever the display needs to redraw... } DiskII::~DiskII() @@ -74,12 +72,12 @@ uint8_t DiskII::readSwitches(uint8_t s) case 0x08: // drive off indicatorIsOn[selectedDisk] = 99; - indicatorNeedsDrawing = true; + g_display->setDriveIndicator(selectedDisk, false); // FIXME: after a spell... flushTrack(); break; case 0x09: // drive on indicatorIsOn[selectedDisk] = 100; - indicatorNeedsDrawing = true; + g_display->setDriveIndicator(selectedDisk, true); break; case 0x0A: // select drive 1 @@ -123,11 +121,14 @@ uint8_t DiskII::readSwitches(uint8_t s) if (!indicatorIsOn[selectedDisk]) { // printf("Unexpected read while disk isn't on?\n"); indicatorIsOn[selectedDisk] = 100; - indicatorNeedsDrawing = true; + g_display->setDriveIndicator(selectedDisk, true); } if (indicatorIsOn[selectedDisk] > 0 && indicatorIsOn[selectedDisk] < 100) { - indicatorIsOn[selectedDisk]--; // slowly spin it down... + if (--indicatorIsOn[selectedDisk] == 0) { + g_display->setDriveIndicator(selectedDisk, false); + } + } // Any even address read returns the readWriteLatch (UTA2E Table 9.1, @@ -305,7 +306,7 @@ void DiskII::select(int8_t which) if (which != selectedDisk) { indicatorIsOn[selectedDisk] = 0; - indicatorNeedsDrawing = true; + g_display->setDriveIndicator(selectedDisk, false); flushTrack(); // in case it's dirty: flush before changing drives trackBuffer->clear(); diff --git a/apple/diskii.h b/apple/diskii.h index 9f661bc..b931bcd 100644 --- a/apple/diskii.h +++ b/apple/diskii.h @@ -61,7 +61,6 @@ class DiskII : public Slot { uint8_t diskType[2]; volatile int8_t selectedDisk; - volatile bool indicatorNeedsDrawing; volatile int8_t trackToRead; // -1 when we're idle; not -1 when we need to read a track. }; diff --git a/physicaldisplay.h b/physicaldisplay.h index 93e0985..9f6cdbc 100644 --- a/physicaldisplay.h +++ b/physicaldisplay.h @@ -14,7 +14,7 @@ class PhysicalDisplay { virtual void blit(AiieRect r) = 0; // redraw just the VM display area virtual void drawDriveDoor(uint8_t which, bool isOpen) = 0; - virtual void drawDriveStatus(uint8_t which, bool isRunning) = 0; + virtual void setDriveIndicator(uint8_t which, bool isRunning) = 0; virtual void drawBatteryStatus(uint8_t percent) = 0; virtual void drawCharacter(uint8_t mode, uint16_t x, uint8_t y, char c) = 0; diff --git a/sdl/sdl-display.cpp b/sdl/sdl-display.cpp index e56f184..ddbd348 100644 --- a/sdl/sdl-display.cpp +++ b/sdl/sdl-display.cpp @@ -67,25 +67,10 @@ void SDLDisplay::redraw() } } -void SDLDisplay::drawDriveStatus(uint8_t which, bool isRunning) +void SDLDisplay::setDriveIndicator(uint8_t which, bool isRunning) { - // FIXME: this is a draw from another thread. Can't do that with SDL. - return; - - // location of status indicator for left drive - uint16_t xoff = 125; - uint16_t yoff = 213; - - // and right drive - if (which == 1) - xoff += 135; - - for (int y=0; y<1; y++) { - for (int x=0; x<6; x++) { - drawPixel(x + xoff, y + yoff, isRunning ? 0xF800 : 0x8AA9); - } - } - + driveIndicator[which] = isRunning; + driveIndicatorDirty = true; } void SDLDisplay::drawDriveDoor(uint8_t which, bool isOpen) @@ -177,6 +162,20 @@ void SDLDisplay::blit(AiieRect r) drawString(M_SELECTDISABLED, 1, 240 - 16 - 12, overlayMessage); } + if (driveIndicatorDirty) { + // location of status indicator for left drive + uint16_t xoff = 125; + uint16_t yoff = 213; + for (int which=0; which<2; which++,xoff+=135) { // +135 for right drive + for (int y=0; y<1; y++) { + for (int x=0; x<6; x++) { + drawPixel(x + xoff, y + yoff, driveIndicator[which] ? 0xF800 : 0x8AA9); + } + } + } + driveIndicatorDirty = false; + } + SDL_RenderPresent(renderer); } diff --git a/sdl/sdl-display.h b/sdl/sdl-display.h index d95f2f8..043a121 100644 --- a/sdl/sdl-display.h +++ b/sdl/sdl-display.h @@ -25,7 +25,7 @@ class SDLDisplay : public PhysicalDisplay { virtual void redraw(); virtual void drawDriveDoor(uint8_t which, bool isOpen); - virtual void drawDriveStatus(uint8_t which, bool isRunning); + virtual void setDriveIndicator(uint8_t which, bool isRunning); virtual void drawBatteryStatus(uint8_t percent); void drawPixel(uint16_t x, uint8_t y, uint16_t color); @@ -37,6 +37,9 @@ class SDLDisplay : public PhysicalDisplay { private: SDL_Window *screen; SDL_Renderer *renderer; + + bool driveIndicator[2]; + bool driveIndicatorDirty; }; #endif diff --git a/teensy/teensy-display.cpp b/teensy/teensy-display.cpp index aca0086..498fa81 100644 --- a/teensy/teensy-display.cpp +++ b/teensy/teensy-display.cpp @@ -160,11 +160,12 @@ TeensyDisplay::TeensyDisplay() // LCD initialization complete - setColor(255, 255, 255); clrScr(); + driveIndicator[0] = driveIndicator[1] = false; + driveIndicatorDirty = true; } TeensyDisplay::~TeensyDisplay() @@ -410,6 +411,8 @@ void TeensyDisplay::blit(AiieRect r) drawString(M_SELECTDISABLED, 1, 240 - 16 - 12, overlayMessage); } + + redrawDriveIndicators(); } void TeensyDisplay::drawCharacter(uint8_t mode, uint16_t x, uint8_t y, char c) @@ -473,7 +476,6 @@ void TeensyDisplay::drawDriveDoor(uint8_t which, bool isOpen) uint16_t xoff = 55; uint16_t yoff = 216; - return; // debugging: disabling this for testing // location for right drive @@ -498,22 +500,29 @@ void TeensyDisplay::drawDriveDoor(uint8_t which, bool isOpen) } } -void TeensyDisplay::drawDriveStatus(uint8_t which, bool isRunning) +void TeensyDisplay::setDriveIndicator(uint8_t which, bool isRunning) { - // location of status indicator for left drive - uint16_t xoff = 125; - uint16_t yoff = 213; + driveIndicator[which] = isRunning; + driveIndicatorDirty = true; +} - // and right drive - if (which == 1) - xoff += 135; -#if 0 - for (int y=0; y<2; y++) { - for (int x=0; x<6; x++) { - drawPixel(x + xoff, y + yoff, isRunning ? 0xF800 : 0x8AA9); +void TeensyDisplay::redrawDriveIndicators() +{ + if (driveIndicatorDirty) { + // location of status indicator for left drive + uint16_t xoff = 125; + uint16_t yoff = 213; + + for (int which = 0; which <= 1; which++,xoff += 135) { + + for (int y=0; y<2; y++) { + for (int x=0; x<6; x++) { + drawPixel(x + xoff, y + yoff, driveIndicator[which] ? 0xF800 : 0x8AA9); + } + } } + driveIndicatorDirty = false; } -#endif } void TeensyDisplay::drawBatteryStatus(uint8_t percent) @@ -521,9 +530,6 @@ void TeensyDisplay::drawBatteryStatus(uint8_t percent) uint16_t xoff = 300; uint16_t yoff = 222; - // DEBUGGING: disabling this; it's drawing it a *lot* - return; - // the area around the apple is 12 wide // it's exactly 11 high // the color is 210/202/159 diff --git a/teensy/teensy-display.h b/teensy/teensy-display.h index 53c0b9b..86bc605 100644 --- a/teensy/teensy-display.h +++ b/teensy/teensy-display.h @@ -43,13 +43,13 @@ class TeensyDisplay : public PhysicalDisplay { virtual void drawString(uint8_t mode, uint16_t x, uint8_t y, const char *str); virtual void drawDriveDoor(uint8_t which, bool isOpen); - virtual void drawDriveStatus(uint8_t which, bool isRunning); + virtual void setDriveIndicator(uint8_t which, bool isRunning); virtual void drawBatteryStatus(uint8_t percent); protected: void moveTo(uint16_t col, uint16_t row); void drawNextPixel(uint16_t color); - + void redrawDriveIndicators(); private: regtype *P_RS, *P_WR, *P_CS, *P_RST, *P_SDA, *P_SCL, *P_ALE; @@ -76,6 +76,8 @@ class TeensyDisplay : public PhysicalDisplay { void LCD_Write_COM_DATA(uint8_t com1,uint16_t dat1); bool needsRedraw; + bool driveIndicator[2]; + bool driveIndicatorDirty; }; #endif diff --git a/teensy/teensy.ino b/teensy/teensy.ino index d87f98e..d1c68e0 100644 --- a/teensy/teensy.ino +++ b/teensy/teensy.ino @@ -281,7 +281,7 @@ void loop() // in the appropriate block below if (millis() >= nextBattCheck) { // FIXME: what about rollover? - nextBattCheck = millis() + 1 * 1000; // once a minute? maybe? FIXME: Right now 1/sec + nextBattCheck = millis() + 30 * 1000; // check every 30 seconds // FIXME: scale appropriately. batteryLevel = analogRead(BATTERYPIN);