draw the drive status indicators from outside the CPU thread/ISR

This commit is contained in:
Jorj Bauer 2017-02-26 20:25:47 -05:00
parent 85d81d398a
commit b955dd106f
8 changed files with 58 additions and 48 deletions

View File

@ -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();

View File

@ -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.
};

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);